2015-08-27 01:55:55 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Drawing;
|
2015-08-30 00:19:56 +00:00
|
|
|
|
using System.IO;
|
2015-08-27 01:55:55 +00:00
|
|
|
|
using System.Linq;
|
2015-08-30 21:57:02 +00:00
|
|
|
|
using System.Text;
|
2015-08-27 01:55:55 +00:00
|
|
|
|
using System.Windows.Forms;
|
2015-09-06 03:39:51 +00:00
|
|
|
|
using BizHawk.Client.EmuHawk.ToolExtensions;
|
2015-08-27 01:55:55 +00:00
|
|
|
|
|
|
|
|
|
using BizHawk.Emulation.Common;
|
2015-08-27 02:41:34 +00:00
|
|
|
|
using BizHawk.Client.Common;
|
2015-08-27 01:55:55 +00:00
|
|
|
|
|
|
|
|
|
namespace BizHawk.Client.EmuHawk
|
|
|
|
|
{
|
|
|
|
|
public partial class BasicBot : Form , IToolFormAutoConfig
|
|
|
|
|
{
|
2015-09-06 03:39:51 +00:00
|
|
|
|
private const string DialogTitle = "Basic Bot";
|
|
|
|
|
|
|
|
|
|
private string _currentFileName = string.Empty;
|
2015-09-07 02:21:12 +00:00
|
|
|
|
|
|
|
|
|
private string CurrentFileName
|
|
|
|
|
{
|
|
|
|
|
get { return _currentFileName; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
_currentFileName = value;
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(_currentFileName))
|
|
|
|
|
{
|
|
|
|
|
Text = DialogTitle + " - " + Path.GetFileNameWithoutExtension(_currentFileName);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Text = DialogTitle;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
private bool _isBotting = false;
|
|
|
|
|
private long _attempts = 1;
|
|
|
|
|
private long _frames = 0;
|
|
|
|
|
private int _targetFrame = 0;
|
|
|
|
|
private bool _oldCountingSetting = false;
|
|
|
|
|
private BotAttempt _currentBotAttempt = null;
|
|
|
|
|
private BotAttempt _bestBotAttempt = null;
|
2015-09-06 02:04:26 +00:00
|
|
|
|
private bool _replayMode = false;
|
|
|
|
|
private int _startFrame = 0;
|
2015-09-07 02:29:46 +00:00
|
|
|
|
private string _lastRom = string.Empty;
|
2015-08-30 21:57:02 +00:00
|
|
|
|
|
|
|
|
|
private bool _dontUpdateValues = false;
|
|
|
|
|
|
2015-09-06 23:37:15 +00:00
|
|
|
|
private MemoryDomain _currentDomain;
|
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
#region Services and Settings
|
|
|
|
|
|
2015-08-27 01:55:55 +00:00
|
|
|
|
[RequiredService]
|
|
|
|
|
private IEmulator Emulator { get; set; }
|
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
// Unused, due to the use of MainForm to loadstate, but this needs to be kept here in order to establish an IStatable dependency
|
2015-08-27 01:55:55 +00:00
|
|
|
|
[RequiredService]
|
|
|
|
|
private IStatable StatableCore { get; set; }
|
|
|
|
|
|
|
|
|
|
[RequiredService]
|
|
|
|
|
private IMemoryDomains MemoryDomains { get; set; }
|
|
|
|
|
|
|
|
|
|
[ConfigPersist]
|
|
|
|
|
public BasicBotSettings Settings { get; set; }
|
|
|
|
|
|
|
|
|
|
public class BasicBotSettings
|
|
|
|
|
{
|
2015-09-06 03:39:51 +00:00
|
|
|
|
public BasicBotSettings()
|
|
|
|
|
{
|
|
|
|
|
RecentBotFiles = new RecentFiles();
|
2015-09-06 22:00:39 +00:00
|
|
|
|
TurboWhenBotting = true;
|
2015-09-06 03:39:51 +00:00
|
|
|
|
}
|
2015-08-27 01:55:55 +00:00
|
|
|
|
|
2015-09-06 03:39:51 +00:00
|
|
|
|
public RecentFiles RecentBotFiles { get; set; }
|
2015-09-06 22:00:39 +00:00
|
|
|
|
public bool TurboWhenBotting { get; set; }
|
2015-08-27 01:55:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Initialize
|
|
|
|
|
|
2015-08-27 01:55:55 +00:00
|
|
|
|
public BasicBot()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
2015-09-06 03:39:51 +00:00
|
|
|
|
Text = DialogTitle;
|
|
|
|
|
Settings = new BasicBotSettings();
|
2015-08-27 01:55:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void BasicBot_Load(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-08-27 02:41:34 +00:00
|
|
|
|
|
2015-09-07 02:29:46 +00:00
|
|
|
|
}
|
2015-08-27 01:55:55 +00:00
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
#endregion
|
2015-08-27 01:55:55 +00:00
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
#region UI Bindings
|
2015-08-27 01:55:55 +00:00
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
private Dictionary<string, double> ControlProbabilities
|
2015-08-27 01:55:55 +00:00
|
|
|
|
{
|
2015-08-30 21:57:02 +00:00
|
|
|
|
get
|
2015-08-30 00:19:56 +00:00
|
|
|
|
{
|
2015-08-30 21:57:02 +00:00
|
|
|
|
return ControlProbabilityPanel.Controls
|
|
|
|
|
.OfType<BotControlsRow>()
|
|
|
|
|
.ToDictionary(tkey => tkey.ButtonName, tvalue => tvalue.Probability);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string SelectedSlot
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
char num = StartFromSlotBox.SelectedItem
|
|
|
|
|
.ToString()
|
|
|
|
|
.Last();
|
|
|
|
|
|
|
|
|
|
return "QuickSave" + num;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private long Attempts
|
|
|
|
|
{
|
|
|
|
|
get { return _attempts; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
_attempts = value;
|
|
|
|
|
AttemptsLabel.Text = _attempts.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private long Frames
|
|
|
|
|
{
|
|
|
|
|
get { return _frames; }
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
_frames = value;
|
|
|
|
|
FramesLabel.Text = _frames.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int FrameLength
|
|
|
|
|
{
|
|
|
|
|
get { return (int)FrameLengthNumeric.Value; }
|
2015-09-06 03:39:51 +00:00
|
|
|
|
set { FrameLengthNumeric.Value = value; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int MaximizeAddress
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
int? addr = MaximizeAddressBox.ToRawInt();
|
|
|
|
|
if (addr.HasValue)
|
|
|
|
|
{
|
|
|
|
|
return addr.Value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
MaximizeAddressBox.SetFromRawInt(value);
|
|
|
|
|
}
|
2015-08-30 21:57:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int MaximizeValue
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
int? addr = MaximizeAddressBox.ToRawInt();
|
|
|
|
|
if (addr.HasValue)
|
2015-08-30 00:19:56 +00:00
|
|
|
|
{
|
2015-08-30 21:57:02 +00:00
|
|
|
|
return GetRamvalue(addr.Value);
|
2015-08-30 00:19:56 +00:00
|
|
|
|
}
|
2015-08-27 01:55:55 +00:00
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
return 0;
|
2015-08-30 00:19:56 +00:00
|
|
|
|
}
|
2015-08-30 21:57:02 +00:00
|
|
|
|
}
|
2015-08-27 01:55:55 +00:00
|
|
|
|
|
2015-09-06 03:39:51 +00:00
|
|
|
|
public int TieBreaker1Address
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
int? addr = TieBreaker1Box.ToRawInt();
|
|
|
|
|
if (addr.HasValue)
|
|
|
|
|
{
|
|
|
|
|
return addr.Value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
TieBreaker1Box.SetFromRawInt(value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
public int TieBreaker1Value
|
2015-08-27 01:55:55 +00:00
|
|
|
|
{
|
2015-08-30 21:57:02 +00:00
|
|
|
|
get
|
2015-08-30 00:19:56 +00:00
|
|
|
|
{
|
2015-08-30 21:57:02 +00:00
|
|
|
|
int? addr = TieBreaker1Box.ToRawInt();
|
|
|
|
|
if (addr.HasValue)
|
|
|
|
|
{
|
|
|
|
|
return GetRamvalue(addr.Value);
|
|
|
|
|
}
|
2015-08-27 01:55:55 +00:00
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
return 0;
|
2015-08-30 00:19:56 +00:00
|
|
|
|
}
|
2015-08-27 01:55:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-06 03:39:51 +00:00
|
|
|
|
public int TieBreaker2Address
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
int? addr = TieBreaker2Box.ToRawInt();
|
|
|
|
|
if (addr.HasValue)
|
|
|
|
|
{
|
|
|
|
|
return addr.Value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
TieBreaker2Box.SetFromRawInt(value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
public int TieBreaker2Value
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
int? addr = TieBreaker2Box.ToRawInt();
|
|
|
|
|
if (addr.HasValue)
|
|
|
|
|
{
|
|
|
|
|
return GetRamvalue(addr.Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-06 03:39:51 +00:00
|
|
|
|
public int TieBreaker3Address
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
int? addr = TieBreaker3Box.ToRawInt();
|
|
|
|
|
if (addr.HasValue)
|
|
|
|
|
{
|
|
|
|
|
return addr.Value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
TieBreaker3Box.SetFromRawInt(value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
public int TieBreaker3Value
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
int? addr = TieBreaker3Box.ToRawInt();
|
|
|
|
|
if (addr.HasValue)
|
|
|
|
|
{
|
|
|
|
|
return GetRamvalue(addr.Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-06 03:39:51 +00:00
|
|
|
|
public string FromSlot
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return StartFromSlotBox.SelectedItem != null
|
|
|
|
|
? StartFromSlotBox.SelectedItem.ToString()
|
|
|
|
|
: string.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
var item = StartFromSlotBox.Items.
|
|
|
|
|
OfType<object>()
|
|
|
|
|
.FirstOrDefault(o => o.ToString() == value);
|
|
|
|
|
|
|
|
|
|
if (item != null)
|
|
|
|
|
{
|
|
|
|
|
StartFromSlotBox.SelectedItem = item;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
StartFromSlotBox.SelectedItem = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region IToolForm Implementation
|
|
|
|
|
|
|
|
|
|
public bool UpdateBefore { get { return true; } }
|
|
|
|
|
|
|
|
|
|
public void UpdateValues()
|
2015-08-27 01:55:55 +00:00
|
|
|
|
{
|
2015-08-30 21:57:02 +00:00
|
|
|
|
Update(fast: false);
|
|
|
|
|
}
|
2015-08-27 01:55:55 +00:00
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
public void FastUpdate()
|
|
|
|
|
{
|
|
|
|
|
Update(fast: true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Restart()
|
|
|
|
|
{
|
2015-09-06 23:37:15 +00:00
|
|
|
|
if (_currentDomain == null ||
|
|
|
|
|
MemoryDomains.Contains(_currentDomain))
|
|
|
|
|
{
|
|
|
|
|
_currentDomain = MemoryDomains.MainMemory;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-07 02:29:46 +00:00
|
|
|
|
if (_isBotting)
|
|
|
|
|
{
|
|
|
|
|
StopBot();
|
|
|
|
|
}
|
|
|
|
|
else if (_replayMode)
|
|
|
|
|
{
|
|
|
|
|
FinishReplay();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_lastRom != GlobalWin.MainForm.CurrentlyOpenRom)
|
|
|
|
|
{
|
|
|
|
|
_lastRom = GlobalWin.MainForm.CurrentlyOpenRom;
|
|
|
|
|
SetupControlsAndProperties();
|
|
|
|
|
}
|
2015-08-27 01:55:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool AskSaveChanges()
|
|
|
|
|
{
|
2015-09-07 00:18:57 +00:00
|
|
|
|
return true;
|
2015-08-27 01:55:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
#region Control Events
|
|
|
|
|
|
2015-09-06 21:39:11 +00:00
|
|
|
|
#region FileMenu
|
|
|
|
|
|
|
|
|
|
private void FileSubMenu_DropDownOpened(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-09-07 02:21:12 +00:00
|
|
|
|
SaveMenuItem.Enabled = !string.IsNullOrWhiteSpace(CurrentFileName);
|
2015-09-06 21:39:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RecentSubMenu_DropDownOpened(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
RecentSubMenu.DropDownItems.Clear();
|
|
|
|
|
RecentSubMenu.DropDownItems.AddRange(
|
|
|
|
|
Settings.RecentBotFiles.RecentMenu(LoadFileFromRecent, true));
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-06 03:39:51 +00:00
|
|
|
|
private void NewMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-09-07 02:21:12 +00:00
|
|
|
|
CurrentFileName = string.Empty;
|
2015-09-06 03:47:27 +00:00
|
|
|
|
_bestBotAttempt = null;
|
|
|
|
|
|
|
|
|
|
ControlProbabilityPanel.Controls
|
|
|
|
|
.OfType<BotControlsRow>()
|
|
|
|
|
.ToList()
|
|
|
|
|
.ForEach(cp => cp.Probability = 0);
|
|
|
|
|
|
|
|
|
|
FrameLength = 0;
|
|
|
|
|
MaximizeAddress = 0;
|
|
|
|
|
TieBreaker1Address = 0;
|
|
|
|
|
TieBreaker2Address = 0;
|
|
|
|
|
TieBreaker3Address = 0;
|
|
|
|
|
StartFromSlotBox.SelectedIndex = 0;
|
|
|
|
|
|
|
|
|
|
UpdateBestAttempt();
|
2015-09-06 03:39:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OpenMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var file = ToolHelpers.OpenFileDialog(
|
2015-09-07 02:21:12 +00:00
|
|
|
|
CurrentFileName,
|
2015-09-06 03:39:51 +00:00
|
|
|
|
PathManager.GetRomsPath(Global.Game.System), // TODO: bot path
|
|
|
|
|
"Bot files",
|
|
|
|
|
"bot"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (file != null)
|
|
|
|
|
{
|
|
|
|
|
LoadBotFile(file.FullName);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SaveMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-09-07 02:21:12 +00:00
|
|
|
|
if (!string.IsNullOrWhiteSpace(CurrentFileName))
|
2015-09-06 03:39:51 +00:00
|
|
|
|
{
|
2015-09-07 02:21:12 +00:00
|
|
|
|
SaveBotFile(CurrentFileName);
|
2015-09-06 03:39:51 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SaveAsMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var file = ToolHelpers.SaveFileDialog(
|
2015-09-07 02:21:12 +00:00
|
|
|
|
CurrentFileName,
|
2015-09-06 03:39:51 +00:00
|
|
|
|
PathManager.GetRomsPath(Global.Game.System), // TODO: bot path
|
|
|
|
|
"Bot files",
|
|
|
|
|
"bot"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (file != null)
|
|
|
|
|
{
|
|
|
|
|
SaveBotFile(file.FullName);
|
2015-09-07 02:21:12 +00:00
|
|
|
|
_currentFileName = file.FullName;
|
2015-09-06 03:39:51 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-06 21:39:11 +00:00
|
|
|
|
private void ExitMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Close();
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
2015-09-06 22:00:39 +00:00
|
|
|
|
#region Options Menu
|
|
|
|
|
|
|
|
|
|
private void OptionsSubMenu_DropDownOpened(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
TurboWhileBottingMenuItem.Checked = Settings.TurboWhenBotting;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-06 23:37:15 +00:00
|
|
|
|
private void MemoryDomainsMenuItem_DropDownOpened(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
MemoryDomainsMenuItem.DropDownItems.Clear();
|
|
|
|
|
MemoryDomainsMenuItem.DropDownItems.AddRange(
|
|
|
|
|
MemoryDomains.MenuItems(SetMemoryDomain, _currentDomain.Name)
|
|
|
|
|
.ToArray());
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-06 22:00:39 +00:00
|
|
|
|
private void TurboWhileBottingMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Settings.TurboWhenBotting ^= true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2015-09-06 21:39:11 +00:00
|
|
|
|
private void RunBtn_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
StartBot();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void StopBtn_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
StopBot();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ClearBestButton_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_bestBotAttempt = null;
|
|
|
|
|
UpdateBestAttempt();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void PlayBestButton_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-09-06 22:00:39 +00:00
|
|
|
|
StopBot();
|
2015-09-06 21:39:11 +00:00
|
|
|
|
_replayMode = true;
|
|
|
|
|
_dontUpdateValues = true;
|
|
|
|
|
GlobalWin.MainForm.LoadQuickSave(SelectedSlot); // Triggers an UpdateValues call
|
|
|
|
|
_dontUpdateValues = false;
|
|
|
|
|
_startFrame = Emulator.Frame;
|
2015-09-06 22:00:39 +00:00
|
|
|
|
SetNormalSpeed();
|
2015-09-07 02:21:12 +00:00
|
|
|
|
UpdateBotStatusIcon();
|
|
|
|
|
MessageLabel.Text = "Replaying";
|
2015-09-06 21:39:11 +00:00
|
|
|
|
GlobalWin.MainForm.UnpauseEmulator();
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-07 00:45:48 +00:00
|
|
|
|
private void FrameLengthNumeric_ValueChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
AssessRunButtonStatus();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ClearStatsContextMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Attempts = 0;
|
|
|
|
|
Frames = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-06 21:39:11 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Classes
|
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
private class BotAttempt
|
|
|
|
|
{
|
|
|
|
|
public BotAttempt()
|
2015-08-27 02:41:34 +00:00
|
|
|
|
{
|
2015-08-30 21:57:02 +00:00
|
|
|
|
Log = new List<string>();
|
2015-08-27 02:41:34 +00:00
|
|
|
|
}
|
2015-08-30 21:57:02 +00:00
|
|
|
|
|
|
|
|
|
public long Attempt { get; set; }
|
|
|
|
|
public int Maximize { get; set; }
|
|
|
|
|
public int TieBreak1 { get; set; }
|
|
|
|
|
public int TieBreak2 { get; set; }
|
|
|
|
|
public int TieBreak3 { get; set; }
|
|
|
|
|
public List<string> Log { get; set; }
|
2015-08-27 02:41:34 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-06 03:39:51 +00:00
|
|
|
|
private class BotData
|
|
|
|
|
{
|
|
|
|
|
public BotAttempt Best { get; set; }
|
|
|
|
|
public Dictionary<string, double> ControlProbabilities { get; set; }
|
|
|
|
|
public int Maximize { get; set; }
|
|
|
|
|
public int TieBreaker1 { get; set; }
|
|
|
|
|
public int TieBreaker2 { get; set; }
|
|
|
|
|
public int TieBreaker3 { get; set; }
|
|
|
|
|
public int FrameLength { get; set; }
|
|
|
|
|
public string FromSlot { get; set; }
|
2015-09-06 23:54:16 +00:00
|
|
|
|
public long Attempts { get; set; }
|
|
|
|
|
public long Frames { get; set; }
|
2015-09-06 03:39:51 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-09-06 21:39:11 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region File Handling
|
|
|
|
|
|
|
|
|
|
private void LoadFileFromRecent(string path)
|
|
|
|
|
{
|
|
|
|
|
var result = LoadBotFile(path);
|
|
|
|
|
if (!result)
|
|
|
|
|
{
|
|
|
|
|
Settings.RecentBotFiles.HandleLoadError(path);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool LoadBotFile(string path)
|
|
|
|
|
{
|
|
|
|
|
var file = new FileInfo(path);
|
|
|
|
|
if (!file.Exists)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var json = File.ReadAllText(path);
|
|
|
|
|
var botData = (BotData)ConfigService.LoadWithType(json);
|
|
|
|
|
|
|
|
|
|
_bestBotAttempt = botData.Best;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var probabilityControls = ControlProbabilityPanel.Controls
|
|
|
|
|
.OfType<BotControlsRow>()
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
foreach (var kvp in botData.ControlProbabilities)
|
|
|
|
|
{
|
|
|
|
|
var control = probabilityControls.Single(c => c.ButtonName == kvp.Key);
|
|
|
|
|
control.Probability = kvp.Value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MaximizeAddress = botData.Maximize;
|
|
|
|
|
TieBreaker1Address = botData.TieBreaker1;
|
|
|
|
|
TieBreaker2Address = botData.TieBreaker2;
|
|
|
|
|
TieBreaker3Address = botData.TieBreaker3;
|
|
|
|
|
FrameLength = botData.FrameLength;
|
|
|
|
|
FromSlot = botData.FromSlot;
|
2015-09-06 23:54:16 +00:00
|
|
|
|
Attempts = botData.Attempts;
|
|
|
|
|
Frames = botData.Frames;
|
|
|
|
|
|
2015-09-06 21:39:11 +00:00
|
|
|
|
UpdateBestAttempt();
|
|
|
|
|
|
|
|
|
|
if (_bestBotAttempt != null)
|
|
|
|
|
{
|
|
|
|
|
PlayBestButton.Enabled = true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-07 02:21:12 +00:00
|
|
|
|
CurrentFileName = path;
|
|
|
|
|
Settings.RecentBotFiles.Add(CurrentFileName);
|
|
|
|
|
MessageLabel.Text = Path.GetFileNameWithoutExtension(path) + " loaded";
|
2015-09-06 21:39:11 +00:00
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SaveBotFile(string path)
|
|
|
|
|
{
|
|
|
|
|
var data = new BotData
|
|
|
|
|
{
|
|
|
|
|
Best = _bestBotAttempt,
|
|
|
|
|
ControlProbabilities = ControlProbabilities,
|
|
|
|
|
Maximize = MaximizeAddress,
|
|
|
|
|
TieBreaker1 = TieBreaker1Address,
|
|
|
|
|
TieBreaker2 = TieBreaker2Address,
|
|
|
|
|
TieBreaker3 = TieBreaker3Address,
|
2015-09-06 22:00:39 +00:00
|
|
|
|
FromSlot = FromSlot,
|
2015-09-06 23:54:16 +00:00
|
|
|
|
FrameLength = FrameLength,
|
|
|
|
|
Attempts = Attempts,
|
|
|
|
|
Frames = Frames
|
2015-09-06 21:39:11 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var json = ConfigService.SaveWithType(data);
|
|
|
|
|
|
|
|
|
|
File.WriteAllText(path, json);
|
2015-09-07 02:21:12 +00:00
|
|
|
|
CurrentFileName = path;
|
|
|
|
|
Settings.RecentBotFiles.Add(CurrentFileName);
|
|
|
|
|
MessageLabel.Text = Path.GetFileName(CurrentFileName) + " saved";
|
2015-09-06 21:39:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2015-09-07 02:29:46 +00:00
|
|
|
|
private void SetupControlsAndProperties()
|
|
|
|
|
{
|
|
|
|
|
MaximizeAddressBox.SetHexProperties(MemoryDomains.MainMemory.Size);
|
|
|
|
|
TieBreaker1Box.SetHexProperties(MemoryDomains.MainMemory.Size);
|
|
|
|
|
TieBreaker2Box.SetHexProperties(MemoryDomains.MainMemory.Size);
|
|
|
|
|
TieBreaker3Box.SetHexProperties(MemoryDomains.MainMemory.Size);
|
|
|
|
|
|
|
|
|
|
StartFromSlotBox.SelectedIndex = 0;
|
|
|
|
|
|
|
|
|
|
int starty = 0;
|
|
|
|
|
int accumulatedy = 0;
|
|
|
|
|
int lineHeight = 30;
|
|
|
|
|
int marginLeft = 15;
|
|
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
|
|
ControlProbabilityPanel.Controls.Clear();
|
|
|
|
|
|
|
|
|
|
foreach (var button in Emulator.ControllerDefinition.BoolButtons)
|
|
|
|
|
{
|
|
|
|
|
var control = new BotControlsRow
|
|
|
|
|
{
|
|
|
|
|
ButtonName = button,
|
|
|
|
|
Probability = 0.0,
|
|
|
|
|
Location = new Point(marginLeft, starty + accumulatedy),
|
|
|
|
|
TabIndex = count + 1,
|
|
|
|
|
ProbabilityChangedCallback = AssessRunButtonStatus
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ControlProbabilityPanel.Controls.Add(control);
|
|
|
|
|
accumulatedy += lineHeight;
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (Settings.RecentBotFiles.AutoLoad)
|
|
|
|
|
{
|
|
|
|
|
LoadFileFromRecent(Settings.RecentBotFiles.MostRecent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UpdateBotStatusIcon();
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-06 23:37:15 +00:00
|
|
|
|
private void SetMemoryDomain(string name)
|
|
|
|
|
{
|
|
|
|
|
_currentDomain = MemoryDomains[name];
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
private int GetRamvalue(int addr)
|
|
|
|
|
{
|
2015-09-06 23:37:15 +00:00
|
|
|
|
// TODO: ability to pick byte size/display type/endian
|
|
|
|
|
return _currentDomain.PeekByte(addr);
|
2015-08-30 21:57:02 +00:00
|
|
|
|
}
|
2015-08-30 00:19:56 +00:00
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
private void Update(bool fast)
|
2015-08-27 02:41:34 +00:00
|
|
|
|
{
|
2015-09-06 02:04:26 +00:00
|
|
|
|
if (_dontUpdateValues)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_replayMode)
|
|
|
|
|
{
|
|
|
|
|
int index = Emulator.Frame - _startFrame;
|
|
|
|
|
|
|
|
|
|
if (index < _bestBotAttempt.Log.Count)
|
|
|
|
|
{
|
|
|
|
|
var logEntry = _bestBotAttempt.Log[index];
|
|
|
|
|
var lg = Global.MovieSession.MovieControllerInstance();
|
|
|
|
|
lg.SetControllersAsMnemonic(logEntry);
|
|
|
|
|
|
|
|
|
|
foreach (var button in lg.Type.BoolButtons)
|
|
|
|
|
{
|
|
|
|
|
// TODO: make an input adapter specifically for the bot?
|
|
|
|
|
Global.LuaAndAdaptor.SetButton(button, lg.IsPressed(button));
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-09-07 02:29:46 +00:00
|
|
|
|
else
|
2015-09-06 02:04:26 +00:00
|
|
|
|
{
|
2015-09-07 02:29:46 +00:00
|
|
|
|
FinishReplay();
|
2015-09-06 02:04:26 +00:00
|
|
|
|
}
|
2015-09-07 02:21:12 +00:00
|
|
|
|
}
|
2015-09-06 02:04:26 +00:00
|
|
|
|
else if (_isBotting)
|
2015-08-30 21:57:02 +00:00
|
|
|
|
{
|
|
|
|
|
if (Global.Emulator.Frame >= _targetFrame)
|
|
|
|
|
{
|
|
|
|
|
Attempts++;
|
|
|
|
|
Frames += FrameLength;
|
|
|
|
|
|
|
|
|
|
_currentBotAttempt.Maximize = MaximizeValue;
|
|
|
|
|
_currentBotAttempt.TieBreak1 = TieBreaker1Value;
|
|
|
|
|
_currentBotAttempt.TieBreak2 = TieBreaker2Value;
|
|
|
|
|
_currentBotAttempt.TieBreak3 = TieBreaker3Value;
|
2015-09-06 02:04:26 +00:00
|
|
|
|
PlayBestButton.Enabled = true;
|
2015-08-30 21:57:02 +00:00
|
|
|
|
|
|
|
|
|
if (_bestBotAttempt == null || IsBetter(_bestBotAttempt, _currentBotAttempt))
|
|
|
|
|
{
|
|
|
|
|
_bestBotAttempt = _currentBotAttempt;
|
|
|
|
|
UpdateBestAttempt();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_currentBotAttempt = new BotAttempt { Attempt = Attempts };
|
|
|
|
|
GlobalWin.MainForm.LoadQuickSave(SelectedSlot);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PressButtons();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-07 02:29:46 +00:00
|
|
|
|
private void FinishReplay()
|
|
|
|
|
{
|
|
|
|
|
GlobalWin.MainForm.PauseEmulator();
|
|
|
|
|
_startFrame = 0;
|
|
|
|
|
_replayMode = false;
|
|
|
|
|
UpdateBotStatusIcon();
|
|
|
|
|
MessageLabel.Text = "Replay stopped";
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
private bool IsBetter(BotAttempt best, BotAttempt current)
|
|
|
|
|
{
|
|
|
|
|
if (current.Maximize > best.Maximize)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else if (current.Maximize == best.Maximize)
|
|
|
|
|
{
|
|
|
|
|
if (current.TieBreak1 > best.TieBreak1)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else if (current.TieBreak1 == best.TieBreak1)
|
|
|
|
|
{
|
|
|
|
|
if (current.TieBreak2 > best.TieBreak2)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else if (current.TieBreak2 == best.TieBreak2)
|
|
|
|
|
{
|
|
|
|
|
if (current.TieBreak3 > current.TieBreak3)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateBestAttempt()
|
|
|
|
|
{
|
2015-08-31 00:53:22 +00:00
|
|
|
|
if (_bestBotAttempt != null)
|
2015-08-30 21:57:02 +00:00
|
|
|
|
{
|
|
|
|
|
|
2015-08-31 00:53:22 +00:00
|
|
|
|
|
|
|
|
|
ClearBestButton.Enabled = true;
|
|
|
|
|
BestAttemptNumberLabel.Text = _bestBotAttempt.Attempt.ToString();
|
|
|
|
|
BestMaximizeBox.Text = _bestBotAttempt.Maximize.ToString();
|
|
|
|
|
BestTieBreak1Box.Text = _bestBotAttempt.TieBreak1.ToString();
|
|
|
|
|
BestTieBreak2Box.Text = _bestBotAttempt.TieBreak2.ToString();
|
|
|
|
|
BestTieBreak3Box.Text = _bestBotAttempt.TieBreak3.ToString();
|
|
|
|
|
|
|
|
|
|
var sb = new StringBuilder();
|
|
|
|
|
foreach (var logEntry in _bestBotAttempt.Log)
|
|
|
|
|
{
|
|
|
|
|
sb.AppendLine(logEntry);
|
|
|
|
|
}
|
|
|
|
|
BestAttemptLogLabel.Text = sb.ToString();
|
2015-09-06 03:47:27 +00:00
|
|
|
|
PlayBestButton.Enabled = true;
|
2015-08-31 00:53:22 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ClearBestButton.Enabled = false;
|
|
|
|
|
BestAttemptNumberLabel.Text = string.Empty;
|
|
|
|
|
BestMaximizeBox.Text = string.Empty;
|
|
|
|
|
BestTieBreak1Box.Text = string.Empty;
|
|
|
|
|
BestTieBreak2Box.Text = string.Empty;
|
|
|
|
|
BestTieBreak3Box.Text = string.Empty;
|
|
|
|
|
BestAttemptLogLabel.Text = string.Empty;
|
2015-09-06 03:47:27 +00:00
|
|
|
|
PlayBestButton.Enabled = false;
|
2015-08-31 00:53:22 +00:00
|
|
|
|
}
|
2015-08-30 21:57:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void PressButtons()
|
|
|
|
|
{
|
|
|
|
|
var rand = new Random((int)DateTime.Now.Ticks);
|
|
|
|
|
|
|
|
|
|
var buttonLog = new Dictionary<string, bool>();
|
|
|
|
|
|
|
|
|
|
foreach (var button in Emulator.ControllerDefinition.BoolButtons)
|
|
|
|
|
{
|
|
|
|
|
double probability = ControlProbabilities[button];
|
|
|
|
|
bool pressed = !(rand.Next(100) < probability);
|
|
|
|
|
|
|
|
|
|
buttonLog.Add(button, pressed);
|
|
|
|
|
Global.ClickyVirtualPadController.SetBool(button, pressed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var lg = Global.MovieSession.LogGeneratorInstance();
|
|
|
|
|
lg.SetSource(Global.ClickyVirtualPadController);
|
|
|
|
|
_currentBotAttempt.Log.Add(lg.GenerateLogEntry());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void StartBot()
|
|
|
|
|
{
|
|
|
|
|
if (!CanStart())
|
|
|
|
|
{
|
2015-09-07 00:37:46 +00:00
|
|
|
|
MessageBox.Show("Unable to run with current settings");
|
2015-08-30 21:57:02 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-30 00:19:56 +00:00
|
|
|
|
_isBotting = true;
|
|
|
|
|
ControlsBox.Enabled = false;
|
2015-08-30 21:57:02 +00:00
|
|
|
|
StartFromSlotBox.Enabled = false;
|
2015-08-31 00:53:22 +00:00
|
|
|
|
RunBtn.Visible = false;
|
|
|
|
|
StopBtn.Visible = true;
|
2015-08-30 21:57:02 +00:00
|
|
|
|
GoalGroupBox.Enabled = false;
|
|
|
|
|
_currentBotAttempt = new BotAttempt { Attempt = Attempts };
|
2015-08-27 02:41:34 +00:00
|
|
|
|
|
|
|
|
|
if (Global.MovieSession.Movie.IsRecording)
|
|
|
|
|
{
|
2015-08-30 21:57:02 +00:00
|
|
|
|
_oldCountingSetting = Global.MovieSession.Movie.IsCountingRerecords;
|
2015-08-27 02:41:34 +00:00
|
|
|
|
Global.MovieSession.Movie.IsCountingRerecords = false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
_dontUpdateValues = true;
|
|
|
|
|
GlobalWin.MainForm.LoadQuickSave(SelectedSlot); // Triggers an UpdateValues call
|
|
|
|
|
_dontUpdateValues = false;
|
|
|
|
|
|
|
|
|
|
_targetFrame = Global.Emulator.Frame + (int)FrameLengthNumeric.Value;
|
2015-08-30 00:19:56 +00:00
|
|
|
|
|
2015-09-06 22:00:39 +00:00
|
|
|
|
GlobalWin.MainForm.UnpauseEmulator();
|
|
|
|
|
if (Settings.TurboWhenBotting)
|
2015-08-30 00:19:56 +00:00
|
|
|
|
{
|
2015-09-06 22:00:39 +00:00
|
|
|
|
SetMaxSpeed();
|
2015-08-30 00:19:56 +00:00
|
|
|
|
}
|
2015-09-07 02:21:12 +00:00
|
|
|
|
|
|
|
|
|
UpdateBotStatusIcon();
|
|
|
|
|
MessageLabel.Text = "Running...";
|
2015-08-30 21:57:02 +00:00
|
|
|
|
}
|
2015-08-30 00:19:56 +00:00
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
private bool CanStart()
|
|
|
|
|
{
|
|
|
|
|
if (!ControlProbabilities.Any(cp => cp.Value > 0))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!MaximizeAddressBox.ToRawInt().HasValue)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (FrameLengthNumeric.Value == 0)
|
2015-08-27 02:41:34 +00:00
|
|
|
|
{
|
2015-08-30 21:57:02 +00:00
|
|
|
|
return false;
|
2015-08-27 02:41:34 +00:00
|
|
|
|
}
|
2015-08-30 21:57:02 +00:00
|
|
|
|
|
|
|
|
|
return true;
|
2015-08-27 02:41:34 +00:00
|
|
|
|
}
|
2015-08-30 00:19:56 +00:00
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
private void StopBot()
|
2015-08-30 00:19:56 +00:00
|
|
|
|
{
|
2015-08-31 00:53:22 +00:00
|
|
|
|
RunBtn.Visible = true;
|
|
|
|
|
StopBtn.Visible = false;
|
2015-08-30 00:19:56 +00:00
|
|
|
|
_isBotting = false;
|
|
|
|
|
_targetFrame = 0;
|
2015-08-30 21:57:02 +00:00
|
|
|
|
ControlsBox.Enabled = true;
|
|
|
|
|
StartFromSlotBox.Enabled = true;
|
2015-08-30 00:19:56 +00:00
|
|
|
|
_targetFrame = 0;
|
2015-08-30 21:57:02 +00:00
|
|
|
|
_currentBotAttempt = null;
|
|
|
|
|
GoalGroupBox.Enabled = true;
|
2015-08-30 00:19:56 +00:00
|
|
|
|
|
2015-08-30 21:57:02 +00:00
|
|
|
|
if (Global.MovieSession.Movie.IsRecording)
|
2015-08-30 00:19:56 +00:00
|
|
|
|
{
|
2015-08-30 21:57:02 +00:00
|
|
|
|
Global.MovieSession.Movie.IsCountingRerecords = _oldCountingSetting;
|
2015-08-30 00:19:56 +00:00
|
|
|
|
}
|
2015-08-31 00:53:22 +00:00
|
|
|
|
|
|
|
|
|
GlobalWin.MainForm.PauseEmulator();
|
2015-09-06 22:00:39 +00:00
|
|
|
|
SetNormalSpeed();
|
2015-09-07 02:21:12 +00:00
|
|
|
|
UpdateBotStatusIcon();
|
|
|
|
|
MessageLabel.Text = "Bot stopped";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateBotStatusIcon()
|
|
|
|
|
{
|
|
|
|
|
if (_replayMode)
|
|
|
|
|
{
|
|
|
|
|
BotStatusButton.Image = Properties.Resources.Play;
|
|
|
|
|
BotStatusButton.ToolTipText = "Replaying best result";
|
|
|
|
|
}
|
|
|
|
|
else if (_isBotting)
|
|
|
|
|
{
|
|
|
|
|
BotStatusButton.Image = Properties.Resources.RecordHS;
|
|
|
|
|
BotStatusButton.ToolTipText = "Botting in progress";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
BotStatusButton.Image = Properties.Resources.Pause;
|
|
|
|
|
BotStatusButton.ToolTipText = "Bot is currently not running";
|
|
|
|
|
}
|
2015-09-06 23:54:16 +00:00
|
|
|
|
}
|
2015-09-06 22:00:39 +00:00
|
|
|
|
|
|
|
|
|
private void SetMaxSpeed()
|
|
|
|
|
{
|
|
|
|
|
GlobalWin.MainForm.Unthrottle();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SetNormalSpeed()
|
|
|
|
|
{
|
|
|
|
|
GlobalWin.MainForm.Throttle();
|
2015-08-30 00:19:56 +00:00
|
|
|
|
}
|
2015-09-07 00:37:46 +00:00
|
|
|
|
|
|
|
|
|
private void AssessRunButtonStatus()
|
|
|
|
|
{
|
|
|
|
|
RunBtn.Enabled =
|
|
|
|
|
FrameLength > 0
|
|
|
|
|
&& !string.IsNullOrWhiteSpace(MaximizeAddressBox.Text)
|
|
|
|
|
&& ControlProbabilities.Any(kvp => kvp.Value > 0);
|
|
|
|
|
}
|
2015-08-27 01:55:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|