-Added reset function for the SS crate settings
-Haystacks are now usable in Winter -Tilesets are now searched in the given order -Mods are separated into a setting per game -Trigger and teamtype names are now always restricted to respectively 4 and 8 characters. -Adjusted player settings to SS -Fixed triggers being selectable on unbuilt buildings. -Error messages added during load no longer implicitly mark the map as modified; a specific "modified" boolean is now added for that. -Pressing [Enter] in Waypoints mode will now jump to the selected waypoint.
This commit is contained in:
parent
9c91112cd5
commit
f1fac05636
@ -13,8 +13,14 @@
|
||||
</startup>
|
||||
<applicationSettings>
|
||||
<MobiusEditor.Properties.Settings>
|
||||
<setting name="ModsToLoad" serializeAs="String">
|
||||
<value>2844969675;Tiberian_Dawn\ConcretePavementTD</value>
|
||||
<setting name="ModsToLoadTD" serializeAs="String">
|
||||
<value>2844969675;ConcretePavementTD</value>
|
||||
</setting>
|
||||
<setting name="ModsToLoadRA" serializeAs="String">
|
||||
<value />
|
||||
</setting>
|
||||
<setting name="ModsToLoadSS" serializeAs="String">
|
||||
<value>2844969675;ConcretePavementTD</value>
|
||||
</setting>
|
||||
<setting name="MapScale" serializeAs="String">
|
||||
<value>0.5</value>
|
||||
|
164
CnCTDRAMapEditor/Controls/CrateSettings.Designer.cs
generated
164
CnCTDRAMapEditor/Controls/CrateSettings.Designer.cs
generated
@ -83,6 +83,8 @@ namespace MobiusEditor.Controls
|
||||
this.nudDensity = new MobiusEditor.Controls.EnhNumericUpDown();
|
||||
this.nudIonFactor = new MobiusEditor.Controls.EnhNumericUpDown();
|
||||
this.nudCrateTimer = new MobiusEditor.Controls.EnhNumericUpDown();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.btnDefaults = new System.Windows.Forms.Button();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudAddStrength)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudAddWeapon)).BeginInit();
|
||||
@ -103,15 +105,17 @@ namespace MobiusEditor.Controls
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudDensity)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudIonFactor)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudCrateTimer)).BeginInit();
|
||||
this.panel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.tableLayoutPanel1.AutoSize = true;
|
||||
this.tableLayoutPanel1.ColumnCount = 3;
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 35F));
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 15F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.label5, 0, 4);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label4, 0, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label3, 0, 2);
|
||||
@ -152,7 +156,6 @@ namespace MobiusEditor.Controls
|
||||
this.tableLayoutPanel1.Controls.Add(this.nudDensity, 1, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.nudIonFactor, 1, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.nudCrateTimer, 1, 3);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 25;
|
||||
@ -181,7 +184,7 @@ namespace MobiusEditor.Controls
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(400, 645);
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(463, 554);
|
||||
this.tableLayoutPanel1.TabIndex = 1;
|
||||
//
|
||||
// label5
|
||||
@ -191,7 +194,7 @@ namespace MobiusEditor.Controls
|
||||
this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.label5.Location = new System.Drawing.Point(3, 104);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(334, 26);
|
||||
this.label5.Size = new System.Drawing.Size(457, 26);
|
||||
this.label5.TabIndex = 38;
|
||||
this.label5.Text = "Crate chance settings:";
|
||||
this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -202,7 +205,7 @@ namespace MobiusEditor.Controls
|
||||
this.label4.Location = new System.Drawing.Point(2, 78);
|
||||
this.label4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(136, 26);
|
||||
this.label4.Size = new System.Drawing.Size(186, 26);
|
||||
this.label4.TabIndex = 37;
|
||||
this.label4.Text = "Crate Timer";
|
||||
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -213,7 +216,7 @@ namespace MobiusEditor.Controls
|
||||
this.label3.Location = new System.Drawing.Point(2, 52);
|
||||
this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(136, 26);
|
||||
this.label3.Size = new System.Drawing.Size(186, 26);
|
||||
this.label3.TabIndex = 36;
|
||||
this.label3.Text = "Ion Factor";
|
||||
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -225,7 +228,7 @@ namespace MobiusEditor.Controls
|
||||
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.label2.Location = new System.Drawing.Point(3, 0);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(334, 26);
|
||||
this.label2.Size = new System.Drawing.Size(457, 26);
|
||||
this.label2.TabIndex = 34;
|
||||
this.label2.Text = "General crate settings:";
|
||||
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -236,7 +239,7 @@ namespace MobiusEditor.Controls
|
||||
this.label1.Location = new System.Drawing.Point(2, 26);
|
||||
this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(136, 26);
|
||||
this.label1.Size = new System.Drawing.Size(186, 26);
|
||||
this.label1.TabIndex = 33;
|
||||
this.label1.Text = "Crate Density";
|
||||
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -247,7 +250,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblStealth.Location = new System.Drawing.Point(2, 313);
|
||||
this.lblStealth.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.lblStealth.Name = "lblStealth";
|
||||
this.lblStealth.Size = new System.Drawing.Size(136, 26);
|
||||
this.lblStealth.Size = new System.Drawing.Size(186, 26);
|
||||
this.lblStealth.TabIndex = 14;
|
||||
this.lblStealth.Text = "Crate: Stealth";
|
||||
this.lblStealth.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -258,7 +261,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblSuper.Location = new System.Drawing.Point(2, 521);
|
||||
this.lblSuper.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.lblSuper.Name = "lblSuper";
|
||||
this.lblSuper.Size = new System.Drawing.Size(136, 26);
|
||||
this.lblSuper.Size = new System.Drawing.Size(186, 26);
|
||||
this.lblSuper.TabIndex = 30;
|
||||
this.lblSuper.Text = "Crate: Super";
|
||||
this.lblSuper.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -269,7 +272,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblArmageddon.Location = new System.Drawing.Point(2, 495);
|
||||
this.lblArmageddon.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.lblArmageddon.Name = "lblArmageddon";
|
||||
this.lblArmageddon.Size = new System.Drawing.Size(136, 26);
|
||||
this.lblArmageddon.Size = new System.Drawing.Size(186, 26);
|
||||
this.lblArmageddon.TabIndex = 28;
|
||||
this.lblArmageddon.Text = "Crate: Armageddon";
|
||||
this.lblArmageddon.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -280,7 +283,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblRadar.Location = new System.Drawing.Point(2, 469);
|
||||
this.lblRadar.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.lblRadar.Name = "lblRadar";
|
||||
this.lblRadar.Size = new System.Drawing.Size(136, 26);
|
||||
this.lblRadar.Size = new System.Drawing.Size(186, 26);
|
||||
this.lblRadar.TabIndex = 26;
|
||||
this.lblRadar.Text = "Crate: Radar";
|
||||
this.lblRadar.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -291,7 +294,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblUnshroud.Location = new System.Drawing.Point(2, 443);
|
||||
this.lblUnshroud.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.lblUnshroud.Name = "lblUnshroud";
|
||||
this.lblUnshroud.Size = new System.Drawing.Size(136, 26);
|
||||
this.lblUnshroud.Size = new System.Drawing.Size(186, 26);
|
||||
this.lblUnshroud.TabIndex = 24;
|
||||
this.lblUnshroud.Text = "Crate: Unshroud";
|
||||
this.lblUnshroud.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -302,7 +305,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblReshroud.Location = new System.Drawing.Point(2, 417);
|
||||
this.lblReshroud.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.lblReshroud.Name = "lblReshroud";
|
||||
this.lblReshroud.Size = new System.Drawing.Size(136, 26);
|
||||
this.lblReshroud.Size = new System.Drawing.Size(186, 26);
|
||||
this.lblReshroud.TabIndex = 22;
|
||||
this.lblReshroud.Text = "Crate: Reshroud";
|
||||
this.lblReshroud.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -313,7 +316,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblUncloakAll.Location = new System.Drawing.Point(2, 391);
|
||||
this.lblUncloakAll.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.lblUncloakAll.Name = "lblUncloakAll";
|
||||
this.lblUncloakAll.Size = new System.Drawing.Size(136, 26);
|
||||
this.lblUncloakAll.Size = new System.Drawing.Size(186, 26);
|
||||
this.lblUncloakAll.TabIndex = 20;
|
||||
this.lblUncloakAll.Text = "Crate: Uncloak All";
|
||||
this.lblUncloakAll.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -324,7 +327,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblKill.Location = new System.Drawing.Point(2, 365);
|
||||
this.lblKill.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.lblKill.Name = "lblKill";
|
||||
this.lblKill.Size = new System.Drawing.Size(136, 26);
|
||||
this.lblKill.Size = new System.Drawing.Size(186, 26);
|
||||
this.lblKill.TabIndex = 18;
|
||||
this.lblKill.Text = "Crate: Kill";
|
||||
this.lblKill.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -335,7 +338,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblTeleport.Location = new System.Drawing.Point(2, 339);
|
||||
this.lblTeleport.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.lblTeleport.Name = "lblTeleport";
|
||||
this.lblTeleport.Size = new System.Drawing.Size(136, 26);
|
||||
this.lblTeleport.Size = new System.Drawing.Size(186, 26);
|
||||
this.lblTeleport.TabIndex = 16;
|
||||
this.lblTeleport.Text = "Crate: Teleport";
|
||||
this.lblTeleport.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -345,7 +348,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblAddStrength.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.lblAddStrength.Location = new System.Drawing.Point(3, 130);
|
||||
this.lblAddStrength.Name = "lblAddStrength";
|
||||
this.lblAddStrength.Size = new System.Drawing.Size(134, 26);
|
||||
this.lblAddStrength.Size = new System.Drawing.Size(184, 26);
|
||||
this.lblAddStrength.TabIndex = 0;
|
||||
this.lblAddStrength.Text = "Crate: Add Strength";
|
||||
this.lblAddStrength.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -355,7 +358,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblAddWeapon.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.lblAddWeapon.Location = new System.Drawing.Point(3, 156);
|
||||
this.lblAddWeapon.Name = "lblAddWeapon";
|
||||
this.lblAddWeapon.Size = new System.Drawing.Size(134, 26);
|
||||
this.lblAddWeapon.Size = new System.Drawing.Size(184, 26);
|
||||
this.lblAddWeapon.TabIndex = 2;
|
||||
this.lblAddWeapon.Text = "Crate: Add Weapon";
|
||||
this.lblAddWeapon.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -365,7 +368,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblAddSpeed.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.lblAddSpeed.Location = new System.Drawing.Point(3, 182);
|
||||
this.lblAddSpeed.Name = "lblAddSpeed";
|
||||
this.lblAddSpeed.Size = new System.Drawing.Size(134, 26);
|
||||
this.lblAddSpeed.Size = new System.Drawing.Size(184, 26);
|
||||
this.lblAddSpeed.TabIndex = 4;
|
||||
this.lblAddSpeed.Text = "Crate: Add Speed";
|
||||
this.lblAddSpeed.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -375,7 +378,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblRapidReload.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.lblRapidReload.Location = new System.Drawing.Point(3, 208);
|
||||
this.lblRapidReload.Name = "lblRapidReload";
|
||||
this.lblRapidReload.Size = new System.Drawing.Size(134, 26);
|
||||
this.lblRapidReload.Size = new System.Drawing.Size(184, 26);
|
||||
this.lblRapidReload.TabIndex = 6;
|
||||
this.lblRapidReload.Text = "Crate: Rapid Reload";
|
||||
this.lblRapidReload.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -385,7 +388,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblAddRange.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.lblAddRange.Location = new System.Drawing.Point(3, 234);
|
||||
this.lblAddRange.Name = "lblAddRange";
|
||||
this.lblAddRange.Size = new System.Drawing.Size(134, 27);
|
||||
this.lblAddRange.Size = new System.Drawing.Size(184, 27);
|
||||
this.lblAddRange.TabIndex = 8;
|
||||
this.lblAddRange.Text = "Crate: Add Range";
|
||||
this.lblAddRange.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -396,7 +399,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblHeal.Location = new System.Drawing.Point(2, 261);
|
||||
this.lblHeal.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.lblHeal.Name = "lblHeal";
|
||||
this.lblHeal.Size = new System.Drawing.Size(136, 26);
|
||||
this.lblHeal.Size = new System.Drawing.Size(186, 26);
|
||||
this.lblHeal.TabIndex = 10;
|
||||
this.lblHeal.Text = "Crate: Heal";
|
||||
this.lblHeal.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -407,7 +410,7 @@ namespace MobiusEditor.Controls
|
||||
this.lblBomb.Location = new System.Drawing.Point(2, 287);
|
||||
this.lblBomb.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
|
||||
this.lblBomb.Name = "lblBomb";
|
||||
this.lblBomb.Size = new System.Drawing.Size(136, 26);
|
||||
this.lblBomb.Size = new System.Drawing.Size(186, 26);
|
||||
this.lblBomb.TabIndex = 12;
|
||||
this.lblBomb.Text = "Crate: Bomb";
|
||||
this.lblBomb.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -421,7 +424,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudAddStrength.IntValue = 0;
|
||||
this.nudAddStrength.Location = new System.Drawing.Point(143, 133);
|
||||
this.nudAddStrength.Location = new System.Drawing.Point(193, 133);
|
||||
this.nudAddStrength.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -431,7 +434,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudAddStrength.SelectedText = "";
|
||||
this.nudAddStrength.SelectionLength = 0;
|
||||
this.nudAddStrength.SelectionStart = 0;
|
||||
this.nudAddStrength.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudAddStrength.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudAddStrength.TabIndex = 35;
|
||||
//
|
||||
// nudAddWeapon
|
||||
@ -443,7 +446,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudAddWeapon.IntValue = 0;
|
||||
this.nudAddWeapon.Location = new System.Drawing.Point(143, 159);
|
||||
this.nudAddWeapon.Location = new System.Drawing.Point(193, 159);
|
||||
this.nudAddWeapon.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -453,7 +456,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudAddWeapon.SelectedText = "";
|
||||
this.nudAddWeapon.SelectionLength = 0;
|
||||
this.nudAddWeapon.SelectionStart = 0;
|
||||
this.nudAddWeapon.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudAddWeapon.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudAddWeapon.TabIndex = 35;
|
||||
//
|
||||
// nudAddSpeed
|
||||
@ -465,7 +468,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudAddSpeed.IntValue = 0;
|
||||
this.nudAddSpeed.Location = new System.Drawing.Point(143, 185);
|
||||
this.nudAddSpeed.Location = new System.Drawing.Point(193, 185);
|
||||
this.nudAddSpeed.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -475,7 +478,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudAddSpeed.SelectedText = "";
|
||||
this.nudAddSpeed.SelectionLength = 0;
|
||||
this.nudAddSpeed.SelectionStart = 0;
|
||||
this.nudAddSpeed.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudAddSpeed.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudAddSpeed.TabIndex = 35;
|
||||
//
|
||||
// nudRapidReload
|
||||
@ -487,7 +490,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudRapidReload.IntValue = 0;
|
||||
this.nudRapidReload.Location = new System.Drawing.Point(143, 211);
|
||||
this.nudRapidReload.Location = new System.Drawing.Point(193, 211);
|
||||
this.nudRapidReload.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -497,7 +500,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudRapidReload.SelectedText = "";
|
||||
this.nudRapidReload.SelectionLength = 0;
|
||||
this.nudRapidReload.SelectionStart = 0;
|
||||
this.nudRapidReload.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudRapidReload.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudRapidReload.TabIndex = 35;
|
||||
//
|
||||
// nudAddRange
|
||||
@ -509,7 +512,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudAddRange.IntValue = 0;
|
||||
this.nudAddRange.Location = new System.Drawing.Point(143, 237);
|
||||
this.nudAddRange.Location = new System.Drawing.Point(193, 237);
|
||||
this.nudAddRange.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -519,7 +522,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudAddRange.SelectedText = "";
|
||||
this.nudAddRange.SelectionLength = 0;
|
||||
this.nudAddRange.SelectionStart = 0;
|
||||
this.nudAddRange.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudAddRange.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudAddRange.TabIndex = 35;
|
||||
//
|
||||
// nudHeal
|
||||
@ -531,7 +534,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudHeal.IntValue = 0;
|
||||
this.nudHeal.Location = new System.Drawing.Point(143, 264);
|
||||
this.nudHeal.Location = new System.Drawing.Point(193, 264);
|
||||
this.nudHeal.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -541,7 +544,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudHeal.SelectedText = "";
|
||||
this.nudHeal.SelectionLength = 0;
|
||||
this.nudHeal.SelectionStart = 0;
|
||||
this.nudHeal.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudHeal.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudHeal.TabIndex = 35;
|
||||
//
|
||||
// nudBomb
|
||||
@ -553,7 +556,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudBomb.IntValue = 0;
|
||||
this.nudBomb.Location = new System.Drawing.Point(143, 290);
|
||||
this.nudBomb.Location = new System.Drawing.Point(193, 290);
|
||||
this.nudBomb.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -563,7 +566,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudBomb.SelectedText = "";
|
||||
this.nudBomb.SelectionLength = 0;
|
||||
this.nudBomb.SelectionStart = 0;
|
||||
this.nudBomb.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudBomb.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudBomb.TabIndex = 35;
|
||||
//
|
||||
// nudStealth
|
||||
@ -575,7 +578,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudStealth.IntValue = 0;
|
||||
this.nudStealth.Location = new System.Drawing.Point(143, 316);
|
||||
this.nudStealth.Location = new System.Drawing.Point(193, 316);
|
||||
this.nudStealth.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -585,7 +588,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudStealth.SelectedText = "";
|
||||
this.nudStealth.SelectionLength = 0;
|
||||
this.nudStealth.SelectionStart = 0;
|
||||
this.nudStealth.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudStealth.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudStealth.TabIndex = 35;
|
||||
//
|
||||
// nudTeleport
|
||||
@ -597,7 +600,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudTeleport.IntValue = 0;
|
||||
this.nudTeleport.Location = new System.Drawing.Point(143, 342);
|
||||
this.nudTeleport.Location = new System.Drawing.Point(193, 342);
|
||||
this.nudTeleport.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -607,7 +610,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudTeleport.SelectedText = "";
|
||||
this.nudTeleport.SelectionLength = 0;
|
||||
this.nudTeleport.SelectionStart = 0;
|
||||
this.nudTeleport.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudTeleport.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudTeleport.TabIndex = 35;
|
||||
//
|
||||
// nudKill
|
||||
@ -619,7 +622,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudKill.IntValue = 0;
|
||||
this.nudKill.Location = new System.Drawing.Point(143, 368);
|
||||
this.nudKill.Location = new System.Drawing.Point(193, 368);
|
||||
this.nudKill.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -629,7 +632,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudKill.SelectedText = "";
|
||||
this.nudKill.SelectionLength = 0;
|
||||
this.nudKill.SelectionStart = 0;
|
||||
this.nudKill.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudKill.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudKill.TabIndex = 35;
|
||||
//
|
||||
// nudUncloakAll
|
||||
@ -641,7 +644,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudUncloakAll.IntValue = 0;
|
||||
this.nudUncloakAll.Location = new System.Drawing.Point(143, 394);
|
||||
this.nudUncloakAll.Location = new System.Drawing.Point(193, 394);
|
||||
this.nudUncloakAll.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -651,7 +654,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudUncloakAll.SelectedText = "";
|
||||
this.nudUncloakAll.SelectionLength = 0;
|
||||
this.nudUncloakAll.SelectionStart = 0;
|
||||
this.nudUncloakAll.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudUncloakAll.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudUncloakAll.TabIndex = 35;
|
||||
//
|
||||
// nudReshroud
|
||||
@ -663,7 +666,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudReshroud.IntValue = 0;
|
||||
this.nudReshroud.Location = new System.Drawing.Point(143, 420);
|
||||
this.nudReshroud.Location = new System.Drawing.Point(193, 420);
|
||||
this.nudReshroud.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -673,7 +676,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudReshroud.SelectedText = "";
|
||||
this.nudReshroud.SelectionLength = 0;
|
||||
this.nudReshroud.SelectionStart = 0;
|
||||
this.nudReshroud.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudReshroud.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudReshroud.TabIndex = 35;
|
||||
//
|
||||
// nudUnshroud
|
||||
@ -685,7 +688,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudUnshroud.IntValue = 0;
|
||||
this.nudUnshroud.Location = new System.Drawing.Point(143, 446);
|
||||
this.nudUnshroud.Location = new System.Drawing.Point(193, 446);
|
||||
this.nudUnshroud.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -695,7 +698,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudUnshroud.SelectedText = "";
|
||||
this.nudUnshroud.SelectionLength = 0;
|
||||
this.nudUnshroud.SelectionStart = 0;
|
||||
this.nudUnshroud.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudUnshroud.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudUnshroud.TabIndex = 35;
|
||||
//
|
||||
// nudRadar
|
||||
@ -707,7 +710,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudRadar.IntValue = 0;
|
||||
this.nudRadar.Location = new System.Drawing.Point(143, 472);
|
||||
this.nudRadar.Location = new System.Drawing.Point(193, 472);
|
||||
this.nudRadar.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -717,7 +720,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudRadar.SelectedText = "";
|
||||
this.nudRadar.SelectionLength = 0;
|
||||
this.nudRadar.SelectionStart = 0;
|
||||
this.nudRadar.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudRadar.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudRadar.TabIndex = 35;
|
||||
//
|
||||
// nudArmageddon
|
||||
@ -729,7 +732,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudArmageddon.IntValue = 0;
|
||||
this.nudArmageddon.Location = new System.Drawing.Point(143, 498);
|
||||
this.nudArmageddon.Location = new System.Drawing.Point(193, 498);
|
||||
this.nudArmageddon.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -739,7 +742,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudArmageddon.SelectedText = "";
|
||||
this.nudArmageddon.SelectionLength = 0;
|
||||
this.nudArmageddon.SelectionStart = 0;
|
||||
this.nudArmageddon.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudArmageddon.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudArmageddon.TabIndex = 35;
|
||||
//
|
||||
// nudSuper
|
||||
@ -751,7 +754,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudSuper.IntValue = 0;
|
||||
this.nudSuper.Location = new System.Drawing.Point(143, 524);
|
||||
this.nudSuper.Location = new System.Drawing.Point(193, 524);
|
||||
this.nudSuper.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -761,7 +764,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudSuper.SelectedText = "";
|
||||
this.nudSuper.SelectionLength = 0;
|
||||
this.nudSuper.SelectionStart = 0;
|
||||
this.nudSuper.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudSuper.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudSuper.TabIndex = 35;
|
||||
//
|
||||
// nudDensity
|
||||
@ -773,7 +776,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudDensity.IntValue = 0;
|
||||
this.nudDensity.Location = new System.Drawing.Point(143, 29);
|
||||
this.nudDensity.Location = new System.Drawing.Point(193, 29);
|
||||
this.nudDensity.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -783,7 +786,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudDensity.SelectedText = "";
|
||||
this.nudDensity.SelectionLength = 0;
|
||||
this.nudDensity.SelectionStart = 0;
|
||||
this.nudDensity.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudDensity.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudDensity.TabIndex = 35;
|
||||
//
|
||||
// nudIonFactor
|
||||
@ -795,7 +798,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudIonFactor.IntValue = 0;
|
||||
this.nudIonFactor.Location = new System.Drawing.Point(143, 55);
|
||||
this.nudIonFactor.Location = new System.Drawing.Point(193, 55);
|
||||
this.nudIonFactor.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -805,7 +808,7 @@ namespace MobiusEditor.Controls
|
||||
this.nudIonFactor.SelectedText = "";
|
||||
this.nudIonFactor.SelectionLength = 0;
|
||||
this.nudIonFactor.SelectionStart = 0;
|
||||
this.nudIonFactor.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudIonFactor.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudIonFactor.TabIndex = 35;
|
||||
//
|
||||
// nudCrateTimer
|
||||
@ -817,7 +820,7 @@ namespace MobiusEditor.Controls
|
||||
0,
|
||||
0});
|
||||
this.nudCrateTimer.IntValue = 0;
|
||||
this.nudCrateTimer.Location = new System.Drawing.Point(143, 81);
|
||||
this.nudCrateTimer.Location = new System.Drawing.Point(193, 81);
|
||||
this.nudCrateTimer.Maximum = new decimal(new int[] {
|
||||
2147483647,
|
||||
0,
|
||||
@ -827,18 +830,40 @@ namespace MobiusEditor.Controls
|
||||
this.nudCrateTimer.SelectedText = "";
|
||||
this.nudCrateTimer.SelectionLength = 0;
|
||||
this.nudCrateTimer.SelectionStart = 0;
|
||||
this.nudCrateTimer.Size = new System.Drawing.Size(194, 20);
|
||||
this.nudCrateTimer.Size = new System.Drawing.Size(267, 20);
|
||||
this.nudCrateTimer.TabIndex = 35;
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.panel1.AutoScroll = true;
|
||||
this.panel1.Controls.Add(this.tableLayoutPanel1);
|
||||
this.panel1.Location = new System.Drawing.Point(0, 4);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(485, 526);
|
||||
this.panel1.TabIndex = 2;
|
||||
//
|
||||
// btnDefaults
|
||||
//
|
||||
this.btnDefaults.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnDefaults.Location = new System.Drawing.Point(365, 536);
|
||||
this.btnDefaults.Name = "btnDefaults";
|
||||
this.btnDefaults.Size = new System.Drawing.Size(117, 23);
|
||||
this.btnDefaults.TabIndex = 3;
|
||||
this.btnDefaults.Text = "Reset to defaults";
|
||||
this.btnDefaults.UseVisualStyleBackColor = true;
|
||||
this.btnDefaults.Click += new System.EventHandler(this.btnDefaults_Click);
|
||||
//
|
||||
// CrateSettings
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.AutoScroll = true;
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.Controls.Add(this.btnDefaults);
|
||||
this.Controls.Add(this.panel1);
|
||||
this.Name = "CrateSettings";
|
||||
this.Size = new System.Drawing.Size(400, 645);
|
||||
this.Load += new System.EventHandler(this.CrateSettings_Load);
|
||||
this.Size = new System.Drawing.Size(485, 565);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudAddStrength)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudAddWeapon)).EndInit();
|
||||
@ -859,8 +884,9 @@ namespace MobiusEditor.Controls
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudDensity)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudIonFactor)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudCrateTimer)).EndInit();
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
@ -907,5 +933,7 @@ namespace MobiusEditor.Controls
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.Button btnDefaults;
|
||||
}
|
||||
}
|
||||
|
@ -7,45 +7,76 @@ namespace MobiusEditor.Controls
|
||||
{
|
||||
public partial class CrateSettings : UserControl
|
||||
{
|
||||
private PropertyTracker<SoleSurvivor.CratesSection> cratesSettings;
|
||||
|
||||
public CrateSettings(PropertyTracker<SoleSurvivor.CratesSection> cratesSection)
|
||||
{
|
||||
this.cratesSettings = cratesSection;
|
||||
InitializeComponent();
|
||||
nudAddStrength.DataBindings.Add("IntValue", cratesSection, "AddStrength");
|
||||
nudAddWeapon.DataBindings.Add("IntValue", cratesSection, "AddWeapon");
|
||||
nudAddSpeed.DataBindings.Add("IntValue", cratesSection, "AddSpeed");
|
||||
nudRapidReload.DataBindings.Add("IntValue", cratesSection, "RapidReload");
|
||||
nudAddRange.DataBindings.Add("IntValue", cratesSection, "AddRange");
|
||||
nudHeal.DataBindings.Add("IntValue", cratesSection, "Heal");
|
||||
nudBomb.DataBindings.Add("IntValue", cratesSection, "Bomb");
|
||||
nudStealth.DataBindings.Add("IntValue", cratesSection, "Stealth");
|
||||
nudTeleport.DataBindings.Add("IntValue", cratesSection, "Teleport");
|
||||
nudKill.DataBindings.Add("IntValue", cratesSection, "Kill");
|
||||
nudUncloakAll.DataBindings.Add("IntValue", cratesSection, "UncloakAll");
|
||||
nudReshroud.DataBindings.Add("IntValue", cratesSection, "Reshroud");
|
||||
nudUnshroud.DataBindings.Add("IntValue", cratesSection, "Unshroud");
|
||||
nudRadar.DataBindings.Add("IntValue", cratesSection, "Radar");
|
||||
nudArmageddon.DataBindings.Add("IntValue", cratesSection, "Armageddon");
|
||||
nudSuper.DataBindings.Add("IntValue", cratesSection, "Super");
|
||||
nudDensity.DataBindings.Add("IntValue", cratesSection, "Density");
|
||||
nudIonFactor.DataBindings.Add("IntValue", cratesSection, "IonFactor");
|
||||
nudCrateTimer.DataBindings.Add("IntValue", cratesSection, "CrateTimer");
|
||||
AddDataBindings();
|
||||
}
|
||||
|
||||
private void CrateSettings_Load(Object sender, EventArgs e)
|
||||
private void btnDefaults_Click(Object sender, EventArgs e)
|
||||
{
|
||||
AdjustPanelSize(this, tableLayoutPanel1);
|
||||
}
|
||||
|
||||
private void AdjustPanelSize(ScrollableControl panel, TableLayoutPanel tableLayoutPanel)
|
||||
{
|
||||
int maxX = 0;
|
||||
int maxY = 0;
|
||||
foreach (Control c in tableLayoutPanel.Controls)
|
||||
if (DialogResult.Yes == MessageBox.Show("This will reset all crate values to their game defaults. Are you sure you want to continue?", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1))
|
||||
{
|
||||
maxX = Math.Max(maxX, c.Location.X + c.Width);
|
||||
maxY = Math.Max(maxY, c.Location.Y + c.Height);
|
||||
ResetToDefaultValues();
|
||||
}
|
||||
panel.AutoScrollMinSize = new Size(maxX, maxY);
|
||||
}
|
||||
|
||||
private void ResetToDefaultValues()
|
||||
{
|
||||
RemoveDataBindings();
|
||||
SoleSurvivor.CratesSection cratesSection = new SoleSurvivor.CratesSection();
|
||||
cratesSection.SetDefault();
|
||||
cratesSettings.SetValues(cratesSection);
|
||||
AddDataBindings();
|
||||
}
|
||||
|
||||
private void AddDataBindings()
|
||||
{
|
||||
nudAddStrength.DataBindings.Add("IntValue", cratesSettings, "AddStrength");
|
||||
nudAddWeapon.DataBindings.Add("IntValue", cratesSettings, "AddWeapon");
|
||||
nudAddSpeed.DataBindings.Add("IntValue", cratesSettings, "AddSpeed");
|
||||
nudRapidReload.DataBindings.Add("IntValue", cratesSettings, "RapidReload");
|
||||
nudAddRange.DataBindings.Add("IntValue", cratesSettings, "AddRange");
|
||||
nudHeal.DataBindings.Add("IntValue", cratesSettings, "Heal");
|
||||
nudBomb.DataBindings.Add("IntValue", cratesSettings, "Bomb");
|
||||
nudStealth.DataBindings.Add("IntValue", cratesSettings, "Stealth");
|
||||
nudTeleport.DataBindings.Add("IntValue", cratesSettings, "Teleport");
|
||||
nudKill.DataBindings.Add("IntValue", cratesSettings, "Kill");
|
||||
nudUncloakAll.DataBindings.Add("IntValue", cratesSettings, "UncloakAll");
|
||||
nudReshroud.DataBindings.Add("IntValue", cratesSettings, "Reshroud");
|
||||
nudUnshroud.DataBindings.Add("IntValue", cratesSettings, "Unshroud");
|
||||
nudRadar.DataBindings.Add("IntValue", cratesSettings, "Radar");
|
||||
nudArmageddon.DataBindings.Add("IntValue", cratesSettings, "Armageddon");
|
||||
nudSuper.DataBindings.Add("IntValue", cratesSettings, "Super");
|
||||
nudDensity.DataBindings.Add("IntValue", cratesSettings, "Density");
|
||||
nudIonFactor.DataBindings.Add("IntValue", cratesSettings, "IonFactor");
|
||||
nudCrateTimer.DataBindings.Add("IntValue", cratesSettings, "CrateTimer");
|
||||
}
|
||||
|
||||
private void RemoveDataBindings()
|
||||
{
|
||||
nudAddStrength.DataBindings.Clear();
|
||||
nudAddWeapon.DataBindings.Clear();
|
||||
nudAddSpeed.DataBindings.Clear();
|
||||
nudRapidReload.DataBindings.Clear();
|
||||
nudAddRange.DataBindings.Clear();
|
||||
nudHeal.DataBindings.Clear();
|
||||
nudBomb.DataBindings.Clear();
|
||||
nudStealth.DataBindings.Clear();
|
||||
nudTeleport.DataBindings.Clear();
|
||||
nudKill.DataBindings.Clear();
|
||||
nudUncloakAll.DataBindings.Clear();
|
||||
nudReshroud.DataBindings.Clear();
|
||||
nudUnshroud.DataBindings.Clear();
|
||||
nudRadar.DataBindings.Clear();
|
||||
nudArmageddon.DataBindings.Clear();
|
||||
nudSuper.DataBindings.Clear();
|
||||
nudDensity.DataBindings.Clear();
|
||||
nudIonFactor.DataBindings.Clear();
|
||||
nudCrateTimer.DataBindings.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,15 +120,17 @@ namespace MobiusEditor.Controls
|
||||
string[] filteredEvents;
|
||||
string[] filteredActions;
|
||||
Boolean isAircraft = obj is Unit un && un.Type.IsAircraft;
|
||||
Boolean isOnMap = true;
|
||||
switch (obj)
|
||||
{
|
||||
case Infantry infantry:
|
||||
case Unit unit:
|
||||
items = Plugin.Map.FilterUnitTriggers().Select(t => t.Name).Distinct().ToArray();
|
||||
filteredEvents = isAircraft ? new string[0] : Plugin.Map.EventTypes.Where(ev => Plugin.Map.UnitEventTypes.Contains(ev)).Distinct().ToArray();
|
||||
filteredActions = isAircraft ? new string[0] : Plugin.Map.ActionTypes.Where(ac => Plugin.Map.UnitActionTypes.Contains(ac)).Distinct().ToArray();
|
||||
filteredEvents = Plugin.Map.EventTypes.Where(ev => Plugin.Map.UnitEventTypes.Contains(ev)).Distinct().ToArray();
|
||||
filteredActions = Plugin.Map.ActionTypes.Where(ac => Plugin.Map.UnitActionTypes.Contains(ac)).Distinct().ToArray();
|
||||
break;
|
||||
case Building building:
|
||||
isOnMap = building.IsPrebuilt;
|
||||
items = Plugin.Map.FilterStructureTriggers().Select(t => t.Name).Distinct().ToArray();
|
||||
filteredEvents = Plugin.Map.EventTypes.Where(ac => Plugin.Map.StructureEventTypes.Contains(ac)).Distinct().ToArray();
|
||||
filteredActions = Plugin.Map.ActionTypes.Where(ac => Plugin.Map.StructureActionTypes.Contains(ac)).Distinct().ToArray();
|
||||
@ -143,7 +145,7 @@ namespace MobiusEditor.Controls
|
||||
items = Trigger.None.Yield().Concat(Plugin.Map.Triggers.Select(t => t.Name).Where(t => allowedTriggers.Contains(t)).Distinct()).ToArray();
|
||||
int selectIndex = selected == null ? 0 : Enumerable.Range(0, items.Length).FirstOrDefault(x => String.Equals(items[x], selected, StringComparison.InvariantCultureIgnoreCase));
|
||||
triggerComboBox.DataSource = items;
|
||||
triggerComboBox.Enabled = !isAircraft;
|
||||
triggerComboBox.Enabled = !isAircraft && isOnMap;
|
||||
triggerToolTip = Map.MakeAllowedTriggersToolTip(filteredEvents, filteredActions);
|
||||
if (obj != null)
|
||||
{
|
||||
@ -163,12 +165,10 @@ namespace MobiusEditor.Controls
|
||||
prebuiltCheckBox.DataBindings.Clear();
|
||||
sellableCheckBox.DataBindings.Clear();
|
||||
rebuildCheckBox.DataBindings.Clear();
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (obj)
|
||||
{
|
||||
case Infantry infantry:
|
||||
@ -177,7 +177,6 @@ namespace MobiusEditor.Controls
|
||||
directionComboBox.DataSource = Plugin.Map.DirectionTypes
|
||||
.Where(t => t.Facing != FacingType.None)
|
||||
.Select(t => new TypeItem<DirectionType>(t.Name, t)).ToArray();
|
||||
|
||||
missionComboBox.DataBindings.Add("SelectedItem", obj, "Mission");
|
||||
missionLabel.Visible = missionComboBox.Visible = true;
|
||||
basePriorityLabel.Visible = basePriorityNud.Visible = false;
|
||||
@ -243,7 +242,6 @@ namespace MobiusEditor.Controls
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
houseComboBox.DataBindings.Add("SelectedValue", obj, "House");
|
||||
strengthNud.DataBindings.Add("Value", obj, "Strength");
|
||||
directionComboBox.DataBindings.Add("SelectedValue", obj, "Direction");
|
||||
|
@ -46,6 +46,7 @@ namespace MobiusEditor.Controls
|
||||
switch (plugin.GameType)
|
||||
{
|
||||
case GameType.TiberianDawn:
|
||||
case GameType.SoleSurvivor:
|
||||
maxInfantryNud.Visible = maxInfantryLbl.Visible = false;
|
||||
maxVesselsNud.Visible = maxVesselsLbl.Visible = false;
|
||||
techLevelNud.Visible = techLevelLbl.Visible = false;
|
||||
|
@ -587,6 +587,7 @@ namespace MobiusEditor.Dialogs
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudInitNum.IntValue = 0;
|
||||
this.nudInitNum.Location = new System.Drawing.Point(85, 198);
|
||||
this.nudInitNum.Margin = new System.Windows.Forms.Padding(2);
|
||||
this.nudInitNum.Maximum = new decimal(new int[] {
|
||||
@ -610,6 +611,7 @@ namespace MobiusEditor.Dialogs
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.maxAllowedNud.IntValue = 0;
|
||||
this.maxAllowedNud.Location = new System.Drawing.Point(85, 222);
|
||||
this.maxAllowedNud.Margin = new System.Windows.Forms.Padding(2);
|
||||
this.maxAllowedNud.Maximum = new decimal(new int[] {
|
||||
@ -633,6 +635,7 @@ namespace MobiusEditor.Dialogs
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudFear.IntValue = 0;
|
||||
this.nudFear.Location = new System.Drawing.Point(85, 246);
|
||||
this.nudFear.Margin = new System.Windows.Forms.Padding(2);
|
||||
this.nudFear.Maximum = new decimal(new int[] {
|
||||
@ -716,6 +719,7 @@ namespace MobiusEditor.Dialogs
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudRecruitPriority.IntValue = 0;
|
||||
this.nudRecruitPriority.Location = new System.Drawing.Point(85, 174);
|
||||
this.nudRecruitPriority.Margin = new System.Windows.Forms.Padding(2);
|
||||
this.nudRecruitPriority.Maximum = new decimal(new int[] {
|
||||
|
@ -32,6 +32,7 @@ namespace MobiusEditor.Dialogs
|
||||
private Bitmap infoImage;
|
||||
private string triggerToolTip;
|
||||
|
||||
private const int maxLength = 8;
|
||||
private readonly IGamePlugin plugin;
|
||||
private readonly int maxTeams;
|
||||
private readonly IEnumerable<ITechnoType> technoTypes;
|
||||
@ -394,17 +395,6 @@ namespace MobiusEditor.Dialogs
|
||||
|
||||
private void TeamTypesListView_AfterLabelEdit(object sender, LabelEditEventArgs e)
|
||||
{
|
||||
int maxLength = int.MaxValue;
|
||||
switch (plugin.GameType)
|
||||
{
|
||||
case GameType.TiberianDawn:
|
||||
case GameType.SoleSurvivor:
|
||||
maxLength = 8;
|
||||
break;
|
||||
case GameType.RedAlert:
|
||||
maxLength = 23;
|
||||
break;
|
||||
}
|
||||
String curName = e.Label;
|
||||
if (string.IsNullOrEmpty(curName))
|
||||
{
|
||||
|
@ -25,6 +25,7 @@ namespace MobiusEditor.Dialogs
|
||||
{
|
||||
public partial class TriggersDialog : Form
|
||||
{
|
||||
private const int maxLength = 4;
|
||||
private readonly IGamePlugin plugin;
|
||||
private readonly int maxTriggers;
|
||||
|
||||
@ -311,17 +312,6 @@ namespace MobiusEditor.Dialogs
|
||||
|
||||
private void triggersListView_AfterLabelEdit(object sender, LabelEditEventArgs e)
|
||||
{
|
||||
int maxLength = int.MaxValue;
|
||||
switch (plugin.GameType)
|
||||
{
|
||||
case GameType.TiberianDawn:
|
||||
case GameType.SoleSurvivor:
|
||||
maxLength = 4;
|
||||
break;
|
||||
case GameType.RedAlert:
|
||||
maxLength = 23;
|
||||
break;
|
||||
}
|
||||
String curName = e.Label;
|
||||
if (string.IsNullOrEmpty(curName))
|
||||
{
|
||||
|
@ -306,12 +306,7 @@ namespace MobiusEditor
|
||||
string[] modPaths = null;
|
||||
if (ModPaths != null)
|
||||
{
|
||||
GameType modGameType = nmd.GameType;
|
||||
if (modGameType == GameType.SoleSurvivor)
|
||||
{
|
||||
modGameType = GameType.TiberianDawn;
|
||||
}
|
||||
ModPaths.TryGetValue(modGameType, out modPaths);
|
||||
ModPaths.TryGetValue(nmd.GameType, out modPaths);
|
||||
}
|
||||
Globals.TheTextureManager.ExpandModPaths = modPaths;
|
||||
Globals.TheTextureManager.Reset();
|
||||
@ -896,11 +891,7 @@ namespace MobiusEditor
|
||||
{
|
||||
case FileType.INI:
|
||||
{
|
||||
gameType = File.Exists(Path.ChangeExtension(loadFilename, ".bin")) ? GameType.TiberianDawn : GameType.RedAlert;
|
||||
if (gameType == GameType.RedAlert && !RedAlert.GamePlugin.CheckForRAMap(loadFilename, fileType))
|
||||
{
|
||||
gameType = GameType.TiberianDawn;
|
||||
}
|
||||
gameType = RedAlert.GamePlugin.CheckForRAMap(loadFilename, fileType) ? GameType.RedAlert : GameType.TiberianDawn;
|
||||
break;
|
||||
}
|
||||
case FileType.BIN:
|
||||
@ -933,9 +924,11 @@ namespace MobiusEditor
|
||||
}
|
||||
#endif
|
||||
}
|
||||
bool isTdMegaMap = false;
|
||||
if (gameType == GameType.TiberianDawn)
|
||||
{
|
||||
if (SoleSurvivor.GamePlugin.CheckForSSmap(loadFilename, fileType))
|
||||
isTdMegaMap = TiberianDawn.GamePlugin.CheckForMegamap(loadFilename, fileType);
|
||||
if (isTdMegaMap && SoleSurvivor.GamePlugin.CheckForSSmap(loadFilename, fileType))
|
||||
{
|
||||
gameType = GameType.SoleSurvivor;
|
||||
}
|
||||
@ -953,12 +946,7 @@ namespace MobiusEditor
|
||||
string[] modPaths = null;
|
||||
if (ModPaths != null)
|
||||
{
|
||||
GameType modGameType = gameType;
|
||||
if (modGameType == GameType.SoleSurvivor)
|
||||
{
|
||||
modGameType = GameType.TiberianDawn;
|
||||
}
|
||||
ModPaths.TryGetValue(modGameType, out modPaths);
|
||||
ModPaths.TryGetValue(gameType, out modPaths);
|
||||
}
|
||||
Globals.TheTextureManager.ExpandModPaths = modPaths;
|
||||
Globals.TheTextureManager.Reset();
|
||||
@ -968,19 +956,14 @@ namespace MobiusEditor
|
||||
switch (gameType)
|
||||
{
|
||||
case GameType.TiberianDawn:
|
||||
{
|
||||
Globals.TheTeamColorManager.Reset();
|
||||
Globals.TheTeamColorManager.Load(@"DATA\XML\CNCTDTEAMCOLORS.XML");
|
||||
bool isMegaMap = TiberianDawn.GamePlugin.CheckForMegamap(loadFilename, fileType);
|
||||
plugin = new TiberianDawn.GamePlugin(isMegaMap, this);
|
||||
}
|
||||
Globals.TheTeamColorManager.Reset();
|
||||
Globals.TheTeamColorManager.Load(@"DATA\XML\CNCTDTEAMCOLORS.XML");
|
||||
plugin = new TiberianDawn.GamePlugin(isTdMegaMap, this);
|
||||
break;
|
||||
case GameType.RedAlert:
|
||||
{
|
||||
Globals.TheTeamColorManager.Reset();
|
||||
Globals.TheTeamColorManager.Load(@"DATA\XML\CNCRATEAMCOLORS.XML");
|
||||
plugin = new RedAlert.GamePlugin(this);
|
||||
}
|
||||
Globals.TheTeamColorManager.Reset();
|
||||
Globals.TheTeamColorManager.Load(@"DATA\XML\CNCRATEAMCOLORS.XML");
|
||||
plugin = new RedAlert.GamePlugin(this);
|
||||
break;
|
||||
case GameType.SoleSurvivor:
|
||||
Globals.TheTeamColorManager.Reset();
|
||||
@ -1688,11 +1671,6 @@ namespace MobiusEditor
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!SteamworksUGC.IsInit)
|
||||
{
|
||||
MessageBox.Show("Steam interface is not initialized. To enable Workshop publishing, log into Steam and restart the editor.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
if (plugin.GameType == GameType.SoleSurvivor)
|
||||
{
|
||||
MessageBox.Show("Sole Survivor maps cannot be published to Steam; they are not usable by the C&C Remastered Collection.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
@ -1707,6 +1685,11 @@ namespace MobiusEditor
|
||||
MessageBox.Show("Tiberian Dawn megamaps cannot be published to Steam; they are not usable by the C&C Remastered Collection without modding, and may cause issues on the official servers.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
if (!SteamworksUGC.IsInit)
|
||||
{
|
||||
MessageBox.Show("Steam interface is not initialized. To enable Workshop publishing, log into Steam and restart the editor.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
if (!PromptSaveMap())
|
||||
{
|
||||
return;
|
||||
|
@ -1070,7 +1070,7 @@ namespace MobiusEditor.Model
|
||||
{
|
||||
continue;
|
||||
}
|
||||
MapLayerFlag layer = MapLayerFlag.None;
|
||||
MapLayerFlag layer;
|
||||
if (overlay.Type.IsResource)
|
||||
{
|
||||
layer = MapLayerFlag.Resources;
|
||||
|
@ -14,6 +14,7 @@
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MobiusEditor.Model
|
||||
{
|
||||
@ -29,7 +30,7 @@ namespace MobiusEditor.Model
|
||||
{
|
||||
ID = id;
|
||||
Name = name;
|
||||
Tilesets = tilesets;
|
||||
Tilesets = tilesets.Distinct();
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
|
@ -117,7 +117,16 @@ namespace MobiusEditor
|
||||
}
|
||||
#endif
|
||||
// Check if any mods are allowed to override the default stuff to load.
|
||||
Dictionary<GameType, string[]> modPaths = GetModPaths(gameId, Properties.Settings.Default.ModsToLoad);
|
||||
Dictionary<GameType, string> pathsToLoad = new Dictionary<GameType, string>();
|
||||
pathsToLoad.Add(GameType.TiberianDawn, Properties.Settings.Default.ModsToLoadTD);
|
||||
pathsToLoad.Add(GameType.RedAlert, Properties.Settings.Default.ModsToLoadRA);
|
||||
pathsToLoad.Add(GameType.SoleSurvivor, Properties.Settings.Default.ModsToLoadSS);
|
||||
Dictionary<GameType, string[]> modPaths = new Dictionary<GameType, string[]>();
|
||||
const string tdModFolder = "Tiberian_Dawn";
|
||||
const string raModFolder = "Red_Alert";
|
||||
modPaths.Add(GameType.TiberianDawn, GetModPaths(gameId, Properties.Settings.Default.ModsToLoadTD, tdModFolder, "TD"));
|
||||
modPaths.Add(GameType.RedAlert, GetModPaths(gameId, Properties.Settings.Default.ModsToLoadRA, raModFolder, "RA"));
|
||||
modPaths.Add(GameType.SoleSurvivor, GetModPaths(gameId, Properties.Settings.Default.ModsToLoadSS, tdModFolder, "TD"));
|
||||
// Initialize texture, tileset, team color, and game text managers
|
||||
Globals.TheTextureManager = new TextureManager(Globals.TheMegafileManager);
|
||||
Globals.TheTilesetManager = new TilesetManager(Globals.TheMegafileManager, Globals.TheTextureManager, Globals.TilesetsXMLPath, Globals.TexturesPath);
|
||||
@ -133,13 +142,8 @@ namespace MobiusEditor
|
||||
// Initialize Steam if this is a Steam build
|
||||
if (SteamworksUGC.IsSteamBuild)
|
||||
{
|
||||
if (!SteamworksUGC.Init())
|
||||
{
|
||||
#if !DEVELOPER
|
||||
//MessageBox.Show("Unable to initialize Steam interface.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
//return;
|
||||
#endif
|
||||
}
|
||||
// Ignore result from this.
|
||||
SteamworksUGC.Init();
|
||||
}
|
||||
if (Properties.Settings.Default.ShowInviteWarning)
|
||||
{
|
||||
@ -174,21 +178,17 @@ namespace MobiusEditor
|
||||
Globals.TheMegafileManager.Dispose();
|
||||
}
|
||||
|
||||
private static Dictionary<GameType, string[]> GetModPaths(string gameId, string modstoLoad)
|
||||
private static string[] GetModPaths(string gameId, string modstoLoad, string modFolder, string modIdentifier)
|
||||
{
|
||||
Regex numbersOnly = new Regex("^\\d+$");
|
||||
Regex modregex = new Regex("\"game_type\"\\s*:\\s*\"((RA)|(TD))\"");
|
||||
const string tdModFolder = "Tiberian_Dawn";
|
||||
const string raModFolder = "Red_Alert";
|
||||
Regex modregex = new Regex("\"game_type\"\\s*:\\s*\""+ modIdentifier + "\"");
|
||||
const string contentFile = "ccmod.json";
|
||||
string modsFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "CnCRemastered", "Mods");
|
||||
string[] steamLibraryFolders = SteamAssist.GetLibraryFoldersForAppId(gameId);
|
||||
string[] mods = (modstoLoad ?? String.Empty).Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
List<string> modPathsRa = new List<string>();
|
||||
List<string> modPathsTd = new List<string>();
|
||||
List<string> modPaths = new List<string>();
|
||||
for (int i = 0; i < mods.Length; ++i)
|
||||
{
|
||||
List<string> modList;
|
||||
string modDef = mods[i].Trim();
|
||||
if (String.IsNullOrEmpty(modDef))
|
||||
{
|
||||
@ -201,48 +201,22 @@ namespace MobiusEditor
|
||||
addonModPath = SteamAssist.TryGetSteamModFolder(gameId, modDef, null, contentFile); // addonModName);
|
||||
if (addonModPath != null)
|
||||
{
|
||||
switch (CheckAddonPathModType(addonModPath, contentFile, modregex, 1))
|
||||
if (CheckAddonPathModType(addonModPath, contentFile, modregex))
|
||||
{
|
||||
case "TD":
|
||||
modList = modPathsTd;
|
||||
break;
|
||||
case "RA":
|
||||
modList = modPathsRa;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
modList.Add(addonModPath);
|
||||
modPaths.Add(addonModPath);
|
||||
}
|
||||
}
|
||||
// don't bother checking more on a numbers-only entry.
|
||||
continue;
|
||||
}
|
||||
// Lookup by folder name
|
||||
bool isTDMod = modDef.StartsWith(tdModFolder, StringComparison.OrdinalIgnoreCase);
|
||||
bool isRAMod = modDef.StartsWith(raModFolder, StringComparison.OrdinalIgnoreCase);
|
||||
if (!isTDMod && !isRAMod)
|
||||
addonModPath = Path.Combine(modsFolder, modFolder, modDef);
|
||||
if (CheckAddonPathModType(addonModPath, contentFile, modregex))
|
||||
{
|
||||
modPaths.Add(addonModPath);
|
||||
// Found in local mods; don't check Steam ones.
|
||||
continue;
|
||||
}
|
||||
String expectedModType = isTDMod ? "TD" : "RA";
|
||||
modList = isTDMod ? modPathsTd : modPathsRa;
|
||||
string actualModFolder = modDef.Substring(isTDMod ? tdModFolder.Length : raModFolder.Length);
|
||||
// check if the trimmed-off part was indeed the whole folder name.
|
||||
if (!actualModFolder.StartsWith("\\") && !actualModFolder.StartsWith("/"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
actualModFolder = actualModFolder.Trim('\\', '/');
|
||||
// C&C Remastered mods can only be one path deep.
|
||||
if (actualModFolder.Contains('\\') || actualModFolder.Contains('/'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
addonModPath = Path.Combine(modsFolder, modDef);
|
||||
if (CheckAddonPathModType(addonModPath, contentFile, modregex, 1) == expectedModType)
|
||||
{
|
||||
modList.Add(addonModPath);
|
||||
}
|
||||
// try to find mod in steam library.
|
||||
foreach (string libFolder in steamLibraryFolders)
|
||||
{
|
||||
@ -251,39 +225,35 @@ namespace MobiusEditor
|
||||
{
|
||||
continue;
|
||||
}
|
||||
foreach (string modFolder in Directory.GetDirectories(modPath))
|
||||
foreach (string modPth in Directory.GetDirectories(modPath))
|
||||
{
|
||||
addonModPath = Path.Combine(modFolder, actualModFolder);
|
||||
if (CheckAddonPathModType(addonModPath, contentFile, modregex, 1) == expectedModType)
|
||||
addonModPath = Path.Combine(modPth, modDef);
|
||||
if (CheckAddonPathModType(addonModPath, contentFile, modregex))
|
||||
{
|
||||
modList.Add(addonModPath);
|
||||
modPaths.Add(addonModPath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Dictionary<GameType, string[]> finalModPaths = new Dictionary<GameType, string[]>();
|
||||
finalModPaths.Add(GameType.TiberianDawn, modPathsTd.Distinct(StringComparer.CurrentCultureIgnoreCase).ToArray());
|
||||
finalModPaths.Add(GameType.RedAlert, modPathsRa.Distinct(StringComparer.CurrentCultureIgnoreCase).ToArray());
|
||||
return finalModPaths;
|
||||
return modPaths.Distinct(StringComparer.CurrentCultureIgnoreCase).ToArray();
|
||||
}
|
||||
|
||||
private static string CheckAddonPathModType(string addonModPath, string contentFile, Regex modregex, int group)
|
||||
private static bool CheckAddonPathModType(string addonModPath, string contentFile, Regex modregex)
|
||||
{
|
||||
try
|
||||
{
|
||||
string checkPath = Path.Combine(addonModPath, contentFile);
|
||||
if (!File.Exists(checkPath))
|
||||
{
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
string ccModDefContents = File.ReadAllText(checkPath);
|
||||
MatchCollection mc = modregex.Matches(ccModDefContents);
|
||||
return mc.Count == 0 ? null : mc[0].Groups[group].Value;
|
||||
return modregex.IsMatch(ccModDefContents);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
24
CnCTDRAMapEditor/Properties/Settings.Designer.cs
generated
24
CnCTDRAMapEditor/Properties/Settings.Designer.cs
generated
@ -25,10 +25,28 @@ namespace MobiusEditor.Properties {
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("2844969675;Tiberian_Dawn\\ConcretePavementTD")]
|
||||
public string ModsToLoad {
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("2844969675;ConcretePavementTD")]
|
||||
public string ModsToLoadTD {
|
||||
get {
|
||||
return ((string)(this["ModsToLoad"]));
|
||||
return ((string)(this["ModsToLoadTD"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("")]
|
||||
public string ModsToLoadRA {
|
||||
get {
|
||||
return ((string)(this["ModsToLoadRA"]));
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.ApplicationScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("2844969675;ConcretePavementTD")]
|
||||
public string ModsToLoadSS {
|
||||
get {
|
||||
return ((string)(this["ModsToLoadSS"]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,14 @@
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="MobiusEditor.Properties" GeneratedClassName="Settings">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="ModsToLoad" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">2844969675;Tiberian_Dawn\ConcretePavementTD</Value>
|
||||
<Setting Name="ModsToLoadTD" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">2844969675;ConcretePavementTD</Value>
|
||||
</Setting>
|
||||
<Setting Name="ModsToLoadRA" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)" />
|
||||
</Setting>
|
||||
<Setting Name="ModsToLoadSS" Type="System.String" Scope="Application">
|
||||
<Value Profile="(Default)">2844969675;ConcretePavementTD</Value>
|
||||
</Setting>
|
||||
<Setting Name="MapScale" Type="System.Double" Scope="Application">
|
||||
<Value Profile="(Default)">0.5</Value>
|
||||
|
@ -460,7 +460,7 @@ namespace MobiusEditor.RedAlert
|
||||
ini.Parse(reader);
|
||||
}
|
||||
forceSingle = SinglePlayRegex.IsMatch(Path.GetFileNameWithoutExtension(path));
|
||||
errors.AddRange(LoadINI(ini, forceSingle));
|
||||
errors.AddRange(LoadINI(ini, forceSingle, ref modified));
|
||||
}
|
||||
break;
|
||||
case FileType.MEG:
|
||||
@ -478,18 +478,13 @@ namespace MobiusEditor.RedAlert
|
||||
{
|
||||
ini.Parse(reader);
|
||||
}
|
||||
errors.AddRange(LoadINI(ini, false));
|
||||
errors.AddRange(LoadINI(ini, false, ref modified));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("Unsupported filetype.");
|
||||
}
|
||||
if (errors.Count > 0)
|
||||
{
|
||||
// If only one message is inside the errors, and the "force single" boolean is set, the single message is about that.
|
||||
modified = !forceSingle || errors.Count > 1;
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
finally
|
||||
@ -498,7 +493,7 @@ namespace MobiusEditor.RedAlert
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<string> LoadINI(INI ini, bool forceSoloMission)
|
||||
private IEnumerable<string> LoadINI(INI ini, bool forceSoloMission, ref bool modified)
|
||||
{
|
||||
var errors = new List<string>();
|
||||
Map.BeginUpdate();
|
||||
@ -570,6 +565,10 @@ namespace MobiusEditor.RedAlert
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Key.Length > 8)
|
||||
{
|
||||
errors.Add(string.Format("TeamType '{0}' has a name that is longer than 8 characters. This will not be corrected by the loading process, but should be addressed, since it can make the teams fail to read correctly, and might even crash the game.", Key));
|
||||
}
|
||||
var teamType = new TeamType { Name = Key };
|
||||
var tokens = Value.Split(',').ToList();
|
||||
teamType.House = Map.HouseTypes.Where(t => t.Equals(sbyte.Parse(tokens[0]))).FirstOrDefault(); tokens.RemoveAt(0);
|
||||
@ -598,17 +597,20 @@ namespace MobiusEditor.RedAlert
|
||||
{
|
||||
errors.Add(string.Format("Team '{0}' contains expansion unit '{0}', but expansion units not enabled; enabling expansion units.", Key, type.Name));
|
||||
Map.BasicSection.ExpansionEnabled = aftermathEnabled = true;
|
||||
modified = true;
|
||||
}
|
||||
teamType.Classes.Add(new TeamTypeClass { Type = type, Count = count });
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Team '{0}' references unknown class '{1}'.", Key, classTokens[0]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Team '{0}' has wrong number of tokens for class index {1} (expecting 2).", Key, i));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
var numMissions = int.Parse(tokens[0]); tokens.RemoveAt(0);
|
||||
@ -622,6 +624,7 @@ namespace MobiusEditor.RedAlert
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Team '{0}' has wrong number of tokens for mission index {1} (expecting 2).", Key, i));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
teamTypes.Add(teamType);
|
||||
@ -629,10 +632,12 @@ namespace MobiusEditor.RedAlert
|
||||
catch (Exception ex)
|
||||
{
|
||||
errors.Add(string.Format("Teamtype '{0}' has errors and can't be parsed: {1}.", Key, ex.Message));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
var triggersSection = ini.Sections.Extract("Trigs");
|
||||
List<Trigger> triggers = new List<Trigger>();
|
||||
if (triggersSection != null)
|
||||
{
|
||||
foreach (var (Key, Value) in triggersSection)
|
||||
@ -642,6 +647,10 @@ namespace MobiusEditor.RedAlert
|
||||
var tokens = Value.Split(',');
|
||||
if (tokens.Length == 18)
|
||||
{
|
||||
if (Key.Length > 4)
|
||||
{
|
||||
errors.Add(string.Format("Trigger '{0}' has a name that is longer than 4 characters. This will not be corrected by the loading process, but should be addressed, since it can make the triggers fail to read correctly and link to objects and cell triggers, and might even crash the game.", Key));
|
||||
}
|
||||
var trigger = new Trigger { Name = Key };
|
||||
trigger.PersistentType = (TriggerPersistentType)int.Parse(tokens[0]);
|
||||
trigger.House = Map.HouseTypes.Where(t => t.Equals(sbyte.Parse(tokens[1]))).FirstOrDefault()?.Name ?? "None";
|
||||
@ -725,20 +734,22 @@ namespace MobiusEditor.RedAlert
|
||||
fixEvent(trigger.Event2);
|
||||
fixAction(trigger.Action1);
|
||||
fixAction(trigger.Action2);
|
||||
Map.Triggers.Add(trigger);
|
||||
triggers.Add(trigger);
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Trigger '{0}' has too few tokens (expecting 18).", Key));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errors.Add(string.Format("Trigger '{0}' has errors and can't be parsed: {1}.", Key, ex.Message));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
HashSet<string> checkTrigs = Trigger.None.Yield().Concat(Map.Triggers.Select(t => t.Name)).ToHashSet(StringComparer.InvariantCultureIgnoreCase);
|
||||
HashSet<string> checkTrigs = Trigger.None.Yield().Concat(triggers.Select(t => t.Name)).ToHashSet(StringComparer.InvariantCultureIgnoreCase);
|
||||
HashSet<string> checkCellTrigs = Map.FilterCellTriggers().Select(t => t.Name).ToHashSet(StringComparer.InvariantCultureIgnoreCase);
|
||||
HashSet<string> checkUnitTrigs = Trigger.None.Yield().Concat(Map.FilterUnitTriggers().Select(t => t.Name)).ToHashSet(StringComparer.InvariantCultureIgnoreCase);
|
||||
HashSet<string> checkStrcTrigs = Trigger.None.Yield().Concat(Map.FilterStructureTriggers().Select(t => t.Name)).ToHashSet(StringComparer.InvariantCultureIgnoreCase);
|
||||
@ -768,6 +779,7 @@ namespace MobiusEditor.RedAlert
|
||||
if (templateType == null && typeValue != 0xFFFF)
|
||||
{
|
||||
errors.Add(String.Format("Unknown template value {0:X4} at cell [{1},{2}]; clearing.", typeValue, x, y));
|
||||
modified = true;
|
||||
}
|
||||
else if (templateType != null)
|
||||
{
|
||||
@ -785,6 +797,7 @@ namespace MobiusEditor.RedAlert
|
||||
if (!clearedOldClear)
|
||||
{
|
||||
errors.Add(String.Format("Use of obsolete version of 'Clear' terrain detected; clearing."));
|
||||
modified = true;
|
||||
clearedOldClear = true;
|
||||
}
|
||||
templateType = null;
|
||||
@ -793,6 +806,7 @@ namespace MobiusEditor.RedAlert
|
||||
else
|
||||
{
|
||||
errors.Add(String.Format("Template '{0}' at cell [{1},{2}] is not available in the set theater; clearing.", templateType.Name.ToUpper(), x, y));
|
||||
modified = true;
|
||||
templateType = null;
|
||||
}
|
||||
}
|
||||
@ -820,6 +834,7 @@ namespace MobiusEditor.RedAlert
|
||||
{
|
||||
// This is an old map. Clear any 255 tile.
|
||||
errors.Add(String.Format("Use of obsolete version of 'Clear' terrain detected; clearing."));
|
||||
modified = true;
|
||||
for (var y = 0; y < height; ++y)
|
||||
{
|
||||
for (var x = 0; x < width; ++x)
|
||||
@ -848,10 +863,12 @@ namespace MobiusEditor.RedAlert
|
||||
if (iconValue >= templateType.NumIcons)
|
||||
{
|
||||
errors.Add(String.Format("Template '{0}' at cell [{1},{2}] has an icon set ({3}) that is outside its icons range; clearing.", templateType.Name.ToUpper(), x, y, iconValue));
|
||||
modified = true;
|
||||
}
|
||||
else if (!isRandom && templateType.IconMask != null && !templateType.IconMask[iconValue / templateType.IconWidth, iconValue % templateType.IconWidth])
|
||||
{
|
||||
errors.Add(String.Format("Template '{0}' at cell [{1},{2}] has an icon set ({3}) that is not part of its placeable cells; clearing.", templateType.Name.ToUpper(), x, y, iconValue));
|
||||
modified = true;
|
||||
}
|
||||
else if (templateType != TemplateTypes.Clear)
|
||||
{
|
||||
@ -880,6 +897,7 @@ namespace MobiusEditor.RedAlert
|
||||
if (!int.TryParse(Key, out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for terrain cannot be parsed. Key: '{0}', value: '{1}'; skipping.", Key, Value));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var name = Value.Split(',')[0];
|
||||
@ -889,6 +907,7 @@ namespace MobiusEditor.RedAlert
|
||||
if (Globals.FilterTheaterObjects && terrainType.Theaters != null && !terrainType.Theaters.Contains(Map.Theater))
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' is not available in the set theater; skipping.", terrainType.Name));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
Terrain newTerr = new Terrain
|
||||
@ -901,43 +920,51 @@ namespace MobiusEditor.RedAlert
|
||||
//if (!checkTrigs.Contains(newTerr.Trigger))
|
||||
//{
|
||||
// errors.Add(string.Format("Terrain '{0}' links to unknown trigger '{1}'; clearing trigger..", terrainType, newTerr.Trigger));
|
||||
// modified = true;
|
||||
// newTerr.Trigger = Trigger.None;
|
||||
//}
|
||||
//else if (!checkTerrTrigs.Contains(Value))
|
||||
//{
|
||||
// errors.Add(string.Format("Terrain '{0}' links to trigger '{1}' which does not contain an event or action applicable to terrain; clearing trigger.", terrainType, newTerr.Trigger));
|
||||
// modified = true;
|
||||
// newTerr.Trigger = Trigger.None;
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
var techno = Map.FindBlockingObject(cell, terrainType, out int blockingCell);
|
||||
string reportCell = blockingCell == -1 ? cell.ToString() : "<unknown>";
|
||||
string reportCell = blockingCell == -1 ? "<unknown>" : cell.ToString();
|
||||
if (techno is Building building)
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' on cell {1} overlaps structure '{2}' in cell {3}; skipping.", terrainType.Name, cell, building.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Overlay overlay)
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' on cell {1} overlaps overlay '{2}' in cell {3}; skipping.", terrainType.Name, cell, overlay.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Terrain terrain)
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' on cell {1} overlaps terrain '{2}' in cell {3}; skipping.", terrainType.Name, cell, terrain.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is InfantryGroup infantry)
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' on cell {1} overlaps infantry in cell {2}; skipping.", terrainType.Name, cell, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Unit unit)
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' on cell {1} overlaps unit '{2}' in cell {3}; skipping.", terrainType.Name, cell, unit.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (blockingCell != -1)
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' placed on cell {1} overlaps unknown techno in cell {2}; skipping.", terrainType.Name, cell, blockingCell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -949,6 +976,7 @@ namespace MobiusEditor.RedAlert
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' references unknown terrain.", name));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -971,6 +999,7 @@ namespace MobiusEditor.RedAlert
|
||||
if (Globals.FilterTheaterObjects && overlayType.Theaters != null && !overlayType.Theaters.Contains(Map.Theater))
|
||||
{
|
||||
errors.Add(string.Format("Overlay '{0}' is not available in the set theater; skipping.", overlayType.Name));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
Map.Overlay[i] = new Overlay { Type = overlayType, Icon = 0 };
|
||||
@ -978,6 +1007,7 @@ namespace MobiusEditor.RedAlert
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Overlay ID {0} references unknown overlay.", overlayId));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -992,6 +1022,7 @@ namespace MobiusEditor.RedAlert
|
||||
if (!int.TryParse(Key, out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for Smudge cannot be parsed. Key: '{0}', value: '{1}'; skipping.", Key, Value));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var tokens = Value.Split(',');
|
||||
@ -1005,11 +1036,13 @@ namespace MobiusEditor.RedAlert
|
||||
if (Globals.FilterTheaterObjects && smudgeType.Theaters != null && !smudgeType.Theaters.Contains(Map.Theater))
|
||||
{
|
||||
errors.Add(string.Format("Smudge '{0}' is not available in the set theater; skipping.", smudgeType.Name));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
if (badCrater)
|
||||
{
|
||||
errors.Add(string.Format("Smudge '{0}' does not function correctly in maps. Correcting to '{1}'.", tokens[0], smudgeType.Name));
|
||||
modified = true;
|
||||
}
|
||||
int icon = 0;
|
||||
if (smudgeType.Icons > 1 && int.TryParse(tokens[2], out icon))
|
||||
@ -1038,11 +1071,13 @@ namespace MobiusEditor.RedAlert
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Smudge '{0}' references unknown smudge.", tokens[0]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Smudge on cell '{0}' has wrong number of tokens (expecting 3).", Key));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1058,29 +1093,34 @@ namespace MobiusEditor.RedAlert
|
||||
if (unitType == null)
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' references unknown unit.", tokens[1]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
if (!aftermathEnabled && unitType.IsExpansionUnit)
|
||||
{
|
||||
errors.Add(string.Format("Expansion unit '{0}' encountered, but expansion units not enabled; enabling expansion units.", unitType.Name));
|
||||
modified = true;
|
||||
Map.BasicSection.ExpansionEnabled = aftermathEnabled = true;
|
||||
}
|
||||
int strength;
|
||||
if (!int.TryParse(tokens[2], out strength))
|
||||
{
|
||||
errors.Add(string.Format("Strength for unit '{0}' cannot be parsed; value: '{1}'; skipping.", unitType.Name, tokens[2]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int cell;
|
||||
if (!int.TryParse(tokens[3], out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for unit '{0}' cannot be parsed; value: '{1}'; skipping.", unitType.Name, tokens[3]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int dirValue;
|
||||
if (!int.TryParse(tokens[4], out dirValue))
|
||||
{
|
||||
errors.Add(string.Format("Direction for unit '{0}' cannot be parsed; value: '{1}'; skipping.", unitType.Name, tokens[4]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var direction = (byte)((dirValue + 0x08) & ~0x0F);
|
||||
@ -1098,11 +1138,13 @@ namespace MobiusEditor.RedAlert
|
||||
if (!checkTrigs.Contains(tokens[6]))
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' links to unknown trigger '{1}'; clearing trigger.", unitType.Name, tokens[6]));
|
||||
modified = true;
|
||||
newUnit.Trigger = Trigger.None;
|
||||
}
|
||||
else if (!checkUnitTrigs.Contains(tokens[6]))
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' links to trigger '{1}' which does not contain an event or action applicable to units; clearing trigger.", unitType.Name, tokens[6]));
|
||||
modified = true;
|
||||
newUnit.Trigger = Trigger.None;
|
||||
}
|
||||
}
|
||||
@ -1112,26 +1154,32 @@ namespace MobiusEditor.RedAlert
|
||||
if (techno is Building building)
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' overlaps structure '{1}' in cell {2}; skipping.", unitType.Name, building.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Overlay overlay)
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' overlaps overlay '{1}' in cell {2}; skipping.", unitType.Name, overlay.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Terrain terrain)
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' overlaps terrain '{1}' in cell {2}; skipping.", unitType.Name, terrain.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is InfantryGroup infantry)
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' overlaps infantry in cell {1}; skipping.", unitType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Unit unit)
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' overlaps unit '{1}' in cell {2}; skipping.", unitType.Name, unit.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' overlaps unknown techno in cell {1}; skipping.", unitType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1140,10 +1188,12 @@ namespace MobiusEditor.RedAlert
|
||||
if (tokens.Length < 2)
|
||||
{
|
||||
errors.Add(string.Format("Unit entry '{0}' has wrong number of tokens (expecting 7).", Key));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' has wrong number of tokens (expecting 7).", tokens[1]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1162,24 +1212,28 @@ namespace MobiusEditor.RedAlert
|
||||
if (aircraftType == null)
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' references unknown aircraft.", tokens[1]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int strength;
|
||||
if (!int.TryParse(tokens[2], out strength))
|
||||
{
|
||||
errors.Add(string.Format("Strength for aircraft '{0}' cannot be parsed; value: '{1}'; skipping.", aircraftType.Name, tokens[2]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int cell;
|
||||
if (!int.TryParse(tokens[3], out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for aircraft '{0}' cannot be parsed; value: '{1}'; skipping.", aircraftType.Name, tokens[3]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int dirValue;
|
||||
if (!int.TryParse(tokens[4], out dirValue))
|
||||
{
|
||||
errors.Add(string.Format("Direction for aircraft '{0}' cannot be parsed; value: '{1}'; skipping.", aircraftType.Name, tokens[4]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var direction = (byte)((dirValue + 0x08) & ~0x0F);
|
||||
@ -1197,26 +1251,32 @@ namespace MobiusEditor.RedAlert
|
||||
if (techno is Building building)
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' overlaps structure '{1}' in cell {2}; skipping.", aircraftType.Name, building.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Overlay overlay)
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' overlaps overlay '{1}' in cell {2}; skipping.", aircraftType.Name, overlay.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Terrain terrain)
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' overlaps terrain '{1}' in cell {2}; skipping.", aircraftType.Name, terrain.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is InfantryGroup infantry)
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' overlaps infantry in cell {1}; skipping.", aircraftType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Unit unit)
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' overlaps unit '{1}' in cell {2}; skipping.", aircraftType.Name, unit.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' overlaps unknown techno in cell {1}; skipping.", aircraftType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1225,10 +1285,12 @@ namespace MobiusEditor.RedAlert
|
||||
if (tokens.Length < 2)
|
||||
{
|
||||
errors.Add(string.Format("Aircraft entry '{0}' has wrong number of tokens (expecting 6).", Key));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' has wrong number of tokens (expecting 6).", tokens[1]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1245,24 +1307,28 @@ namespace MobiusEditor.RedAlert
|
||||
if (vesselType == null)
|
||||
{
|
||||
errors.Add(string.Format("Ship '{0}' references unknown ship.", tokens[1]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int strength;
|
||||
if (!int.TryParse(tokens[2], out strength))
|
||||
{
|
||||
errors.Add(string.Format("Strength for aircraft '{0}' cannot be parsed; value: '{1}'; skipping.", vesselType.Name, tokens[2]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int cell;
|
||||
if (!int.TryParse(tokens[3], out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for aircraft '{0}' cannot be parsed; value: '{1}'; skipping.", vesselType.Name, tokens[3]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int dirValue;
|
||||
if (!int.TryParse(tokens[4], out dirValue))
|
||||
{
|
||||
errors.Add(string.Format("Direction for aircraft '{0}' cannot be parsed; value: '{1}'; skipping.", vesselType.Name, tokens[4]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var direction = (byte)((dirValue + 0x08) & ~0x0F);
|
||||
@ -1280,11 +1346,13 @@ namespace MobiusEditor.RedAlert
|
||||
if (!checkTrigs.Contains(tokens[6]))
|
||||
{
|
||||
errors.Add(string.Format("Ship '{0}' links to unknown trigger '{1}'; clearing trigger.", vesselType.Name, tokens[6]));
|
||||
modified = true;
|
||||
newShip.Trigger = Trigger.None;
|
||||
}
|
||||
else if (!checkUnitTrigs.Contains(tokens[6]))
|
||||
{
|
||||
errors.Add(string.Format("Ship '{0}' links to trigger '{1}' which does not contain an event or action applicable to ships; clearing trigger.", vesselType.Name, tokens[6]));
|
||||
modified = true;
|
||||
newShip.Trigger = Trigger.None;
|
||||
}
|
||||
}
|
||||
@ -1294,26 +1362,32 @@ namespace MobiusEditor.RedAlert
|
||||
if (techno is Building building)
|
||||
{
|
||||
errors.Add(string.Format("Ship '{0}' overlaps structure '{1}' in cell {2}; skipping.", vesselType.Name, building.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Overlay overlay)
|
||||
{
|
||||
errors.Add(string.Format("Ship '{0}' overlaps overlay '{1}' in cell {2}; skipping.", vesselType.Name, overlay.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Terrain terrain)
|
||||
{
|
||||
errors.Add(string.Format("Ship '{0}' overlaps terrain '{1}' in cell {2}; skipping.", vesselType.Name, terrain.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is InfantryGroup infantry)
|
||||
{
|
||||
errors.Add(string.Format("Ship '{0}' overlaps infantry in cell {1}; skipping.", vesselType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Unit unit)
|
||||
{
|
||||
errors.Add(string.Format("Ship '{0}' overlaps unit '{1}' in cell {2}; skipping.", vesselType.Name, unit.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Ship '{0}' overlaps unknown techno in cell {1}; skipping.", vesselType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1322,10 +1396,12 @@ namespace MobiusEditor.RedAlert
|
||||
if (tokens.Length < 2)
|
||||
{
|
||||
errors.Add(string.Format("Ship entry '{0}' has wrong number of tokens (expecting 7).", Key));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Ship '{0}' has wrong number of tokens (expecting 7).", tokens[1]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1342,23 +1418,27 @@ namespace MobiusEditor.RedAlert
|
||||
if (infantryType == null)
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' references unknown infantry.", tokens[1]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
if (!aftermathEnabled && infantryType.IsExpansionUnit)
|
||||
{
|
||||
errors.Add(string.Format("Expansion infantry '{0}' encountered, but expansion units not enabled; enabling expansion units.", infantryType.Name));
|
||||
modified = true;
|
||||
Map.BasicSection.ExpansionEnabled = aftermathEnabled = true;
|
||||
}
|
||||
int strength;
|
||||
if (!int.TryParse(tokens[2], out strength))
|
||||
{
|
||||
errors.Add(string.Format("Strength for infantry '{0}' cannot be parsed; value: '{1}'; skipping.", infantryType.Name, tokens[2]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int cell;
|
||||
if (!int.TryParse(tokens[3], out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for infantry '{0}' cannot be parsed; value: '{1}'; skipping.", infantryType.Name, tokens[3]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var infantryGroup = Map.Technos[cell] as InfantryGroup;
|
||||
@ -1373,6 +1453,7 @@ namespace MobiusEditor.RedAlert
|
||||
if (!int.TryParse(tokens[4], out stoppingPos))
|
||||
{
|
||||
errors.Add(string.Format("Sub-position for infantry '{0}' cannot be parsed; value: '{1}'; skipping.", infantryType.Name, tokens[4]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
if (stoppingPos < Globals.NumInfantryStops)
|
||||
@ -1381,6 +1462,7 @@ namespace MobiusEditor.RedAlert
|
||||
if (!int.TryParse(tokens[6], out dirValue))
|
||||
{
|
||||
errors.Add(string.Format("Direction for infantry '{0}' cannot be parsed; value: '{1}'; skipping.", infantryType.Name, tokens[6]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var direction = (byte)((dirValue + 0x08) & ~0x0F);
|
||||
@ -1389,11 +1471,13 @@ namespace MobiusEditor.RedAlert
|
||||
if (!checkTrigs.Contains(tokens[7]))
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' links to unknown trigger '{1}'; clearing trigger.", infantryType.Name, tokens[7]));
|
||||
modified = true;
|
||||
tokens[7] = Trigger.None;
|
||||
}
|
||||
else if (!checkUnitTrigs.Contains(tokens[7]))
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' links to trigger '{1}' which does not contain an event or action applicable to infantry; clearing trigger.", infantryType.Name, tokens[7]));
|
||||
modified = true;
|
||||
tokens[7] = Trigger.None;
|
||||
}
|
||||
infantryGroup.Infantry[stoppingPos] = new Infantry(infantryGroup)
|
||||
@ -1409,11 +1493,13 @@ namespace MobiusEditor.RedAlert
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' overlaps another infantry at position {1} in cell {2}; skipping.", infantryType.Name, stoppingPos, cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' has invalid position {1} in cell {2}; skipping.", infantryType.Name, stoppingPos, cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1422,22 +1508,27 @@ namespace MobiusEditor.RedAlert
|
||||
if (techno is Building building)
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' overlaps structure '{1}' in cell {2}; skipping.", infantryType.Name, building.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Overlay overlay)
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' overlaps overlay '{1}' in cell {2}; skipping.", infantryType.Name, overlay.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Terrain terrain)
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' overlaps terrain '{1}' in cell {2}; skipping.", infantryType.Name, terrain.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Unit unit)
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' overlaps unit '{1}' in cell {2}; skipping.", infantryType.Name, unit.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' overlaps unknown techno in cell {1}; skipping.", infantryType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1446,10 +1537,12 @@ namespace MobiusEditor.RedAlert
|
||||
if (tokens.Length < 2)
|
||||
{
|
||||
errors.Add(string.Format("Infantry entry '{0}' has wrong number of tokens (expecting 8).", Key));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' has wrong number of tokens (expecting 8).", tokens[1]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1466,29 +1559,34 @@ namespace MobiusEditor.RedAlert
|
||||
if (buildingType == null)
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' references unknown structure.", tokens[1]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
if (Globals.FilterTheaterObjects && buildingType.Theaters != null && !buildingType.Theaters.Contains(Map.Theater))
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' is not available in the set theater; skipping.", buildingType.Name));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int strength;
|
||||
if (!int.TryParse(tokens[2], out strength))
|
||||
{
|
||||
errors.Add(string.Format("Strength for structure '{0}' cannot be parsed; value: '{1}'; skipping.", buildingType.Name, tokens[2]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int cell;
|
||||
if (!int.TryParse(tokens[3], out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for structure '{0}' cannot be parsed; value: '{1}'; skipping.", buildingType.Name, tokens[3]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int dirValue;
|
||||
if (!int.TryParse(tokens[4], out dirValue))
|
||||
{
|
||||
errors.Add(string.Format("Direction for structure '{0}' cannot be parsed; value: '{1}'; skipping.", buildingType.Name, tokens[4]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var direction = (byte)((dirValue + 0x08) & ~0x0F);
|
||||
@ -1509,18 +1607,20 @@ namespace MobiusEditor.RedAlert
|
||||
if (!checkTrigs.Contains(tokens[5]))
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' links to unknown trigger '{1}'; clearing trigger.", buildingType.Name, tokens[5]));
|
||||
modified = true;
|
||||
newBld.Trigger = Trigger.None;
|
||||
}
|
||||
else if (!checkStrcTrigs.Contains(tokens[5]))
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' links to trigger '{1}' which does not contain an event or action applicable to structures; clearing trigger.", buildingType.Name, tokens[5]));
|
||||
modified = true;
|
||||
newBld.Trigger = Trigger.None;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var techno = Map.FindBlockingObject(cell, buildingType, out int blockingCell);
|
||||
string reportCell = blockingCell == -1 ? cell.ToString() : "<unknown>";
|
||||
string reportCell = blockingCell == -1 ? "<unknown>" : cell.ToString();
|
||||
if (techno is Building building)
|
||||
{
|
||||
bool onBib = false;
|
||||
@ -1533,37 +1633,45 @@ namespace MobiusEditor.RedAlert
|
||||
if (onBib)
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps bib of structure '{2}' in cell {3}; skipping.", buildingType.Name, cell, building.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps structure '{2}' in cell {3}; skipping.", buildingType.Name, cell, building.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else if (techno is Overlay overlay)
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps overlay '{2}' in cell {3}; skipping.", buildingType.Name, cell, overlay.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Terrain terrain)
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps terrain '{2}' in cell {3}; skipping.", buildingType.Name, cell, terrain.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is InfantryGroup infantry)
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps infantry in cell {2}; skipping.", buildingType.Name, cell, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Unit unit)
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps unit '{2}' in cell {3}; skipping.", buildingType.Name, cell, unit.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (blockingCell != -1)
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps unknown techno in cell {2}; skipping.", buildingType.Name, cell, blockingCell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps unknown techno; skipping.", buildingType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1573,10 +1681,12 @@ namespace MobiusEditor.RedAlert
|
||||
if (tokens.Length < 2)
|
||||
{
|
||||
errors.Add(string.Format("Structure entry '{0}' has wrong number of tokens (expecting 6).", Key));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' has wrong number of tokens (expecting 6).", tokens[1]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1599,17 +1709,20 @@ namespace MobiusEditor.RedAlert
|
||||
if (buildingType == null)
|
||||
{
|
||||
errors.Add(string.Format("Base rebuild entry {0} references unknown structure '{1}'.", priority, tokens[0]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
if (Globals.FilterTheaterObjects && buildingType.Theaters != null && !buildingType.Theaters.Contains(Map.Theater))
|
||||
{
|
||||
errors.Add(string.Format("Base rebuild entry {0} references structure '{1}' which is not available in the set theater; skipping.", priority, buildingType.Name));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int cell;
|
||||
if (!int.TryParse(tokens[1], out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for base rebuild entry '{0}' cannot be parsed; value: '{1}'; skipping.", buildingType.Name, tokens[1]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
Map.Metrics.GetLocation(cell, out Point location);
|
||||
@ -1632,11 +1745,13 @@ namespace MobiusEditor.RedAlert
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Base rebuild entry {0} has wrong number of tokens (expecting 2).", priority));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else if (!Key.Equals("Count", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
errors.Add(string.Format("Invalid base rebuild priority '{0}' (expecting integer).", Key));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1661,22 +1776,26 @@ namespace MobiusEditor.RedAlert
|
||||
if (cell != -1)
|
||||
{
|
||||
errors.Add(string.Format("Waypoint {0} cell value {1} out of range (expecting between {2} and {3}).", waypoint, cell, 0, Map.Metrics.Length - 1));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cell != -1)
|
||||
{
|
||||
errors.Add(string.Format("Waypoint {0} out of range (expecting between {1} and {2}).", waypoint, 0, Map.Waypoints.Length - 1));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Waypoint {0} has invalid cell '{1}' (expecting integer).", waypoint, Value));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Invalid waypoint '{0}' (expecting integer).", Key));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1701,21 +1820,25 @@ namespace MobiusEditor.RedAlert
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Cell trigger {0} links to trigger '{1}' which does not contain a placeable event; skipping.", cell, Value));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Cell trigger {0} links to unknown trigger '{1}'; skipping.", cell, Value));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Cell trigger {0} outside map bounds; skipping.", cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Invalid cell trigger '{0}' (expecting integer).", Key));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1754,10 +1877,11 @@ namespace MobiusEditor.RedAlert
|
||||
}
|
||||
foreach (var teamType in teamTypes)
|
||||
{
|
||||
string trigName = indexToName(Map.Triggers, teamType.Trigger, Trigger.None);
|
||||
string trigName = indexToName(triggers, teamType.Trigger, Trigger.None);
|
||||
if (!checkUnitTrigs.Contains(trigName))
|
||||
{
|
||||
errors.Add(string.Format("Team '{0}' links to trigger '{1}' which does not contain an event or action applicable to units; clearing trigger.", teamType.Name, trigName));
|
||||
modified = true;
|
||||
teamType.Trigger = Trigger.None;
|
||||
}
|
||||
else
|
||||
@ -1765,27 +1889,27 @@ namespace MobiusEditor.RedAlert
|
||||
teamType.Trigger = trigName;
|
||||
}
|
||||
}
|
||||
foreach (var trigger in Map.Triggers)
|
||||
foreach (var trigger in triggers)
|
||||
{
|
||||
trigger.Event1.Team = indexToName(teamTypes, trigger.Event1.Team, TeamType.None);
|
||||
trigger.Event2.Team = indexToName(teamTypes, trigger.Event2.Team, TeamType.None);
|
||||
trigger.Action1.Team = indexToName(teamTypes, trigger.Action1.Team, TeamType.None);
|
||||
trigger.Action1.Trigger = indexToName(Map.Triggers, trigger.Action1.Trigger, Trigger.None);
|
||||
trigger.Action1.Trigger = indexToName(triggers, trigger.Action1.Trigger, Trigger.None);
|
||||
trigger.Action2.Team = indexToName(teamTypes, trigger.Action2.Team, TeamType.None);
|
||||
trigger.Action2.Trigger = indexToName(Map.Triggers, trigger.Action2.Trigger, Trigger.None);
|
||||
trigger.Action2.Trigger = indexToName(triggers, trigger.Action2.Trigger, Trigger.None);
|
||||
}
|
||||
// Sort
|
||||
var comparer = new ExplorerComparer();
|
||||
Map.TeamTypes.Clear();
|
||||
Map.TeamTypes.AddRange(teamTypes.OrderBy(t => t.Name, comparer));
|
||||
UpdateBasePlayerHouse();
|
||||
List<Trigger> reorderedTriggers = Map.Triggers.OrderBy(t => t.Name, comparer).ToList();
|
||||
// Won't trigger the automatic cleanup and notifications.
|
||||
Map.Triggers.Clear();
|
||||
Map.Triggers.AddRange(reorderedTriggers);
|
||||
Map.Triggers.AddRange(triggers.OrderBy(t => t.Name, comparer));
|
||||
extraSections = ini.Sections;
|
||||
bool switchedToSolo = forceSoloMission && !Map.BasicSection.SoloMission
|
||||
&& (reorderedTriggers.Any(t => t.Action1.ActionType == ActionTypes.TACTION_WIN) || reorderedTriggers.Any(t => t.Action2.ActionType == ActionTypes.TACTION_WIN))
|
||||
&& (reorderedTriggers.Any(t => t.Action1.ActionType == ActionTypes.TACTION_LOSE) || reorderedTriggers.Any(t => t.Action2.ActionType == ActionTypes.TACTION_LOSE));
|
||||
&& (Map.Triggers.Any(t => t.Action1.ActionType == ActionTypes.TACTION_WIN) || Map.Triggers.Any(t => t.Action2.ActionType == ActionTypes.TACTION_WIN))
|
||||
&& (Map.Triggers.Any(t => t.Action1.ActionType == ActionTypes.TACTION_LOSE) || Map.Triggers.Any(t => t.Action2.ActionType == ActionTypes.TACTION_LOSE));
|
||||
if (switchedToSolo)
|
||||
{
|
||||
errors.Insert(0, "Filename detected as classic single player mission format, and win and lose trigger detected. Applying \"SoloMission\" flag.");
|
||||
@ -1958,7 +2082,7 @@ namespace MobiusEditor.RedAlert
|
||||
using (var jsonStream = new MemoryStream())
|
||||
using (var iniWriter = new StreamWriter(iniStream))
|
||||
using (var jsonWriter = new JsonTextWriter(new StreamWriter(jsonStream)))
|
||||
using (var megafileBuilder = new MegafileBuilder(@"", path))
|
||||
using (var megafileBuilder = new MegafileBuilder(String.Empty, path))
|
||||
{
|
||||
iniWriter.Write(ini.ToString());
|
||||
iniWriter.Flush();
|
||||
@ -2010,7 +2134,7 @@ namespace MobiusEditor.RedAlert
|
||||
}
|
||||
}
|
||||
Model.BasicSection basic = Map.BasicSection;
|
||||
// Make new section
|
||||
// Make new Aftermath section
|
||||
INISection newAftermathSection = new INISection("Aftermath");
|
||||
newAftermathSection["NewUnitsEnabled"] = basic.ExpansionEnabled ? "1" : "0";
|
||||
if (aftermathSection != null)
|
||||
@ -2022,8 +2146,11 @@ namespace MobiusEditor.RedAlert
|
||||
newAftermathSection[key] = value;
|
||||
}
|
||||
}
|
||||
// Add Aftermath section
|
||||
ini.Sections.Add(newAftermathSection);
|
||||
// Add any other rules / unmanaged sections.
|
||||
ini.Sections.AddRange(addedExtra);
|
||||
// Clean up video names
|
||||
char[] cutfrom = { ';', '(' };
|
||||
basic.Intro = GeneralUtils.TrimRemarks(basic.Intro, true, cutfrom);
|
||||
basic.Brief = GeneralUtils.TrimRemarks(basic.Brief, true, cutfrom);
|
||||
@ -2035,7 +2162,7 @@ namespace MobiusEditor.RedAlert
|
||||
basic.Lose = GeneralUtils.TrimRemarks(basic.Lose, true, cutfrom);
|
||||
if (String.IsNullOrWhiteSpace(basic.Name))
|
||||
{
|
||||
string[] name = Path.GetFileNameWithoutExtension(fileName).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] name = Path.GetFileNameWithoutExtension(fileName).Split(new[] { ' ', '_' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
for (Int32 i = 0; i < name.Length; i++)
|
||||
{
|
||||
String word = name[i];
|
||||
|
@ -435,8 +435,10 @@ namespace MobiusEditor.Render
|
||||
int damageIcon = 0;
|
||||
int collapseIcon = 0;
|
||||
bool hasCollapseFrame = false;
|
||||
// In TD, damage is when BELOW the threshold. In RA, it's ON the threshold.
|
||||
int healthyMin = gameType == GameType.RedAlert ? 128 : 127;
|
||||
// Only fetch if damaged. BuildingType.IsSingleFrame is an override for the RA mines. Everything else works with one simple logic.
|
||||
if (building.Strength <= 128 && !building.Type.IsSingleFrame)
|
||||
if (building.Strength <= healthyMin && !building.Type.IsSingleFrame)
|
||||
{
|
||||
maxIcon = Globals.TheTilesetManager.GetTileDataLength(theater.Tilesets, building.Type.Tilename);
|
||||
hasCollapseFrame = (gameType == GameType.TiberianDawn || gameType == GameType.SoleSurvivor) && maxIcon > 1 && maxIcon % 2 == 1;
|
||||
@ -446,7 +448,7 @@ namespace MobiusEditor.Render
|
||||
if (building.Type.HasTurret)
|
||||
{
|
||||
icon = BodyShape[Facing32[building.Direction.ID]];
|
||||
if (building.Strength <= 128)
|
||||
if (building.Strength <= healthyMin)
|
||||
{
|
||||
icon += damageIcon;
|
||||
}
|
||||
@ -457,7 +459,7 @@ namespace MobiusEditor.Render
|
||||
{
|
||||
icon = collapseIcon;
|
||||
}
|
||||
else if (building.Strength <= 128)
|
||||
else if (building.Strength <= healthyMin)
|
||||
{
|
||||
icon = damageIcon;
|
||||
}
|
||||
@ -474,7 +476,7 @@ namespace MobiusEditor.Render
|
||||
if (building.Type.FactoryOverlay != null && (building.Strength > 1 || !hasCollapseFrame))
|
||||
{
|
||||
int overlayIcon = 0;
|
||||
if (building.Strength <= 128)
|
||||
if (building.Strength <= healthyMin)
|
||||
{
|
||||
int maxOverlayIcon = Globals.TheTilesetManager.GetTileDataLength(theater.Tilesets, building.Type.FactoryOverlay);
|
||||
overlayIcon = maxOverlayIcon / 2;
|
||||
@ -623,9 +625,10 @@ namespace MobiusEditor.Render
|
||||
if (unit.Type == TiberianDawn.UnitTypes.GunBoat)
|
||||
{
|
||||
// East facing is not actually possible to set in missions. This is just the turret facing.
|
||||
if (unit.Strength <= 128)
|
||||
// In TD, damage is when BELOW the threshold. In RA, it's ON the threshold.
|
||||
if (unit.Strength < 128)
|
||||
icon += 32;
|
||||
if (unit.Strength <= 64)
|
||||
if (unit.Strength < 64)
|
||||
icon += 32;
|
||||
}
|
||||
}
|
||||
@ -807,6 +810,12 @@ namespace MobiusEditor.Render
|
||||
}
|
||||
|
||||
public static (Rectangle, Action<Graphics>) Render(GameType gameType, bool soloMission, TheaterType theater, Size tileSize, TeamColor[] flagColors, Waypoint waypoint)
|
||||
{
|
||||
float defaultOpacity = !soloMission && (waypoint.Flag & WaypointFlag.PlayerStart) == WaypointFlag.PlayerStart ? 1.0f : 0.5f;
|
||||
return Render(gameType, soloMission, theater, tileSize, flagColors, waypoint, defaultOpacity);
|
||||
}
|
||||
|
||||
public static (Rectangle, Action<Graphics>) Render(GameType gameType, bool soloMission, TheaterType theater, Size tileSize, TeamColor[] flagColors, Waypoint waypoint, float transparencyModifier)
|
||||
{
|
||||
if (!waypoint.Point.HasValue)
|
||||
{
|
||||
@ -817,12 +826,11 @@ namespace MobiusEditor.Render
|
||||
TeamColor teamColor = null;
|
||||
Color tint = waypoint.Tint;
|
||||
float brightness = 1.0f;
|
||||
float transMod = 0.5f;
|
||||
if (!soloMission && (waypoint.Flag & WaypointFlag.PlayerStart) == WaypointFlag.PlayerStart)
|
||||
{
|
||||
tileGraphics = "flagfly";
|
||||
// Always paint flags as opaque.
|
||||
transMod = 1.0f;
|
||||
transparencyModifier = 1.0f;
|
||||
int pls = (int)WaypointFlag.PlayerStart;
|
||||
int flagId = ((int)waypoint.Flag & ~pls) / (pls << 1);
|
||||
int mpId = 0;
|
||||
@ -857,14 +865,14 @@ namespace MobiusEditor.Render
|
||||
{
|
||||
var imageAttributes = new ImageAttributes();
|
||||
// Waypoints get drawn as semitransparent, so always execute this.
|
||||
if (tint != Color.White || brightness != 1.0 || transMod != 1.0)
|
||||
if (tint != Color.White || brightness != 1.0 || transparencyModifier != 1.0)
|
||||
{
|
||||
var colorMatrix = new ColorMatrix(new float[][]
|
||||
{
|
||||
new float[] {tint.R * brightness / 255.0f, 0, 0, 0, 0},
|
||||
new float[] {0, tint.G * brightness / 255.0f, 0, 0, 0},
|
||||
new float[] {0, 0, tint.B * brightness / 255.0f, 0, 0},
|
||||
new float[] {0, 0, 0, (tint.A * transMod) / 255.0f, 0},
|
||||
new float[] {0, 0, 0, (tint.A * transparencyModifier) / 255.0f, 0},
|
||||
new float[] {0, 0, 0, 0, 1},
|
||||
});
|
||||
imageAttributes.SetColorMatrix(colorMatrix);
|
||||
@ -1236,8 +1244,8 @@ namespace MobiusEditor.Render
|
||||
};
|
||||
var paintBounds = new Rectangle(new Point(topLeft.X * tileSize.Width, topLeft.Y * tileSize.Height), tileSize);
|
||||
string wpText = waypoint.Name;
|
||||
using (var baseBackgroundBrush = new SolidBrush(Color.FromArgb((forPreview ? 48 : 96) * 2 / 3, Color.Black)))
|
||||
using (var baseTextBrush = new SolidBrush(Color.FromArgb(forPreview ? 64 : 128, textColor)))
|
||||
using (var baseBackgroundBrush = new SolidBrush(Color.FromArgb(forPreview ? 64 : 128, Color.Black)))
|
||||
using (var baseTextBrush = new SolidBrush(Color.FromArgb(forPreview ? 128 : 255, textColor)))
|
||||
{
|
||||
using (var font = graphics.GetAdjustedFont(wpText, SystemFonts.DefaultFont, paintBounds.Width,
|
||||
Math.Max(1, (int)(12 * tileScale)), Math.Max(1, (int)(30 * tileScale)), true))
|
||||
|
@ -28,8 +28,9 @@ namespace MobiusEditor.SoleSurvivor
|
||||
|
||||
public static bool CheckForSSmap(string path, FileType fileType)
|
||||
{
|
||||
return CheckForMegamap(path, fileType) && GeneralUtils.CheckForIniInfo(path, fileType, "Crates", null, null);
|
||||
return GeneralUtils.CheckForIniInfo(path, fileType, "Crates", null, null);
|
||||
}
|
||||
|
||||
protected CratesSection cratesSection;
|
||||
public CratesSection CratesSection => cratesSection;
|
||||
|
||||
@ -114,7 +115,7 @@ namespace MobiusEditor.SoleSurvivor
|
||||
// Clean up this mess.
|
||||
foreach (House house in Map.Houses)
|
||||
{
|
||||
if (house.Type.ID > HouseTypes.Multi1.ID)
|
||||
if (house.Type.ID >= HouseTypes.Multi1.ID)
|
||||
{
|
||||
house.Enabled = false;
|
||||
}
|
||||
@ -130,9 +131,9 @@ namespace MobiusEditor.SoleSurvivor
|
||||
return Load(path, fileType, true, out modified);
|
||||
}
|
||||
|
||||
protected override List<string> LoadINI(INI ini, bool forceSoloMission)
|
||||
protected override List<string> LoadINI(INI ini, bool forceSoloMission, ref bool modified)
|
||||
{
|
||||
List<string> errors = LoadINI(ini, forceSoloMission, true);
|
||||
List<string> errors = LoadINI(ini, forceSoloMission, true, ref modified);
|
||||
var cratesIniSection = extraSections.Extract("Crates");
|
||||
if (cratesIniSection != null)
|
||||
{
|
||||
@ -181,7 +182,7 @@ namespace MobiusEditor.SoleSurvivor
|
||||
SaveIniStructures(ini);
|
||||
SaveINITerrain(ini);
|
||||
SaveIniOverlay(ini);
|
||||
if (waypointBackup != null)
|
||||
if (overlayBackup != null)
|
||||
{
|
||||
ini.Sections.Add(overlayBackup);
|
||||
}
|
||||
|
@ -55,8 +55,8 @@ namespace MobiusEditor.TiberianDawn
|
||||
public static readonly BuildingType V09 = new BuildingType(31, "v09", "TEXT_STRUCTURE_TITLE_CIV9", 0, 0, new bool[1, 1] { { true } }, "Neutral", new [] { TheaterTypes.Temperate, TheaterTypes.Winter });
|
||||
public static readonly BuildingType V10 = new BuildingType(32, "v10", "TEXT_STRUCTURE_TITLE_CIV10", 0, 0, new bool[1, 1] { { true } }, "Neutral", new [] { TheaterTypes.Temperate, TheaterTypes.Winter });
|
||||
public static readonly BuildingType V11 = new BuildingType(33, "v11", "TEXT_STRUCTURE_TITLE_CIV11", 0, 0, new bool[1, 1] { { true } }, "Neutral", new [] { TheaterTypes.Temperate, TheaterTypes.Winter });
|
||||
public static readonly BuildingType V12 = new BuildingType(34, "v12", "TEXT_STRUCTURE_TITLE_CIV12", 0, 0, new bool[1, 1] { { true } }, "Neutral", new [] { TheaterTypes.Temperate });
|
||||
public static readonly BuildingType V13 = new BuildingType(35, "v13", "TEXT_STRUCTURE_TITLE_CIV12", 0, 0, new bool[1, 1] { { true } }, "Neutral", new [] { TheaterTypes.Temperate });
|
||||
public static readonly BuildingType V12 = new BuildingType(34, "v12", "TEXT_STRUCTURE_TITLE_CIV12", 0, 0, new bool[1, 1] { { true } }, "Neutral", new [] { TheaterTypes.Temperate, TheaterTypes.Winter });
|
||||
public static readonly BuildingType V13 = new BuildingType(35, "v13", "TEXT_STRUCTURE_TITLE_CIV12", 0, 0, new bool[1, 1] { { true } }, "Neutral", new [] { TheaterTypes.Temperate, TheaterTypes.Winter });
|
||||
public static readonly BuildingType V14 = new BuildingType(36, "v14", "TEXT_STRUCTURE_TITLE_CIV13", 0, 0, new bool[1, 1] { { true } }, "Neutral", new [] { TheaterTypes.Temperate, TheaterTypes.Winter });
|
||||
public static readonly BuildingType V15 = new BuildingType(37, "v15", "TEXT_STRUCTURE_TITLE_CIV14", 0, 0, new bool[1, 1] { { true } }, "Neutral", new [] { TheaterTypes.Temperate, TheaterTypes.Winter });
|
||||
public static readonly BuildingType V16 = new BuildingType(38, "v16", "TEXT_STRUCTURE_TITLE_CIV15", 0, 0, new bool[1, 1] { { true } }, "Neutral", new [] { TheaterTypes.Temperate, TheaterTypes.Winter });
|
||||
|
@ -314,11 +314,12 @@ namespace MobiusEditor.TiberianDawn
|
||||
}
|
||||
ini.Parse(iniText);
|
||||
forceSingle = !forSole && SinglePlayRegex.IsMatch(Path.GetFileNameWithoutExtension(path));
|
||||
errors.AddRange(LoadINI(ini, forceSingle, forSole));
|
||||
errors.AddRange(LoadINI(ini, forceSingle, ref modified));
|
||||
}
|
||||
if (!File.Exists(binPath))
|
||||
{
|
||||
errors.Add(String.Format("No .bin file found for file '{0}'. Using empty map.", Path.GetFileName(path)));
|
||||
modified = true;
|
||||
Map.Templates.Clear();
|
||||
}
|
||||
else
|
||||
@ -328,11 +329,12 @@ namespace MobiusEditor.TiberianDawn
|
||||
long mapLen = binReader.BaseStream.Length;
|
||||
if ((!isMegaMap && mapLen == 0x2000) || (isMegaMap && mapLen % 4 == 0))
|
||||
{
|
||||
errors.AddRange(!isMegaMap ? LoadBinaryClassic(binReader) : LoadBinaryMega(binReader));
|
||||
errors.AddRange(!isMegaMap ? LoadBinaryClassic(binReader, ref modified) : LoadBinaryMega(binReader, ref modified));
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(String.Format("'{0}' does not have the correct size for a " + this.Name + " .bin file.", Path.GetFileName(binPath)));
|
||||
modified = true;
|
||||
Map.Templates.Clear();
|
||||
}
|
||||
}
|
||||
@ -357,15 +359,16 @@ namespace MobiusEditor.TiberianDawn
|
||||
iniText = FixRoad2Load(iniText);
|
||||
}
|
||||
ini.Parse(iniText);
|
||||
errors.AddRange(LoadINI(ini, false, forSole));
|
||||
errors.AddRange(LoadINI(ini, false, ref modified));
|
||||
long mapLen = binReader.BaseStream.Length;
|
||||
if ((!isMegaMap && mapLen == 0x2000) || (isMegaMap && mapLen % 4 == 0))
|
||||
{
|
||||
errors.AddRange(!isMegaMap ? LoadBinaryClassic(binReader) : LoadBinaryMega(binReader));
|
||||
errors.AddRange(!isMegaMap ? LoadBinaryClassic(binReader, ref modified) : LoadBinaryMega(binReader, ref modified));
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(String.Format("'{0}' does not have the correct size for a " + this.Name + " .bin file.", Path.GetFileName(binFile)));
|
||||
modified = true;
|
||||
Map.Templates.Clear();
|
||||
}
|
||||
}
|
||||
@ -374,11 +377,6 @@ namespace MobiusEditor.TiberianDawn
|
||||
default:
|
||||
throw new NotSupportedException("Unsupported filetype.");
|
||||
}
|
||||
if (errors.Count > 0)
|
||||
{
|
||||
// If only one message is inside the errors, and the "force single" boolean is set, the single message is about that.
|
||||
modified = !forceSingle || errors.Count > 1;
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
@ -498,12 +496,12 @@ namespace MobiusEditor.TiberianDawn
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
protected virtual List<string> LoadINI(INI ini, bool forceSoloMission)
|
||||
protected virtual List<string> LoadINI(INI ini, bool forceSoloMission, ref bool modified)
|
||||
{
|
||||
return LoadINI(ini, forceSoloMission, false);
|
||||
return LoadINI(ini, forceSoloMission, false, ref modified);
|
||||
}
|
||||
|
||||
protected List<string> LoadINI(INI ini, bool forceSoloMission, bool forSole)
|
||||
protected List<string> LoadINI(INI ini, bool forceSoloMission, bool forSole, ref bool modified)
|
||||
{
|
||||
var errors = new List<string>();
|
||||
Map.BeginUpdate();
|
||||
@ -584,8 +582,12 @@ namespace MobiusEditor.TiberianDawn
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Key.Length > 8)
|
||||
{
|
||||
errors.Add(string.Format("TeamType '{0}' has a name that is longer than 8 characters. This will not be corrected by the loading process, but should be addressed, since it can make the teams fail to read correctly, and might even crash the game.", Key));
|
||||
modified = true;
|
||||
}
|
||||
var teamType = new TeamType { Name = Key };
|
||||
|
||||
var tokens = Value.Split(',').ToList();
|
||||
teamType.House = Map.HouseTypes.Where(t => t.Equals(tokens[0])).FirstOrDefault(); tokens.RemoveAt(0);
|
||||
teamType.IsRoundAbout = int.Parse(tokens[0]) != 0; tokens.RemoveAt(0);
|
||||
@ -614,11 +616,13 @@ namespace MobiusEditor.TiberianDawn
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Team '{0}' references unknown class '{1}'.", Key, classTokens[0]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Team '{0}' has wrong number of tokens for class index {1} (expecting 2).", Key, i));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
var numMissions = int.Parse(tokens[0]); tokens.RemoveAt(0);
|
||||
@ -639,11 +643,13 @@ namespace MobiusEditor.TiberianDawn
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Team '{0}' references unknown class '{1}'.", Key, missionTokens[0]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Team '{0}' has wrong number of tokens for mission index {1} (expecting 2).", Key, i));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
if (tokens.Count > 0)
|
||||
@ -659,6 +665,7 @@ namespace MobiusEditor.TiberianDawn
|
||||
catch (Exception ex)
|
||||
{
|
||||
errors.Add(string.Format("Teamtype '{0}' has errors and can't be parsed: {1}.", Key, ex.Message));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -669,6 +676,11 @@ namespace MobiusEditor.TiberianDawn
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Key.Length > 4)
|
||||
{
|
||||
errors.Add(string.Format("Trigger '{0}' has a name that is longer than 4 characters. This will not be corrected by the loading process, but should be addressed, since it can make the triggers fail to read correctly and link to objects and cell triggers, and might even crash the game.", Key));
|
||||
modified = true;
|
||||
}
|
||||
var tokens = Value.Split(',');
|
||||
if (tokens.Length >= 5)
|
||||
{
|
||||
@ -691,11 +703,13 @@ namespace MobiusEditor.TiberianDawn
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Trigger '{0}' has too few tokens (expecting at least 5).", Key));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
errors.Add(string.Format("Trigger '{0}' has errors and can't be parsed: {1}.", Key, ex.Message));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -713,6 +727,7 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (!int.TryParse(Key, out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for terrain cannot be parsed. Key: '{0}', value: '{1}'; skipping.", Key, Value));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var tokens = Value.Split(',');
|
||||
@ -724,6 +739,7 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (Globals.FilterTheaterObjects && terrainType.Theaters != null && !terrainType.Theaters.Contains(Map.Theater))
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' is not available in the set theater; skipping.", terrainType.Name));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
Terrain newTerr = new Terrain
|
||||
@ -736,47 +752,57 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (!checkTrigs.Contains(newTerr.Trigger))
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' links to unknown trigger '{1}'; clearing trigger.", terrainType.Name, tokens[1]));
|
||||
modified = true;
|
||||
newTerr.Trigger = Trigger.None;
|
||||
}
|
||||
else if (!checkTerrTrigs.Contains(newTerr.Trigger))
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' links to trigger '{1}' which does not contain an event applicable to terrain; clearing trigger.", terrainType.Name, tokens[1]));
|
||||
modified = true;
|
||||
newTerr.Trigger = Trigger.None;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var techno = Map.FindBlockingObject(cell, terrainType, out int blockingCell);
|
||||
string reportCell = blockingCell == -1 ? cell.ToString() : "<unknown>";
|
||||
string reportCell = blockingCell == -1 ? "<unknown>" : cell.ToString();
|
||||
if (techno is Building building)
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' on cell {1} overlaps structure '{2}' in cell {3}; skipping.", terrainType.Name, cell, building.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Overlay overlay)
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' on cell {1} overlaps overlay '{2}' in cell {3}; skipping.", terrainType.Name, cell, overlay.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Terrain terrain)
|
||||
{
|
||||
MessageBox.Show("overlap");
|
||||
errors.Add(string.Format("Terrain '{0}' on cell {1} overlaps terrain '{2}' in cell {3}; skipping.", terrainType.Name, cell, terrain.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is InfantryGroup infantry)
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' on cell {1} overlaps infantry in cell {2}; skipping.", terrainType.Name, cell, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Unit unit)
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' on cell {1} overlaps unit '{2}' in cell {3}; skipping.", terrainType.Name, cell, unit.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (blockingCell != -1)
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' placed on cell {1} overlaps unknown techno in cell {2}; skipping.", terrainType.Name, cell, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' placed on cell {1} overlaps unknown techno; skipping.", terrainType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -784,11 +810,13 @@ namespace MobiusEditor.TiberianDawn
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' references unknown terrain.", tokens[0]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Terrain '{0}' has wrong number of tokens (expecting 2).", Key));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -801,6 +829,7 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (!int.TryParse(Key, out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for overlay cannot be parsed. Key: '{0}', value: '{1}'; skipping.", Key, Value));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var overlayType = Map.OverlayTypes.Where(t => t.Equals(Value)).FirstOrDefault();
|
||||
@ -809,6 +838,7 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (Globals.FilterTheaterObjects && overlayType.Theaters != null && !overlayType.Theaters.Contains(Map.Theater))
|
||||
{
|
||||
errors.Add(string.Format("Overlay '{0}' is not available in the set theater; skipping.", overlayType.Name));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
Map.Overlay[cell] = new Overlay { Type = overlayType, Icon = 0 };
|
||||
@ -816,6 +846,7 @@ namespace MobiusEditor.TiberianDawn
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Overlay '{0}' references unknown overlay.", Value));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -828,6 +859,7 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (!int.TryParse(Key, out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for Smudge cannot be parsed. Key: '{0}', value: '{1}'; skipping.", Key, Value));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var tokens = Value.Split(',');
|
||||
@ -841,11 +873,13 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (Globals.FilterTheaterObjects && smudgeType.Theaters != null && !smudgeType.Theaters.Contains(Map.Theater))
|
||||
{
|
||||
errors.Add(string.Format("Smudge '{0}' is not available in the set theater; skipping.", smudgeType.Name));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
if (badCrater)
|
||||
{
|
||||
errors.Add(string.Format("Smudge '{0}' does not function correctly in maps. Correcting to '{1}'.", tokens[0], smudgeType.Name));
|
||||
modified = true;
|
||||
}
|
||||
int icon = 0;
|
||||
if (smudgeType.Icons > 1 && int.TryParse(tokens[2], out icon))
|
||||
@ -874,11 +908,13 @@ namespace MobiusEditor.TiberianDawn
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Smudge '{0}' references unknown smudge.", tokens[0]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Smudge on cell '{0}' has wrong number of tokens (expecting 3).", Key));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -894,18 +930,21 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (infantryType == null)
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' references unknown infantry.", tokens[1]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int strength;
|
||||
if (!int.TryParse(tokens[2], out strength))
|
||||
{
|
||||
errors.Add(string.Format("Strength for infantry '{0}' cannot be parsed; value: '{1}'; skipping.", infantryType.Name, tokens[2]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int cell;
|
||||
if (!int.TryParse(tokens[3], out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for infantry '{0}' cannot be parsed; value: '{1}'; skipping.", infantryType.Name, tokens[3]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var infantryGroup = Map.Technos[cell] as InfantryGroup;
|
||||
@ -920,6 +959,7 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (!int.TryParse(tokens[4], out stoppingPos))
|
||||
{
|
||||
errors.Add(string.Format("Sub-position for infantry '{0}' cannot be parsed; value: '{1}'; skipping.", infantryType.Name, tokens[4]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
if (stoppingPos < Globals.NumInfantryStops)
|
||||
@ -928,6 +968,7 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (!int.TryParse(tokens[6], out dirValue))
|
||||
{
|
||||
errors.Add(string.Format("Direction for infantry '{0}' cannot be parsed; value: '{1}'; skipping.", infantryType.Name, tokens[6]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var direction = (byte)((dirValue + 0x08) & ~0x0F);
|
||||
@ -936,11 +977,13 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (!checkTrigs.Contains(tokens[7]))
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' links to unknown trigger '{1}'; clearing trigger.", infantryType.Name, tokens[7]));
|
||||
modified = true;
|
||||
tokens[7] = Trigger.None;
|
||||
}
|
||||
else if (!checkUnitTrigs.Contains(tokens[7]))
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' links to trigger '{1}' which does not contain an event applicable to infantry; clearing trigger.", infantryType.Name, tokens[7]));
|
||||
modified = true;
|
||||
tokens[7] = Trigger.None;
|
||||
}
|
||||
infantryGroup.Infantry[stoppingPos] = new Infantry(infantryGroup)
|
||||
@ -956,11 +999,13 @@ namespace MobiusEditor.TiberianDawn
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' overlaps another infantry at position {1} in cell {2}; skipping.", infantryType.Name, stoppingPos, cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' has invalid position {1} in cell {2}; skipping.", infantryType.Name, stoppingPos, cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -969,22 +1014,27 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (techno is Building building)
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' overlaps structure '{1}' in cell {2}; skipping.", infantryType.Name, building.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Overlay overlay)
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' overlaps overlay '{1}' in cell {2}; skipping.", infantryType.Name, overlay.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Terrain terrain)
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' overlaps terrain '{1}' in cell {2}; skipping.", infantryType.Name, terrain.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Unit unit)
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' overlaps unit '{1}' in cell {2}; skipping.", infantryType.Name, unit.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' overlaps unknown techno in cell {1}; skipping.", infantryType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -993,10 +1043,12 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (tokens.Length < 2)
|
||||
{
|
||||
errors.Add(string.Format("Infantry entry '{0}' has wrong number of tokens (expecting 8).", Key));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Infantry '{0}' has wrong number of tokens (expecting 8).", tokens[1]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1013,24 +1065,28 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (unitType == null)
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' references unknown unit.", tokens[1]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int strength;
|
||||
if (!int.TryParse(tokens[2], out strength))
|
||||
{
|
||||
errors.Add(string.Format("Strength for unit '{0}' cannot be parsed; value: '{1}'; skipping.", unitType.Name, tokens[2]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int cell;
|
||||
if (!int.TryParse(tokens[3], out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for unit '{0}' cannot be parsed; value: '{1}'; skipping.", unitType.Name, tokens[3]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int dirValue;
|
||||
if (!int.TryParse(tokens[4], out dirValue))
|
||||
{
|
||||
errors.Add(string.Format("Direction for unit '{0}' cannot be parsed; value: '{1}'; skipping.", unitType.Name, tokens[4]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var direction = (byte)((dirValue + 0x08) & ~0x0F);
|
||||
@ -1053,11 +1109,13 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (!checkTrigs.Contains(tokens[6]))
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' links to unknown trigger '{1}'; clearing trigger.", unitType.Name, newUnit.Trigger));
|
||||
modified = true;
|
||||
newUnit.Trigger = Trigger.None;
|
||||
}
|
||||
else if (!checkUnitTrigs.Contains(tokens[6]))
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' links to trigger '{1}' which does not contain an event applicable to units; clearing trigger.", unitType.Name, newUnit.Trigger));
|
||||
modified = true;
|
||||
newUnit.Trigger = Trigger.None;
|
||||
}
|
||||
}
|
||||
@ -1067,26 +1125,32 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (techno is Building building)
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' overlaps structure '{1}' in cell {2}; skipping.", unitType.Name, building.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Overlay overlay)
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' overlaps overlay '{1}' in cell {2}; skipping.", unitType.Name, overlay.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Terrain terrain)
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' overlaps terrain '{1}' in cell {2}; skipping.", unitType.Name, terrain.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is InfantryGroup infantry)
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' overlaps infantry in cell {1}; skipping.", unitType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Unit unit)
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' overlaps unit '{1}' in cell {2}; skipping.", unitType.Name, unit.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' overlaps unknown techno in cell {1}; skipping.", unitType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1095,10 +1159,12 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (tokens.Length < 2)
|
||||
{
|
||||
errors.Add(string.Format("Unit entry '{0}' has wrong number of tokens (expecting 7).", Key));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Unit '{0}' has wrong number of tokens (expecting 7).", tokens[1]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1117,24 +1183,28 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (aircraftType == null)
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' references unknown aircraft.", tokens[1]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int strength;
|
||||
if (!int.TryParse(tokens[2], out strength))
|
||||
{
|
||||
errors.Add(string.Format("Strength for aircraft '{0}' cannot be parsed; value: '{1}'; skipping.", aircraftType.Name, tokens[2]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int cell;
|
||||
if (!int.TryParse(tokens[3], out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for aircraft '{0}' cannot be parsed; value: '{1}'; skipping.", aircraftType.Name, tokens[3]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int dirValue;
|
||||
if (!int.TryParse(tokens[4], out dirValue))
|
||||
{
|
||||
errors.Add(string.Format("Direction for aircraft '{0}' cannot be parsed; value: '{1}'; skipping.", aircraftType.Name, tokens[4]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var direction = (byte)((dirValue + 0x08) & ~0x0F);
|
||||
@ -1152,26 +1222,32 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (techno is Building building)
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' overlaps structure '{1}' in cell {2}; skipping.", aircraftType.Name, building.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Overlay overlay)
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' overlaps overlay '{1}' in cell {2}; skipping.", aircraftType.Name, overlay.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Terrain terrain)
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' overlaps terrain '{1}' in cell {2}; skipping.", aircraftType.Name, terrain.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is InfantryGroup infantry)
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' overlaps infantry in cell {1}; skipping.", aircraftType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Unit unit)
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' overlaps unit '{1}' in cell {2}; skipping.", aircraftType.Name, unit.Type.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' overlaps unknown techno in cell {1}; skipping.", aircraftType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1180,10 +1256,12 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (tokens.Length < 2)
|
||||
{
|
||||
errors.Add(string.Format("Aircraft entry '{0}' has wrong number of tokens (expecting 6).", Key));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Aircraft '{0}' has wrong number of tokens (expecting 6).", tokens[1]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1200,29 +1278,34 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (buildingType == null)
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' references unknown structure.", tokens[1]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
if (Globals.FilterTheaterObjects && buildingType.Theaters != null && !buildingType.Theaters.Contains(Map.Theater))
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' is not available in the set theater; skipping.", buildingType.Name));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int strength;
|
||||
if (!int.TryParse(tokens[2], out strength))
|
||||
{
|
||||
errors.Add(string.Format("Strength for structure '{0}' cannot be parsed; value: '{1}'; skipping.", buildingType.Name, tokens[2]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int cell;
|
||||
if (!int.TryParse(tokens[3], out cell))
|
||||
{
|
||||
errors.Add(string.Format("Cell for structure '{0}' cannot be parsed; value: '{1}'; skipping.", buildingType.Name, tokens[3]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int dirValue;
|
||||
if (!int.TryParse(tokens[4], out dirValue))
|
||||
{
|
||||
errors.Add(string.Format("Direction for structure '{0}' cannot be parsed; value: '{1}'; skipping.", buildingType.Name, tokens[4]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
var direction = (byte)((dirValue + 0x08) & ~0x0F);
|
||||
@ -1239,18 +1322,20 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (!checkTrigs.Contains(tokens[5]))
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' links to unknown trigger '{1}'; clearing trigger.", buildingType.Name, tokens[5]));
|
||||
modified = true;
|
||||
newBld.Trigger = Trigger.None;
|
||||
}
|
||||
else if (!checkStrcTrigs.Contains(tokens[5]))
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' links to trigger '{1}' which does not contain an event applicable to structures; clearing trigger.", buildingType.Name, tokens[5]));
|
||||
modified = true;
|
||||
newBld.Trigger = Trigger.None;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var techno = Map.FindBlockingObject(cell, buildingType, out int blockingCell);
|
||||
string reportCell = blockingCell == -1 ? cell.ToString() : "<unknown>";
|
||||
string reportCell = blockingCell == -1 ? "<unknown>" : cell.ToString();
|
||||
if (techno is Building building)
|
||||
{
|
||||
bool onBib = false;
|
||||
@ -1263,37 +1348,45 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (onBib)
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps bib of structure '{2}' in cell {3}; skipping.", buildingType.Name, cell, building.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps structure '{2}' in cell {3}; skipping.", buildingType.Name, cell, building.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else if (techno is Overlay overlay)
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps overlay '{2}' in cell {3}; skipping.", buildingType.Name, cell, overlay.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Terrain terrain)
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps terrain '{2}' in cell {3}; skipping.", buildingType.Name, cell, terrain.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is InfantryGroup infantry)
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps infantry in cell {2}; skipping.", buildingType.Name, cell, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else if (techno is Unit unit)
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps unit '{2}' in cell {3}; skipping.", buildingType.Name, cell, unit.Type.Name, reportCell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (blockingCell != -1)
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps unknown techno in cell {2}; skipping.", buildingType.Name, cell, blockingCell));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' placed on cell {1} overlaps unknown techno; skipping.", buildingType.Name, cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1303,10 +1396,12 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (tokens.Length < 2)
|
||||
{
|
||||
errors.Add(string.Format("Structure entry '{0}' has wrong number of tokens (expecting 6).", Key));
|
||||
modified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Structure '{0}' has wrong number of tokens (expecting 6).", tokens[1]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1327,12 +1422,14 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (Globals.FilterTheaterObjects && buildingType.Theaters != null && !buildingType.Theaters.Contains(Map.Theater))
|
||||
{
|
||||
errors.Add(string.Format("Base rebuild entry {0} references structure '{1}' which is not available in the set theater; skipping.", priority, buildingType.Name));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
int coord;
|
||||
if (!int.TryParse(tokens[1], out coord))
|
||||
{
|
||||
errors.Add(string.Format("Coordinates for base rebuild entry '{0}' cannot be parsed; value: '{1}'; skipping.", buildingType.Name, tokens[1]));
|
||||
modified = true;
|
||||
continue;
|
||||
}
|
||||
// Preparations for megamap support.
|
||||
@ -1357,16 +1454,19 @@ namespace MobiusEditor.TiberianDawn
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Base rebuild entry {0} references unknown structure '{1}'.", priority, tokens[0]));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Base rebuild entry {0} has wrong number of tokens (expecting 2).", priority));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else if (!Key.Equals("Count", StringComparison.CurrentCultureIgnoreCase))
|
||||
{
|
||||
errors.Add(string.Format("Invalid base rebuild priority '{0}' (expecting integer).", Key));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1391,22 +1491,26 @@ namespace MobiusEditor.TiberianDawn
|
||||
if (cell != -1)
|
||||
{
|
||||
errors.Add(string.Format("Waypoint {0} cell value {1} out of range (expecting between {2} and {3}).", waypoint, cell, 0, Map.Metrics.Length - 1));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cell != -1)
|
||||
{
|
||||
errors.Add(string.Format("Waypoint {0} out of range (expecting between {1} and {2}).", waypoint, 0, Map.Waypoints.Length - 1));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Waypoint {0} has invalid cell '{1}' (expecting integer).", waypoint, Value));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Invalid waypoint '{0}' (expecting integer).", Key));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1431,21 +1535,25 @@ namespace MobiusEditor.TiberianDawn
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Cell trigger {0} links to trigger '{1}' which does not contain a placeable event; skipping.", cell, Value));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Cell trigger {0} links to unknown trigger '{1}'; skipping.", cell, Value));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Cell trigger {0} is outside map bounds; skipping.", cell));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errors.Add(string.Format("Invalid cell trigger '{0}' (expecting integer).", Key));
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1484,8 +1592,8 @@ namespace MobiusEditor.TiberianDawn
|
||||
Map.TeamTypes.Sort((x, y) => comparer.Compare(x.Name, y.Name));
|
||||
extraSections = ini.Sections;
|
||||
bool switchedToSolo = !forSole && forceSoloMission && !Map.BasicSection.SoloMission
|
||||
&& reorderedTriggers.Any(t => t.Action1.ActionType == ActionTypes.ACTION_WIN)
|
||||
&& reorderedTriggers.Any(t => t.Action1.ActionType == ActionTypes.ACTION_LOSE);
|
||||
&& ((reorderedTriggers.Any(t => t.Action1.ActionType == ActionTypes.ACTION_WIN) && reorderedTriggers.Any(t => t.Action1.ActionType == ActionTypes.ACTION_LOSE))
|
||||
|| reorderedTriggers.Any(t => t.Event1.EventType == EventTypes.EVENT_ANY && t.Action1.ActionType == ActionTypes.ACTION_WINLOSE));
|
||||
if (switchedToSolo)
|
||||
{
|
||||
errors.Insert(0, "Filename detected as classic single player mission format, and win and lose trigger detected. Applying \"SoloMission\" flag.");
|
||||
@ -1495,7 +1603,7 @@ namespace MobiusEditor.TiberianDawn
|
||||
return errors;
|
||||
}
|
||||
|
||||
protected IEnumerable<string> LoadBinaryClassic(BinaryReader reader)
|
||||
protected IEnumerable<string> LoadBinaryClassic(BinaryReader reader, ref bool modified)
|
||||
{
|
||||
var errors = new List<string>();
|
||||
Map.Templates.Clear();
|
||||
@ -1505,28 +1613,38 @@ namespace MobiusEditor.TiberianDawn
|
||||
{
|
||||
var typeValue = reader.ReadByte();
|
||||
var iconValue = reader.ReadByte();
|
||||
TemplateType templateType = ChecKTemplateType(typeValue, iconValue, x, y, errors);
|
||||
TemplateType templateType = ChecKTemplateType(typeValue, iconValue, x, y, errors, ref modified);
|
||||
Map.Templates[y, x] = (templateType != null) ? new Template { Type = templateType, Icon = iconValue } : null;
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
protected IEnumerable<string> LoadBinaryMega(BinaryReader reader)
|
||||
protected IEnumerable<string> LoadBinaryMega(BinaryReader reader, ref bool modified)
|
||||
{
|
||||
var errors = new List<string>();
|
||||
Map.Templates.Clear();
|
||||
long dataLen = reader.BaseStream.Length;
|
||||
int mapLen = Map.Metrics.Length;
|
||||
int mapWidth = Map.Metrics.Width;
|
||||
int lastCell = -1;
|
||||
while (reader.BaseStream.Position < dataLen)
|
||||
{
|
||||
byte cellLow = reader.ReadByte();
|
||||
byte cellHi = reader.ReadByte();
|
||||
int cell = (cellHi << 8) | cellLow;
|
||||
if (cell == lastCell)
|
||||
{
|
||||
errors.Add(String.Format("Map contains duplicate cell numbers.", cell));
|
||||
}
|
||||
else if (cell < lastCell)
|
||||
{
|
||||
errors.Add(String.Format("Map cell numbers are not in sequential order.", cell));
|
||||
}
|
||||
if (cell > mapLen)
|
||||
{
|
||||
errors.Add(String.Format("Map contains cell number '{0}' which is too large for a TD MegaMap.", cell));
|
||||
modified = true;
|
||||
// Just abort I guess?
|
||||
break;
|
||||
}
|
||||
@ -1534,13 +1652,13 @@ namespace MobiusEditor.TiberianDawn
|
||||
int x = cell % mapWidth;
|
||||
byte typeValue = reader.ReadByte();
|
||||
byte iconValue = reader.ReadByte();
|
||||
TemplateType templateType = ChecKTemplateType(typeValue, iconValue, x, y, errors);
|
||||
TemplateType templateType = ChecKTemplateType(typeValue, iconValue, x, y, errors, ref modified);
|
||||
Map.Templates[y,x] = (templateType != null) ? new Template { Type = templateType, Icon = iconValue } : null;
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
protected TemplateType ChecKTemplateType(int typeValue, int iconValue, int x, int y, List<string> errors)
|
||||
protected TemplateType ChecKTemplateType(int typeValue, int iconValue, int x, int y, List<string> errors, ref bool modified)
|
||||
{
|
||||
TemplateType templateType = Map.TemplateTypes.Where(t => t.Equals(typeValue)).FirstOrDefault();
|
||||
// Prevent loading of illegal tiles.
|
||||
@ -1555,22 +1673,26 @@ namespace MobiusEditor.TiberianDawn
|
||||
else if (templateType.Theaters != null && !templateType.Theaters.Contains(Map.Theater))
|
||||
{
|
||||
errors.Add(String.Format("Template '{0}' at cell [{1},{2}] is not available in the set theater; clearing.", templateType.Name.ToUpper(), x, y));
|
||||
modified = true;
|
||||
templateType = null;
|
||||
}
|
||||
else if (iconValue >= templateType.NumIcons)
|
||||
{
|
||||
errors.Add(String.Format("Template '{0}' at cell [{1},{2}] has an icon set ({3}) that is outside its icons range; clearing.", templateType.Name.ToUpper(), x, y, iconValue));
|
||||
modified = true;
|
||||
templateType = null;
|
||||
}
|
||||
else if (!isRandom && templateType.IconMask != null && !templateType.IconMask[iconValue / templateType.IconWidth, iconValue % templateType.IconWidth])
|
||||
{
|
||||
errors.Add(String.Format("Template '{0}' at cell [{1},{2}] has an icon set ({3}) that is not part of its placeable cells; clearing.", templateType.Name.ToUpper(), x, y, iconValue));
|
||||
modified = true;
|
||||
templateType = null;
|
||||
}
|
||||
}
|
||||
else if (typeValue != 0xFF)
|
||||
{
|
||||
errors.Add(String.Format("Unknown template value {0:X2} at cell [{1},{2}]; clearing.", typeValue, x, y));
|
||||
modified = true;
|
||||
}
|
||||
return templateType;
|
||||
}
|
||||
@ -1585,9 +1707,9 @@ namespace MobiusEditor.TiberianDawn
|
||||
return Save(path, fileType, false, customPreview);
|
||||
}
|
||||
|
||||
public bool Save(string path, FileType fileType, bool forSS, Bitmap customPreview)
|
||||
public bool Save(string path, FileType fileType, bool forSole, Bitmap customPreview)
|
||||
{
|
||||
String errors = Validate(forSS);
|
||||
String errors = Validate(forSole);
|
||||
if (errors != null)
|
||||
{
|
||||
MessageBox.Show(errors, "Validation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
@ -1603,7 +1725,7 @@ namespace MobiusEditor.TiberianDawn
|
||||
SaveINI(ini, fileType, path);
|
||||
using (var iniWriter = new StreamWriter(iniPath))
|
||||
{
|
||||
if (forSS)
|
||||
if (forSole)
|
||||
{
|
||||
iniWriter.Write(ini.ToString());
|
||||
}
|
||||
@ -1624,8 +1746,8 @@ namespace MobiusEditor.TiberianDawn
|
||||
SaveBinaryMega(binWriter);
|
||||
}
|
||||
}
|
||||
// None of this junk for SS.
|
||||
if (!forSS && (!Map.BasicSection.SoloMission || !Properties.Settings.Default.NoMetaFilesForSinglePlay))
|
||||
// None of this junk for Sole Survivor.
|
||||
if (!forSole && (!Map.BasicSection.SoloMission || !Properties.Settings.Default.NoMetaFilesForSinglePlay))
|
||||
{
|
||||
var tgaPath = Path.ChangeExtension(path, ".tga");
|
||||
var jsonPath = Path.ChangeExtension(path, ".json");
|
||||
@ -1657,9 +1779,9 @@ namespace MobiusEditor.TiberianDawn
|
||||
using (var iniWriter = new StreamWriter(iniStream))
|
||||
using (var binWriter = new BinaryWriter(binStream))
|
||||
using (var jsonWriter = new JsonTextWriter(new StreamWriter(jsonStream)))
|
||||
using (var megafileBuilder = new MegafileBuilder(@"", path))
|
||||
using (var megafileBuilder = new MegafileBuilder(String.Empty, path))
|
||||
{
|
||||
if (forSS)
|
||||
if (forSole)
|
||||
{
|
||||
iniWriter.Write(ini.ToString());
|
||||
}
|
||||
@ -1790,7 +1912,7 @@ namespace MobiusEditor.TiberianDawn
|
||||
basic.Lose = GeneralUtils.TrimRemarks(basic.Lose, true, cutfrom);
|
||||
if (String.IsNullOrWhiteSpace(basic.Name))
|
||||
{
|
||||
string[] name = Path.GetFileNameWithoutExtension(fileName).Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
string[] name = Path.GetFileNameWithoutExtension(fileName).Split(new[] { ' ', '_' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
for (Int32 i = 0; i < name.Length; i++)
|
||||
{
|
||||
String word = name[i];
|
||||
|
@ -46,8 +46,8 @@ namespace MobiusEditor.TiberianDawn
|
||||
public static readonly OverlayType Road2 = new OverlayType(19, "roadfullslab", "Concrete Road (full)", null, OverlayTypeFlag.Decoration, "road", 1);
|
||||
// Not available to place down sadly: even the ini read for it in the game code only succeeds if 'IsGross' is enabled.
|
||||
//public static readonly OverlayType Squishy = new OverlayType(19, "SQUISH", OverlayTypeFlag.Decoration);
|
||||
public static readonly OverlayType V12 = new OverlayType(20, "v12", "TEXT_STRUCTURE_TITLE_CIV12", new[] { TheaterTypes.Temperate });
|
||||
public static readonly OverlayType V13 = new OverlayType(21, "v13", "TEXT_STRUCTURE_TITLE_CIV12", new[] { TheaterTypes.Temperate });
|
||||
public static readonly OverlayType V12 = new OverlayType(20, "v12", "TEXT_STRUCTURE_TITLE_CIV12", new[] { TheaterTypes.Temperate, TheaterTypes.Winter });
|
||||
public static readonly OverlayType V13 = new OverlayType(21, "v13", "TEXT_STRUCTURE_TITLE_CIV12", new[] { TheaterTypes.Temperate, TheaterTypes.Winter });
|
||||
public static readonly OverlayType V14 = new OverlayType(22, "v14", "TEXT_STRUCTURE_TITLE_CIV13", new[] { TheaterTypes.Temperate, TheaterTypes.Winter });
|
||||
public static readonly OverlayType V15 = new OverlayType(23, "v15", "TEXT_STRUCTURE_TITLE_CIV14", new[] { TheaterTypes.Temperate, TheaterTypes.Winter });
|
||||
public static readonly OverlayType V16 = new OverlayType(24, "v16", "TEXT_STRUCTURE_TITLE_CIV15", new[] { TheaterTypes.Temperate, TheaterTypes.Winter });
|
||||
|
@ -26,7 +26,8 @@ namespace MobiusEditor.TiberianDawn
|
||||
|
||||
public static readonly TheaterType Desert = new TheaterType(0, "desert", "TD_Terrain_Desert".Yield().Concat(commonTilesets));
|
||||
public static readonly TheaterType Temperate = new TheaterType(2, "temperate", "TD_Terrain_Temperate".Yield().Concat(commonTilesets));
|
||||
public static readonly TheaterType Winter = new TheaterType(2, "winter", "TD_Terrain_Winter".Yield().Concat(commonTilesets));
|
||||
// Winter seems to fall back on Temperate for the Haystack graphics.
|
||||
public static readonly TheaterType Winter = new TheaterType(2, "winter", "TD_Terrain_Winter".Yield().Concat(commonTilesets).Concat("TD_Terrain_Temperate".Yield()));
|
||||
|
||||
private static TheaterType[] Types;
|
||||
|
||||
|
@ -65,7 +65,7 @@ namespace MobiusEditor.Tools.Dialogs
|
||||
this.tableLayoutPanel4.RowCount = 2;
|
||||
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel4.Size = new System.Drawing.Size(145, 77);
|
||||
this.tableLayoutPanel4.Size = new System.Drawing.Size(200, 77);
|
||||
this.tableLayoutPanel4.TabIndex = 3;
|
||||
//
|
||||
// lblWaypoint
|
||||
@ -86,7 +86,7 @@ namespace MobiusEditor.Tools.Dialogs
|
||||
this.waypointCombo.FormattingEnabled = true;
|
||||
this.waypointCombo.Location = new System.Drawing.Point(61, 3);
|
||||
this.waypointCombo.Name = "waypointCombo";
|
||||
this.waypointCombo.Size = new System.Drawing.Size(81, 21);
|
||||
this.waypointCombo.Size = new System.Drawing.Size(136, 21);
|
||||
this.waypointCombo.TabIndex = 1;
|
||||
//
|
||||
// btnJumpTo
|
||||
@ -94,7 +94,7 @@ namespace MobiusEditor.Tools.Dialogs
|
||||
this.btnJumpTo.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.btnJumpTo.Location = new System.Drawing.Point(61, 30);
|
||||
this.btnJumpTo.Name = "btnJumpTo";
|
||||
this.btnJumpTo.Size = new System.Drawing.Size(81, 23);
|
||||
this.btnJumpTo.Size = new System.Drawing.Size(136, 23);
|
||||
this.btnJumpTo.TabIndex = 2;
|
||||
this.btnJumpTo.Text = "Jump to...";
|
||||
this.btnJumpTo.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@ -102,6 +102,7 @@ namespace MobiusEditor.Tools.Dialogs
|
||||
//
|
||||
// WaypointsToolDialog
|
||||
//
|
||||
this.AcceptButton = this.btnJumpTo;
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.AutoSize = true;
|
||||
|
@ -33,7 +33,7 @@ namespace MobiusEditor.Tools
|
||||
/// Layers that are not painted by the PostRenderMap function on ViewTool level because they are handled
|
||||
/// at a specific point in the PostRenderMap override by the implementing tool.
|
||||
/// </summary>
|
||||
protected override MapLayerFlag ManuallyHandledLayers => MapLayerFlag.WaypointsIndic;
|
||||
protected override MapLayerFlag ManuallyHandledLayers => MapLayerFlag.WaypointsIndic | MapLayerFlag.TechnoTriggers;
|
||||
|
||||
private readonly ComboBox waypointCombo;
|
||||
private readonly Button jumpToButton;
|
||||
@ -246,6 +246,9 @@ namespace MobiusEditor.Tools
|
||||
case Keys.Up:
|
||||
newVal = Math.Max(curVal - 1, 0);
|
||||
break;
|
||||
case Keys.Enter:
|
||||
JumpToWaypoint();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (newVal.HasValue && curVal != newVal.Value)
|
||||
@ -393,29 +396,37 @@ namespace MobiusEditor.Tools
|
||||
|
||||
private void JumpToButton_Click(Object sender, EventArgs e)
|
||||
{
|
||||
if (waypointCombo.SelectedItem is Waypoint wp)
|
||||
JumpToWaypoint();
|
||||
}
|
||||
|
||||
protected void JumpToWaypoint()
|
||||
{
|
||||
if (!(waypointCombo.SelectedItem is Waypoint wp))
|
||||
{
|
||||
int cell = wp.Cell.GetValueOrDefault(-1);
|
||||
if (cell != -1)
|
||||
{
|
||||
Point cellPoint;
|
||||
if (RenderMap.Metrics.GetLocation(cell, out cellPoint))
|
||||
{
|
||||
int scaleFull = Math.Min(mapPanel.ClientRectangle.Width, mapPanel.ClientRectangle.Height);
|
||||
bool isWidth = scaleFull == mapPanel.ClientRectangle.Width;
|
||||
double mapSize = isWidth ? map.Metrics.Width : map.Metrics.Height;
|
||||
// pixels per tile at zoom level 1.
|
||||
double basicTileSize = scaleFull / mapSize;
|
||||
// Convert cell position to actual position on image.
|
||||
int cellX = (int)Math.Round(basicTileSize * mapPanel.Zoom * (cellPoint.X + 0.5));
|
||||
int cellY = (int)Math.Round(basicTileSize * mapPanel.Zoom * (cellPoint.Y + 0.5));
|
||||
// Get location to use to center the waypoint on the screen.
|
||||
int x = cellX - mapPanel.ClientRectangle.Width / 2;
|
||||
int y = cellY - mapPanel.ClientRectangle.Height / 2;
|
||||
mapPanel.AutoScrollPosition = new Point(x,y);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
int cell = wp.Cell.GetValueOrDefault(-1);
|
||||
if (cell == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Point cellPoint;
|
||||
if (!RenderMap.Metrics.GetLocation(cell, out cellPoint))
|
||||
{
|
||||
return;
|
||||
}
|
||||
int scaleFull = Math.Min(mapPanel.ClientRectangle.Width, mapPanel.ClientRectangle.Height);
|
||||
bool isWidth = scaleFull == mapPanel.ClientRectangle.Width;
|
||||
double mapSize = isWidth ? map.Metrics.Width : map.Metrics.Height;
|
||||
// pixels per tile at zoom level 1.
|
||||
double basicTileSize = scaleFull / mapSize;
|
||||
// Convert cell position to actual position on image.
|
||||
int cellX = (int)Math.Round(basicTileSize * mapPanel.Zoom * (cellPoint.X + 0.5));
|
||||
int cellY = (int)Math.Round(basicTileSize * mapPanel.Zoom * (cellPoint.Y + 0.5));
|
||||
// Get location to use to center the waypoint on the screen.
|
||||
int x = cellX - mapPanel.ClientRectangle.Width / 2;
|
||||
int y = cellY - mapPanel.ClientRectangle.Height / 2;
|
||||
mapPanel.AutoScrollPosition = new Point(x, y);
|
||||
}
|
||||
|
||||
protected override void PreRenderMap()
|
||||
@ -458,6 +469,13 @@ namespace MobiusEditor.Tools
|
||||
MapRenderer.RenderAllFootballAreas(graphics, map, Globals.MapTileSize, Globals.MapTileScale, plugin.GameType);
|
||||
MapRenderer.RenderFootballAreaFlags(graphics, plugin.GameType, map, Globals.MapTileSize);
|
||||
}
|
||||
// If the selected waypoint is not a flag, re-render it as opaque.
|
||||
if (selected != null && (plugin.Map.BasicSection.SoloMission || (selected.Flag & WaypointFlag.PlayerStart) != WaypointFlag.PlayerStart))
|
||||
{
|
||||
MapRenderer.Render(plugin.GameType, true, map.Theater, Globals.MapTileSize, map.FlagColors.ToArray(), selected, 1.0f).Item2(graphics);
|
||||
}
|
||||
// Render those here to they are put over the opaque redraw of the current waypoint.
|
||||
MapRenderer.RenderAllTechnoTriggers(graphics, plugin.Map, Globals.MapTileSize, Globals.MapTileScale, Layers);
|
||||
MapRenderer.RenderAllBoundsFromCell(graphics, Globals.MapTileSize,
|
||||
map.Waypoints.Where(wp => wp != selected && wp.Cell.HasValue).Select(wp => wp.Cell.Value), map.Metrics, Color.Orange);
|
||||
MapRenderer.RenderWayPointIndicators(graphics, map, Globals.MapTileSize, Globals.MapTileScale, Color.LightGreen, false, true, selectedRange);
|
||||
|
@ -116,6 +116,14 @@ namespace MobiusEditor.Utility
|
||||
propertyValues.Clear();
|
||||
}
|
||||
|
||||
public void SetValues(T valuesObject)
|
||||
{
|
||||
foreach (var propertyValue in trackableProperties)
|
||||
{
|
||||
TrySetMember(propertyValue.Key, trackableProperties[propertyValue.Key].GetValue(valuesObject));
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary<string, object> GetUndoValues() => propertyValues.ToDictionary(kv => kv.Key, kv => trackableProperties[kv.Key].GetValue(Object));
|
||||
|
||||
public IDictionary<string, object> GetRedoValues() => new Dictionary<string, object>(propertyValues);
|
||||
|
@ -109,8 +109,15 @@ namespace MobiusEditor.Utility
|
||||
fps = 0;
|
||||
tiles = null;
|
||||
Tileset first = null;
|
||||
foreach (var tileset in tilesets.Join(searchTilesets, x => x.Key, y => y, (x, y) => x.Value))
|
||||
// Tilesets are now searched in the given order, allowing accurate defining of main tilesets and fallback tilesets.
|
||||
//foreach (var tileset in tilesets.Join(searchTilesets, x => x.Key, y => y, (x, y) => x.Value))
|
||||
foreach (string searchTileset in searchTilesets)
|
||||
{
|
||||
if (!tilesets.ContainsKey(searchTileset))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Tileset tileset = tilesets[searchTileset];
|
||||
if (generateFallback && first == null)
|
||||
{
|
||||
first = tileset;
|
||||
|
16
README.md
16
README.md
@ -1,4 +1,4 @@
|
||||
## C&C Tiberian Dawn and Red Alert Map Editor
|
||||
## Mobius Map Editor
|
||||
|
||||
An enhanced version of the C&C Tiberian Dawn and Red Alert Map Editor based on the source code released by Electronic Arts. The goal of the project is simply to improve the usability and convenience of the map editor, fix bugs, improve and clean its code-base, enhance compatibility with different kinds of systems and enhance the editor's support for mods.
|
||||
|
||||
@ -12,7 +12,7 @@ Right now, I'm not really looking into making this a joint project. Specific bug
|
||||
|
||||
**DO NOT unpack this in the C&C Remastered Collection's install folder.** It is absolutely unnecessary to overwrite any files of the installed game.
|
||||
|
||||
Simply unpack the editor into a new folder on your disk somewhere. On first startup, it will automatically try to detect the folder in which the game is installed, and if it can't find it, it will show a popup asking you to locate it.
|
||||
Simply unpack the editor into a new folder on your disk somewhere. On first startup, it will automatically try to detect the folder in which the game is installed, and if it can't find it, it will show a popup asking you to locate it. Note that this autodetect only works on Steam installations of the game.
|
||||
|
||||
---
|
||||
|
||||
@ -38,7 +38,7 @@ The file "CnCTDRAMapEditor.exe.config" contains settings to customise the editor
|
||||
|
||||
### Editor options:
|
||||
|
||||
* **ModsToLoad**: semicolon (or comma) separated list of mod entries. A mod entry can either be a Steam workshop ID, or a path of the type "Tiberian_Dawn\ModName" or "Red_Alert\ModName". The paths will initially be looked up under My Documents, but the loading system will also check the Steam workshop files, and use the game prefix part to verify the mod's targeted game. A mod will only be applied to the editor when a map of its targeted game is opened. Note that mods can only apply graphical changes from the tileset and house color xml files; the editor can't read any data from compiled dll files.
|
||||
* **ModsToLoadTD** / **ModsToLoadRA** / **ModsToLoadSS**: semicolon (or comma) separated list of mod entries for each supported game. A mod entry can either be a Steam workshop ID, or a folder name. The paths will initially be looked up in the mods folder of the respective game in the CnCRemastered\mods\ folder under your Documents folder, but the loading system will also check the Steam workshop files for a matching mod. Sole Survivor will use Tiberian Dawn mods. Note that mods can only apply graphical changes from the tileset and house color xml files; the editor can't read any data from compiled dll files. This mods system is mostly meant to apply graphical fixes to the editor.
|
||||
* **MapScale**: Scaling multiplier for the size at which assets are rendered on the map; higher means lower quality. This will make the UI more responsive. Negative values will enable smooth scaling, which gives nicer graphics but will make the UI noticeable _less_ responsive. Defaults to 0.5.
|
||||
* **PreviewScale**: Scaling multiplier for the size at which assets are rendered on the preview tools. Negative values will enable smooth scaling, but this usually doesn't look good on the upscaled preview graphics. Defaults to 1.
|
||||
* **ExportScale**: Scaling multiplier for the size at which an exported image will be generated through "Tools" → "Export As Image". Negative values will enable smooth scaling. Defaults to -0.5.
|
||||
@ -47,7 +47,7 @@ The file "CnCTDRAMapEditor.exe.config" contains settings to customise the editor
|
||||
* **MaxMapTileTextureSize**: Maximum for the size of the tiles shown on the Map tool. Leave on 0 to disable.
|
||||
* **UndoRedoStackSize**: The amount of undo/redo actions stored in memory. Defaults to 50.
|
||||
|
||||
The **ModsToLoad** setting will have the `Tiberian_Dawn\ConcretePavementTD` mod set by default, to complete the incomplete TD Remastered graphics set, meaning it will automatically be loaded if found.
|
||||
The **ModsToLoadTD** and **ModsToLoadSS** settings will have the `ConcretePavementTD` mod set by default, to complete the incomplete TD Remastered graphics set, meaning the mod will automatically be loaded if found. Note that the editor has no way to check whether mods are enabled in the game, so that makes no difference.
|
||||
|
||||
You can find the mod [on the Steam workshop](https://steamcommunity.com/sharedfiles/filedetails/?id=2844969675) and [on ModDB](https://www.moddb.com/games/command-conquer-remastered/addons/concretepavementtd).
|
||||
|
||||
@ -366,6 +366,14 @@ These options are all enabled by default, but can be disabled if you wish. Use t
|
||||
* Changed the editor name in the title to "Mobius Map Editor".
|
||||
* Red Alert maps are now specifically detected on the presence of the "[MapPack]" section. If this is not present, and there is no .bin file, it loads as TD map without map templates.
|
||||
* Sole Survivor maps now don't support owned objects (infantry, units, structures) by default, though this can be re-enabled using the "NoOwnedObjectsInSole" setting in "CnCTDRAMapEditor.exe.config".
|
||||
* Restricted Red Alert trigger and teamtype names to the same lengths as Tiberian Dawn; 4 for triggers, 8 for Teamtypes.
|
||||
* Pressing [Enter] in Waypoints mode will now jump to the selected waypoint.
|
||||
* Fixed a bug in the overlap detection system that made it always give "<unknown>" for the overlapped cell on Terrain objects.
|
||||
* Split mods up into ModsToLoadTD, ModsToLoadRA and ModsToLoadSS.
|
||||
* The Civilian buildings V12 and V13 (haystacks) are now also available in TD Winter theater.
|
||||
* The trigger "Any: Cap=Win,Des=Lose" is now also seen as flag to autodetect classic single play scenarios.
|
||||
* Like the game, the editor will now fall back to Temperate graphics when not finding the Winter graphics for the Haystack buildings/overlays.
|
||||
* Fixed triggers being selectable on unbuilt buildings.
|
||||
|
||||
### Possible future features
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user