The eight internet pod rows are furniture the operator builds once in Manage Site — the slot-to-IP map is frozen — but which of those slots a human actually claimed changes every session. New SessionRoster reads the roster TeslaLobby writes at the state=launching flip, and both game panes grow a session strip above Mission Properties: a banner (session key, game, slots claimed, waiting, written-at), Apply Session, and the Reset Pods that until now existed only as a right-click on a Go button that is disabled exactly when the reset is wanted. Two properties shape all of it. Only claimed slots appear in the file, so absence is the unclaimed signal and every failure path — truncated, stale, unreadable, refused — degrades to "no roster", which is byte-for-byte today's arcade behaviour; museums run this software and a bad JSON file must never stop a mission that would otherwise run by hand. And enabled implies claimed, not the reverse: the operator may always sit a pilot out, never add one, because an enabled row nobody claimed puts a dead IP in the egg and the pods then wait on a peer that will never boot. Roster issues join the pane's existing issue text, so the Go button is still the gate. The roster is one file per launch generation and deliberately not a live view: pod peer tables are boot-static, so a player whose lobby crashed is still in every pod's table and still playable, and live tracking would evict that working pod mid-session. Poll runs at ~1Hz off the existing network timer with its own deadline, and the strips are built at runtime — InitializeComponent is decompiled 1995 designer output that the differential tests compare literally. Go/Load also re-checks CheckAllValues at the click instead of trusting the last status tick: a pod that died in that gap went straight into the mission, and the post-Load barrier in NetworkScan then waited forever for a WaitingForLaunch that never arrives. vPOD gains -bind <ip>. Both listeners defaulted to IPAddress.Any, so a second vPOD on the machine lost the port and the console could only ever see one fake pod; binding each instance to its own address runs a whole eight-pod session side by side with no cockpits. Bind all of them or none — Windows lets IPAddress.Any take a port that specific addresses already hold, and the unbound instance then answers for every slot nobody claimed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1803 lines
66 KiB
C#
1803 lines
66 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using Munga.Net;
|
|
using WeifenLuo.WinFormsUI.Docking;
|
|
|
|
namespace TeslaConsole.BattleTech;
|
|
|
|
/// <summary>
|
|
/// The BattleTech game pane: mission-configuration UI plus the run/stop state
|
|
/// loop that drives each pod's <see cref="MungaGame" />. A close mirror of
|
|
/// <c>TeslaConsole.RedPlanet.RPGame</c> — same GameStateData/state machine/
|
|
/// NetworkScan engine — with the BT differences: the pod app is
|
|
/// <see cref="ApplicationID.BTL4" />, the grid carries the BT pilot fields
|
|
/// (mech/camo/patch/badge/experience), Advanced Damage replaces Score
|
|
/// Compression, and the in-match events are the Mech* messages. Free For All
|
|
/// and No Return share this one pane; the mode only selects the pilots' role.
|
|
/// The score-sheet printing controls (RPGame's Auto Print / Print Last
|
|
/// Mission) are deferred until a BT print document exists; results are still
|
|
/// recorded and saved as .btm files.
|
|
/// </summary>
|
|
internal class BTGame : DockContent
|
|
{
|
|
private class DragDropData
|
|
{
|
|
public int StartRow;
|
|
|
|
public int EndRow;
|
|
|
|
public bool RightClick;
|
|
|
|
public DragDropData(int startRow, bool rightClick)
|
|
{
|
|
StartRow = startRow;
|
|
RightClick = rightClick;
|
|
}
|
|
}
|
|
|
|
private class GameStateData
|
|
{
|
|
public bool EggMessageSent;
|
|
|
|
public bool RunMessageSent;
|
|
|
|
public bool AbortMessageSent;
|
|
|
|
public bool StopMessageSent;
|
|
|
|
public bool PodAppearsReset;
|
|
|
|
public void Reset()
|
|
{
|
|
EggMessageSent = (RunMessageSent = (AbortMessageSent = (StopMessageSent = (PodAppearsReset = false))));
|
|
}
|
|
}
|
|
|
|
private enum BTGameState
|
|
{
|
|
Idle,
|
|
Load,
|
|
AutoTransCount,
|
|
Run,
|
|
Reset
|
|
}
|
|
|
|
private static readonly Color sDataLockedColor = Color.LightGray;
|
|
|
|
private static readonly Random sRand = new Random();
|
|
|
|
private Site mSite;
|
|
|
|
private readonly bool mNoReturnMode;
|
|
|
|
private readonly string mGameName;
|
|
|
|
private EggFileMessage[] mEggFileMessages;
|
|
|
|
private BTGameState mCurrentState;
|
|
|
|
private BTGameState mRequestedState;
|
|
|
|
private TimeSpan mMissionLength;
|
|
|
|
private DateTime mGameStart;
|
|
|
|
private bool mNormalMissionEnd;
|
|
|
|
private bool mProcessingMissionEndStateChangeReq;
|
|
|
|
private int mRemainingUntilTranslocate;
|
|
|
|
private Dictionary<MungaGame, GameStateData> mGameStateData = new Dictionary<MungaGame, GameStateData>();
|
|
|
|
private BTMissionRecorder mMissionRecorder;
|
|
|
|
private Dictionary<int, BTPlayer> mMissionPlayers;
|
|
|
|
private LogOutputWindow mLogWindow;
|
|
|
|
private BTMissionResults mLastMissionResults;
|
|
|
|
private IContainer components;
|
|
|
|
private GroupBox mMissionPropertiesGroupBox;
|
|
|
|
private Label mIssuesLabel;
|
|
|
|
private Label mMissionLengthDisplayLabel;
|
|
|
|
private Label mMissionLengthTextLabel;
|
|
|
|
private CheckBox mAdvancedDamage;
|
|
|
|
private ComboBox mWeather;
|
|
|
|
private ComboBox mMap;
|
|
|
|
private ComboBox mTimeOfDay;
|
|
|
|
private Label mTimeOfDayLabel;
|
|
|
|
private Label mWeatherLabel;
|
|
|
|
private Label mMapLabel;
|
|
|
|
private GroupBox mPilotsGroupBox;
|
|
|
|
private TableLayoutPanel mMissionPropertiesTable;
|
|
|
|
private DataGridView mPilotsDataGrid;
|
|
|
|
private Button mGoButton;
|
|
|
|
private ContextMenuStrip mDragDropContextMenu;
|
|
|
|
private ToolStripMenuItem mSwapPilots;
|
|
|
|
private ToolStripMenuItem mShiftPilots;
|
|
|
|
private Timer mNetworkTimer;
|
|
|
|
private DataGridViewCheckBoxColumn mEnabledColumn;
|
|
|
|
private DataGridViewImageColumn mStatusIconColumn;
|
|
|
|
private DataGridViewTextBoxColumn mStatusTextColumn;
|
|
|
|
private DataGridViewTextBoxColumn mPilotColumn;
|
|
|
|
private DataGridViewComboBoxColumn mVehicleColumn;
|
|
|
|
private DataGridViewComboBoxColumn mColorColumn;
|
|
|
|
private DataGridViewComboBoxColumn mPatchColumn;
|
|
|
|
private DataGridViewComboBoxColumn mBadgeColumn;
|
|
|
|
private DataGridViewComboBoxColumn mExperienceColumn;
|
|
|
|
private ContextMenuStrip mResetContextMenu;
|
|
|
|
private ToolStripMenuItem resetToolStripMenuItem;
|
|
|
|
private Button mPrintLastMission;
|
|
|
|
private CheckBox mAutoPrint;
|
|
|
|
private CheckBox mAutoTranslocateCheckbox;
|
|
|
|
private Button mRandomMap;
|
|
|
|
private Button mRandomWeather;
|
|
|
|
private Button mRandomTimeOfDay;
|
|
|
|
private TextBox mMissionLengthTextBox;
|
|
|
|
private Timer tmrAutoTranslocate;
|
|
|
|
private readonly bool mDosBoxAddressShift = BTDefaults.DosBoxAddressShift;
|
|
|
|
private Panel mSessionStrip;
|
|
|
|
private Label mSessionBanner;
|
|
|
|
private Button mSessionApply;
|
|
|
|
private Button mSessionReset;
|
|
|
|
private DateTime mNextRosterPoll = DateTime.MinValue;
|
|
|
|
private DateTime mStateChangePendingSince = DateTime.MinValue;
|
|
|
|
private string GameStatusText
|
|
{
|
|
set
|
|
{
|
|
if (string.IsNullOrEmpty(value))
|
|
{
|
|
base.TabText = (Text = mGameName);
|
|
}
|
|
else
|
|
{
|
|
base.TabText = (Text = $"{mGameName} [{value}]");
|
|
}
|
|
}
|
|
}
|
|
|
|
private BTDefaults.BattleDefaults ModeDefaults => mNoReturnMode ? BTDefaults.NoReturn : BTDefaults.FreeForAll;
|
|
|
|
private BTRole ModeRole => BTConfig.FreeForAll.Roles[mNoReturnMode ? "NoReturn" : "Default"];
|
|
|
|
private BTGame()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
internal BTGame(Site site, bool noReturnMode)
|
|
: this()
|
|
{
|
|
mNoReturnMode = noReturnMode;
|
|
mSite = site;
|
|
SuspendLayout();
|
|
mGameName = (mNoReturnMode ? "BattleTech No Return" : "BattleTech Free For All");
|
|
GameStatusText = null;
|
|
BTScenario scenario = BTConfig.FreeForAll;
|
|
BTDefaults.BattleDefaults defaults = ModeDefaults;
|
|
int selectedIndex;
|
|
int num = (selectedIndex = 0);
|
|
string text = defaults.MapKey;
|
|
mMap.DisplayMember = "Name";
|
|
mMap.ValueMember = "Key";
|
|
foreach (BTMap item in scenario.Maps.Values)
|
|
{
|
|
mMap.Items.Add(item);
|
|
if (item.Key == text)
|
|
{
|
|
selectedIndex = num;
|
|
}
|
|
num++;
|
|
}
|
|
mMap.SelectedIndex = selectedIndex;
|
|
num = (selectedIndex = 0);
|
|
text = defaults.WeatherKey;
|
|
mWeather.DisplayMember = "Name";
|
|
mWeather.ValueMember = "Key";
|
|
foreach (BTWeather item2 in scenario.Weather.Values)
|
|
{
|
|
mWeather.Items.Add(item2);
|
|
if (item2.Key == text)
|
|
{
|
|
selectedIndex = num;
|
|
}
|
|
num++;
|
|
}
|
|
mWeather.SelectedIndex = selectedIndex;
|
|
num = (selectedIndex = 0);
|
|
text = defaults.TimeOfDayKey;
|
|
mTimeOfDay.DisplayMember = "Value";
|
|
mTimeOfDay.ValueMember = "Key";
|
|
foreach (KeyValuePair<string, string> item3 in scenario.TimesOfDay)
|
|
{
|
|
mTimeOfDay.Items.Add(item3);
|
|
if (item3.Key == text)
|
|
{
|
|
selectedIndex = num;
|
|
}
|
|
num++;
|
|
}
|
|
mTimeOfDay.SelectedIndex = selectedIndex;
|
|
mAdvancedDamage.Checked = defaults.AdvancedDamage;
|
|
mMissionLengthTextBox.Text = defaults.MissionLength.TotalMinutes.ToString();
|
|
num = (selectedIndex = 0);
|
|
text = defaults.VehicleKey;
|
|
mVehicleColumn.DisplayMember = "Name";
|
|
mVehicleColumn.ValueMember = "Key";
|
|
foreach (BTVehicle item4 in scenario.Vehicles.Values)
|
|
{
|
|
mVehicleColumn.Items.Add(item4);
|
|
if (item4.Key == text)
|
|
{
|
|
selectedIndex = num;
|
|
}
|
|
num++;
|
|
}
|
|
mVehicleColumn.Tag = selectedIndex;
|
|
SetupKeyValueColumn(mColorColumn, scenario.Colors, defaults.CamoKey);
|
|
SetupKeyValueColumn(mPatchColumn, scenario.Patches, defaults.PatchKey);
|
|
SetupKeyValueColumn(mBadgeColumn, scenario.Badges, defaults.EmblemKey);
|
|
SetupKeyValueColumn(mExperienceColumn, scenario.Experiences, defaults.ExperienceKey);
|
|
List<Tuple<Squad, Pod>> list = new List<Tuple<Squad, Pod>>();
|
|
foreach (Squad squad in mSite.Squads)
|
|
{
|
|
foreach (Pod pod in squad.Pods)
|
|
{
|
|
if (pod.HostType == HostType.GameMachineHostType)
|
|
{
|
|
BuildPodRow(squad, pod);
|
|
}
|
|
else if (pod.HostType == HostType.MissionReviewHostType)
|
|
{
|
|
list.Add(new Tuple<Squad, Pod>(squad, pod));
|
|
}
|
|
}
|
|
}
|
|
foreach (Tuple<Squad, Pod> item5 in list)
|
|
{
|
|
BuildPodRow(item5.A, item5.B);
|
|
}
|
|
BuildSessionStrip();
|
|
SessionRoster.Poll();
|
|
UpdateSessionStrip();
|
|
CheckAllValues();
|
|
ResumeLayout();
|
|
}
|
|
|
|
/// <summary>
|
|
/// The internet-session strip: roster banner, Apply, and the Reset that has
|
|
/// always existed as a right-click on the (disabled) Go button.
|
|
///
|
|
/// Built here and not in InitializeComponent on purpose. That block is the
|
|
/// decompiled 1995 designer output and the differential tests compare it
|
|
/// literally, so anything new has to be assembled at runtime instead.
|
|
/// Docked last, which is docked first, so the strip sits above Mission
|
|
/// Properties rather than between it and the pilot grid.
|
|
/// </summary>
|
|
private void BuildSessionStrip()
|
|
{
|
|
mSessionStrip = new Panel();
|
|
mSessionStrip.Dock = DockStyle.Top;
|
|
mSessionStrip.Height = 28;
|
|
mSessionStrip.Visible = false;
|
|
mSessionBanner = new Label();
|
|
mSessionBanner.Dock = DockStyle.Fill;
|
|
mSessionBanner.TextAlign = ContentAlignment.MiddleLeft;
|
|
mSessionBanner.Padding = new Padding(6, 0, 6, 0);
|
|
mSessionApply = new Button();
|
|
mSessionApply.Dock = DockStyle.Left;
|
|
mSessionApply.Width = 110;
|
|
mSessionApply.Text = "Apply Session";
|
|
mSessionApply.Visible = false;
|
|
mSessionApply.UseVisualStyleBackColor = true;
|
|
mSessionApply.Click += new EventHandler(mSessionApply_Click);
|
|
mSessionReset = new Button();
|
|
mSessionReset.Dock = DockStyle.Right;
|
|
mSessionReset.Width = 110;
|
|
mSessionReset.Text = "Reset Pods";
|
|
mSessionReset.Visible = false;
|
|
mSessionReset.UseVisualStyleBackColor = true;
|
|
// The same action as the hidden context-menu item, which no operator has
|
|
// ever found: it lives on a button that is disabled exactly when the reset
|
|
// is wanted.
|
|
mSessionReset.Click += new EventHandler(resetToolStripMenuItem_Click);
|
|
mSessionStrip.Controls.Add(mSessionBanner);
|
|
mSessionStrip.Controls.Add(mSessionApply);
|
|
mSessionStrip.Controls.Add(mSessionReset);
|
|
base.Controls.Add(mSessionStrip);
|
|
}
|
|
|
|
private void UpdateSessionStrip()
|
|
{
|
|
if (mRequestedState == mCurrentState)
|
|
{
|
|
mStateChangePendingSince = DateTime.MinValue;
|
|
mSessionReset.Visible = false;
|
|
}
|
|
else
|
|
{
|
|
if (mStateChangePendingSince == DateTime.MinValue)
|
|
{
|
|
mStateChangePendingSince = DateTime.Now;
|
|
}
|
|
// Ten seconds, so a healthy Load/Launch never makes the button flicker
|
|
// past. Past that the pane is not slow, it is stuck: the state barrier
|
|
// in NetworkScan has no timeout of its own.
|
|
mSessionReset.Visible = mStateChangePendingSince.AddSeconds(10.0) < DateTime.Now;
|
|
}
|
|
string text = SessionBannerText();
|
|
mSessionBanner.Text = text;
|
|
mSessionBanner.ForeColor = (SessionRoster.Active ? SystemColors.ControlText : Color.Red);
|
|
mSessionApply.Visible = SessionRoster.Active;
|
|
// Nothing claimed, nothing wrong and nothing stuck: no roster file at all
|
|
// leaves the pane looking exactly as it does today. Museums run this.
|
|
mSessionStrip.Visible = text.Length > 0 || mSessionReset.Visible;
|
|
}
|
|
|
|
private static string SessionBannerText()
|
|
{
|
|
if (!SessionRoster.Active)
|
|
{
|
|
// Empty with no file; when a file was refused this is why, and the
|
|
// operator needs to read it before hand-enabling eight rows.
|
|
return SessionRoster.LoadError;
|
|
}
|
|
string text = SessionRoster.SessionKey;
|
|
if (text.Length > 8)
|
|
{
|
|
text = text.Substring(0, 8);
|
|
}
|
|
// Local time: the lobby writes the file on this machine, and the operator
|
|
// is comparing the stamp against the clock on the wall.
|
|
return $"SESSION {text} - {SessionRoster.Game} - {SessionRoster.Claims.Count} slots claimed - {SessionRoster.WaitingCount} waiting - written {SessionRoster.WrittenUtc.ToLocalTime():HH:mm:ss}";
|
|
}
|
|
|
|
private void mSessionApply_Click(object sender, EventArgs e)
|
|
{
|
|
string text = SessionRoster.Validate("bt", mDosBoxAddressShift, mPilotsDataGrid, mEnabledColumn.Index, mPilotColumn.Index);
|
|
if (text.Length > 0)
|
|
{
|
|
// Named offender, never a silent fix: the pilot name is about to become
|
|
// an INI section name in the egg, so the operator must see the name that
|
|
// will be written.
|
|
MessageBox.Show(text, "Can Not Apply Session Roster");
|
|
return;
|
|
}
|
|
SessionRoster.Apply(mPilotsDataGrid, mEnabledColumn.Index, mPilotColumn.Index, this, mDosBoxAddressShift);
|
|
CheckAllValues();
|
|
mPilotsDataGrid.Refresh();
|
|
}
|
|
|
|
private static void SetupKeyValueColumn(DataGridViewComboBoxColumn column, Dictionary<string, string> options, string defaultKey)
|
|
{
|
|
int num = 0;
|
|
int selectedIndex = 0;
|
|
column.DisplayMember = "Value";
|
|
column.ValueMember = "Key";
|
|
foreach (KeyValuePair<string, string> option in options)
|
|
{
|
|
column.Items.Add(option);
|
|
if (option.Key == defaultKey)
|
|
{
|
|
selectedIndex = num;
|
|
}
|
|
num++;
|
|
}
|
|
column.Tag = selectedIndex;
|
|
}
|
|
|
|
private void BuildPodRow(Squad squad, Pod pod)
|
|
{
|
|
int index = mPilotsDataGrid.Rows.Add();
|
|
DataGridViewRow row = mPilotsDataGrid.Rows[index];
|
|
row.Tag = pod;
|
|
row.HeaderCell.Value = $"{squad.Name} - {pod.Name}";
|
|
row.Cells[mEnabledColumn.Index].Value = false;
|
|
if (pod.HostType == HostType.GameMachineHostType)
|
|
{
|
|
row.Cells[mVehicleColumn.Index].Value = mVehicleColumn.Items[(int)mVehicleColumn.Tag];
|
|
row.Cells[mColorColumn.Index].Value = mColorColumn.Items[(int)mColorColumn.Tag];
|
|
row.Cells[mPatchColumn.Index].Value = mPatchColumn.Items[(int)mPatchColumn.Tag];
|
|
row.Cells[mBadgeColumn.Index].Value = mBadgeColumn.Items[(int)mBadgeColumn.Tag];
|
|
row.Cells[mExperienceColumn.Index].Value = mExperienceColumn.Items[(int)mExperienceColumn.Tag];
|
|
}
|
|
else
|
|
{
|
|
row.Cells[mVehicleColumn.Index].Value = "";
|
|
row.Cells[mColorColumn.Index].Value = "";
|
|
row.Cells[mPatchColumn.Index].Value = "";
|
|
row.Cells[mBadgeColumn.Index].Value = "";
|
|
row.Cells[mExperienceColumn.Index].Value = "";
|
|
row.Cells[mPilotColumn.Index].ReadOnly = true;
|
|
row.Cells[mVehicleColumn.Index].ReadOnly = true;
|
|
row.Cells[mColorColumn.Index].ReadOnly = true;
|
|
row.Cells[mPatchColumn.Index].ReadOnly = true;
|
|
row.Cells[mBadgeColumn.Index].ReadOnly = true;
|
|
row.Cells[mExperienceColumn.Index].ReadOnly = true;
|
|
}
|
|
mGameStateData[pod.MungaGame] = new GameStateData();
|
|
SetPodStatus(row, pod.MungaGame);
|
|
pod.MungaGame.OnPodStatusUpdated += delegate(object sender, EventArgs e)
|
|
{
|
|
if (!base.IsDisposed)
|
|
{
|
|
SetPodStatus(row, (MungaGame)sender);
|
|
}
|
|
};
|
|
}
|
|
|
|
protected override void OnClosing(CancelEventArgs e)
|
|
{
|
|
if (mCurrentState != 0 && MessageBox.Show("A BattleTech game controlled by this window is currently in progress. If you choose to continue, the game will end immediately. Are you sure you wish to procede?", "Game Running", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
|
|
{
|
|
e.Cancel = true;
|
|
}
|
|
else
|
|
{
|
|
base.OnClosing(e);
|
|
}
|
|
}
|
|
|
|
protected override void OnClosed(EventArgs e)
|
|
{
|
|
foreach (Squad squad in mSite.Squads)
|
|
{
|
|
foreach (Pod pod in squad.Pods)
|
|
{
|
|
ForcePodRelease(pod.MungaGame);
|
|
pod.MungaGame.ReleaseRequest(this);
|
|
}
|
|
}
|
|
base.OnClosed(e);
|
|
}
|
|
|
|
private static string GetStringOrKey(DataGridViewCell cell)
|
|
{
|
|
if (cell.Value is string)
|
|
{
|
|
return (string)cell.Value;
|
|
}
|
|
return ((KeyValuePair<string, string>)cell.Value).Key;
|
|
}
|
|
|
|
private string MissionAddress(Pod pod)
|
|
{
|
|
return (mDosBoxAddressShift ? DosBox.ShiftAddress(pod.IPAddress) : pod.IPAddress).ToString();
|
|
}
|
|
|
|
private void NetworkScan(object sender, EventArgs e)
|
|
{
|
|
// Own deadline rather than a count of ticks: mNetworkTimer's interval is
|
|
// the designer default and this must stay ~1Hz whatever that becomes. Same
|
|
// shape as MungaGame.QueryStateIfNeeded (MungaGame.cs:159-167).
|
|
DateTime now = DateTime.Now;
|
|
if (mNextRosterPoll < now)
|
|
{
|
|
mNextRosterPoll = now.AddSeconds(1.0);
|
|
if (SessionRoster.Poll() && mCurrentState == BTGameState.Idle && mRequestedState == BTGameState.Idle)
|
|
{
|
|
// Guarded like SetPodStatus: CheckAllValues owns mGoButton.Enabled,
|
|
// and mid-mission that button is Stop Mission.
|
|
CheckAllValues();
|
|
}
|
|
}
|
|
UpdateSessionStrip();
|
|
if (mCurrentState == BTGameState.Run && mRequestedState == BTGameState.Run && !mProcessingMissionEndStateChangeReq)
|
|
{
|
|
mProcessingMissionEndStateChangeReq = true;
|
|
TimeSpan timeRemaining = mMissionLength - (DateTime.Now - mGameStart);
|
|
if (timeRemaining.Ticks < 0)
|
|
{
|
|
mNormalMissionEnd = true;
|
|
RequestState(BTGameState.Idle);
|
|
timeRemaining = new TimeSpan(0L);
|
|
}
|
|
string gameStatusText = FormatTimeRemaining(timeRemaining);
|
|
mMissionLengthDisplayLabel.Text = gameStatusText;
|
|
GameStatusText = gameStatusText;
|
|
mProcessingMissionEndStateChangeReq = false;
|
|
}
|
|
bool flag = true;
|
|
foreach (DataGridViewRow item in (IEnumerable)mPilotsDataGrid.Rows)
|
|
{
|
|
Pod pod = (Pod)item.Tag;
|
|
if (mRequestedState == BTGameState.Idle)
|
|
{
|
|
GetPodReleased(pod.MungaGame);
|
|
if (pod.MungaGame.IsOwner(this))
|
|
{
|
|
flag = false;
|
|
}
|
|
}
|
|
else if (!(bool)item.Cells[mEnabledColumn.Index].Value)
|
|
{
|
|
if (pod.MungaGame.IsOwner(this))
|
|
{
|
|
GetPodReleased(pod.MungaGame);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GameStateData gameStateData = mGameStateData[pod.MungaGame];
|
|
if (!gameStateData.PodAppearsReset)
|
|
{
|
|
if (!pod.MungaGame.IsOwned)
|
|
{
|
|
pod.MungaGame.TakeOwnership(this);
|
|
}
|
|
if (!pod.MungaGame.IsOwner(this))
|
|
{
|
|
flag = false;
|
|
}
|
|
else if (!pod.MungaGame.IsPodOperational(ApplicationID.BTL4))
|
|
{
|
|
flag = false;
|
|
}
|
|
else if (mRequestedState == BTGameState.Load)
|
|
{
|
|
switch (pod.MungaGame.AppState.Value)
|
|
{
|
|
case ApplicationState.RunningMission:
|
|
if (!gameStateData.AbortMessageSent)
|
|
{
|
|
pod.MungaGame.Send(0, 1, new AbortMissionMessage(0));
|
|
gameStateData.AbortMessageSent = true;
|
|
}
|
|
break;
|
|
case ApplicationState.WaitingForEgg:
|
|
if (!pod.MungaGame.EggAcknowledged && pod.MungaGame.EggDelayTimer < DateTime.Now && pod.MungaGame.EggSent.AddSeconds(5.0) < DateTime.Now)
|
|
{
|
|
LogMessage("Egg Sent.");
|
|
EggFileMessage[] array = mEggFileMessages;
|
|
foreach (EggFileMessage message in array)
|
|
{
|
|
pod.MungaGame.Send(0, 1, message);
|
|
}
|
|
pod.MungaGame.EggSent = DateTime.Now;
|
|
}
|
|
break;
|
|
}
|
|
if (!pod.MungaGame.IsPodAppState(ApplicationID.BTL4, ApplicationState.WaitingForLaunch))
|
|
{
|
|
flag = false;
|
|
}
|
|
}
|
|
else if (mRequestedState == BTGameState.Run)
|
|
{
|
|
switch (pod.MungaGame.AppState.Value)
|
|
{
|
|
case ApplicationState.WaitingForEgg:
|
|
gameStateData.PodAppearsReset = true;
|
|
GetPodReleased(pod.MungaGame);
|
|
break;
|
|
case ApplicationState.WaitingForLaunch:
|
|
if (!gameStateData.RunMessageSent)
|
|
{
|
|
pod.MungaGame.Send(0, 1, new RunMissionMessage());
|
|
gameStateData.RunMessageSent = true;
|
|
}
|
|
break;
|
|
}
|
|
if (!pod.MungaGame.IsPodAppState(ApplicationID.BTL4, ApplicationState.RunningMission))
|
|
{
|
|
flag = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!pod.MungaGame.IsOwner(this))
|
|
{
|
|
continue;
|
|
}
|
|
for (MetaMessage metaMessage = pod.MungaGame.Receive(); metaMessage != null; metaMessage = pod.MungaGame.Receive())
|
|
{
|
|
LogMessage(pod, metaMessage);
|
|
if (metaMessage.Message is MechDamagedMessage)
|
|
{
|
|
MechDamagedMessage mechDamagedMessage = (MechDamagedMessage)metaMessage.Message;
|
|
mMissionRecorder.PlayerDamaged(mMissionPlayers[mechDamagedMessage.PlayerHostID], mMissionPlayers[mechDamagedMessage.DamagerHostID], mechDamagedMessage.DamageLoss, mechDamagedMessage.PointsTransfered, mechDamagedMessage.DamageZoneIndex, mechDamagedMessage.DamageZoneDestroyed, mechDamagedMessage.WeaponIndex);
|
|
}
|
|
else if (metaMessage.Message is MechKilledMessage)
|
|
{
|
|
MechKilledMessage mechKilledMessage = (MechKilledMessage)metaMessage.Message;
|
|
mMissionRecorder.PlayerKilled(mMissionPlayers[mechKilledMessage.PlayerHostID], mMissionPlayers[mechKilledMessage.KillerHostID]);
|
|
}
|
|
else if (metaMessage.Message is MechDeathWithoutHonorMessage)
|
|
{
|
|
MechDeathWithoutHonorMessage mechDeathWithoutHonorMessage = (MechDeathWithoutHonorMessage)metaMessage.Message;
|
|
mMissionRecorder.PlayerDeathWithoutHonor(mMissionPlayers[mechDeathWithoutHonorMessage.PlayerHostID]);
|
|
}
|
|
else if (metaMessage.Message is MechScoreUpdateMessage)
|
|
{
|
|
MechScoreUpdateMessage mechScoreUpdateMessage = (MechScoreUpdateMessage)metaMessage.Message;
|
|
mMissionRecorder.PlayerScoreUpdate(mMissionPlayers[mechScoreUpdateMessage.PlayerHostID], mechScoreUpdateMessage.PlayerScore);
|
|
}
|
|
else if (metaMessage.Message is EndMissionMessage)
|
|
{
|
|
EndMissionMessage endMissionMessage = (EndMissionMessage)metaMessage.Message;
|
|
mMissionRecorder.PlayerFinalScore(mMissionPlayers[endMissionMessage.PlayerHostID], endMissionMessage.FinalScore);
|
|
}
|
|
}
|
|
}
|
|
if (mCurrentState != mRequestedState && flag)
|
|
{
|
|
StateChangeApproved();
|
|
}
|
|
}
|
|
|
|
private void LogMessage(string message)
|
|
{
|
|
if (mLogWindow != null && !mLogWindow.IsDisposed)
|
|
{
|
|
mLogWindow.LogMessage(message);
|
|
}
|
|
}
|
|
|
|
private void LogMessage(Pod pod, MetaMessage msg)
|
|
{
|
|
if (mLogWindow == null || mLogWindow.IsDisposed)
|
|
{
|
|
return;
|
|
}
|
|
if (msg.Message is AcknowledgeEggFileMessage)
|
|
{
|
|
mLogWindow.LogMessage("{0}: {1}: {2}: Egg ACK", pod.Name, msg.Header.ClientID, msg.Message.GetType().Name);
|
|
}
|
|
else if (msg.Message is EndMissionMessage)
|
|
{
|
|
EndMissionMessage endMissionMessage = (EndMissionMessage)msg.Message;
|
|
mLogWindow.LogMessage("{0}: {1}: {2}: Final Score {3}", pod.Name, msg.Header.ClientID, msg.Message.GetType().Name, endMissionMessage.FinalScore);
|
|
}
|
|
else if (msg.Message is ReadyToRunMessage)
|
|
{
|
|
mLogWindow.LogMessage("{0}: {1}: {2}", pod.Name, msg.Header.ClientID, msg.Message.GetType().Name);
|
|
}
|
|
else if (msg.Message is MechKilledMessage)
|
|
{
|
|
MechKilledMessage mechKilledMessage = (MechKilledMessage)msg.Message;
|
|
mLogWindow.LogMessage("{0}: {1}: {2}: {3} killed {4}", pod.Name, msg.Header.ClientID, msg.Message.GetType().Name, mechKilledMessage.KillerHostID, mechKilledMessage.PlayerHostID);
|
|
}
|
|
else if (msg.Message is MechDeathWithoutHonorMessage)
|
|
{
|
|
mLogWindow.LogMessage("{0}: {1}: {2}: {3} died without honor", pod.Name, msg.Header.ClientID, msg.Message.GetType().Name, ((MechDeathWithoutHonorMessage)msg.Message).PlayerHostID);
|
|
}
|
|
else if (msg.Message is MechScoreUpdateMessage)
|
|
{
|
|
mLogWindow.LogMessage("{0}: {1}: {2}: {3} Score = {4}", pod.Name, msg.Header.ClientID, msg.Message.GetType().Name, ((MechScoreUpdateMessage)msg.Message).PlayerHostID, ((MechScoreUpdateMessage)msg.Message).PlayerScore);
|
|
}
|
|
else if (msg.Message is BTTeamScoreUpdateMessage)
|
|
{
|
|
mLogWindow.LogMessage("{0}: {1}: {2}: Team {3} Score = {4}", pod.Name, msg.Header.ClientID, msg.Message.GetType().Name, ((BTTeamScoreUpdateMessage)msg.Message).TeamID, ((BTTeamScoreUpdateMessage)msg.Message).TeamScore);
|
|
}
|
|
else if (msg.Message is MechDamagedMessage)
|
|
{
|
|
MechDamagedMessage mechDamagedMessage = (MechDamagedMessage)msg.Message;
|
|
if (mechDamagedMessage.DamageLoss != 0)
|
|
{
|
|
mLogWindow.LogMessage("{0}: {1}: {2}: {3} Damaged {4} For {5} Points.", pod.Name, msg.Header.ClientID, msg.Message.GetType().Name, mechDamagedMessage.DamagerHostID, mechDamagedMessage.PlayerHostID, mechDamagedMessage.PointsTransfered);
|
|
}
|
|
}
|
|
}
|
|
|
|
private string FormatTimeRemaining(TimeSpan timeRemaining)
|
|
{
|
|
long num = (long)timeRemaining.TotalMinutes;
|
|
long num2 = (long)(timeRemaining.TotalSeconds - (double)(num * 60));
|
|
return $"{num:00}:{num2:00}";
|
|
}
|
|
|
|
private void ForcePodRelease(MungaGame munga)
|
|
{
|
|
GetPodReleased(munga);
|
|
munga.ReleaseOwnership(this);
|
|
}
|
|
|
|
private void GetPodReleased(MungaGame munga)
|
|
{
|
|
if (!munga.IsOwner(this))
|
|
{
|
|
return;
|
|
}
|
|
if (!munga.IsPodOperational(ApplicationID.BTL4))
|
|
{
|
|
munga.ReleaseOwnership(this);
|
|
return;
|
|
}
|
|
GameStateData gameStateData = mGameStateData[munga];
|
|
switch (munga.AppState.Value)
|
|
{
|
|
case ApplicationState.WaitingForLaunch:
|
|
if (!gameStateData.AbortMessageSent)
|
|
{
|
|
munga.Send(0, 1, new AbortMissionMessage(0));
|
|
gameStateData.AbortMessageSent = true;
|
|
}
|
|
break;
|
|
case ApplicationState.RunningMission:
|
|
if (!gameStateData.StopMessageSent)
|
|
{
|
|
munga.Send(0, 1, new StopMissionMessage(0));
|
|
gameStateData.StopMessageSent = true;
|
|
}
|
|
break;
|
|
case ApplicationState.WaitingForEgg:
|
|
munga.ReleaseOwnership(this);
|
|
break;
|
|
case ApplicationState.LoadingMission:
|
|
case ApplicationState.LaunchingMission:
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void StateChangeApproved()
|
|
{
|
|
switch (mRequestedState)
|
|
{
|
|
case BTGameState.Idle:
|
|
EndMission();
|
|
GameStatusText = null;
|
|
mGoButton.Text = "Load";
|
|
mEggFileMessages = null;
|
|
SwitchControlsMode(editMode: true);
|
|
CheckAllValues();
|
|
mCurrentState = BTGameState.Idle;
|
|
break;
|
|
case BTGameState.Load:
|
|
GameStatusText = "Loaded";
|
|
mGoButton.Text = "Run Mission";
|
|
mGoButton.Enabled = true;
|
|
foreach (GameStateData value in mGameStateData.Values)
|
|
{
|
|
value.Reset();
|
|
}
|
|
mCurrentState = BTGameState.Load;
|
|
if (mAutoTranslocateCheckbox.Checked)
|
|
{
|
|
int num = ModeDefaults.LaunchDelay;
|
|
if (num == 0)
|
|
{
|
|
mGoButton.Text = "Launching...";
|
|
GameStatusText = "Launching...";
|
|
mGoButton.Enabled = false;
|
|
RequestState(BTGameState.Run);
|
|
}
|
|
else
|
|
{
|
|
mGoButton.Text = $"Launching in {num}...";
|
|
GameStatusText = mGoButton.Text;
|
|
mRemainingUntilTranslocate = num;
|
|
tmrAutoTranslocate.Start();
|
|
}
|
|
}
|
|
break;
|
|
case BTGameState.Run:
|
|
mGameStart = DateTime.Now;
|
|
mGoButton.Text = "Stop Mission";
|
|
mGoButton.Enabled = true;
|
|
mCurrentState = BTGameState.Run;
|
|
mMissionRecorder.SetMissionStart();
|
|
mMissionLengthDisplayLabel.ForeColor = Color.DarkGreen;
|
|
break;
|
|
case BTGameState.AutoTransCount:
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void mGoButton_Click(object sender, EventArgs e)
|
|
{
|
|
switch (mCurrentState)
|
|
{
|
|
case BTGameState.Idle:
|
|
RequestState(BTGameState.Load);
|
|
break;
|
|
case BTGameState.Load:
|
|
tmrAutoTranslocate.Stop();
|
|
RequestState(BTGameState.Run);
|
|
break;
|
|
case BTGameState.Run:
|
|
mNormalMissionEnd = false;
|
|
RequestState(BTGameState.Idle);
|
|
break;
|
|
case BTGameState.AutoTransCount:
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void resetToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
RequestState(BTGameState.Reset);
|
|
}
|
|
|
|
private void RequestState(BTGameState state)
|
|
{
|
|
switch (state)
|
|
{
|
|
case BTGameState.Load:
|
|
{
|
|
// Re-check at the click, not at the last status tick. Nothing between
|
|
// here and the egg validates anything -- mGoButton.Enabled is a UI flag
|
|
// CheckAllValues set at some earlier moment -- so a pod that died in
|
|
// that gap goes straight into the mission, and the post-Load barrier in
|
|
// NetworkScan then waits forever for a WaitingForLaunch that will never
|
|
// arrive (that loop has no timeout). Safe only at the very top of this
|
|
// case: mMissionLength, mMissionRecorder, mMissionPlayers,
|
|
// mRequestedState and SwitchControlsMode are all still untouched below,
|
|
// so returning here leaves the pane exactly as the operator left it.
|
|
CheckAllValues();
|
|
if (!mGoButton.Enabled)
|
|
{
|
|
MessageBox.Show(mIssuesLabel.Text, "Can Not Load Mission");
|
|
return;
|
|
}
|
|
mMissionLength = ParseMissionLength();
|
|
string key = ((BTMap)mMap.SelectedItem).Key;
|
|
string key2 = ((KeyValuePair<string, string>)mTimeOfDay.SelectedItem).Key;
|
|
BTWeather bTWeather = (BTWeather)mWeather.SelectedItem;
|
|
BTFreeForAllMission bTMission = new BTFreeForAllMission(key, key2, bTWeather.Key, bTWeather.Temperature, mMissionLength);
|
|
BTRole role = ModeRole;
|
|
mMissionRecorder = new BTMissionRecorder(bTMission);
|
|
mMissionPlayers = new Dictionary<int, BTPlayer>();
|
|
int num = 2;
|
|
foreach (DataGridViewRow item in (IEnumerable)mPilotsDataGrid.Rows)
|
|
{
|
|
if (!(bool)item.Cells[mEnabledColumn.Index].Value)
|
|
{
|
|
continue;
|
|
}
|
|
Pod pod = (Pod)item.Tag;
|
|
if (pod.HostType == HostType.GameMachineHostType)
|
|
{
|
|
string value = (string)item.Cells[mPilotColumn.Index].Value;
|
|
BTPlayer bTPlayer = new BTPlayer(MissionAddress(pod), value, (item.Cells[mVehicleColumn.Index].Value is string) ? ((string)item.Cells[mVehicleColumn.Index].Value) : ((BTVehicle)item.Cells[mVehicleColumn.Index].Value).Key, GetStringOrKey(item.Cells[mColorColumn.Index]), GetStringOrKey(item.Cells[mPatchColumn.Index]), GetStringOrKey(item.Cells[mBadgeColumn.Index]), GetStringOrKey(item.Cells[mExperienceColumn.Index]), role, mAdvancedDamage.Checked);
|
|
bTMission.BattlePlayers.Add(bTPlayer);
|
|
mMissionPlayers.Add(num++, bTPlayer);
|
|
PilotNameCache.PilotNames.Add(value);
|
|
}
|
|
else
|
|
{
|
|
bTMission.Cameras.Add(new BTCamera(MissionAddress(pod), pod.HostType));
|
|
}
|
|
}
|
|
mEggFileMessages = bTMission.ToEggFileMessages();
|
|
mRequestedState = BTGameState.Load;
|
|
SwitchControlsMode(editMode: false);
|
|
GameStatusText = "Loading...";
|
|
mGoButton.Text = "Loading...";
|
|
mGoButton.Enabled = false;
|
|
break;
|
|
}
|
|
case BTGameState.Run:
|
|
mRequestedState = BTGameState.Run;
|
|
GameStatusText = "Launching...";
|
|
mGoButton.Text = "Launching...";
|
|
mGoButton.Enabled = false;
|
|
break;
|
|
case BTGameState.Idle:
|
|
mRequestedState = BTGameState.Idle;
|
|
mMissionLengthDisplayLabel.ForeColor = Color.Red;
|
|
GameStatusText = "Stopping Game...";
|
|
mGoButton.Text = "Stopping Game...";
|
|
mGoButton.Enabled = false;
|
|
break;
|
|
case BTGameState.Reset:
|
|
foreach (Squad squad in mSite.Squads)
|
|
{
|
|
foreach (Pod pod2 in squad.Pods)
|
|
{
|
|
ForcePodRelease(pod2.MungaGame);
|
|
}
|
|
}
|
|
mRequestedState = BTGameState.Idle;
|
|
StateChangeApproved();
|
|
break;
|
|
case BTGameState.AutoTransCount:
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void EndMission()
|
|
{
|
|
try
|
|
{
|
|
mLastMissionResults = mMissionRecorder.EndMission(mNormalMissionEnd ? mMissionLength : (DateTime.Now - mGameStart));
|
|
try
|
|
{
|
|
mLastMissionResults.Save();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (Debugger.IsAttached)
|
|
{
|
|
throw;
|
|
}
|
|
Program.LogExceptionAndShowDialog(ex, "Mission results failed to save.", "Error Saving Mission Results");
|
|
}
|
|
if (mAutoPrint.Checked)
|
|
{
|
|
try
|
|
{
|
|
mLastMissionResults.GetPrintDocument().Print();
|
|
}
|
|
catch (Exception ex2)
|
|
{
|
|
if (Debugger.IsAttached)
|
|
{
|
|
throw;
|
|
}
|
|
Program.LogExceptionAndShowDialog(ex2, "Mission results failed to print.", "Error Printing Mission Results");
|
|
}
|
|
}
|
|
mPrintLastMission.Enabled = true;
|
|
}
|
|
catch (Exception ex3)
|
|
{
|
|
if (Debugger.IsAttached)
|
|
{
|
|
throw;
|
|
}
|
|
Program.LogExceptionAndShowDialog(ex3, "Failed to create mission results.", "Error Creating Mission Results");
|
|
}
|
|
mMissionRecorder = null;
|
|
mMissionPlayers = null;
|
|
}
|
|
|
|
private void mPrintLastMission_Click(object sender, EventArgs e)
|
|
{
|
|
mLastMissionResults.GetPrintDocument().Print();
|
|
}
|
|
|
|
private void SwitchControlsMode(bool editMode)
|
|
{
|
|
// Applying a roster rewrites pilot names and enabled rows, so it is an edit
|
|
// like any other and rides the same gate as the rest of the pane.
|
|
mSessionApply.Enabled = editMode;
|
|
mMap.Enabled = editMode;
|
|
mWeather.Enabled = editMode;
|
|
mTimeOfDay.Enabled = editMode;
|
|
mAdvancedDamage.Enabled = editMode;
|
|
mRandomMap.Enabled = editMode;
|
|
mRandomWeather.Enabled = editMode;
|
|
mRandomTimeOfDay.Enabled = editMode;
|
|
mMissionLengthDisplayLabel.Text = FormatTimeRemaining(mMissionLength);
|
|
mMissionLengthDisplayLabel.ForeColor = Color.Orange;
|
|
mMissionLengthTextBox.Visible = editMode;
|
|
mMissionLengthDisplayLabel.Visible = !editMode;
|
|
int column = mMissionPropertiesTable.GetColumn(mMissionLengthTextBox);
|
|
mMissionPropertiesTable.ColumnStyles[column].Width = 0f;
|
|
mMissionPropertiesTable.ColumnStyles[column].SizeType = ((!editMode) ? SizeType.Absolute : SizeType.AutoSize);
|
|
int column2 = mMissionPropertiesTable.GetColumn(mMissionLengthDisplayLabel);
|
|
mMissionPropertiesTable.ColumnStyles[column2].Width = 0f;
|
|
mMissionPropertiesTable.ColumnStyles[column2].SizeType = (editMode ? SizeType.Absolute : SizeType.AutoSize);
|
|
mPilotsDataGrid.EditMode = (editMode ? DataGridViewEditMode.EditOnKeystrokeOrF2 : DataGridViewEditMode.EditProgrammatically);
|
|
Color backColor = (editMode ? Color.White : sDataLockedColor);
|
|
foreach (DataGridViewRow item in (IEnumerable)mPilotsDataGrid.Rows)
|
|
{
|
|
item.Cells[mEnabledColumn.Index].Style.BackColor = backColor;
|
|
if (((Pod)item.Tag).HostType == HostType.GameMachineHostType)
|
|
{
|
|
Color foreColor = (((bool)item.Cells[mEnabledColumn.Index].Value) ? Color.Black : Color.DarkGray);
|
|
foreach (DataGridViewColumn pilotColumn in PilotDataColumns())
|
|
{
|
|
item.Cells[pilotColumn.Index].Style.BackColor = backColor;
|
|
item.Cells[pilotColumn.Index].Style.ForeColor = foreColor;
|
|
}
|
|
}
|
|
}
|
|
if (editMode)
|
|
{
|
|
CheckAllValues();
|
|
}
|
|
}
|
|
|
|
private DataGridViewColumn[] PilotDataColumns()
|
|
{
|
|
return new DataGridViewColumn[6] { mPilotColumn, mVehicleColumn, mColorColumn, mPatchColumn, mBadgeColumn, mExperienceColumn };
|
|
}
|
|
|
|
private void SetPodStatus(DataGridViewRow row, MungaGame munga)
|
|
{
|
|
if (munga.IsOwned && !munga.IsOwner(this))
|
|
{
|
|
row.Cells[mStatusIconColumn.Index].Value = ImageCache.PodQuestion16;
|
|
row.Cells[mStatusTextColumn.Index].Value = "In Use";
|
|
}
|
|
else
|
|
{
|
|
row.Cells[mStatusIconColumn.Index].Value = munga.Image;
|
|
row.Cells[mStatusTextColumn.Index].Value = munga.StatusMessage;
|
|
}
|
|
if (mCurrentState == BTGameState.Idle && mRequestedState == BTGameState.Idle)
|
|
{
|
|
CheckAllValues();
|
|
}
|
|
}
|
|
|
|
private void CheckAllValues()
|
|
{
|
|
foreach (DataGridViewRow item in (IEnumerable)mPilotsDataGrid.Rows)
|
|
{
|
|
item.Cells[mPilotColumn.Index].ErrorText = "";
|
|
}
|
|
uint num = 0u;
|
|
uint num2 = 0u;
|
|
uint num3 = 0u;
|
|
bool flag = false;
|
|
for (int i = 0; i < mPilotsDataGrid.Rows.Count; i++)
|
|
{
|
|
DataGridViewRow dataGridViewRow = mPilotsDataGrid.Rows[i];
|
|
Pod pod = (Pod)dataGridViewRow.Tag;
|
|
if (!(bool)dataGridViewRow.Cells[mEnabledColumn.Index].Value)
|
|
{
|
|
GreyOutRow(dataGridViewRow);
|
|
continue;
|
|
}
|
|
if (!pod.MungaGame.IsPodAppState(ApplicationID.BTL4, ApplicationState.WaitingForEgg))
|
|
{
|
|
num++;
|
|
}
|
|
if (pod.HostType == HostType.GameMachineHostType)
|
|
{
|
|
num2++;
|
|
DataGridViewCell dataGridViewCell = dataGridViewRow.Cells[mPilotColumn.Index];
|
|
foreach (DataGridViewColumn pilotColumn in PilotDataColumns())
|
|
{
|
|
dataGridViewRow.Cells[pilotColumn.Index].Style.ForeColor = pilotColumn.DefaultCellStyle.ForeColor;
|
|
if (pilotColumn != mPilotColumn)
|
|
{
|
|
dataGridViewRow.Cells[pilotColumn.Index].Style.BackColor = pilotColumn.DefaultCellStyle.BackColor;
|
|
}
|
|
}
|
|
if (dataGridViewCell.ErrorText == "")
|
|
{
|
|
if (dataGridViewCell.Value == null || (string)dataGridViewCell.Value == "")
|
|
{
|
|
dataGridViewCell.ErrorText = "Pilot name can not be blank.";
|
|
num3++;
|
|
continue;
|
|
}
|
|
for (int j = i + 1; j < mPilotsDataGrid.Rows.Count; j++)
|
|
{
|
|
DataGridViewRow dataGridViewRow2 = mPilotsDataGrid.Rows[j];
|
|
DataGridViewCell dataGridViewCell2 = dataGridViewRow2.Cells[mPilotColumn.Index];
|
|
if (((Pod)dataGridViewRow2.Tag).HostType == HostType.GameMachineHostType && (bool)dataGridViewRow2.Cells[mEnabledColumn.Index].Value && dataGridViewCell2.ErrorText == "" && dataGridViewCell.Value.Equals(dataGridViewCell2.Value))
|
|
{
|
|
dataGridViewCell.ErrorText = (dataGridViewCell2.ErrorText = "A pilot with this name already exists.");
|
|
flag = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GreyOutRow(dataGridViewRow);
|
|
}
|
|
}
|
|
StringBuilder stringBuilder = new StringBuilder();
|
|
if (num2 < 1)
|
|
{
|
|
stringBuilder.AppendLine("You should put at least one player in the game.");
|
|
}
|
|
if (num2 > 8)
|
|
{
|
|
stringBuilder.AppendLine("BattleTech only supports 8 players in a game.");
|
|
}
|
|
if (num3 != 0)
|
|
{
|
|
stringBuilder.AppendLine((num3 > 1) ? "Some pilots have a blank name." : "A pilot has a blank name.");
|
|
}
|
|
if (flag)
|
|
{
|
|
stringBuilder.AppendLine("Some pilots have duplicate names.");
|
|
}
|
|
if (num != 0)
|
|
{
|
|
stringBuilder.AppendLine((num > 1) ? "Some pods are not ready." : "A pod is not ready.");
|
|
}
|
|
if (ParseMissionLength() == TimeSpan.MinValue)
|
|
{
|
|
stringBuilder.AppendLine("The mission length is not valid.");
|
|
}
|
|
else if (ParseMissionLength() < TimeSpan.FromSeconds(10.0))
|
|
{
|
|
stringBuilder.AppendLine("The mission length must be at least 10 seconds.");
|
|
}
|
|
// Enabled implies claimed: an enabled row nobody took in the lobby puts a
|
|
// dead IP in the egg and every pod then waits on a peer that never boots.
|
|
// Empty with no session roster, which is what keeps the arcade path intact.
|
|
stringBuilder.Append(SessionRoster.Issues(mPilotsDataGrid, mEnabledColumn.Index, mDosBoxAddressShift));
|
|
mGoButton.Enabled = stringBuilder.Length <= 0;
|
|
mIssuesLabel.Text = stringBuilder.ToString();
|
|
}
|
|
|
|
private void GreyOutRow(DataGridViewRow row)
|
|
{
|
|
foreach (DataGridViewColumn pilotColumn in PilotDataColumns())
|
|
{
|
|
row.Cells[pilotColumn.Index].Style.ForeColor = Color.DarkGray;
|
|
if (pilotColumn != mPilotColumn || ((Pod)row.Tag).HostType != 0)
|
|
{
|
|
row.Cells[pilotColumn.Index].Style.BackColor = sDataLockedColor;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void mMissionLengthTextBox_TextChanged(object sender, EventArgs e)
|
|
{
|
|
CheckAllValues();
|
|
}
|
|
|
|
private TimeSpan ParseMissionLength()
|
|
{
|
|
if (!double.TryParse(mMissionLengthTextBox.Text, out var result))
|
|
{
|
|
return TimeSpan.MinValue;
|
|
}
|
|
try
|
|
{
|
|
return TimeSpan.FromMinutes(result);
|
|
}
|
|
catch (OverflowException)
|
|
{
|
|
return TimeSpan.MinValue;
|
|
}
|
|
}
|
|
|
|
private void mPilotsDataGrid_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
|
|
{
|
|
if (e.ColumnIndex == mPilotColumn.Index && !(bool)mPilotsDataGrid.Rows[e.RowIndex].Cells[mEnabledColumn.Index].Value)
|
|
{
|
|
mPilotsDataGrid.Rows[e.RowIndex].Cells[mPilotColumn.Index].Style.ForeColor = mPilotColumn.DefaultCellStyle.ForeColor;
|
|
}
|
|
}
|
|
|
|
private void mPilotsDataGrid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
|
|
{
|
|
if (mPilotsDataGrid.EditingControl is TextBox textBox)
|
|
{
|
|
textBox.AutoCompleteCustomSource = PilotNameCache.PilotNames;
|
|
textBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
|
|
textBox.AutoCompleteSource = AutoCompleteSource.CustomSource;
|
|
}
|
|
}
|
|
|
|
private void mPilotsDataGrid_CellEndEdit(object sender, DataGridViewCellEventArgs e)
|
|
{
|
|
bool? flag = null;
|
|
DataGridViewRow dataGridViewRow = mPilotsDataGrid.Rows[e.RowIndex];
|
|
if (e.ColumnIndex == mPilotColumn.Index)
|
|
{
|
|
if (dataGridViewRow.Cells[mPilotColumn.Index].Value != null && (string)dataGridViewRow.Cells[mPilotColumn.Index].Value != "")
|
|
{
|
|
dataGridViewRow.Cells[mEnabledColumn.Index].Value = true;
|
|
flag = true;
|
|
}
|
|
else
|
|
{
|
|
dataGridViewRow.Cells[mEnabledColumn.Index].Value = false;
|
|
flag = false;
|
|
}
|
|
}
|
|
else if (e.ColumnIndex == mEnabledColumn.Index)
|
|
{
|
|
flag = ((!(bool)dataGridViewRow.Cells[mEnabledColumn.Index].Value) ? new bool?(false) : new bool?(true));
|
|
}
|
|
if (flag.HasValue)
|
|
{
|
|
if (flag.Value)
|
|
{
|
|
((Pod)dataGridViewRow.Tag).MungaGame.DosBoxAddressShift = mDosBoxAddressShift;
|
|
((Pod)dataGridViewRow.Tag).MungaGame.MakeRequested(this);
|
|
}
|
|
else
|
|
{
|
|
((Pod)dataGridViewRow.Tag).MungaGame.ReleaseRequest(this);
|
|
}
|
|
}
|
|
CheckAllValues();
|
|
}
|
|
|
|
private void mPilotsDataGrid_KeyUp(object sender, KeyEventArgs e)
|
|
{
|
|
if ((e.KeyCode == Keys.Delete || e.KeyCode == Keys.Back) && mPilotsDataGrid.SelectedCells.Count == 1 && mPilotsDataGrid.SelectedCells[0].ColumnIndex == mPilotColumn.Index)
|
|
{
|
|
mPilotsDataGrid.SelectedCells[0].Value = "";
|
|
DataGridViewRow dataGridViewRow = mPilotsDataGrid.Rows[mPilotsDataGrid.SelectedCells[0].RowIndex];
|
|
dataGridViewRow.Cells[mEnabledColumn.Index].Value = false;
|
|
((Pod)dataGridViewRow.Tag).MungaGame.ReleaseRequest(this);
|
|
CheckAllValues();
|
|
}
|
|
}
|
|
|
|
private void mPilotsDataGrid_MouseDown(object sender, MouseEventArgs e)
|
|
{
|
|
if (mPilotsDataGrid.FirstDisplayedScrollingRowIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
for (int i = mPilotsDataGrid.FirstDisplayedScrollingRowIndex; i < mPilotsDataGrid.Rows.Count && ((Pod)mPilotsDataGrid.Rows[i].Tag).HostType == HostType.GameMachineHostType; i++)
|
|
{
|
|
if (mPilotsDataGrid.GetCellDisplayRectangle(-1, i, cutOverflow: true).Contains(e.Location))
|
|
{
|
|
mPilotsDataGrid.DoDragDrop(new DragDropData(i, e.Button == MouseButtons.Right), DragDropEffects.Move);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void mPilotsDataGrid_DragOver(object sender, DragEventArgs e)
|
|
{
|
|
if (mPilotsDataGrid.FirstDisplayedScrollingRowIndex >= 0)
|
|
{
|
|
for (int i = mPilotsDataGrid.FirstDisplayedScrollingRowIndex; i < mPilotsDataGrid.Rows.Count && ((Pod)mPilotsDataGrid.Rows[i].Tag).HostType == HostType.GameMachineHostType; i++)
|
|
{
|
|
if (!mPilotsDataGrid.GetCellDisplayRectangle(-1, i, cutOverflow: true).Contains(mPilotsDataGrid.PointToClient(new Point(e.X, e.Y))))
|
|
{
|
|
continue;
|
|
}
|
|
if (e.Data.GetDataPresent(typeof(DragDropData)))
|
|
{
|
|
DragDropData dragDropData = (DragDropData)e.Data.GetData(typeof(DragDropData));
|
|
if (dragDropData.StartRow != i)
|
|
{
|
|
e.Effect = DragDropEffects.Move;
|
|
}
|
|
else
|
|
{
|
|
e.Effect = DragDropEffects.None;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
e.Effect = DragDropEffects.None;
|
|
}
|
|
|
|
private void mPilotsDataGrid_DragDrop(object sender, DragEventArgs e)
|
|
{
|
|
for (int i = mPilotsDataGrid.FirstDisplayedScrollingRowIndex; i < mPilotsDataGrid.Rows.Count; i++)
|
|
{
|
|
if (!mPilotsDataGrid.GetCellDisplayRectangle(-1, i, cutOverflow: true).Contains(mPilotsDataGrid.PointToClient(new Point(e.X, e.Y))))
|
|
{
|
|
continue;
|
|
}
|
|
if (!e.Data.GetDataPresent(typeof(DragDropData)))
|
|
{
|
|
break;
|
|
}
|
|
DragDropData dragDropData = (DragDropData)e.Data.GetData(typeof(DragDropData));
|
|
if (dragDropData.StartRow != i)
|
|
{
|
|
if (dragDropData.RightClick)
|
|
{
|
|
dragDropData.EndRow = i;
|
|
mDragDropContextMenu.Tag = dragDropData;
|
|
mDragDropContextMenu.Show(e.X, e.Y);
|
|
}
|
|
else
|
|
{
|
|
SwapPilots(i, dragDropData.StartRow, update: true);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void swapToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (mDragDropContextMenu.Tag is DragDropData)
|
|
{
|
|
DragDropData dragDropData = (DragDropData)mDragDropContextMenu.Tag;
|
|
SwapPilots(dragDropData.StartRow, dragDropData.EndRow, update: true);
|
|
}
|
|
}
|
|
|
|
private void shiftToolStripMenuItem_Click(object sender, EventArgs e)
|
|
{
|
|
if (!(mDragDropContextMenu.Tag is DragDropData))
|
|
{
|
|
return;
|
|
}
|
|
DragDropData dragDropData = (DragDropData)mDragDropContextMenu.Tag;
|
|
if (dragDropData.StartRow < dragDropData.EndRow)
|
|
{
|
|
for (int i = dragDropData.StartRow; i < dragDropData.EndRow; i++)
|
|
{
|
|
SwapPilots(i, i + 1, i + 1 == dragDropData.EndRow);
|
|
}
|
|
return;
|
|
}
|
|
for (int num = dragDropData.StartRow; num > dragDropData.EndRow; num--)
|
|
{
|
|
SwapPilots(num, num - 1, num - 1 == dragDropData.EndRow);
|
|
}
|
|
}
|
|
|
|
private void SwapPilots(int row1, int row2, bool update)
|
|
{
|
|
foreach (DataGridViewColumn column in mPilotsDataGrid.Columns)
|
|
{
|
|
if (column != mStatusIconColumn && column != mStatusTextColumn && column != mEnabledColumn)
|
|
{
|
|
object value = mPilotsDataGrid[column.Index, row1].Value;
|
|
mPilotsDataGrid[column.Index, row1].Value = mPilotsDataGrid[column.Index, row2].Value;
|
|
mPilotsDataGrid[column.Index, row2].Value = value;
|
|
}
|
|
}
|
|
if (update)
|
|
{
|
|
CheckAllValues();
|
|
mPilotsDataGrid.Refresh();
|
|
}
|
|
}
|
|
|
|
protected override void OnKeyDown(KeyEventArgs e)
|
|
{
|
|
if (e.Modifiers == Keys.Control && e.KeyCode == Keys.L)
|
|
{
|
|
if (mLogWindow == null || mLogWindow.IsDisposed)
|
|
{
|
|
mLogWindow = new LogOutputWindow();
|
|
}
|
|
mLogWindow.Show();
|
|
e.Handled = true;
|
|
}
|
|
base.OnKeyDown(e);
|
|
}
|
|
|
|
private void mRandomMap_Click(object sender, EventArgs e)
|
|
{
|
|
mMap.SelectedIndex = sRand.Next(mMap.Items.Count);
|
|
}
|
|
|
|
private void mRandomWeather_Click(object sender, EventArgs e)
|
|
{
|
|
mWeather.SelectedIndex = sRand.Next(mWeather.Items.Count);
|
|
}
|
|
|
|
private void mRandomTimeOfDay_Click(object sender, EventArgs e)
|
|
{
|
|
mTimeOfDay.SelectedIndex = sRand.Next(mTimeOfDay.Items.Count);
|
|
}
|
|
|
|
private void tmrAutoTranslocate_Tick(object sender, EventArgs e)
|
|
{
|
|
mRemainingUntilTranslocate--;
|
|
if (mRemainingUntilTranslocate < 1)
|
|
{
|
|
RequestState(BTGameState.Run);
|
|
tmrAutoTranslocate.Stop();
|
|
}
|
|
else
|
|
{
|
|
string text2 = (GameStatusText = $"Launching in {mRemainingUntilTranslocate}...");
|
|
mGoButton.Text = text2;
|
|
}
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (disposing && components != null)
|
|
{
|
|
components.Dispose();
|
|
}
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
private void InitializeComponent()
|
|
{
|
|
this.components = new System.ComponentModel.Container();
|
|
this.mMissionPropertiesGroupBox = new System.Windows.Forms.GroupBox();
|
|
this.mMissionPropertiesTable = new System.Windows.Forms.TableLayoutPanel();
|
|
this.mIssuesLabel = new System.Windows.Forms.Label();
|
|
this.mMissionLengthTextLabel = new System.Windows.Forms.Label();
|
|
this.mMap = new System.Windows.Forms.ComboBox();
|
|
this.mMissionLengthDisplayLabel = new System.Windows.Forms.Label();
|
|
this.mWeather = new System.Windows.Forms.ComboBox();
|
|
this.mTimeOfDay = new System.Windows.Forms.ComboBox();
|
|
this.mMapLabel = new System.Windows.Forms.Label();
|
|
this.mWeatherLabel = new System.Windows.Forms.Label();
|
|
this.mTimeOfDayLabel = new System.Windows.Forms.Label();
|
|
this.mAdvancedDamage = new System.Windows.Forms.CheckBox();
|
|
this.mGoButton = new System.Windows.Forms.Button();
|
|
this.mResetContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
|
|
this.resetToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
this.mPrintLastMission = new System.Windows.Forms.Button();
|
|
this.mAutoPrint = new System.Windows.Forms.CheckBox();
|
|
this.mAutoTranslocateCheckbox = new System.Windows.Forms.CheckBox();
|
|
this.mRandomMap = new System.Windows.Forms.Button();
|
|
this.mRandomWeather = new System.Windows.Forms.Button();
|
|
this.mRandomTimeOfDay = new System.Windows.Forms.Button();
|
|
this.mMissionLengthTextBox = new System.Windows.Forms.TextBox();
|
|
this.mPilotsGroupBox = new System.Windows.Forms.GroupBox();
|
|
this.mPilotsDataGrid = new System.Windows.Forms.DataGridView();
|
|
this.mEnabledColumn = new System.Windows.Forms.DataGridViewCheckBoxColumn();
|
|
this.mStatusIconColumn = new System.Windows.Forms.DataGridViewImageColumn();
|
|
this.mStatusTextColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
|
this.mPilotColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
|
this.mVehicleColumn = new System.Windows.Forms.DataGridViewComboBoxColumn();
|
|
this.mColorColumn = new System.Windows.Forms.DataGridViewComboBoxColumn();
|
|
this.mPatchColumn = new System.Windows.Forms.DataGridViewComboBoxColumn();
|
|
this.mBadgeColumn = new System.Windows.Forms.DataGridViewComboBoxColumn();
|
|
this.mExperienceColumn = new System.Windows.Forms.DataGridViewComboBoxColumn();
|
|
this.mDragDropContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
|
|
this.mSwapPilots = new System.Windows.Forms.ToolStripMenuItem();
|
|
this.mShiftPilots = new System.Windows.Forms.ToolStripMenuItem();
|
|
this.mNetworkTimer = new System.Windows.Forms.Timer(this.components);
|
|
this.tmrAutoTranslocate = new System.Windows.Forms.Timer(this.components);
|
|
this.mMissionPropertiesGroupBox.SuspendLayout();
|
|
this.mMissionPropertiesTable.SuspendLayout();
|
|
this.mResetContextMenu.SuspendLayout();
|
|
this.mPilotsGroupBox.SuspendLayout();
|
|
((System.ComponentModel.ISupportInitialize)this.mPilotsDataGrid).BeginInit();
|
|
this.mDragDropContextMenu.SuspendLayout();
|
|
base.SuspendLayout();
|
|
this.mMissionPropertiesGroupBox.Controls.Add(this.mMissionPropertiesTable);
|
|
this.mMissionPropertiesGroupBox.Dock = System.Windows.Forms.DockStyle.Top;
|
|
this.mMissionPropertiesGroupBox.Location = new System.Drawing.Point(8, 8);
|
|
this.mMissionPropertiesGroupBox.Name = "mMissionPropertiesGroupBox";
|
|
this.mMissionPropertiesGroupBox.Padding = new System.Windows.Forms.Padding(5);
|
|
this.mMissionPropertiesGroupBox.Size = new System.Drawing.Size(1040, 105);
|
|
this.mMissionPropertiesGroupBox.TabIndex = 10;
|
|
this.mMissionPropertiesGroupBox.TabStop = false;
|
|
this.mMissionPropertiesGroupBox.Text = "Mission Properties";
|
|
this.mMissionPropertiesTable.AutoSize = true;
|
|
this.mMissionPropertiesTable.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
|
this.mMissionPropertiesTable.ColumnCount = 8;
|
|
this.mMissionPropertiesTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
|
this.mMissionPropertiesTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
|
this.mMissionPropertiesTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
|
this.mMissionPropertiesTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
|
this.mMissionPropertiesTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
|
this.mMissionPropertiesTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 0f));
|
|
this.mMissionPropertiesTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
|
this.mMissionPropertiesTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
|
this.mMissionPropertiesTable.Controls.Add(this.mIssuesLabel, 7, 0);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mMissionLengthTextLabel, 3, 1);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mMap, 1, 0);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mMissionLengthDisplayLabel, 5, 1);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mWeather, 1, 1);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mTimeOfDay, 1, 2);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mMapLabel, 0, 0);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mWeatherLabel, 0, 1);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mTimeOfDayLabel, 0, 2);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mAdvancedDamage, 3, 0);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mGoButton, 3, 2);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mPrintLastMission, 6, 2);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mAutoPrint, 6, 1);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mAutoTranslocateCheckbox, 6, 0);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mRandomMap, 2, 0);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mRandomWeather, 2, 1);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mRandomTimeOfDay, 2, 2);
|
|
this.mMissionPropertiesTable.Controls.Add(this.mMissionLengthTextBox, 4, 1);
|
|
this.mMissionPropertiesTable.Dock = System.Windows.Forms.DockStyle.Fill;
|
|
this.mMissionPropertiesTable.GrowStyle = System.Windows.Forms.TableLayoutPanelGrowStyle.AddColumns;
|
|
this.mMissionPropertiesTable.Location = new System.Drawing.Point(5, 18);
|
|
this.mMissionPropertiesTable.MinimumSize = new System.Drawing.Size(0, 85);
|
|
this.mMissionPropertiesTable.Name = "mMissionPropertiesTable";
|
|
this.mMissionPropertiesTable.RowCount = 4;
|
|
this.mMissionPropertiesTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
|
this.mMissionPropertiesTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
|
this.mMissionPropertiesTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
|
this.mMissionPropertiesTable.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100f));
|
|
this.mMissionPropertiesTable.Size = new System.Drawing.Size(1030, 85);
|
|
this.mMissionPropertiesTable.TabIndex = 0;
|
|
this.mIssuesLabel.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
|
this.mIssuesLabel.AutoSize = true;
|
|
this.mIssuesLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25f, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0);
|
|
this.mIssuesLabel.ForeColor = System.Drawing.Color.Red;
|
|
this.mIssuesLabel.Location = new System.Drawing.Point(642, 0);
|
|
this.mIssuesLabel.Name = "mIssuesLabel";
|
|
this.mMissionPropertiesTable.SetRowSpan(this.mIssuesLabel, 4);
|
|
this.mIssuesLabel.Size = new System.Drawing.Size(385, 85);
|
|
this.mIssuesLabel.TabIndex = 0;
|
|
this.mMissionLengthTextLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
|
this.mMissionLengthTextLabel.AutoSize = true;
|
|
this.mMissionLengthTextLabel.Location = new System.Drawing.Point(311, 37);
|
|
this.mMissionLengthTextLabel.Name = "mMissionLengthTextLabel";
|
|
this.mMissionLengthTextLabel.Size = new System.Drawing.Size(106, 13);
|
|
this.mMissionLengthTextLabel.TabIndex = 7;
|
|
this.mMissionLengthTextLabel.Text = "Mission Length (min):";
|
|
this.mMap.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
|
this.mMap.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
|
this.mMap.FormattingEnabled = true;
|
|
this.mMap.Location = new System.Drawing.Point(76, 4);
|
|
this.mMap.Name = "mMap";
|
|
this.mMap.Size = new System.Drawing.Size(198, 21);
|
|
this.mMap.TabIndex = 0;
|
|
this.mMissionLengthDisplayLabel.Anchor = System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
|
this.mMissionLengthDisplayLabel.AutoSize = true;
|
|
this.mMissionLengthDisplayLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 12f, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0);
|
|
this.mMissionLengthDisplayLabel.ForeColor = System.Drawing.Color.Green;
|
|
this.mMissionLengthDisplayLabel.Location = new System.Drawing.Point(529, 33);
|
|
this.mMissionLengthDisplayLabel.Name = "mMissionLengthDisplayLabel";
|
|
this.mMissionLengthDisplayLabel.Size = new System.Drawing.Size(1, 20);
|
|
this.mMissionLengthDisplayLabel.TabIndex = 9;
|
|
this.mMissionLengthDisplayLabel.Text = "00:00";
|
|
this.mMissionLengthDisplayLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
|
|
this.mMissionLengthDisplayLabel.Visible = false;
|
|
this.mWeather.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
|
this.mWeather.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
|
this.mWeather.FormattingEnabled = true;
|
|
this.mWeather.Location = new System.Drawing.Point(76, 33);
|
|
this.mWeather.Name = "mWeather";
|
|
this.mWeather.Size = new System.Drawing.Size(198, 21);
|
|
this.mWeather.TabIndex = 1;
|
|
this.mTimeOfDay.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
|
this.mTimeOfDay.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
|
this.mTimeOfDay.FormattingEnabled = true;
|
|
this.mTimeOfDay.Location = new System.Drawing.Point(76, 62);
|
|
this.mTimeOfDay.Name = "mTimeOfDay";
|
|
this.mTimeOfDay.Size = new System.Drawing.Size(198, 21);
|
|
this.mTimeOfDay.TabIndex = 2;
|
|
this.mMapLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
|
this.mMapLabel.AutoSize = true;
|
|
this.mMapLabel.Location = new System.Drawing.Point(3, 8);
|
|
this.mMapLabel.Name = "mMapLabel";
|
|
this.mMapLabel.Size = new System.Drawing.Size(31, 13);
|
|
this.mMapLabel.TabIndex = 0;
|
|
this.mMapLabel.Text = "Map:";
|
|
this.mWeatherLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
|
this.mWeatherLabel.AutoSize = true;
|
|
this.mWeatherLabel.Location = new System.Drawing.Point(3, 37);
|
|
this.mWeatherLabel.Name = "mWeatherLabel";
|
|
this.mWeatherLabel.Size = new System.Drawing.Size(51, 13);
|
|
this.mWeatherLabel.TabIndex = 2;
|
|
this.mWeatherLabel.Text = "Weather:";
|
|
this.mTimeOfDayLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
|
this.mTimeOfDayLabel.AutoSize = true;
|
|
this.mTimeOfDayLabel.Location = new System.Drawing.Point(3, 66);
|
|
this.mTimeOfDayLabel.Name = "mTimeOfDayLabel";
|
|
this.mTimeOfDayLabel.Size = new System.Drawing.Size(67, 13);
|
|
this.mTimeOfDayLabel.TabIndex = 4;
|
|
this.mTimeOfDayLabel.Text = "Time of Day:";
|
|
this.mAdvancedDamage.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
|
this.mAdvancedDamage.AutoSize = true;
|
|
this.mMissionPropertiesTable.SetColumnSpan(this.mAdvancedDamage, 3);
|
|
this.mAdvancedDamage.Checked = true;
|
|
this.mAdvancedDamage.CheckState = System.Windows.Forms.CheckState.Checked;
|
|
this.mAdvancedDamage.Location = new System.Drawing.Point(311, 6);
|
|
this.mAdvancedDamage.Name = "mAdvancedDamage";
|
|
this.mAdvancedDamage.Size = new System.Drawing.Size(117, 17);
|
|
this.mAdvancedDamage.TabIndex = 6;
|
|
this.mAdvancedDamage.Text = "Advanced Damage";
|
|
this.mAdvancedDamage.UseVisualStyleBackColor = true;
|
|
this.mGoButton.Anchor = System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
|
this.mMissionPropertiesTable.SetColumnSpan(this.mGoButton, 3);
|
|
this.mGoButton.ContextMenuStrip = this.mResetContextMenu;
|
|
this.mGoButton.Location = new System.Drawing.Point(311, 61);
|
|
this.mGoButton.Name = "mGoButton";
|
|
this.mGoButton.Size = new System.Drawing.Size(212, 23);
|
|
this.mGoButton.TabIndex = 10;
|
|
this.mGoButton.Text = "Load";
|
|
this.mGoButton.UseVisualStyleBackColor = true;
|
|
this.mGoButton.Click += new System.EventHandler(mGoButton_Click);
|
|
this.mResetContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[1] { this.resetToolStripMenuItem });
|
|
this.mResetContextMenu.Name = "mResetContextMenu";
|
|
this.mResetContextMenu.Size = new System.Drawing.Size(103, 26);
|
|
this.resetToolStripMenuItem.Name = "resetToolStripMenuItem";
|
|
this.resetToolStripMenuItem.Size = new System.Drawing.Size(102, 22);
|
|
this.resetToolStripMenuItem.Text = "&Reset";
|
|
this.resetToolStripMenuItem.Click += new System.EventHandler(resetToolStripMenuItem_Click);
|
|
this.mPrintLastMission.Anchor = System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
|
this.mPrintLastMission.AutoSize = true;
|
|
this.mPrintLastMission.Enabled = false;
|
|
this.mPrintLastMission.Location = new System.Drawing.Point(529, 61);
|
|
this.mPrintLastMission.Name = "mPrintLastMission";
|
|
this.mPrintLastMission.Size = new System.Drawing.Size(107, 23);
|
|
this.mPrintLastMission.TabIndex = 11;
|
|
this.mPrintLastMission.Text = "Print Last Mission";
|
|
this.mPrintLastMission.UseVisualStyleBackColor = true;
|
|
this.mPrintLastMission.Click += new System.EventHandler(mPrintLastMission_Click);
|
|
this.mAutoPrint.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
|
this.mAutoPrint.AutoSize = true;
|
|
this.mAutoPrint.Location = new System.Drawing.Point(529, 35);
|
|
this.mAutoPrint.Name = "mAutoPrint";
|
|
this.mAutoPrint.Size = new System.Drawing.Size(72, 17);
|
|
this.mAutoPrint.TabIndex = 9;
|
|
this.mAutoPrint.Text = "Auto Print";
|
|
this.mAutoPrint.UseVisualStyleBackColor = true;
|
|
this.mAutoTranslocateCheckbox.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
|
this.mAutoTranslocateCheckbox.AutoSize = true;
|
|
this.mAutoTranslocateCheckbox.Location = new System.Drawing.Point(529, 6);
|
|
this.mAutoTranslocateCheckbox.Name = "mAutoTranslocateCheckbox";
|
|
this.mAutoTranslocateCheckbox.Size = new System.Drawing.Size(107, 17);
|
|
this.mAutoTranslocateCheckbox.TabIndex = 8;
|
|
this.mAutoTranslocateCheckbox.Text = "Auto Translocate";
|
|
this.mAutoTranslocateCheckbox.UseVisualStyleBackColor = true;
|
|
this.mRandomMap.Location = new System.Drawing.Point(280, 3);
|
|
this.mRandomMap.Name = "mRandomMap";
|
|
this.mRandomMap.Size = new System.Drawing.Size(25, 23);
|
|
this.mRandomMap.TabIndex = 3;
|
|
this.mRandomMap.Text = "R";
|
|
this.mRandomMap.UseVisualStyleBackColor = true;
|
|
this.mRandomMap.Click += new System.EventHandler(mRandomMap_Click);
|
|
this.mRandomWeather.Location = new System.Drawing.Point(280, 32);
|
|
this.mRandomWeather.Name = "mRandomWeather";
|
|
this.mRandomWeather.Size = new System.Drawing.Size(25, 23);
|
|
this.mRandomWeather.TabIndex = 4;
|
|
this.mRandomWeather.Text = "R";
|
|
this.mRandomWeather.UseVisualStyleBackColor = true;
|
|
this.mRandomWeather.Click += new System.EventHandler(mRandomWeather_Click);
|
|
this.mRandomTimeOfDay.Location = new System.Drawing.Point(280, 61);
|
|
this.mRandomTimeOfDay.Name = "mRandomTimeOfDay";
|
|
this.mRandomTimeOfDay.Size = new System.Drawing.Size(25, 23);
|
|
this.mRandomTimeOfDay.TabIndex = 5;
|
|
this.mRandomTimeOfDay.Text = "R";
|
|
this.mRandomTimeOfDay.UseVisualStyleBackColor = true;
|
|
this.mRandomTimeOfDay.Click += new System.EventHandler(mRandomTimeOfDay_Click);
|
|
this.mMissionLengthTextBox.Anchor = System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
|
this.mMissionLengthTextBox.Location = new System.Drawing.Point(423, 33);
|
|
this.mMissionLengthTextBox.Name = "mMissionLengthTextBox";
|
|
this.mMissionLengthTextBox.Size = new System.Drawing.Size(100, 20);
|
|
this.mMissionLengthTextBox.TabIndex = 12;
|
|
this.mMissionLengthTextBox.TextChanged += new System.EventHandler(mMissionLengthTextBox_TextChanged);
|
|
this.mPilotsGroupBox.Controls.Add(this.mPilotsDataGrid);
|
|
this.mPilotsGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
|
|
this.mPilotsGroupBox.Location = new System.Drawing.Point(8, 113);
|
|
this.mPilotsGroupBox.Name = "mPilotsGroupBox";
|
|
this.mPilotsGroupBox.Padding = new System.Windows.Forms.Padding(5);
|
|
this.mPilotsGroupBox.Size = new System.Drawing.Size(1040, 425);
|
|
this.mPilotsGroupBox.TabIndex = 11;
|
|
this.mPilotsGroupBox.TabStop = false;
|
|
this.mPilotsGroupBox.Text = "Pilots";
|
|
this.mPilotsDataGrid.AllowDrop = true;
|
|
this.mPilotsDataGrid.AllowUserToAddRows = false;
|
|
this.mPilotsDataGrid.AllowUserToDeleteRows = false;
|
|
this.mPilotsDataGrid.AllowUserToResizeColumns = false;
|
|
this.mPilotsDataGrid.AllowUserToResizeRows = false;
|
|
this.mPilotsDataGrid.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
|
this.mPilotsDataGrid.Columns.AddRange(this.mEnabledColumn, this.mStatusIconColumn, this.mStatusTextColumn, this.mPilotColumn, this.mVehicleColumn, this.mColorColumn, this.mPatchColumn, this.mBadgeColumn, this.mExperienceColumn);
|
|
this.mPilotsDataGrid.Dock = System.Windows.Forms.DockStyle.Fill;
|
|
this.mPilotsDataGrid.Location = new System.Drawing.Point(5, 18);
|
|
this.mPilotsDataGrid.MultiSelect = false;
|
|
this.mPilotsDataGrid.Name = "mPilotsDataGrid";
|
|
this.mPilotsDataGrid.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
|
|
this.mPilotsDataGrid.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.CellSelect;
|
|
this.mPilotsDataGrid.ShowEditingIcon = false;
|
|
this.mPilotsDataGrid.Size = new System.Drawing.Size(1030, 402);
|
|
this.mPilotsDataGrid.TabIndex = 0;
|
|
this.mPilotsDataGrid.MouseDown += new System.Windows.Forms.MouseEventHandler(mPilotsDataGrid_MouseDown);
|
|
this.mPilotsDataGrid.CellBeginEdit += new System.Windows.Forms.DataGridViewCellCancelEventHandler(mPilotsDataGrid_CellBeginEdit);
|
|
this.mPilotsDataGrid.DragOver += new System.Windows.Forms.DragEventHandler(mPilotsDataGrid_DragOver);
|
|
this.mPilotsDataGrid.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(mPilotsDataGrid_CellEndEdit);
|
|
this.mPilotsDataGrid.EditingControlShowing += new System.Windows.Forms.DataGridViewEditingControlShowingEventHandler(mPilotsDataGrid_EditingControlShowing);
|
|
this.mPilotsDataGrid.KeyUp += new System.Windows.Forms.KeyEventHandler(mPilotsDataGrid_KeyUp);
|
|
this.mPilotsDataGrid.DragDrop += new System.Windows.Forms.DragEventHandler(mPilotsDataGrid_DragDrop);
|
|
this.mEnabledColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.DisplayedCells;
|
|
this.mEnabledColumn.HeaderText = "Enabled";
|
|
this.mEnabledColumn.Name = "mEnabledColumn";
|
|
this.mEnabledColumn.Width = 52;
|
|
this.mStatusIconColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.ColumnHeader;
|
|
this.mStatusIconColumn.HeaderText = "Status";
|
|
this.mStatusIconColumn.Name = "mStatusIconColumn";
|
|
this.mStatusIconColumn.ReadOnly = true;
|
|
this.mStatusIconColumn.Resizable = System.Windows.Forms.DataGridViewTriState.False;
|
|
this.mStatusIconColumn.Width = 43;
|
|
this.mStatusTextColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
|
this.mStatusTextColumn.HeaderText = "Status Text";
|
|
this.mStatusTextColumn.MinimumWidth = 100;
|
|
this.mStatusTextColumn.Name = "mStatusTextColumn";
|
|
this.mStatusTextColumn.ReadOnly = true;
|
|
this.mPilotColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
|
this.mPilotColumn.HeaderText = "Pilot";
|
|
this.mPilotColumn.MinimumWidth = 100;
|
|
this.mPilotColumn.Name = "mPilotColumn";
|
|
this.mPilotColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
|
|
this.mVehicleColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
|
this.mVehicleColumn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
|
this.mVehicleColumn.HeaderText = "Mech";
|
|
this.mVehicleColumn.MinimumWidth = 100;
|
|
this.mVehicleColumn.Name = "mVehicleColumn";
|
|
this.mColorColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
|
this.mColorColumn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
|
this.mColorColumn.HeaderText = "Camo";
|
|
this.mColorColumn.MinimumWidth = 80;
|
|
this.mColorColumn.Name = "mColorColumn";
|
|
this.mPatchColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
|
this.mPatchColumn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
|
this.mPatchColumn.HeaderText = "Patch";
|
|
this.mPatchColumn.MinimumWidth = 80;
|
|
this.mPatchColumn.Name = "mPatchColumn";
|
|
this.mBadgeColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
|
this.mBadgeColumn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
|
this.mBadgeColumn.HeaderText = "Badge";
|
|
this.mBadgeColumn.MinimumWidth = 80;
|
|
this.mBadgeColumn.Name = "mBadgeColumn";
|
|
this.mExperienceColumn.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
|
|
this.mExperienceColumn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
|
this.mExperienceColumn.HeaderText = "Experience";
|
|
this.mExperienceColumn.MinimumWidth = 80;
|
|
this.mExperienceColumn.Name = "mExperienceColumn";
|
|
this.mDragDropContextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[2] { this.mSwapPilots, this.mShiftPilots });
|
|
this.mDragDropContextMenu.Name = "contextMenuStrip1";
|
|
this.mDragDropContextMenu.Size = new System.Drawing.Size(103, 48);
|
|
this.mSwapPilots.Name = "mSwapPilots";
|
|
this.mSwapPilots.Size = new System.Drawing.Size(102, 22);
|
|
this.mSwapPilots.Text = "Swap";
|
|
this.mSwapPilots.Click += new System.EventHandler(swapToolStripMenuItem_Click);
|
|
this.mShiftPilots.Name = "mShiftPilots";
|
|
this.mShiftPilots.Size = new System.Drawing.Size(102, 22);
|
|
this.mShiftPilots.Text = "Shift";
|
|
this.mShiftPilots.Click += new System.EventHandler(shiftToolStripMenuItem_Click);
|
|
this.mNetworkTimer.Enabled = true;
|
|
this.mNetworkTimer.Tick += new System.EventHandler(NetworkScan);
|
|
this.tmrAutoTranslocate.Interval = 1000;
|
|
this.tmrAutoTranslocate.Tick += new System.EventHandler(tmrAutoTranslocate_Tick);
|
|
base.AutoScaleDimensions = new System.Drawing.SizeF(6f, 13f);
|
|
base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
|
base.ClientSize = new System.Drawing.Size(1056, 546);
|
|
base.Controls.Add(this.mPilotsGroupBox);
|
|
base.Controls.Add(this.mMissionPropertiesGroupBox);
|
|
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25f, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 0);
|
|
base.KeyPreview = true;
|
|
base.Name = "BTGame";
|
|
base.Padding = new System.Windows.Forms.Padding(8);
|
|
base.TabText = "BattleTech Game";
|
|
this.Text = "BattleTech Game";
|
|
this.mMissionPropertiesGroupBox.ResumeLayout(false);
|
|
this.mMissionPropertiesGroupBox.PerformLayout();
|
|
this.mMissionPropertiesTable.ResumeLayout(false);
|
|
this.mMissionPropertiesTable.PerformLayout();
|
|
this.mResetContextMenu.ResumeLayout(false);
|
|
this.mPilotsGroupBox.ResumeLayout(false);
|
|
((System.ComponentModel.ISupportInitialize)this.mPilotsDataGrid).EndInit();
|
|
this.mDragDropContextMenu.ResumeLayout(false);
|
|
base.ResumeLayout(false);
|
|
}
|
|
}
|