├── RazorScripts ├── packages.config ├── LootmasterReconfigure.cs ├── LootmasterClearCurrentConfig.cs ├── FindAndUseTool.cs ├── LootmasterDirectContainer.cs ├── Repeater.cs ├── WeedPuller.cs ├── GuardMe.cs ├── ReleaseAll.cs ├── App.config ├── TargetAllOfType.cs ├── BagTransfer.cs ├── CottonPicker.cs ├── MoveBoards.cs ├── Greed.cs ├── Properties │ └── AssemblyInfo.cs ├── MountUp.cs ├── Weak.cs ├── TeleTalk.cs ├── Hiding.cs ├── Honoring.cs ├── MultiQuestmark.cs ├── AnimalReleaser.cs ├── ChestBreaker.cs ├── IdocScanner.cs ├── MineNode.cs ├── Targeting.cs ├── RaritySorter.cs ├── Ranger.cs ├── ScriptMonitor.cs ├── RazorScripts.csproj ├── RuneBookFinder.cs ├── HealMaster.cs ├── Butcher.cs ├── Debugger.cs ├── Reloader.cs ├── SampMaster.cs ├── WeaponMaster.cs ├── TheRanger.cs ├── CasterTrain.cs ├── SlayerBar.cs └── SummonMaster.cs ├── .idea └── .idea.RazorScripts │ └── .idea │ ├── encodings.xml │ ├── vcs.xml │ ├── indexLayout.xml │ └── .gitignore ├── .gitignore ├── RazorScripts.sln.DotSettings.user ├── RazorScripts.sln └── README.md /RazorScripts/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/.idea.RazorScripts/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/.idea.RazorScripts/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/.idea.RazorScripts/.idea/indexLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | packages/ 2 | Crypt/Debug/ 3 | Crypt/Release/ 4 | Debug/ 5 | FastColoredTextBox/bin/ 6 | FastColoredTextBox/obj/ 7 | Loader/Debug/ 8 | Loader/Release/ 9 | Razor/obj/ 10 | Razor/bin/ 11 | Release/ 12 | UltimaSDK/bin/ 13 | UltimaSDK/obj/ 14 | /.vs/ 15 | 16 | *~ 17 | 18 | *.htm 19 | 20 | 21 | 22 | # JetBrains Rider 23 | .idea/ 24 | *.sln.iml -------------------------------------------------------------------------------- /RazorScripts/LootmasterReconfigure.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using RazorEnhanced; 4 | 5 | namespace Razorscripts 6 | { 7 | public class LootmasterReconfigure 8 | { 9 | public void Run() 10 | { 11 | Misc.SetSharedValue("Lootmaster:ReconfigureBags", true); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /.idea/.idea.RazorScripts/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Rider ignored files 5 | /contentModel.xml 6 | /.idea.RazorScripts.iml 7 | /projectSettingsUpdater.xml 8 | /modules.xml 9 | # Editor-based HTTP Client requests 10 | /httpRequests/ 11 | # Datasource local storage ignored files 12 | /dataSources/ 13 | /dataSources.local.xml 14 | -------------------------------------------------------------------------------- /RazorScripts/LootmasterClearCurrentConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Runtime.Remoting.Messaging; 4 | using RazorEnhanced; 5 | 6 | namespace Razorscripts 7 | { 8 | public class LootmasterClearCurrentConfig 9 | { 10 | public void Run() 11 | { 12 | Misc.SetSharedValue("Lootmaster:ClearCurrentCharacter", true); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /RazorScripts/FindAndUseTool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using RazorEnhanced; 4 | 5 | namespace Razorscripts 6 | { 7 | public class MapRepeater 8 | { 9 | private int _itemId = Convert.ToInt32("0x0FBF", 16); 10 | 11 | public void Run() 12 | { 13 | var tool = Player.Backpack.Contains.FirstOrDefault(i => i.ItemID == _itemId); 14 | if (tool == null) 15 | { 16 | return; 17 | } 18 | 19 | Items.UseItem(tool); 20 | } 21 | 22 | } 23 | } -------------------------------------------------------------------------------- /RazorScripts.sln.DotSettings.user: -------------------------------------------------------------------------------- 1 | 2 | <AssemblyExplorer> 3 | <Assembly Path="C:\Source\RazorEnhanced\bin\Win32\Debug\Ultima.dll" /> 4 | </AssemblyExplorer> -------------------------------------------------------------------------------- /RazorScripts/LootmasterDirectContainer.cs: -------------------------------------------------------------------------------- 1 | using RazorEnhanced; 2 | 3 | namespace Razorscripts 4 | { 5 | public class LootmasterDirectContainer 6 | { 7 | public void Run() 8 | { 9 | var tar = new Target(); 10 | var source = tar.PromptTarget("Select container to run LootMaster on"); 11 | if (source == -1) 12 | { 13 | Misc.SendMessage("No target selected", 201); 14 | return; 15 | } 16 | 17 | Misc.SetSharedValue("Lootmaster:DirectContainer", source); 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /RazorScripts/Repeater.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using RazorEnhanced; 4 | 5 | namespace Razorscripts 6 | { 7 | public class Repeater 8 | { 9 | public void Run() 10 | { 11 | while (Player.GetSkillValue("Necromancy") < 95) 12 | { 13 | Spells.Cast("Wither"); 14 | 15 | Misc.Pause(3000); 16 | 17 | if (Player.Mana < 25) 18 | { 19 | Player.UseSkill("Meditation"); 20 | Misc.Pause(15000); 21 | } 22 | } 23 | 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /RazorScripts/WeedPuller.cs: -------------------------------------------------------------------------------- 1 | using RazorEnhanced; 2 | 3 | namespace RazorScripts 4 | { 5 | public class WeedPuller 6 | { 7 | public void Run() 8 | { 9 | while (true) 10 | { 11 | var weeds = Items.ApplyFilter(new Items.Filter 12 | { 13 | RangeMin = 0, 14 | RangeMax = 1, 15 | Name = "Creepy weeds" 16 | }); 17 | foreach (var weed in weeds) 18 | { 19 | Items.UseItem(weed); 20 | Misc.Pause(100); 21 | } 22 | 23 | Misc.Pause(100); 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /RazorScripts/GuardMe.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using RazorEnhanced; 4 | 5 | namespace Razorscripts 6 | { 7 | public class GuardMe 8 | { 9 | public void Run() 10 | { 11 | var filter = new Mobiles.Filter 12 | { 13 | RangeMax = 20, 14 | RangeMin = 0, 15 | Notorieties = new List { 1 } 16 | }; 17 | 18 | var mobs = Mobiles.ApplyFilter(filter); 19 | foreach (var mob in mobs) 20 | { 21 | Mobiles.WaitForProps(mob,1000); 22 | var sumProp = mob.Properties.FirstOrDefault(p => p.Number == 1049646); 23 | if (sumProp == null || !sumProp.ToString().Contains("summoned")) continue; 24 | Misc.WaitForContext(mob, 500); 25 | Misc.ContextReply(mob, 2); 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /RazorScripts/ReleaseAll.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using RazorEnhanced; 4 | 5 | namespace Razorscripts 6 | { 7 | public class ReleaseAll 8 | { 9 | public void Run() 10 | { 11 | var filter = new Mobiles.Filter 12 | { 13 | RangeMax = 20, 14 | RangeMin = 0, 15 | Notorieties = new List { 1 } 16 | }; 17 | 18 | var mobs = Mobiles.ApplyFilter(filter); 19 | foreach (var mob in mobs) 20 | { 21 | Mobiles.WaitForProps(mob,1000); 22 | var sumProp = mob.Properties.FirstOrDefault(p => p.Number == 1049646); 23 | if (sumProp == null || !sumProp.ToString().Contains("summoned")) continue; 24 | Misc.WaitForContext(mob, 500); 25 | Misc.ContextReply(mob, 5); 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /RazorScripts/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /RazorScripts/TargetAllOfType.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Runtime.Remoting.Messaging; 4 | using RazorEnhanced; 5 | 6 | namespace Razorscripts 7 | { 8 | public class TargetAllOfType 9 | { 10 | public void Run() 11 | { 12 | if (!Target.HasTarget()) 13 | { 14 | Misc.SendMessage("You are not currently waiting for targets",201); 15 | return; 16 | } 17 | var itemSerial = Target.GetLast(); 18 | var targetItem = Player.Backpack.Contains.FirstOrDefault(i => i.Serial == itemSerial); 19 | if (targetItem != null) 20 | { 21 | var all = Player.Backpack.Contains.Where(i => i.ItemID == targetItem.ItemID).ToList(); 22 | foreach (var i in all) 23 | { 24 | Target.TargetExecute(i); 25 | Target.WaitForTarget(3000); 26 | } 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /RazorScripts/BagTransfer.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using RazorEnhanced; 3 | 4 | namespace RazorScripts 5 | { 6 | public class BagTransfer 7 | { 8 | public void Run() 9 | { 10 | var tar = new Target(); 11 | var sourceSerial = tar.PromptTarget("Select Source bag"); 12 | var sourceBag = Items.FindBySerial(sourceSerial); 13 | var targetSerial = tar.PromptTarget("Select Target bag"); 14 | var targetBag = Items.FindBySerial(targetSerial); 15 | Items.WaitForContents(sourceBag,3000); 16 | Misc.Pause(200); 17 | while (sourceBag.Contains.Any(i => i.IsLootable && i.Container == sourceBag.Serial)) 18 | { 19 | foreach (var item in sourceBag.Contains.Where(i => i.IsLootable)) 20 | { 21 | Items.Move(item.Serial, targetBag, item.Amount); 22 | Misc.Pause(250); 23 | } 24 | Misc.Pause(2000); 25 | Items.WaitForContents(sourceBag, 3000); 26 | } 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /RazorScripts/CottonPicker.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using RazorEnhanced; 4 | 5 | namespace RazorScripts 6 | { 7 | public class CottonPicker 8 | { 9 | private List CottonPlants = new List 10 | { 11 | 0x0C51, 12 | 0x0C52, 13 | 0x0C53, 14 | 0x0C54 15 | }; 16 | 17 | public void Run() 18 | { 19 | var plantFilter = new Items.Filter 20 | { 21 | RangeMin = 0, 22 | RangeMax = 2 23 | }; 24 | foreach (var item in Items.ApplyFilter(plantFilter).Where(item => CottonPlants.Contains(item.ItemID))) 25 | { 26 | Items.UseItem(item); 27 | Misc.Pause(100); 28 | } 29 | 30 | Misc.Pause(200); 31 | 32 | var cottonFilter = new Items.Filter 33 | { 34 | RangeMin = 0, 35 | RangeMax = 2 36 | }; 37 | foreach (var cotton in Items.ApplyFilter(cottonFilter)) 38 | { 39 | Items.Move(cotton, Player.Backpack, cotton.Amount); 40 | Misc.Pause(300); 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /RazorScripts.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RazorScripts", "RazorScripts\RazorScripts.csproj", "{06B26608-0E38-411D-98A9-4A8C9EC66030}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Razor", "..\RazorEnhanced\Razor\Razor.csproj", "{B24E4FB1-4936-4544-9E88-F3FF9B04FDBA}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {06B26608-0E38-411D-98A9-4A8C9EC66030}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {06B26608-0E38-411D-98A9-4A8C9EC66030}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {06B26608-0E38-411D-98A9-4A8C9EC66030}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {06B26608-0E38-411D-98A9-4A8C9EC66030}.Release|Any CPU.Build.0 = Release|Any CPU 17 | {B24E4FB1-4936-4544-9E88-F3FF9B04FDBA}.Debug|Any CPU.ActiveCfg = Debug|x86 18 | {B24E4FB1-4936-4544-9E88-F3FF9B04FDBA}.Debug|Any CPU.Build.0 = Debug|x86 19 | {B24E4FB1-4936-4544-9E88-F3FF9B04FDBA}.Release|Any CPU.ActiveCfg = Release|x86 20 | {B24E4FB1-4936-4544-9E88-F3FF9B04FDBA}.Release|Any CPU.Build.0 = Release|x86 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /RazorScripts/MoveBoards.cs: -------------------------------------------------------------------------------- 1 | using RazorEnhanced; 2 | using System.Linq; 3 | 4 | namespace Razorscripts 5 | { 6 | public class MoveBoards 7 | { 8 | private string OrganizerListName = "boardmove"; //The name of the organizer hat moves boards to horse 9 | 10 | public void Run() 11 | { 12 | var axe = Player.GetItemOnLayer("RightHand") ?? Player.GetItemOnLayer("LeftHand"); 13 | if (axe == null) 14 | { 15 | Misc.SendMessage("No Axe Equipped", 201); 16 | return; 17 | } 18 | 19 | var logstacks = Player.Backpack.Contains.Where(l => l.ItemID == 7133).ToList(); 20 | if (logstacks.Any()) 21 | { 22 | foreach (var logs in logstacks) 23 | { 24 | Items.UseItem(axe); 25 | Target.WaitForTarget(2000); 26 | Target.TargetExecute(logs); 27 | Misc.Pause(500); 28 | } 29 | } 30 | else 31 | { 32 | Misc.SendMessage("No boards found in backpack", 201); 33 | } 34 | 35 | Organizer.ChangeList(OrganizerListName); 36 | Organizer.FStop(); 37 | Organizer.FStart(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /RazorScripts/Greed.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using RazorEnhanced; 3 | 4 | namespace RazorScripts 5 | { 6 | public class Greed 7 | { 8 | public void Run() 9 | { 10 | var bos = Player.Backpack.Contains.FirstOrDefault(i => i.ItemID == 0x0E76 && i.IsBagOfSending); 11 | if (bos == null) 12 | { 13 | Player.HeadMessage(201,"No Bag of Sending found in backpack"); 14 | return; 15 | } 16 | Player.HeadMessage(201,"Global Response Electronic Emergency Deposit (G.R.E.E.D) program Online"); 17 | while (true) 18 | { 19 | var goldPile = 20 | Player.Backpack.Contains.FirstOrDefault(i => i.ItemID == 0x0EED && i.Hue == 0 && i.Amount > 10000); 21 | if(goldPile != null) 22 | { 23 | if (Player.Hits < 20) 24 | { 25 | Player.HeadMessage(201,"Executing G.R.E.E.D protocol"); 26 | Items.UseItem(bos); 27 | Target.WaitForTarget(1000); 28 | Target.TargetExecute(goldPile); 29 | Misc.Pause(2000); 30 | } 31 | } 32 | Misc.Pause(1000); 33 | } 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /RazorScripts/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("RazorScripts")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("RazorScripts")] 12 | [assembly: AssemblyCopyright("Copyright © 2023")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("06B26608-0E38-411D-98A9-4A8C9EC66030")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] -------------------------------------------------------------------------------- /RazorScripts/MountUp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text.RegularExpressions; 4 | using RazorEnhanced; 5 | 6 | namespace RazorScripts 7 | { 8 | public class MountUp 9 | { 10 | public void Run() 11 | { 12 | //&Check for bonded bet 1049608 13 | var found = Mobiles.ApplyFilter(new Mobiles.Filter 14 | { 15 | Notorieties = { 1, 2 }, 16 | RangeMax = 2, 17 | }).ToList(); 18 | 19 | foreach (var mob in found) 20 | { 21 | Mobiles.WaitForProps(mob, 1000); 22 | } 23 | 24 | var bonded = found.Where(m => m.Properties.Any(p => p.Number == 1049608)); 25 | if (bonded.Any()) 26 | { 27 | foreach (var mobile in bonded) 28 | { 29 | var isMine = mobile.CanRename; 30 | if (mobile.Backpack == null && isMine) 31 | { 32 | Mobiles.UseMobile(mobile); 33 | return; 34 | } 35 | } 36 | } 37 | 38 | 39 | var regex = new Regex(@"\bEthereal\b.*\bStatuette\b|\bStatuette\b.*\bEthereal\b", RegexOptions.IgnoreCase); 40 | 41 | var mount = Player.Backpack.Contains.FirstOrDefault(i => regex.Match(i.Name).Success); 42 | if (mount == null) 43 | { 44 | return; 45 | } 46 | 47 | Items.UseItem(mount); 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /RazorScripts/Weak.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using RazorEnhanced; 3 | 4 | namespace RazorScripts 5 | { 6 | public class Weak 7 | { 8 | private int? weightLimit = null; 9 | private int? goldLimit = 55000; 10 | 11 | public void Run() 12 | { 13 | var bos = Player.Backpack.Contains.FirstOrDefault(i => i.ItemID == 0x0E76 && i.IsBagOfSending); 14 | if (bos == null) 15 | { 16 | Player.HeadMessage(201,"No Bag of Sending found in backpack"); 17 | return; 18 | } 19 | Player.HeadMessage(201,"When Encumbered, Automatically Kachink (W.E.A.K) program Online"); 20 | while (true) 21 | { 22 | var goldPile = 23 | Player.Backpack.Contains.FirstOrDefault(i => i.ItemID == 0x0EED && i.Hue == 0 && i.Amount > 10000); 24 | if(goldPile != null) 25 | { 26 | var maxWeight = Player.MaxWeight; 27 | if (weightLimit != null && weightLimit < maxWeight) 28 | { 29 | maxWeight = weightLimit.Value; 30 | } 31 | 32 | if (Player.Weight >= maxWeight || ( goldLimit != null && goldPile.Amount >= goldLimit)) 33 | { 34 | Player.HeadMessage(201,"Executing W.E.A.K protocol"); 35 | Items.UseItem(bos); 36 | Target.WaitForTarget(1000); 37 | Target.TargetExecute(goldPile); 38 | Misc.Pause(2000); 39 | } 40 | } 41 | Misc.Pause(200); 42 | } 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /RazorScripts/TeleTalk.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using RazorEnhanced; 5 | 6 | namespace RazorScripts 7 | { 8 | public class TeleTalk 9 | { 10 | private List Triggers = new List 11 | { 12 | new TriggerTalk 13 | { 14 | Trigger = "beam me up", 15 | Script = "recall.py" 16 | }, 17 | new TriggerTalk 18 | { 19 | Trigger = "take me home", 20 | Script = "gatehome.py" 21 | }, 22 | }; 23 | 24 | public void Run() 25 | { 26 | Journal jo = new Journal(); 27 | Journal.JournalEntry lastEntry = null; 28 | 29 | try 30 | { 31 | while (true) 32 | { 33 | var entries = jo.GetJournalEntry(lastEntry).OrderBy(j => j.Timestamp).ToList(); 34 | //Find first match between triggers and journal entries and run the script 35 | foreach (var trigger in Triggers) 36 | { 37 | var entry = entries.FirstOrDefault(e => e.Text.Equals(trigger.Trigger, StringComparison.OrdinalIgnoreCase) && e.Name == Player.Name); 38 | if (entry != null) 39 | { 40 | Misc.ScriptRun(trigger.Script); 41 | Misc.Pause(3000); 42 | } 43 | } 44 | 45 | lastEntry = entries.Last(); 46 | Misc.Pause(500); 47 | } 48 | } 49 | catch (Exception e) 50 | { 51 | Misc.SendMessage("Something went wrong, and the script has stopped"); 52 | Misc.SendMessage(e.ToString()); 53 | } 54 | } 55 | } 56 | 57 | public class TriggerTalk 58 | { 59 | public string Trigger { get; set; } 60 | public string Script { get; set; } 61 | } 62 | } -------------------------------------------------------------------------------- /RazorScripts/Hiding.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using RazorEnhanced; 5 | 6 | namespace Razorscripts 7 | { 8 | public class Honoring 9 | { 10 | public void Run() 11 | { 12 | var last = Target.GetLast(); 13 | 14 | var target = PickTarget(); 15 | if (target == null) 16 | { 17 | Misc.SendMessage("No target found"); 18 | Target.SetLast(last); 19 | return; 20 | } 21 | InvokeHonor(target); 22 | Attack(target); 23 | } 24 | 25 | private void InvokeHonor(Mobile target) 26 | { 27 | Player.InvokeVirtue("Honor"); 28 | Target.WaitForTarget(3000, true); 29 | Target.TargetExecute(target); 30 | } 31 | 32 | private void Attack(Mobile target) 33 | { 34 | if (Player.HasSecondarySpecial) 35 | { 36 | Player.WeaponSecondarySA(); 37 | } 38 | 39 | Misc.Pause(300); 40 | Player.Attack(target); 41 | Target.SetLast(target); 42 | } 43 | 44 | private Mobile PickTarget() 45 | { 46 | var filter = new Mobiles.Filter 47 | { 48 | IsGhost = 0, 49 | RangeMax = 10, 50 | RangeMin = 0, 51 | Friend = 0, 52 | Notorieties = new List 53 | { 54 | 3, 4, 5, 6 55 | } 56 | }; 57 | 58 | var mobs = Mobiles.ApplyFilter(filter); 59 | var orderedMobs = mobs.OrderBy(m => m.DistanceTo(Mobiles.FindBySerial(Player.Serial))).ToList(); 60 | 61 | foreach (var mob in orderedMobs) 62 | { 63 | Mobiles.WaitForProps(mob,1000); 64 | if (mob.Properties.Any(p => p.Number == 1049646)) 65 | { 66 | continue; 67 | } 68 | 69 | return mob; 70 | } 71 | 72 | return null; 73 | } 74 | } 75 | } -------------------------------------------------------------------------------- /RazorScripts/Honoring.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using RazorEnhanced; 5 | 6 | namespace Razorscripts 7 | { 8 | public class Honoring 9 | { 10 | public void Run() 11 | { 12 | var last = Target.GetLast(); 13 | 14 | var target = PickTarget(); 15 | if (target == null) 16 | { 17 | Misc.SendMessage("No target found"); 18 | Target.SetLast(last); 19 | return; 20 | } 21 | InvokeHonor(target); 22 | Attack(target); 23 | } 24 | 25 | private void InvokeHonor(Mobile target) 26 | { 27 | Player.InvokeVirtue("Honor"); 28 | Target.WaitForTarget(3000, true); 29 | Target.TargetExecute(target); 30 | } 31 | 32 | private void Attack(Mobile target) 33 | { 34 | if (Player.HasSecondarySpecial) 35 | { 36 | Player.WeaponSecondarySA(); 37 | } 38 | 39 | Misc.Pause(300); 40 | Player.Attack(target); 41 | Target.SetLast(target); 42 | } 43 | 44 | private Mobile PickTarget() 45 | { 46 | var filter = new Mobiles.Filter 47 | { 48 | IsGhost = 0, 49 | RangeMax = 10, 50 | RangeMin = 0, 51 | Friend = 0, 52 | Notorieties = new List 53 | { 54 | 3, 4, 5, 6 55 | }, 56 | CheckLineOfSight = true 57 | }; 58 | 59 | var mobs = Mobiles.ApplyFilter(filter); 60 | var orderedMobs = mobs.OrderBy(m => m.DistanceTo(Mobiles.FindBySerial(Player.Serial))).ToList(); 61 | 62 | foreach (var mob in orderedMobs) 63 | { 64 | Mobiles.WaitForProps(mob,1000); 65 | if (mob.Properties.Any(p => p.Number == 1049646)) 66 | { 67 | continue; 68 | } 69 | 70 | return mob; 71 | } 72 | 73 | return null; 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /RazorScripts/MultiQuestmark.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.SqlTypes; 4 | using System.Linq; 5 | using Assistant; 6 | using RazorEnhanced; 7 | using Item = RazorEnhanced.Item; 8 | 9 | namespace Razorscripts 10 | { 11 | public class MultiQuestmark 12 | { 13 | public void Run() 14 | { 15 | var player = Mobiles.FindBySerial(Player.Serial); 16 | Target.ClearLast(); 17 | var rows = Misc.WaitForContext(Player.Serial, 10000); 18 | foreach (var row in rows) 19 | { 20 | if (row.Entry.Equals("Toggle Quest Item", StringComparison.InvariantCultureIgnoreCase)) 21 | { 22 | Misc.ContextReply(Player.Serial, rows.IndexOf(row)); 23 | break; 24 | } 25 | } 26 | 27 | 28 | for (var i = 0; i <= 200; i++) 29 | { 30 | if (Target.GetLast() != 0) 31 | { 32 | break; 33 | } 34 | Misc.Pause(50); 35 | } 36 | 37 | if (Target.GetLast() == 0) 38 | { 39 | Misc.SendMessage("No item selected, aborting script",201); 40 | Target.Cancel(); 41 | return; 42 | } 43 | 44 | 45 | var itemSerial = Target.GetLast(); 46 | var targetItem = Player.Backpack.Contains.FirstOrDefault(i => i.Serial == itemSerial); 47 | 48 | if (targetItem != null) 49 | { 50 | var alreadyMarked = targetItem.Properties.Any(p => p.ToString() == "Quest Item"); 51 | 52 | var all = Player.Backpack.Contains.Where(i=> i.ItemID == targetItem.ItemID && i.Serial != itemSerial).ToList(); 53 | 54 | var filtered = new List(); 55 | if (alreadyMarked) 56 | { 57 | filtered = all.Where(i => i.Properties.Any(p => p.ToString() == "Quest Item")).ToList(); 58 | } 59 | else 60 | { 61 | filtered = all.Where(i => i.Properties.All(p => p.ToString() != "Quest Item")).ToList(); 62 | } 63 | 64 | Misc.Pause(100); 65 | 66 | foreach (var i in filtered) 67 | { 68 | Target.WaitForTarget(3000); 69 | Target.TargetExecute(i); 70 | } 71 | } 72 | 73 | Misc.SendMessage("Multi Toggle Complete, any further clicks will toggle only selected Item"); 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /RazorScripts/AnimalReleaser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Xml; 6 | using RazorEnhanced; 7 | 8 | namespace RazorScripts 9 | { 10 | public class AnimalReleaser 11 | { 12 | public void Run() 13 | { 14 | List _friendlies = Mobiles.ApplyFilter(new Mobiles.Filter 15 | { 16 | RangeMax = 100, 17 | RangeMin = 0, 18 | Notorieties = new List { 1,2}, 19 | }).Select(m => m.Serial).ToList(); 20 | 21 | while (true) 22 | { 23 | var friends = Mobiles.ApplyFilter(new Mobiles.Filter 24 | { 25 | RangeMax = 100, 26 | RangeMin = 0, 27 | Notorieties = new List { 1,2}, 28 | }); 29 | 30 | friends.ForEach(f => Mobiles.WaitForProps(f, 3000)); 31 | var pets = friends.Where(f => f.Properties.Any(p => p.Number == 502006)); 32 | var newFriendsList = new List(); 33 | // check if any pet.Setial is ot in the _friendlies list 34 | foreach (var pet in pets) 35 | { 36 | if (!_friendlies.Contains(pet.Serial)) 37 | { 38 | Misc.WaitForContext(pet, 500); 39 | Misc.PetRename(pet, "Tamed"); 40 | Misc.Pause(100); 41 | Misc.ContextReply(pet, 9); 42 | var ids = Gumps.AllGumpIDs(); 43 | var foundGunp = 0; 44 | while(foundGunp == 0) 45 | { 46 | var newIds = Gumps.AllGumpIDs(); 47 | //get Id's not earlier existing 48 | var diff = newIds.Except(ids).ToList(); 49 | 50 | foreach (var gid in diff) 51 | { 52 | var lines = Gumps.GetLineList(gid); 53 | if (lines.Any(l => l.Contains("release your pet"))) 54 | { 55 | foundGunp = (int)gid; 56 | break; 57 | } 58 | } 59 | Misc.Pause(50); 60 | } 61 | Gumps.SendAction((uint)foundGunp,2); 62 | Misc.Pause(200); 63 | } 64 | newFriendsList.Add(pet.Serial); 65 | } 66 | 67 | _friendlies = newFriendsList; 68 | Misc.Pause(1000); 69 | } 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /RazorScripts/ChestBreaker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.Remoting.Messaging; 5 | using RazorEnhanced; 6 | 7 | namespace Razorscripts 8 | { 9 | public class ChestBreaker 10 | { 11 | Journal _journal = new Journal(); 12 | private Target _tar = new Target(); 13 | 14 | public void Run() 15 | { 16 | var lastEntry = _journal.GetJournalEntry(null).LastOrDefault(); 17 | Misc.SendMessage(lastEntry.Text); 18 | var chestSerial = _tar.PromptTarget("Select Treasure Chest to break open"); 19 | if (chestSerial == 0) 20 | { 21 | Misc.SendMessage("No target selected", 201); 22 | return; 23 | } 24 | 25 | var lockPicks = DigDeep(Player.Backpack,Convert.ToInt32("0x14FC", 16)); 26 | if (lockPicks == null) 27 | { 28 | Misc.SendMessage("Unable to find Lock Picks", 201); 29 | } 30 | 31 | 32 | lastEntry = _journal.GetJournalEntry(lastEntry).LastOrDefault(); 33 | 34 | while (!_journal.GetJournalEntry(lastEntry).Any(j => (j.Text.ToLower().Contains("the lock quickly yields to your skill") || j.Text.ToLower().Contains("this does not appear to be locked")))) 35 | { 36 | Items.UseItem(lockPicks); 37 | Target.WaitForTarget(1000); 38 | Target.TargetExecute(chestSerial); 39 | Misc.Pause(1500); 40 | } 41 | 42 | 43 | lastEntry = _journal.GetJournalEntry(lastEntry).OrderBy(j => j.Timestamp).LastOrDefault(); 44 | 45 | while(!_journal.GetJournalEntry(lastEntry).Any(j => j.Text.ToLower().Contains("you successfully disarm the trap"))) 46 | { 47 | if (_journal.GetJournalEntry(lastEntry).Any(j => j.Type == "System" && j.Text.Contains("You must wait"))) 48 | { 49 | Misc.Pause(1000); 50 | lastEntry = _journal.GetJournalEntry(lastEntry).LastOrDefault(); 51 | continue; 52 | } 53 | 54 | Player.UseSkill("Remove Trap"); 55 | Target.WaitForTarget(3000); 56 | Target.TargetExecute(chestSerial); 57 | Misc.Pause(11250); 58 | } 59 | } 60 | 61 | 62 | private Item DigDeep(Item container, int itemId) 63 | { 64 | var found = container.Contains.FirstOrDefault(i => i.ItemID == itemId); 65 | if (found != null) 66 | { 67 | return found; 68 | } 69 | 70 | var subContainers = container.Contains.Where(c => c.IsContainer && c.Contains.Any() && c.Contains.First().Name != " (0000)").ToList(); 71 | foreach (var subcont in subContainers) 72 | { 73 | return DigDeep(subcont, itemId); 74 | } 75 | 76 | return null; 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /RazorScripts/IdocScanner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using RazorEnhanced; 6 | 7 | namespace RazorScripts 8 | { 9 | public class IdocScanner 10 | { 11 | private List idocSerialCache = new List(); 12 | private uint _guildGumpId = 1345112424; 13 | private List _trackings = new List(); 14 | 15 | public void Run() 16 | { 17 | try 18 | { 19 | UpdateGump(); 20 | while (Player.Connected) 21 | { 22 | List idocHouses = new List(); 23 | var signs = Items.ApplyFilter(new Items.Filter 24 | { 25 | RangeMax = 100, 26 | RangeMin = 0, 27 | Name = "A House Sign" 28 | }).ToList(); 29 | 30 | foreach (var sign in signs) 31 | { 32 | Items.WaitForProps(sign, 2000); 33 | var conditionProp = sign.Properties.FirstOrDefault(p => p.Number == 1062028); 34 | if (conditionProp?.Args == "#1043015") 35 | { 36 | idocHouses.Add(sign); 37 | } 38 | } 39 | 40 | var cachevalue = idocSerialCache.Sum(i => i.Serial); 41 | var newvalue = idocHouses.Sum(i => i.Serial); 42 | if (cachevalue != newvalue) 43 | { 44 | idocSerialCache = idocHouses; 45 | UpdateGump(); 46 | foreach (var arrow in _trackings) 47 | { 48 | Player.TrackingArrow((ushort)arrow.X, (ushort)arrow.Y, false); 49 | } 50 | foreach (var idoc in idocSerialCache) 51 | { 52 | _trackings.Add(new Tracker 53 | { 54 | X = idoc.Position.X+2, 55 | Y = idoc.Position.Y+2, 56 | Serial = idoc.Serial 57 | }); 58 | Player.TrackingArrow((ushort)(idoc.Position.X+2), (ushort)(idoc.Position.Y+2), true); 59 | } 60 | } 61 | 62 | Misc.Pause(1000); 63 | } 64 | } 65 | catch (ThreadAbortException) 66 | { 67 | //Silent 68 | } 69 | catch (Exception e) 70 | { 71 | Misc.SendMessage(e); 72 | throw; 73 | } 74 | finally 75 | { 76 | Gumps.CloseGump(_guildGumpId); 77 | } 78 | 79 | } 80 | 81 | private void UpdateGump() 82 | { 83 | var gump = Gumps.CreateGump(); 84 | gump.gumpId = _guildGumpId; 85 | gump.serial = (uint)Player.Serial; 86 | var height = idocSerialCache.Count*75; 87 | Gumps.AddImage(ref gump, 0, 0, 1764); 88 | Gumps.AddBackground(ref gump, 0, 49, 205, height, 1755); 89 | Gumps.AddLabel(ref gump, 60, 18, 400, "IDOC Scanner"); 90 | foreach (var sign in idocSerialCache) 91 | { 92 | Gumps.AddItem(ref gump, 5, 60 + idocSerialCache.IndexOf(sign) * 50, sign.ItemID); 93 | Gumps.AddLabel(ref gump, 40, 60 + idocSerialCache.IndexOf(sign) * 50, 0x7b, sign.Properties.FirstOrDefault(s => s.Number == 1061639)?.Args ?? "Unknown"); 94 | } 95 | Gumps.CloseGump(_guildGumpId); 96 | Gumps.SendGump(gump,500,500); 97 | } 98 | 99 | internal class Tracker 100 | { 101 | public int X { get; set; } 102 | public int Y { get; set; } 103 | public int Serial { get; set; } 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /RazorScripts/MineNode.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms.VisualStyles; 6 | using RazorEnhanced; 7 | 8 | namespace Razorscripts 9 | { 10 | public class MineNode 11 | { 12 | private List _tools = new List 13 | { 14 | 0x0E86, 15 | 0x0F39 16 | }; 17 | private Journal _journal = new Journal(); 18 | private Journal.JournalEntry _journalEntry = null; 19 | 20 | private int _firePetSerial = 0x026888DD; // set to fire beetle or fire fox serial, if you do not have one set to 0 21 | private int _packPetSerial = 0; // set to fire beetle or fire fox serial, if you do not have one set to 0 22 | 23 | private List directSmelts = new List 24 | { 25 | 0x19B8, 26 | 0x19BA, 27 | 0x19B9 28 | }; 29 | private List needs2Smelts = new List 30 | { 31 | 0x19B7 32 | }; 33 | 34 | public void Run() 35 | { 36 | _journalEntry = _journal.GetJournalEntry(_journalEntry).OrderBy(je => je.Timestamp).LastOrDefault(); 37 | while (true) 38 | { 39 | if(Player.Weight > Player.MaxWeight - 50) 40 | { 41 | if(_firePetSerial == 0) 42 | { 43 | if (Player.Weight >= Player.MaxWeight) 44 | { 45 | Player.HeadMessage(33, "Backpack is full, Stopping"); 46 | return; 47 | } 48 | } 49 | else 50 | { 51 | Smelt(); 52 | } 53 | 54 | if(_packPetSerial != 0) 55 | { 56 | var ores = Player.Backpack.Contains.Where(i => i.Name.ToLower().Contains("ore")).ToList(); 57 | var ingots = Player.Backpack.Contains.Where(i => i.ItemID == 0x1BF2).ToList(); 58 | 59 | var combined = ores.Concat(ingots).ToList(); 60 | 61 | foreach (var item in combined) 62 | { 63 | Items.Move(item, _packPetSerial, item.Amount); 64 | Misc.Pause(200); 65 | } 66 | } 67 | 68 | } 69 | 70 | var tool = Player.Backpack.Contains.FirstOrDefault(i => _tools.Contains(i.ItemID)); 71 | if (tool == null) 72 | { 73 | Player.HeadMessage(33, "No tool found"); 74 | return; 75 | } 76 | Target.TargetResource(tool, "ore"); 77 | var newLines = _journal.GetJournalEntry(_journalEntry); 78 | if (newLines.Any(j => j.Text.Contains("There is no metal here to mine"))) 79 | { 80 | return; 81 | } 82 | Misc.Pause(600); 83 | } 84 | } 85 | 86 | private void Smelt() 87 | { 88 | var potentialSmeltings = Player.Backpack.Contains.Where(i => i.Name.ToLower().Contains("ore")).ToList(); 89 | 90 | foreach (var ps in potentialSmeltings) 91 | { 92 | if (directSmelts.Contains(ps.ItemID)) 93 | { 94 | Items.UseItem(ps); 95 | Target.WaitForTarget(1000); 96 | Target.TargetExecute(_firePetSerial); 97 | Misc.Pause(500); 98 | continue; 99 | } 100 | if(needs2Smelts.Contains(ps.ItemID)) 101 | { 102 | if (ps.Amount >= 2) 103 | { 104 | Items.UseItem(ps); 105 | Target.WaitForTarget(1000); 106 | Target.TargetExecute(_firePetSerial); 107 | Misc.Pause(500); 108 | continue; 109 | } 110 | } 111 | } 112 | } 113 | } 114 | } -------------------------------------------------------------------------------- /RazorScripts/Targeting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using RazorEnhanced; 5 | 6 | namespace RazorScripts 7 | { 8 | public class Targeting 9 | { 10 | private bool _treasureHuntMode = true; 11 | 12 | private Journal _journal = new Journal(); 13 | private Journal.JournalEntry _lastEntry = null; 14 | public void Run() 15 | { 16 | Mobile _player = Mobiles.FindBySerial(Player.Serial); 17 | if (!Target.HasTarget()) 18 | { 19 | return; 20 | } 21 | 22 | if (_treasureHuntMode) 23 | { 24 | 25 | var lastObjSerial = Target.LastUsedObject(); 26 | var lastObject = Items.FindBySerial(lastObjSerial); 27 | if (lastObject != null && 28 | lastObject.Name.ToLower().Contains("lockpick")) 29 | { 30 | var chest = Items.FindByName("Treasure Chest", -1, -1, 3); 31 | if (chest != null) 32 | { 33 | Target.TargetExecute(chest); 34 | } 35 | } 36 | 37 | var newEntries = _journal.GetJournalEntry(_lastEntry).OrderBy(j => j.Timestamp).ToList(); 38 | if (newEntries.Any()) 39 | { 40 | var systemEntries = newEntries.Where(j => 41 | j.Type.Equals("System", StringComparison.InvariantCultureIgnoreCase)).ToList(); 42 | DateTime dateTimeBase = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); 43 | var recent = systemEntries.Where(se => (DateTime.Now - dateTimeBase.AddSeconds(se.Timestamp)).TotalSeconds < 5).ToList(); 44 | 45 | if (recent.Any(j => j.Text.Equals("Which trap will you attempt to disarm?",StringComparison.InvariantCultureIgnoreCase))) 46 | { 47 | var chest = Items.FindByName("Treasure Chest", -1, -1, 3); 48 | if (chest != null) 49 | { 50 | Target.TargetExecute(chest); 51 | } 52 | } 53 | } 54 | 55 | } 56 | 57 | if (Target.GetLast() != 0) 58 | { 59 | var filter = new Mobiles.Filter 60 | { 61 | IsGhost = 0, 62 | RangeMax = 10, 63 | RangeMin = 0, 64 | Friend = 0, 65 | Notorieties = new List 66 | { 67 | 3, 4, 5, 6 68 | }, 69 | CheckLineOfSight = true 70 | }; 71 | 72 | var tSerial = Target.GetLast(); 73 | 74 | var mobs = Mobiles.ApplyFilter(filter); 75 | var tar = mobs.FirstOrDefault(t => t.Serial == tSerial); 76 | 77 | if (tar != null) 78 | { 79 | Target.Last(); 80 | return; 81 | } 82 | 83 | if(mobs.Any()) 84 | { 85 | var sorted = mobs.OrderBy(m => m.DistanceTo(_player)).ToList(); 86 | 87 | Mobile selected = null; 88 | 89 | for (int i = 0; i < mobs.Count; i++) 90 | { 91 | selected = sorted[i]; 92 | Mobiles.WaitForProps(selected,1000); 93 | if (selected.Properties.All(p => p.Number != 1049646)) 94 | { 95 | break; 96 | } 97 | } 98 | 99 | if (selected != null) 100 | { 101 | Target.TargetExecute(selected); 102 | Target.SetLast(selected); 103 | 104 | return; 105 | } 106 | } 107 | 108 | 109 | if (tSerial != -1 && tSerial != 0 && tSerial != Player.Serial) 110 | { 111 | Target.Last(); 112 | } 113 | 114 | Target.Cancel(); 115 | } 116 | } 117 | } 118 | } -------------------------------------------------------------------------------- /RazorScripts/RaritySorter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text.RegularExpressions; 6 | using RazorEnhanced; 7 | 8 | namespace RazorScripts 9 | { 10 | public class RaritySorter 11 | { 12 | List _rules = new List(); 13 | 14 | public void Run() 15 | { 16 | var tar = new Target(); 17 | var raities = Enum.GetValues(typeof(ItemRarity)).Cast().ToList(); 18 | 19 | var sourceBag = tar.PromptTarget("Pick bag you wish to sort"); 20 | 21 | if (sourceBag != -1) 22 | { 23 | var source = Items.FindBySerial(sourceBag); 24 | if (!source.IsContainer) 25 | { 26 | Player.HeadMessage(33, "That s Not a suitable source"); 27 | } 28 | 29 | if (!source.Contains.Any(i => i.IsLootable)) 30 | { 31 | Player.HeadMessage(33, "That bag is empty"); 32 | } 33 | 34 | foreach (var rarity in raities) 35 | { 36 | var rarityName = SplitCamelCase(rarity.ToString()); 37 | var targetSerial = tar.PromptTarget($"Pick a bag for {rarityName}"); 38 | if (targetSerial != -1) 39 | { 40 | _rules.Add(new SortRule 41 | { 42 | TaretBag = Items.FindBySerial(targetSerial), 43 | Rarity = rarity 44 | }); 45 | } 46 | } 47 | 48 | Misc.SendMessage("Starting Sort Cycle", 0x99); 49 | 50 | foreach (var item in source.Contains.Where(i => i.IsLootable)) 51 | { 52 | Items.WaitForProps(item, 1000); 53 | var rarityProp = item.Properties.FirstOrDefault(p => p.Number == 1042971); 54 | if (rarityProp == null) 55 | { 56 | continue; 57 | } 58 | 59 | foreach (var rule in _rules) 60 | { 61 | //Find text between > and < and remove spaces 62 | var rarityString = ""; 63 | var cleaned = rarityProp.Args.Substring(rarityProp.Args.IndexOf(">", StringComparison.Ordinal) + 1).Replace(" ", ""); 64 | var length = cleaned.IndexOf("<", StringComparison.Ordinal); 65 | if (length == -1) 66 | { 67 | rarityString = cleaned.Substring(0); 68 | } 69 | else 70 | { 71 | rarityString = cleaned.Substring(0, cleaned.IndexOf("<", StringComparison.Ordinal)); 72 | } 73 | 74 | 75 | var matched = rarityString.Equals(rule.Rarity.ToString(), StringComparison.OrdinalIgnoreCase); 76 | if (matched) 77 | { 78 | Items.Move(item.Serial, rule.TaretBag.Serial, item.Amount); 79 | Misc.Pause(300); 80 | } 81 | } 82 | } 83 | 84 | Misc.SendMessage("Sorting Complete", 0x99); 85 | 86 | } 87 | 88 | 89 | } 90 | 91 | public string SplitCamelCase(string str) 92 | { 93 | return Regex.Replace( 94 | Regex.Replace( 95 | str, 96 | @"(\P{Ll})(\P{Ll}\p{Ll})", 97 | "$1 $2" 98 | ), 99 | @"(\p{Ll})(\P{Ll})", 100 | "$1 $2" 101 | ); 102 | } 103 | 104 | 105 | } 106 | 107 | internal class SortRule 108 | { 109 | public Item TaretBag { get; set; } 110 | public ItemRarity Rarity { get; set; } 111 | } 112 | 113 | internal enum ItemRarity 114 | { 115 | MinorMagicItem = 0, 116 | LesserMagicItem = 1, 117 | GreaterMagicItem = 2, 118 | MajorMagicItem = 3, 119 | MinorArtifact = 4, 120 | LesserArtifact = 5, 121 | GreaterArtifact = 6, 122 | MajorArtifact = 7, 123 | LegendaryArtifact = 8 124 | } 125 | } -------------------------------------------------------------------------------- /RazorScripts/Ranger.cs: -------------------------------------------------------------------------------- 1 | // This script is redundant as the features are not included in "TheRanger" instead along with the Reloader functionality 2 | 3 | 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading; 8 | using System.Windows.Forms.VisualStyles; 9 | using RazorEnhanced; 10 | 11 | namespace Razorscripts 12 | { 13 | public class Ranger 14 | { 15 | private uint _gumpId = 788435742; 16 | 17 | private List LoadedPowers = new List 18 | { 19 | new Power { Name = "None", Type = PowerType.None, GumpId = 21016 }, 20 | new Power { Name = "Armor Ingore", Type = PowerType.WeaponPrimary, GumpId = 20992 }, 21 | new Power { Name = "Lightening Strike", Type = PowerType.Bushido, GumpId = 21540 }, 22 | new Power { Name = "Momentum Strike", Type = PowerType.Bushido, GumpId = 21541 }, 23 | }; 24 | 25 | private Power _selectedPower; 26 | 27 | public void Run() 28 | { 29 | try 30 | { 31 | UpdateGump(); 32 | while (Player.Connected) 33 | { 34 | var reply = Gumps.GetGumpData(_gumpId); 35 | if (reply.buttonid > 0) 36 | { 37 | _selectedPower = LoadedPowers[reply.buttonid - 1]; 38 | UpdateGump(); 39 | 40 | reply.buttonid = -1; 41 | } 42 | 43 | PrimePower(); 44 | 45 | Misc.Pause(1000); 46 | } 47 | } 48 | catch (ThreadAbortException) 49 | { 50 | //Silent 51 | } 52 | catch (Exception e) 53 | { 54 | Misc.SendMessage(e); 55 | throw; 56 | } 57 | finally 58 | { 59 | Gumps.CloseGump(_gumpId); 60 | } 61 | } 62 | 63 | private void PrimePower() 64 | { 65 | if (_selectedPower == null) 66 | { 67 | return; 68 | } 69 | switch (_selectedPower.Type) 70 | { 71 | case PowerType.Bushido: 72 | if (!Player.BuffsExist(_selectedPower.Name)) 73 | { 74 | Spells.CastBushido(_selectedPower.Name); 75 | } 76 | break; 77 | case PowerType.WeaponPrimary: 78 | if (!Player.HasPrimarySpecial) 79 | { 80 | Player.WeaponPrimarySA(); 81 | } 82 | break; 83 | case PowerType.WeaponSecondary: 84 | if (!Player.HasSecondarySpecial) 85 | { 86 | Player.WeaponSecondarySA(); 87 | } 88 | break; 89 | case PowerType.None: 90 | default: 91 | break; 92 | } 93 | } 94 | 95 | private void UpdateGump() 96 | { 97 | var bar = Gumps.CreateGump(); 98 | bar.buttonid = -1; 99 | // bar.gumpId = ; 100 | bar.serial = (uint)Player.Serial; 101 | bar.gumpId = _gumpId; 102 | bar.x = 500; 103 | bar.y = 500; 104 | var powerIndex = 0; 105 | Gumps.AddBackground(ref bar, 0, 0, (LoadedPowers.Count*60-5), 55, 1755); 106 | foreach (var power in LoadedPowers) 107 | { 108 | var x = powerIndex * 60 + 5; 109 | var y = 5; 110 | Gumps.AddButton(ref bar, x,y,(int)power.GumpId,(int)power.GumpId,LoadedPowers.IndexOf(power)+1,1,0); 111 | Gumps.AddTooltip(ref bar, power.Name); 112 | powerIndex++; 113 | } 114 | 115 | if (_selectedPower != null) 116 | { 117 | var index = LoadedPowers.IndexOf(_selectedPower); 118 | Gumps.AddImage(ref bar, (60 * index-17),0,30071); 119 | } 120 | 121 | Gumps.CloseGump(_gumpId); 122 | Gumps.SendGump(bar, 500,500); 123 | } 124 | 125 | 126 | private class Power 127 | { 128 | public string Name { get; set; } 129 | public PowerType Type { get; set; } 130 | public int GumpId { get; set; } 131 | } 132 | 133 | private enum PowerType 134 | { 135 | WeaponPrimary, 136 | WeaponSecondary, 137 | Bushido, 138 | None 139 | } 140 | } 141 | } -------------------------------------------------------------------------------- /RazorScripts/ScriptMonitor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using RazorEnhanced; 6 | 7 | namespace RazorScripts 8 | { 9 | public class ScriptMonitor 10 | { 11 | private int _checksum; 12 | private uint _gumpId = 344763792; 13 | 14 | // please edit this section with your own scripts, it's important that you add the file extension as well sicne this is part of the key that Razor uses to identify the script. 15 | // The script you add must also already be added into the script grid in Razor Enhance for this to work. 16 | //Always add the line with false (this is used internally and should not be changed) 17 | private List _scriptStatus = new List() 18 | { 19 | new ScriptData("Lootmaster.cs"), 20 | new ScriptData("SlayerBar.cs", "Slayer Bar"), 21 | }; 22 | 23 | public void Run() 24 | { 25 | try 26 | { 27 | UpdateGump(); 28 | while (Player.Connected) 29 | { 30 | if (CheckScripts()) 31 | { 32 | UpdateGump(); 33 | } 34 | 35 | HandleReply(); 36 | 37 | Misc.Pause(1000); 38 | } 39 | } 40 | catch (ThreadAbortException) 41 | { 42 | // Silent 43 | } 44 | catch (Exception e) 45 | { 46 | Misc.SendMessage(e); 47 | throw; 48 | } 49 | finally 50 | { 51 | Gumps.CloseGump(_gumpId); 52 | } 53 | 54 | } 55 | 56 | private void HandleReply() 57 | { 58 | var reply = Gumps.GetGumpData(_gumpId); 59 | var replyIndex = reply.buttonid - 1; 60 | if (replyIndex >= 0) 61 | { 62 | UpdateGump(); 63 | reply.buttonid = -1; 64 | var script = _scriptStatus[replyIndex]; 65 | if (script.IsRunning) 66 | { 67 | Misc.ScriptStop(script.ScriptFile); 68 | } 69 | else 70 | { 71 | Misc.ScriptRun(script.ScriptFile); 72 | } 73 | Misc.Pause(500); 74 | 75 | UpdateGump(); 76 | } 77 | } 78 | 79 | private void UpdateGump() 80 | { 81 | var gump = Gumps.CreateGump(); 82 | gump.gumpId = _gumpId; 83 | gump.serial = (uint)Player.Serial; 84 | var height = _scriptStatus.Count * 20 + 30; 85 | Gumps.AddBackground(ref gump, 0, 0, 200, height, 1755); 86 | var index = 0; 87 | foreach (var script in _scriptStatus) 88 | { 89 | var marker = script.IsRunning ? 11400 : 11410; 90 | Gumps.AddButton(ref gump, 15, 15 + index * 20, marker,marker,index+1,1,0); 91 | Gumps.AddLabel(ref gump, 40,15 + index * 20, 0x7b, script.Name); 92 | index++; 93 | } 94 | 95 | Gumps.CloseGump(_gumpId); 96 | Gumps.SendGump(gump,500,500); 97 | } 98 | 99 | 100 | private bool CheckScripts() 101 | { 102 | var checkSum = 0; 103 | string checksumString = string.Empty; 104 | foreach (var script in _scriptStatus) 105 | { 106 | var result = Misc.ScriptStatus(script.ScriptFile); 107 | checksumString += result ? "1" : "0"; 108 | script.IsRunning = result; 109 | } 110 | 111 | checkSum = Convert.ToInt32(checksumString, 2); 112 | 113 | if (checkSum != _checksum) 114 | { 115 | _checksum = checkSum; 116 | return true; 117 | } 118 | 119 | return false; 120 | } 121 | 122 | private class ScriptData 123 | { 124 | public string Name { get; set; } 125 | public string ScriptFile { get; set; } 126 | public bool IsRunning { get; set; } 127 | 128 | //Chain this to the ScriptData(string scriptFile, name) constructor 129 | public ScriptData(string scriptFile) : this(scriptFile, scriptFile.Split('.').FirstOrDefault() ?? "N/A") 130 | { 131 | 132 | } 133 | 134 | public ScriptData(string scriptFile, string name) 135 | { 136 | Name = name; 137 | ScriptFile = scriptFile; 138 | } 139 | } 140 | } 141 | } -------------------------------------------------------------------------------- /RazorScripts/RazorScripts.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {06B26608-0E38-411D-98A9-4A8C9EC66030} 8 | Library 9 | Properties 10 | RazorScripts 11 | RazorScripts 12 | v4.8 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 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 | {b24e4fb1-4936-4544-9e88-f3ff9b04fdba} 94 | Razor 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /RazorScripts/RuneBookFinder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using RazorEnhanced; 5 | 6 | namespace RazorScripts 7 | { 8 | public class RuneBookFinder 9 | { 10 | private int GumpId = 4598751; 11 | private Item CurrentBook = null; 12 | private List CurrentHits = new List(); 13 | 14 | private readonly List Messages = new List 15 | { 16 | "Pssst...over here...", 17 | "MARCO!", 18 | "Come closer little one...", 19 | }; 20 | public void Run() 21 | { 22 | Gumps.CloseGump((uint)GumpId); 23 | ShowGump(); 24 | while (true) 25 | { 26 | var sd = Gumps.GetGumpData((uint)GumpId); 27 | if (sd.buttonid != -1) 28 | { 29 | if (sd.buttonid == 100) 30 | { 31 | var searchPrompt = sd.text.FirstOrDefault(); 32 | FindBooks(searchPrompt); 33 | } 34 | else if (sd.buttonid == 200) 35 | { 36 | CurrentBook = null; 37 | CurrentHits.Clear(); 38 | sd.text.Clear(); 39 | } 40 | else 41 | { 42 | 43 | CurrentBook = CurrentHits.FirstOrDefault(b => b.Serial == sd.buttonid); 44 | 45 | if (CurrentBook != null) 46 | { 47 | Items.Message(CurrentBook.Serial, 0x1d,GetItemMessage()); 48 | var hue = CurrentBook.Hue; 49 | // for(var i = 0; i<15; i++) 50 | // { 51 | // var curHue = i % 2 == 0 ? 0x7b : hue; 52 | // Items.SetColor(CurrentBook.Serial, curHue); 53 | // Misc.Pause(100); 54 | // } 55 | // Items.SetColor(CurrentBook.Serial, hue); 56 | } 57 | else 58 | { 59 | Misc.SendMessage("Book Missing"); 60 | } 61 | } 62 | sd.buttonid = -1; 63 | ShowGump(); 64 | } 65 | Misc.Pause(100); 66 | } 67 | } 68 | 69 | private void FindBooks(string description) 70 | { 71 | CurrentHits = new List(); 72 | if (string.IsNullOrEmpty(description)) 73 | { 74 | return; 75 | } 76 | 77 | var books = Items.ApplyFilter(new Items.Filter 78 | { 79 | RangeMin = 0, 80 | RangeMax = 10, 81 | }).Where(b => b.Name.Equals("Runebook", StringComparison.Ordinal) || b.Name.Equals("Runic Atlas", StringComparison.OrdinalIgnoreCase)).ToList(); 82 | 83 | books.ForEach(b => Items.WaitForProps(b, 1000)); 84 | 85 | CurrentHits.AddRange(books.Where(b => b.Properties.Any(p => p.ToString().ToLower().Contains(description.ToLower())))); 86 | } 87 | 88 | private void ShowGump() 89 | { 90 | var searchGump = Gumps.CreateGump(); 91 | searchGump.gumpId = (uint)GumpId; 92 | searchGump.serial = (uint)Player.Serial; 93 | Gumps.AddImage(ref searchGump, 0,0,206); 94 | Gumps.AddImage(ref searchGump, 44,0,201); 95 | Gumps.AddImage(ref searchGump, 471,0,207); 96 | Gumps.AddImageTiled(ref searchGump, 0,44,44,GetHeight(), 202); 97 | Gumps.AddImageTiled(ref searchGump, 471,44,44,GetHeight(), 203); 98 | Gumps.AddImage(ref searchGump, 0,44+GetHeight(),204); 99 | Gumps.AddImage(ref searchGump, 44,44+GetHeight(),233); 100 | Gumps.AddImage(ref searchGump, 471,44+GetHeight(),205); 101 | Gumps.AddImageTiled(ref searchGump, 44,44,427,GetHeight(), 200); 102 | Gumps.AddHtml(ref searchGump, 44,24,427,20, "

