diff --git a/KHAOS.COMMANDS.md b/KHAOS.COMMANDS.md index 372d01a..380710a 100644 --- a/KHAOS.COMMANDS.md +++ b/KHAOS.COMMANDS.md @@ -25,7 +25,7 @@ * command honest * Subweapons Only: Can only use subweapons for combat for the next minute. Gives Alucard Cube of Zoe, a subweapon and 200 hearts. * command subonly -* Cripple: Not so fast! Speed set to 75% +* Cripple: Not so fast! Speed set to 75% for one minute. * command cripple * Blood Mana: Spells now cost HP instead of mana. * command bloodmana @@ -53,3 +53,5 @@ * command fourbeasts * ZA WARUDO: mudamudamudamudamudamudamudamudamudamudamudamudamudamudamudamudamudamuda * command zawarudo +* Haste: Increase movement speed for one minute. + * command haste diff --git a/README.md b/README.md index 0a7960a..edb6b28 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,6 @@ The new tracker has been re-written from the ground up for better performance an ## Co-Op Currently coop requires the host to have the port they want to use forwarded. Hosting automatically copies your address(ip:port) to the clipboard. The other player uses that address to connect. Please be careful to not leak your IP! -Enable BizHawk messages through `View > Display Messages`. Open the BizHawk console through `View > Open Log Window` for detailed information. The Select button is used to send the currently highlighted item in the inventory or relic in the relic menu. The Circle button is used to perform an assist action. Using a potion in your inventory and activating it for the other player. diff --git a/SotnRandoTools/src/Configuration/KhaosConfig.cs b/SotnRandoTools/src/Configuration/KhaosConfig.cs index 11fd9a4..5aa1fc9 100644 --- a/SotnRandoTools/src/Configuration/KhaosConfig.cs +++ b/SotnRandoTools/src/Configuration/KhaosConfig.cs @@ -10,8 +10,15 @@ public KhaosConfig() { Alerts = true; ControlPannelQueueActions = true; - Volume = 8; + Volume = 2; BotActionsFilePath = ""; + WeakenFactor = 0.5F; + CrippleFactor = 0.8F; + HasteFactor = 1.3F; + ThirstDrainPerSecond = 1; + PandoraMinItems = 3; + PandoraMaxItems = 32; + Actions = new List { new Action{Name="Khaos Status", Aliases = new string[] {"kstatus"}, Enabled = true, Scaling = false}, @@ -25,5 +32,11 @@ public KhaosConfig() public string BotActionsFilePath { get; set; } public List Actions { get; set; } + public float WeakenFactor { get; set; } + public float CrippleFactor { get; set; } + public float HasteFactor { get; set; } + public uint ThirstDrainPerSecond { get; set; } + public int PandoraMinItems { get; set; } + public int PandoraMaxItems { get; set; } } } diff --git a/SotnRandoTools/src/Constants/Paths.cs b/SotnRandoTools/src/Constants/Paths.cs index 8e90507..bb4cb88 100644 --- a/SotnRandoTools/src/Constants/Paths.cs +++ b/SotnRandoTools/src/Constants/Paths.cs @@ -6,10 +6,17 @@ public static class Paths public const string AlertDeathLaugh = "./ExternalTools/SotnRandoTools/Sounds/DeathLaugh.wav"; public const string AlertLibrarianThankYou = "./ExternalTools/SotnRandoTools/Sounds/LibrarianThankYou.wav"; public const string AlertFairyPotion = "./ExternalTools/SotnRandoTools/Sounds/FairyPotion.wav"; - public const string AlertMelty = "./ExternalTools/SotnRandoTools/Sounds/Melty.wav"; + public const string AlertMelty = "./ExternalTools/SotnRandoTools/Sounds/Melty.mp3"; public const string AlertZaWarudo = "./ExternalTools/SotnRandoTools/Sounds/ZaWarudo.wav"; public const string AlertAlucardWhat = "./ExternalTools/SotnRandoTools/Sounds/AlucardWhat.wav"; + public const string SourceLink = "https://github.com/TalicZealot/SotnRandoTools/"; + public const string ReadmeLink = "https://github.com/TalicZealot/SotnRandoTools/blob/main/README.md"; + public const string ApiLink = "https://github.com/TalicZealot/SotnApi"; + public const string UpdaterLink = "https://github.com/TalicZealot/SimpleLatestReleaseUpdater"; + public const string RandoSourceLink = "https://github.com/3snowp7im/SotN-Randomizer"; + public const string DonateLink = "https://streamlabs.com/taliczealot"; + public const string LatestReleaseApi = "https://api.github.com/repos/taliczealot/sotnrandotools/releases"; public const string LatestReleaseUrl = "https://github.com/TalicZealot/SotnRandoTools/releases/latest"; public const string UpdaterPath = @"\ExternalTools\SotnRandoTools\Updater\SimpleLatestReleaseUpdater.exe"; diff --git a/SotnRandoTools/src/Coop/CoopMessanger.cs b/SotnRandoTools/src/Coop/CoopMessanger.cs index 337b0c4..6cbafa0 100644 --- a/SotnRandoTools/src/Coop/CoopMessanger.cs +++ b/SotnRandoTools/src/Coop/CoopMessanger.cs @@ -4,6 +4,7 @@ using SotnRandoTools.Configuration.Interfaces; using SotnRandoTools.Coop.Enums; using SotnRandoTools.Coop.Interfaces; +using SotnRandoTools.Coop.Models; using SotnRandoTools.Utils; namespace SotnRandoTools.Coop @@ -12,24 +13,31 @@ public class CoopMessanger : ICoopMessanger { private readonly IToolConfig toolConfig; private readonly ICoopReceiver coopReceiver; + private readonly ICoopViewModel coopViewModel; + private SimpleTcpServer? server; private SimpleTcpClient? client; private string connectedClientAddress = ""; private bool manualDisconnect = false; - public CoopMessanger(IToolConfig toolConfig, ICoopReceiver coopReceiver) + public CoopMessanger(IToolConfig toolConfig, ICoopReceiver coopReceiver, ICoopViewModel coopViewModel) { if (toolConfig is null) throw new ArgumentNullException(nameof(toolConfig)); if (coopReceiver is null) throw new ArgumentNullException(nameof(coopReceiver)); + if (coopViewModel is null) throw new ArgumentNullException(nameof(coopViewModel)); this.toolConfig = toolConfig; this.coopReceiver = coopReceiver; + this.coopViewModel = coopViewModel; } - public bool Connect(string hostIp, int port) + public void Connect(string hostIp, int port) { if (client is null) { client = new SimpleTcpClient(hostIp, port); + client.Events.DataReceived += DataReceived; + client.Events.Connected += Connected; + client.Events.Disconnected += Disconnected; } try @@ -38,28 +46,25 @@ public bool Connect(string hostIp, int port) } catch (Exception) { - Console.WriteLine("Connection timed out."); - return false; + Console.WriteLine("Connection timed out!"); + coopViewModel.ClientConnected = false; + return; } - client.Events.DataReceived += DataReceived; - client.Events.Connected += Connected; - client.Events.Disconnected += Disconnected; - - return true; + return; } public void Disconnect() { - if (client is not null) + if (client is not null && client.IsConnected) { manualDisconnect = true; client.Disconnect(); - client.Dispose(); + coopViewModel.ClientConnected = false; } } - public bool StartServer(int port) + public void StartServer(int port) { string hostName = Dns.GetHostName(); @@ -72,23 +77,47 @@ public bool StartServer(int port) server.Events.DataReceived += DataReceived; } - server.Start(); + try + { + coopViewModel.ServerStarted = true; + server.Start(); + } + catch (Exception) + { + Console.WriteLine("Error: Could not start server!"); + coopViewModel.ServerStarted = false; + return; + } + string myIP = WebRequests.getExternalIP().Replace("\n", ""); System.Windows.Forms.Clipboard.SetText(myIP + ":" + port); - toolConfig.Coop.InitiateServerSettings(); Console.WriteLine($"Server started. Address copied to clipboard."); + coopViewModel.Message = "Server started"; - return true; + return; } public void StopServer() { - if (server is not null) + if (server is not null && server.IsListening) { + coopViewModel.ServerStarted = false; + server.DisconnectClient(connectedClientAddress); server.Stop(); + } + } + + public void DisposeAll() + { + if (server is not null) + { server.Dispose(); } + if (client is not null) + { + client.Dispose(); + } } public void SendData(MessageType type, byte[] data) @@ -110,6 +139,9 @@ public void SendData(MessageType type, byte[] data) private void Connected(object sender, ClientConnectedEventArgs e) { Console.WriteLine("Connected successfully."); + coopViewModel.ClientConnected = true; + coopViewModel.Message = "Connected"; + if (toolConfig.Coop.StoreLastServer) { toolConfig.Coop.DefaultServer = client.ServerIpPort; @@ -118,14 +150,27 @@ private void Connected(object sender, ClientConnectedEventArgs e) private void Disconnected(object sender, ClientDisconnectedEventArgs e) { - Console.WriteLine($"Disconnected from host."); + Console.WriteLine("Disconnected from host."); if (!manualDisconnect) { Console.WriteLine($"Attempting to reconnect..."); - client.ConnectWithRetries(2 * 1000); + coopViewModel.Message = "Reconnecting..."; + try + { + client.ConnectWithRetries(2 * 1000); + } + catch (Exception) + { + coopViewModel.Message = "Disconnected"; + Console.WriteLine("Connection timed out!"); + coopViewModel.ClientConnected = false; + return; + } } else { + coopViewModel.Message = "Disconnected"; + coopViewModel.ClientConnected = false; manualDisconnect = false; } } @@ -140,6 +185,7 @@ private void ClientConnected(object sender, ClientConnectedEventArgs e) private void ClientDisconnected(object sender, ClientDisconnectedEventArgs e) { + coopViewModel.Message = "Client disconnected"; Console.WriteLine($"Client has disconnected."); if (connectedClientAddress == e.IpPort) { diff --git a/SotnRandoTools/src/Coop/CoopReceiver.cs b/SotnRandoTools/src/Coop/CoopReceiver.cs index 9ba9933..27d4a43 100644 --- a/SotnRandoTools/src/Coop/CoopReceiver.cs +++ b/SotnRandoTools/src/Coop/CoopReceiver.cs @@ -37,6 +37,12 @@ public void ProcessMessage(byte[] data) { MessageType type = (MessageType) data[0]; ushort index = BitConverter.ToUInt16(data, 1); + byte indexByte = data[1]; + byte dataByte = 0; + if (data.Length > 2) + { + dataByte = data[2]; + } switch (type) { case MessageType.Relic: @@ -50,11 +56,11 @@ public void ProcessMessage(byte[] data) } break; case MessageType.Location: - gameApi.SetRoomToVisited(watchlistService.CoopLocationWatches[index].Address); + gameApi.SetRoomValue(watchlistService.CoopLocationWatches[indexByte].Address, dataByte); watchlistService.UpdateWatchlist(watchlistService.CoopLocationWatches); watchlistService.CoopLocationWatches.ClearChangeCounts(); - notificationService.DisplayMessage(watchlistService.CoopLocationWatches[index].Notes); - Console.WriteLine($"Received location: {watchlistService.CoopLocationWatches[index].Notes}"); + //notificationService.DisplayMessage($"location {watchlistService.CoopLocationWatches[indexByte].Notes}"); + Console.WriteLine($"Received location: {watchlistService.CoopLocationWatches[indexByte].Notes}"); break; case MessageType.Item: alucardApi.GrantItemByName(Equipment.Items[index]); @@ -240,7 +246,7 @@ private void DecodeShortcut(Shortcut shortcut) } break; default: - Console.WriteLine($"RShortcut {shortcut} not found!"); + Console.WriteLine($"Shortcut {shortcut} not found!"); return; } diff --git a/SotnRandoTools/src/Coop/CoopSender.cs b/SotnRandoTools/src/Coop/CoopSender.cs index 0c75fb3..1ee2b75 100644 --- a/SotnRandoTools/src/Coop/CoopSender.cs +++ b/SotnRandoTools/src/Coop/CoopSender.cs @@ -184,7 +184,7 @@ private void UpdateLocations() { if (watchlistService.CoopLocationWatches[i].Value > 0) { - coopMessanger.SendData(MessageType.Location, BitConverter.GetBytes((ushort) i)); + coopMessanger.SendData(MessageType.Location, new byte[] { (byte) i, (byte) watchlistService.CoopLocationWatches[i].Value }); Console.WriteLine($"Sending Location: {watchlistService.CoopLocationWatches[i].Notes}"); } } diff --git a/SotnRandoTools/src/Coop/Interfaces/ICoopMessanger.cs b/SotnRandoTools/src/Coop/Interfaces/ICoopMessanger.cs index 036e744..eb633c3 100644 --- a/SotnRandoTools/src/Coop/Interfaces/ICoopMessanger.cs +++ b/SotnRandoTools/src/Coop/Interfaces/ICoopMessanger.cs @@ -4,10 +4,11 @@ namespace SotnRandoTools.Coop.Interfaces { public interface ICoopMessanger { - bool Connect(string hostIp, int port); + void Connect(string hostIp, int port); void Disconnect(); - bool StartServer(int port); + void StartServer(int port); void StopServer(); + void DisposeAll(); void SendData(MessageType type, byte[] data); } } \ No newline at end of file diff --git a/SotnRandoTools/src/Coop/Interfaces/ICoopViewModel.cs b/SotnRandoTools/src/Coop/Interfaces/ICoopViewModel.cs new file mode 100644 index 0000000..9570dfb --- /dev/null +++ b/SotnRandoTools/src/Coop/Interfaces/ICoopViewModel.cs @@ -0,0 +1,13 @@ +using System.ComponentModel; + +namespace SotnRandoTools.Coop.Models +{ + public interface ICoopViewModel + { + bool ClientConnected { get; set; } + bool ServerStarted { get; set; } + string Message { get; set; } + + event PropertyChangedEventHandler PropertyChanged; + } +} \ No newline at end of file diff --git a/SotnRandoTools/src/Coop/Models/CoopViewModel.cs b/SotnRandoTools/src/Coop/Models/CoopViewModel.cs new file mode 100644 index 0000000..89dd731 --- /dev/null +++ b/SotnRandoTools/src/Coop/Models/CoopViewModel.cs @@ -0,0 +1,62 @@ +using System.ComponentModel; + +namespace SotnRandoTools.Coop.Models +{ + public class CoopViewModel : INotifyPropertyChanged, ICoopViewModel + { + private bool serverStarted; + private bool clientConnected; + private string message; + public bool ServerStarted + { + get + { + return serverStarted; + } + set + { + serverStarted = value; + + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs("ServerStarted")); + } + } + } + public bool ClientConnected + { + get + { + return clientConnected; + } + set + { + clientConnected = value; + + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs("ClientConnected")); + } + } + } + + public string Message + { + get + { + return message; + } + set + { + message = value; + + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs("Message")); + } + } + } + + public event PropertyChangedEventHandler PropertyChanged; + } +} diff --git a/SotnRandoTools/src/CoopForm.Designer.cs b/SotnRandoTools/src/CoopForm.Designer.cs index 41aaec7..0e604a5 100644 --- a/SotnRandoTools/src/CoopForm.Designer.cs +++ b/SotnRandoTools/src/CoopForm.Designer.cs @@ -29,6 +29,7 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CoopForm)); this.hostButton = new System.Windows.Forms.Button(); this.connectButton = new System.Windows.Forms.Button(); @@ -36,15 +37,26 @@ private void InitializeComponent() this.IPlabel = new System.Windows.Forms.Label(); this.portLabel = new System.Windows.Forms.Label(); this.portNumeric = new System.Windows.Forms.NumericUpDown(); + this.serverGroup = new System.Windows.Forms.GroupBox(); + this.clientGroup = new System.Windows.Forms.GroupBox(); + this.addressTooltip = new System.Windows.Forms.ToolTip(this.components); ((System.ComponentModel.ISupportInitialize)(this.portNumeric)).BeginInit(); + this.serverGroup.SuspendLayout(); + this.clientGroup.SuspendLayout(); this.SuspendLayout(); // // hostButton // + this.hostButton.CausesValidation = false; + this.hostButton.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(57)))), ((int)(((byte)(21)))), ((int)(((byte)(57))))); + this.hostButton.FlatAppearance.BorderSize = 2; + this.hostButton.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(67)))), ((int)(((byte)(35)))), ((int)(((byte)(67))))); + this.hostButton.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(20)))), ((int)(((byte)(48))))); + this.hostButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.hostButton.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.hostButton.Location = new System.Drawing.Point(4, 8); + this.hostButton.Location = new System.Drawing.Point(8, 18); this.hostButton.Name = "hostButton"; - this.hostButton.Size = new System.Drawing.Size(85, 21); + this.hostButton.Size = new System.Drawing.Size(85, 23); this.hostButton.TabIndex = 0; this.hostButton.Text = "Host"; this.hostButton.UseVisualStyleBackColor = true; @@ -52,10 +64,15 @@ private void InitializeComponent() // // connectButton // + this.connectButton.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(57)))), ((int)(((byte)(21)))), ((int)(((byte)(57))))); + this.connectButton.FlatAppearance.BorderSize = 2; + this.connectButton.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(67)))), ((int)(((byte)(35)))), ((int)(((byte)(67))))); + this.connectButton.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(20)))), ((int)(((byte)(48))))); + this.connectButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.connectButton.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.connectButton.Location = new System.Drawing.Point(5, 33); + this.connectButton.Location = new System.Drawing.Point(8, 14); this.connectButton.Name = "connectButton"; - this.connectButton.Size = new System.Drawing.Size(85, 21); + this.connectButton.Size = new System.Drawing.Size(261, 24); this.connectButton.TabIndex = 1; this.connectButton.Text = "Connect"; this.connectButton.UseVisualStyleBackColor = true; @@ -64,13 +81,14 @@ private void InitializeComponent() // targetIp // this.targetIp.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.targetIp.Location = new System.Drawing.Point(141, 33); + this.targetIp.Location = new System.Drawing.Point(49, 44); this.targetIp.Name = "targetIp"; - this.targetIp.Size = new System.Drawing.Size(139, 21); + this.targetIp.Size = new System.Drawing.Size(219, 21); this.targetIp.TabIndex = 2; this.targetIp.UseSystemPasswordChar = true; this.targetIp.TextChanged += new System.EventHandler(this.targetIp_TextChanged); this.targetIp.Validating += new System.ComponentModel.CancelEventHandler(this.targetIp_Validating); + this.targetIp.Validated += new System.EventHandler(this.targetIp_Validated); // // IPlabel // @@ -78,12 +96,12 @@ private void InitializeComponent() this.IPlabel.BackColor = System.Drawing.Color.Transparent; this.IPlabel.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); this.IPlabel.ForeColor = System.Drawing.Color.White; - this.IPlabel.Location = new System.Drawing.Point(91, 37); + this.IPlabel.Location = new System.Drawing.Point(5, 47); this.IPlabel.Margin = new System.Windows.Forms.Padding(0); this.IPlabel.Name = "IPlabel"; - this.IPlabel.Size = new System.Drawing.Size(50, 13); + this.IPlabel.Size = new System.Drawing.Size(41, 13); this.IPlabel.TabIndex = 4; - this.IPlabel.Text = "Address:"; + this.IPlabel.Text = "IP:port"; // // portLabel // @@ -91,7 +109,7 @@ private void InitializeComponent() this.portLabel.BackColor = System.Drawing.Color.Transparent; this.portLabel.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); this.portLabel.ForeColor = System.Drawing.Color.White; - this.portLabel.Location = new System.Drawing.Point(109, 12); + this.portLabel.Location = new System.Drawing.Point(99, 23); this.portLabel.Name = "portLabel"; this.portLabel.Size = new System.Drawing.Size(31, 13); this.portLabel.TabIndex = 5; @@ -100,7 +118,7 @@ private void InitializeComponent() // portNumeric // this.portNumeric.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.portNumeric.Location = new System.Drawing.Point(141, 8); + this.portNumeric.Location = new System.Drawing.Point(129, 20); this.portNumeric.Maximum = new decimal(new int[] { 49151, 0, @@ -120,16 +138,46 @@ private void InitializeComponent() 0, 0}); // + // serverGroup + // + this.serverGroup.Controls.Add(this.hostButton); + this.serverGroup.Controls.Add(this.portNumeric); + this.serverGroup.Controls.Add(this.portLabel); + this.serverGroup.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.serverGroup.ForeColor = System.Drawing.Color.White; + this.serverGroup.Location = new System.Drawing.Point(4, 12); + this.serverGroup.Name = "serverGroup"; + this.serverGroup.Size = new System.Drawing.Size(275, 58); + this.serverGroup.TabIndex = 7; + this.serverGroup.TabStop = false; + this.serverGroup.Text = "Server"; + // + // clientGroup + // + this.clientGroup.Controls.Add(this.connectButton); + this.clientGroup.Controls.Add(this.targetIp); + this.clientGroup.Controls.Add(this.IPlabel); + this.clientGroup.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.clientGroup.ForeColor = System.Drawing.Color.White; + this.clientGroup.Location = new System.Drawing.Point(4, 74); + this.clientGroup.Name = "clientGroup"; + this.clientGroup.Size = new System.Drawing.Size(275, 79); + this.clientGroup.TabIndex = 8; + this.clientGroup.TabStop = false; + this.clientGroup.Text = "Client"; + // + // addressTooltip + // + this.addressTooltip.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Error; + // // CoopForm // + this.AutoValidate = System.Windows.Forms.AutoValidate.EnableAllowFocusChange; this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(0)))), ((int)(((byte)(17))))); - this.ClientSize = new System.Drawing.Size(284, 61); - this.Controls.Add(this.portNumeric); - this.Controls.Add(this.portLabel); - this.Controls.Add(this.IPlabel); - this.Controls.Add(this.targetIp); - this.Controls.Add(this.connectButton); - this.Controls.Add(this.hostButton); + this.CausesValidation = false; + this.ClientSize = new System.Drawing.Size(284, 158); + this.Controls.Add(this.clientGroup); + this.Controls.Add(this.serverGroup); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.MaximizeBox = false; @@ -142,8 +190,11 @@ private void InitializeComponent() this.Load += new System.EventHandler(this.CoopForm_Load); this.Move += new System.EventHandler(this.CoopForm_Move); ((System.ComponentModel.ISupportInitialize)(this.portNumeric)).EndInit(); + this.serverGroup.ResumeLayout(false); + this.serverGroup.PerformLayout(); + this.clientGroup.ResumeLayout(false); + this.clientGroup.PerformLayout(); this.ResumeLayout(false); - this.PerformLayout(); } @@ -155,6 +206,9 @@ private void InitializeComponent() private System.Windows.Forms.Label IPlabel; private System.Windows.Forms.Label portLabel; private System.Windows.Forms.NumericUpDown portNumeric; + private System.Windows.Forms.GroupBox serverGroup; + private System.Windows.Forms.GroupBox clientGroup; + private System.Windows.Forms.ToolTip addressTooltip; } } diff --git a/SotnRandoTools/src/CoopForm.cs b/SotnRandoTools/src/CoopForm.cs index 69735fb..e3b0ab4 100644 --- a/SotnRandoTools/src/CoopForm.cs +++ b/SotnRandoTools/src/CoopForm.cs @@ -1,10 +1,13 @@ using System; +using System.ComponentModel; +using System.Drawing; using System.Text.RegularExpressions; using System.Windows.Forms; using BizHawk.Client.Common; using SotnApi.Interfaces; using SotnRandoTools.Configuration.Interfaces; using SotnRandoTools.Coop; +using SotnRandoTools.Coop.Models; using SotnRandoTools.Services; namespace SotnRandoTools @@ -15,19 +18,62 @@ public partial class CoopForm : Form private readonly CoopSender coopSender; private readonly CoopMessanger coopMessanger; private readonly CoopReceiver coopReceiver; + private readonly INotificationService notificationService; + private CoopViewModel coopViewModel = new CoopViewModel(); + private bool addressValidated = false; public CoopForm(IToolConfig toolConfig, IWatchlistService watchlistService, IGameApi gameApi, IAlucardApi alucardApi, IJoypadApi joypadApi, INotificationService notificationService) { if (toolConfig is null) throw new ArgumentNullException(nameof(toolConfig)); + if (watchlistService is null) throw new ArgumentNullException(nameof(watchlistService)); + if (gameApi is null) throw new ArgumentNullException(nameof(gameApi)); + if (alucardApi is null) throw new ArgumentNullException(nameof(alucardApi)); + if (joypadApi is null) throw new ArgumentNullException(nameof(joypadApi)); + if (notificationService is null) throw new ArgumentNullException(nameof(notificationService)); this.toolConfig = toolConfig; + this.notificationService = notificationService; this.coopReceiver = new CoopReceiver(toolConfig, gameApi, alucardApi, notificationService, watchlistService); - this.coopMessanger = new CoopMessanger(toolConfig, coopReceiver); + this.coopMessanger = new CoopMessanger(toolConfig, coopReceiver, coopViewModel); this.coopSender = new CoopSender(toolConfig, watchlistService, gameApi, alucardApi, joypadApi, coopMessanger); InitializeComponent(); SuspendLayout(); ResumeLayout(); this.portNumeric.Controls[0].Visible = false; + coopViewModel.PropertyChanged += CoopViewModelPropertyChanged; + } + + private void CoopViewModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + if (e.PropertyName == "Message") + { + notificationService.DisplayMessage(coopViewModel.Message); + return; + } + + if (!coopViewModel.ClientConnected && !coopViewModel.ServerStarted) + { + this.connectButton.Text = "Connect"; + this.hostButton.Text = "Host"; + this.hostButton.Enabled = true; + this.connectButton.Enabled = true; + this.targetIp.Enabled = true; + this.portNumeric.Enabled = true; + } + else if (coopViewModel.ClientConnected) + { + this.connectButton.Text = "Disconnect"; + this.hostButton.Enabled = false; + this.targetIp.Enabled = false; + this.portNumeric.Enabled = false; + } + else if (coopViewModel.ServerStarted) + { + this.hostButton.Text = "Stop"; + this.connectButton.Enabled = false; + this.targetIp.Enabled = false; + this.portNumeric.Enabled = false; + } } public void UpdateCoop() @@ -40,6 +86,7 @@ private void CoopForm_Load(object sender, EventArgs e) this.Location = toolConfig.Coop.Location; this.portNumeric.Value = toolConfig.Coop.DefaultPort; this.targetIp.Text = toolConfig.Coop.DefaultServer; + ValidateAddress(); } private void CoopForm_Move(object sender, EventArgs e) @@ -56,6 +103,12 @@ private void CoopForm_FormClosed(object sender, FormClosedEventArgs e) private void hostButton_Click(object sender, EventArgs e) { + if (coopViewModel.ServerStarted) + { + coopMessanger.StopServer(); + return; + } + int port = (int) this.portNumeric.Value; if (port > 1024 && port < 49151) @@ -66,10 +119,15 @@ private void hostButton_Click(object sender, EventArgs e) private void connectButton_Click(object sender, EventArgs e) { + if (coopViewModel.ClientConnected) + { + coopMessanger.Disconnect(); + return; + } + string[] hostAddress = this.targetIp.Text.Split(':'); - string[] ip = hostAddress[0].Split('.'); - Regex validIpPort = new Regex(@"^(\d{1,3})\.(\d{1,3})\.(\d{1,3}).(\d{1,3})\:(\d{2,5})$"); - if (!validIpPort.IsMatch(this.targetIp.Text)) + + if (!addressValidated) { Console.WriteLine("Invalid address!"); } @@ -82,26 +140,46 @@ private void connectButton_Click(object sender, EventArgs e) private void targetIp_Validating(object sender, System.ComponentModel.CancelEventArgs e) { - Regex validIpPort = new Regex(@"^(\d{1,3})\.(\d{1,3})\.(\d{1,3}).(\d{1,3})\:(\d{2,5})$"); - if (!validIpPort.IsMatch(this.targetIp.Text)) + //If validation is triggered by the form, return in order to ignore it and let the user close the window. + if (this.ActiveControl.Equals(sender)) + return; + if (!ValidateAddress()) { e.Cancel = true; } } + private bool ValidateAddress() + { + Regex validIpPort = new Regex(@"^(\d{1,3})\.(\d{1,3})\.(\d{1,3}).(\d{1,3})\:(\d{3,5})$"); + if (!validIpPort.IsMatch(this.targetIp.Text)) + { + addressValidated = false; + this.targetIp.Text = ""; + this.targetIp.BackColor = Color.Red; + this.addressTooltip.SetToolTip(targetIp, "Invalid address!"); + this.addressTooltip.ToolTipIcon = ToolTipIcon.Warning; + return false; + } + addressValidated = true; + return true; + } + private void CoopForm_FormClosing(object sender, FormClosingEventArgs e) { coopMessanger.Disconnect(); coopMessanger.StopServer(); + coopMessanger.DisposeAll(); } private void targetIp_TextChanged(object sender, EventArgs e) { - //Until I can get the client connected event to fire. - if (toolConfig.Coop.StoreLastServer) - { - toolConfig.Coop.DefaultServer = targetIp.Text; - } + this.targetIp.BackColor = Color.White; + } + + private void targetIp_Validated(object sender, EventArgs e) + { + addressValidated = true; } } } diff --git a/SotnRandoTools/src/CoopForm.resx b/SotnRandoTools/src/CoopForm.resx index e0fd13b..e804a96 100644 --- a/SotnRandoTools/src/CoopForm.resx +++ b/SotnRandoTools/src/CoopForm.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + diff --git a/SotnRandoTools/src/Khaos/KhaosController.cs b/SotnRandoTools/src/Khaos/KhaosController.cs index 76e717c..76f6215 100644 --- a/SotnRandoTools/src/Khaos/KhaosController.cs +++ b/SotnRandoTools/src/Khaos/KhaosController.cs @@ -1,9 +1,8 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Windows.Forms; -using System.Windows.Media; - using BizHawk.Client.Common; using SotnApi.Constants.Addresses; using SotnApi.Constants.Values.Alucard; @@ -21,20 +20,12 @@ namespace SotnRandoTools.Khaos { public class KhaosController { - private const float WeakenFactor = 0.5F; - private const float CrippleFactor = 0.8F; - private const int DrainPerSecond = 1; - private const int PandoraMinItems = 3; - private const int PandoraMaxItems = 32; - private readonly IToolConfig toolConfig; private readonly IGameApi gameApi; private readonly IAlucardApi alucardApi; private readonly IActorApi actorApi; private readonly ICheatCollectionAdapter cheats; private readonly INotificationService notificationService; - //replace with WMPLib.WindowsMediaPlayer - private MediaPlayer audioPlayer = new MediaPlayer(); private string[] lightHelpItems = @@ -161,11 +152,8 @@ public class KhaosController private Timer actionTimer = new Timer(); private Timer fastActionTimer = new Timer(); - private System.Timers.Timer zawarudoTimer = new System.Timers.Timer(); private System.Timers.Timer honestGamerTimer = new System.Timers.Timer(); private System.Timers.Timer subweaponsOnlyTimer = new System.Timers.Timer(); - private System.Timers.Timer magicianTimer = new System.Timers.Timer(); - private System.Timers.Timer meltyTimer = new System.Timers.Timer(); private System.Timers.Timer crippleTimer = new System.Timers.Timer(); private System.Timers.Timer bloodManaTimer = new System.Timers.Timer(); private System.Timers.Timer bloodManaTickTimer = new System.Timers.Timer(); @@ -173,6 +161,10 @@ public class KhaosController private System.Timers.Timer thirstTickTimer = new System.Timers.Timer(); private System.Timers.Timer hordeTimer = new System.Timers.Timer(); private System.Timers.Timer hordeSpawnTimer = new System.Timers.Timer(); + private System.Timers.Timer magicianTimer = new System.Timers.Timer(); + private System.Timers.Timer meltyTimer = new System.Timers.Timer(); + private System.Timers.Timer zawarudoTimer = new System.Timers.Timer(); + private System.Timers.Timer hasteTimer = new System.Timers.Timer(); private uint hordeZone = 0; private uint hordeZone2 = 0; @@ -209,8 +201,6 @@ public KhaosController(IToolConfig toolConfig, IGameApi gameApi, IAlucardApi alu Console.WriteLine("Bot action file not found!"); } - audioPlayer.Volume = (float) toolConfig.Khaos.Volume / 10F; - InitializeTimers(); } @@ -230,6 +220,18 @@ public void StartKhaos() gameApi.OverwriteString(Strings.Dracula, "3snoW"); } + public void StopKhaos() + { + if (File.Exists(toolConfig.Khaos.BotActionsFilePath)) + { + botFileWatcher.EnableRaisingEvents = false; + } + actionTimer.Stop(); + fastActionTimer.Stop(); + Cheat faerieScroll = cheats.GetCheatByName("FaerieScroll"); + faerieScroll.Disable(); + } + public void OverwriteBossNames(string[] subscribers) { int i = 0; @@ -244,29 +246,184 @@ public void OverwriteBossNames(string[] subscribers) } } - public void RandomizeRelics() + #region Khaotic Effects + public void InflictRandomStatus(string user = "Khaos") { - RandomizeRelicsActivate(); - audioPlayer.Open(new Uri(Paths.AlertAlucardWhat, UriKind.Relative)); - audioPlayer.Play(); + Random rnd = new Random(); + int result = rnd.Next(1, 4); + switch (result) + { + case 1: + SpawnPoisonHitbox(); + notificationService.DisplayMessage($"{user} poisoned you"); + break; + case 2: + SpawnCurseHitbox(); + notificationService.DisplayMessage($"{user} cursed you"); + break; + case 3: + SpawnStoneHitbox(); + notificationService.DisplayMessage($"{user} petrified you"); + break; + default: + break; + } + + notificationService.PlayAlert(Paths.AlertDeathLaugh); } + public void RandomizeEquipment(string user = "Khaos") + { + RandomizeEquipmentSlots(); - public void RandomizeEquipment() + notificationService.DisplayMessage($"{user} used Khaos Equipment"); + notificationService.PlayAlert(Paths.AlertAlucardWhat); + } + public void RandomizeStats(string user = "Khaos") + { + RandomizeStatsActivate(); + notificationService.DisplayMessage($"{user} used Khaos Stats"); + notificationService.PlayAlert(Paths.AlertAlucardWhat); + } + public void RandomizeRelics(string user = "Khaos") { + RandomizeRelicsActivate(); + notificationService.DisplayMessage($"{user} used Khaos Relics"); + notificationService.PlayAlert(Paths.AlertAlucardWhat); + } + public void PandorasBox(string user = "Khaos") + { + RandomizeGold(); + RandomizeStatsActivate(); RandomizeEquipmentSlots(); + RandomizeRelicsActivate(); + RandomizeInventory(); + RandomizeSubweapon(); + gameApi.RespawnBosses(); + notificationService.DisplayMessage($"{user} opened Pandora's Box"); + notificationService.PlayAlert(Paths.AlertAlucardWhat); + } + public void Gamble(string user = "Khaos") + { + Random rnd = new Random(); + double goldPercent = rnd.NextDouble(); + uint newGold = (uint) ((double) alucardApi.Gold * goldPercent); + uint goldSpent = alucardApi.Gold - newGold; + alucardApi.Gold = newGold; + string item = Equipment.Items[rnd.Next(1, Equipment.Items.Count)]; + while (item.Contains("empty hand") || item.Contains("-")) + { + item = Equipment.Items[rnd.Next(1, Equipment.Items.Count)]; + } + alucardApi.GrantItemByName(item); + - audioPlayer.Open(new Uri(Paths.AlertAlucardWhat, UriKind.Relative)); - audioPlayer.Play(); + notificationService.DisplayMessage($"{user} gambled {goldSpent} gold for {item}"); + notificationService.PlayAlert(Paths.AlertLibrarianThankYou); } + #endregion + #region Debuffs + public void Thirst(string user = "Khaos") + { + alucardApi.DarkMetamorphasisTimer = 40; + thirstTimer.Start(); + thirstTickTimer.Start(); - public void RandomizeStats() + notificationService.DisplayMessage($"{user} used Thirst"); + notificationService.PlayAlert(Paths.AlertDeathLaugh); + } + public void Weaken(string user = "Khaos") { - RandomizeStatsActivate(); - audioPlayer.Open(new Uri(Paths.AlertAlucardWhat, UriKind.Relative)); - audioPlayer.Play(); + alucardApi.CurrentHp = (uint) (alucardApi.CurrentHp * toolConfig.Khaos.WeakenFactor); + alucardApi.CurrentMp = (uint) (alucardApi.CurrentHp * toolConfig.Khaos.WeakenFactor); + alucardApi.CurrentHearts = (uint) (alucardApi.CurrentHp * toolConfig.Khaos.WeakenFactor); + alucardApi.MaxtHp = (uint) (alucardApi.MaxtHp * toolConfig.Khaos.WeakenFactor); + alucardApi.MaxtMp = (uint) (alucardApi.MaxtHp * toolConfig.Khaos.WeakenFactor); + alucardApi.MaxtHearts = (uint) (alucardApi.MaxtHp * toolConfig.Khaos.WeakenFactor); + alucardApi.Str = (uint) (alucardApi.Str * toolConfig.Khaos.WeakenFactor); + alucardApi.Con = (uint) (alucardApi.Con * toolConfig.Khaos.WeakenFactor); + alucardApi.Int = (uint) (alucardApi.Int * toolConfig.Khaos.WeakenFactor); + alucardApi.Lck = (uint) (alucardApi.Lck * toolConfig.Khaos.WeakenFactor); + + notificationService.DisplayMessage($"{user} used Weaken"); + notificationService.PlayAlert(Paths.AlertDeathLaugh); + } + public void Cripple(string user = "Khaos") + { + SetSpeed(toolConfig.Khaos.CrippleFactor); + crippleTimer.Start(); + notificationService.DisplayMessage($"{user} used Cripple"); + notificationService.PlayAlert(Paths.AlertAlucardWhat); + } + public void BloodMana(string user = "Khaos") + { + storedMana = alucardApi.CurrentMp; + bloodManaActive = true; + bloodManaTimer.Start(); + bloodManaTickTimer.Start(); + notificationService.DisplayMessage($"{user} used Blood Mana"); + notificationService.PlayAlert(Paths.AlertRichterLaugh); } + public void HonestGamer(string user = "Khaos") + { + Cheat manaCheat = cheats.GetCheatByName("Mana"); + manaCheat.PokeValue(5); + manaCheat.Enable(); + honestGamerTimer.Start(); + notificationService.DisplayMessage($"{user} used Honest Gamer"); + notificationService.PlayAlert(Paths.AlertRichterLaugh); - public void RandomLightHelp() + } + public void SubweaponsOnly(string user = "Khaos") + { + Random rnd = new Random(); + int roll = rnd.Next(1, 10); + while (roll == 6) + { + roll = rnd.Next(1, 10); + } + alucardApi.Subweapon = (Subweapon) roll; + alucardApi.CurrentHearts = 200; + alucardApi.ActivatePotion(Potion.SmartPotion); + alucardApi.GrantRelic(Relic.CubeOfZoe); + HonestGamer(); + Cheat curse = cheats.GetCheatByName("CurseTimer"); + curse.Enable(); + Cheat manaCheat = cheats.GetCheatByName("Mana"); + manaCheat.PokeValue(5); + manaCheat.Enable(); + subweaponsOnlyTimer.Start(); + notificationService.DisplayMessage($"{user} used Subweapons Only"); + notificationService.PlayAlert(Paths.AlertRichterLaugh); + } + public void Bankrupt(string user = "Khaos") + { + BankruptActivate(); + notificationService.DisplayMessage($"{user} used Bankrupt"); + notificationService.PlayAlert(Paths.AlertDeathLaugh); + } + public void RespawnBosses(string user = "Khaos") + { + gameApi.RespawnBosses(); + notificationService.DisplayMessage($"{user} used Respawn Bosses"); + notificationService.PlayAlert(Paths.AlertDeathLaugh); + } + public void Horde(string user = "Khaos") + { + hordeTimer.Start(); + hordeSpawnTimer.Start(); + notificationService.DisplayMessage($"{user} summoned the Horde"); + notificationService.PlayAlert(Paths.AlertRichterLaugh); + } + public void Endurance(string user = "Khaos") + { + hordeTimer.Start(); + hordeSpawnTimer.Start(); + notificationService.DisplayMessage($"{user} used Endurance"); + notificationService.PlayAlert(Paths.AlertRichterLaugh); + } + #endregion + #region Buffs + public void RandomLightHelp(string user = "Khaos") { Random rnd = new Random(); string item = lightHelpItems[rnd.Next(0, lightHelpItems.Length)]; @@ -276,21 +433,22 @@ public void RandomLightHelp() { case 1: alucardApi.GrantItemByName(item); + notificationService.DisplayMessage($"{user} gave you a {item}"); break; case 2: alucardApi.ActivatePotion(Potion.Potion); + notificationService.DisplayMessage($"{user} healed you"); break; case 3: alucardApi.ActivatePotion(Potion.ShieldPotion); + notificationService.DisplayMessage($"{user} used a Shield Potion"); break; default: break; } - audioPlayer.Open(new Uri(Paths.AlertFairyPotion, UriKind.Relative)); - audioPlayer.Play(); + notificationService.PlayAlert(Paths.AlertFairyPotion); } - - public void RandomMediumHelp() + public void RandomMediumHelp(string user = "Khaos") { Random rnd = new Random(); string item = mediumHelpItems[rnd.Next(0, mediumHelpItems.Length)]; @@ -300,21 +458,22 @@ public void RandomMediumHelp() { case 1: alucardApi.GrantItemByName(item); + notificationService.DisplayMessage($"{user} gave you a {item}"); break; case 2: alucardApi.ActivatePotion(Potion.Elexir); + notificationService.DisplayMessage($"{user} healed you"); break; case 3: alucardApi.ActivatePotion(Potion.ManaPrism); + notificationService.DisplayMessage($"{user} used a Mana Prism"); break; default: break; } - audioPlayer.Open(new Uri(Paths.AlertFairyPotion, UriKind.Relative)); - audioPlayer.Play(); + notificationService.PlayAlert(Paths.AlertFairyPotion); } - - public void RandomHeavytHelp() + public void RandomHeavytHelp(string user = "Khaos") { Random rnd = new Random(); string item = heavyHelpItems[rnd.Next(0, heavyHelpItems.Length)]; @@ -338,173 +497,39 @@ public void RandomHeavytHelp() { case 1: alucardApi.GrantItemByName(item); + notificationService.DisplayMessage($"{user} gave you a {item}"); break; case 2: alucardApi.GrantRelic((Relic) relic); + notificationService.DisplayMessage($"{user} gave you {(Relic) relic}"); break; default: break; } - audioPlayer.Open(new Uri(Paths.AlertFairyPotion, UriKind.Relative)); - audioPlayer.Play(); - } - - public void PandorasBox() - { - RandomizeGold(); - RandomizeStatsActivate(); - RandomizeEquipmentSlots(); - RandomizeRelicsActivate(); - RandomizeInventory(); - RandomizeSubweapon(); - gameApi.RespawnBosses(); - audioPlayer.Open(new Uri(Paths.AlertAlucardWhat, UriKind.Relative)); - audioPlayer.Play(); - } - - public void InflictRandomStatus() - { - Random rnd = new Random(); - int result = rnd.Next(1, 4); - switch (result) - { - case 1: - SpawnPoisonHitbox(); - break; - case 2: - SpawnCurseHitbox(); - break; - case 3: - SpawnStoneHitbox(); - break; - default: - break; - } - audioPlayer.Open(new Uri(Paths.AlertDeathLaugh, UriKind.Relative)); - audioPlayer.Play(); + notificationService.PlayAlert(Paths.AlertFairyPotion); } - - public void Vampire() + public void Vampire(string user = "Khaos") { alucardApi.DarkMetamorphasisTimer = 0xD; + notificationService.DisplayMessage($"{user} used Vampire"); } - - public void Weaken() - { - alucardApi.CurrentHp = (uint) (alucardApi.CurrentHp * WeakenFactor); - alucardApi.CurrentMp = (uint) (alucardApi.CurrentHp * WeakenFactor); - alucardApi.CurrentHearts = (uint) (alucardApi.CurrentHp * WeakenFactor); - alucardApi.MaxtHp = (uint) (alucardApi.MaxtHp * WeakenFactor); - alucardApi.MaxtMp = (uint) (alucardApi.MaxtHp * WeakenFactor); - alucardApi.MaxtHearts = (uint) (alucardApi.MaxtHp * WeakenFactor); - alucardApi.Str = (uint) (alucardApi.Str * WeakenFactor); - alucardApi.Con = (uint) (alucardApi.Con * WeakenFactor); - alucardApi.Int = (uint) (alucardApi.Int * WeakenFactor); - alucardApi.Lck = (uint) (alucardApi.Lck * WeakenFactor); - - audioPlayer.Open(new Uri(Paths.AlertRichterLaugh, UriKind.Relative)); - audioPlayer.Play(); - } - - public void Cripple() - { - CrippleToggle(true); - crippleTimer.Start(); - audioPlayer.Open(new Uri(Paths.AlertAlucardWhat, UriKind.Relative)); - audioPlayer.Play(); - } - - public void BloodMana() - { - storedMana = alucardApi.CurrentMp; - bloodManaActive = true; - bloodManaTimer.Start(); - bloodManaTickTimer.Start(); - audioPlayer.Open(new Uri(Paths.AlertRichterLaugh, UriKind.Relative)); - audioPlayer.Play(); - } - - public void SubweaponsOnly() - { - Random rnd = new Random(); - int roll = rnd.Next(1, 10); - while (roll == 6) - { - roll = rnd.Next(1, 10); - } - alucardApi.Subweapon = (Subweapon) roll; - alucardApi.CurrentHearts = 200; - alucardApi.ActivatePotion(Potion.SmartPotion); - alucardApi.GrantRelic(Relic.CubeOfZoe); - HonestGamer(); - Cheat curse = cheats.GetCheatByName("CurseTimer"); - curse.Enable(); - Cheat manaCheat = cheats.GetCheatByName("Mana"); - manaCheat.PokeValue(5); - manaCheat.Enable(); - subweaponsOnlyTimer.Start(); - audioPlayer.Open(new Uri(Paths.AlertRichterLaugh, UriKind.Relative)); - audioPlayer.Play(); - } - - public void Bankrupt() - { - BankruptActivate(); - - audioPlayer.Open(new Uri(Paths.AlertDeathLaugh, UriKind.Relative)); - audioPlayer.Play(); - } - - public void RespawnBosses() - { - gameApi.RespawnBosses(); - audioPlayer.Open(new Uri(Paths.AlertDeathLaugh, UriKind.Relative)); - audioPlayer.Play(); - } - - public void Gamble() - { - Random rnd = new Random(); - double goldPercent = rnd.NextDouble(); - alucardApi.Gold = (uint) ((double) alucardApi.Gold * goldPercent); - string item = Equipment.Items[rnd.Next(1, Equipment.Items.Count)]; - while (item.Contains("empty hand") || item.Contains("-")) - { - item = Equipment.Items[rnd.Next(1, Equipment.Items.Count)]; - } - alucardApi.GrantItemByName(item); - - audioPlayer.Open(new Uri(Paths.AlertLibrarianThankYou, UriKind.Relative)); - audioPlayer.Play(); - } - - public void BattleOrders() + public void BattleOrders(string user = "Khaos") { alucardApi.CurrentHp = alucardApi.MaxtHp * 2; alucardApi.CurrentMp = alucardApi.MaxtMp; alucardApi.ActivatePotion(Potion.ShieldPotion); + notificationService.DisplayMessage($"{user} used Battle Orders"); } - - public void HonestGamer() - { - Cheat manaCheat = cheats.GetCheatByName("Mana"); - manaCheat.PokeValue(5); - manaCheat.Enable(); - honestGamerTimer.Start(); - audioPlayer.Open(new Uri(Paths.AlertRichterLaugh, UriKind.Relative)); - audioPlayer.Play(); - } - - public void Magician() + public void Magician(string user = "Khaos") { alucardApi.ActivatePotion(Potion.SmartPotion); Cheat manaCheat = cheats.GetCheatByName("Mana"); manaCheat.PokeValue(99); manaCheat.Enable(); magicianTimer.Start(); + notificationService.DisplayMessage($"{user} activated Magician mode"); } - - public void ZaWarudo() + public void ZaWarudo(string user = "Khaos") { alucardApi.ActivateStopwatch(); alucardApi.Subweapon = Subweapon.Stopwatch; @@ -513,44 +538,33 @@ public void ZaWarudo() stopwatchTimer.Enable(); zawarudoTimer.Start(); - audioPlayer.Open(new Uri(Paths.AlertZaWarudo, UriKind.Relative)); - audioPlayer.Play(); + notificationService.DisplayMessage($"{user} used ZA WARUDO"); + notificationService.PlayAlert(Paths.AlertZaWarudo); } - - public void MeltyBlood() + public void MeltyBlood(string user = "Khaos") { Cheat width = cheats.GetCheatByName("AlucardAttackHitboxWidth"); Cheat height = cheats.GetCheatByName("AlucardAttackHitboxHeight"); width.Enable(); height.Enable(); meltyTimer.Start(); - audioPlayer.Open(new Uri(Paths.AlertMelty, UriKind.Relative)); - audioPlayer.Play(); + notificationService.DisplayMessage($"{user} activated Melty Blood"); + notificationService.PlayAlert(Paths.AlertMelty); } - - public void FourBeasts() + public void FourBeasts(string user = "Khaos") { alucardApi.InvincibilityTimer = 0xD; alucardApi.AttackPotionTimer = 0xD; alucardApi.ShineTimer = 0xD; + notificationService.DisplayMessage($"{user} used Four Beasts"); } - - public void Thirst() - { - alucardApi.DarkMetamorphasisTimer = 40; - thirstTimer.Start(); - thirstTickTimer.Start(); - audioPlayer.Open(new Uri(Paths.AlertDeathLaugh, UriKind.Relative)); - audioPlayer.Play(); - } - - public void Horde() + public void Haste(string user = "Khaos") { - hordeTimer.Start(); - hordeSpawnTimer.Start(); - audioPlayer.Open(new Uri(Paths.AlertRichterLaugh, UriKind.Relative)); - audioPlayer.Play(); + SetSpeed(toolConfig.Khaos.HasteFactor); + hasteTimer.Start(); + notificationService.DisplayMessage($"{user} used Haste"); } + #endregion public void Update() { @@ -564,113 +578,95 @@ public void EnqueueAction(string command) { if (command is null) throw new ArgumentNullException(nameof(command)); if (command == "") throw new ArgumentException($"Parameter {nameof(command)} is empty!"); - string user = ""; + string user = String.Empty; string[] commandArgs = command.Split(' '); - Console.WriteLine(String.Join(" + ", commandArgs)); string action = commandArgs[0]; if (commandArgs.Length > 1) { user = commandArgs[1]; } + if (user == String.Empty) + { + user = "Khaos"; + } switch (action) { case "kstatus": - queuedFastActions.Enqueue(InflictRandomStatus); - notificationService.DisplayMessage(user + " used Khaos Status"); + queuedFastActions.Enqueue(new MethodInvoker(() => InflictRandomStatus(user))); break; case "kequipment": - queuedFastActions.Enqueue(RandomizeEquipment); - notificationService.DisplayMessage(user + " used Khaos Equipment"); + queuedFastActions.Enqueue(new MethodInvoker(() => RandomizeEquipment(user))); break; case "kstats": - queuedFastActions.Enqueue(RandomizeStats); - notificationService.DisplayMessage(user + " used Khaos Stats"); + queuedFastActions.Enqueue(new MethodInvoker(() => RandomizeStats(user))); break; case "krelics": - queuedFastActions.Enqueue(RandomizeRelics); - notificationService.DisplayMessage(user + " used Khaos Relics"); + queuedFastActions.Enqueue(new MethodInvoker(() => RandomizeRelics(user))); break; case "pandora": - queuedActions.Enqueue(PandorasBox); - notificationService.DisplayMessage(user + " opened Pandora's Box"); + queuedFastActions.Enqueue(new MethodInvoker(() => PandorasBox(user))); break; case "gamble": - queuedFastActions.Enqueue(Gamble); - notificationService.DisplayMessage(user + " used Gamble"); + queuedFastActions.Enqueue(new MethodInvoker(() => Gamble(user))); break; case "bankrupt": - queuedFastActions.Enqueue(Bankrupt); - notificationService.DisplayMessage(user + " used Bankrupt"); + queuedFastActions.Enqueue(new MethodInvoker(() => Bankrupt(user))); break; case "weaken": - queuedActions.Enqueue(Weaken); - notificationService.DisplayMessage(user + " used Weaken"); + queuedFastActions.Enqueue(new MethodInvoker(() => Weaken(user))); break; case "respawnbosses": - queuedActions.Enqueue(RespawnBosses); - notificationService.DisplayMessage(user + " used Respawn Bosses"); + queuedFastActions.Enqueue(new MethodInvoker(() => RespawnBosses(user))); break; case "honest": - queuedFastActions.Enqueue(HonestGamer); - notificationService.DisplayMessage(user + " used Honest Gamer"); + queuedFastActions.Enqueue(new MethodInvoker(() => HonestGamer(user))); break; case "subsonly": - queuedActions.Enqueue(SubweaponsOnly); - notificationService.DisplayMessage(user + " used Subweapons Only"); + queuedFastActions.Enqueue(new MethodInvoker(() => SubweaponsOnly(user))); break; case "cripple": - queuedFastActions.Enqueue(Cripple); - notificationService.DisplayMessage(user + " used Cripple"); + queuedFastActions.Enqueue(new MethodInvoker(() => Cripple(user))); break; case "bloodmana": - queuedFastActions.Enqueue(BloodMana); - notificationService.DisplayMessage(user + " used Blood Mana"); + queuedFastActions.Enqueue(new MethodInvoker(() => BloodMana(user))); break; case "thirst": - queuedFastActions.Enqueue(Thirst); - notificationService.DisplayMessage(user + " used Thirst"); + queuedFastActions.Enqueue(new MethodInvoker(() => Thirst(user))); break; case "horde": - queuedFastActions.Enqueue(Horde); - notificationService.DisplayMessage(user + " used Horde"); + queuedFastActions.Enqueue(new MethodInvoker(() => Horde(user))); break; case "vampire": - queuedFastActions.Enqueue(Vampire); - notificationService.DisplayMessage(user + " used Vampire"); + queuedFastActions.Enqueue(new MethodInvoker(() => Vampire(user))); break; case "lighthelp": - queuedFastActions.Enqueue(RandomLightHelp); - notificationService.DisplayMessage(user + " used Light Help"); + queuedFastActions.Enqueue(new MethodInvoker(() => RandomLightHelp(user))); break; case "mediumhelp": - queuedFastActions.Enqueue(RandomMediumHelp); - notificationService.DisplayMessage(user + " used Medium Help"); + queuedFastActions.Enqueue(new MethodInvoker(() => RandomMediumHelp(user))); break; case "heavyhelp": - queuedFastActions.Enqueue(RandomHeavytHelp); - notificationService.DisplayMessage(user + " used Heavy Help"); + queuedFastActions.Enqueue(new MethodInvoker(() => RandomHeavytHelp(user))); break; case "battleorders": - queuedFastActions.Enqueue(BattleOrders); - notificationService.DisplayMessage(user + " used Battle Orders"); + queuedFastActions.Enqueue(new MethodInvoker(() => BattleOrders(user))); break; case "magician": - queuedFastActions.Enqueue(Magician); - notificationService.DisplayMessage(user + " used Magician"); + queuedFastActions.Enqueue(new MethodInvoker(() => Magician(user))); break; case "melty": - queuedFastActions.Enqueue(MeltyBlood); - notificationService.DisplayMessage(user + " used Melty Blood"); + queuedFastActions.Enqueue(new MethodInvoker(() => MeltyBlood(user))); break; case "fourbeasts": - queuedFastActions.Enqueue(FourBeasts); - notificationService.DisplayMessage(user + " used Four Beasts"); + queuedFastActions.Enqueue(new MethodInvoker(() => FourBeasts(user))); break; case "zawarudo": - notificationService.DisplayMessage(user + " ZA WARUDO"); - queuedFastActions.Enqueue(ZaWarudo); + queuedFastActions.Enqueue(new MethodInvoker(() => ZaWarudo(user))); + break; + case "haste": + queuedFastActions.Enqueue(new MethodInvoker(() => Haste(user))); break; default: break; @@ -683,14 +679,11 @@ private void InitializeTimers() fastActionTimer.Interval = 2 * (1 * 1000); actionTimer.Tick += ExecuteAction; actionTimer.Interval = 1 * (60 * 1000); + honestGamerTimer.Elapsed += HonestGamerOff; honestGamerTimer.Interval = 1 * (60 * 1000); subweaponsOnlyTimer.Elapsed += SubweaponsOnlyOff; subweaponsOnlyTimer.Interval = 1 * (60 * 1000); - magicianTimer.Elapsed += MagicianOff; - magicianTimer.Interval = 1 * (60 * 1000); - meltyTimer.Elapsed += MeltyBloodOff; - meltyTimer.Interval = 1 * (60 * 1000); crippleTimer.Elapsed += CrippleOff; crippleTimer.Interval = 1 * (60 * 1000); bloodManaTimer.Elapsed += BloodManaOff; @@ -705,8 +698,16 @@ private void InitializeTimers() hordeTimer.Interval = 1 * (60 * 1000); hordeSpawnTimer.Elapsed += HordeSpawn; hordeSpawnTimer.Interval = 1 * (1000); + //hordeSpawnTimer.Interval = toolConfig.Khaos.Actions.Where(a => a.Name == "Khaos Horde").FirstOrDefault().Interval.TotalMilliseconds; + + magicianTimer.Elapsed += MagicianOff; + magicianTimer.Interval = 1 * (60 * 1000); + meltyTimer.Elapsed += MeltyBloodOff; + meltyTimer.Interval = 1 * (60 * 1000); zawarudoTimer.Elapsed += ZawarudoOff; zawarudoTimer.Interval = 1 * (40 * 1000); + hasteTimer.Elapsed += HasteOff; + hasteTimer.Interval = 1 * (60 * 1000); } private void ExecuteAction(Object sender, EventArgs e) @@ -731,45 +732,187 @@ private void ExecuteFastAction(Object sender, EventArgs e) } } - private void HonestGamerOff(Object sender, EventArgs e) + #region Khaotic events + private void RandomizeGold() { - Cheat manaCheat = cheats.GetCheatByName("Mana"); - manaCheat.Disable(); - honestGamerTimer.Stop(); + Random rnd = new Random(); + uint gold = (uint) rnd.Next(0, 5000); + uint roll = (uint) rnd.Next(0, 21); + if (roll > 16 && roll < 20) + { + gold = gold * (uint) rnd.Next(1, 11); + } + else if (roll > 19) + { + gold = gold * (uint) rnd.Next(10, 81); + } + alucardApi.Gold = gold; } - - private void SubweaponsOnlyOff(object sender, EventArgs e) + private void RandomizeStatsActivate() { - Cheat curse = cheats.GetCheatByName("CurseTimer"); - curse.Disable(); - Cheat manaCheat = cheats.GetCheatByName("Mana"); - manaCheat.Disable(); - subweaponsOnlyTimer.Stop(); - } + Random rnd = new Random(); + uint maxHp = alucardApi.MaxtHp; + uint currentHp = alucardApi.CurrentHp; + uint maxMana = alucardApi.MaxtMp; + uint currentMana = alucardApi.CurrentMp; + uint str = alucardApi.Str; + uint con = alucardApi.Con; + uint intel = alucardApi.Int; + uint lck = alucardApi.Lck; + uint statPool = str + con + intel + lck > 28 ? str + con + intel + lck - 28 : str + con + intel + lck; + uint offset = (uint) (rnd.NextDouble() * statPool); - private void MagicianOff(Object sender, EventArgs e) - { - //int potion - Cheat manaCheat = cheats.GetCheatByName("Mana"); - manaCheat.Disable(); - magicianTimer.Stop(); + int statPoolRoll = rnd.Next(1, 3); + if (statPoolRoll > 1) + { + statPool = statPool + offset; + } + else + { + statPool = ((int) statPool - (int) offset) < 0 ? 0 : statPool - offset; + } + + double a = rnd.NextDouble(); + double b = rnd.NextDouble(); + double c = rnd.NextDouble(); + double d = rnd.NextDouble(); + double sum = a + b + c + d; + double percentageStr = (a / sum); + double percentageCon = (b / sum); + double percentageInt = (c / sum); + double percentageLck = (d / sum); + + alucardApi.Str = (uint) (6 + (statPool * percentageStr)); + alucardApi.Con = (uint) (6 + (statPool * percentageCon)); + alucardApi.Int = (uint) (6 + (statPool * percentageInt)); + alucardApi.Lck = (uint) (6 + (statPool * percentageLck)); + + uint pointsPool = maxHp + maxMana > 110 ? maxHp + maxMana - 110 : maxHp + maxMana; + if (maxHp + maxMana < 110) + { + pointsPool = 110; + } + offset = (uint) (rnd.NextDouble() * pointsPool); + + int pointsRoll = rnd.Next(1, 3); + if (pointsRoll > 1) + { + pointsPool = pointsPool + offset; + } + else + { + pointsPool = ((int) pointsPool - (int) offset) < 0 ? 0 : pointsPool - offset; + } + + double hpPercent = rnd.NextDouble(); + uint pointsHp = 80 + (uint) (hpPercent * pointsPool); + uint pointsMp = 30 + (uint) (pointsPool - (hpPercent * pointsPool)); + + if (currentHp > pointsHp) + { + alucardApi.CurrentHp = pointsHp; + } + if (currentMana > pointsMp) + { + alucardApi.CurrentMp = pointsMp; + } + + alucardApi.MaxtHp = pointsHp; + alucardApi.MaxtMp = pointsMp; } + private void RandomizeInventory() + { + bool hasHolyGlasses = alucardApi.HasItemInInventory("Holy glasses"); + bool hasSpikeBreaker = alucardApi.HasItemInInventory("Spike Breaker"); + bool hasGoldRing = alucardApi.HasItemInInventory("Gold Ring"); + bool hasSilverRing = alucardApi.HasItemInInventory("Silver Ring"); - private void MeltyBloodOff(Object sender, EventArgs e) + alucardApi.ClearInventory(); + Random rnd = new Random(); + + int itemCount = rnd.Next(toolConfig.Khaos.PandoraMinItems, toolConfig.Khaos.PandoraMaxItems + 1); + + for (int i = 0; i < itemCount; i++) + { + int result = rnd.Next(0, Equipment.Items.Count); + alucardApi.GrantItemByName(Equipment.Items[result]); + } + + if (hasHolyGlasses) + { + alucardApi.GrantItemByName("Holy glasses"); + } + if (hasSpikeBreaker) + { + alucardApi.GrantItemByName("Spike Breaker"); + } + if (hasGoldRing) + { + alucardApi.GrantItemByName("Gold Ring"); + } + if (hasSilverRing) + { + alucardApi.GrantItemByName("Silver Ring"); + } + } + private void RandomizeSubweapon() { - Cheat width = cheats.GetCheatByName("AlucardAttackHitboxWidth"); - Cheat height = cheats.GetCheatByName("AlucardAttackHitboxHeight"); - width.Disable(); - height.Disable(); - meltyTimer.Stop(); + Random rnd = new Random(); + var subweapons = Enum.GetValues(typeof(Subweapon)); + alucardApi.Subweapon = (Subweapon) subweapons.GetValue(rnd.Next(subweapons.Length)); } - - private void CrippleOff(Object sender, EventArgs e) + private void RandomizeRelicsActivate() { - CrippleToggle(false); - crippleTimer.Stop(); + Random rnd = new Random(); + var relics = Enum.GetValues(typeof(Relic)); + foreach (var relic in relics) + { + alucardApi.TakeRelic((Relic) relic); + } + foreach (var relic in relics) + { + if (rnd.Next(0, 2) > 0) + { + alucardApi.GrantRelic((Relic) relic); + } + } } + private void RandomizeEquipmentSlots() + { + bool equippedHolyGlasses = Equipment.Items[(int) (alucardApi.Helm + Equipment.HandCount + 1)] == "Holy glasses"; + bool equippedSpikeBreaker = Equipment.Items[(int) (alucardApi.Armor + Equipment.HandCount + 1)] == "Spike Breaker"; + bool equippedGoldRing = Equipment.Items[(int) (alucardApi.Accessory1 + Equipment.HandCount + 1)] == "Gold Ring" || Equipment.Items[(int) (alucardApi.Accessory2 + Equipment.HandCount)] == "Gold Ring"; + bool equippedSilverRing = Equipment.Items[(int) (alucardApi.Accessory1 + Equipment.HandCount + 1)] == "Silver Ring" || Equipment.Items[(int) (alucardApi.Accessory2 + Equipment.HandCount)] == "Silver Ring"; + Random rnd = new Random(); + alucardApi.RightHand = (uint) rnd.Next(0, Equipment.HandCount + 1); + alucardApi.LeftHand = (uint) rnd.Next(0, Equipment.HandCount + 1); + alucardApi.Armor = (uint) rnd.Next(0, Equipment.ArmorCount + 1); + alucardApi.Helm = Equipment.HelmStart + (uint) rnd.Next(0, Equipment.HelmCount + 1); + alucardApi.Cloak = Equipment.CloakStart + (uint) rnd.Next(0, Equipment.CloakCount + 1); + alucardApi.Accessory1 = Equipment.AccessoryStart + (uint) rnd.Next(0, Equipment.AccessoryCount + 1); + alucardApi.Accessory2 = Equipment.AccessoryStart + (uint) rnd.Next(0, Equipment.AccessoryCount + 1); + RandomizeSubweapon(); + + if (equippedHolyGlasses) + { + alucardApi.GrantItemByName("Holy glasses"); + } + if (equippedSpikeBreaker) + { + alucardApi.GrantItemByName("Spike Breaker"); + } + if (equippedGoldRing) + { + alucardApi.GrantItemByName("Gold Ring"); + } + if (equippedSilverRing) + { + alucardApi.GrantItemByName("Silver Ring"); + } + } + #endregion + #region Debuff events private void BloodManaUpdate(Object sender, EventArgs e) { if (spentMana > 1) @@ -778,41 +921,29 @@ private void BloodManaUpdate(Object sender, EventArgs e) alucardApi.CurrentHp -= (uint) spentMana; } } - private void BloodManaOff(Object sender, EventArgs e) { bloodManaActive = false; bloodManaTimer.Stop(); bloodManaTickTimer.Stop(); } - private void ThirstDrain(Object sender, EventArgs e) { if (alucardApi.CurrentHp > 1) { - alucardApi.CurrentHp -= DrainPerSecond; + alucardApi.CurrentHp -= toolConfig.Khaos.ThirstDrainPerSecond; } } - private void ThirstOff(Object sender, EventArgs e) { thirstTimer.Stop(); thirstTickTimer.Stop(); } - private void HordeOff(Object sender, EventArgs e) { hordeTimer.Stop(); hordeSpawnTimer.Stop(); } - - private void ZawarudoOff(Object sender, EventArgs e) - { - Cheat stopwatchTimer = cheats.GetCheatByName("SubweaponTimer"); - stopwatchTimer.Disable(); - zawarudoTimer.Stop(); - } - private void HordeSpawn(Object sender, EventArgs e) { if (!gameApi.InAlucardMode() || !gameApi.CanMenu() || alucardApi.CurrentHp < 5) @@ -845,7 +976,25 @@ private void HordeSpawn(Object sender, EventArgs e) actorApi.SpawnActor(hordeEnemy); } } - + private void HonestGamerOff(Object sender, EventArgs e) + { + Cheat manaCheat = cheats.GetCheatByName("Mana"); + manaCheat.Disable(); + honestGamerTimer.Stop(); + } + private void SubweaponsOnlyOff(object sender, EventArgs e) + { + Cheat curse = cheats.GetCheatByName("CurseTimer"); + curse.Disable(); + Cheat manaCheat = cheats.GetCheatByName("Mana"); + manaCheat.Disable(); + subweaponsOnlyTimer.Stop(); + } + private void CrippleOff(Object sender, EventArgs e) + { + SetSpeed(); + crippleTimer.Stop(); + } private void EnduranceSpawn(Object sender, EventArgs e) { if (!gameApi.InAlucardMode() || !gameApi.CanMenu() || alucardApi.CurrentHp < 5) @@ -869,13 +1018,6 @@ private void EnduranceSpawn(Object sender, EventArgs e) return; } } - - private void OnBotFileChanged(object sender, FileSystemEventArgs e) - { - string lastLine = FileExtensions.GetLastLine(toolConfig.Khaos.BotActionsFilePath); - EnqueueAction(lastLine); - } - private void SpawnPoisonHitbox() { Actor poison = new Actor(); @@ -886,7 +1028,6 @@ private void SpawnPoisonHitbox() poison.DamageTypeA = (uint) Actors.Poison; actorApi.SpawnActor(poison); } - private void SpawnCurseHitbox() { Actor poison = new Actor(); @@ -897,7 +1038,6 @@ private void SpawnCurseHitbox() poison.DamageTypeB = (uint) Actors.Curse; actorApi.SpawnActor(poison); } - private void SpawnStoneHitbox() { Actor poison = new Actor(); @@ -909,24 +1049,6 @@ private void SpawnStoneHitbox() poison.DamageTypeB = (uint) Actors.Stone; actorApi.SpawnActor(poison); } - - private void CrippleToggle(bool on) - { - float factor = on == true ? CrippleFactor : 1; - - alucardApi.WingsmashHorizontalSpeed = (uint) (DefaultSpeeds.WingsmashHorizontal * factor); - alucardApi.WalkingWholeSpeed = (uint) (DefaultSpeeds.WalkingWhole * factor); - alucardApi.WalkingFractSpeed = (uint) (DefaultSpeeds.WalkingFract * factor); - alucardApi.JumpingHorizontalWholeSpeed = (uint) (DefaultSpeeds.WalkingWhole * factor); - alucardApi.JumpingHorizontalFractSpeed = (uint) (DefaultSpeeds.WalkingFract * factor); - alucardApi.FallingHorizontalWholeSpeed = (uint) (DefaultSpeeds.WalkingWhole * factor); - alucardApi.FallingHorizontalFractSpeed = (uint) (DefaultSpeeds.WalkingFract * factor); - alucardApi.WolfDashTopRightSpeed = (sbyte) ((sbyte) DefaultSpeeds.WolfDashTopRight - 1); - alucardApi.WolfDashTopLeftSpeed = (sbyte) ((sbyte) DefaultSpeeds.WolfDashTopLeft - 1); - uint adjustedBackdashDecel = on == true ? DefaultSpeeds.BackdashDecelSlow : DefaultSpeeds.BackdashDecel; - alucardApi.BackdashDecel = adjustedBackdashDecel; - } - private void BankruptActivate() { bool hasHolyGlasses = alucardApi.HasItemInInventory("Holy glasses"); @@ -966,196 +1088,67 @@ private void BankruptActivate() alucardApi.GrantItemByName("Silver Ring"); } } - - private void RandomizeGold() - { - Random rnd = new Random(); - uint gold = (uint) rnd.Next(0, 5000); - uint roll = (uint) rnd.Next(0, 21); - if (roll > 16 && roll < 20) - { - gold = gold * (uint) rnd.Next(1, 11); - } - else if (roll > 19) - { - gold = gold * (uint) rnd.Next(10, 81); - } - alucardApi.Gold = gold; - } - - private void RandomizeStatsActivate() + #endregion + #region Buff events + private void MagicianOff(Object sender, EventArgs e) { - Random rnd = new Random(); - uint maxHp = alucardApi.MaxtHp; - uint currentHp = alucardApi.CurrentHp; - uint maxMana = alucardApi.MaxtMp; - uint currentMana = alucardApi.CurrentMp; - uint str = alucardApi.Str; - uint con = alucardApi.Con; - uint intel = alucardApi.Int; - uint lck = alucardApi.Lck; - uint statPool = str + con + intel + lck > 28 ? str + con + intel + lck - 28 : str + con + intel + lck; - uint offset = (uint) (rnd.NextDouble() * statPool); - - int statPoolRoll = rnd.Next(1, 3); - if (statPoolRoll > 1) - { - statPool = statPool + offset; - } - else - { - statPool = ((int) statPool - (int) offset) < 0 ? 0 : statPool - offset; - } - - double a = rnd.NextDouble(); - double b = rnd.NextDouble(); - double c = rnd.NextDouble(); - double d = rnd.NextDouble(); - double sum = a + b + c + d; - double percentageStr = (a / sum); - double percentageCon = (b / sum); - double percentageInt = (c / sum); - double percentageLck = (d / sum); - - alucardApi.Str = (uint) (6 + (statPool * percentageStr)); - alucardApi.Con = (uint) (6 + (statPool * percentageCon)); - alucardApi.Int = (uint) (6 + (statPool * percentageInt)); - alucardApi.Lck = (uint) (6 + (statPool * percentageLck)); - - uint pointsPool = maxHp + maxMana > 110 ? maxHp + maxMana - 110 : maxHp + maxMana; - if (maxHp + maxMana < 110) - { - pointsPool = 110; - } - offset = (uint) (rnd.NextDouble() * pointsPool); - - int pointsRoll = rnd.Next(1, 3); - if (pointsRoll > 1) - { - pointsPool = pointsPool + offset; - } - else - { - pointsPool = ((int) pointsPool - (int) offset) < 0 ? 0 : pointsPool - offset; - } - - double hpPercent = rnd.NextDouble(); - uint pointsHp = 80 + (uint) (hpPercent * pointsPool); - uint pointsMp = 30 + (uint) (pointsPool - (hpPercent * pointsPool)); - - if (currentHp > pointsHp) - { - alucardApi.CurrentHp = pointsHp; - } - if (currentMana > pointsMp) - { - alucardApi.CurrentMp = pointsMp; - } - - alucardApi.MaxtHp = pointsHp; - alucardApi.MaxtMp = pointsMp; + //int potion + Cheat manaCheat = cheats.GetCheatByName("Mana"); + manaCheat.Disable(); + magicianTimer.Stop(); } - - private void RandomizeInventory() + private void MeltyBloodOff(Object sender, EventArgs e) { - bool hasHolyGlasses = alucardApi.HasItemInInventory("Holy glasses"); - bool hasSpikeBreaker = alucardApi.HasItemInInventory("Spike Breaker"); - bool hasGoldRing = alucardApi.HasItemInInventory("Gold Ring"); - bool hasSilverRing = alucardApi.HasItemInInventory("Silver Ring"); - - alucardApi.ClearInventory(); - Random rnd = new Random(); - - int itemCount = rnd.Next(PandoraMinItems, PandoraMaxItems + 1); - - for (int i = 0; i < itemCount; i++) - { - int result = rnd.Next(0, Equipment.Items.Count); - alucardApi.GrantItemByName(Equipment.Items[result]); - } - - if (hasHolyGlasses) - { - alucardApi.GrantItemByName("Holy glasses"); - } - if (hasSpikeBreaker) - { - alucardApi.GrantItemByName("Spike Breaker"); - } - if (hasGoldRing) - { - alucardApi.GrantItemByName("Gold Ring"); - } - if (hasSilverRing) - { - alucardApi.GrantItemByName("Silver Ring"); - } + Cheat width = cheats.GetCheatByName("AlucardAttackHitboxWidth"); + Cheat height = cheats.GetCheatByName("AlucardAttackHitboxHeight"); + width.Disable(); + height.Disable(); + meltyTimer.Stop(); } - - private void RandomizeSubweapon() + private void ZawarudoOff(Object sender, EventArgs e) { - Random rnd = new Random(); - var subweapons = Enum.GetValues(typeof(Subweapon)); - alucardApi.Subweapon = (Subweapon) subweapons.GetValue(rnd.Next(subweapons.Length)); + Cheat stopwatchTimer = cheats.GetCheatByName("SubweaponTimer"); + stopwatchTimer.Disable(); + zawarudoTimer.Stop(); } - - private void RandomizeRelicsActivate() + private void HasteOff(Object sender, EventArgs e) { - Random rnd = new Random(); - var relics = Enum.GetValues(typeof(Relic)); - foreach (var relic in relics) - { - alucardApi.TakeRelic((Relic) relic); - } - foreach (var relic in relics) - { - if (rnd.Next(0, 2) > 0) - { - alucardApi.GrantRelic((Relic) relic); - } - } + SetSpeed(); + hasteTimer.Stop(); } + #endregion - private void RandomizeEquipmentSlots() + private void SetSpeed(float factor = 1) { - bool equippedHolyGlasses = Equipment.Items[(int) (alucardApi.Helm + Equipment.HandCount + 1)] == "Holy glasses"; - bool equippedSpikeBreaker = Equipment.Items[(int) (alucardApi.Armor + Equipment.HandCount + 1)] == "Spike Breaker"; - bool equippedGoldRing = Equipment.Items[(int) (alucardApi.Accessory1 + Equipment.HandCount + 1)] == "Gold Ring" || Equipment.Items[(int) (alucardApi.Accessory2 + Equipment.HandCount)] == "Gold Ring"; - bool equippedSilverRing = Equipment.Items[(int) (alucardApi.Accessory1 + Equipment.HandCount + 1)] == "Silver Ring" || Equipment.Items[(int) (alucardApi.Accessory2 + Equipment.HandCount)] == "Silver Ring"; - - Random rnd = new Random(); - alucardApi.RightHand = (uint) rnd.Next(0, Equipment.HandCount + 1); - alucardApi.LeftHand = (uint) rnd.Next(0, Equipment.HandCount + 1); - alucardApi.Armor = (uint) rnd.Next(0, Equipment.ArmorCount + 1); - alucardApi.Helm = Equipment.HelmStart + (uint) rnd.Next(0, Equipment.HelmCount + 1); - alucardApi.Cloak = Equipment.CloakStart + (uint) rnd.Next(0, Equipment.CloakCount + 1); - alucardApi.Accessory1 = Equipment.AccessoryStart + (uint) rnd.Next(0, Equipment.AccessoryCount + 1); - alucardApi.Accessory2 = Equipment.AccessoryStart + (uint) rnd.Next(0, Equipment.AccessoryCount + 1); - RandomizeSubweapon(); - - if (equippedHolyGlasses) - { - alucardApi.GrantItemByName("Holy glasses"); - } - if (equippedSpikeBreaker) - { - alucardApi.GrantItemByName("Spike Breaker"); - } - if (equippedGoldRing) - { - alucardApi.GrantItemByName("Gold Ring"); - } - if (equippedSilverRing) - { - alucardApi.GrantItemByName("Silver Ring"); - } + bool slow = factor < 1; + bool fast = factor > 1; + alucardApi.WingsmashHorizontalSpeed = (uint) (DefaultSpeeds.WingsmashHorizontal * factor); + alucardApi.WalkingWholeSpeed = fast == true ? (uint) (DefaultSpeeds.WalkingWhole * (factor * 2)) : (uint) (DefaultSpeeds.WalkingWhole * factor); + alucardApi.WalkingFractSpeed = (uint) (DefaultSpeeds.WalkingFract * factor); + alucardApi.JumpingHorizontalWholeSpeed = fast == true ? (uint) (DefaultSpeeds.WalkingWhole * (factor * 2)) : (uint) (DefaultSpeeds.WalkingWhole * factor); + alucardApi.JumpingHorizontalFractSpeed = (uint) (DefaultSpeeds.WalkingFract * factor); + alucardApi.FallingHorizontalWholeSpeed = fast == true ? (uint) (DefaultSpeeds.WalkingWhole * (factor * 2)) : (uint) (DefaultSpeeds.WalkingWhole * factor); + alucardApi.FallingHorizontalFractSpeed = (uint) (DefaultSpeeds.WalkingFract * factor); + alucardApi.WolfDashTopRightSpeed = (sbyte) Math.Floor(DefaultSpeeds.WolfDashTopRight * factor); + alucardApi.WolfDashTopLeftSpeed = (sbyte) Math.Ceiling(DefaultSpeeds.WolfDashTopLeft * factor); + alucardApi.BackdashDecel = slow == true ? DefaultSpeeds.BackdashDecelSlow : DefaultSpeeds.BackdashDecel; } - private void CheckManaUsage() { uint currentMana = alucardApi.CurrentMp; spentMana = (int) storedMana - (int) currentMana; storedMana = currentMana; } + private void CheckExperience() + { + uint currentExperiecne = alucardApi.Experiecne; + //gainedExperiecne = (int) currentExperiecne - (int) storedExperiecne; + //storedExperiecne = currentExperiecne; + } + private void OnBotFileChanged(object sender, FileSystemEventArgs e) + { + string lastLine = FileExtensions.GetLastLine(toolConfig.Khaos.BotActionsFilePath); + EnqueueAction(lastLine); + } } } diff --git a/SotnRandoTools/src/Khaos/Models/KhaosViewModel.cs b/SotnRandoTools/src/Khaos/Models/KhaosViewModel.cs new file mode 100644 index 0000000..42bdd8e --- /dev/null +++ b/SotnRandoTools/src/Khaos/Models/KhaosViewModel.cs @@ -0,0 +1,28 @@ +using System.ComponentModel; + +namespace SotnRandoTools.Khaos.Models +{ + public class KhaosViewModel : INotifyPropertyChanged + { + private bool started; + + public bool Started + { + get + { + return started; + } + set + { + started = value; + + if (PropertyChanged != null) + { + PropertyChanged(this, new PropertyChangedEventArgs("Started")); + } + } + } + + public event PropertyChangedEventHandler PropertyChanged; + } +} diff --git a/SotnRandoTools/src/KhaosForm.Designer.cs b/SotnRandoTools/src/KhaosForm.Designer.cs index 435eca9..8d6e274 100644 --- a/SotnRandoTools/src/KhaosForm.Designer.cs +++ b/SotnRandoTools/src/KhaosForm.Designer.cs @@ -31,6 +31,8 @@ private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(KhaosForm)); this.controlBox = new System.Windows.Forms.GroupBox(); + this.hasteButton = new System.Windows.Forms.Button(); + this.subsonlyButton = new System.Windows.Forms.Button(); this.hordeButton = new System.Windows.Forms.Button(); this.zawarudoButton = new System.Windows.Forms.Button(); this.modePanel = new System.Windows.Forms.GroupBox(); @@ -58,13 +60,13 @@ private void InitializeComponent() this.randomEquipmentButton = new System.Windows.Forms.Button(); this.randomStatusButton = new System.Windows.Forms.Button(); this.startButton = new System.Windows.Forms.Button(); - this.subsonlyButton = new System.Windows.Forms.Button(); this.controlBox.SuspendLayout(); this.modePanel.SuspendLayout(); this.SuspendLayout(); // // controlBox // + this.controlBox.Controls.Add(this.hasteButton); this.controlBox.Controls.Add(this.subsonlyButton); this.controlBox.Controls.Add(this.hordeButton); this.controlBox.Controls.Add(this.zawarudoButton); @@ -93,13 +95,43 @@ private void InitializeComponent() this.controlBox.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.controlBox.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); this.controlBox.ForeColor = System.Drawing.Color.White; - this.controlBox.Location = new System.Drawing.Point(12, 186); + this.controlBox.Location = new System.Drawing.Point(12, 72); this.controlBox.Name = "controlBox"; - this.controlBox.Size = new System.Drawing.Size(426, 398); + this.controlBox.Size = new System.Drawing.Size(426, 419); this.controlBox.TabIndex = 0; this.controlBox.TabStop = false; this.controlBox.Text = "Manual Control Panel"; // + // hasteButton + // + this.hasteButton.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(57)))), ((int)(((byte)(21)))), ((int)(((byte)(57))))); + this.hasteButton.FlatAppearance.BorderSize = 2; + this.hasteButton.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(67)))), ((int)(((byte)(35)))), ((int)(((byte)(67))))); + this.hasteButton.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(20)))), ((int)(((byte)(48))))); + this.hasteButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.hasteButton.Location = new System.Drawing.Point(286, 385); + this.hasteButton.Name = "hasteButton"; + this.hasteButton.Size = new System.Drawing.Size(134, 26); + this.hasteButton.TabIndex = 25; + this.hasteButton.Text = "Haste"; + this.hasteButton.UseVisualStyleBackColor = true; + this.hasteButton.Click += new System.EventHandler(this.hasteButton_Click); + // + // subsonlyButton + // + this.subsonlyButton.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(57)))), ((int)(((byte)(21)))), ((int)(((byte)(57))))); + this.subsonlyButton.FlatAppearance.BorderSize = 2; + this.subsonlyButton.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(67)))), ((int)(((byte)(35)))), ((int)(((byte)(67))))); + this.subsonlyButton.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(20)))), ((int)(((byte)(48))))); + this.subsonlyButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.subsonlyButton.Location = new System.Drawing.Point(146, 225); + this.subsonlyButton.Name = "subsonlyButton"; + this.subsonlyButton.Size = new System.Drawing.Size(134, 26); + this.subsonlyButton.TabIndex = 24; + this.subsonlyButton.Text = "SubweaponsOnly"; + this.subsonlyButton.UseVisualStyleBackColor = true; + this.subsonlyButton.Click += new System.EventHandler(this.subsonlyButton_Click); + // // hordeButton // this.hordeButton.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(57)))), ((int)(((byte)(21)))), ((int)(((byte)(57))))); @@ -488,7 +520,7 @@ private void InitializeComponent() this.startButton.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(20)))), ((int)(((byte)(48))))); this.startButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.startButton.ForeColor = System.Drawing.Color.White; - this.startButton.Location = new System.Drawing.Point(158, 29); + this.startButton.Location = new System.Drawing.Point(158, 12); this.startButton.Name = "startButton"; this.startButton.Size = new System.Drawing.Size(134, 54); this.startButton.TabIndex = 5; @@ -496,25 +528,10 @@ private void InitializeComponent() this.startButton.UseVisualStyleBackColor = true; this.startButton.Click += new System.EventHandler(this.startButton_Click); // - // subsonlyButton - // - this.subsonlyButton.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(57)))), ((int)(((byte)(21)))), ((int)(((byte)(57))))); - this.subsonlyButton.FlatAppearance.BorderSize = 2; - this.subsonlyButton.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(67)))), ((int)(((byte)(35)))), ((int)(((byte)(67))))); - this.subsonlyButton.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(48)))), ((int)(((byte)(20)))), ((int)(((byte)(48))))); - this.subsonlyButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.subsonlyButton.Location = new System.Drawing.Point(146, 225); - this.subsonlyButton.Name = "subsonlyButton"; - this.subsonlyButton.Size = new System.Drawing.Size(134, 26); - this.subsonlyButton.TabIndex = 24; - this.subsonlyButton.Text = "SubweaponsOnly"; - this.subsonlyButton.UseVisualStyleBackColor = true; - this.subsonlyButton.Click += new System.EventHandler(this.subsonlyButton_Click); - // // KhaosForm // this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(0)))), ((int)(((byte)(17))))); - this.ClientSize = new System.Drawing.Size(450, 596); + this.ClientSize = new System.Drawing.Size(450, 498); this.Controls.Add(this.startButton); this.Controls.Add(this.controlBox); this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); @@ -564,6 +581,7 @@ private void InitializeComponent() private System.Windows.Forms.Button zawarudoButton; private System.Windows.Forms.Button hordeButton; private System.Windows.Forms.Button subsonlyButton; + private System.Windows.Forms.Button hasteButton; } } diff --git a/SotnRandoTools/src/KhaosForm.cs b/SotnRandoTools/src/KhaosForm.cs index e378236..4fe5e63 100644 --- a/SotnRandoTools/src/KhaosForm.cs +++ b/SotnRandoTools/src/KhaosForm.cs @@ -17,6 +17,7 @@ public partial class KhaosForm : Form private readonly IGameApi gameApi; private readonly IAlucardApi alucardApi; private readonly IActorApi actorApi; + private bool started = false; public KhaosForm(IToolConfig toolConfig, CheatCollection cheats, IGameApi gameApi, IAlucardApi alucardApi, IActorApi actorApi, INotificationService notificationService) { @@ -65,7 +66,34 @@ private void KhaosForm_Move(object sender, EventArgs e) toolConfig.Khaos.Location = this.Location; } } + private void queueRadio_CheckedChanged(object sender, EventArgs e) + { + if (queueRadio.Checked) + { + toolConfig.Khaos.ControlPannelQueueActions = true; + } + else + { + toolConfig.Khaos.ControlPannelQueueActions = false; + } + } + private void startButton_Click(object sender, EventArgs e) + { + if (started) + { + started = false; + khaosControler.StopKhaos(); + startButton.Text = "Start"; + } + else + { + started = true; + khaosControler.StartKhaos(); + startButton.Text = "Stop"; + } + } + #region Khaotic effects private void randomStatusButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -77,7 +105,6 @@ private void randomStatusButton_Click(object sender, EventArgs e) khaosControler.InflictRandomStatus(); } } - private void randomEquipmentButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -90,7 +117,6 @@ private void randomEquipmentButton_Click(object sender, EventArgs e) khaosControler.RandomizeEquipment(); } } - private void randomizeStatsButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -103,7 +129,6 @@ private void randomizeStatsButton_Click(object sender, EventArgs e) khaosControler.RandomizeStats(); } } - private void randomizeRelicsButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -116,7 +141,6 @@ private void randomizeRelicsButton_Click(object sender, EventArgs e) khaosControler.RandomizeRelics(); } } - private void pandorasBoxButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -129,7 +153,6 @@ private void pandorasBoxButton_Click(object sender, EventArgs e) khaosControler.PandorasBox(); } } - private void bankruptButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -141,7 +164,20 @@ private void bankruptButton_Click(object sender, EventArgs e) khaosControler.Bankrupt(); } } + private void gambleButton_Click(object sender, EventArgs e) + { + if (toolConfig.Khaos.ControlPannelQueueActions) + { + khaosControler.EnqueueAction("gamble Khaos"); + } + else + { + khaosControler.Gamble(); + } + } + #endregion + #region Debuffs private void weakenButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -153,7 +189,6 @@ private void weakenButton_Click(object sender, EventArgs e) khaosControler.Weaken(); } } - private void respawnBossesButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -165,59 +200,77 @@ private void respawnBossesButton_Click(object sender, EventArgs e) khaosControler.RespawnBosses(); } } - - private void vampireButton_Click(object sender, EventArgs e) + private void honestButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) { - khaosControler.EnqueueAction("vampire Khaos"); + khaosControler.EnqueueAction("honest Khaos"); } else { - khaosControler.Vampire(); + khaosControler.HonestGamer(); } } - - private void gambleButton_Click(object sender, EventArgs e) + private void subsonlyButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) { - khaosControler.EnqueueAction("gamble Khaos"); + khaosControler.EnqueueAction("subsonly Khaos"); } else { - khaosControler.Gamble(); + khaosControler.SubweaponsOnly(); } } - - private void honestButton_Click(object sender, EventArgs e) + private void bloodManaButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) { - khaosControler.EnqueueAction("honest Khaos"); + khaosControler.EnqueueAction("bloodmana Khaos"); } else { - - khaosControler.HonestGamer(); + khaosControler.BloodMana(); } } - - private void subsonlyButton_Click(object sender, EventArgs e) + private void thurstButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) { - khaosControler.EnqueueAction("subsonly Khaos"); + khaosControler.EnqueueAction("thirst Khaos"); } else { - - khaosControler.SubweaponsOnly(); + khaosControler.Thirst(); + } + } + private void hordeButton_Click(object sender, EventArgs e) + { + if (toolConfig.Khaos.ControlPannelQueueActions) + { + khaosControler.EnqueueAction("horde Khaos"); + } + else + { + khaosControler.Horde(); } } + private void crippleButton_Click(object sender, EventArgs e) + { + if (toolConfig.Khaos.ControlPannelQueueActions) + { + khaosControler.EnqueueAction("cripple Khaos"); + } + else + { + khaosControler.Cripple(); + } + } + #endregion + #region Buffs private void lightHelpButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -229,7 +282,6 @@ private void lightHelpButton_Click(object sender, EventArgs e) khaosControler.RandomLightHelp(); } } - private void mediumHelpButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -242,7 +294,6 @@ private void mediumHelpButton_Click(object sender, EventArgs e) khaosControler.RandomMediumHelp(); } } - private void heavyHelpButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -255,7 +306,6 @@ private void heavyHelpButton_Click(object sender, EventArgs e) khaosControler.RandomHeavytHelp(); } } - private void battleOrdersButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -268,7 +318,6 @@ private void battleOrdersButton_Click(object sender, EventArgs e) khaosControler.BattleOrders(); } } - private void magicianButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -281,7 +330,6 @@ private void magicianButton_Click(object sender, EventArgs e) khaosControler.Magician(); } } - private void meltyButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -294,32 +342,18 @@ private void meltyButton_Click(object sender, EventArgs e) khaosControler.MeltyBlood(); } } - - private void crippleButton_Click(object sender, EventArgs e) + private void vampireButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) { - khaosControler.EnqueueAction("cripple Khaos"); + khaosControler.EnqueueAction("vampire Khaos"); } else { - khaosControler.Cripple(); - } - } - - private void bloodManaButton_Click(object sender, EventArgs e) - { - if (toolConfig.Khaos.ControlPannelQueueActions) - { - khaosControler.EnqueueAction("bloodmana Khaos"); - } - else - { - khaosControler.BloodMana(); + khaosControler.Vampire(); } } - private void fourBeastsButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -331,36 +365,6 @@ private void fourBeastsButton_Click(object sender, EventArgs e) khaosControler.FourBeasts(); } } - - private void thurstButton_Click(object sender, EventArgs e) - { - if (toolConfig.Khaos.ControlPannelQueueActions) - { - khaosControler.EnqueueAction("thirst Khaos"); - } - else - { - khaosControler.Thirst(); - } - } - - private void queueRadio_CheckedChanged(object sender, EventArgs e) - { - if (queueRadio.Checked) - { - toolConfig.Khaos.ControlPannelQueueActions = true; - } - else - { - toolConfig.Khaos.ControlPannelQueueActions = false; - } - } - - private void startButton_Click(object sender, EventArgs e) - { - khaosControler.StartKhaos(); - } - private void zawarudoButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) @@ -372,17 +376,17 @@ private void zawarudoButton_Click(object sender, EventArgs e) khaosControler.ZaWarudo(); } } - - private void hordeButton_Click(object sender, EventArgs e) + private void hasteButton_Click(object sender, EventArgs e) { if (toolConfig.Khaos.ControlPannelQueueActions) { - khaosControler.EnqueueAction("horde Khaos"); + khaosControler.EnqueueAction("haste Khaos"); } else { - khaosControler.Horde(); + khaosControler.Haste(); } } + #endregion } } diff --git a/SotnRandoTools/src/Panels/AboutPanel.Designer.cs b/SotnRandoTools/src/Panels/AboutPanel.Designer.cs index cb1231c..ca6937f 100644 --- a/SotnRandoTools/src/Panels/AboutPanel.Designer.cs +++ b/SotnRandoTools/src/Panels/AboutPanel.Designer.cs @@ -35,6 +35,13 @@ private void InitializeComponent() this.versionLabel = new System.Windows.Forms.Label(); this.updateButton = new System.Windows.Forms.Button(); this.upToDateToolTip = new System.Windows.Forms.ToolTip(this.components); + this.descriptionLabel = new System.Windows.Forms.Label(); + this.readmeLink = new System.Windows.Forms.LinkLabel(); + this.sourceLink = new System.Windows.Forms.LinkLabel(); + this.donateLink = new System.Windows.Forms.LinkLabel(); + this.sotnApiLink = new System.Windows.Forms.LinkLabel(); + this.updaterLink = new System.Windows.Forms.LinkLabel(); + this.randoLink = new System.Windows.Forms.LinkLabel(); this.SuspendLayout(); // // autotrackerPanelTitle @@ -57,13 +64,13 @@ private void InitializeComponent() // // versionLabel // - this.versionLabel.AutoSize = true; - this.versionLabel.Font = new System.Drawing.Font("Tahoma", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(204))); - this.versionLabel.Location = new System.Drawing.Point(13, 49); + this.versionLabel.Font = new System.Drawing.Font("Tahoma", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.versionLabel.Location = new System.Drawing.Point(6, 51); this.versionLabel.Name = "versionLabel"; - this.versionLabel.Size = new System.Drawing.Size(62, 19); + this.versionLabel.Size = new System.Drawing.Size(382, 19); this.versionLabel.TabIndex = 2; this.versionLabel.Text = "Version"; + this.versionLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // // updateButton // @@ -83,11 +90,120 @@ private void InitializeComponent() this.updateButton.Visible = false; this.updateButton.Click += new System.EventHandler(this.updateButton_Click); // + // descriptionLabel + // + this.descriptionLabel.AutoSize = true; + this.descriptionLabel.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.descriptionLabel.Location = new System.Drawing.Point(7, 149); + this.descriptionLabel.MaximumSize = new System.Drawing.Size(400, 0); + this.descriptionLabel.Name = "descriptionLabel"; + this.descriptionLabel.Size = new System.Drawing.Size(365, 65); + this.descriptionLabel.TabIndex = 5; + this.descriptionLabel.Text = "SotN Randomizer Tools is a free and open source set of tools to enhance the SotN " + + "randomizer experience.\r\nMade by TalicZealot.\r\n\r\nAssociated Projects:"; + // + // readmeLink + // + this.readmeLink.ActiveLinkColor = System.Drawing.Color.Maroon; + this.readmeLink.AutoSize = true; + this.readmeLink.Font = new System.Drawing.Font("Tahoma", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.readmeLink.LinkColor = System.Drawing.Color.DodgerBlue; + this.readmeLink.Location = new System.Drawing.Point(7, 343); + this.readmeLink.Name = "readmeLink"; + this.readmeLink.Size = new System.Drawing.Size(68, 18); + this.readmeLink.TabIndex = 6; + this.readmeLink.TabStop = true; + this.readmeLink.Text = "Readme"; + this.readmeLink.VisitedLinkColor = System.Drawing.Color.Cyan; + this.readmeLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.readmeLink_LinkClicked); + // + // sourceLink + // + this.sourceLink.ActiveLinkColor = System.Drawing.Color.Maroon; + this.sourceLink.AutoSize = true; + this.sourceLink.Font = new System.Drawing.Font("Tahoma", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.sourceLink.LinkColor = System.Drawing.Color.DodgerBlue; + this.sourceLink.Location = new System.Drawing.Point(171, 343); + this.sourceLink.Name = "sourceLink"; + this.sourceLink.Size = new System.Drawing.Size(60, 18); + this.sourceLink.TabIndex = 7; + this.sourceLink.TabStop = true; + this.sourceLink.Text = "Source"; + this.sourceLink.VisitedLinkColor = System.Drawing.Color.Cyan; + this.sourceLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.sourceLink_LinkClicked); + // + // donateLink + // + this.donateLink.ActiveLinkColor = System.Drawing.Color.Maroon; + this.donateLink.AutoSize = true; + this.donateLink.Font = new System.Drawing.Font("Tahoma", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.donateLink.LinkColor = System.Drawing.Color.DodgerBlue; + this.donateLink.Location = new System.Drawing.Point(324, 343); + this.donateLink.Name = "donateLink"; + this.donateLink.Size = new System.Drawing.Size(61, 18); + this.donateLink.TabIndex = 8; + this.donateLink.TabStop = true; + this.donateLink.Text = "Donate"; + this.donateLink.VisitedLinkColor = System.Drawing.Color.Cyan; + this.donateLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.donateLink_LinkClicked); + // + // sotnApiLink + // + this.sotnApiLink.ActiveLinkColor = System.Drawing.Color.Maroon; + this.sotnApiLink.AutoSize = true; + this.sotnApiLink.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.sotnApiLink.LinkColor = System.Drawing.Color.DodgerBlue; + this.sotnApiLink.Location = new System.Drawing.Point(18, 224); + this.sotnApiLink.Name = "sotnApiLink"; + this.sotnApiLink.Size = new System.Drawing.Size(57, 14); + this.sotnApiLink.TabIndex = 9; + this.sotnApiLink.TabStop = true; + this.sotnApiLink.Text = "SotnApi"; + this.sotnApiLink.VisitedLinkColor = System.Drawing.Color.Cyan; + this.sotnApiLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.sotnApiLink_LinkClicked); + // + // updaterLink + // + this.updaterLink.ActiveLinkColor = System.Drawing.Color.Maroon; + this.updaterLink.AutoSize = true; + this.updaterLink.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.updaterLink.LinkColor = System.Drawing.Color.DodgerBlue; + this.updaterLink.Location = new System.Drawing.Point(18, 247); + this.updaterLink.Name = "updaterLink"; + this.updaterLink.Size = new System.Drawing.Size(181, 14); + this.updaterLink.TabIndex = 10; + this.updaterLink.TabStop = true; + this.updaterLink.Text = "SimpleLatestReleaseUpdater"; + this.updaterLink.VisitedLinkColor = System.Drawing.Color.Cyan; + this.updaterLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.updaterLink_LinkClicked); + // + // randoLink + // + this.randoLink.ActiveLinkColor = System.Drawing.Color.Maroon; + this.randoLink.AutoSize = true; + this.randoLink.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(204))); + this.randoLink.LinkColor = System.Drawing.Color.DodgerBlue; + this.randoLink.Location = new System.Drawing.Point(18, 271); + this.randoLink.Name = "randoLink"; + this.randoLink.Size = new System.Drawing.Size(113, 14); + this.randoLink.TabIndex = 11; + this.randoLink.TabStop = true; + this.randoLink.Text = "SotN Randomizer"; + this.randoLink.VisitedLinkColor = System.Drawing.Color.Cyan; + this.randoLink.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.randoLink_LinkClicked); + // // AboutPanel // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(17)))), ((int)(((byte)(0)))), ((int)(((byte)(17))))); + this.Controls.Add(this.randoLink); + this.Controls.Add(this.updaterLink); + this.Controls.Add(this.sotnApiLink); + this.Controls.Add(this.donateLink); + this.Controls.Add(this.sourceLink); + this.Controls.Add(this.readmeLink); + this.Controls.Add(this.descriptionLabel); this.Controls.Add(this.updateButton); this.Controls.Add(this.versionLabel); this.Controls.Add(this.divider); @@ -109,5 +225,12 @@ private void InitializeComponent() private System.Windows.Forms.Label versionLabel; private System.Windows.Forms.Button updateButton; private System.Windows.Forms.ToolTip upToDateToolTip; + private System.Windows.Forms.Label descriptionLabel; + private System.Windows.Forms.LinkLabel readmeLink; + private System.Windows.Forms.LinkLabel sourceLink; + private System.Windows.Forms.LinkLabel donateLink; + private System.Windows.Forms.LinkLabel sotnApiLink; + private System.Windows.Forms.LinkLabel updaterLink; + private System.Windows.Forms.LinkLabel randoLink; } } diff --git a/SotnRandoTools/src/Panels/AboutPanel.cs b/SotnRandoTools/src/Panels/AboutPanel.cs index 4d9daae..63ffbf9 100644 --- a/SotnRandoTools/src/Panels/AboutPanel.cs +++ b/SotnRandoTools/src/Panels/AboutPanel.cs @@ -1,6 +1,9 @@ using System; using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; using System.Windows.Forms; +using SotnRandoTools.Constants; using SotnRandoTools.Utils; namespace SotnRandoTools @@ -25,11 +28,17 @@ private async void AboutPanel_Load(object sender, EventArgs e) if (await WebRequests.NewReleaseAvaiable(currentVersion)) { updateButton.Visible = true; + this.versionLabel.Text += " ❌"; + this.upToDateToolTip.SetToolTip(versionLabel, "New version available!"); + this.upToDateToolTip.ToolTipIcon = ToolTipIcon.Warning; + this.versionLabel.ForeColor = Color.PaleVioletRed; } else { this.versionLabel.Text += " ✔️"; this.upToDateToolTip.SetToolTip(versionLabel, "Up to date!"); + this.upToDateToolTip.ToolTipIcon = ToolTipIcon.None; + this.versionLabel.ForeColor = Color.SpringGreen; } } @@ -38,5 +47,41 @@ private void updateButton_Click(object sender, EventArgs e) if (this.UpdateButton_Click != null) this.UpdateButton_Click(this, e); } + + private void sotnApiLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + sotnApiLink.LinkVisited = true; + Process.Start(Paths.ApiLink); + } + + private void updaterLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + updaterLink.LinkVisited = true; + Process.Start(Paths.UpdaterLink); + } + + private void randoLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + randoLink.LinkVisited = true; + Process.Start(Paths.RandoSourceLink); + } + + private void readmeLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + readmeLink.LinkVisited = true; + Process.Start(Paths.ReadmeLink); + } + + private void sourceLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + sourceLink.LinkVisited = true; + Process.Start(Paths.SourceLink); + } + + private void donateLink_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + donateLink.LinkVisited = true; + Process.Start(Paths.DonateLink); + } } } diff --git a/SotnRandoTools/src/Panels/KhaosSettingsPanel.cs b/SotnRandoTools/src/Panels/KhaosSettingsPanel.cs index a13a8f6..ef8e8a0 100644 --- a/SotnRandoTools/src/Panels/KhaosSettingsPanel.cs +++ b/SotnRandoTools/src/Panels/KhaosSettingsPanel.cs @@ -24,7 +24,7 @@ private void KhaosSettingsPanel_Load(object sender, EventArgs e) { botCommandsPath.Text = toolConfig.Khaos.BotActionsFilePath; } - volumeTrackBar.Value = toolConfig.Khaos.Volume; + //volumeTrackBar.Value = toolConfig.Khaos.Volume; } private void saveButton_Click(object sender, EventArgs e) @@ -40,7 +40,7 @@ private void botActionFileDialog_FileOk(object sender, System.ComponentModel.Can private void volumeTrackBar_Scroll(object sender, EventArgs e) { - toolConfig.Khaos.Volume = volumeTrackBar.Value; + //toolConfig.Khaos.Volume = volumeTrackBar.Value; } private void botCommandsBrowseButton_Click(object sender, EventArgs e) diff --git a/SotnRandoTools/src/Services/Interfaces/INotificationService.cs b/SotnRandoTools/src/Services/Interfaces/INotificationService.cs index 794380f..af75a51 100644 --- a/SotnRandoTools/src/Services/Interfaces/INotificationService.cs +++ b/SotnRandoTools/src/Services/Interfaces/INotificationService.cs @@ -3,5 +3,7 @@ public interface INotificationService { void DisplayMessage(string message); + + void PlayAlert(string uri); } } \ No newline at end of file diff --git a/SotnRandoTools/src/Services/NotificationService.cs b/SotnRandoTools/src/Services/NotificationService.cs index 638b176..5569fea 100644 --- a/SotnRandoTools/src/Services/NotificationService.cs +++ b/SotnRandoTools/src/Services/NotificationService.cs @@ -2,30 +2,40 @@ using System.Collections.Generic; using System.Drawing; using System.Timers; +using System.Windows.Forms; using BizHawk.Client.Common; +using SotnRandoTools.Configuration.Interfaces; using SotnRandoTools.Constants; namespace SotnRandoTools.Services { public class NotificationService : INotificationService { - private Timer messageTimer; + const int NotificationTime = 5 * 1000; + private readonly IGuiApi guiApi; + private readonly IToolConfig toolConfig; + + private System.Timers.Timer messageTimer; private int screenWidth = 0; private int screenHeight = 0; private Image textbox; + private WMPLib.WindowsMediaPlayer audioPlayer = new WMPLib.WindowsMediaPlayer(); - public NotificationService(IGuiApi guiApi, int screenWidth, int screenHeight) + public NotificationService(IToolConfig toolConfig, IGuiApi guiApi, int screenWidth, int screenHeight) { if (guiApi is null) throw new ArgumentNullException(nameof(guiApi)); + if (toolConfig is null) throw new ArgumentNullException(nameof(toolConfig)); this.guiApi = guiApi; + this.toolConfig = toolConfig; this.screenWidth = screenWidth; this.screenHeight = screenHeight; - messageTimer = new Timer(); - messageTimer.Interval = 4 * 1000; + messageTimer = new System.Timers.Timer(); + messageTimer.Interval = NotificationTime; messageTimer.Elapsed += ClearMessages; textbox = Image.FromFile(Paths.TextboxImage); + audioPlayer.settings.volume = toolConfig.Khaos.Volume * 10; } private void ClearMessages(object sender, ElapsedEventArgs e) @@ -39,16 +49,31 @@ private void ClearMessages(object sender, ElapsedEventArgs e) public void DisplayMessage(string message) { - Console.WriteLine(screenWidth); + int fontSize = 22; + while (TextRenderer.MeasureText(message, new Font("Arial", fontSize)).Width > 428) + { + fontSize--; + } + guiApi.WithSurface(DisplaySurfaceID.Client, () => { guiApi.ClearGraphics(); guiApi.DrawRectangle((int) (screenWidth * 0.6) - 215, (int) (screenHeight * 0.1) + 6, 430, 30, Color.FromArgb(100, Color.Blue), Color.FromArgb(100, Color.Blue)); - guiApi.DrawString((int) (screenWidth * 0.6), (int) (screenHeight * 0.1) + 22, message, Color.White, null, 22, "Arial", "bold", "center", "center"); + guiApi.DrawString((int) (screenWidth * 0.6), (int) (screenHeight * 0.1) + 22, message, Color.White, null, fontSize, "Arial", "bold", "center", "center"); guiApi.DrawImage(textbox, (int) (screenWidth * 0.6) - 220, (int) (screenHeight * 0.1)); }); messageTimer.Start(); } + + public void PlayAlert(string url) + { + if (url == String.Empty || !toolConfig.Khaos.Alerts) + { + return; + } + audioPlayer.URL = url; + audioPlayer.controls.play(); + } } } diff --git a/SotnRandoTools/src/SotnRandoTools.csproj b/SotnRandoTools/src/SotnRandoTools.csproj index 7847ea1..e8adaa0 100644 --- a/SotnRandoTools/src/SotnRandoTools.csproj +++ b/SotnRandoTools/src/SotnRandoTools.csproj @@ -11,7 +11,7 @@ Library false 5.0 - 0.1.5 + 0.1.6 A collection of tools to enhance the experience of playign the SotN randomizer. @@ -24,6 +24,17 @@ + + + 0 + 1 + 6bf52a50-394a-11d3-b153-00c04f79faa6 + 0 + tlbimp + false + true + + diff --git a/SotnRandoTools/src/ToolMainForm.cs b/SotnRandoTools/src/ToolMainForm.cs index ab71ec5..606576d 100644 --- a/SotnRandoTools/src/ToolMainForm.cs +++ b/SotnRandoTools/src/ToolMainForm.cs @@ -126,7 +126,7 @@ private void ToolMainForm_Load(object sender, EventArgs e) gameApi = new GameApi(_maybeMemAPI); renderingApi = new RenderingApi(_maybeMemAPI); watchlistService = new WatchlistService(_memoryDomains, _emu?.SystemId, GlobalConfig); - notificationService = new NotificationService(_maybeGuiAPI, _maybeClientAPI.ScreenWidth() , _maybeClientAPI.ScreenHeight()); + notificationService = new NotificationService(toolConfig, _maybeGuiAPI, _maybeClientAPI.ScreenWidth() , _maybeClientAPI.ScreenHeight()); } public override bool AskSaveChanges() => true;