Runebook Finder

", false, false); 103 | Gumps.AddImage(ref searchGump, 57, 60, 1802); 104 | Gumps.AddImageTiled(ref searchGump, 65, 60, 334, 16,1803); 105 | Gumps.AddImage(ref searchGump, 399, 60, 1804); 106 | Gumps.AddTextEntry(ref searchGump, 65,60,342,32,3171,1,""); 107 | Gumps.AddButton(ref searchGump, 409, 60, 12000,12001,100,1,0); 108 | Gumps.AddButton(ref searchGump, 409, 80, 12003,12004,200,1,0); 109 | 110 | var orderedHits = CurrentHits.OrderBy(GetText).ToList(); 111 | 112 | foreach (var hit in orderedHits) 113 | { 114 | var index = orderedHits.IndexOf(hit); 115 | var baseIndex = CurrentHits.IndexOf(hit); 116 | Gumps.AddButton(ref searchGump, 20, 100 + index * 30, 4005, 4007, hit.Serial, 1, 0); 117 | Gumps.AddLabel(ref searchGump, 60, 100 + index * 30, 0, GetText(hit)); 118 | } 119 | 120 | 121 | Gumps.SendGump(searchGump,500,500); 122 | } 123 | 124 | private string GetText(Item book) 125 | { 126 | return book.Properties.FirstOrDefault(b => b.Number == 1042971)?.ToString(); 127 | } 128 | 129 | private int GetHeight() 130 | { 131 | return CurrentHits.Count * 30 + 50; 132 | } 133 | 134 | private string GetItemMessage() 135 | { 136 | return Messages[new Random().Next(0, Messages.Count)]; 137 | } 138 | } 139 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RazorEnhancedScripts 2 | 3 | This is my bundle of script for Razor Enhanced, Some are useful, some not so much, as they are designed for a very specific purpose upon request from someone. 4 | 5 | Below you can see some highlights of the larger scripts I have made. 6 | 7 | Some have a more detailed Wiki page for further documentation. 8 | 9 | If you have feature requests to any of my scripts or you find a bug, please report them as issues, adding an appropriate Label would be helpful 10 | 11 | ## LootMaster 12 | 13 | This is an autolooter that uses a set of rules, each rule has its own settings, and each characters has his or hers own ruleset 14 | More info on how this works can be found here 15 | https://gamebible.net/wiki/doku.php?id=lootmaster 16 | 17 | ## SlayerBar 18 | 19 | This is a hotbar script. it will look though your skills to find your primary damage skill, 20 | then check your inventory for a bag that contains slayers on weapons that matches that skill. 21 | 22 | It will then generate a bar with buttons, clicking these buttons will swap to the corresponding slayer, and return your current weapon to the previously designated slayer bag. 23 | 24 | It's highly recomended to put all your players in a designated bag, rather than having them loose in your backpack, The backpack works, 25 | but if you might have multiple slayers of the same type and thus the script would list both. 26 | 27 | ## RuneMaster 28 | 29 | RuneMaster is a 1-click travel script. 30 | At first launch it will scan your backpack for rune books and atlases, including those in your strap and build a database of the rnes you have. 31 | These can be grouped by book or map, or displayed as a single list. 32 | They can be displayed alphabetically or by the location in their respective books. 33 | It supports Recall, Gate Travel, and Sacred Journey. depending on your skill levels. 34 | 35 | newly added runes can be synced by using the "Update Runes" button in the options panel. 36 | Runes will display in color (optional) depending on the map they are on. 37 | 38 | It also supports a search function for those with a large amount of runes stored for simplified use. 39 | 40 | 41 | ## MiningMaster 42 | 43 | This is a mining automation script. 44 | It allows the player to record a path and store the locations where the user mines. 45 | You may then save this path and mark a rune for it with the same name(this can be done automatically). 46 | These paths can later be replayed automatically. 47 | 48 | The script will handle smelting, and supports the use of mining satchel it can also be toggled to use Bag of sending to send the largest ingot pile to your bank. 49 | This happens when you go over your carry capacity after the smelting process. 50 | 51 | The script does not handle ambushes or approaching players, while the script can run unattended it's not recommended, and may violate server rules, 52 | 53 | **please always follow the rules of the server you are playing on.** 54 | 55 | ## ShadowGuard 56 | 57 | A semi-automated helper script for Shadowguard. 58 | This script will automatically detect the current room you are in and load the corresponding helper. 59 | This script will automate... 60 | - Automatically pickup and throw bottle in the bar 61 | - Automatically detect the Tree and Apple matches in Orchard 62 | - Automatically pick up, purify and throw phylacteries in the Armory 63 | - Automatically detect, calculate, pick up and place canal pieces in the Fountain 64 | - Automaticaly pickup wings in the Belfry, a button will show in the gump that allows you to use the wing to fly up to the dragon 65 | 66 | Each room has a gump extension attached to it that will activly display room data, such as currently held bottles or phillacteries, or the current canal pieces remaining 67 | 68 | This script is extremely powerful for those who want to run Shadowguard. 69 | This script is aimed at people who has done several runs of Shadowguard and know the mechanics of the rooms and has experienced this awesome dungeon. 70 | 71 | **Do not use this script if...** 72 | - You have never done Shadowguard before 73 | - If your server has a rule against automation 74 | 75 | This script also is a great tool for people with any type of disability that prevents them from playing the game normally, 76 | such as a motor disability or visual impairment since it removes the tedious tasks of clicking items in fast succession. 77 | 78 | ## The Ranger 79 | 80 | This is a script designed towards archers. 81 | It will track thr ammo in your quiver, and allows for automatic restocking of your quiver from your backpack. 82 | It can also be manually reloaded at any time. 83 | Changing between bows and crossbows will automatically restock the ammo in your quiver for the equipped weapon. 84 | 85 | It will check the weapon you have equipped along with the skills you have to present a list of special attacks available 86 | and keep the selected one primed at all times, removing the need to constantly priming things like Armor ignore or Lightening Strike 87 | 88 | ## HealMaster 89 | 90 | A simple script that will heal you when run (best to bind to a keymap) the script will check your skills and mana in order to pick the best healing option for you 91 | Examples : if the player has high enough magery for a greater heal it will cast greater heal if enough health is missing, else it will cast normal heal. 92 | If your health pool is almost full it will cast a normal heal. 93 | 94 | Other healing options supported are Close Wounds for Chivalry and Bandages for dexers. 95 | It also supports healing potions if no other option is available. 96 | 97 | If the player is poisoned the script will instead use spells such as Cure or Cleanse By Fire. 98 | Support for Cleansing Winds, Gift of Renewal and Gift of Life is coming shortly 99 | 100 | ## CasterTrain 101 | 102 | A rather simple script in itsself. 103 | Load thr script, enter the target Skill level of each caster related skills you want to train, 104 | and the script will automatically train them for you. 105 | 106 | A full LRC suit is recommended, as the script will not check for reagents. 107 | The script has built in safety for killing yourself and it will meditate when needed. 108 | 109 | Supported skills are: 110 | - Magery 111 | - Necromancy 112 | - Chivalry 113 | - Mysticism 114 | - Spellweaving 115 | 116 | The following skills will gain naturally if not locked 117 | - Focus 118 | - Meditation -------------------------------------------------------------------------------- /RazorScripts/HealMaster.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Linq; 4 | using RazorEnhanced; 5 | 6 | namespace Razorscripts 7 | { 8 | public class HealMaster 9 | { 10 | public void Run() 11 | { 12 | try 13 | { 14 | var journal = new Journal(); 15 | var counter = 0; 16 | bool retry = false; 17 | do 18 | { 19 | var lastJournal = journal.GetJournalEntry(null).OrderBy(j => j.Timestamp).LastOrDefault(); 20 | if (Player.Poisoned) 21 | { 22 | if (Player.Hits < 15 && Player.GetRealSkillValue("SpiritSpeak") >= 100) 23 | { 24 | var lastNecro = Misc.ReadSharedValue("HealSelf:LastSS").ToString(); 25 | //Check if value is not null and is dateTime 26 | if (lastNecro != null && lastNecro != "0") 27 | { 28 | var lastNecroTime = DateTime.Parse(lastNecro, CultureInfo.InvariantCulture); 29 | if (lastNecroTime.AddSeconds(5) <= DateTime.Now) 30 | { 31 | Misc.SetSharedValue("HealSelf:LastSS", DateTime.Now.ToString(CultureInfo.InvariantCulture)); 32 | Player.UseSkill("SpiritSpeak"); 33 | } 34 | } 35 | else 36 | { 37 | Misc.SetSharedValue("HealSelf:LastSS", DateTime.Now.ToString(CultureInfo.InvariantCulture)); 38 | Player.UseSkill("SpiritSpeak"); 39 | } 40 | } 41 | 42 | Self.Cure(); 43 | } 44 | else 45 | { 46 | if (Self.NeedHealing) 47 | { 48 | Self.Heal(); 49 | } 50 | else 51 | { 52 | Helper.Log("You are already at full health"); 53 | break; 54 | } 55 | } 56 | 57 | if (journal.GetJournalEntry(lastJournal).Any(j => j.Text.ToLower().Contains("you must wait"))) 58 | { 59 | retry = true; 60 | Misc.Pause(100); 61 | } 62 | } while (retry && counter++ < 5); 63 | 64 | Misc.Pause(300); 65 | } 66 | catch (Exception e) 67 | { 68 | Misc.SendMessage(e); 69 | } 70 | } 71 | } 72 | } 73 | 74 | 75 | internal static class Helper 76 | { 77 | public static void Log(object messageString) 78 | { 79 | Misc.SendMessage(messageString, 201); 80 | } 81 | } 82 | 83 | public class Self : Player 84 | { 85 | private static uint USerial => (uint)Serial; 86 | public static bool NeedHealing => HitsMax > Hits; 87 | public static readonly bool ForceBands = GetRealSkillValue("Healing") >= 80; 88 | public static void Cure() 89 | { 90 | Misc.SetSharedValue("Lootmaster:Pause", 2000); 91 | var lastpotstring = Misc.ReadSharedValue("Healmaster:LastPotion").ToString(); 92 | DateTime? lastpot = lastpotstring != "0" ? DateTime.Parse(lastpotstring, CultureInfo.InvariantCulture) : null as DateTime?; 93 | var curepot = Items.FindByID(3847, 0, Backpack.Serial); 94 | var bands = Items.FindByID(3617, 0, Backpack.Serial); 95 | var blockQuickpot = lastpot != null && (DateTime.UtcNow - lastpot).Value.TotalSeconds < 5; 96 | 97 | if(!blockQuickpot && curepot != null && Hits < 20) 98 | { 99 | Items.UseItem(curepot); 100 | Misc.SetSharedValue("Healmaster:LastPotion", DateTime.Now.ToString(CultureInfo.InvariantCulture)); 101 | } 102 | else if (!ForceBands && GetRealSkillValue("Magery") >= 40) 103 | { 104 | Spells.CastMagery("Cure", USerial); 105 | } 106 | else if (!ForceBands && GetRealSkillValue("Chivalry") >= 40) 107 | { 108 | Spells.CastChivalry("Cleanse By Fire", USerial); 109 | } 110 | else if(bands != null) 111 | { 112 | Items.UseItem(bands, (int)USerial); 113 | } 114 | else if (curepot != null) 115 | { 116 | Items.UseItem(curepot); 117 | } 118 | 119 | } 120 | public static void Heal() 121 | { 122 | Misc.SetSharedValue("Lootmaster:Pause", 2000); 123 | var healpot = Items.FindByID(3852, 0, Backpack.Serial); 124 | var barrabPot = Items.FindByID(3846, 1272, Backpack.Serial); 125 | var bands = Items.FindByID(3617, 0, Backpack.Serial); 126 | var lastpotString = Misc.ReadSharedValue("Healmaster:LastPotion").ToString(); 127 | DateTime? lastPot = lastpotString != "0" ? DateTime.Parse(lastpotString) : null as DateTime?; 128 | var lastBarabPotString = Misc.ReadSharedValue("Healmaster:LastBarrabPotion").ToString(); 129 | DateTime? lastBarabPot = lastpotString != "0" ? DateTime.Parse(lastpotString) : null as DateTime?; 130 | var blockQuickpot = lastPot != null && (DateTime.UtcNow - lastPot).Value.TotalSeconds < 5; 131 | var blockBarrabPot = true;//lastPot != null && (DateTime.UtcNow - lastPot).Value.TotalSeconds < 1200; 132 | 133 | //Todo, check LRC Value in order to validate if the player might have died and won't have regs, if so check for Spirit Speak Skill to heal 134 | if(!blockBarrabPot && barrabPot != null && Hits < 40) 135 | { 136 | Items.UseItem(healpot); 137 | Misc.SetSharedValue("Healmaster:LastPotion", DateTime.UtcNow); 138 | } 139 | if(!blockBarrabPot && healpot != null && Hits < 20) 140 | { 141 | Items.UseItem(healpot); 142 | Misc.SetSharedValue("Healmaster:LastPotion", DateTime.UtcNow); 143 | } 144 | else if (!ForceBands && GetRealSkillValue("Magery") > 30) 145 | { 146 | if (GetRealSkillValue("Magery") > 60 && HitsMax - Hits > 20) 147 | { 148 | Spells.CastMagery("Greater Heal", USerial); 149 | } 150 | 151 | else 152 | { 153 | Spells.CastMagery("Heal", USerial); 154 | } 155 | 156 | } 157 | else if (!ForceBands && GetRealSkillValue("Chivalry") > 60 && HitsMax - Hits > 20) 158 | { 159 | Spells.CastChivalry("Close Wounds", USerial); 160 | } 161 | else if(bands != null) 162 | { 163 | Items.UseItem(bands, (int)USerial); 164 | } 165 | else if (healpot != null) 166 | { 167 | Items.UseItem(healpot); 168 | Misc.SetSharedValue("Healmaster:LastPotion", DateTime.UtcNow); 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /RazorScripts/Butcher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using RazorEnhanced; 4 | using System.Linq; 5 | 6 | namespace Razorscripts 7 | { 8 | public class Butcher 9 | { 10 | private readonly bool TakeLeather = false; //should we keep leather 11 | private readonly bool TakeMeat = false; //should we keep meats 12 | private readonly bool TakeFeathers = false; //should we keep feathers 13 | private readonly bool TakeWool = false; //should we keep Wool 14 | private readonly bool TakeScales = true; //should we keep scales 15 | private readonly bool TakeBlood = true; //should we keep blood 16 | 17 | private int _leather = 0x1081; 18 | private int _hide = 0x1079; 19 | private int _meat = 0x09F1; 20 | private int _rotwormMeat = 0x2DB9; 21 | private int _pultry = 0x09B9; 22 | private int _feathers = 0x1BD1; 23 | private int _wool = 0x0DF8; 24 | private int _lambLeg = 0x1609; 25 | private int _dragonscale = 0x26B4; 26 | private int _dragonblood = 0x4077; 27 | 28 | private readonly List _daggers = 29 | new[] 30 | { 31 | 0x2D20, //Harvesters Blade 32 | 0x0F52, //Dagger 33 | 0x0EC4, //Skinning Knife 34 | 0x0EC3, //Butchers Cleaver 35 | 0x13F6, //Butchers Knife 36 | 0x13B6, //Butchers Knife 37 | }.ToList(); 38 | 39 | public void Run() 40 | { 41 | Item dagger = null; 42 | 43 | foreach (var dagId in _daggers) 44 | { 45 | dagger = DigDeep(Player.Backpack, dagId); 46 | if (dagger != null) 47 | { 48 | break; 49 | } 50 | } 51 | 52 | 53 | if (dagger == null || dagger.ItemID != _daggers.First()) //we didn't find dagger in pack, or the dagger was not Harvester 54 | { 55 | var rHand = Player.GetItemOnLayer("RightHand"); 56 | var lHand = Player.GetItemOnLayer("LeftHand"); 57 | 58 | foreach (var dag in _daggers) 59 | { 60 | if (rHand?.ItemID == dag) 61 | { 62 | dagger = rHand; 63 | break; 64 | } 65 | 66 | if (lHand?.ItemID == dag) 67 | { 68 | dagger = lHand; 69 | break; 70 | } 71 | } 72 | } 73 | 74 | if (dagger == null) 75 | { 76 | Misc.SendMessage("Unable to locate preset dagger", 201); 77 | return; 78 | } 79 | 80 | var isHarvestersBlade = dagger.Name == "Harvester's Blade"; 81 | 82 | var corpses = Items.ApplyFilter(new Items.Filter 83 | { 84 | IsCorpse = 1, 85 | RangeMax = 2, 86 | RangeMin = 0 87 | }); 88 | 89 | if (corpses == null || !corpses.Any()) 90 | { 91 | return; 92 | } 93 | 94 | foreach (var corpse in corpses) 95 | { 96 | Items.UseItem(dagger); 97 | Target.WaitForTarget(2000); 98 | Target.TargetExecute(corpse); 99 | Misc.Pause(500); 100 | 101 | if (isHarvestersBlade) continue; 102 | if (TakeFeathers) 103 | { 104 | LootItems(corpse, _feathers); 105 | } 106 | 107 | if (TakeMeat) 108 | { 109 | LootItems(corpse, _meat); 110 | LootItems(corpse, _rotwormMeat); 111 | LootItems(corpse, _pultry); 112 | LootItems(corpse, _lambLeg); 113 | } 114 | 115 | if (TakeLeather) 116 | { 117 | LootItems(corpse, _hide); 118 | } 119 | 120 | if (TakeWool) 121 | { 122 | LootItems(corpse, _wool); 123 | } 124 | 125 | if (TakeScales) 126 | { 127 | LootItems(corpse, _dragonscale); 128 | } 129 | 130 | if (TakeBlood) 131 | { 132 | LootItems(corpse, _dragonblood, "Dragon's Blood"); 133 | } 134 | } 135 | 136 | if (isHarvestersBlade) 137 | { 138 | var dumperCorpse = corpses.First(); 139 | 140 | if (!TakeFeathers) 141 | { 142 | DumpItem(dumperCorpse, _feathers); 143 | Misc.Pause(200); 144 | } 145 | 146 | if (!TakeLeather) 147 | { 148 | DumpItem(dumperCorpse, _leather); 149 | Misc.Pause(200); 150 | } 151 | 152 | if (!TakeMeat) 153 | { 154 | DumpItem(dumperCorpse, _meat); 155 | Misc.Pause(200); 156 | DumpItem(dumperCorpse, _pultry); 157 | Misc.Pause(200); 158 | DumpItem(dumperCorpse, _lambLeg); 159 | Misc.Pause(200); 160 | DumpItem(dumperCorpse, _rotwormMeat); 161 | Misc.Pause(200); 162 | } 163 | 164 | if (!TakeWool) 165 | { 166 | DumpItem(dumperCorpse, _wool); 167 | Misc.Pause(200); 168 | } 169 | 170 | if (!TakeScales) 171 | { 172 | DumpItem(dumperCorpse, _dragonscale); 173 | Misc.Pause(200); 174 | } 175 | 176 | if (!TakeBlood) 177 | { 178 | DumpItem(dumperCorpse, _dragonblood, "Dragon's Blood"); 179 | Misc.Pause(200); 180 | } 181 | } 182 | } 183 | 184 | private Item DigDeep(Item container, int itemId) 185 | { 186 | var found = container.Contains.FirstOrDefault(i => i.ItemID == itemId); 187 | if (found != null) 188 | { 189 | return found; 190 | } 191 | 192 | var subContainers = container.Contains.Where(c => c.IsContainer && c.Contains.Any() && c.Contains.First().Name != " (0000)").ToList(); 193 | foreach (var subcont in subContainers) 194 | { 195 | return DigDeep(subcont, itemId); 196 | } 197 | 198 | return null; 199 | } 200 | 201 | private void LootItems(Item corpse, int itemId, string name = null) 202 | { 203 | var stack = corpse.Contains.Where(i => i.ItemID == itemId && (string.IsNullOrEmpty(name) || i.Name.Contains(name))).ToList(); 204 | foreach (var feather in stack) 205 | { 206 | Items.Move(feather, Player.Backpack.Serial, feather?.Amount ?? int.MaxValue); 207 | Misc.Pause(100); 208 | } 209 | } 210 | 211 | private void DumpItem(Item corpse, int itemId, string name = null) 212 | { 213 | 214 | var dumpThese = Player.Backpack.Contains.Where(i => i.ItemID == itemId && (string.IsNullOrEmpty(name) || i.Name.Contains(name))).ToList(); 215 | foreach (var dump in dumpThese) 216 | { 217 | 218 | Items.Move(dump, corpse, dump?.Amount ?? int.MaxValue); 219 | } 220 | } 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /RazorScripts/Debugger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Dynamic; 4 | using System.Globalization; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Reflection; 8 | using System.Windows.Forms; 9 | using RazorEnhanced; 10 | using RazorEnhanced.UOScript; 11 | 12 | namespace Razorscripts 13 | { 14 | public class Debugger 15 | { 16 | internal class XYPos 17 | { 18 | public int X { get; set; } 19 | public int Y { get; set; } 20 | 21 | public XYPos(int x, int y) 22 | { 23 | X = x; 24 | Y = y; 25 | 26 | 27 | } 28 | 29 | public decimal GetDistance() 30 | { 31 | var a = Math.Abs(Player.Position.X - X); 32 | var b = Math.Abs(Player.Position.Y - Y); 33 | var c = Math.Sqrt(Math.Pow(a, 2) + Math.Pow(b, 2)); 34 | return (decimal) c; 35 | } 36 | } 37 | public void Run() 38 | { 39 | var c1 = Mobiles.FindBySerial(0x000061AB); 40 | var c1field = GetAvailablePosition(c1.Position); 41 | var cloststc1 = GetClosestPosition(c1field); 42 | PathFinding.PathFindTo(cloststc1.X, cloststc1.Y); 43 | 44 | 45 | 46 | // var tar = new Target(); 47 | // var ser = tar.PromptTarget(); 48 | // var itm = Items.FindBySerial(ser); 49 | // Items.WaitForProps(itm, 1000); 50 | // foreach (var prop in itm.Properties) 51 | // { 52 | // Misc.SendMessage($"{prop.Number} {prop.ToString()}"); 53 | // } 54 | 55 | //FocusStrike(); 56 | //PullWeeds(); 57 | // TrainChiv(); 58 | // TrainNecro(); 59 | // TrainBushido(); 60 | } 61 | 62 | private XYPos GetClosestPosition(List field) 63 | { 64 | return field.OrderBy(p => p.GetDistance()).First(); 65 | } 66 | 67 | private List GetAvailablePosition(Point3D pos) 68 | { 69 | var result = new List(); 70 | result.Add(new XYPos(pos.X, pos.Y)); 71 | result.Add(new XYPos(pos.X, pos.Y+1)); 72 | result.Add(new XYPos(pos.X, pos.Y-1)); 73 | result.Add(new XYPos(pos.X+1, pos.Y)); 74 | result.Add(new XYPos(pos.X+1, pos.Y+1)); 75 | result.Add(new XYPos(pos.X+1, pos.Y-1)); 76 | result.Add(new XYPos(pos.X-1, pos.Y)); 77 | result.Add(new XYPos(pos.X-1, pos.Y+1)); 78 | result.Add(new XYPos(pos.X-1, pos.Y-1)); 79 | 80 | return result; 81 | } 82 | 83 | private int? ExampleGetMobId() 84 | { 85 | 86 | var mobs = Mobiles.ApplyFilter(new Mobiles.Filter 87 | { 88 | RangeMax = 12, 89 | RangeMin = 0, 90 | }); 91 | 92 | return mobs.FirstOrDefault(m => m.Name == "MyPetname" && m.MobileID == 0x000)?.Serial; 93 | } 94 | 95 | private void PullWeeds() 96 | { 97 | while (true) 98 | { 99 | var weeds = Items.ApplyFilter(new Items.Filter 100 | { 101 | RangeMin = 0, 102 | RangeMax = 1, 103 | Name = "Creepy weeds" 104 | }); 105 | foreach (var weed in weeds) 106 | { 107 | Items.UseItem(weed); 108 | Misc.Pause(100); 109 | } 110 | } 111 | } 112 | 113 | private void TrainChiv() 114 | { 115 | var skill = Player.GetRealSkillValue("Chivalry"); 116 | while (skill < 100) 117 | { 118 | if (Player.Hits < 20) 119 | { 120 | WaitTillHealed(); 121 | } 122 | if (skill <= 50) 123 | { 124 | Spells.CastChivalry("Consecrate Weapon"); 125 | } 126 | else if (skill <= 70) 127 | { 128 | Spells.CastChivalry("Enemy Of One"); 129 | } 130 | else if (skill <= 90) 131 | { 132 | Spells.CastChivalry("Holy Light"); 133 | } 134 | else 135 | { 136 | Spells.CastChivalry("Noble Sacrifice"); 137 | } 138 | 139 | Misc.Pause(4000); 140 | skill = Player.GetRealSkillValue("Chivalry"); 141 | } 142 | } 143 | 144 | private void WaitTillHealed() 145 | { 146 | while (Player.Hits < Player.HitsMax) 147 | { 148 | Misc.Pause(5000); 149 | } 150 | } 151 | 152 | private void TrainNecro() 153 | { 154 | var skill = Player.GetRealSkillValue("Necromancy"); 155 | var player = Mobiles.FindBySerial(Player.Serial); 156 | while (skill < 100) 157 | { 158 | if (Player.Hits < 20) 159 | { 160 | while (Player.Buffs.Any(b => b.Equals("Lich Form", StringComparison.OrdinalIgnoreCase))) 161 | { 162 | Spells.CastNecro("Lich Form"); 163 | Misc.Pause(5000); 164 | } 165 | 166 | WaitTillHealed(); 167 | } 168 | 169 | if (skill < 50) 170 | { 171 | Spells.CastNecro("Pain Spike"); 172 | Target.WaitForTarget(2000); 173 | Target.TargetExecute(player); 174 | } 175 | else if (skill < 70) 176 | { 177 | Spells.CastNecro("Horrific Beast"); 178 | } 179 | else if (skill == 70 && Player.Buffs.Any(b => b.ToLower().Contains("beast"))) 180 | { 181 | // Spells.CastNecro("Horrific Beast"); 182 | } 183 | else if (skill < 90) 184 | { 185 | Spells.CastNecro("Wither"); 186 | } 187 | else 188 | { 189 | Spells.CastNecro("Lich Form"); 190 | } 191 | 192 | Misc.Pause(5000); 193 | skill = Player.GetRealSkillValue("Necromancy"); 194 | } 195 | } 196 | 197 | private void FocusStrike() 198 | { 199 | while (true) 200 | { 201 | if (!Player.SpellIsEnabled("Focus Attack") && Player.Mana >= 10) 202 | { 203 | Spells.CastNinjitsu("Focus Attack"); 204 | } 205 | Misc.Pause(200); 206 | } 207 | 208 | } 209 | 210 | private void TrainBushido() 211 | { 212 | var skill = Player.GetRealSkillValue("Bushido"); 213 | while (skill < 100) 214 | { 215 | if (Player.Hits < 20) 216 | { 217 | WaitTillHealed(); 218 | } 219 | if (skill <= 60) 220 | { 221 | Spells.CastBushido("Confidence"); 222 | } 223 | else if (skill <= 75) 224 | { 225 | Spells.CastBushido("Counter Attack"); 226 | } 227 | else 228 | { 229 | Spells.CastBushido("Evasion"); 230 | Misc.Pause(16000); 231 | } 232 | 233 | Misc.Pause(4000); 234 | skill = Player.GetRealSkillValue("Bushido"); 235 | } 236 | } 237 | 238 | private void Search(Item container) 239 | { 240 | Items.WaitForContents(container,2000); 241 | foreach (var i in container.Contains) 242 | { 243 | if (i.Name.ToLower().Contains("staff")) 244 | { 245 | Misc.SendMessage(i.Name); 246 | } 247 | 248 | if (i.IsContainer && !i.IsBagOfSending) 249 | { 250 | Search(i); 251 | } 252 | } 253 | } 254 | 255 | } 256 | } -------------------------------------------------------------------------------- /RazorScripts/Reloader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using RazorEnhanced; 6 | 7 | namespace Razorscripts 8 | { 9 | public class Reloader 10 | { 11 | private Item Quiver = null; 12 | private uint _gumpId = 32315123; 13 | private int Checksum = 0; 14 | private int _lastMap = 0; 15 | private Item _lastHeldWeapon = null; 16 | 17 | public void Run() 18 | { 19 | try 20 | { 21 | var success = RefreshQuiver(); 22 | if (!success) 23 | { 24 | Player.HeadMessage(0x23, "You do not have a quiver equipped"); 25 | return; 26 | } 27 | 28 | 29 | _lastHeldWeapon = Player.GetItemOnLayer("LeftHand"); 30 | _lastMap = Player.Map; 31 | var a = Quiver.Contains.Where(i => i.ItemID == 3903).Sum(i => i.Amount); 32 | var b = Quiver.Contains.Where(i => i.ItemID == 7163).Sum(i => i.Amount); 33 | Checksum = a+b*1000; 34 | 35 | // Reload(); 36 | UpdateGump(); 37 | 38 | while (Player.Connected) 39 | { 40 | var arrows = Quiver.Contains.Where(i => i.ItemID == 3903).Sum(i => i.Amount); 41 | var bolts = Quiver.Contains.Where(i => i.ItemID == 7163).Sum(i => i.Amount); 42 | var ammoChecksum = arrows+bolts*1000; 43 | if (ammoChecksum != Checksum) 44 | { 45 | Checksum = ammoChecksum; 46 | UpdateGump(); 47 | } 48 | 49 | if (Player.Map != _lastMap) 50 | { 51 | _lastMap = Player.Map; 52 | RefreshQuiver(); 53 | } 54 | 55 | var held = Player.GetItemOnLayer("LeftHand"); 56 | if (held != null && held != _lastHeldWeapon ) 57 | { 58 | if (WeaponUsesBolts(held) != WeaponUsesBolts(_lastHeldWeapon)) 59 | { 60 | Reload(); 61 | } 62 | _lastHeldWeapon = held; 63 | } 64 | 65 | var sharedValue = Misc.ReadSharedValue("Reloader:Ammo") as int?; 66 | if (sharedValue != null && sharedValue.Value != 0) 67 | { 68 | var ammoTypeInQuiver = Quiver.Contains.FirstOrDefault(); 69 | if (sharedValue != ammoTypeInQuiver?.ItemID) 70 | { 71 | Reload(); 72 | } 73 | Misc.SetSharedValue("Reloader:Ammo", 0); 74 | } 75 | 76 | HandleReply(); 77 | 78 | Misc.Pause(1000); 79 | } 80 | } 81 | catch (ThreadAbortException) 82 | { 83 | //Silent 84 | } 85 | catch (Exception e) 86 | { 87 | Misc.SendMessage(e); 88 | throw; 89 | } 90 | finally 91 | { 92 | Gumps.CloseGump(_gumpId); 93 | } 94 | } 95 | 96 | private void HandleReply() 97 | { 98 | 99 | 100 | var reply = Gumps.GetGumpData(_gumpId); 101 | if (reply.buttonid > 0) 102 | { 103 | if (reply.buttonid == 1) 104 | { 105 | Reload(); 106 | UpdateGump(); 107 | } 108 | 109 | reply.buttonid = -1; 110 | } 111 | } 112 | 113 | 114 | private bool WeaponUsesBolts(Item item) 115 | { 116 | if(item == null) 117 | { 118 | return false; 119 | } 120 | 121 | var crossbows = new List { 9923, 3920, 5117 }; 122 | return crossbows.Contains(item.ItemID); 123 | } 124 | 125 | private void UpdateGump() 126 | { 127 | var gump = Gumps.CreateGump(); 128 | var ammoArrows = Quiver.Contains.Where(i => i.ItemID == 3903).Sum(i => i.Amount); 129 | var ammoBolts = Quiver.Contains.Where(i => i.ItemID == 7163).Sum(i => i.Amount); 130 | var ammoTextArrows = $"Arrows: {ammoArrows} / 500"; 131 | var ammoTextBolts = $"Bolts: {ammoBolts} / 500"; 132 | var defaultText = "No Ammo"; 133 | var height = 50; 134 | gump.gumpId = _gumpId; 135 | gump.serial = (uint)Player.Serial; 136 | Gumps.AddBackground(ref gump,0,0,300,height,1755); 137 | 138 | if (ammoArrows > 0) 139 | { 140 | Gumps.AddLabel(ref gump, 15, 15, 0x7b, ammoTextArrows); 141 | } 142 | 143 | if (ammoBolts > 0) 144 | { 145 | Gumps.AddLabel(ref gump, 15, 15, 0x7b, ammoTextBolts); 146 | } 147 | 148 | if (ammoBolts == 0 && ammoArrows == 0) 149 | { 150 | Gumps.AddLabel(ref gump, 15, 15, 0x7b, defaultText); 151 | } 152 | 153 | Gumps.AddButton(ref gump, 200,15,40018,40018,1,1,1); 154 | Gumps.AddLabel(ref gump, 215,15,0x481, "Reload"); 155 | 156 | Gumps.CloseGump(_gumpId); 157 | Gumps.SendGump(gump,500,500); 158 | } 159 | 160 | private void Reload() 161 | { 162 | RefreshQuiver(); 163 | var wep = Player.GetItemOnLayer("LeftHand"); 164 | if (wep != null) 165 | { 166 | Items.WaitForProps(wep,1000); 167 | var archerWep = wep.Properties.Any(p => p.ToString().Contains("archery")); 168 | if (archerWep) 169 | { 170 | var availableSpace = 500 - Quiver.Contains.Sum(i => i.Amount); 171 | var ammoId = WeaponUsesBolts(wep) ? 7163 : 3903; 172 | var ammoInQuiver = Quiver.Contains.FirstOrDefault(); 173 | if (ammoInQuiver != null && ammoInQuiver.ItemID != ammoId) 174 | { 175 | Items.Move(ammoInQuiver, Player.Backpack, ammoInQuiver.Amount); 176 | availableSpace = 500; 177 | Misc.Pause(350); 178 | } 179 | var ammo = Player.Backpack.Contains.FirstOrDefault(i => i.ItemID == ammoId && i.Amount > 0); 180 | if (ammo != null) 181 | { 182 | Items.WaitForProps(ammo,1000); 183 | var reloadAmount = ammo.Amount; 184 | if (reloadAmount > availableSpace) 185 | { 186 | reloadAmount = availableSpace; 187 | } 188 | 189 | if (reloadAmount == 0) 190 | { 191 | 192 | Player.HeadMessage(0x58,$"You are already full on {(ammoId == 7163 ? "Bolts" : "Arrows")}"); 193 | return; 194 | } 195 | 196 | Player.HeadMessage(0x58,$"Reloading {reloadAmount} {(ammoId == 7163 ? "Bolts" : "Arrows")}"); 197 | Items.Move(ammo, Quiver, reloadAmount); 198 | } 199 | else 200 | { 201 | Player.HeadMessage(0x23,"No Ammo in Backpack"); 202 | } 203 | } 204 | else 205 | { 206 | Player.HeadMessage(0x23,"No Archery Weapon Equipped"); 207 | } 208 | } 209 | else 210 | { 211 | Player.HeadMessage(0x23,"No Weapon Equipped"); 212 | } 213 | } 214 | 215 | private bool RefreshQuiver() 216 | { 217 | var quiver= Player.Quiver; 218 | if (quiver == null) 219 | { 220 | var backup = Player.GetItemOnLayer("Cloak"); 221 | if (backup != null && backup.Name.ToLower().Contains("quiver")) 222 | { 223 | quiver = backup; 224 | } 225 | else 226 | { 227 | return false; 228 | } 229 | 230 | Items.WaitForProps(quiver,1000); 231 | Items.WaitForContents(Quiver, 500); 232 | } 233 | 234 | Quiver = quiver; 235 | 236 | return true; 237 | } 238 | } 239 | } -------------------------------------------------------------------------------- /RazorScripts/SampMaster.cs: -------------------------------------------------------------------------------- 1 | //Add 2 scripts that alter the Shared Value for SampMaster to the 2 values below so that you can keybind these. 2 | //Misc.SetSharedValue("SampMaster:Targets","Multi") 3 | //Misc.SetSharedValue("SampMaster:Targets","Single") 4 | //This is simply to allow swapping stance from keybinds 5 | 6 | 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Diagnostics.Tracing; 10 | using System.Linq; 11 | using System.Threading; 12 | using RazorEnhanced; 13 | 14 | namespace RazorScripts 15 | { 16 | public class SampMaster 17 | { 18 | private static uint GumppId = 126542315; 19 | private bool Multi = false; 20 | private bool UseDoubleStrike = false; 21 | 22 | private List AoeSpecials = new List 23 | { 24 | 21004, 25 | 21006 26 | }; 27 | 28 | public void Run() 29 | { 30 | var defensives = new List 31 | { 32 | "Evasion", 33 | "Counter Attack", 34 | //"Confidence" 35 | }; 36 | 37 | var offensivesSingle = new List 38 | { 39 | "Lightning Strike", 40 | "Honorable Execution", 41 | "Stagger" 42 | }; 43 | 44 | var offensivesMulti = new List 45 | { 46 | 47 | "Whirlwind Attack", 48 | "Momentum Strike", 49 | "Frenzied Whirlwind", 50 | }; 51 | try 52 | { 53 | UpdateGump(); 54 | while (true) 55 | { 56 | var gd = Gumps.GetGumpData(GumppId); 57 | if(gd.buttonid == 2) 58 | { 59 | Misc.SetSharedValue("SampMaster:Targets","Single"); 60 | } 61 | else if(gd.buttonid == 1) 62 | { 63 | Misc.SetSharedValue("SampMaster:Targets","Multi"); 64 | } 65 | var oldTarg = Multi; 66 | Multi = IsMulti(); 67 | var targChanged = oldTarg != Multi; 68 | if (targChanged) 69 | { 70 | UpdateGump(); 71 | } 72 | 73 | if (Player.WarMode && Player.Mana > 10) 74 | { 75 | if (!Player.Buffs.Any(b => defensives.Contains(b))) 76 | { 77 | 78 | Spells.CastBushido("Counter Attack"); 79 | Misc.Pause(200); 80 | } 81 | 82 | else 83 | { 84 | if (Multi) 85 | { 86 | if (!Player.Buffs.Any(b => offensivesMulti.Contains(b)) && !Player.HasSpecial) 87 | { 88 | var force = false; 89 | // var targs = Mobiles.ApplyFilter(new Mobiles.Filter 90 | // { 91 | // RangeMin = 0, 92 | // RangeMax = 1, 93 | // Warmode = 1 94 | // }).ToList(); 95 | // targs.ForEach(m => Mobiles.WaitForStats(m, 200)); 96 | // var primeTarget = targs.OrderBy(m => m.Hits).FirstOrDefault(); 97 | // 98 | // if (primeTarget != null && targs.Count > 1 && targs.Count < 3) 99 | // { 100 | // if (primeTarget.Hits < 30) 101 | // { 102 | // force = true; 103 | // Player.Attack(primeTarget); 104 | // } 105 | // } 106 | 107 | PrimeMulti(force); 108 | Misc.Pause(200); 109 | } 110 | } 111 | else 112 | { 113 | if (!offensivesSingle.Any(Player.SpellIsEnabled)) 114 | { 115 | if (UseDoubleStrike && Player.PrimarySpecial == 20998) 116 | { 117 | Player.WeaponPrimarySA(); 118 | } 119 | else 120 | { 121 | Spells.CastBushido("Lightning Strike"); 122 | } 123 | 124 | Misc.Pause(200); 125 | } 126 | } 127 | } 128 | 129 | 130 | } 131 | 132 | Misc.Pause(500); 133 | } 134 | } 135 | catch (Exception e) 136 | { 137 | if (e.GetType() != typeof(ThreadAbortException)) 138 | { 139 | Misc.SendMessage(e.ToString()); 140 | } 141 | } 142 | } 143 | 144 | 145 | private void PrimeMulti(bool forceMomentum = false) 146 | { 147 | if (!forceMomentum && AoeSpecials.Contains(GetMultiIcon("primary"))) 148 | { 149 | Player.WeaponPrimarySA(); 150 | } 151 | else if (!forceMomentum && AoeSpecials.Contains(GetMultiIcon("secondary"))) 152 | { 153 | Player.WeaponSecondarySA(); 154 | } 155 | 156 | else 157 | { 158 | Spells.CastBushido("Momentum Strike"); 159 | } 160 | } 161 | 162 | private bool IsMulti() 163 | { 164 | var val = Misc.ReadSharedValue("SampMaster:Targets"); 165 | var stance = (val is string) ? !string.IsNullOrEmpty(val.ToString()) ? val.ToString() : "Single" : "Single"; 166 | if (string.IsNullOrEmpty(stance)) 167 | { 168 | stance = "Single"; 169 | } 170 | 171 | return stance == "Multi"; 172 | } 173 | 174 | private bool IsDefensive() 175 | { 176 | var val = Misc.ReadSharedValue("SampMaster:Stance"); 177 | var stance = (val is string) ? !string.IsNullOrEmpty(val.ToString()) ? val.ToString() : "Offensive" : "Offensive"; 178 | if (string.IsNullOrEmpty(stance)) 179 | { 180 | stance = "Offensive"; 181 | } 182 | 183 | 184 | 185 | return stance == "Defensive"; 186 | } 187 | 188 | private void UpdateGump() 189 | { 190 | var gump = Gumps.CreateGump(); 191 | gump.gumpId = GumppId; 192 | gump.serial = (uint)Player.Serial; 193 | Gumps.AddBackground(ref gump,0,0,55,55,1755); 194 | 195 | if (!Multi) 196 | { 197 | // Gumps.AddImage(ref gump,5,5,21540); 198 | Gumps.AddButton(ref gump, 5,5,21540,21540,1,1,0); 199 | Gumps.AddTooltip(ref gump, "Single Target"); 200 | } 201 | else 202 | { 203 | Gumps.AddButton(ref gump, 5,5,(int)GetMultiIcon(),(int)GetMultiIcon(),2,1,0); 204 | Gumps.AddTooltip(ref gump, "Multi Target"); 205 | } 206 | 207 | Gumps.CloseGump(GumppId); 208 | Gumps.SendGump(gump,500,500); 209 | } 210 | 211 | private uint GetMultiIcon(string slot = null) 212 | { 213 | switch (slot) 214 | { 215 | case "primary": 216 | { 217 | if (AoeSpecials.Contains(Player.PrimarySpecial)) 218 | { 219 | return Player.PrimarySpecial; 220 | } 221 | 222 | break; 223 | } 224 | case "secondary": 225 | { 226 | if (AoeSpecials.Contains(Player.SecondarySpecial)) 227 | { 228 | return Player.SecondarySpecial; 229 | } 230 | 231 | break; 232 | } 233 | default: 234 | { 235 | if (AoeSpecials.Contains(Player.PrimarySpecial)) 236 | { 237 | return Player.PrimarySpecial; 238 | } 239 | 240 | if (AoeSpecials.Contains(Player.SecondarySpecial)) 241 | { 242 | return Player.SecondarySpecial; 243 | } 244 | 245 | break; 246 | } 247 | } 248 | 249 | return 21541; 250 | } 251 | } 252 | } -------------------------------------------------------------------------------- /RazorScripts/WeaponMaster.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text.RegularExpressions; 6 | using RazorEnhanced; 7 | 8 | namespace RazorScripts 9 | { 10 | public class WeaponMaster 11 | { 12 | private Item _weaponContainer { get; set; } 13 | private readonly List _slayerWeapons = new List(); 14 | private readonly List _areaWeapons = new List(); 15 | private readonly List _extras = new List(); 16 | private BaseSkill _skill; 17 | private static string _version = "1.0.1"; 18 | 19 | private Func _slayerSearchFilter; 20 | private Func _areaSearchFilter; 21 | private readonly List _slayerList = new List 22 | { 23 | WeaponIcon.None, 24 | WeaponIcon.RepondSlayer, 25 | WeaponIcon.UndeadSlayer, 26 | WeaponIcon.ReptileSlayer, 27 | WeaponIcon.DragonSlayer, 28 | WeaponIcon.ArachnidSlayer, 29 | WeaponIcon.ElementalSlayer, 30 | WeaponIcon.AirElementalSlayer, 31 | WeaponIcon.FireElementalSlayer, 32 | WeaponIcon.WaterElementalSlayer, 33 | WeaponIcon.EarthElementalSlayer, 34 | WeaponIcon.BloodElementalSlayer, 35 | WeaponIcon.DemonSlayer, 36 | WeaponIcon.FeySlayer, 37 | }; 38 | 39 | private TextInfo _tinfo; 40 | 41 | public void Run() 42 | { 43 | _tinfo = CultureInfo.CurrentCulture.TextInfo; 44 | _skill = TryFindSkill(); 45 | 46 | if (_skill == BaseSkill.Magery) 47 | { 48 | _slayerSearchFilter = i => IsSpellBook(i) 49 | && (i.Properties.Any(p => p.ToString().ToLower().Contains("slayer")) 50 | || i.Properties.Any(p => p.ToString().ToLower().Contains("silver"))); 51 | } 52 | else 53 | { 54 | _slayerSearchFilter = i => (i.Properties.Any(p => p.ToString().ToLower().Contains("slayer")) 55 | || i.Properties.Any(p => p.ToString().ToLower().Contains("silver"))) 56 | && i.Properties.Any(p => p.ToString().ToLower().Contains(_tinfo.ToTitleCase(_skill.ToString()).ToLower())); 57 | } 58 | 59 | 60 | if (TryFindWeaponBag(Player.Backpack)) 61 | { 62 | SetWeapons(_weaponContainer); 63 | } 64 | else 65 | { 66 | Misc.SendMessage("Unable to find Slayer weapon container, please open the container and try again"); 67 | return; 68 | } 69 | 70 | UpdateBar(); 71 | 72 | while (true) 73 | { 74 | var bar = Gumps.GetGumpData(788435749); 75 | if (bar.buttonid != -1 && bar.buttonid != 0) 76 | { 77 | UpdateBar(); 78 | 79 | EquipSlayer(_slayerWeapons.FirstOrDefault(i => i.Slayer == (WeaponIcon)bar.buttonid)); 80 | 81 | UpdateBar(); 82 | } 83 | 84 | 85 | 86 | Misc.Pause(100); 87 | } 88 | } 89 | 90 | private void EquipSlayer(Weapon book) 91 | { 92 | var held = GetEquippedWeapon(); 93 | var resolved = _slayerWeapons.FirstOrDefault(b => b.Serial == held?.Serial); 94 | if (_weaponContainer == null) 95 | { 96 | Misc.SendMessage("Unable to find book binder"); 97 | } 98 | 99 | if (held != null && resolved != null) 100 | { 101 | if (resolved.Serial == book.Serial) 102 | { 103 | return; 104 | } 105 | 106 | var gameEquipped = Items.FindBySerial(resolved.Serial); 107 | var index = _slayerList.IndexOf(resolved.Slayer); 108 | var offset = index > 5 ? 6 : 0; 109 | Items.Move(gameEquipped, _weaponContainer, 1,(index-offset)*20+45, offset == 0 ? 95 : 125); 110 | Misc.Pause(600); 111 | } 112 | else 113 | { 114 | if (held != null) 115 | { 116 | Items.Move(held, Player.Backpack.Serial,held.Amount); 117 | Misc.Pause(600); 118 | } 119 | } 120 | 121 | var gameTarget = Items.FindBySerial(book.Serial); 122 | Player.EquipItem(gameTarget); 123 | Misc.Pause(200); 124 | } 125 | 126 | private int GetActiveBookIndex() 127 | { 128 | var held = GetEquippedWeapon(); 129 | var booksSorted = _slayerWeapons.OrderBy(b => _slayerList.IndexOf(b.Slayer)).ToList(); 130 | var resolved = _slayerWeapons.FirstOrDefault(b => b.Serial == held?.Serial); 131 | if (resolved != null) 132 | { 133 | return booksSorted.IndexOf(resolved); 134 | } 135 | 136 | return -1; 137 | } 138 | 139 | private void UpdateBar() 140 | { 141 | var activeBookIndex = GetActiveBookIndex(); 142 | var bar = Gumps.CreateGump(); 143 | bar.buttonid = -1; 144 | bar.gumpId = 788435749; 145 | bar.serial = (uint)Player.Serial; 146 | bar.x = 500; 147 | bar.y = 500; 148 | Gumps.AddBackground(ref bar, 0, 0, (_slayerWeapons.Count*60-5), 55, 1755); 149 | var slayersSorted = _slayerWeapons.OrderBy(b => _slayerList.IndexOf(b.Slayer)).ToList(); 150 | foreach (var slayerItem in slayersSorted) 151 | { 152 | var index = slayersSorted.IndexOf(slayerItem); 153 | var x = index * 60 + 5; 154 | var y = 5; 155 | Gumps.AddButton(ref bar, x,y,(int)slayerItem.Slayer,(int)slayerItem.Slayer,(int)slayerItem.Slayer,1,0); 156 | Gumps.AddTooltip(ref bar, slayerItem.Name); 157 | } 158 | 159 | if (activeBookIndex != -1) 160 | { 161 | Gumps.AddImage(ref bar, (60 * activeBookIndex-17),0,30071); 162 | } 163 | 164 | Gumps.CloseGump(788435749); 165 | Gumps.SendGump(bar, 500,500); 166 | } 167 | 168 | private BaseSkill TryFindSkill() 169 | { 170 | var dict = new Dictionary(); 171 | foreach (var baseSkill in Enum.GetValues(typeof(BaseSkill)).Cast()) 172 | { 173 | var skillString = _tinfo.ToTitleCase(baseSkill.ToString()); 174 | var value = Player.GetSkillValue(skillString); 175 | dict.Add(baseSkill, value); 176 | } 177 | 178 | //Return key of highest value 179 | return dict.Aggregate((l, r) => l.Value > r.Value ? l : r).Key; 180 | } 181 | 182 | private Item GetEquippedWeapon() 183 | { 184 | var item = Player.GetItemOnLayer("RightHand"); 185 | if (item != null) 186 | { 187 | return item; 188 | } 189 | item = Player.GetItemOnLayer("LeftHand"); 190 | if (item != null) 191 | { 192 | if (item.Properties.Any(p => p.ToString().ToLower().Contains("two-handed"))) 193 | { 194 | return item; 195 | } 196 | } 197 | 198 | return null; 199 | } 200 | 201 | private bool TryFindWeaponBag(Item container) 202 | { 203 | if (_weaponContainer != null) 204 | { 205 | return true; 206 | } 207 | 208 | var slayersFound = 0; 209 | var held = GetEquippedWeapon(); 210 | if (held != null) 211 | { 212 | slayersFound++; 213 | } 214 | 215 | 216 | 217 | List potentials = new List(); 218 | foreach (var item in container.Contains) 219 | { 220 | Items.WaitForProps(item, 1000); 221 | 222 | if (_slayerSearchFilter(item)) 223 | { 224 | potentials.Add(item); 225 | } 226 | 227 | } 228 | 229 | slayersFound += potentials.Count; 230 | 231 | if (slayersFound > 1) 232 | { 233 | _weaponContainer = container; 234 | return true; 235 | } 236 | 237 | foreach (var subContainer in container.Contains.Where(c => c.IsContainer && !c.IsBagOfSending)) 238 | { 239 | var found = TryFindWeaponBag(subContainer); 240 | if (found) 241 | { 242 | return true; 243 | } 244 | } 245 | 246 | return false; 247 | } 248 | 249 | private bool IsSpellBook(Item item) 250 | { 251 | return item.Name.ToLower().Contains("spellbook") || item.Name.Equals("Scrapper's Compendium", StringComparison.InvariantCultureIgnoreCase); 252 | } 253 | 254 | private void SetWeapons(Item container) 255 | { 256 | _slayerWeapons.Clear(); 257 | var compoundList = container.Contains.ToList(); 258 | var held = GetEquippedWeapon(); 259 | if (held != null) 260 | { 261 | compoundList.Add(held); 262 | } 263 | 264 | foreach (var extra in _extras) 265 | { 266 | var exAdd = Items.FindBySerial(extra.Serial); 267 | if (exAdd != null) 268 | { 269 | _slayerWeapons.Add( new Weapon 270 | { 271 | Name = _tinfo.ToTitleCase(exAdd.Name), 272 | Serial = exAdd.Serial, 273 | Slayer = WeaponIcon.None 274 | }); 275 | } 276 | } 277 | 278 | foreach (var item in compoundList.Where(_slayerSearchFilter)) 279 | { 280 | var prop = item.Properties.FirstOrDefault(p => p.ToString().Contains("slayer")) ?? item.Properties.FirstOrDefault(p => p.Number == 1071451); 281 | var slayerString = prop.ToString().ToLower(); 282 | if (slayerString == "silver") 283 | { 284 | slayerString = "undead slayer"; 285 | } 286 | 287 | 288 | 289 | _slayerWeapons.Add( new Weapon 290 | { 291 | Name = _tinfo.ToTitleCase(prop.ToString()), 292 | Serial = item.Serial, 293 | Slayer = _slayerList.Any(s => _tinfo.ToTitleCase(slayerString).Equals(SplitCamelCase(s.ToString()))) ? _slayerList.First(s => _tinfo.ToTitleCase(slayerString).Equals(SplitCamelCase(s.ToString()))) : WeaponIcon.UnKnown 294 | }); 295 | 296 | } 297 | } 298 | 299 | private enum BaseSkill 300 | { 301 | Swordsmanship = 0, 302 | MaceFighting = 1, 303 | Fencing = 2, 304 | Archery = 3, 305 | Throwing = 4, 306 | Magery = 5, 307 | } 308 | 309 | public class Weapon 310 | { 311 | public int Serial { get; set; } 312 | public string Name { get; set; } 313 | public WeaponIcon Slayer { get; set; } 314 | } 315 | 316 | 317 | public enum WeaponIcon 318 | { 319 | None = 20744, 320 | RepondSlayer = 2277, 321 | UndeadSlayer = 20486, 322 | ReptileSlayer = 21282, 323 | ArachnidSlayer = 20994, 324 | ElementalSlayer = 24014, 325 | AirElementalSlayer = 2299, 326 | FireElementalSlayer = 2302, 327 | WaterElementalSlayer = 2303, 328 | EarthElementalSlayer = 2301, 329 | BloodElementalSlayer = 20993, 330 | DemonSlayer = 2300, 331 | DragonSlayer = 21010, 332 | FeySlayer = 23006, 333 | UnKnown = 24015, 334 | 335 | //Hit Area 336 | HitAreaFire = 2267, 337 | HitAreaLightning = 2288, 338 | HitAreaEnergy = 2289, 339 | HitAreaCold = 23010, 340 | HitAreaPoison = 2285, 341 | 342 | //Selectable 343 | SwordFlame = 21015, 344 | SwordSerpent = 21019, 345 | SwordQuick = 21004, 346 | SwordHeart = 21000, 347 | SwordSpin = 21006, 348 | SwordDouble = 20998, 349 | SwordDrop = 20996, 350 | SwordPierce = 20992, 351 | Sword5Point = 20741, 352 | SwordMagic = 20483, 353 | PoisonStrike = 20489, 354 | LighteningArrow = 21017, 355 | BowQuick = 21001, 356 | Crossbow = 21013, 357 | 358 | Shuriken = 21021, 359 | JumpKill = 21293, 360 | 361 | BrokenSword = 2305, 362 | BrokenShield = 2304, 363 | BloodSkull = 2237, 364 | 365 | Swirl = 2297, 366 | FlameStrike = 2290, 367 | BladeSpirit = 2272, 368 | FireBall = 2257, 369 | Poison = 2259, 370 | Needles = 2251, 371 | MagicArrow = 2244, 372 | Heal = 2243, 373 | GreaterHeal = 2268, 374 | 375 | 376 | 377 | } 378 | 379 | public string SplitCamelCase(string str) 380 | { 381 | return Regex.Replace( 382 | Regex.Replace( 383 | str, 384 | @"(\P{Ll})(\P{Ll}\p{Ll})", 385 | "$1 $2" 386 | ), 387 | @"(\p{Ll})(\P{Ll})", 388 | "$1 $2" 389 | ); 390 | } 391 | } 392 | } -------------------------------------------------------------------------------- /RazorScripts/TheRanger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using System.Windows.Forms.VisualStyles; 6 | using RazorEnhanced; 7 | 8 | namespace Razorscripts 9 | { 10 | public class TheRanger 11 | { 12 | private uint _gumpId = 788435742; 13 | private Item Quiver = null; 14 | private int Checksum = 0; 15 | private int _lastMap = 0; 16 | private Item _lastHeldWeapon = null; 17 | private bool _runAutoReload = false; 18 | private string lastPowerChecksum = string.Empty; 19 | private string _lastLoadedSpecial = string.Empty; 20 | 21 | private List LoadedPowers = new List(); 22 | 23 | private Power _selectedPower; 24 | 25 | public void Run() 26 | { 27 | try 28 | { 29 | var success = RefreshQuiver(); 30 | if (!success) 31 | { 32 | Player.HeadMessage(0x23, "You do not have a quiver equipped"); 33 | return; 34 | } 35 | 36 | SetPowers(); 37 | _selectedPower = LoadedPowers.FirstOrDefault(); 38 | 39 | UpdateGump(); 40 | while (Player.Connected) 41 | { 42 | var powerStringChecksum = SetPowers(); 43 | if (powerStringChecksum != lastPowerChecksum) 44 | { 45 | lastPowerChecksum = powerStringChecksum; 46 | UpdateGump(); 47 | } 48 | 49 | if (_lastLoadedSpecial != _selectedPower?.Name && _lastLoadedSpecial != "None") 50 | { 51 | _selectedPower = LoadedPowers.FirstOrDefault(p => p.Name == _lastLoadedSpecial) ?? 52 | _selectedPower; 53 | } 54 | 55 | var arrows = Quiver.Contains.Where(i => i.ItemID == 3903).Sum(i => i.Amount); 56 | var bolts = Quiver.Contains.Where(i => i.ItemID == 7163).Sum(i => i.Amount); 57 | var ammoChecksum = arrows+bolts*1000; 58 | if (ammoChecksum != Checksum) 59 | { 60 | Checksum = ammoChecksum; 61 | UpdateGump(); 62 | } 63 | 64 | if (Player.Map != _lastMap) 65 | { 66 | _lastMap = Player.Map; 67 | RefreshQuiver(); 68 | } 69 | 70 | var held = Player.GetItemOnLayer("LeftHand"); 71 | if (held != null && held != _lastHeldWeapon ) 72 | { 73 | if (WeaponUsesBolts(held) != WeaponUsesBolts(_lastHeldWeapon)) 74 | { 75 | Reload(); 76 | } 77 | _lastHeldWeapon = held; 78 | } 79 | 80 | var sharedValue = Misc.ReadSharedValue("Reloader:Ammo") as int?; 81 | if (sharedValue != null && sharedValue.Value != 0) 82 | { 83 | var ammoTypeInQuiver = Quiver.Contains.FirstOrDefault(); 84 | if (sharedValue != ammoTypeInQuiver?.ItemID) 85 | { 86 | Reload(); 87 | } 88 | Misc.SetSharedValue("Reloader:Ammo", 0); 89 | } 90 | 91 | HandleReply(); 92 | 93 | PrimePower(); 94 | 95 | if (_runAutoReload) 96 | { 97 | if(Quiver.Contains.Sum(i => i.Amount) < 50) 98 | { 99 | Reload(); 100 | } 101 | } 102 | 103 | Misc.Pause(1000); 104 | } 105 | } 106 | catch (ThreadAbortException) 107 | { 108 | //Silent 109 | } 110 | catch (Exception e) 111 | { 112 | Misc.SendMessage(e); 113 | throw; 114 | } 115 | finally 116 | { 117 | Gumps.CloseGump(_gumpId); 118 | } 119 | } 120 | 121 | private string SetPowers() 122 | { 123 | LoadedPowers.Clear(); 124 | LoadedPowers.Add(new Power { Name = "None", Type = PowerType.None, GumpId = 21013 }); 125 | if (Player.PrimarySpecial == 20992) 126 | { 127 | LoadedPowers.Add(new Power { Name = "Armor Ingore", Type = PowerType.WeaponPrimary, GumpId = 20992 }); 128 | } 129 | else if (Player.SecondarySpecial == 20992) 130 | { 131 | LoadedPowers.Add(new Power { Name = "Armor Ingore", Type = PowerType.WeaponSecondary, GumpId = 20992 }); 132 | } 133 | if (Player.PrimarySpecial == 21016) 134 | { 135 | LoadedPowers.Add(new Power { Name = "Force Arrow", Type = PowerType.WeaponPrimary, GumpId = 21016 }); 136 | } 137 | else if (Player.SecondarySpecial == 21016) 138 | { 139 | LoadedPowers.Add(new Power { Name = "Force Arrow", Type = PowerType.WeaponSecondary, GumpId = 21016 }); 140 | } 141 | if (Player.PrimarySpecial == 20994) 142 | { 143 | LoadedPowers.Add(new Power { Name = "Crushing Blow", Type = PowerType.WeaponPrimary, GumpId = 20994 }); 144 | } 145 | else if (Player.SecondarySpecial == 20994) 146 | { 147 | LoadedPowers.Add(new Power { Name = "Crushing Blow", Type = PowerType.WeaponSecondary, GumpId = 20994 }); 148 | } 149 | if (Player.PrimarySpecial == 20998) 150 | { 151 | LoadedPowers.Add(new Power { Name = "Double Strike", Type = PowerType.WeaponPrimary, GumpId = 20998 }); 152 | } 153 | else if (Player.SecondarySpecial == 20998) 154 | { 155 | LoadedPowers.Add(new Power { Name = "Double Strike", Type = PowerType.WeaponSecondary, GumpId = 20998 }); 156 | } 157 | if(Player.GetSkillValue("Bushido") > 70) 158 | { 159 | LoadedPowers.Add(new Power { Name = "Lightening Strike", Type = PowerType.Bushido, GumpId = 21540 }); 160 | LoadedPowers.Add(new Power { Name = "Momentum Strike", Type = PowerType.Bushido, GumpId = 21541 }); 161 | } 162 | 163 | return string.Join(":", LoadedPowers.Select(p => p.Name)); 164 | } 165 | 166 | private void HandleReply() 167 | { 168 | var reply = Gumps.GetGumpData(_gumpId); 169 | if (reply.buttonid > 0 && reply.buttonid < 100) 170 | { 171 | _selectedPower = LoadedPowers[reply.buttonid - 1]; 172 | _lastLoadedSpecial = _selectedPower.Name; 173 | UpdateGump(); 174 | } 175 | else if (reply.buttonid == 100) 176 | { 177 | Reload(); 178 | UpdateGump(); 179 | } 180 | else if(reply.buttonid == 200) 181 | { 182 | _runAutoReload = !_runAutoReload; 183 | UpdateGump(); 184 | } 185 | 186 | reply.buttonid = -1; 187 | } 188 | 189 | private void Reload() 190 | { 191 | RefreshQuiver(); 192 | var wep = Player.GetItemOnLayer("LeftHand"); 193 | if (wep != null) 194 | { 195 | Items.WaitForProps(wep,1000); 196 | var archerWep = wep.Properties.Any(p => p.ToString().Contains("archery")); 197 | if (archerWep) 198 | { 199 | var availableSpace = 500 - Quiver.Contains.Sum(i => i.Amount); 200 | var ammoId = WeaponUsesBolts(wep) ? 7163 : 3903; 201 | var ammoInQuiver = Quiver.Contains.FirstOrDefault(); 202 | if (ammoInQuiver != null && ammoInQuiver.ItemID != ammoId) 203 | { 204 | Items.Move(ammoInQuiver, Player.Backpack, ammoInQuiver.Amount); 205 | availableSpace = 500; 206 | Misc.Pause(350); 207 | } 208 | var ammo = Player.Backpack.Contains.FirstOrDefault(i => i.ItemID == ammoId && i.Amount > 0); 209 | if (ammo != null) 210 | { 211 | Items.WaitForProps(ammo,1000); 212 | var reloadAmount = ammo.Amount; 213 | if (reloadAmount > availableSpace) 214 | { 215 | reloadAmount = availableSpace; 216 | } 217 | 218 | if (reloadAmount == 0) 219 | { 220 | 221 | Player.HeadMessage(0x58,$"You are already full on {(ammoId == 7163 ? "Bolts" : "Arrows")}"); 222 | return; 223 | } 224 | 225 | Player.HeadMessage(0x58,$"Reloading {reloadAmount} {(ammoId == 7163 ? "Bolts" : "Arrows")}"); 226 | Items.Move(ammo, Quiver, reloadAmount); 227 | } 228 | else 229 | { 230 | Player.HeadMessage(0x23,"No Ammo in Backpack"); 231 | } 232 | } 233 | else 234 | { 235 | Player.HeadMessage(0x23,"No Archery Weapon Equipped"); 236 | } 237 | } 238 | else 239 | { 240 | Player.HeadMessage(0x23,"No Weapon Equipped"); 241 | } 242 | } 243 | 244 | private bool RefreshQuiver() 245 | { 246 | var quiver= Player.Quiver; 247 | if (quiver == null) 248 | { 249 | var backup = Player.GetItemOnLayer("Cloak"); 250 | if (backup != null && backup.Name.ToLower().Contains("quiver")) 251 | { 252 | quiver = backup; 253 | } 254 | else 255 | { 256 | return false; 257 | } 258 | 259 | Items.WaitForProps(quiver,1000); 260 | Items.WaitForContents(Quiver, 500); 261 | } 262 | 263 | Quiver = quiver; 264 | 265 | return true; 266 | } 267 | 268 | private bool WeaponUsesBolts(Item item) 269 | { 270 | if(item == null) 271 | { 272 | return false; 273 | } 274 | 275 | var crossbows = new List { 9923, 3920, 5117 }; 276 | return crossbows.Contains(item.ItemID); 277 | } 278 | 279 | private void PrimePower() 280 | { 281 | if (_selectedPower == null) 282 | { 283 | return; 284 | } 285 | var held = Player.GetItemOnLayer("LeftHand"); 286 | if (held == null) 287 | { 288 | return; 289 | } 290 | switch (_selectedPower.Type) 291 | { 292 | case PowerType.Bushido: 293 | if (!Player.BuffsExist(_selectedPower.Name)) 294 | { 295 | Spells.CastBushido(_selectedPower.Name); 296 | } 297 | break; 298 | case PowerType.WeaponPrimary: 299 | if (!Player.HasPrimarySpecial) 300 | { 301 | if (Player.PrimarySpecial == _selectedPower.GumpId) 302 | { 303 | Player.WeaponPrimarySA(); 304 | } 305 | } 306 | break; 307 | case PowerType.WeaponSecondary: 308 | if (!Player.HasSecondarySpecial) 309 | { 310 | if (Player.SecondarySpecial == _selectedPower.GumpId) 311 | { 312 | Player.WeaponSecondarySA(); 313 | } 314 | } 315 | break; 316 | case PowerType.None: 317 | default: 318 | break; 319 | } 320 | } 321 | 322 | private void UpdateGump() 323 | { 324 | var gump = Gumps.CreateGump(); 325 | gump.buttonid = -1; 326 | // bar.gumpId = ; 327 | gump.serial = (uint)Player.Serial; 328 | gump.gumpId = _gumpId; 329 | gump.x = 500; 330 | gump.y = 500; 331 | var width = (LoadedPowers.Count * 60 - 5); 332 | if(width < 250) 333 | { 334 | width = 250; 335 | } 336 | UpdateRangerGumpDetails(gump, width); 337 | UpdateReloaderGumpDetails(gump, width); 338 | 339 | Gumps.CloseGump(_gumpId); 340 | Gumps.SendGump(gump, 500,500); 341 | } 342 | 343 | private void UpdateRangerGumpDetails(Gumps.GumpData gump, int width) 344 | { 345 | 346 | Gumps.AddBackground(ref gump, 0, 0, width, 55, 1755); 347 | var powerIndex = 0; 348 | foreach (var power in LoadedPowers) 349 | { 350 | var x = powerIndex * 60 + 5; 351 | var y = 5; 352 | Gumps.AddButton(ref gump, x,y,(int)power.GumpId,(int)power.GumpId,LoadedPowers.IndexOf(power)+1,1,0); 353 | Gumps.AddTooltip(ref gump, power.Name); 354 | powerIndex++; 355 | } 356 | 357 | if (_selectedPower != null) 358 | { 359 | var selected = LoadedPowers.FirstOrDefault(i => i.Name == _selectedPower.Name); 360 | var index = LoadedPowers.IndexOf(selected); 361 | if (index < 0) 362 | { 363 | index = 0; 364 | } 365 | Gumps.AddImage(ref gump, (60 * index-17),0,30071); 366 | } 367 | } 368 | 369 | private void UpdateReloaderGumpDetails(Gumps.GumpData gump, int width) 370 | { 371 | var baseY = 55; 372 | var ammoArrows = Quiver.Contains.Where(i => i.ItemID == 3903).Sum(i => i.Amount); 373 | var ammoBolts = Quiver.Contains.Where(i => i.ItemID == 7163).Sum(i => i.Amount); 374 | var ammoTextArrows = $"Arrows: {ammoArrows} / 500"; 375 | var ammoTextBolts = $"Bolts: {ammoBolts} / 500"; 376 | var defaultText = "No Ammo"; 377 | var height = 50; 378 | gump.gumpId = _gumpId; 379 | gump.serial = (uint)Player.Serial; 380 | Gumps.AddBackground(ref gump,0,baseY,width,height,1755); 381 | 382 | if (ammoArrows > 0) 383 | { 384 | Gumps.AddLabel(ref gump, 15, baseY+15, 0x7b, ammoTextArrows); 385 | } 386 | 387 | if (ammoBolts > 0) 388 | { 389 | Gumps.AddLabel(ref gump, 15, baseY+15, 0x7b, ammoTextBolts); 390 | } 391 | 392 | if (ammoBolts == 0 && ammoArrows == 0) 393 | { 394 | Gumps.AddLabel(ref gump, 15, baseY+15, 0x7b, defaultText); 395 | } 396 | 397 | var buttonId = _runAutoReload ? 9027 : 9026; 398 | 399 | Gumps.AddButton(ref gump, width-105, baseY+15 , buttonId,buttonId,200,1,1); 400 | 401 | Gumps.AddButton(ref gump, width-80,baseY+15,40018,40018,100,1,1); 402 | Gumps.AddLabel(ref gump, width-65,baseY+15,0x481, "Reload"); 403 | } 404 | 405 | 406 | private class Power 407 | { 408 | public string Name { get; set; } 409 | public PowerType Type { get; set; } 410 | public int GumpId { get; set; } 411 | } 412 | 413 | private enum PowerType 414 | { 415 | WeaponPrimary, 416 | WeaponSecondary, 417 | Bushido, 418 | None 419 | } 420 | } 421 | } -------------------------------------------------------------------------------- /RazorScripts/CasterTrain.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using System.Xml.Schema; 6 | using RazorEnhanced; 7 | 8 | namespace RazorScripts 9 | { 10 | public class CasterTrain 11 | { 12 | private Mobile _player; 13 | 14 | private Dictionary _spellSchools = new Dictionary 15 | { 16 | {"Magery", 0}, 17 | {"Necromancy", 0}, 18 | {"Chivalry", 0}, 19 | {"Mysticism", 0}, 20 | {"Spellweaving", 0} 21 | }; 22 | private uint _gumpId = 1239862396; 23 | private bool _running = false; 24 | private Item _targetWeapon = null; 25 | 26 | 27 | private Dictionary> _castHolder = new Dictionary>(); 28 | 29 | public void Run() 30 | { 31 | try 32 | { 33 | UpdateGump(""); 34 | 35 | if (_spellSchools.Any(sc => sc.Value > 0)) 36 | { 37 | _running = true; 38 | } 39 | 40 | while (!_running) 41 | { 42 | var reply = Gumps.GetGumpData(_gumpId); 43 | if (reply.buttonid == 1) 44 | { 45 | var changes = new Dictionary(); 46 | var index = 0; 47 | foreach (var sc in _spellSchools) 48 | { 49 | var valueString = reply.text[index]; 50 | if (int.TryParse(valueString, out var value)) 51 | { 52 | changes[sc.Key] = value; 53 | } 54 | 55 | index++; 56 | } 57 | 58 | foreach (var change in changes) 59 | { 60 | _spellSchools[change.Key] = change.Value; 61 | } 62 | 63 | UpdateGump(""); 64 | reply.buttonid = -1; 65 | _running = true; 66 | } 67 | 68 | Misc.Pause(500); 69 | } 70 | 71 | 72 | Setup(); 73 | 74 | if(_spellSchools["Chivalry"] > 0) 75 | { 76 | var currentSkill = Player.GetSkillValue("Chivalry"); 77 | if (currentSkill < 45) 78 | { 79 | Misc.SendMessage("You need to have a weapon to train Chivalry, please target one in your backpack", 0x22); 80 | var tar = new Target(); 81 | int tarSerial = 0; 82 | while (tarSerial == 0) 83 | { 84 | tarSerial = tar.PromptTarget("Select Weapon"); 85 | } 86 | var tarItem = Items.FindBySerial(tarSerial); 87 | 88 | _targetWeapon = tarItem; 89 | } 90 | } 91 | if(_spellSchools["Spellweaving"] > 20 && _targetWeapon == null) 92 | { 93 | var currentSkill = Player.GetSkillValue("Spellweaving"); 94 | if (currentSkill < 44) 95 | { 96 | Misc.SendMessage("You need to have a weapon to train Spellweaving, please target one in your backpack", 0x22); 97 | var tar = new Target(); 98 | int tarSerial = 0; 99 | while (tarSerial == 0) 100 | { 101 | tarSerial = tar.PromptTarget("Select Weapon"); 102 | } 103 | var tarItem = Items.FindBySerial(tarSerial); 104 | 105 | _targetWeapon = tarItem; 106 | } 107 | } 108 | 109 | foreach (var caster in _castHolder) 110 | { 111 | var needsWeapon = true; 112 | if(caster.Key == "Spellweaving") 113 | { 114 | if(Player.GetSkillValue("Spellweaving") >= 44) 115 | { 116 | needsWeapon = false; 117 | } 118 | if (needsWeapon) 119 | { 120 | Player.EquipItem(_targetWeapon); 121 | Misc.Pause(500); 122 | } 123 | } 124 | if(caster.Key == "Chivalry") 125 | { 126 | if(Player.GetSkillValue("Chivalry") >= 45) 127 | { 128 | needsWeapon = false; 129 | } 130 | if (needsWeapon) 131 | { 132 | Player.EquipItem(_targetWeapon); 133 | Misc.Pause(500); 134 | } 135 | } 136 | 137 | TrainSkill(caster.Key); 138 | UpdateGump(""); 139 | } 140 | } 141 | catch (ThreadAbortException) 142 | { 143 | Gumps.CloseGump(_gumpId); 144 | } 145 | catch (Exception e) 146 | { 147 | Misc.SendMessage(e); 148 | throw; 149 | } 150 | } 151 | 152 | private Action GetCastFunction(string casterKey) 153 | { 154 | switch (casterKey) 155 | { 156 | case "Magery": 157 | return Spells.CastMagery; 158 | case "Necromancy": 159 | return Spells.CastNecro; 160 | case "Chivalry": 161 | return Spells.CastChivalry; 162 | case "Mysticism": 163 | return Spells.CastMysticism; 164 | case "Spellweaving": 165 | return Spells.CastSpellweaving; 166 | default: 167 | return null; 168 | } 169 | } 170 | 171 | private void TrainSkill(string casterKey) 172 | { 173 | var skillList = _castHolder[casterKey]; 174 | var skillCap = _spellSchools[casterKey]; 175 | var skill = Player.GetSkillValue(casterKey); 176 | if (skill >= skillCap) 177 | { 178 | return; 179 | } 180 | 181 | var castFunc = GetCastFunction(casterKey); 182 | while (skill <= skillCap) 183 | { 184 | skillCap = _spellSchools[casterKey]; 185 | skill = Player.GetRealSkillValue(casterKey); 186 | if (_player.Hits < 30) 187 | { 188 | while (_player.Hits < Player.HitsMax) 189 | { 190 | var magerySkill = Player.GetSkillValue("Magery"); 191 | if (magerySkill >= 50) 192 | { 193 | CheckMana(); 194 | Spells.CastMagery("Greater Heal", _player); 195 | Misc.Pause(4000); 196 | continue; 197 | } 198 | 199 | if (magerySkill >= 30) 200 | { 201 | CheckMana(); 202 | Spells.CastMagery("Heal", _player); 203 | Misc.Pause(4000); 204 | continue; 205 | } 206 | 207 | var chivalrySkill = Player.GetSkillValue("Chivalry"); 208 | if (chivalrySkill >= 30) 209 | { 210 | CheckMana(); 211 | Spells.CastChivalry("Close Wounds", _player); 212 | Misc.Pause(4000); 213 | continue; 214 | } 215 | 216 | var spiritSpeakSkill = Player.GetSkillValue("Spirit Speak"); 217 | if (spiritSpeakSkill >= 30) 218 | { 219 | Player.UseSkill("Spirit Speak"); 220 | Misc.Pause(7000); 221 | continue; 222 | } 223 | 224 | var spellweavingSkill = Player.GetSkillValue("Spellweaving"); 225 | if (spellweavingSkill >= 24 && !Player.BuffsExist("Gift of Renewal")) 226 | { 227 | Spells.CastSpellweaving("Gift of Renewal", _player); 228 | Misc.Pause(7000); 229 | continue; 230 | } 231 | 232 | var bandages = _player.Backpack.Contains.FirstOrDefault(i => i.ItemID == 0x0E21); 233 | if (bandages != null) 234 | { 235 | Items.UseItem(bandages, _player); 236 | Misc.Pause(7000); 237 | continue; 238 | } 239 | 240 | Misc.Pause(2000); 241 | } 242 | } 243 | 244 | UpdateGump(casterKey); 245 | if (skill >= skillCap) 246 | { 247 | break; 248 | } 249 | 250 | CheckMana(); 251 | 252 | 253 | foreach (var spell in skillList) 254 | { 255 | if (skill < spell.SkillLevel) 256 | { 257 | castFunc.Invoke(spell.SpellName, _player, true); 258 | Misc.Pause(spell.WaitTime); 259 | UpdateGump(casterKey); 260 | break; 261 | } 262 | } 263 | } 264 | } 265 | 266 | private void CheckMana() 267 | { 268 | if (Player.Mana < 30) 269 | { 270 | while (Player.Mana < Player.ManaMax) 271 | { 272 | if (Player.Buffs.Any(b => b.Contains("Medit"))) 273 | { 274 | while (Player.Mana < Player.ManaMax) 275 | { 276 | Misc.Pause(1000); 277 | } 278 | } 279 | else 280 | { 281 | Player.UseSkill("Mediation"); 282 | Misc.Pause(3000); 283 | } 284 | } 285 | } 286 | } 287 | 288 | private void UpdateGump(string current) 289 | { 290 | var schoolstToTrain = _spellSchools.Where(ss => ss.Value > 0).ToList(); 291 | var gump = Gumps.CreateGump(); 292 | gump.buttonid = -1; 293 | gump.gumpId = _gumpId; 294 | gump.serial = (uint)Player.Serial; 295 | gump.x = 500; 296 | gump.y = 500; 297 | 298 | var height = schoolstToTrain.Any() ? 35 + (schoolstToTrain.Count() * 35) : 100 + (_spellSchools.Count() * 35); 299 | 300 | Gumps.AddBackground(ref gump, 0, 0, 200, height, 1755); 301 | Gumps.AddLabel(ref gump,10,10,0x7b, "Caster Training by Dorana"); 302 | 303 | var index = 0; 304 | if (schoolstToTrain.Any()) 305 | { 306 | foreach (var school in schoolstToTrain) 307 | { 308 | var currentSkill = Player.GetRealSkillValue(school.Key); 309 | var cap = school.Value; 310 | var crystal = school.Key == current ? 2152 : (currentSkill >= cap ? 5826 : 5832); 311 | Gumps.AddImage(ref gump, 10, 30 + (index * 35), crystal); 312 | Gumps.AddLabel(ref gump, 45, 35 + (index * 35), 203, $"{school.Key} - {currentSkill}/{cap}"); 313 | index++; 314 | } 315 | } 316 | else 317 | { 318 | Gumps.AddLabel(ref gump,15,30,0x7f, $"Skill name"); 319 | Gumps.AddLabel(ref gump,100,30,0x7f, $"Target Skill"); 320 | foreach (var school in _spellSchools) 321 | { 322 | var name = school.Key; 323 | var value = school.Value; 324 | Gumps.AddLabel(ref gump,15,55+(index*35),0x7b, $"{name}"); 325 | Gumps.AddImageTiled(ref gump, 100, 59+(index*35), 75, 16,1803); 326 | Gumps.AddTextEntry(ref gump, 100,59+(index*35),75,32,0x16a,index+1,value > 0 ? value.ToString() : ""); 327 | index++; 328 | } 329 | Gumps.AddButton(ref gump, 100,height-50, 247,248, 1,1,1); 330 | } 331 | Gumps.CloseGump(1239862396); 332 | Gumps.SendGump(gump, 500, 500); 333 | } 334 | 335 | private void Setup() 336 | { 337 | _player = Mobiles.FindBySerial(Player.Serial); 338 | if (_spellSchools["Magery"] > 0) 339 | { 340 | var spellList = new List(); 341 | spellList.Add(new SpellSkill {SkillLevel = 45, SpellName = "Fireball",}); 342 | spellList.Add(new SpellSkill {SkillLevel = 55, SpellName = "Lightning",}); 343 | spellList.Add(new SpellSkill {SkillLevel = 65, SpellName = "Paralyse",}); 344 | spellList.Add(new SpellSkill {SkillLevel = 75, SpellName = "Reveal",}); 345 | spellList.Add(new SpellSkill {SkillLevel = 90, SpellName = "Flame Strike",}); 346 | spellList.Add(new SpellSkill {SkillLevel = 120, SpellName = "Earthquake",WaitTime = 5000}); 347 | _castHolder.Add("Magery", spellList); 348 | } 349 | if (_spellSchools["Mysticism"] > 0) 350 | { 351 | var spellList = new List(); 352 | spellList.Add(new SpellSkill {SkillLevel = 60, SpellName = "Stone Form"}); 353 | spellList.Add(new SpellSkill {SkillLevel = 80, SpellName = "Cleansing Winds"}); 354 | spellList.Add(new SpellSkill {SkillLevel = 95, SpellName = "Hail Storm"}); 355 | spellList.Add(new SpellSkill {SkillLevel = 120, SpellName = "Nether Cyclone"}); 356 | _castHolder.Add("Mysticism", spellList); 357 | } 358 | if(_spellSchools["Necromancy"] > 0) 359 | { 360 | var spellList = new List(); 361 | spellList.Add(new SpellSkill {SkillLevel = 50, SpellName = "Pain Spike"}); 362 | spellList.Add(new SpellSkill {SkillLevel = 70, SpellName = "Horrific Beast", DoNotEndOnBuff = "Horrific Beast"}); 363 | spellList.Add(new SpellSkill {SkillLevel = 90, SpellName = "Wither"}); 364 | spellList.Add(new SpellSkill {SkillLevel = 95, SpellName = "Lich Form", DoNotEndOnBuff = "Lich Form"}); 365 | spellList.Add(new SpellSkill {SkillLevel = 120, SpellName = "Vampiric Embrace"}); 366 | _castHolder.Add("Necromancy", spellList); 367 | } 368 | if(_spellSchools["Chivalry"] > 0) 369 | { 370 | var spellList = new List(); 371 | spellList.Add(new SpellSkill {SkillLevel = 45, SpellName = "Consecrate Weapon"}); 372 | spellList.Add(new SpellSkill {SkillLevel = 60, SpellName = "Divine Fury"}); 373 | spellList.Add(new SpellSkill {SkillLevel = 70, SpellName = "Enemy of One"}); 374 | spellList.Add(new SpellSkill {SkillLevel = 90, SpellName = "Holy Light"}); 375 | spellList.Add(new SpellSkill {SkillLevel = 120, SpellName = "Noble Sacrifice"}); 376 | _castHolder.Add("Chivalry", spellList); 377 | } 378 | if(_spellSchools["Spellweaving"] > 0) 379 | { 380 | var spellList = new List(); 381 | spellList.Add(new SpellSkill {SkillLevel = 20, SpellName = "Arcane Circle"}); 382 | spellList.Add(new SpellSkill {SkillLevel = 33, SpellName = "Immolating Weapon", WaitTime = 9000}); 383 | spellList.Add(new SpellSkill {SkillLevel = 52, SpellName = "Reaper Form", DoNotEndOnBuff = "Reaper Form"}); 384 | // spellList.Add(new SpellSkill {SkillLevel = 55, SpellName = "Summon Fey"}); 385 | spellList.Add(new SpellSkill {SkillLevel = 74, SpellName = "Essence of Wind"}); 386 | spellList.Add(new SpellSkill {SkillLevel = 90, SpellName = "Wildfire", WaitTime = 3000}); 387 | spellList.Add(new SpellSkill {SkillLevel = 120, SpellName = "Word of Death"}); 388 | _castHolder.Add("Spellweaving", spellList); 389 | } 390 | } 391 | } 392 | 393 | public class SpellSkill 394 | { 395 | public int SkillLevel { get; set; } 396 | public string SpellName { get; set; } 397 | public int WaitTime { get; set; } = 4000; 398 | public string DoNotEndOnBuff { get; set; } 399 | } 400 | } -------------------------------------------------------------------------------- /RazorScripts/SlayerBar.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Diagnostics.CodeAnalysis; 5 | using System.Globalization; 6 | using System.Linq; 7 | using System.Text.RegularExpressions; 8 | using System.Threading; 9 | using RazorEnhanced; 10 | 11 | namespace RazorScripts 12 | { 13 | [SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse")] 14 | public class SlayerBar 15 | { 16 | private Item _SlayerBag { get; set; } 17 | private readonly List _slayerItems = new List(); 18 | private BaseSkill _skill; 19 | // private static string _version = "1.0.1"; 20 | private int _nonSlayerSerial = -1; 21 | private uint _gumpId = 788435749; 22 | //Set to true if you want to open containers to find slayers 23 | //(note that this will open any and all containers in your backpack until a slayer container is found) 24 | private bool _allowOpeningContainers = false; 25 | 26 | private Dictionary _propertyMapper = new Dictionary 27 | { 28 | {BaseSkill.Swordsmanship, 1061172}, 29 | {BaseSkill.MaceFighting, 1061173}, 30 | {BaseSkill.Fencing, 1061174}, 31 | {BaseSkill.Archery, 1061175}, 32 | {BaseSkill.Throwing, 1112075} 33 | }; 34 | 35 | private int GetProperyNumber(BaseSkill skill) 36 | { 37 | if (_propertyMapper.TryGetValue(skill, out var value)) 38 | { 39 | return value; 40 | } 41 | 42 | return 0; 43 | } 44 | 45 | private Func _searchFilter; 46 | private readonly List _slayerList = new List 47 | { 48 | SlayerType.None, 49 | SlayerType.RepondSlayer, 50 | SlayerType.UndeadSlayer, 51 | SlayerType.ReptileSlayer, 52 | SlayerType.DragonSlayer, 53 | SlayerType.ArachnidSlayer, 54 | SlayerType.SpiderSlayer, 55 | SlayerType.ElementalSlayer, 56 | SlayerType.AirElementalSlayer, 57 | SlayerType.FireElementalSlayer, 58 | SlayerType.WaterElementalSlayer, 59 | SlayerType.EarthElementalSlayer, 60 | SlayerType.BloodElementalSlayer, 61 | SlayerType.DemonSlayer, 62 | SlayerType.FeySlayer, 63 | SlayerType.EodonSlayer, 64 | }; 65 | 66 | private bool IsSlayer(Item checkItem) 67 | { 68 | Items.WaitForProps(checkItem,1000); 69 | return checkItem.Properties.Any(p => p.ToString().ToLower().Contains("slayer")) 70 | || checkItem.Properties.Any(p => p.ToString().ToLower().Contains("silver")); 71 | } 72 | 73 | private bool IsCorrectSkill(Item checkItem) 74 | { 75 | Items.WaitForProps(checkItem,1000); 76 | return checkItem.Properties.Any(p => p.Number == GetProperyNumber(_skill)); 77 | } 78 | 79 | private TextInfo _tinfo; 80 | 81 | public void Run() 82 | { 83 | try 84 | { 85 | _tinfo = CultureInfo.CurrentCulture.TextInfo; 86 | _skill = TryFindSkill(); 87 | 88 | if (_skill == BaseSkill.Magery) 89 | { 90 | _searchFilter = i => IsSpellBook(i) 91 | && (IsSlayer(i)); 92 | } 93 | else 94 | { 95 | _searchFilter = i => IsSlayer(i) && IsCorrectSkill(i); 96 | } 97 | 98 | 99 | if (TryFindSlayerBag(Player.Backpack)) 100 | { 101 | SetSlayers(_SlayerBag); 102 | } 103 | else 104 | { 105 | Misc.SendMessage("Unable to find Slayer weapon container, please open the container and try again"); 106 | return; 107 | } 108 | 109 | UpdateBar(); 110 | 111 | while (true) 112 | { 113 | var bar = Gumps.GetGumpData(788435749); 114 | if (bar.buttonid != -1 && bar.buttonid != 0) 115 | { 116 | UpdateBar(); 117 | 118 | EquipSlayer(_slayerItems.FirstOrDefault(i => i.Slayer == (SlayerType)bar.buttonid)); 119 | 120 | UpdateBar(); 121 | } 122 | 123 | 124 | 125 | Misc.Pause(100); 126 | } 127 | } 128 | catch (ThreadAbortException) 129 | { 130 | //Ignore 131 | } 132 | catch (Exception e) 133 | { 134 | Misc.SendMessage(e.ToString()); 135 | throw; 136 | } 137 | finally 138 | { 139 | Gumps.CloseGump(_gumpId); 140 | } 141 | } 142 | 143 | private void EquipSlayer(SlayerItem book) 144 | { 145 | var held = GetEquippedWeapon(); 146 | var resolved = _slayerItems.FirstOrDefault(b => b.Serial == held?.Serial); 147 | if (_SlayerBag == null) 148 | { 149 | Misc.SendMessage("Unable to find slayer bag"); 150 | } 151 | 152 | if (held != null && resolved != null) 153 | { 154 | if (resolved.Serial == book.Serial) 155 | { 156 | return; 157 | } 158 | 159 | var gameEquipped = Items.FindBySerial(resolved.Serial); 160 | var index = _slayerList.IndexOf(resolved.Slayer); 161 | var offset = index > 5 ? 6 : 0; 162 | Items.Move(gameEquipped, _SlayerBag, 1,(index-offset)*20+45, offset == 0 ? 95 : 125); 163 | Misc.Pause(650); 164 | } 165 | else 166 | { 167 | if (held != null) 168 | { 169 | Items.Move(held, Player.Backpack.Serial,held.Amount); 170 | Misc.Pause(600); 171 | } 172 | } 173 | 174 | var gameTarget = Items.FindBySerial(book.Serial); 175 | 176 | while (GetEquippedWeapon()?.ItemID != gameTarget.ItemID) 177 | { 178 | Player.EquipItem(gameTarget); 179 | Misc.Pause(100); 180 | } 181 | Misc.Pause(300); 182 | } 183 | 184 | private int GetActiveSlayerIndex() 185 | { 186 | var held = GetEquippedWeapon(); 187 | var booksSorted = _slayerItems.OrderBy(b => _slayerList.IndexOf(b.Slayer)).ToList(); 188 | var resolved = _slayerItems.FirstOrDefault(b => b.Serial == held?.Serial); 189 | if (resolved != null) 190 | { 191 | return booksSorted.IndexOf(resolved); 192 | } 193 | 194 | return -1; 195 | } 196 | 197 | private void UpdateBar() 198 | { 199 | var activeBookIndex = GetActiveSlayerIndex(); 200 | var bar = Gumps.CreateGump(); 201 | bar.buttonid = -1; 202 | bar.gumpId = _gumpId; 203 | bar.serial = (uint)Player.Serial; 204 | bar.x = 500; 205 | bar.y = 500; 206 | Gumps.AddBackground(ref bar, 0, 0, (_slayerItems.Count*60-5), 55, 1755); 207 | var slayersSorted = _slayerItems.OrderBy(b => _slayerList.IndexOf(b.Slayer)).ToList(); 208 | foreach (var slayerItem in slayersSorted) 209 | { 210 | var index = slayersSorted.IndexOf(slayerItem); 211 | var x = index * 60 + 5; 212 | var y = 5; 213 | Gumps.AddButton(ref bar, x,y,(int)slayerItem.Slayer,(int)slayerItem.Slayer,(int)slayerItem.Slayer,1,0); 214 | Gumps.AddTooltip(ref bar, slayerItem.Name); 215 | } 216 | 217 | if (activeBookIndex != -1) 218 | { 219 | Gumps.AddImage(ref bar, (60 * activeBookIndex-17),0,30071); 220 | } 221 | 222 | Gumps.CloseGump(_gumpId); 223 | Gumps.SendGump(bar, 500,500); 224 | } 225 | 226 | private BaseSkill TryFindSkill() 227 | { 228 | var dict = new Dictionary(); 229 | foreach (var baseSkill in Enum.GetValues(typeof(BaseSkill)).Cast()) 230 | { 231 | // var skillString = _tinfo.ToTitleCase(baseSkill.ToString()); 232 | var value = Player.GetSkillValue(GetSkillName(baseSkill)); 233 | dict.Add(baseSkill, value); 234 | } 235 | 236 | //Return key of highest value 237 | return dict.Aggregate((l, r) => l.Value > r.Value ? l : r).Key; 238 | } 239 | 240 | private string GetSkillName(BaseSkill skill) 241 | { 242 | switch (skill) 243 | { 244 | case BaseSkill.Swordsmanship: 245 | return "Swords"; 246 | case BaseSkill.MaceFighting: 247 | return "Mace Fighting"; 248 | case BaseSkill.Fencing: 249 | return "Fencing"; 250 | case BaseSkill.Archery: 251 | return "Archery"; 252 | case BaseSkill.Throwing: 253 | return "Throwing"; 254 | case BaseSkill.Magery: 255 | return "Magery"; 256 | } 257 | 258 | return ""; 259 | } 260 | 261 | private Item GetEquippedWeapon() 262 | { 263 | var item = Player.GetItemOnLayer("RightHand"); 264 | if (item != null) 265 | { 266 | return item; 267 | } 268 | item = Player.GetItemOnLayer("LeftHand"); 269 | if (item != null) 270 | { 271 | Items.WaitForProps(item,1000); 272 | if (item.Properties.Any(p => p.ToString().ToLower().Contains("two-handed"))) 273 | { 274 | return item; 275 | } 276 | } 277 | 278 | return null; 279 | } 280 | 281 | private bool TryFindSlayerBag(Item container) 282 | { 283 | if (_SlayerBag != null) 284 | { 285 | return true; 286 | } 287 | 288 | var slayersFound = 0; 289 | var held = GetEquippedWeapon(); 290 | if (held != null) 291 | { 292 | var match = IsSlayer(held); 293 | if (match && !IsSpellBook(held)) 294 | { 295 | match = IsCorrectSkill(held); 296 | } 297 | 298 | if (match) 299 | { 300 | slayersFound++; 301 | } 302 | } 303 | 304 | if (_allowOpeningContainers) 305 | { 306 | Items.WaitForContents(container, 1000); 307 | } 308 | 309 | List potentials = new List(); 310 | foreach (var item in container.Contains) 311 | { 312 | Items.WaitForProps(item, 1000); 313 | 314 | if (_searchFilter(item)) 315 | { 316 | potentials.Add(item); 317 | } 318 | 319 | } 320 | 321 | slayersFound += potentials.Count; 322 | 323 | if (slayersFound > 1) 324 | { 325 | _SlayerBag = container; 326 | return true; 327 | } 328 | 329 | foreach (var subContainer in container.Contains.Where(c => c.IsContainer && !c.IsBagOfSending)) 330 | { 331 | var found = TryFindSlayerBag(subContainer); 332 | if (found) 333 | { 334 | return true; 335 | } 336 | } 337 | 338 | return false; 339 | } 340 | 341 | private bool IsSpellBook(Item item) 342 | { 343 | return item.Name.ToLower().Contains("spellbook") || item.Name.Equals("Scrapper's Compendium", StringComparison.InvariantCultureIgnoreCase) || item.Name.Equals("Juo'nar's Grimoire", StringComparison.InvariantCultureIgnoreCase); 344 | } 345 | 346 | private void SetSlayers(Item container) 347 | { 348 | _slayerItems.Clear(); 349 | var compoundList = container.Contains.ToList(); 350 | var held = GetEquippedWeapon(); 351 | if (held != null) 352 | { 353 | compoundList.Add(held); 354 | } 355 | 356 | if (_skill == BaseSkill.Magery) 357 | { 358 | if (_nonSlayerSerial != -1) 359 | { 360 | var nonSlayer = Items.FindBySerial(_nonSlayerSerial); 361 | if (nonSlayer != null) 362 | { 363 | _slayerItems.Add( new SlayerItem 364 | { 365 | Name = _tinfo.ToTitleCase(nonSlayer.Name), 366 | Serial = nonSlayer.Serial, 367 | Slayer = SlayerType.None 368 | }); 369 | } 370 | } 371 | else 372 | { 373 | var nonSlayer = compoundList.FirstOrDefault(i => i.Name.Equals("Scrapper's Compendium", StringComparison.InvariantCultureIgnoreCase)); 374 | if (nonSlayer != null) 375 | { 376 | _slayerItems.Add( new SlayerItem 377 | { 378 | Name = _tinfo.ToTitleCase(nonSlayer.Name), 379 | Serial = nonSlayer.Serial, 380 | Slayer = SlayerType.None 381 | }); 382 | } 383 | } 384 | } 385 | else 386 | { 387 | if (_nonSlayerSerial != -1) 388 | { 389 | var nonSlayer = Items.FindBySerial(_nonSlayerSerial); 390 | if (nonSlayer != null) 391 | { 392 | _slayerItems.Add( new SlayerItem 393 | { 394 | Name = _tinfo.ToTitleCase(nonSlayer.Name), 395 | Serial = nonSlayer.Serial, 396 | Slayer = SlayerType.None 397 | }); 398 | } 399 | } 400 | } 401 | 402 | foreach (var item in compoundList.Where(_searchFilter)) 403 | { 404 | Items.WaitForProps(item,1000); 405 | var prop = item.Properties.FirstOrDefault(p => p.ToString().Contains("slayer")) ?? item.Properties.FirstOrDefault(p => p.Number == 1071451 || p.Number == 1156126); 406 | var slayerString = prop?.ToString().ToLower(); 407 | if (slayerString == "silver") 408 | { 409 | slayerString = "undead slayer"; 410 | } 411 | 412 | 413 | 414 | _slayerItems.Add( new SlayerItem 415 | { 416 | Name = _tinfo.ToTitleCase(prop.ToString()), 417 | Serial = item.Serial, 418 | Slayer = _slayerList.Any(s => _tinfo.ToTitleCase(slayerString).Equals(SplitCamelCase(s.ToString()))) ? _slayerList.First(s => _tinfo.ToTitleCase(slayerString).Equals(SplitCamelCase(s.ToString()))) : SlayerType.UnKnown 419 | }); 420 | 421 | } 422 | } 423 | 424 | private enum BaseSkill 425 | { 426 | Swordsmanship = 0, 427 | MaceFighting = 1, 428 | Fencing = 2, 429 | Archery = 3, 430 | Throwing = 4, 431 | Magery = 5, 432 | } 433 | 434 | public class SlayerItem 435 | { 436 | public int Serial { get; set; } 437 | public string Name { get; set; } 438 | public SlayerType Slayer { get; set; } 439 | } 440 | 441 | public enum SlayerType 442 | { 443 | None = 20744, 444 | RepondSlayer = 2277, 445 | UndeadSlayer = 20486, 446 | ReptileSlayer = 21282, 447 | ArachnidSlayer = 20994, 448 | SpiderSlayer = 20994, 449 | ElementalSlayer = 24014, 450 | AirElementalSlayer = 2299, 451 | FireElementalSlayer = 2302, 452 | WaterElementalSlayer = 2303, 453 | EarthElementalSlayer = 2301, 454 | BloodElementalSlayer = 20993, 455 | DemonSlayer = 2300, 456 | DragonSlayer = 21010, 457 | FeySlayer = 23006, 458 | EodonSlayer = 24011, 459 | UnKnown = 24015 460 | } 461 | 462 | public string SplitCamelCase(string str) 463 | { 464 | return Regex.Replace( 465 | Regex.Replace( 466 | str, 467 | @"(\P{Ll})(\P{Ll}\p{Ll})", 468 | "$1 $2" 469 | ), 470 | @"(\p{Ll})(\P{Ll})", 471 | "$1 $2" 472 | ); 473 | } 474 | } 475 | } -------------------------------------------------------------------------------- /RazorScripts/SummonMaster.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using RazorEnhanced; 7 | using Mobile = RazorEnhanced.Mobile; 8 | 9 | namespace RazorScripts 10 | { 11 | public class SummonMaster 12 | { 13 | private bool _compactMode = false; 14 | private bool _transparancyMode = false; 15 | 16 | private bool _optionShow = false; 17 | private uint Gumpid = 98413566; 18 | private List Summons = new List(); 19 | private List LastLoop = new List(); 20 | private List SerialsLog = new List(); 21 | Dictionary _timers = new Dictionary(); 22 | System.Timers.Timer _timer = new System.Timers.Timer(5000); 23 | private Target _target = new Target(); 24 | private string _version = "1.4.0"; 25 | Journal _journal = new Journal(); 26 | private Journal.JournalEntry _lastJournalEntry = null; 27 | 28 | private List _summonBenefitSpells = new List 29 | { 30 | "In Mani", 31 | "In Vas Mani", 32 | "In Vas Mani Hur", 33 | "Vas An Nox", 34 | "An Nox", 35 | "Olorisstra", 36 | "Rel Sanct" 37 | }; 38 | 39 | public void Run() 40 | { 41 | UpdateGump(); 42 | try 43 | { 44 | _timer.Enabled = true; 45 | _timer.Elapsed += (sender, e) => UpdateGump(); 46 | _timer.AutoReset = true; 47 | _timer.Start(); 48 | 49 | while (true) 50 | { 51 | var newSummons = false; 52 | 53 | var runMobs = Mobiles.ApplyFilter(new Mobiles.Filter 54 | { 55 | RangeMax = 20, 56 | RangeMin = 0, 57 | Notorieties = new List { 1, 2 }, 58 | }).ToList(); 59 | 60 | runMobs.ForEach(m => Mobiles.WaitForProps(m, 1000)); 61 | var runSums = runMobs.Where(m => m.Properties.Any(p => p.Number == (int)PropertyNumber.Summoned)).ToList(); 62 | var mySumms = FilterMySummons(runSums); 63 | Summons = mySumms; 64 | foreach (var summon in Summons) 65 | { 66 | if (SerialsLog.Contains(summon.Serial)) 67 | { 68 | continue; 69 | } 70 | 71 | SerialsLog.Add(summon.Serial); 72 | newSummons = true; 73 | } 74 | var change = false; 75 | if (newSummons) 76 | { 77 | GuardMode(); 78 | } 79 | 80 | var reply = Gumps.GetGumpData(Gumpid); 81 | if (reply.buttonid != -1) 82 | { 83 | switch ((SumReply)reply.buttonid) 84 | { 85 | case SumReply.Guard: 86 | UpdateGump(); 87 | GuardMode(); 88 | reply.buttonid = -1; 89 | break; 90 | case SumReply.Release: 91 | UpdateGump(); 92 | ReleaseAll(); 93 | reply.buttonid = -1; 94 | break; 95 | case SumReply.Follow: 96 | UpdateGump(); 97 | Follow(); 98 | reply.buttonid = -1; 99 | break; 100 | case SumReply.Attack: 101 | var targetSerial = _target.PromptTarget(); 102 | 103 | if(targetSerial != 0) 104 | { 105 | var mob = Mobiles.FindBySerial(targetSerial); 106 | if (mob != null) 107 | { 108 | Attack(mob); 109 | } 110 | } 111 | reply.buttonid = -1; 112 | break; 113 | case SumReply.SetCompact: 114 | _compactMode = true; 115 | break; 116 | case SumReply.SetClassic: 117 | _compactMode = false; 118 | break; 119 | case SumReply.ToggleTransparency: 120 | _transparancyMode = !_transparancyMode; 121 | break; 122 | case SumReply.ToggleOptions: 123 | _optionShow = !_optionShow; 124 | break; 125 | default: 126 | if (Target.HasTarget()) 127 | { 128 | var lines = _journal.GetJournalEntry(_lastJournalEntry).OrderBy(j => j.Timestamp).ToList(); 129 | if (lines.Any()) 130 | { 131 | var lastSpell = lines.LastOrDefault(l => 132 | l.Type.Equals("Spell", StringComparison.InvariantCultureIgnoreCase) && 133 | l.Name.Equals(Player.Name, StringComparison.InvariantCultureIgnoreCase)); 134 | if (lastSpell != null) 135 | { 136 | if (_summonBenefitSpells.Any(word => 137 | lastSpell.Text.Equals(word, 138 | StringComparison.InvariantCultureIgnoreCase))) 139 | { 140 | Target.TargetExecute(reply.buttonid); 141 | UpdateGump(); 142 | reply.buttonid = -1; 143 | _lastJournalEntry = lines.Last(); 144 | break; 145 | } 146 | } 147 | _lastJournalEntry = lines.Last(); 148 | } 149 | } 150 | ReleaseSummon(reply.buttonid); 151 | UpdateGump(); 152 | reply.buttonid = -1; 153 | break; 154 | } 155 | 156 | change = true; 157 | } 158 | 159 | if (Summons.Count != LastLoop.Count) 160 | change = true; 161 | 162 | //compare all Mobiles in Summons with LastLoop, Check Mobile.Warmode and Mobile.Properties for any changes 163 | foreach (var sum in Summons) 164 | { 165 | var last = LastLoop.FirstOrDefault(m => m.Serial == sum.Serial); 166 | if (last == null) 167 | { 168 | change = true; 169 | break; 170 | } 171 | 172 | //check warmode 173 | if (last.WarMode != sum.WarMode) 174 | { 175 | change = true; 176 | break; 177 | } 178 | 179 | //check properties 180 | if (sum.Properties.Count != last.Properties.Count) 181 | { 182 | change = true; 183 | break; 184 | } 185 | 186 | foreach (var prop in sum.Properties) 187 | { 188 | var lastProp = last.Properties.FirstOrDefault(p => p.Number == prop.Number); 189 | if (lastProp == null) 190 | { 191 | //new property 192 | change = true; 193 | break; 194 | } 195 | } 196 | } 197 | 198 | if (change) 199 | { 200 | UpdateGump(); 201 | LastLoop.Clear(); 202 | Summons.ForEach(s => LastLoop.Add(new MockMob 203 | { 204 | Serial = s.Serial, 205 | WarMode = s.WarMode, 206 | Properties = s.Properties.ToList() 207 | })); 208 | } 209 | Misc.Pause(500); 210 | } 211 | } 212 | catch (ThreadAbortException) 213 | { 214 | //silent 215 | } 216 | catch (Exception e) 217 | { 218 | Misc.SendMessage(e.ToString()); 219 | } 220 | finally 221 | { 222 | _timer.Stop(); 223 | _timer.Dispose(); 224 | Gumps.CloseGump(Gumpid); 225 | } 226 | 227 | } 228 | 229 | private List FilterMySummons(List summons) 230 | { 231 | var result = new List(); 232 | foreach (var mob in summons) 233 | { 234 | if(mob.CanRename) 235 | { 236 | result.Add(mob); 237 | } 238 | } 239 | 240 | return result; 241 | } 242 | 243 | private Task GuardMode() 244 | { 245 | foreach (var mob in Summons) 246 | { 247 | Misc.WaitForContext(mob, 500); 248 | Misc.ContextReply(mob, 2); 249 | var timeprop = mob.Properties.FirstOrDefault(p => p.Number == (int)PropertyNumber.TimeRemaining); 250 | if(timeprop != null) 251 | { 252 | var propString = timeprop.Args.Split('\t'); 253 | if(propString.Length >= 2) 254 | { 255 | var parts = propString[1].Split(':'); 256 | if (parts.Length == 2) 257 | { 258 | var time = DateTime.Now.AddMinutes(int.Parse(parts[0])).AddSeconds(int.Parse(parts[1])); 259 | _timers[mob.Serial] = time; 260 | } 261 | } 262 | 263 | } 264 | } 265 | 266 | return Task.CompletedTask; 267 | } 268 | 269 | private Task Follow() 270 | { 271 | foreach (var mob in Summons) 272 | { 273 | Misc.WaitForContext(mob, 500); 274 | Misc.ContextReply(mob, 1); 275 | Target.WaitForTarget(1000); 276 | Target.TargetExecute(Player.Serial); 277 | } 278 | 279 | return Task.CompletedTask; 280 | } 281 | 282 | private Task ReleaseAll() 283 | { 284 | foreach (var mob in Summons) 285 | { 286 | ReleaseSummon(mob.Serial); 287 | } 288 | 289 | return Task.CompletedTask; 290 | } 291 | 292 | private Task Attack(Mobile target) 293 | { 294 | foreach (var mob in Summons) 295 | { 296 | Misc.WaitForContext(mob, 500); 297 | Misc.ContextReply(mob, 0); 298 | Target.WaitForTarget(1000); 299 | Target.TargetExecute(target); 300 | } 301 | 302 | return Task.CompletedTask; 303 | } 304 | 305 | private void ReleaseSummon(int serial) 306 | { 307 | var mob = Mobiles.FindBySerial(serial); 308 | if (mob != null) 309 | { 310 | Misc.WaitForContext(mob, 500); 311 | Misc.ContextReply(mob, 5); 312 | } 313 | } 314 | 315 | private void HandleOptionPanel(Gumps.GumpData gump, int width) 316 | { 317 | var baseX = width+15; 318 | var indentX = baseX+5; 319 | var optionsWidth = 110; 320 | if (_optionShow) 321 | { 322 | Gumps.AddBackground(ref gump,width,0,optionsWidth,140,1755); 323 | if (_transparancyMode) 324 | { 325 | Gumps.AddAlphaRegion(ref gump, width, 0, optionsWidth, 140); 326 | } 327 | 328 | Gumps.AddLabel(ref gump,baseX, 15,0x75, "Mode"); 329 | Gumps.AddButton(ref gump,indentX, 40, 5601, 5601, (int)SumReply.SetCompact, 1, 1); 330 | Gumps.AddLabel(ref gump,indentX+20, 40, _compactMode ? 72 : 0x7b, "Compact"); 331 | Gumps.AddButton(ref gump,indentX, 60, 5601, 5601, (int)SumReply.SetClassic, 1, 1); 332 | Gumps.AddLabel(ref gump,indentX+20, 60,!_compactMode ? 72 : 0x7b, "Classic"); 333 | 334 | Gumps.AddLabel(ref gump,baseX, 85,0x75, "Transparency"); 335 | Gumps.AddButton(ref gump,indentX, 110, 5601, 5601, (int)SumReply.ToggleTransparency, 1, 1); 336 | Gumps.AddLabel(ref gump,indentX+20, 110, _transparancyMode ? 72 : 0x7b, "Ghost"); 337 | 338 | Gumps.AddButton(ref gump, width+optionsWidth-25, 10, 9781, 9781, (int)SumReply.ToggleOptions, 1, 1); 339 | Gumps.AddTooltip(ref gump, "Hide Options"); 340 | } 341 | else 342 | { 343 | Gumps.AddButton(ref gump, width-25, 10, 9780, 9780, (int)SumReply.ToggleOptions, 1, 1); 344 | Gumps.AddTooltip(ref gump, "Show Options"); 345 | } 346 | 347 | } 348 | 349 | private void UpdateGump() 350 | { 351 | var sumGump = Gumps.CreateGump(); 352 | var width = (_compactMode ? (Summons.Count * 58) + 100 : 400)+10; 353 | sumGump.gumpId = Gumpid; 354 | sumGump.serial = (uint)Player.Serial; 355 | Gumps.AddBackground(ref sumGump,0,0, width,140,1755); 356 | if (_transparancyMode) 357 | { 358 | Gumps.AddAlphaRegion(ref sumGump, 0, 0, width, 140); 359 | } 360 | 361 | HandleOptionPanel(sumGump, width); 362 | 363 | foreach (var sum in Summons) 364 | { 365 | var index = Summons.IndexOf(sum) + 1; 366 | 367 | 368 | var healthFraction = (double)sum.Hits / sum.HitsMax; 369 | var healthVal = (int)Math.Floor(healthFraction * 44); 370 | Gumps.AddImageTiled(ref sumGump, index*60-48,30,8,44,9740); 371 | if(sum.Poisoned) 372 | { 373 | Gumps.AddImageTiled(ref sumGump, index*60-48,74-healthVal,8,healthVal,9742); 374 | } 375 | else if(sum.YellowHits) 376 | { 377 | Gumps.AddImageTiled(ref sumGump, index*60-48,74-healthVal,8,healthVal,9743); 378 | } 379 | else 380 | { 381 | Gumps.AddImageTiled(ref sumGump, index*60-48,74-healthVal,8,healthVal,9741); 382 | } 383 | 384 | Gumps.AddButton(ref sumGump,index*60-40,30,GetGumpKey(sum),GetGumpKey(sum),sum.Serial,1,1); 385 | Gumps.AddTooltip(ref sumGump,"Release " + sum.Name); 386 | if (sum.Properties.Any(p => p.Number == (int)PropertyNumber.Guarding)) 387 | { 388 | Gumps.AddLabel(ref sumGump, index*60-40+5,75,0x35,"Guard"); 389 | } 390 | if (sum.WarMode) 391 | { 392 | Gumps.AddLabel(ref sumGump, index*60-40+2,90,0x25,"Combat"); 393 | } 394 | if(_timers.ContainsKey(sum.Serial)) 395 | { 396 | var time = _timers[sum.Serial]; 397 | var diff = time - DateTime.Now; 398 | Gumps.AddLabel(ref sumGump, index*60-40+5,10,0x35,$"{diff.Minutes.ToString("D2")}:{diff.Seconds.ToString("D2")}"); 399 | } 400 | } 401 | 402 | Gumps.AddButton(ref sumGump, width - 90, 10, 9903, 9904, (int)SumReply.Attack, 1, 0); 403 | Gumps.AddButton(ref sumGump, width - 90, 40, 9903, 9904, (int)SumReply.Release, 1, 0); 404 | Gumps.AddButton(ref sumGump, width - 90, 70, 9903, 9904, (int)SumReply.Guard, 1, 0); 405 | Gumps.AddButton(ref sumGump, width - 90, 100, 9903, 9904, (int)SumReply.Follow, 1, 0); 406 | Gumps.AddLabel(ref sumGump, width - 70, 10, 0x30, "Attack"); 407 | Gumps.AddLabel(ref sumGump, width - 70, 40, 0x6D, "Release"); 408 | Gumps.AddLabel(ref sumGump, width - 70, 70, 0x35, "Guard"); 409 | Gumps.AddLabel(ref sumGump, width - 70, 100, 0x55, "Follow"); 410 | 411 | if (!_compactMode || Summons.Count >= 2) 412 | { 413 | Gumps.AddLabel(ref sumGump, 15, 115, 0x7b, "SummonMaster"); 414 | Gumps.AddLabel(ref sumGump, 100, 115, 0x7b, _version); 415 | } 416 | 417 | Gumps.CloseGump(Gumpid); 418 | Gumps.SendGump(sumGump,500,500); 419 | } 420 | 421 | private int GetGumpKey(Mobile mobile) 422 | { 423 | switch ((KnownSummon)mobile.MobileID) 424 | { 425 | case KnownSummon.Fey: 426 | return 23006; 427 | case KnownSummon.AirElemental: 428 | return 2299; 429 | case KnownSummon.Daemon: 430 | return 2300; 431 | case KnownSummon.EarthElemental: 432 | return 2301; 433 | case KnownSummon.FireElemental: 434 | return 2302; 435 | case KnownSummon.WaterElemental: 436 | return 2303; 437 | case KnownSummon.Colossus: 438 | return 24015; 439 | case KnownSummon.AnimateWeapon: 440 | return 24006; 441 | default : 442 | return 2279; 443 | } 444 | } 445 | 446 | private enum PropertyNumber 447 | { 448 | Summoned = 1049646, 449 | Guarding = 1080078, 450 | TimeRemaining = 1060847 451 | } 452 | 453 | private enum KnownSummon 454 | { 455 | BladeSpirits = 0x023E, 456 | EnergyVortex = 0x00A4, 457 | Fey = 0x0080, 458 | AnimateWeapon = 0x02B4, 459 | EarthElemental = 0x000E, 460 | AirElemental = 0x000D, 461 | FireElemental = 0x000F, 462 | WaterElemental = 0x0010, 463 | Daemon = 0x000A, 464 | Colossus = 0x033D 465 | } 466 | 467 | private enum SumReply 468 | { 469 | Attack = 1, 470 | Release = 2, 471 | Guard = 3, 472 | Follow = 4, 473 | SetCompact = 5, 474 | SetClassic = 6, 475 | ToggleTransparency = 7, 476 | ToggleOptions = 8 477 | } 478 | 479 | private class MockMob 480 | { 481 | public int Serial { get; set; } 482 | public List Properties { get; set; } 483 | public bool WarMode { get; set; } 484 | } 485 | } 486 | } --------------------------------------------------------------------------------