diff --git a/OpenRA.Editor/Form1.Designer.cs b/OpenRA.Editor/Form1.Designer.cs index 82f7f76bbe..854561d7d7 100755 --- a/OpenRA.Editor/Form1.Designer.cs +++ b/OpenRA.Editor/Form1.Designer.cs @@ -82,6 +82,9 @@ namespace OpenRA.Editor this.statusStrip1 = new System.Windows.Forms.StatusStrip(); this.toolStripStatusLabelFiller = new System.Windows.Forms.ToolStripStatusLabel(); this.toolStripStatusLabelMousePosition = new System.Windows.Forms.ToolStripStatusLabel(); + this.copySelectionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); + this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); this.splitContainer1.SuspendLayout(); @@ -417,8 +420,11 @@ namespace OpenRA.Editor this.resizeToolStripMenuItem, this.showActorNamesToolStripMenuItem, this.showGridToolStripMenuItem, + this.toolStripSeparator5, this.fixOpenAreasToolStripMenuItem, - this.setupDefaultPlayersMenuItem}); + this.setupDefaultPlayersMenuItem, + this.toolStripSeparator4, + this.copySelectionToolStripMenuItem}); this.mapToolStripMenuItem.Name = "mapToolStripMenuItem"; this.mapToolStripMenuItem.Size = new System.Drawing.Size(43, 23); this.mapToolStripMenuItem.Text = "&Map"; @@ -507,6 +513,23 @@ namespace OpenRA.Editor this.toolStripStatusLabelMousePosition.Size = new System.Drawing.Size(22, 17); this.toolStripStatusLabelMousePosition.Text = "0,0"; // + // copySelectionToolStripMenuItem + // + this.copySelectionToolStripMenuItem.Name = "copySelectionToolStripMenuItem"; + this.copySelectionToolStripMenuItem.Size = new System.Drawing.Size(185, 22); + this.copySelectionToolStripMenuItem.Text = "Copy Selection"; + this.copySelectionToolStripMenuItem.Click += new System.EventHandler(this.copySelectionToolStripMenuItem_Click); + // + // toolStripSeparator4 + // + this.toolStripSeparator4.Name = "toolStripSeparator4"; + this.toolStripSeparator4.Size = new System.Drawing.Size(182, 6); + // + // toolStripSeparator5 + // + this.toolStripSeparator5.Name = "toolStripSeparator5"; + this.toolStripSeparator5.Size = new System.Drawing.Size(182, 6); + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -520,9 +543,9 @@ namespace OpenRA.Editor this.Name = "Form1"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "OpenRA Editor"; - this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyUp); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OnFormClosing); this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown); + this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyUp); this.splitContainer1.Panel1.ResumeLayout(false); this.splitContainer1.Panel2.ResumeLayout(false); this.splitContainer1.ResumeLayout(false); @@ -592,6 +615,9 @@ namespace OpenRA.Editor private System.Windows.Forms.Panel panel1; private System.Windows.Forms.FlowLayoutPanel actorPalette; private System.Windows.Forms.ComboBox actorOwnerChooser; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator5; + private System.Windows.Forms.ToolStripSeparator toolStripSeparator4; + private System.Windows.Forms.ToolStripMenuItem copySelectionToolStripMenuItem; } } diff --git a/OpenRA.Editor/Form1.cs b/OpenRA.Editor/Form1.cs index 53351cb450..d3353199df 100755 --- a/OpenRA.Editor/Form1.cs +++ b/OpenRA.Editor/Form1.cs @@ -138,7 +138,8 @@ namespace OpenRA.Editor Rules.LoadRules(manifest, map); tileset = Rules.TileSets[map.Tileset]; tileset.LoadTiles(); - var palette = new Palette(FileSystem.Open(tileset.Palette), true); + int[] ShadowIndex = { 3, 4 }; + var palette = new Palette(FileSystem.Open(tileset.Palette), ShadowIndex); surface1.Bind(map, tileset, palette); // construct the palette of tiles @@ -545,5 +546,10 @@ namespace OpenRA.Editor var player = actorOwnerChooser.SelectedItem as PlayerReference; surface1.NewActorOwner = player.Name; } + + private void copySelectionToolStripMenuItem_Click(object sender, EventArgs e) + { + surface1.CopySelection(); + } } } diff --git a/OpenRA.Editor/Form1.resx b/OpenRA.Editor/Form1.resx index e21860adab..9757275de8 100755 --- a/OpenRA.Editor/Form1.resx +++ b/OpenRA.Editor/Form1.resx @@ -120,13 +120,45 @@ 17, 17 - - 76, 17 - 198, 17 + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 + JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACCklE + QVQ4T6WT30tTUQDHz39QD0UQSpAPIkgPyR60AiUiyoGBL4qZjOyt0tZP9tBDk1AsXIhj93ILdd27DPPH + 3VwrUrdK2ioJHAgVOdoPaQsarBg43L6ec+akuRsEPnw5D4fP5/vlXg4BQHaSf8LjjwdqaTA2cg+y1Ith + qxmi5Tas/SYWk+QRoPgmtNsLcPq7GYX8+XoTqaUL+KR2cAmDxeBgqeBv2NhWzwUFOBk4g5/zRxB3V8Es + 38AtbzuIw/0RLMrMeyhTs2CzGdRtaOTn1dajvLkAR9VKLNvLcHmoExddzSDKzAfkcjkkEtEiOLxoQpdB + z+Er7ScQUg/DL5TD2bsfl5oPoKWnCZ3jehDZGeAC1hwL3uXNs55Jep7Gis/AJWxyTeVe1FXvhq5qH6oP + 7nlw/NoxGByNIKPT77CezSEeD6Pn+jlEIiGk6X8N+F9zyfLYIZzUVUCwT0J36jy9yX83KjDq7zSADE8t + cGB7kpksFt76YDzbgMWVFLzBX0WCTcku8mjiTSm8lkUslcHnH2kK/+aw6k+UCJiESE+9XCApz2Gzu5Gk + sEVy4r6got82vRV5blVbIDyZ21rAZrPmL7w5P5s1KxQWXRFtgU15lV8ge2AbdXPY8pAuEIsXWJ6FtAVW + +SWSmXWssuZ4vnl+s5nNFl1hMLjP8U1bMGR/wS/+N9tf7o6eMpNtADko6xybtEXLAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 + JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAADLklE + QVQ4T3WS60/ScRjFf39CL3rR1ovurduWbbU2t7ZqdlkXt7Lrym6O1VoXcdYqQ54wKlGxABE1CzWF0nIm + lZcoTbyUNJFIzDJSJK+E0qy8wInvz+i2erazfd+cz3m+zw4nTS+FLOeZNim3Vp6UU5sqvf5MSZqnyjhV + pfKUvEx54kqp8rCkWHVQVKSJPHtbs+tUgSYiOicVAMfEqfR1dVFCGSqrX94cHQeN/aXhbyD3Zz91uf3U + 9tFHTQ4fzVtH9BOQVdKcW2F6/eKkWA1zcxu6vUAQMmCzk/3AErLtDyFrrY035z16T3PXin8B5LfqZE6P + HyZzKw5FX+Yh4XtjwZKZGV3lNPIkhhojplON3Uc3S9/Q7LDfADKtKYklMsgTkwV7joixKHQr2Nq2fSET + 5uQwqtsyjcot45R510ozV8f/2iAhsyolCNh9WIyFoRGYHbIGfYN+SVd7Nznzk8ll0FLzKxdZO3xkaOjG + GYUxcIIfRxSlPU4N/rn1fS8JJVlU1WCT3npggVLfAIWuHjJtNRIyjIhTPEKM7D6OSop4RcXpwZ2Wl11l + gHanmze/c36ioc8jyRlFjSzljxl2daI9Pwuv1Cnw9PRjZeQ1cCcSS68Fza6+IXL2fCG7w0ssmc3o2IR8 + gbc1PQU9NUp48sNRcUyAkPBL4AIlUbLk3gEvS6YXrW6p0dx9UZ5n4gHjzBmYAAPPYwRwazeiMXYWqjcs + wLSVInAHRYWq0TEf9Q+NUEsg+fr9t2nF1U71leyqn+u3vPuIl2298HZ2wnxkO5q2LYOtxoKpK86D23tW + r+7zfCVzywAVGT/QVV2LvNDo0Eo0j3mAtbUTiRnFOJ94Axp9LfIKK5Ctq0RDmw9TQuPAsW7bHYNUYLCQ + JL2GRAqjtMDYwV+8wzUAWeY9eIfHYW0fxNodxyGWZeOSPBvzl27C5OXnwG0T5irmr79wgdWTNYyVJFL8 + kAeo8wyBA/rx2jGErBIH0nXPsWmPEHcM9YgURGPS0jMTZfiXGKDfM4Y0fVOgA/UgRQWECTpExaqxUyDF + wuUbJjb4H0AQfxtrDqiweLMUc8LEmLEqnv9zUMzM9B1/cM83lepxTAAAAABJRU5ErkJggg== + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 @@ -260,41 +292,6 @@ z2ki+Wo1CWklROkMCiT8wEm0kXEsCTmrAiTbDtcEpTVdZOS1oDfWk5xZ6RPeQZeUR8zxK0Qe1BO65xjr t0YotXhjAEAeQ7It8ZSESUjkznIq2bYsTGYW29JZxIs2nFEdLOSdfwFwpvLxRKIY2AAAAABJRU5ErkJg gg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 - JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAACCklE - QVQ4T6WT30tTUQDHz39QD0UQSpAPIkgPyR60AiUiyoGBL4qZjOyt0tZP9tBDk1AsXIhj93ILdd27DPPH - 3VwrUrdK2ioJHAgVOdoPaQsarBg43L6ec+akuRsEPnw5D4fP5/vlXg4BQHaSf8LjjwdqaTA2cg+y1Ith - qxmi5Tas/SYWk+QRoPgmtNsLcPq7GYX8+XoTqaUL+KR2cAmDxeBgqeBv2NhWzwUFOBk4g5/zRxB3V8Es - 38AtbzuIw/0RLMrMeyhTs2CzGdRtaOTn1dajvLkAR9VKLNvLcHmoExddzSDKzAfkcjkkEtEiOLxoQpdB - z+Er7ScQUg/DL5TD2bsfl5oPoKWnCZ3jehDZGeAC1hwL3uXNs55Jep7Gis/AJWxyTeVe1FXvhq5qH6oP - 7nlw/NoxGByNIKPT77CezSEeD6Pn+jlEIiGk6X8N+F9zyfLYIZzUVUCwT0J36jy9yX83KjDq7zSADE8t - cGB7kpksFt76YDzbgMWVFLzBX0WCTcku8mjiTSm8lkUslcHnH2kK/+aw6k+UCJiESE+9XCApz2Gzu5Gk - sEVy4r6got82vRV5blVbIDyZ21rAZrPmL7w5P5s1KxQWXRFtgU15lV8ge2AbdXPY8pAuEIsXWJ6FtAVW - +SWSmXWssuZ4vnl+s5nNFl1hMLjP8U1bMGR/wS/+N9tf7o6eMpNtADko6xybtEXLAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAAB6 - JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAAF2+SX8VGAAAACXBIWXMAAAsMAAALDAE/QCLIAAADLklE - QVQ4T3WS60/ScRjFf39CL3rR1ovurduWbbU2t7ZqdlkXt7Lrym6O1VoXcdYqQ54wKlGxABE1CzWF0nIm - lZcoTbyUNJFIzDJSJK+E0qy8wInvz+i2erazfd+cz3m+zw4nTS+FLOeZNim3Vp6UU5sqvf5MSZqnyjhV - pfKUvEx54kqp8rCkWHVQVKSJPHtbs+tUgSYiOicVAMfEqfR1dVFCGSqrX94cHQeN/aXhbyD3Zz91uf3U - 9tFHTQ4fzVtH9BOQVdKcW2F6/eKkWA1zcxu6vUAQMmCzk/3AErLtDyFrrY035z16T3PXin8B5LfqZE6P - HyZzKw5FX+Yh4XtjwZKZGV3lNPIkhhojplON3Uc3S9/Q7LDfADKtKYklMsgTkwV7joixKHQr2Nq2fSET - 5uQwqtsyjcot45R510ozV8f/2iAhsyolCNh9WIyFoRGYHbIGfYN+SVd7Nznzk8ll0FLzKxdZO3xkaOjG - GYUxcIIfRxSlPU4N/rn1fS8JJVlU1WCT3npggVLfAIWuHjJtNRIyjIhTPEKM7D6OSop4RcXpwZ2Wl11l - gHanmze/c36ioc8jyRlFjSzljxl2daI9Pwuv1Cnw9PRjZeQ1cCcSS68Fza6+IXL2fCG7w0ssmc3o2IR8 - gbc1PQU9NUp48sNRcUyAkPBL4AIlUbLk3gEvS6YXrW6p0dx9UZ5n4gHjzBmYAAPPYwRwazeiMXYWqjcs - wLSVInAHRYWq0TEf9Q+NUEsg+fr9t2nF1U71leyqn+u3vPuIl2298HZ2wnxkO5q2LYOtxoKpK86D23tW - r+7zfCVzywAVGT/QVV2LvNDo0Eo0j3mAtbUTiRnFOJ94Axp9LfIKK5Ctq0RDmw9TQuPAsW7bHYNUYLCQ - JL2GRAqjtMDYwV+8wzUAWeY9eIfHYW0fxNodxyGWZeOSPBvzl27C5OXnwG0T5irmr79wgdWTNYyVJFL8 - kAeo8wyBA/rx2jGErBIH0nXPsWmPEHcM9YgURGPS0jMTZfiXGKDfM4Y0fVOgA/UgRQWECTpExaqxUyDF - wuUbJjb4H0AQfxtrDqiweLMUc8LEmLEqnv9zUMzM9B1/cM83lepxTAAAAABJRU5ErkJggg== diff --git a/OpenRA.Editor/Surface.cs b/OpenRA.Editor/Surface.cs index 9185036e87..c6e353d508 100755 --- a/OpenRA.Editor/Surface.cs +++ b/OpenRA.Editor/Surface.cs @@ -38,6 +38,12 @@ namespace OpenRA.Editor public bool ShowActorNames; public bool ShowGrid; + public bool IsPaste { get { return TileSelection != null && ResourceSelection != null; } } + public TileReference[,] TileSelection; + public TileReference[,] ResourceSelection; + public CPos SelectionStart; + public CPos SelectionEnd; + public string NewActorOwner; public event Action AfterChange = () => { }; @@ -59,7 +65,7 @@ namespace OpenRA.Editor Tool = null; } - public void SetTool(ITool tool) { Tool = tool; } + public void SetTool(ITool tool) { Tool = tool; ClearSelection(); } public void BindActorTemplates(IEnumerable templates) { @@ -83,6 +89,8 @@ namespace OpenRA.Editor UpdateStyles(); } + static readonly Pen SelectionPen = new Pen(Color.Blue); + static readonly Pen PastePen = new Pen(Color.Green); static readonly Pen CordonPen = new Pen(Color.Red); int2 MousePos; @@ -182,12 +190,20 @@ namespace OpenRA.Editor } AfterChange(); + ClearSelection(); } void Draw() { - if (Tool != null) Tool.Apply(this); - AfterChange(); + if (Tool != null) + { + Tool.Apply(this); + AfterChange(); + } + else if (IsPaste) + PasteSelection(); + else + SelectionEnd = GetBrushLocationBR(); } protected override void OnMouseDown(MouseEventArgs e) @@ -199,7 +215,12 @@ namespace OpenRA.Editor if (!IsPanning) { if (e.Button == MouseButtons.Right) Erase(); - if (e.Button == MouseButtons.Left) Draw(); + if (e.Button == MouseButtons.Left) + { + Draw(); + if (!IsPaste) + SelectionStart = SelectionEnd = GetBrushLocation(); + } } Invalidate(); @@ -274,6 +295,14 @@ namespace OpenRA.Editor return new CPos(vX / TileSet.TileSize, vY / TileSet.TileSize); } + public CPos GetBrushLocationBR() + { + var vX = (int)Math.Floor((MousePos.X - Offset.X) / Zoom); + var vY = (int)Math.Floor((MousePos.Y - Offset.Y) / Zoom); + return new CPos((vX + TileSet.TileSize - 1) / TileSet.TileSize, + (vY + TileSet.TileSize - 1) / TileSet.TileSize); + } + public void DrawActor(SGraphics g, CPos p, ActorTemplate t, ColorPalette cp) { var centered = t.Appearance == null || !t.Appearance.RelativeToTopLeft; @@ -367,6 +396,25 @@ namespace OpenRA.Editor Map.Bounds.Width * TileSet.TileSize * Zoom, Map.Bounds.Height * TileSet.TileSize * Zoom); + e.Graphics.DrawRectangle(SelectionPen, + (SelectionStart.X * TileSet.TileSize * Zoom) + Offset.X, + (SelectionStart.Y * TileSet.TileSize * Zoom) + Offset.Y, + (SelectionEnd - SelectionStart).X * TileSet.TileSize * Zoom, + (SelectionEnd - SelectionStart).Y * TileSet.TileSize * Zoom); + + if (IsPaste) + { + var loc = GetBrushLocation(); + var width = Math.Abs((SelectionStart - SelectionEnd).X); + var height = Math.Abs((SelectionStart - SelectionEnd).Y); + + e.Graphics.DrawRectangle(PastePen, + (loc.X * TileSet.TileSize * Zoom) + Offset.X, + (loc.Y * TileSet.TileSize * Zoom) + Offset.Y, + width * (TileSet.TileSize * Zoom), + height * (TileSet.TileSize * Zoom)); + } + foreach (var ar in Map.Actors.Value) { if (ActorTemplates.ContainsKey(ar.Value.Type)) @@ -395,6 +443,67 @@ namespace OpenRA.Editor DrawActorBorder(e.Graphics, x.Value.Location(), ActorTemplates[x.Value.Type]); } } + + public void CopySelection() + { + // Grab tiles and resources within selection (doesn't do actors) + var start = SelectionStart; + var end = SelectionEnd; + + if (start == end) return; + + int width = Math.Abs((start - end).X); + int height = Math.Abs((start - end).Y); + + TileSelection = new TileReference[width, height]; + ResourceSelection = new TileReference[width, height]; + + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + //todo: crash prevention + TileSelection[x, y] = Map.MapTiles.Value[start.X + x, start.Y + y]; + ResourceSelection[x, y] = Map.MapResources.Value[start.X + x, start.Y + y]; + } + } + } + + void PasteSelection() + { + var loc = GetBrushLocation(); + var width = Math.Abs((SelectionStart - SelectionEnd).X); + var height = Math.Abs((SelectionStart - SelectionEnd).Y); + + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + var mapX = loc.X + x; + var mapY = loc.Y + y; + + //todo: crash prevention for outside of bounds + Map.MapTiles.Value[mapX, mapY] = TileSelection[x, y]; + Map.MapResources.Value[mapX, mapY] = ResourceSelection[x, y]; + + var ch = new int2(mapX / ChunkSize, mapY / ChunkSize); + if (Chunks.ContainsKey(ch)) + { + Chunks[ch].Dispose(); + Chunks.Remove(ch); + } + } + } + AfterChange(); + } + + void ClearSelection() + { + SelectionStart = CPos.Zero; + SelectionEnd = CPos.Zero; + TileSelection = null; + ResourceSelection = null; + } } static class ActorReferenceExts diff --git a/OpenRA.FileFormats/Exts.cs b/OpenRA.FileFormats/Exts.cs index 9d4216a5ea..f7e6c538aa 100755 --- a/OpenRA.FileFormats/Exts.cs +++ b/OpenRA.FileFormats/Exts.cs @@ -184,6 +184,58 @@ namespace OpenRA return ts.Concat(moreTs); } + public static Dictionary ToDictionaryWithConflictLog(this IEnumerable source, Func keySelector, string debugName, Func logKey, Func logValue) + { + return ToDictionaryWithConflictLog(source, keySelector, x => x, debugName, logKey, logValue); + } + + public static Dictionary ToDictionaryWithConflictLog(this IEnumerable source, Func keySelector, Func elementSelector, string debugName, Func logKey, Func logValue) + { + // Fall back on ToString() if null functions are provided: + logKey = logKey ?? (s => s.ToString()); + logValue = logValue ?? (s => s.ToString()); + + // Try to build a dictionary and log all duplicates found (if any): + var dupKeys = new Dictionary>(); + var d = new Dictionary(); + foreach (var item in source) + { + TKey key = keySelector(item); + TElement element = elementSelector(item); + + // Check for a key conflict: + if (d.ContainsKey(key)) + { + List dupKeyMessages; + if (!dupKeys.TryGetValue(key, out dupKeyMessages)) + { + // Log the initial conflicting value already inserted: + dupKeyMessages = new List(); + dupKeyMessages.Add(logValue(d[key])); + dupKeys.Add(key, dupKeyMessages); + } + + // Log this conflicting value: + dupKeyMessages.Add(logValue(element)); + continue; + } + + d.Add(key, element); + } + + // If any duplicates were found, log it and throw a descriptive error + if (dupKeys.Count > 0) + { + string badKeysFormatted = String.Join(", ", dupKeys.Select(p => "{0}: [{1}]".F(logKey(p.Key), String.Join(",", p.Value.ToArray()))).ToArray()); + string msg = "{0}, duplicate values found for the following keys: {1}".F(debugName, badKeysFormatted); + Log.Write("debug", msg); + throw new ArgumentException(msg); + } + + // Return the dictionary we built: + return d; + } + public static Color ColorLerp(float t, Color c1, Color c2) { return Color.FromArgb( diff --git a/OpenRA.FileFormats/Filesystem/MixFile.cs b/OpenRA.FileFormats/Filesystem/MixFile.cs index 647490640f..88a1e3324f 100644 --- a/OpenRA.FileFormats/Filesystem/MixFile.cs +++ b/OpenRA.FileFormats/Filesystem/MixFile.cs @@ -58,7 +58,9 @@ namespace OpenRA.FileFormats isEncrypted = 0 != (signature & (uint)MixFileFlags.Encrypted); if( isEncrypted ) { - index = ParseRaHeader( s, out dataStart ).ToDictionary(x => x.Hash); + index = ParseRaHeader(s, out dataStart).ToDictionaryWithConflictLog(x => x.Hash, + "MixFile.RaHeader", null, x => "(offs={0}, len={1})".F(x.Offset, x.Length) + ); return; } } @@ -66,7 +68,9 @@ namespace OpenRA.FileFormats s.Seek( 0, SeekOrigin.Begin ); isEncrypted = false; - index = ParseTdHeader(s, out dataStart).ToDictionary(x => x.Hash); + index = ParseTdHeader(s, out dataStart).ToDictionaryWithConflictLog(x => x.Hash, + "MixFile.TdHeader", null, x => "(offs={0}, len={1})".F(x.Offset, x.Length) + ); } const long headerStart = 84; diff --git a/OpenRA.FileFormats/Manifest.cs b/OpenRA.FileFormats/Manifest.cs index 7752928577..acea418e73 100644 --- a/OpenRA.FileFormats/Manifest.cs +++ b/OpenRA.FileFormats/Manifest.cs @@ -20,7 +20,7 @@ namespace OpenRA.FileFormats public readonly string[] Mods, Folders, Packages, Rules, ServerTraits, Sequences, Cursors, Chrome, Assemblies, ChromeLayout, - Weapons, Voices, Music, Movies, TileSets, ChromeMetrics; + Weapons, Voices, Notifications, Music, Movies, TileSets, ChromeMetrics; public readonly MiniYaml LoadScreen; public readonly Dictionary> Fonts; public readonly int TileSize = 24; @@ -44,6 +44,7 @@ namespace OpenRA.FileFormats ChromeLayout = YamlList(yaml, "ChromeLayout"); Weapons = YamlList(yaml, "Weapons"); Voices = YamlList(yaml, "Voices"); + Notifications = YamlList(yaml, "Notifications"); Music = YamlList(yaml, "Music"); Movies = YamlList(yaml, "Movies"); TileSets = YamlList(yaml, "TileSets"); diff --git a/OpenRA.FileFormats/Map/TileSet.cs b/OpenRA.FileFormats/Map/TileSet.cs index 4578605e2f..0c835e14cc 100644 --- a/OpenRA.FileFormats/Map/TileSet.cs +++ b/OpenRA.FileFormats/Map/TileSet.cs @@ -23,6 +23,7 @@ namespace OpenRA.FileFormats public string[] AcceptsSmudgeType = { }; public bool IsWater = false; public Color Color; + public string CustomCursor; public TerrainTypeInfo() {} public TerrainTypeInfo(MiniYaml my) { FieldLoader.Load(this, my); } diff --git a/OpenRA.FileFormats/Palette.cs b/OpenRA.FileFormats/Palette.cs index bf3bd46cd1..9b96021f6f 100644 --- a/OpenRA.FileFormats/Palette.cs +++ b/OpenRA.FileFormats/Palette.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -39,7 +39,7 @@ namespace OpenRA.FileFormats get { return colors; } } - public Palette(Stream s, bool remapTransparent) + public Palette(Stream s, int[] remapShadow) { colors = new uint[256]; @@ -54,13 +54,9 @@ namespace OpenRA.FileFormats } } - colors[0] = 0; - if (remapTransparent) - { - colors[1] = 178u << 24; // Hack for d2k; may have side effects - colors[3] = 178u << 24; - colors[4] = 140u << 24; - } + colors[0] = 0; //convert black background to transparency + foreach (int i in remapShadow) + colors[i] = 140u << 24; } public Palette(Palette p, IPaletteRemap r) @@ -92,12 +88,12 @@ namespace OpenRA.FileFormats return pal; } - public static Palette Load( string filename, bool remap ) + public static Palette Load(string filename, int[] remap) { using(var s = File.OpenRead(filename)) return new Palette(s, remap); } } - public interface IPaletteRemap { Color GetRemappedColor(Color original, int index); } + public interface IPaletteRemap { Color GetRemappedColor(Color original, int index); } } diff --git a/OpenRA.Game/GameRules/Rules.cs b/OpenRA.Game/GameRules/Rules.cs index 020174334b..bf0d6fd4d5 100755 --- a/OpenRA.Game/GameRules/Rules.cs +++ b/OpenRA.Game/GameRules/Rules.cs @@ -20,7 +20,8 @@ namespace OpenRA { public static Dictionary Info; public static Dictionary Weapons; - public static Dictionary Voices; + public static Dictionary Voices; + public static Dictionary Notifications; public static Dictionary Music; public static Dictionary Movies; public static Dictionary TileSets; @@ -30,7 +31,8 @@ namespace OpenRA // Added support to extend the list of rules (add it to m.LocalRules) Info = LoadYamlRules(m.Rules, map.Rules, (k, y) => new ActorInfo(k.Key.ToLowerInvariant(), k.Value, y)); Weapons = LoadYamlRules(m.Weapons, map.Weapons, (k, _) => new WeaponInfo(k.Key.ToLowerInvariant(), k.Value)); - Voices = LoadYamlRules(m.Voices, map.Voices, (k, _) => new VoiceInfo(k.Value)); + Voices = LoadYamlRules(m.Voices, map.Voices, (k, _) => new SoundInfo(k.Value)); + Notifications = LoadYamlRules(m.Notifications, map.Notifications, (k, _) => new SoundInfo(k.Value)); Music = LoadYamlRules(m.Music, new List(), (k, _) => new MusicInfo(k.Key, k.Value)); Movies = LoadYamlRules(m.Movies, new List(), (k, v) => k.Value.Value); diff --git a/OpenRA.Game/GameRules/VoiceInfo.cs b/OpenRA.Game/GameRules/SoundInfo.cs similarity index 72% rename from OpenRA.Game/GameRules/VoiceInfo.cs rename to OpenRA.Game/GameRules/SoundInfo.cs index 17b85d87e7..4561bb6c68 100644 --- a/OpenRA.Game/GameRules/VoiceInfo.cs +++ b/OpenRA.Game/GameRules/SoundInfo.cs @@ -1,4 +1,4 @@ -#region Copyright & License Information +#region Copyright & License Information /* * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made @@ -15,11 +15,12 @@ using OpenRA.FileFormats; namespace OpenRA.GameRules { - public class VoiceInfo + public class SoundInfo { [FieldLoader.Ignore] public readonly Dictionary Variants; [FieldLoader.Ignore] public readonly Dictionary Prefixes; [FieldLoader.Ignore] public readonly Dictionary Voices; + [FieldLoader.Ignore] public readonly Dictionary Notifications; public readonly string DefaultVariant = ".aud" ; public readonly string DefaultPrefix = "" ; public readonly string[] DisableVariants = { }; @@ -34,31 +35,28 @@ namespace OpenRA.GameRules : new Dictionary(); } - public readonly OpenRA.FileFormats.Lazy> Pools; + public readonly OpenRA.FileFormats.Lazy> VoicePools; + public readonly OpenRA.FileFormats.Lazy> NotificationsPools; - public VoiceInfo( MiniYaml y ) + public SoundInfo( MiniYaml y ) { FieldLoader.Load( this, y ); Variants = Load(y, "Variants"); Prefixes = Load(y, "Prefixes"); Voices = Load(y, "Voices"); + Notifications = Load(y, "Notifications"); - if (!Voices.ContainsKey("Attack")) - Voices.Add("Attack", Voices["Move"]); - - if (!Voices.ContainsKey("AttackMove")) - Voices.Add("AttackMove", Voices["Move"]); - - Pools = Lazy.New(() => Voices.ToDictionary( a => a.Key, a => new VoicePool(a.Value) )); + VoicePools = Lazy.New(() => Voices.ToDictionary( a => a.Key, a => new SoundPool(a.Value) )); + NotificationsPools = Lazy.New(() => Notifications.ToDictionary( a => a.Key, a => new SoundPool(a.Value) )); } } - public class VoicePool + public class SoundPool { readonly string[] clips; readonly List liveclips = new List(); - public VoicePool(params string[] clips) + public SoundPool(params string[] clips) { this.clips = clips; } diff --git a/OpenRA.Game/GameRules/WeaponInfo.cs b/OpenRA.Game/GameRules/WeaponInfo.cs index 1bc07ecd42..101e77aeec 100644 --- a/OpenRA.Game/GameRules/WeaponInfo.cs +++ b/OpenRA.Game/GameRules/WeaponInfo.cs @@ -26,7 +26,7 @@ namespace OpenRA.GameRules public readonly string WaterExplosion = null; // explosion effect on hitting water (usually a splash) public readonly string[] SmudgeType = { }; // type of smudge to apply public readonly int[] Size = { 0, 0 }; // size of the explosion. provide 2 values for a ring effect (outer/inner) - public readonly int InfDeath = 0; // infantry death animation to use + public readonly int InfDeath = 1; // infantry death animation to use public readonly string ImpactSound = null; // sound to play on impact public readonly string WaterImpactSound = null; // sound to play on impact with water public readonly int Damage = 0; // how much (raw) damage to deal diff --git a/OpenRA.Game/Graphics/CursorProvider.cs b/OpenRA.Game/Graphics/CursorProvider.cs index 032ae22447..a0dc94b86d 100644 --- a/OpenRA.Game/Graphics/CursorProvider.cs +++ b/OpenRA.Game/Graphics/CursorProvider.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -25,13 +25,16 @@ namespace OpenRA.Graphics { cursors = new Dictionary(); var sequences = new MiniYaml(null, sequenceFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(MiniYaml.MergeLiberal)); - var transparent = false; + int[] ShadowIndex = { }; - if (sequences.NodesDict.ContainsKey("Transparent")) - transparent = true; + if (sequences.NodesDict.ContainsKey("ShadowIndex")) + { + Array.Resize(ref ShadowIndex, ShadowIndex.Length + 1); + ShadowIndex[ShadowIndex.Length - 1] = Convert.ToInt32(sequences.NodesDict["ShadowIndex"].Value); + } foreach (var s in sequences.NodesDict["Palettes"].Nodes) - Game.modData.Palette.AddPalette(s.Key, new Palette(FileSystem.Open(s.Value.Value), transparent)); + Game.modData.Palette.AddPalette(s.Key, new Palette(FileSystem.Open(s.Value.Value), ShadowIndex)); foreach (var s in sequences.NodesDict["Cursors"].Nodes) LoadSequencesForCursor(s.Key, s.Value); diff --git a/OpenRA.Game/Map.cs b/OpenRA.Game/Map.cs index dd342cf2bc..e60a4dbbc9 100644 --- a/OpenRA.Game/Map.cs +++ b/OpenRA.Game/Map.cs @@ -60,6 +60,7 @@ namespace OpenRA [FieldLoader.Ignore] public List Sequences = new List(); [FieldLoader.Ignore] public List Weapons = new List(); [FieldLoader.Ignore] public List Voices = new List(); + [FieldLoader.Ignore] public List Notifications = new List(); // Binary map data [FieldLoader.Ignore] public byte TileFormat = 1; @@ -150,6 +151,7 @@ namespace OpenRA Sequences = NodesOrEmpty(yaml, "Sequences"); Weapons = NodesOrEmpty(yaml, "Weapons"); Voices = NodesOrEmpty(yaml, "Voices"); + Notifications = NodesOrEmpty(yaml, "Notifications"); CustomTerrain = new string[MapSize.X, MapSize.Y]; @@ -204,6 +206,7 @@ namespace OpenRA root.Add(new MiniYamlNode("Sequences", null, Sequences)); root.Add(new MiniYamlNode("Weapons", null, Weapons)); root.Add(new MiniYamlNode("Voices", null, Voices)); + root.Add(new MiniYamlNode("Notifications", null, Notifications)); var entries = new Dictionary(); entries.Add("map.bin", SaveBinaryData()); diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index 6743891fb9..1cb028b145 100755 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -94,7 +94,7 @@ - + @@ -167,7 +167,6 @@ - @@ -261,4 +260,4 @@ --> - \ No newline at end of file + diff --git a/OpenRA.Game/Player.cs b/OpenRA.Game/Player.cs index 4eed1b1ade..248e451af3 100644 --- a/OpenRA.Game/Player.cs +++ b/OpenRA.Game/Player.cs @@ -90,11 +90,6 @@ namespace OpenRA } } - public void GiveAdvice(string advice) - { - Sound.PlayToPlayer(this, advice); - } - public Dictionary Stances = new Dictionary(); } } diff --git a/OpenRA.Game/Server/UPnP.cs b/OpenRA.Game/Server/UPnP.cs index 6b3e2ecdc4..06f68b07de 100644 --- a/OpenRA.Game/Server/UPnP.cs +++ b/OpenRA.Game/Server/UPnP.cs @@ -37,25 +37,33 @@ namespace UPnP DateTime start = DateTime.Now; - do + try { - s.SendTo(data, ipe); - - int length = 0; do { - length = s.Receive(buffer); - - string resp = Encoding.ASCII.GetString(buffer, 0, length).ToLower(); - if (resp.Contains("upnp:rootdevice")) + s.SendTo(data, ipe); + + int length = 0; + do { - resp = resp.Substring(resp.ToLower().IndexOf("location:") + 9); - resp = resp.Substring(0, resp.IndexOf("\r")).Trim(); - if (!string.IsNullOrEmpty(_serviceUrl = GetServiceUrl(resp))) - return true; - } - } while (length > 0); - } while ((start - DateTime.Now) < _timeout); + length = s.Receive(buffer); + + string resp = Encoding.ASCII.GetString(buffer, 0, length).ToLower(); + if (resp.Contains("upnp:rootdevice")) + { + resp = resp.Substring(resp.ToLower().IndexOf("location:") + 9); + resp = resp.Substring(0, resp.IndexOf("\r")).Trim(); + if (!string.IsNullOrEmpty(_serviceUrl = GetServiceUrl(resp))) + return true; + } + } while (length > 0); + } while ((start - DateTime.Now) < _timeout); + } + catch (Exception e) + { + OpenRA.Log.Write("server", "UPNP discover failed: {0}", e); + } + return false; } diff --git a/OpenRA.Game/Sound.cs b/OpenRA.Game/Sound.cs index a557a7fde3..4d2d5cca01 100644 --- a/OpenRA.Game/Sound.cs +++ b/OpenRA.Game/Sound.cs @@ -29,6 +29,12 @@ namespace OpenRA static ISoundSource LoadSound(string filename) { + if (!FileSystem.Exists(filename)) + { + Log.Write("debug", "LoadSound, file does not exist: {0}", filename); + return null; + } + return LoadSoundRaw(AudLoader.LoadSound(FileSystem.Open(filename))); } @@ -140,10 +146,12 @@ namespace OpenRA } StopMusic(); + var sound = sounds[m.Filename]; + if (sound == null) return; + + music = soundEngine.Play2D(sound, false, true, float2.Zero, MusicVolume); currentMusic = m; MusicPlaying = true; - var sound = sounds[m.Filename]; - music = soundEngine.Play2D(sound, false, true, float2.Zero, MusicVolume); } public static void PlayMusic() @@ -238,7 +246,45 @@ namespace OpenRA get { return (video != null) ? video.SeekPosition : 0; } } - // Returns true if it played a phrase + // Returns true if played successfully + public static bool PlayPredefined(Player p, Actor voicedUnit, string type, string definition, string variant) + { + if (definition == null) return false; + + var rules = (voicedUnit != null) ? Rules.Voices[type] : Rules.Notifications[type]; + + var ID = (voicedUnit != null) ? voicedUnit.ActorID : 0; + + var clip = (voicedUnit != null) ? rules.VoicePools.Value[definition].GetNext() : rules.NotificationsPools.Value[definition].GetNext(); + if (clip == null) return false; + + var suffix = rules.DefaultVariant; + var prefix = rules.DefaultPrefix; + + if (voicedUnit != null) + { + if (!rules.VoicePools.Value.ContainsKey("Attack")) + rules.VoicePools.Value.Add("Attack", rules.VoicePools.Value["Move"]); + + if (!rules.VoicePools.Value.ContainsKey("AttackMove")) + rules.VoicePools.Value.Add("AttackMove", rules.VoicePools.Value["Move"]); + } + + if (variant != null) + { + if (rules.Variants.ContainsKey(variant) && !rules.DisableVariants.Contains(definition)) + suffix = rules.Variants[variant][ID % rules.Variants[variant].Length]; + if (rules.Prefixes.ContainsKey(variant) && !rules.DisablePrefixes.Contains(definition)) + prefix = rules.Prefixes[variant][ID % rules.Prefixes[variant].Length]; + } + + if (p == null) + Play(prefix + clip + suffix); + else + PlayToPlayer(p, prefix + clip + suffix); + return true; + } + public static bool PlayVoice(string phrase, Actor voicedUnit, string variant) { if (voicedUnit == null) return false; @@ -248,21 +294,17 @@ namespace OpenRA if (mi == null) return false; if (mi.Voice == null) return false; - var vi = Rules.Voices[mi.Voice.ToLowerInvariant()]; + var type = mi.Voice.ToLowerInvariant(); - if (!vi.Pools.Value.ContainsKey(phrase)) - return false; + return PlayPredefined(null, voicedUnit, type, phrase, variant); + } - var clip = vi.Pools.Value[phrase].GetNext(); - if (clip == null) - return false; + public static bool PlayNotification(Player player, string type, string notification, string variant) + { + if (type == null) return false; + if (notification == null) return false; - var variantExt = (vi.Variants.ContainsKey(variant) && !vi.DisableVariants.Contains(phrase)) ? - vi.Variants[variant][voicedUnit.ActorID % vi.Variants[variant].Length] : vi.DefaultVariant; - var prefix = (vi.Prefixes.ContainsKey(variant) && !vi.DisablePrefixes.Contains(phrase)) ? - vi.Prefixes[variant][voicedUnit.ActorID % vi.Prefixes[variant].Length] : vi.DefaultPrefix; - Play(prefix + clip + variantExt); - return true; + return PlayPredefined(player, null, type.ToLowerInvariant(), notification, variant); } } @@ -357,6 +399,11 @@ namespace OpenRA public ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos, float volume) { + if (sound == null) + { + Log.Write("debug", "Attempt to Play2D a null `ISoundSource`"); + return null; + } int source = GetSourceFromPool(); return new OpenAlSound(source, (sound as OpenAlSoundSource).buffer, loop, relative, pos, volume); } @@ -369,6 +416,8 @@ namespace OpenRA public void PauseSound(ISound sound, bool paused) { + if (sound == null) return; + int key = ((OpenAlSound)sound).source; int state; Al.alGetSourcei(key, Al.AL_SOURCE_STATE, out state); @@ -410,6 +459,8 @@ namespace OpenRA public void StopSound(ISound sound) { + if (sound == null) return; + int key = ((OpenAlSound)sound).source; int state; Al.alGetSourcei(key, Al.AL_SOURCE_STATE, out state); diff --git a/OpenRA.Game/Traits/Player/EvaAlerts.cs b/OpenRA.Game/Traits/Player/EvaAlerts.cs deleted file mode 100644 index 8b4f51d206..0000000000 --- a/OpenRA.Game/Traits/Player/EvaAlerts.cs +++ /dev/null @@ -1,43 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation. For more information, - * see COPYING. - */ -#endregion - -namespace OpenRA.Traits -{ - public class EvaAlertsInfo : TraitInfo - { - // Sound effects - public readonly string RadarUp = "radaron2.aud"; - public readonly string RadarDown = "radardn1.aud"; - - public readonly string CashTickUp = "cashup1.aud"; - public readonly string CashTickDown = "cashdn1.aud"; - - // Build Palette - public readonly string BuildingCannotPlaceAudio = "nodeply1.aud"; - public readonly string NewOptions = "newopt1.aud"; - - // For manual powerup/down in ra-ng - public readonly string DisablePower = "bleep11.aud"; - public readonly string EnablePower = "bleep12.aud"; - - // Eva speech - public readonly string Repairing = "repair1.aud"; - public readonly string LowPower = "lopower1.aud"; - public readonly string SilosNeeded = "silond1.aud"; - public readonly string PrimaryBuildingSelected = "pribldg1.aud"; - - // Special powers - public readonly string AbilityInsufficientPower = "nopowr1.aud"; - - public readonly string LevelUp = "hydrod1.aud"; - } - - public class EvaAlerts {} -} diff --git a/OpenRA.Game/Traits/Player/PlayerResources.cs b/OpenRA.Game/Traits/Player/PlayerResources.cs index c5af6d6362..aac361d748 100644 --- a/OpenRA.Game/Traits/Player/PlayerResources.cs +++ b/OpenRA.Game/Traits/Player/PlayerResources.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -136,8 +136,6 @@ namespace OpenRA.Traits public void Tick(Actor self) { - var eva = self.World.WorldActor.Info.Traits.Get(); - if(cashtickallowed > 0) { cashtickallowed = cashtickallowed - 1; } @@ -152,7 +150,7 @@ namespace OpenRA.Traits if (--nextSiloAdviceTime <= 0) { if (Ore > 0.8*OreCapacity) - Owner.GiveAdvice(eva.SilosNeeded); + Sound.PlayNotification(Owner, "Speech", "SilosNeeded", Owner.Country.Race); nextSiloAdviceTime = AdviceInterval; } @@ -192,21 +190,19 @@ namespace OpenRA.Traits public void playCashTickUp(Actor self) { - var eva = self.World.WorldActor.Info.Traits.Get(); if (Game.Settings.Sound.SoundCashTickType != SoundCashTicks.Disabled) { - Sound.PlayToPlayer(self.Owner, eva.CashTickUp); + Sound.PlayNotification(self.Owner, "Sounds", "CashTickUp", self.Owner.Country.Race); } } public void playCashTickDown(Actor self) { - var eva = self.World.WorldActor.Info.Traits.Get(); if ( Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Extreme || (Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Normal && cashtickallowed == 0) ) { - Sound.PlayToPlayer(self.Owner, eva.CashTickDown); + Sound.PlayNotification(self.Owner, "Sounds", "CashTickDown", self.Owner.Country.Race); cashtickallowed = 3; } diff --git a/OpenRA.Game/Traits/TraitsInterfaces.cs b/OpenRA.Game/Traits/TraitsInterfaces.cs index 5ef0602331..8143ddcb6b 100755 --- a/OpenRA.Game/Traits/TraitsInterfaces.cs +++ b/OpenRA.Game/Traits/TraitsInterfaces.cs @@ -54,6 +54,7 @@ namespace OpenRA.Traits public interface IResolveOrder { void ResolveOrder(Actor self, Order order); } public interface IValidateOrder { bool OrderValidation(OrderManager orderManager, World world, int clientId, Order order); } public interface IOrderVoice { string VoicePhraseForOrder(Actor self, Order order); } + public interface INotify { void Play(Player p, string notification); } public interface INotifySold { void Selling(Actor self); void Sold(Actor self); } public interface INotifyDamage { void Damaged(Actor self, AttackInfo e); } public interface INotifyDamageStateChanged { void DamageStateChanged(Actor self, AttackInfo e); } diff --git a/OpenRA.Game/Widgets/ButtonWidget.cs b/OpenRA.Game/Widgets/ButtonWidget.cs index 5a4acdc6ce..4fc4e832cb 100644 --- a/OpenRA.Game/Widgets/ButtonWidget.cs +++ b/OpenRA.Game/Widgets/ButtonWidget.cs @@ -22,8 +22,6 @@ namespace OpenRA.Widgets public bool Depressed = false; public int VisualHeight = ChromeMetrics.Get("ButtonDepth"); public string Font = ChromeMetrics.Get("ButtonFont"); - public string ClickSound = null; - public string ClickDisabledSound = null; public bool Disabled = false; public Func GetText; public Func IsDisabled; @@ -73,10 +71,10 @@ namespace OpenRA.Widgets if (!IsDisabled()) { OnKeyPress(e); - Sound.Play(ClickSound); + Sound.PlayNotification(null, "Sounds", "ClickSound", null); } else - Sound.Play(ClickDisabledSound); + Sound.PlayNotification(null, "Sounds", "ClickDisabledSound", null); return true; } @@ -105,12 +103,12 @@ namespace OpenRA.Widgets { OnMouseDown(mi); Depressed = true; - Sound.Play(ClickSound); + Sound.PlayNotification(null, "Sounds", "ClickSound", null); } else { LoseFocus(mi); - Sound.Play(ClickDisabledSound); + Sound.PlayNotification(null, "Sounds", "ClickDisabledSound", null); } } else if (mi.Event == MouseInputEvent.Move && Focused) diff --git a/OpenRA.Game/WorldUtils.cs b/OpenRA.Game/WorldUtils.cs index 53c442fa92..7769a698ab 100755 --- a/OpenRA.Game/WorldUtils.cs +++ b/OpenRA.Game/WorldUtils.cs @@ -121,7 +121,7 @@ namespace OpenRA return selectable != null && selectable.Voice != null; } - public static VoiceInfo GetVoice(this Actor a) + public static SoundInfo GetVoice(this Actor a) { var selectable = a.Info.Traits.GetOrDefault(); if (selectable == null) return null; diff --git a/OpenRA.Mods.Cnc/Missions/CncShellmapScript.cs b/OpenRA.Mods.Cnc/Missions/CncShellmapScript.cs index d35ddfd2ac..7086c416cd 100755 --- a/OpenRA.Mods.Cnc/Missions/CncShellmapScript.cs +++ b/OpenRA.Mods.Cnc/Missions/CncShellmapScript.cs @@ -82,7 +82,7 @@ namespace OpenRA.Mods.RA { var mobile = self.Trait(); self.QueueActivity(mobile.ScriptedMove(left)); - self.QueueActivity(new Teleport(right)); + self.QueueActivity(new SimpleTeleport(right)); self.QueueActivity(new CallFunc(() => LoopTrack(self,left,right))); } } diff --git a/OpenRA.Mods.Cnc/RenderCargo.cs b/OpenRA.Mods.Cnc/RenderCargo.cs index fa38c27d09..9e5101f41b 100644 --- a/OpenRA.Mods.Cnc/RenderCargo.cs +++ b/OpenRA.Mods.Cnc/RenderCargo.cs @@ -19,6 +19,7 @@ namespace OpenRA.Mods.Cnc { /* altitude of the cargo, relative to us. -ve is underneath us */ public readonly int RelativeAltitude = 0; + public readonly string[] PassengerTypes; public object Create(ActorInitializer init) { return new RenderCargo(init.self, this); } } @@ -49,7 +50,12 @@ namespace OpenRA.Mods.Cnc cargoFacing.Facing = facing.Facing; } - return r.Concat(cargo.Passengers.SelectMany(a => a.Render()) + var visiblePassengers = (Info.PassengerTypes != null && Info.PassengerTypes.Length > 0) + ? cargo.Passengers.Where(p => + Info.PassengerTypes.Contains(p.Trait().info.CargoType)) + : cargo.Passengers; + + return r.Concat(visiblePassengers.SelectMany(a => a.Render()) .Select(a => a.WithPos(a.Pos - new float2(0, Info.RelativeAltitude)) .WithZOffset(a.ZOffset + Info.RelativeAltitude))); } diff --git a/OpenRA.Mods.Cnc/SpawnViceroid.cs b/OpenRA.Mods.Cnc/SpawnViceroid.cs index ffe3c8558f..b7f584abe2 100644 --- a/OpenRA.Mods.Cnc/SpawnViceroid.cs +++ b/OpenRA.Mods.Cnc/SpawnViceroid.cs @@ -19,7 +19,7 @@ namespace OpenRA.Mods.Cnc [ActorReference] public readonly string ViceroidActor = "vice"; public readonly int Probability = 10; public readonly string Owner = "Creeps"; - public readonly int InfDeath = 5; + public readonly int InfDeath = 6; public object Create(ActorInitializer init) { return new SpawnViceroid(this); } } diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/CncIngameMenuLogic.cs b/OpenRA.Mods.Cnc/Widgets/Logic/CncIngameMenuLogic.cs index cac9e11e6e..b83e0216d4 100644 --- a/OpenRA.Mods.Cnc/Widgets/Logic/CncIngameMenuLogic.cs +++ b/OpenRA.Mods.Cnc/Widgets/Logic/CncIngameMenuLogic.cs @@ -35,7 +35,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic // TODO: Create a mechanism to do things like this cleaner. Also needed for scripted missions Action onQuit = () => { - Sound.Play("batlcon1.aud"); + Sound.PlayNotification(null, "Speech", "Leave", null); resumeDisabled = true; Game.RunAfterDelay(1200, () => mpe.Fade(CncMenuPaletteEffect.EffectType.Black)); Game.RunAfterDelay(1200 + 40 * mpe.Info.FadeLength, () => diff --git a/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs b/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs index 10e3fb0090..a25fa0af3d 100755 --- a/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs +++ b/OpenRA.Mods.Cnc/Widgets/ProductionTabsWidget.cs @@ -61,8 +61,6 @@ namespace OpenRA.Mods.Cnc.Widgets class ProductionTabsWidget : Widget { public readonly string PaletteWidget = null; - public readonly string ClickSound = null; - public readonly string DisabledClickSound = null; public readonly float ScrollVelocity = 4f; public readonly int TabWidth = 30; public readonly int ArrowWidth = 20; @@ -248,9 +246,9 @@ namespace OpenRA.Mods.Cnc.Widgets if (leftPressed || rightPressed) { if ((leftPressed && !leftDisabled) || (rightPressed && !rightDisabled)) - Sound.Play(ClickSound); + Sound.PlayNotification(null, "Sounds", "ClickSound", null); else - Sound.Play(DisabledClickSound); + Sound.PlayNotification(null, "Sounds", "DisabledClickSound", null); } // Check production tabs @@ -258,7 +256,7 @@ namespace OpenRA.Mods.Cnc.Widgets if (offsetloc.X > 0 && offsetloc.X < ContentWidth) { CurrentQueue = Groups[queueGroup].Tabs[offsetloc.X/(TabWidth - 1)].Queue; - Sound.Play(ClickSound); + Sound.PlayNotification(null, "Sounds", "ClickSound", null); return true; } @@ -270,7 +268,7 @@ namespace OpenRA.Mods.Cnc.Widgets if (e.Event != KeyInputEvent.Down) return false; if (e.KeyName == "tab") { - Sound.Play(ClickSound); + Sound.PlayNotification(null, "Sounds", "ClickSound", null); SelectNextTab(e.Modifiers.HasModifier(Modifiers.Shift)); return true; } diff --git a/OpenRA.Mods.D2k/Widgets/Logic/D2kExtractGameFilesLogic.cs b/OpenRA.Mods.D2k/Widgets/Logic/D2kExtractGameFilesLogic.cs index 6b2a4edab5..f2a0609b47 100644 --- a/OpenRA.Mods.D2k/Widgets/Logic/D2kExtractGameFilesLogic.cs +++ b/OpenRA.Mods.D2k/Widgets/Logic/D2kExtractGameFilesLogic.cs @@ -267,7 +267,7 @@ namespace OpenRA.Mods.D2k.Widgets.Logic new string[] {"--r8", PathToDataR8, PathToPalette, "4463", "4477", Path.Combine(PathToSHPs, "craneo"), "--building"}, new string[] {"--r8", PathToDataR8, PathToPalette, "4760", "4819", Path.Combine(PathToSHPs, "windtrap_anim"), "--building"}, //? new string[] {"--r8", PathToDataR8, PathToPalette, "4820", "4840", Path.Combine(PathToSHPs, "missile_launch"), "--building"}, - new string[] {"--r8", Path.Combine(Platform.SupportDir, "Content/d2k/MOUSE.R8"), PathToPalette, "0", "264", Path.Combine(PathToSHPs, "mouse"), "--transparent"}, + new string[] {"--r8", Path.Combine(Platform.SupportDir, "Content/d2k/MOUSE.R8"), PathToPalette, "0", "264", Path.Combine(PathToSHPs, "mouse")}, new string[] {"--r8", Path.Combine(Platform.SupportDir, "Content/d2k/BLOXBASE.R8"), PathToPalette, "0", "799", Path.Combine(PathToTilesets, "BASE"), "--tileset"}, new string[] {"--r8", Path.Combine(Platform.SupportDir, "Content/d2k/BLOXBASE.R8"), PathToPalette, "748", "749", Path.Combine(PathToSHPs, "spice0")}, new string[] {"--r8", Path.Combine(Platform.SupportDir, "Content/d2k/BLOXBAT.R8"), PathToPalette, "0", "799", Path.Combine(PathToTilesets, "BAT"), "--tileset"}, diff --git a/OpenRA.Mods.RA/Activities/CaptureActor.cs b/OpenRA.Mods.RA/Activities/CaptureActor.cs index dd22a4f412..cef8d7ef96 100644 --- a/OpenRA.Mods.RA/Activities/CaptureActor.cs +++ b/OpenRA.Mods.RA/Activities/CaptureActor.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -10,6 +10,7 @@ using System.Linq; using OpenRA.Traits; +using OpenRA.Mods.RA.Move; namespace OpenRA.Mods.RA.Activities { @@ -25,9 +26,6 @@ namespace OpenRA.Mods.RA.Activities if (target == null || !target.IsInWorld || target.IsDead()) return NextActivity; if (target.Owner == self.Owner) return NextActivity; - if( !target.OccupiesSpace.OccupiedCells().Any( x => x.First == self.Location ) ) - return NextActivity; - var capturable = target.TraitOrDefault(); if (capturable != null && capturable.CaptureInProgress && capturable.Captor.Owner.Stances[self.Owner] == Stance.Ally) return NextActivity; @@ -36,8 +34,14 @@ namespace OpenRA.Mods.RA.Activities if (sellable != null && sellable.Selling) return NextActivity; - target.Trait().BeginCapture(target, self); - self.World.AddFrameEndTask(w => self.Destroy()); + var captures = self.TraitOrDefault(); + var capturesInfo = self.Info.Traits.Get(); + if (captures != null && Combat.IsInRange(self.CenterLocation, capturesInfo.Range, target)) + target.Trait().BeginCapture(target, self); + else + return Util.SequenceActivities(self.Trait().MoveWithinRange(Target.FromActor(target), capturesInfo.Range), this); + if (capturesInfo != null && capturesInfo.wastedAfterwards) + self.World.AddFrameEndTask(w => self.Destroy()); return this; } diff --git a/OpenRA.Mods.RA/Activities/Teleport.cs b/OpenRA.Mods.RA/Activities/Teleport.cs index 3155c16378..ede8cbed78 100755 --- a/OpenRA.Mods.RA/Activities/Teleport.cs +++ b/OpenRA.Mods.RA/Activities/Teleport.cs @@ -10,18 +10,59 @@ using System.Linq; using OpenRA.Traits; +using OpenRA.Mods.RA.Render; namespace OpenRA.Mods.RA.Activities { public class Teleport : Activity { CPos destination; + bool killCargo; + Actor chronosphere; - public Teleport(CPos destination) + public Teleport(Actor chronosphere, CPos destination, bool killCargo) { + this.chronosphere = chronosphere; this.destination = destination; + this.killCargo = killCargo; } + public override Activity Tick(Actor self) + { + Sound.Play("chrono2.aud", self.Location.ToPPos()); + Sound.Play("chrono2.aud", destination.ToPPos()); + + self.Trait().SetPosition(self, destination); + + if (killCargo && self.HasTrait()) + { + var cargo = self.Trait(); + while (!cargo.IsEmpty(self)) + { + if (chronosphere != null) + chronosphere.Owner.Kills++; + var a = cargo.Unload(self); + a.Owner.Deaths++; + } + } + + // Trigger screen desaturate effect + foreach (var a in self.World.ActorsWithTrait()) + a.Trait.Enable(); + + if (chronosphere != null && !chronosphere.Destroyed && chronosphere.HasTrait()) + chronosphere.Trait().PlayCustomAnim(chronosphere, "active"); + + return NextActivity; + } + } + + public class SimpleTeleport : Activity + { + CPos destination; + + public SimpleTeleport(CPos destination) { this.destination = destination; } + public override Activity Tick(Actor self) { self.Trait().SetPosition(self, destination); diff --git a/OpenRA.Mods.RA/Activities/Transform.cs b/OpenRA.Mods.RA/Activities/Transform.cs index 4641f91d40..5bba52cffa 100644 --- a/OpenRA.Mods.RA/Activities/Transform.cs +++ b/OpenRA.Mods.RA/Activities/Transform.cs @@ -52,11 +52,11 @@ namespace OpenRA.Mods.RA.Activities var health = self.TraitOrDefault(); if (health != null) { - // TODO: Fix bogus health init - if (ForceHealthPercentage > 0) - init.Add( new HealthInit( ForceHealthPercentage * 1f / 100 )); - else - init.Add( new HealthInit( (float)health.HP / health.MaxHP )); + var newHP = (ForceHealthPercentage > 0) + ? ForceHealthPercentage / 100f + : (float)health.HP / health.MaxHP; + + init.Add( new HealthInit(newHP) ); } var cargo = self.TraitOrDefault(); diff --git a/OpenRA.Mods.RA/Activities/UnloadCargo.cs b/OpenRA.Mods.RA/Activities/UnloadCargo.cs index ae2e7bcd8a..0531a346da 100644 --- a/OpenRA.Mods.RA/Activities/UnloadCargo.cs +++ b/OpenRA.Mods.RA/Activities/UnloadCargo.cs @@ -18,6 +18,10 @@ namespace OpenRA.Mods.RA.Activities { public class UnloadCargo : Activity { + bool unloadAll; + + public UnloadCargo(bool unloadAll) { this.unloadAll = unloadAll; } + CPos? ChooseExitTile(Actor self, Actor cargo) { // is anyone still hogging this tile? @@ -35,6 +39,19 @@ namespace OpenRA.Mods.RA.Activities return null; } + CPos? ChooseRallyPoint(Actor self) + { + var mobile = self.Trait(); + + for (var i = -1; i < 2; i++) + for (var j = -1; j < 2; j++) + if ((i != 0 || j != 0) && + mobile.CanEnterCell(self.Location + new CVec(i, j))) + return self.Location + new CVec(i, j); + + return self.Location; + } + public override Activity Tick(Actor self) { if (IsCanceled) return NextActivity; @@ -80,10 +97,13 @@ namespace OpenRA.Mods.RA.Activities actor.CancelActivity(); actor.QueueActivity(new Drag(currentPx, exitPx, length)); actor.QueueActivity(mobile.MoveTo(exitTile.Value, 0)); - actor.SetTargetLine(Target.FromCell(exitTile.Value), Color.Green, false); + + var rallyPoint = ChooseRallyPoint(actor).Value; + actor.QueueActivity(mobile.MoveTo(rallyPoint, 0)); + actor.SetTargetLine(Target.FromCell(rallyPoint), Color.Green, false); }); - return this; + return unloadAll ? this : NextActivity; } } } diff --git a/OpenRA.Mods.RA/Attack/AttackLoyalty.cs b/OpenRA.Mods.RA/Attack/AttackLoyalty.cs new file mode 100644 index 0000000000..0b371cb4fa --- /dev/null +++ b/OpenRA.Mods.RA/Attack/AttackLoyalty.cs @@ -0,0 +1,43 @@ +#region Copyright & License Information +/* + * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using OpenRA.Traits; +using OpenRA.Mods.RA.Activities; + +namespace OpenRA.Mods.RA +{ + public class AttackLoyaltyInfo : AttackFrontalInfo + { + public override object Create(ActorInitializer init) { return new AttackLoyalty(init.self, this); } + } + + public class AttackLoyalty : AttackFrontal + { + public AttackLoyalty(Actor self, AttackLoyaltyInfo info) + : base( self, info ) {} + + public override void DoAttack(Actor self, Target target) + { + if (!CanAttack (self, target)) return; + + var weapon = Weapons[0].Info; + if (!Combat.IsInRange(self.CenterLocation, weapon.Range, target)) return; + + var move = self.TraitOrDefault(); + var facing = self.TraitOrDefault(); + foreach (var w in Weapons) + w.CheckFire(self, this, move, facing, target); + + if (target.Actor != null) + target.Actor.ChangeOwner(self.Owner); + } + } +} diff --git a/OpenRA.Mods.RA/Buildings/CanPowerDown.cs b/OpenRA.Mods.RA/Buildings/CanPowerDown.cs index 496b6e8c26..2e7372fe41 100755 --- a/OpenRA.Mods.RA/Buildings/CanPowerDown.cs +++ b/OpenRA.Mods.RA/Buildings/CanPowerDown.cs @@ -37,9 +37,7 @@ namespace OpenRA.Mods.RA.Buildings if (order.OrderString == "PowerDown") { disabled = !disabled; - var eva = self.World.WorldActor.Info.Traits.Get(); - Sound.PlayToPlayer(self.Owner, disabled ? eva.EnablePower : eva.DisablePower); - + Sound.PlayNotification(self.Owner, "Sounds", (disabled ? "EnablePower" : "DisablePower"), self.Owner.Country.Race); PowerManager.UpdateActor(self, disabled ? 0 : normalPower); if (disabled) diff --git a/OpenRA.Mods.RA/Buildings/PowerManager.cs b/OpenRA.Mods.RA/Buildings/PowerManager.cs index 3bbef31542..e1c1747f91 100755 --- a/OpenRA.Mods.RA/Buildings/PowerManager.cs +++ b/OpenRA.Mods.RA/Buildings/PowerManager.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -108,8 +108,7 @@ namespace OpenRA.Mods.RA.Buildings if (--nextPowerAdviceTime <= 0) { if (lowPower) - Player.GiveAdvice(Rules.Info["world"].Traits.Get().LowPower); - + Sound.PlayNotification(self.Owner, "Speech", "LowPower", self.Owner.Country.Race); nextPowerAdviceTime = Info.AdviceInterval; } } diff --git a/OpenRA.Mods.RA/Buildings/RepairableBuilding.cs b/OpenRA.Mods.RA/Buildings/RepairableBuilding.cs index 7d131fec0a..1a905ac45f 100755 --- a/OpenRA.Mods.RA/Buildings/RepairableBuilding.cs +++ b/OpenRA.Mods.RA/Buildings/RepairableBuilding.cs @@ -48,7 +48,7 @@ namespace OpenRA.Mods.RA.Buildings else { Repairer = p; - Sound.PlayToPlayer(Repairer, p.World.WorldActor.Info.Traits.Get().Repairing); + Sound.PlayNotification(Repairer, "Speech", "Repairing", self.Owner.Country.Race); self.World.AddFrameEndTask( w => w.Add(new RepairIndicator(self, p))); diff --git a/OpenRA.Mods.RA/Captures.cs b/OpenRA.Mods.RA/Captures.cs index 375a840a88..67b5ab18d0 100644 --- a/OpenRA.Mods.RA/Captures.cs +++ b/OpenRA.Mods.RA/Captures.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -22,6 +22,8 @@ namespace OpenRA.Mods.RA class CapturesInfo : ITraitInfo { public string[] CaptureTypes = {"building"}; + public int Range = 3; + public bool wastedAfterwards = true; public object Create(ActorInitializer init) { return new Captures(init.self, this); } } @@ -40,7 +42,7 @@ namespace OpenRA.Mods.RA { get { - yield return new CaptureOrderTargeter(Info.CaptureTypes, target => CanEnter(target)); + yield return new CaptureOrderTargeter(Info.CaptureTypes, target => CanCapture(target)); } } @@ -55,24 +57,23 @@ namespace OpenRA.Mods.RA public string VoicePhraseForOrder(Actor self, Order order) { return (order.OrderString == "CaptureActor" - && CanEnter(order.TargetActor)) ? "Attack" : null; + && CanCapture(order.TargetActor)) ? "Attack" : null; } public void ResolveOrder(Actor self, Order order) { if (order.OrderString == "CaptureActor") { - if (!CanEnter(order.TargetActor)) return; + if (!CanCapture(order.TargetActor)) return; self.SetTargetLine(Target.FromOrder(order), Color.Red); self.CancelActivity(); - self.QueueActivity(new Enter(order.TargetActor)); self.QueueActivity(new CaptureActor(order.TargetActor)); } } - bool CanEnter(Actor target) + bool CanCapture(Actor target) { var c = target.TraitOrDefault(); return c != null && ( !c.CaptureInProgress || c.Captor.Owner.Stances[self.Owner] != Stance.Ally ); @@ -104,9 +105,11 @@ namespace OpenRA.Mods.RA IsQueued = forceQueued; + var Info = self.Info.Traits.Get(); + if (captureTypes.Contains(ci.Type)) { - cursor = useEnterCursor(target) ? "enter" : "enter-blocked"; + cursor = (Info.wastedAfterwards) ? (useEnterCursor(target) ? "enter" : "enter-blocked") : "attack"; return true; } diff --git a/OpenRA.Mods.RA/Cargo.cs b/OpenRA.Mods.RA/Cargo.cs index 64269e2cda..0dc2d1b816 100644 --- a/OpenRA.Mods.RA/Cargo.cs +++ b/OpenRA.Mods.RA/Cargo.cs @@ -81,7 +81,7 @@ namespace OpenRA.Mods.RA return; self.CancelActivity(); - self.QueueActivity(new UnloadCargo()); + self.QueueActivity(new UnloadCargo(true)); } } diff --git a/OpenRA.Mods.RA/ChronoshiftDeploy.cs b/OpenRA.Mods.RA/ChronoshiftDeploy.cs index af4cea046f..a6837e000b 100644 --- a/OpenRA.Mods.RA/ChronoshiftDeploy.cs +++ b/OpenRA.Mods.RA/ChronoshiftDeploy.cs @@ -52,18 +52,11 @@ namespace OpenRA.Mods.RA if (order.OrderString == "ChronoshiftSelf" && movement.CanEnterCell(order.TargetLocation)) { if (self.Owner == self.World.LocalPlayer) - { self.World.CancelInputMode(); - } self.CancelActivity(); - self.QueueActivity(new Teleport(order.TargetLocation)); - Sound.Play("chrotnk1.aud", self.CenterLocation); - Sound.Play("chrotnk1.aud", order.TargetLocation.ToPPos()); + self.QueueActivity(new Teleport(null, order.TargetLocation, true)); chargeTick = 25 * self.Info.Traits.Get().ChargeTime; - - foreach (var a in self.World.ActorsWithTrait()) - a.Trait.Enable(); } } diff --git a/OpenRA.Mods.RA/Chronoshiftable.cs b/OpenRA.Mods.RA/Chronoshiftable.cs index 0d722e0f22..90de1a7e56 100755 --- a/OpenRA.Mods.RA/Chronoshiftable.cs +++ b/OpenRA.Mods.RA/Chronoshiftable.cs @@ -20,6 +20,8 @@ namespace OpenRA.Mods.RA // Return-to-sender logic [Sync] CPos chronoshiftOrigin; [Sync] int chronoshiftReturnTicks = 0; + Actor chronosphere; + bool killCargo; public void Tick(Actor self) { @@ -34,7 +36,7 @@ namespace OpenRA.Mods.RA { self.CancelActivity(); // Todo: need a new Teleport method that will move to the closest available cell - self.QueueActivity(new Teleport(chronoshiftOrigin)); + self.QueueActivity(new Teleport(chronosphere, chronoshiftOrigin, killCargo)); } } @@ -52,22 +54,12 @@ namespace OpenRA.Mods.RA /// Set up return-to-sender info chronoshiftOrigin = self.Location; chronoshiftReturnTicks = duration; - - // Kill cargo - if (killCargo && self.HasTrait()) - { - var cargo = self.Trait(); - while (!cargo.IsEmpty(self)) - { - chronosphere.Owner.Kills++; - var a = cargo.Unload(self); - a.Owner.Deaths++; - } - } + this.chronosphere = chronosphere; + this.killCargo = killCargo; // Set up the teleport self.CancelActivity(); - self.QueueActivity(new Teleport(targetLocation)); + self.QueueActivity(new Teleport(chronosphere, targetLocation, killCargo)); return true; } diff --git a/OpenRA.Mods.RA/ConquestVictoryConditions.cs b/OpenRA.Mods.RA/ConquestVictoryConditions.cs index 334562f751..173f162aae 100644 --- a/OpenRA.Mods.RA/ConquestVictoryConditions.cs +++ b/OpenRA.Mods.RA/ConquestVictoryConditions.cs @@ -15,10 +15,7 @@ namespace OpenRA.Mods.RA { public class ConquestVictoryConditionsInfo : ITraitInfo { - public string WinNotification = null; - public string LoseNotification = null; public int NotificationDelay = 1500; // Milliseconds - public readonly string Race = null; public object Create(ActorInitializer init) { return new ConquestVictoryConditions(this); } } @@ -55,7 +52,6 @@ namespace OpenRA.Mods.RA public void Lose(Actor self) { - if (Info.Race != null && Info.Race != self.Owner.Country.Race) return; if (self.Owner.WinState == WinState.Lost) return; self.Owner.WinState = WinState.Lost; @@ -70,14 +66,13 @@ namespace OpenRA.Mods.RA Game.RunAfterDelay(Info.NotificationDelay, () => { if (Game.IsCurrentWorld(self.World)) - Sound.Play(Info.LoseNotification); + Sound.PlayNotification(self.Owner, "Speech", "Lose", self.Owner.Country.Race); }); } } public void Win(Actor self) { - if (Info.Race != null && Info.Race != self.Owner.Country.Race) return; if (self.Owner.WinState == WinState.Won) return; self.Owner.WinState = WinState.Won; @@ -85,7 +80,7 @@ namespace OpenRA.Mods.RA if (self.Owner == self.World.LocalPlayer) { self.World.LocalShroud.Disabled = true; - Game.RunAfterDelay(Info.NotificationDelay, () => Sound.Play(Info.WinNotification)); + Game.RunAfterDelay(Info.NotificationDelay, () => Sound.PlayNotification(self.Owner, "Speech", "Win", self.Owner.Country.Race)); } } } diff --git a/OpenRA.Mods.RA/Crate.cs b/OpenRA.Mods.RA/Crate.cs index 5e622c6e0f..6ccbc9f274 100644 --- a/OpenRA.Mods.RA/Crate.cs +++ b/OpenRA.Mods.RA/Crate.cs @@ -14,17 +14,6 @@ using OpenRA.FileFormats; using OpenRA.Traits; using OpenRA.Mods.RA.Buildings; -/* - * Crates left to implement: -HealBase=1,INVUN ; all buildings to full strength -ICBM=1,MISSILE2 ; nuke missile one time shot -Sonar=3,SONARBOX ; one time sonar pulse -Squad=20,NONE ; squad of random infantry -Unit=20,NONE ; vehicle -Invulnerability=3,INVULBOX,1.0 ; invulnerability (duration in minutes) -TimeQuake=3,TQUAKE ; time quake -*/ - namespace OpenRA.Mods.RA { class CrateInfo : ITraitInfo, Requires @@ -35,7 +24,7 @@ namespace OpenRA.Mods.RA } // ITeleportable is required for paradrop - class Crate : ITick, IOccupySpace, ITeleportable, ICrushable, ISync + class Crate : ITick, IOccupySpace, ITeleportable, ICrushable, ISync, INotifyParachuteLanded { readonly Actor self; [Sync] int ticks; @@ -73,6 +62,15 @@ namespace OpenRA.Mods.RA n -= s.Second; } + public void OnLanded() + { + var landedOn = self.World.ActorMap.GetUnitsAt(self.Location) + .FirstOrDefault(a => a != self); + + if (landedOn != null) + OnCrush(landedOn); + } + public void Tick(Actor self) { if( ++ticks >= Info.Lifetime * 25 ) diff --git a/OpenRA.Mods.RA/Effects/Parachute.cs b/OpenRA.Mods.RA/Effects/Parachute.cs index 318bce35ee..eede52a569 100644 --- a/OpenRA.Mods.RA/Effects/Parachute.cs +++ b/OpenRA.Mods.RA/Effects/Parachute.cs @@ -67,6 +67,9 @@ namespace OpenRA.Mods.RA.Effects cargo.CancelActivity(); cargo.Trait().SetPosition(cargo, loc); w.Add(cargo); + + foreach( var npl in cargo.TraitsImplementing() ) + npl.OnLanded(); }); } diff --git a/OpenRA.Mods.RA/GainsExperience.cs b/OpenRA.Mods.RA/GainsExperience.cs index 45ef373575..a267df8ab9 100644 --- a/OpenRA.Mods.RA/GainsExperience.cs +++ b/OpenRA.Mods.RA/GainsExperience.cs @@ -77,8 +77,7 @@ namespace OpenRA.Mods.RA while (Level < MaxLevel && Experience >= Levels[Level]) { Level++; - var eva = self.World.WorldActor.Info.Traits.Get(); - Sound.PlayToPlayer(self.Owner, eva.LevelUp, self.CenterLocation); + Sound.PlayNotification(self.Owner, "Sounds", "LevelUp", self.Owner.Country.Race); self.World.AddFrameEndTask(w => w.Add(new CrateEffect(self, "levelup", new int2(0,-24)))); } } diff --git a/OpenRA.Mods.RA/Harvester.cs b/OpenRA.Mods.RA/Harvester.cs index 20ff2da840..4199aa7a66 100644 --- a/OpenRA.Mods.RA/Harvester.cs +++ b/OpenRA.Mods.RA/Harvester.cs @@ -51,6 +51,7 @@ namespace OpenRA.Mods.RA public CPos? LastOrderLocation = null; [Sync] public int ContentValue { get { return contents.Sum(c => c.Key.ValuePerUnit * c.Value); } } readonly HarvesterInfo Info; + bool idleSmart = true; public Harvester(Actor self, HarvesterInfo info) { @@ -61,6 +62,7 @@ namespace OpenRA.Mods.RA public void SetProcLines(Actor proc) { if (proc == null) return; + if (proc.Destroyed) return; var linkedHarvs = proc.World.ActorsWithTrait() .Where(a => a.Trait.LinkedProc == proc) @@ -147,7 +149,7 @@ namespace OpenRA.Mods.RA { // Check that we're not in a critical location and being useless (refinery drop-off): var lastproc = LastLinkedProc ?? LinkedProc; - if (lastproc != null) + if (lastproc != null && !lastproc.Destroyed) { var deliveryLoc = lastproc.Location + lastproc.Trait().DeliverOffset; if (self.Location == deliveryLoc) @@ -191,6 +193,9 @@ namespace OpenRA.Mods.RA public void TickIdle(Actor self) { + // Should we be intelligent while idle? + if (!idleSmart) return; + // Are we not empty? Deliver resources: if (!IsEmpty) { @@ -262,9 +267,11 @@ namespace OpenRA.Mods.RA { // NOTE: An explicit harvest order allows the harvester to decide which refinery to deliver to. LinkProc(self, OwnerLinkedProc = null); + idleSmart = true; - var mobile = self.Trait(); self.CancelActivity(); + + var mobile = self.Trait(); if (order.TargetLocation != CPos.Zero) { var loc = order.TargetLocation; @@ -290,7 +297,7 @@ namespace OpenRA.Mods.RA else { // A bot order gives us a CPos.Zero TargetLocation, so find some good resources for him: - CPos? loc = FindNextResourceForBot(self); + var loc = FindNextResourceForBot(self); // No more resources? Oh well. if (!loc.HasValue) return; @@ -301,6 +308,8 @@ namespace OpenRA.Mods.RA LastOrderLocation = loc; } + // This prevents harvesters returning to an empty patch when the player orders them to a new patch: + LastHarvestedCell = LastOrderLocation; self.QueueActivity(new FindResources()); } else if (order.OrderString == "Deliver") @@ -316,11 +325,18 @@ namespace OpenRA.Mods.RA if (IsEmpty) return; + idleSmart = true; + self.SetTargetLine(Target.FromOrder(order), Color.Green); self.CancelActivity(); self.QueueActivity(new DeliverResources()); } + else if (order.OrderString == "Stop" || order.OrderString == "Move") + { + // Turn off idle smarts to obey the stop/move: + idleSmart = false; + } } CPos? FindNextResourceForBot(Actor self) diff --git a/OpenRA.Mods.RA/Missions/Allies01Script.cs b/OpenRA.Mods.RA/Missions/Allies01Script.cs index 9fc74f33ab..011fc95a06 100644 --- a/OpenRA.Mods.RA/Missions/Allies01Script.cs +++ b/OpenRA.Mods.RA/Missions/Allies01Script.cs @@ -258,6 +258,7 @@ namespace OpenRA.Mods.RA.Missions chinook.QueueActivity(new Turn(0)); chinook.QueueActivity(new HeliLand(true)); chinook.QueueActivity(new UnloadCargo()); + chinook.QueueActivity(new UnloadCargo(true)); chinook.QueueActivity(new CallFunc(() => Sound.Play("laugh1.aud"))); chinook.QueueActivity(new Wait(150)); chinook.QueueActivity(new HeliFly(chinookExitPoint.CenterLocation)); diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index 6b68c8d1f4..0eff2703bb 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -456,6 +456,10 @@ namespace OpenRA.Mods.RA.Move { IsQueued = forceQueued; cursor = "move"; + + if (self.World.LocalPlayer.Shroud.IsExplored(location)) + cursor = self.World.GetTerrainInfo(location).CustomCursor ?? cursor; + if (!self.World.Map.IsInMap(location) || (self.World.LocalPlayer.Shroud.IsExplored(location) && unitType.MovementCostForCell(self.World, location) == int.MaxValue)) cursor = "move-blocked"; diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index cf6f8c3ed1..c29ab2d9dd 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -127,6 +127,7 @@ + @@ -384,6 +385,7 @@ + diff --git a/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs b/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs index 5367ccc611..8864ae20ae 100755 --- a/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs +++ b/OpenRA.Mods.RA/Orders/PlaceBuildingOrderGenerator.cs @@ -58,8 +58,7 @@ namespace OpenRA.Mods.RA.Orders if (!world.CanPlaceBuilding( Building, BuildingInfo, topLeft, null) || !BuildingInfo.IsCloseEnoughToBase(world, Producer.Owner, Building, topLeft)) { - var eva = world.WorldActor.Info.Traits.Get(); - Sound.Play(eva.BuildingCannotPlaceAudio); + Sound.PlayNotification(Producer.Owner, "Speech", "BuildingCannotPlaceAudio", Producer.Owner.Country.Race); yield break; } diff --git a/OpenRA.Mods.RA/PaletteFromCurrentTileset.cs b/OpenRA.Mods.RA/PaletteFromCurrentTileset.cs index ab6db57594..f98af6175c 100644 --- a/OpenRA.Mods.RA/PaletteFromCurrentTileset.cs +++ b/OpenRA.Mods.RA/PaletteFromCurrentTileset.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -16,7 +16,7 @@ namespace OpenRA.Mods.RA class PaletteFromCurrentTilesetInfo : ITraitInfo { public readonly string Name = null; - public readonly bool Transparent = true; + public readonly int[] ShadowIndex = { }; public object Create(ActorInitializer init) { return new PaletteFromCurrentTileset(init.world, this); } } @@ -34,7 +34,7 @@ namespace OpenRA.Mods.RA public void InitPalette( OpenRA.Graphics.WorldRenderer wr ) { - wr.AddPalette( info.Name, new Palette( FileSystem.Open( world.TileSet.Palette ), info.Transparent ) ); + wr.AddPalette( info.Name, new Palette( FileSystem.Open( world.TileSet.Palette ), info.ShadowIndex ) ); } } } diff --git a/OpenRA.Mods.RA/PaletteFromFile.cs b/OpenRA.Mods.RA/PaletteFromFile.cs index 8ea64870b9..94706ea61e 100644 --- a/OpenRA.Mods.RA/PaletteFromFile.cs +++ b/OpenRA.Mods.RA/PaletteFromFile.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -19,7 +19,7 @@ namespace OpenRA.Mods.RA public readonly string Name = null; public readonly string Tileset = null; public readonly string Filename = null; - public readonly bool Transparent = true; + public readonly int[] ShadowIndex = { }; public object Create(ActorInitializer init) { return new PaletteFromFile(init.world, this); } } @@ -37,7 +37,7 @@ namespace OpenRA.Mods.RA public void InitPalette( WorldRenderer wr ) { if( info.Tileset == null || info.Tileset.ToLowerInvariant() == world.Map.Tileset.ToLowerInvariant() ) - wr.AddPalette( info.Name, new Palette( FileSystem.Open( info.Filename ), info.Transparent ) ); + wr.AddPalette( info.Name, new Palette( FileSystem.Open( info.Filename ), info.ShadowIndex ) ); } } } diff --git a/OpenRA.Mods.RA/Passenger.cs b/OpenRA.Mods.RA/Passenger.cs index d5cc9911fe..7a4c9fc6b8 100644 --- a/OpenRA.Mods.RA/Passenger.cs +++ b/OpenRA.Mods.RA/Passenger.cs @@ -28,7 +28,7 @@ namespace OpenRA.Mods.RA public class Passenger : IIssueOrder, IResolveOrder, IOrderVoice { - readonly PassengerInfo info; + public readonly PassengerInfo info; public Passenger( PassengerInfo info ) { this.info = info; } public IEnumerable Orders diff --git a/OpenRA.Mods.RA/Player/BaseAttackNotifier.cs b/OpenRA.Mods.RA/Player/BaseAttackNotifier.cs index d0b4ac68e7..a5495f6277 100644 --- a/OpenRA.Mods.RA/Player/BaseAttackNotifier.cs +++ b/OpenRA.Mods.RA/Player/BaseAttackNotifier.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) * This file is part of OpenRA, which is free software. It is made * available to you under the terms of the GNU General Public License * as published by the Free Software Foundation. For more information, @@ -17,9 +17,7 @@ namespace OpenRA.Mods.RA { public class BaseAttackNotifierInfo : ITraitInfo { - public readonly int NotifyInterval = 30; /* seconds */ - public readonly string Audio = "baseatk1.aud"; - public readonly string Race = null; + public readonly int NotifyInterval = 30; // seconds public object Create(ActorInitializer init) { return new BaseAttackNotifier(this); } } @@ -35,17 +33,16 @@ namespace OpenRA.Mods.RA public void Damaged(Actor self, AttackInfo e) { - if (info.Race != null && info.Race != self.Owner.Country.Race) return; - /* only track last hit against our base */ + // only track last hit against our base if (!self.HasTrait()) return; - /* don't track self-damage */ + // don't track self-damage if (e.Attacker != null && e.Attacker.Owner == self.Owner) return; if (self.World.FrameNumber - lastAttackTime > info.NotifyInterval * 25) - Sound.PlayToPlayer(self.Owner, info.Audio); + Sound.PlayNotification(self.Owner, "Speech", "BaseAttack", self.Owner.Country.Race); lastAttackLocation = self.CenterLocation.ToCPos(); lastAttackTime = self.World.FrameNumber; diff --git a/OpenRA.Mods.RA/Player/HarvesterAttackNotifier.cs b/OpenRA.Mods.RA/Player/HarvesterAttackNotifier.cs new file mode 100644 index 0000000000..ac4e76df59 --- /dev/null +++ b/OpenRA.Mods.RA/Player/HarvesterAttackNotifier.cs @@ -0,0 +1,52 @@ +#region Copyright & License Information +/* + * Copyright 2007-2012 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using OpenRA.Mods.RA.Buildings; +using OpenRA.Mods.RA.Effects; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA +{ + public class HarvesterAttackNotifierInfo : ITraitInfo + { + public readonly int NotifyInterval = 30; // seconds + + public object Create(ActorInitializer init) { return new HarvesterAttackNotifier(this); } + } + + public class HarvesterAttackNotifier : INotifyDamage + { + HarvesterAttackNotifierInfo info; + + public int lastAttackTime = -1; + public CPos lastAttackLocation; + + public HarvesterAttackNotifier(HarvesterAttackNotifierInfo info) { this.info = info; } + + public void Damaged(Actor self, AttackInfo e) + { + // only track last hit against our base + if (!self.HasTrait()) + return; + + // don't track self-damage + if (e.Attacker != null && e.Attacker.Owner == self.Owner) + return; + + if (self.World.FrameNumber - lastAttackTime > info.NotifyInterval * 25) + Sound.PlayNotification(self.Owner, "Speech", "HarvesterAttack", self.Owner.Country.Race); + + lastAttackLocation = self.CenterLocation.ToCPos(); + lastAttackTime = self.World.FrameNumber; + } + } +} + diff --git a/OpenRA.Mods.RA/Player/PlaceBuilding.cs b/OpenRA.Mods.RA/Player/PlaceBuilding.cs index 4fdeaf0328..4405d6a8d8 100755 --- a/OpenRA.Mods.RA/Player/PlaceBuilding.cs +++ b/OpenRA.Mods.RA/Player/PlaceBuilding.cs @@ -82,8 +82,7 @@ namespace OpenRA.Mods.RA if (GetNumBuildables(self.Owner) > prevItems) w.Add(new DelayedAction(10, - () => Sound.PlayToPlayer(order.Player, - w.WorldActor.Info.Traits.Get().NewOptions))); + () => Sound.PlayNotification(order.Player, "Speech", "NewOptions", order.Player.Country.Race))); }); } } diff --git a/OpenRA.Mods.RA/PrimaryBuilding.cs b/OpenRA.Mods.RA/PrimaryBuilding.cs index 85921f04b1..9e4b73bc51 100755 --- a/OpenRA.Mods.RA/PrimaryBuilding.cs +++ b/OpenRA.Mods.RA/PrimaryBuilding.cs @@ -66,8 +66,7 @@ namespace OpenRA.Mods.RA isPrimary = true; - var eva = self.World.WorldActor.Info.Traits.Get(); - Sound.PlayToPlayer(self.Owner, eva.PrimaryBuildingSelected); + Sound.PlayNotification(self.Owner, "Speech", "PrimaryBuildingSelected", self.Owner.Country.Race); } } diff --git a/OpenRA.Mods.RA/Render/RenderInfantry.cs b/OpenRA.Mods.RA/Render/RenderInfantry.cs index f3cd34b495..bba5c0a611 100644 --- a/OpenRA.Mods.RA/Render/RenderInfantry.cs +++ b/OpenRA.Mods.RA/Render/RenderInfantry.cs @@ -127,7 +127,7 @@ namespace OpenRA.Mods.RA.Render self.World.AddFrameEndTask(w => { if (!self.Destroyed) - w.Add(new Corpse(self, "die{0}".F(e.Warhead.InfDeath + 1))); + w.Add(new Corpse(self, "die{0}".F(e.Warhead.InfDeath))); }); } } diff --git a/OpenRA.Mods.RA/Scripting/RASpecialPowers.cs b/OpenRA.Mods.RA/Scripting/RASpecialPowers.cs index 0cb8c4d09a..47ddcf1818 100644 --- a/OpenRA.Mods.RA/Scripting/RASpecialPowers.cs +++ b/OpenRA.Mods.RA/Scripting/RASpecialPowers.cs @@ -20,15 +20,6 @@ namespace OpenRA.Scripting { public static void Chronoshift(World world, List> units, Actor chronosphere, int duration, bool killCargo) { - if (chronosphere != null) - chronosphere.Trait().PlayCustomAnim(chronosphere, "active"); - - // Trigger screen desaturate effect - foreach (var a in world.ActorsWithTrait()) - a.Trait.Enable(); - - Sound.Play("chrono2.aud", units.First().First.CenterLocation); - foreach (var kv in units) { var target = kv.First; @@ -37,8 +28,6 @@ namespace OpenRA.Scripting if (cs.CanChronoshiftTo(target, targetCell, true)) cs.Teleport(target, targetCell, duration, killCargo,chronosphere); } - - } } } diff --git a/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs b/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs index e3b85e08c8..38b0486994 100755 --- a/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs +++ b/OpenRA.Mods.RA/SupportPowers/ChronoshiftPower.cs @@ -39,14 +39,6 @@ namespace OpenRA.Mods.RA public override void Activate(Actor self, Order order) { - self.Trait().PlayCustomAnim(self, "active"); - - // Trigger screen desaturate effect - foreach (var a in self.World.ActorsWithTrait()) - a.Trait.Enable(); - - Sound.Play("chrono2.aud", order.TargetLocation.ToPPos()); - Sound.Play("chrono2.aud", order.ExtraLocation.ToPPos()); foreach (var target in UnitsInRange(order.ExtraLocation)) { var cs = target.Trait(); diff --git a/OpenRA.Mods.RA/TeslaInstantKills.cs b/OpenRA.Mods.RA/TeslaInstantKills.cs index df50b42947..57da307888 100755 --- a/OpenRA.Mods.RA/TeslaInstantKills.cs +++ b/OpenRA.Mods.RA/TeslaInstantKills.cs @@ -19,7 +19,7 @@ namespace OpenRA.Mods.RA { public float GetDamageModifier(Actor attacker, WarheadInfo warhead ) { - if( warhead != null && warhead.InfDeath == 5 ) + if( warhead != null && warhead.InfDeath == 6 ) return 1000f; return 1f; } diff --git a/OpenRA.Mods.RA/TraitsInterfaces.cs b/OpenRA.Mods.RA/TraitsInterfaces.cs index e4f4f2d32d..18b2619777 100755 --- a/OpenRA.Mods.RA/TraitsInterfaces.cs +++ b/OpenRA.Mods.RA/TraitsInterfaces.cs @@ -42,4 +42,6 @@ namespace OpenRA.Mods.RA { void OnNotifyResourceClaimLost(Actor self, ResourceClaim claim, Actor claimer); } + + public interface INotifyParachuteLanded { void OnLanded(); } } diff --git a/OpenRA.Mods.RA/Widgets/BuildPaletteWidget.cs b/OpenRA.Mods.RA/Widgets/BuildPaletteWidget.cs index 08ee276faa..8c2712e5a3 100755 --- a/OpenRA.Mods.RA/Widgets/BuildPaletteWidget.cs +++ b/OpenRA.Mods.RA/Widgets/BuildPaletteWidget.cs @@ -44,9 +44,6 @@ namespace OpenRA.Mods.RA.Widgets List>> tabs = new List>>(); Animation cantBuild; Animation clock; - public readonly string BuildPaletteOpen = "bleep13.aud"; - public readonly string BuildPaletteClose = "bleep13.aud"; - public readonly string TabClick = "ramenu1.aud"; readonly WorldRenderer worldRenderer; readonly World world; @@ -118,11 +115,11 @@ namespace OpenRA.Mods.RA.Widgets // Play palette-open sound at the start of the activate anim (open) if (paletteAnimationFrame == 1 && paletteOpen) - Sound.Play(BuildPaletteOpen); + Sound.PlayNotification(null, "Sounds", "BuildPaletteOpen", null); // Play palette-close sound at the start of the activate anim (close) if (paletteAnimationFrame == paletteAnimationLength + -1 && !paletteOpen) - Sound.Play(BuildPaletteClose); + Sound.PlayNotification(null, "Sounds", "BuildPaletteClose", null); // Animation is complete if ((paletteAnimationFrame == 0 && !paletteOpen) @@ -291,7 +288,7 @@ namespace OpenRA.Mods.RA.Widgets Action HandleClick(string name, World world) { return mi => { - Sound.Play(TabClick); + Sound.PlayNotification(null, "Sounds", "TabClick", null); if (name != null) HandleBuildPalette(world, name, (mi.Button == MouseButton.Left)); @@ -304,7 +301,7 @@ namespace OpenRA.Mods.RA.Widgets if (mi.Button != MouseButton.Left) return; - Sound.Play(TabClick); + Sound.PlayNotification(null, "Sounds", "TabClick", null); var wasOpen = paletteOpen; paletteOpen = (CurrentQueue == queue && wasOpen) ? false : true; CurrentQueue = queue; @@ -496,7 +493,7 @@ namespace OpenRA.Mods.RA.Widgets if ( toBuild != null ) { - Sound.Play(TabClick); + Sound.PlayNotification(null, "Sounds", "TabClick", null); HandleBuildPalette(world, toBuild.Name, true); return true; } @@ -507,7 +504,7 @@ namespace OpenRA.Mods.RA.Widgets void TabChange(bool shift) { var queues = VisibleQueues.Concat(VisibleQueues); - if (shift) queues.Reverse(); + if (shift) queues = queues.Reverse(); var nextQueue = queues.SkipWhile( q => q != CurrentQueue ) .ElementAtOrDefault(1); if (nextQueue != null) diff --git a/OpenRA.Mods.RA/Widgets/Logic/IngameChromeLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/IngameChromeLogic.cs index b9e17cfb6d..c54ba06f9a 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/IngameChromeLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/IngameChromeLogic.cs @@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic }; cheatsButton.IsVisible = () => world.LocalPlayer != null && world.LobbyInfo.GlobalSettings.AllowCheats; - optionsBG.Get("DISCONNECT").OnClick = () => LeaveGame(optionsBG); + optionsBG.Get("DISCONNECT").OnClick = () => LeaveGame(optionsBG, world); optionsBG.Get("SETTINGS").OnClick = () => Ui.OpenWindow("SETTINGS_MENU"); optionsBG.Get("MUSIC").OnClick = () => Ui.OpenWindow("MUSIC_MENU"); @@ -57,7 +57,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic var postGameObserve = postgameBG.Get("POSTGAME_OBSERVE"); var postgameQuit = postgameBG.Get("POSTGAME_QUIT"); - postgameQuit.OnClick = () => LeaveGame(postgameQuit); + postgameQuit.OnClick = () => LeaveGame(postgameQuit, world); postGameObserve.OnClick = () => postgameQuit.Visible = false; postGameObserve.IsVisible = () => world.LocalPlayer.WinState != WinState.Won; @@ -76,8 +76,9 @@ namespace OpenRA.Mods.RA.Widgets.Logic }; } - void LeaveGame(Widget pane) + void LeaveGame(Widget pane, World world) { + Sound.PlayNotification(null, "Speech", "Leave", world.LocalPlayer.Country.Race); pane.Visible = false; Game.Disconnect(); Game.LoadShellMap(); diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs index f10f9bc0d7..2c9ab8136b 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs @@ -237,7 +237,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic chatPanel.AddChild(template); chatPanel.ScrollToBottom(); - Sound.Play("scold1.aud"); + Sound.PlayNotification(null, "Sounds", "ChatLine", null); } void UpdateCurrentMap() diff --git a/OpenRA.Mods.RA/Widgets/RadarBinWidget.cs b/OpenRA.Mods.RA/Widgets/RadarBinWidget.cs index a9af7ada3f..9505c29cb4 100755 --- a/OpenRA.Mods.RA/Widgets/RadarBinWidget.cs +++ b/OpenRA.Mods.RA/Widgets/RadarBinWidget.cs @@ -175,8 +175,7 @@ namespace OpenRA.Mods.RA.Widgets if (hasRadarNew != hasRadar) { radarAnimating = true; - var eva = Rules.Info["world"].Traits.Get(); - Sound.Play(hasRadarNew ? eva.RadarUp : eva.RadarDown); + Sound.PlayNotification(null, "Sounds", (hasRadarNew ? "RadarUp" : "RadarDown"), null); } hasRadar = hasRadarNew; diff --git a/OpenRA.TilesetBuilder/frmBuilder.cs b/OpenRA.TilesetBuilder/frmBuilder.cs index b9d6c5eabe..bf85e2825d 100644 --- a/OpenRA.TilesetBuilder/frmBuilder.cs +++ b/OpenRA.TilesetBuilder/frmBuilder.cs @@ -56,9 +56,11 @@ namespace OpenRA.TilesetBuilder Bitmap rbitmap = fbitmap.Clone(new Rectangle(0, 0, fbitmap.Width, fbitmap.Height), fbitmap.PixelFormat); + int[] ShadowIndex = { }; + if (!PaletteFromImage) { - tpal = Palette.Load(PaletteFile, false); + tpal = Palette.Load(PaletteFile, ShadowIndex); rbitmap.Palette = tpal.AsSystemPalette(); } diff --git a/OpenRA.Utility/Command.cs b/OpenRA.Utility/Command.cs index 6857e757e6..725976ce01 100644 --- a/OpenRA.Utility/Command.cs +++ b/OpenRA.Utility/Command.cs @@ -81,8 +81,15 @@ namespace OpenRA.Utility var dest = Path.ChangeExtension(src, ".png"); var srcImage = ShpReader.Load(src); - var shouldRemap = args.Contains( "--transparent" ); - var palette = Palette.Load(args[2], shouldRemap); + int[] ShadowIndex = { }; + if (args.Contains("--noshadow")) + { + Array.Resize(ref ShadowIndex, ShadowIndex.Length + 3); + ShadowIndex[ShadowIndex.Length - 1] = 1; + ShadowIndex[ShadowIndex.Length - 2] = 3; + ShadowIndex[ShadowIndex.Length - 1] = 4; + } + var palette = Palette.Load(args[2], ShadowIndex); using (var bitmap = new Bitmap(srcImage.ImageCount * srcImage.Width, srcImage.Height, PixelFormat.Format8bppIndexed)) { @@ -110,8 +117,13 @@ namespace OpenRA.Utility public static void ConvertR8ToPng(string[] args) { var srcImage = new R8Reader(File.OpenRead(args[1])); - var shouldRemap = args.Contains("--transparent"); - var palette = Palette.Load(args[2], shouldRemap); + int[] ShadowIndex = { }; + if (args.Contains("--noshadow")) + { + Array.Resize(ref ShadowIndex, ShadowIndex.Length + 1); + ShadowIndex[ShadowIndex.Length - 1] = 3; + } + var palette = Palette.Load(args[2], ShadowIndex); var startFrame = int.Parse(args[3]); var endFrame = int.Parse(args[4]) + 1; var filename = args[5]; @@ -319,6 +331,7 @@ namespace OpenRA.Utility var mods = args[1].Split(','); var theater = args[2]; var templateNames = args.Skip(3); + int[] ShadowIndex = { 3, 4 }; var manifest = new Manifest(mods); FileSystem.LoadFromManifest(manifest); @@ -330,7 +343,7 @@ namespace OpenRA.Utility throw new InvalidOperationException("No theater named '{0}'".F(theater)); tileset.LoadTiles(); - var palette = new Palette(FileSystem.Open(tileset.Palette), true); + var palette = new Palette(FileSystem.Open(tileset.Palette), ShadowIndex); foreach( var templateName in templateNames ) { @@ -413,14 +426,15 @@ namespace OpenRA.Utility var destPaletteInfo = Rules.Info["player"].Traits.Get(); int[] destRemapIndex = destPaletteInfo.RemapIndex; + int[] ShadowIndex = { }; // the remap range is always 16 entries, but their location and order changes for (var i = 0; i < 16; i++) remap[PlayerColorRemap.GetRemapIndex(srcRemapIndex, i)] = PlayerColorRemap.GetRemapIndex(destRemapIndex, i); // map everything else to the best match based on channel-wise distance - var srcPalette = Palette.Load(args[1].Split(':')[1], false); - var destPalette = Palette.Load(args[2].Split(':')[1], false); + var srcPalette = Palette.Load(args[1].Split(':')[1], ShadowIndex); + var destPalette = Palette.Load(args[2].Split(':')[1], ShadowIndex); var fullIndexRange = Exts.MakeArray(256, x => x); diff --git a/OpenRA.Utility/Program.cs b/OpenRA.Utility/Program.cs index d46783c004..b6cc18f8c0 100644 --- a/OpenRA.Utility/Program.cs +++ b/OpenRA.Utility/Program.cs @@ -57,11 +57,11 @@ namespace OpenRA.Utility Console.WriteLine(); Console.WriteLine(" --settings-value KEY Get value of KEY from settings.yaml"); Console.WriteLine(" --shp PNGFILE FRAMEWIDTH Convert a single PNG with multiple frames appended after another to a SHP"); - Console.WriteLine(" --png SHPFILE PALETTE [--transparent] Convert a SHP to a PNG containing all of its frames, optionally setting up transparency"); + Console.WriteLine(" --png SHPFILE PALETTE [--noshadow] Convert a SHP to a PNG containing all of its frames, optionally removing the shadow"); Console.WriteLine(" --extract MOD[,MOD]* FILES Extract files from mod packages"); Console.WriteLine(" --tmp-png MOD[,MOD]* THEATER FILES Extract terrain tiles to PNG"); Console.WriteLine(" --remap SRCMOD:PAL DESTMOD:PAL SRCSHP DESTSHP Remap SHPs to another palette"); - Console.WriteLine(" --r8 R8FILE PALETTE START END FILENAME [--transparent] [--infrantry] [--vehicle] [--projectile] [--building] [--wall] [--tileset] Convert Dune 2000 DATA.R8 to PNGs choosing start- and endframe as well as type for correct offset to append multiple frames to one PNG named by filename optionally setting up transparency."); + Console.WriteLine(" --r8 R8FILE PALETTE START END FILENAME [--noshadow] [--infrantry] [--vehicle] [--projectile] [--building] [--wall] [--tileset] Convert Dune 2000 DATA.R8 to PNGs choosing start- and endframe as well as type for correct offset to append multiple frames to one PNG named by filename optionally removing the shadow."); Console.WriteLine(" --transpose SRCSHP DESTSHP START N M [START N M ...] Transpose the N*M block of frames starting at START."); } diff --git a/doc/cnc extracted inirules link.txt b/doc/cnc extracted inirules link.txt deleted file mode 100644 index 84788a199d..0000000000 --- a/doc/cnc extracted inirules link.txt +++ /dev/null @@ -1 +0,0 @@ -http://nyerguds.arsaneus-design.com/cnc95upd/inirules/ diff --git a/mods/cnc/chrome/ingame.yaml b/mods/cnc/chrome/ingame.yaml index 6e25a16d36..d680ede48f 100644 --- a/mods/cnc/chrome/ingame.yaml +++ b/mods/cnc/chrome/ingame.yaml @@ -103,8 +103,6 @@ Container@PLAYER_WIDGETS: Font:Bold TooltipText: Menu TooltipContainer:TOOLTIP_CONTAINER - ClickSound:button.aud - ClickDisabledSound:scold2.aud Children: Image@ICON: X:7 @@ -120,8 +118,6 @@ Container@PLAYER_WIDGETS: Font:Bold TooltipText: Sell TooltipContainer:TOOLTIP_CONTAINER - ClickSound:button.aud - ClickDisabledSound:scold2.aud Children: Image@ICON: X:7 @@ -136,8 +132,6 @@ Container@PLAYER_WIDGETS: Font:Bold TooltipText: Repair TooltipContainer:TOOLTIP_CONTAINER - ClickSound:button.aud - ClickDisabledSound:scold2.aud Children: Image@ICON: X:7 @@ -200,8 +194,6 @@ Container@PLAYER_WIDGETS: Key: q TooltipText: Buildings TooltipContainer:TOOLTIP_CONTAINER - ClickSound:button.aud - ClickDisabledSound:scold2.aud Children: Image@ICON: X:7 @@ -214,8 +206,6 @@ Container@PLAYER_WIDGETS: Key: w TooltipText: Defense TooltipContainer:TOOLTIP_CONTAINER - ClickSound:button.aud - ClickDisabledSound:scold2.aud Children: Image@ICON: X:7 @@ -228,8 +218,6 @@ Container@PLAYER_WIDGETS: Key: e TooltipText: Infantry TooltipContainer:TOOLTIP_CONTAINER - ClickSound:button.aud - ClickDisabledSound:scold2.aud Children: Image@ICON: X:7 @@ -242,8 +230,6 @@ Container@PLAYER_WIDGETS: Key: r TooltipText: Vehicles TooltipContainer:TOOLTIP_CONTAINER - ClickSound:button.aud - ClickDisabledSound:scold2.aud Children: Image@ICON: X:7 @@ -256,8 +242,6 @@ Container@PLAYER_WIDGETS: Key: t TooltipText: Aircraft TooltipContainer:TOOLTIP_CONTAINER - ClickSound:button.aud - ClickDisabledSound:scold2.aud Children: Image@ICON: X:7 @@ -265,8 +249,6 @@ Container@PLAYER_WIDGETS: ImageCollection:production-icons ProductionTabs@PRODUCTION_TABS: PaletteWidget:PRODUCTION_PALETTE - ClickSound:button.aud - DisabledClickSound:scold2.aud X:WINDOW_RIGHT - 204 Y:268 Width:194 @@ -274,8 +256,6 @@ Container@PLAYER_WIDGETS: ProductionPalette@PRODUCTION_PALETTE: X:WINDOW_RIGHT - 204 Y:287 - TabClick: button.aud - DisabledTabClick:scold2.aud TooltipContainer:TOOLTIP_CONTAINER Background@FMVPLAYER: Width:WINDOW_RIGHT diff --git a/mods/cnc/cursors.yaml b/mods/cnc/cursors.yaml index a566ef647b..854dd17291 100644 --- a/mods/cnc/cursors.yaml +++ b/mods/cnc/cursors.yaml @@ -197,6 +197,11 @@ Cursors: length:4 x:12 y:12 + move-rough: + start:0 + length: 8 + x: 12 + y: 12 attackmove:cursor attackmove: diff --git a/mods/cnc/mod.yaml b/mods/cnc/mod.yaml index dbf297aeb9..a018bb46fd 100644 --- a/mods/cnc/mod.yaml +++ b/mods/cnc/mod.yaml @@ -90,6 +90,9 @@ Movies: Voices: mods/cnc/voices.yaml +Notifications: + mods/cnc/notifications.yaml + Music: mods/cnc/music.yaml diff --git a/mods/cnc/notifications.yaml b/mods/cnc/notifications.yaml new file mode 100644 index 0000000000..96665b28cc --- /dev/null +++ b/mods/cnc/notifications.yaml @@ -0,0 +1,26 @@ +Speech: + Notifications: + Repairing: repair1 + LowPower: lopower1 + SilosNeeded: silos1 + PrimaryBuildingSelected: pribldg1 + BuildingCannotPlaceAudio: deploy1 + NewOptions: newopt1 + AbilityInsufficientPower: nopower1 + Win: accom1 + Lose: fail1 + BaseAttack: baseatk1 + HarvesterAttack: + Leave: batlcon1 + +Sounds: + Notifications: + RadarUp: comcntr1 + RadarDown: powrdn1 + CashTickUp: + CashTickDown: + LevelUp: text2 + ChatLine: scold1 + TabClick: button + ClickSound: button + ClickDisabledSound: scold2 \ No newline at end of file diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index fee01a9a67..b4fe022fc4 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -133,8 +133,9 @@ SpawnViceroid: Probability: 2 CrushableInfantry: - Repairable: - RepairBuildings: hosp + RepairableNear: + Buildings: hosp + CloseEnough: 1 ^CivInfantry: Inherits: ^Infantry diff --git a/mods/cnc/rules/system.yaml b/mods/cnc/rules/system.yaml index a38cafb269..1b5424fe86 100644 --- a/mods/cnc/rules/system.yaml +++ b/mods/cnc/rules/system.yaml @@ -3,8 +3,6 @@ Player: TechTree: SupportPowerManager: ConquestVictoryConditions: - WinNotification:accom1.aud - LoseNotification:fail1.aud PowerManager: AllyRepair: PlayerResources: @@ -70,14 +68,18 @@ World: Bridges: bridge1, bridge2, bridge3, bridge4 PaletteFromCurrentTileset@terrain: Name: terrain + ShadowIndex: 4 PaletteFromCurrentTileset@static: Name: staticterrain + ShadowIndex: 4 PaletteFromFile@chrome: Name: chrome Filename: temperat.pal + ShadowIndex: 3 PaletteFromFile@effect: Name: effect Filename: temperat.pal + ShadowIndex: 4 PaletteFromRGBA@shadow: Name: shadow R: 0 @@ -151,17 +153,6 @@ World: CreateMPPlayers: SpawnMPUnits: MPStartLocations: - EvaAlerts: - RadarUp: comcntr1.aud - RadarDown: powrdn1.aud - BuildingCannotPlaceAudio: deploy1.aud - CashTickUp: - CashTickDown: - LowPower: lopower1.aud - SilosNeeded: silos1.aud - PrimaryBuildingSelected: pribldg1.aud - AbilityInsufficientPower: nopower1.aud - LevelUp: text2.aud SpatialBins: BinSize: 4 Shroud: diff --git a/mods/cnc/rules/tech.yaml b/mods/cnc/rules/tech.yaml index e69a4b19d8..ace9a55d64 100644 --- a/mods/cnc/rules/tech.yaml +++ b/mods/cnc/rules/tech.yaml @@ -21,7 +21,7 @@ V19.Husk: # Hospital HOSP: - Inherits: ^TechBuilding + Inherits: ^CivBuilding Building: Footprint: xx xx Dimensions: 2,2 @@ -29,9 +29,7 @@ HOSP: Name: Hospital LeavesHusk: HuskActor: HOSP.Husk - Reservable: RepairsUnits: - RallyPoint: HOSP.Husk: Inherits: ^CivBuildingHusk diff --git a/mods/cnc/weapons.yaml b/mods/cnc/weapons.yaml index a7e222c044..a010367eee 100644 --- a/mods/cnc/weapons.yaml +++ b/mods/cnc/weapons.yaml @@ -8,7 +8,7 @@ UnitExplode: Light: 60% Heavy: 25% Explosion: 8 - InfDeath: 3 + InfDeath: 4 ImpactSound: xplobig6 UnitExplodeSmall: @@ -21,7 +21,7 @@ UnitExplodeSmall: Light: 60% Heavy: 25% Explosion: 8 - InfDeath: 3 + InfDeath: 4 ImpactSound: xplos GrenadierExplode: @@ -34,7 +34,7 @@ GrenadierExplode: Light: 60% Heavy: 25% Explosion: 8 - InfDeath: 2 + InfDeath: 3 ImpactSound: xplos Atomic: @@ -48,7 +48,7 @@ Atomic: Light: 60% Heavy: 25% Explosion: 6 - InfDeath: 4 + InfDeath: 5 ImpactSound: nukexplo Warhead@areanuke: DamageModel: PerCell @@ -62,7 +62,7 @@ Atomic: Light: 60% Heavy: 25% Delay: 3 - InfDeath: 4 + InfDeath: 5 ImpactSound: xplobig4 IonCannon: @@ -75,7 +75,7 @@ IonCannon: Wood: 60% Light: 60% Heavy: 25% - InfDeath: 4 + InfDeath: 5 Warhead@area: DamageModel: PerCell Damage: 200 @@ -88,7 +88,7 @@ IonCannon: Light: 60% Heavy: 25% Delay: 3 - InfDeath: 4 + InfDeath: 5 Sniper: Report: RAMGUN2 @@ -104,7 +104,7 @@ Sniper: Wood: 5% Light: 5% Heavy: 5% - InfDeath: 1 + InfDeath: 2 HighV: ROF: 40 @@ -120,7 +120,7 @@ HighV: Wood: 50% Light: 50% Heavy: 25% - InfDeath: 1 + InfDeath: 2 Explosion: 1 HeliAGGun: @@ -140,7 +140,7 @@ HeliAGGun: Wood: 50% Light: 50% Heavy: 25% - InfDeath: 1 + InfDeath: 2 Explosion: 1 HeliAAGun: @@ -160,7 +160,7 @@ HeliAAGun: Wood: 50% Light: 50% Heavy: 25% - InfDeath: 1 + InfDeath: 2 Explosion: 1 Pistol: @@ -176,7 +176,7 @@ Pistol: Wood: 50% Light: 50% Heavy: 25% - InfDeath: 1 + InfDeath: 2 Explosion: 1 Damage: 1 @@ -194,7 +194,7 @@ M16: Light: 30% Heavy: 10% Explosion: 1 - InfDeath: 1 + InfDeath: 2 Damage: 15 Rockets: @@ -220,7 +220,7 @@ Rockets: Wood: 75% Light: 75% Heavy: 50% - InfDeath: 3 + InfDeath: 4 Explosion: 4 ImpactSound: xplos SmudgeType: Crater @@ -251,7 +251,7 @@ BikeRockets: Wood: 30% Light: 75% Heavy: 30% - InfDeath: 3 + InfDeath: 4 Explosion: 4 ImpactSound: xplos SmudgeType: Crater @@ -282,7 +282,7 @@ OrcaAGMissiles: Wood: 75% Light: 75% Heavy: 50% - InfDeath: 3 + InfDeath: 4 Explosion: 4 ImpactSound: xplos SmudgeType: Crater @@ -313,7 +313,7 @@ OrcaAAMissiles: Wood: 75% Light: 75% Heavy: 50% - InfDeath: 3 + InfDeath: 4 Explosion: 4 ImpactSound: xplos SmudgeType: Crater @@ -332,7 +332,7 @@ Flamethrower: Wood: 200% Light: 75% Heavy: 25% - InfDeath: 4 + InfDeath: 5 ImpactSound: flamer2 SmudgeType: Scorch Damage: 35 @@ -352,7 +352,7 @@ BigFlamer: Wood: 200% Light: 75% Heavy: 25% - InfDeath: 4 + InfDeath: 5 Explosion: 3 ImpactSound: flamer2 SmudgeType: Scorch @@ -372,7 +372,7 @@ Chemspray: Wood: 75% Light: 75% Heavy: 50% - InfDeath: 5 + InfDeath: 6 SmudgeType: Scorch ImpactSound: xplos @@ -392,7 +392,7 @@ Grenade: Wood: 75% Light: 75% Heavy: 50% - InfDeath: 2 + InfDeath: 3 Explosion: 5 ImpactSound: xplos SmudgeType: Crater @@ -412,7 +412,7 @@ Grenade: Wood: 75% Light: 75% Heavy: 50% - InfDeath: 3 + InfDeath: 4 Explosion: 4 ImpactSound: xplos SmudgeType: Crater @@ -432,7 +432,7 @@ Grenade: Wood: 75% Light: 75% Heavy: 50% - InfDeath: 3 + InfDeath: 4 Explosion: 4 ImpactSound: xplos SmudgeType: Crater @@ -452,7 +452,7 @@ Grenade: Wood: 75% Light: 75% Heavy: 50% - InfDeath: 3 + InfDeath: 4 Explosion: 4 ImpactSound: xplos SmudgeType: Crater @@ -473,7 +473,7 @@ Grenade: Wood: 75% Light: 75% Heavy: 50% - InfDeath: 3 + InfDeath: 4 Explosion: 4 ImpactSound: xplos SmudgeType: Crater @@ -493,7 +493,7 @@ TurretGun: Wood: 75% Light: 75% Heavy: 50% - InfDeath: 3 + InfDeath: 4 Explosion: 4 ImpactSound: xplos SmudgeType: Crater @@ -523,7 +523,7 @@ MammothMissiles: Wood: 75% Light: 75% Heavy: 50% - InfDeath: 3 + InfDeath: 4 Explosion: 4 ImpactSound: xplos SmudgeType: Crater @@ -554,7 +554,7 @@ MammothMissiles: Wood: 50% Light: 100% Heavy: 50% - InfDeath: 3 + InfDeath: 4 Explosion: 4 ImpactSound: xplos SmudgeType: Crater @@ -585,7 +585,7 @@ MammothMissiles: Wood: 75% Light: 75% Heavy: 50% - InfDeath: 3 + InfDeath: 4 Explosion: 4 ImpactSound: xplos SmudgeType: Crater @@ -611,7 +611,7 @@ ArtilleryShell: Wood: 75% Light: 60% Heavy: 25% - InfDeath: 2 + InfDeath: 3 Explosion: 8 SmudgeType: Crater ImpactSound: XPLOSML2 @@ -629,7 +629,7 @@ MachineGun: Wood: 50% Light: 50% Heavy: 25% - InfDeath: 1 + InfDeath: 2 Explosion: 1 Damage: 15 @@ -657,7 +657,7 @@ BoatMissile: Wood: 75% Light: 60% Heavy: 25% - InfDeath: 2 + InfDeath: 3 Explosion: 5 ImpactSound: xplos SmudgeType: Crater @@ -688,7 +688,7 @@ TowerMissle: Wood: 75% Light: 60% Heavy: 25% - InfDeath: 2 + InfDeath: 3 Explosion: 5 ImpactSound: xplos SmudgeType: Crater @@ -705,7 +705,7 @@ Napalm: Wood: 100% Light: 60% Heavy: 25% - InfDeath: 4 + InfDeath: 5 Explosion: 3 ImpactSound: flamer2 SmudgeType: Scorch @@ -719,7 +719,7 @@ Napalm.Crate: Wood: 100% Light: 60% Heavy: 25% - InfDeath: 4 + InfDeath: 5 Explosion: 3 ImpactSound: flamer2 SmudgeType: Scorch @@ -734,7 +734,7 @@ Laser: BeamRadius: 1 Warhead: Spread: 1 - InfDeath: 4 + InfDeath: 5 SmudgeType: Scorch Damage: 200 @@ -760,7 +760,7 @@ SAMMissile: Wood: 75% Light: 75% Heavy: 50% - InfDeath: 3 + InfDeath: 4 Explosion: 4 ImpactSound: xplos SmudgeType: Crater @@ -788,7 +788,7 @@ HonestJohn: Wood: 75% Light: 60% Heavy: 25% - InfDeath: 2 + InfDeath: 3 Explosion: 5 ImpactSound: xplos SmudgeType: Crater @@ -798,7 +798,7 @@ Tiberium: ROF: 4 Warhead: Spread: 1 - InfDeath: 5 + InfDeath: 6 Damage: 1 PreventProne: yes diff --git a/mods/d2k/TODO b/mods/d2k/TODO index 93459d291d..f54b90ba80 100644 --- a/mods/d2k/TODO +++ b/mods/d2k/TODO @@ -13,23 +13,21 @@ # add more spice tiles and make them fit # add game logic for concrete plates (use terrain overlay from bridges/ressources) # allow placing turrets on walls -# R8 converter needs infantry/ornithocopter frame resorter # add grenade thrower # make sandworm behave like a moving anti-vehicle mine # add neutral buildings: emperor palace, fremen siech, smugglers factory # add deathhand missile (nuke) # maybe add ornithocopter strikes (they are currently directly contrallable units with non-reloading machine guns as in Dune II) # allow upgrades -# allow different EVA voices for each faction (currently Atreides only) # add muzzles and explosions (currently falls back to RA) # create a shellmap (currently just a blank placeholder) # rework chrome UI, dialoges, tabs # add sonic tank weapon (currently uses tesla) -# make deviator change the allegiance of ememy units (currently shoots rockets) # starport prices should vary # black spots on buildings should be fading team colors # gamefile extraction (setup/setup.z) from CD fails # support patch 1.06 gamefiles: DATA.R8 has more frames and currently fails to extract, also featuring new terrain with white houses and new unit: grenade thrower -# infantry-only areas (Rough) do not show the dark-green mouse cursor # put TilesetBuilder.Export into OpenRA.Utility to call the functions directly when extracting game-files (instead of opening a GUI) -# group number metrics are off \ No newline at end of file +# group number metrics are off +# add bibs +# building offsets wrong (worst for towers) \ No newline at end of file diff --git a/mods/d2k/cursors.yaml b/mods/d2k/cursors.yaml index e001140b8b..51cc2e42ab 100644 --- a/mods/d2k/cursors.yaml +++ b/mods/d2k/cursors.yaml @@ -1,4 +1,4 @@ -Transparent: +ShadowIndex: 1 Palettes: cursor: cursor.pal @@ -180,12 +180,12 @@ Cursors: x: 12 y: 12 ability: - start:96 + start:72 length: 8 x: 12 y: 12 ability-minimap: - start:96 + start:72 length: 8 x: 12 y: 12 @@ -237,6 +237,11 @@ Cursors: length: 1 x: 12 y: 12 + move-rough: + start:256 + length: 8 + x: 12 + y: 12 nopower: cursor powerdown-blocked: diff --git a/mods/d2k/mod.yaml b/mods/d2k/mod.yaml index 61f3999380..2486b4ca85 100644 --- a/mods/d2k/mod.yaml +++ b/mods/d2k/mod.yaml @@ -71,6 +71,9 @@ Weapons: Voices: mods/d2k/voices.yaml +Notifications: + mods/d2k/notifications.yaml + TileSets: mods/d2k/tilesets/arrakis.yaml diff --git a/mods/d2k/notifications.yaml b/mods/d2k/notifications.yaml new file mode 100644 index 0000000000..e380106b80 --- /dev/null +++ b/mods/d2k/notifications.yaml @@ -0,0 +1,37 @@ +# requires Dune 2000/DATA/GAMESFX copied to ~/.openra/Content/d2k + +Speech: + DefaultVariant: .AUD + Prefixes: + atreides: AI_ + ordos: OI_ + harkonnen: HI_ + Notifications: + Repairing: MEND + BuildingCannotPlaceAudio: PLACE + LowPower: POWER + SilosNeeded: SILOS + PrimaryBuildingSelected: PRMRY + AbilityInsufficientPower: + NewOptions: NEWOP + Win: MWIN + Lose: MFAIL + BaseAttack: ATACK + HarvesterAttack: HATTK + Leave: ABORT + +Sounds: + Notifications: + RadarUp: MULTI1 + RadarDown: + DisablePower: POWRDN1 + EnablePower: POWRUP1 + CashTickUp: CASHTIK1 + CashTickDown:CASHTIK1 + LevelUp: SCORTIK1 + ChatLine: CHAT1 + BuildPaletteOpen: BUTTON1 + BuildPaletteClose: BUTTON1 + TabClick: SIDEBAR1 + ClickSound: BUTTON1 + ClickDisabledSound: ENDLIST1 \ No newline at end of file diff --git a/mods/d2k/rules/aircraft.yaml b/mods/d2k/rules/aircraft.yaml index 85df0d311f..994a129961 100644 --- a/mods/d2k/rules/aircraft.yaml +++ b/mods/d2k/rules/aircraft.yaml @@ -1,16 +1,14 @@ -CARRYALL: +^CARRYALL: Inherits: ^Helicopter Buildable: Queue: Plane BuildPaletteOrder: 110 - Prerequisites: anyhightech - BuiltAt: hightecha - Owner: atreides,harkonnen,ordos Valued: Cost: 1200 Tooltip: Name: Carryall Description: Fast drop ship.\n Unarmed + Icon: carryallicon Health: HP: 500 Armor: diff --git a/mods/d2k/rules/atreides.yaml b/mods/d2k/rules/atreides.yaml index 55296daf4e..4193c0c6fc 100644 --- a/mods/d2k/rules/atreides.yaml +++ b/mods/d2k/rules/atreides.yaml @@ -50,6 +50,60 @@ REFA: Owner: atreides RenderBuildingWarFactory: Image: REFA + FreeActor: + Actor: HARVESTERA + InitialActivity: FindResources + SpawnOffset: 1,2 + Facing: 64 + +HARVESTERA: + Inherits: ^HARVESTER + Buildable: + Prerequisites: heavya,refa + Owner: atreides + RenderUnit: + Image: HARVESTER + +TRIKEA: + Inherits: ^TRIKE + Buildable: + Prerequisites: lighta + Owner: atreides + RenderUnit: + Image: TRIKE + +QUADA: + Inherits: ^QUAD + Buildable: + Prerequisites: lighta + Owner: atreides + RenderUnit: + Image: QUAD + +SIEGETANKA: + Inherits: ^SIEGETANK + Buildable: + Prerequisites: heavya, radara + Owner: atreides + RenderUnit: + Image: SIEGETANK + +MISSILETANKA: + Inherits: ^MISSILETANK + Buildable: + Prerequisites: heavya + Owner: atreides + RenderUnit: + Image: MISSILETANK + +CARRYALLA: + Inherits: ^CARRYALL + Buildable: + Prerequisites: hightecha + BuiltAt: hightecha + Owner: atreides + RenderUnit: + Image: CARRYALL BARRA: Inherits: ^BARRACKS diff --git a/mods/d2k/rules/harkonnen.yaml b/mods/d2k/rules/harkonnen.yaml index 4c75833e20..29fb303977 100644 --- a/mods/d2k/rules/harkonnen.yaml +++ b/mods/d2k/rules/harkonnen.yaml @@ -32,6 +32,60 @@ REFH: Owner: harkonnen RenderBuildingWarFactory: Image: REFH + FreeActor: + Actor: HARVESTERH + InitialActivity: FindResources + SpawnOffset: 1,2 + Facing: 64 + +HARVESTERH: + Inherits: ^HARVESTER + Buildable: + Prerequisites: heavyh,refh + Owner: harkonnen + RenderUnit: + Image: HARVESTER + +TRIKEH: + Inherits: ^TRIKE + Buildable: + Prerequisites: lighth + Owner: harkonnen + RenderUnit: + Image: TRIKE + +QUADH: + Inherits: ^QUAD + Buildable: + Prerequisites: lighth + Owner: harkonnen + RenderUnit: + Image: QUAD + +SIEGETANKH: + Inherits: ^SIEGETANK + Buildable: + Prerequisites: heavyh, radarh + Owner: harkonnen + RenderUnit: + Image: SIEGETANK + +MISSILETANKH: + Inherits: ^MISSILETANK + Buildable: + Prerequisites: heavyh + Owner: harkonnen + RenderUnit: + Image: MISSILETANK + +CARRYALLH: + Inherits: ^CARRYALL + Buildable: + Prerequisites: hightechh + BuiltAt: hightechh + Owner: harkonnen + RenderUnit: + Image: CARRYALL BARRH: Inherits: ^BARRACKS diff --git a/mods/d2k/rules/ordos.yaml b/mods/d2k/rules/ordos.yaml index 633c51ea1e..7d82fcda3b 100644 --- a/mods/d2k/rules/ordos.yaml +++ b/mods/d2k/rules/ordos.yaml @@ -32,6 +32,11 @@ REFO: Owner: ordos RenderBuildingWarFactory: Image: REFO + FreeActor: + Actor: HARVESTERO + InitialActivity: FindResources + SpawnOffset: 1,2 + Facing: 64 BARRO: Inherits: ^BARRACKS @@ -160,6 +165,14 @@ MCVO: RenderUnit: Image: DMCV +HARVESTERO: + Inherits: ^HARVESTER + Buildable: + Prerequisites: heavyo,refo + Owner: ordos + RenderUnit: + Image: HARVESTER + COMBATO: Inherits: ^COMBAT Buildable: @@ -171,7 +184,7 @@ RAIDER: Buildable: Queue: Vehicle BuildPaletteOrder: 15 - Prerequisites: anylight + Prerequisites: lighto Owner: ordos Valued: Cost: 200 @@ -197,17 +210,50 @@ RAIDER: SecondaryOffset: 0,0,0,-4 AutoTarget: +QUADO: + Inherits: ^QUAD + Buildable: + Prerequisites: lighto + Owner: ordos + RenderUnit: + Image: QUAD + +SIEGETANKO: + Inherits: ^SIEGETANK + Buildable: + Prerequisites: heavyo, radaro + Owner: ordos + RenderUnit: + Image: SIEGETANK + +MISSILETANKO: + Inherits: ^MISSILETANK + Buildable: + Prerequisites: heavyo + Owner: ordos + RenderUnit: + Image: MISSILETANK + +CARRYALLO: + Inherits: ^CARRYALL + Buildable: + Prerequisites: hightecho + BuiltAt: hightecho + Owner: ordos + RenderUnit: + Image: CARRYALL + DEVIATORTANK: Inherits: ^Tank Valued: Cost: 800 Tooltip: Name: Deviator - Description: Long range artillery.\n Strong vs Infantry, Tanks, Air\n Weak vs Buildings + Description: Will cause no actual damage.\nFires a warhead which changes allegiances\n but does not effect buildings or tanks. Buildable: Queue: Vehicle BuildPaletteOrder: 50 - Prerequisites: anyheavy + Prerequisites: heavyo Owner: ordos Mobile: Speed: 6 @@ -218,8 +264,12 @@ DEVIATORTANK: RevealsShroud: Range: 6 RenderUnit: - AttackFrontal: - PrimaryWeapon: MammothTusk +# Captures: +# CaptureTypes: +# Range: 5 +# wastedAfterwards: false + AttackLoyalty: + PrimaryWeapon: FakeMissile PrimaryLocalOffset: -7,2,0,0,25, 7,2,0,0,-25 PrimaryRecoil: 1 AutoTarget: diff --git a/mods/d2k/rules/structures.yaml b/mods/d2k/rules/structures.yaml index 8a175de16f..0bdda97453 100644 --- a/mods/d2k/rules/structures.yaml +++ b/mods/d2k/rules/structures.yaml @@ -41,8 +41,6 @@ Tooltip: Name: Windtrap Description: Provides power for other structures - ProvidesCustomPrerequisite: - Prerequisite: anypower Building: Power: 100 Footprint: xx xx xx @@ -60,7 +58,6 @@ Buildable: Queue: Building BuildPaletteOrder: 30 - Prerequisites: anypower Hotkey: b Valued: Cost: 400 @@ -104,8 +101,6 @@ Tooltip: Name: High Tech Factory Description: Produces Carryalls - ProvidesCustomPrerequisite: - Prerequisite: anyhightech Building: Power: -30 Footprint: _x_ xxx xxx @@ -180,9 +175,6 @@ Buildable: Queue: Building BuildPaletteOrder: 10 - Prerequisites: anypower - ProvidesCustomPrerequisite: - Prerequisite: anyref Valued: Cost: 1400 Tooltip: @@ -207,11 +199,6 @@ Capacity: 2000 CustomSellValue: Value: 600 - FreeActor: - Actor: HARVESTER - InitialActivity: FindResources - SpawnOffset: 1,2 - Facing: 64 ^SILO: Inherits: ^Building @@ -245,8 +232,6 @@ Buildable: Queue: Building BuildPaletteOrder: 50 - ProvidesCustomPrerequisite: - Prerequisite: anylight Valued: Cost: 1000 Tooltip: @@ -266,8 +251,8 @@ -RenderBuilding: RallyPoint: Exit@1: - SpawnOffset: 10,0 - ExitCell: 1,3 + SpawnOffset: 5,0 + ExitCell: 1,1 Production: Produces: Vehicle PrimaryBuilding: @@ -282,8 +267,6 @@ Buildable: Queue: Building BuildPaletteOrder: 50 - ProvidesCustomPrerequisite: - Prerequisite: anyheavy Valued: Cost: 2000 Tooltip: @@ -302,9 +285,10 @@ Bib: -RenderBuilding: RallyPoint: + RallyPoint: 0,3 Exit@1: - SpawnOffset: 10,0 - ExitCell: 1,3 + SpawnOffset: -2,-2 + ExitCell: 0,2 Production: Produces: Vehicle PrimaryBuilding: @@ -321,8 +305,6 @@ Buildable: Queue: Building BuildPaletteOrder: 60 - ProvidesCustomPrerequisite: - Prerequisite: anyradar Valued: Cost: 1400 Tooltip: @@ -348,8 +330,6 @@ Tooltip: Name: Starport Description: Provides a dropzone for vehicle reinforcements - ProvidesCustomPrerequisite: - Prerequisite: anystarport Buildable: Queue: Building BuildPaletteOrder: 60 diff --git a/mods/d2k/rules/system.yaml b/mods/d2k/rules/system.yaml index 16a55f9f57..c5c3df8814 100644 --- a/mods/d2k/rules/system.yaml +++ b/mods/d2k/rules/system.yaml @@ -2,18 +2,7 @@ Player: TechTree: PlaceBuilding: SupportPowerManager: - ConquestVictoryConditions@Atreides: - Race: atreides - WinNotification: AI_MWIN.AUD - LoseNotification: AI_MFAIL.AUD - ConquestVictoryConditions@Harkonnen: - Race: harkonnen - WinNotification: HI_MWIN.AUD - LoseNotification: HI_MFAIL.AUD - ConquestVictoryConditions@Ordos: - Race: ordos - WinNotification: OI_MWIN.AUD - LoseNotification: OI_MFAIL.AUD + ConquestVictoryConditions: PowerManager: AllyRepair: PlayerResources: @@ -65,15 +54,8 @@ Player: PlayerColorPalette: BasePalette: d2k RemapIndex: 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255 - BaseAttackNotifier@Atreides: - Race: atreides - Audio: AI_ATACK.AUD - BaseAttackNotifier@Harkonnen: - Race: harkonnen - Audio: HI_ATACK.AUD - BaseAttackNotifier@Ordos: - Race: ordos - Audio: OI_ATACK.AUD + BaseAttackNotifier: + HarvesterAttackNotifier: World: OpenWidgetAtGameStart: @@ -91,15 +73,19 @@ World: ValidGround: Sand, Dune, Rock PaletteFromCurrentTileset: Name: terrain + ShadowIndex: 1 PaletteFromFile@d2k: Name: d2k Filename: d2k.pal + ShadowIndex: 1 PaletteFromFile@chrome: Name: chrome Filename: d2k.pal + ShadowIndex: 3 PaletteFromFile@effect: Name: effect Filename: temperat.pal + ShadowIndex: 4 PaletteFromRGBA@shadow: Name: shadow R: 0 @@ -179,25 +165,12 @@ World: SpawnMPUnits@ordos: InitialUnit: mcvo Faction: ordos -#TODO: These are just the Atreides sounds. - EvaAlerts: - RadarUp: POWRUP1.aud - RadarDown: POWRDN1.aud - BuildingCannotPlaceAudio: AI_PLACE.AUD - CashTickUp: CASHTIK1.aud - CashTickDown:CASHTIK1.aud - NewOptions: AI_NEWOP.AUD - LowPower: AI_POWER.AUD - SilosNeeded: AI_SILOS.AUD - PrimaryBuildingSelected: AI_PRMRY.AUD - AbilityInsufficientPower: - LevelUp: SCORTIK1.aud - Repairing: SpatialBins: BinSize: 4 Shroud: PathFinder: ValidateOrder: + CRATE: Tooltip: Name: Crate @@ -234,21 +207,42 @@ CRATE: SelectionShares: 2 NoBaseSelectionShares: 9001 Unit: mcvo - GiveUnitCrateAction@Trike: + GiveUnitCrateAction@TrikeA: SelectionShares: 7 - Unit: trike - GiveUnitCrateAction@Quad: + Unit: trikea + GiveUnitCrateAction@TrikeH: + SelectionShares: 7 + Unit: trikeh + GiveUnitCrateAction@QuadA: SelectionShares: 6 - Unit: quad + Unit: quada + GiveUnitCrateAction@QuadH: + SelectionShares: 6 + Unit: quadh + GiveUnitCrateAction@QuadO: + SelectionShares: 6 + Unit: quado GiveUnitCrateAction@Raider: SelectionShares: 6 Unit: raider - GiveUnitCrateAction@SiegeTank: + GiveUnitCrateAction@SiegeTankA: SelectionShares: 6 - Unit: siegetank - GiveUnitCrateAction@MissileTank: + Unit: siegetanka + GiveUnitCrateAction@SiegeTankH: SelectionShares: 6 - Unit: missiletank + Unit: siegetankh + GiveUnitCrateAction@SiegeTankO: + SelectionShares: 6 + Unit: siegetanko + GiveUnitCrateAction@MissileTankA: + SelectionShares: 6 + Unit: missiletanka + GiveUnitCrateAction@MissileTankH: + SelectionShares: 6 + Unit: missiletankh + GiveUnitCrateAction@MissileTankO: + SelectionShares: 6 + Unit: missiletanko GiveUnitCrateAction@CombatA: SelectionShares: 5 Unit: combata diff --git a/mods/d2k/rules/vehicles.yaml b/mods/d2k/rules/vehicles.yaml index d1c0b7934f..0a690176b7 100644 --- a/mods/d2k/rules/vehicles.yaml +++ b/mods/d2k/rules/vehicles.yaml @@ -27,18 +27,17 @@ Transforms: TransformSounds: BUILD1.aud -HARVESTER: +^HARVESTER: Inherits: ^Vehicle Buildable: Queue: Vehicle BuildPaletteOrder: 10 - Prerequisites: anyref,anyheavy - Owner: atreides,harkonnen,ordos Valued: Cost: 1100 Tooltip: Name: Spice Harvester Description: Collects Spice for processing.\n Unarmed + Icon: harvestericon Selectable: Priority: 7 Bounds: 42,42 @@ -46,7 +45,7 @@ HARVESTER: Capacity: 20 Resources: Spice UnloadTicksPerBale: 1 - # How far away from our linked proc (refinery) to find resources (in cells): + # How far away from our linked refinery to find resources (in cells): SearchFromProcRadius: 24 # How far away from last harvest order location to find more resources (in cells): SearchFromOrderRadius: 12 @@ -62,18 +61,17 @@ HARVESTER: Range: 4 -AttackMove: -TRIKE: +^TRIKE: Inherits: ^Vehicle Buildable: Queue: Vehicle BuildPaletteOrder: 15 - Prerequisites: anylight - Owner: atreides,harkonnen Valued: Cost: 200 Tooltip: Name: Scout Trike Description: Weak Scout.\n Decent vs. Infantry + Icon: trikeicon Selectable: Bounds: 24,24 Health: @@ -91,18 +89,17 @@ TRIKE: PrimaryOffset: 0,0,0,-4 AutoTarget: -QUAD: +^QUAD: Inherits: ^Vehicle Buildable: Queue: Vehicle BuildPaletteOrder: 30 - Prerequisites: anylight - Owner: atreides,harkonnen,ordos Valued: Cost: 400 Tooltip: Name: Quad Description: Fast scout vehicle, armed with \nrockets.\n Strong vs Vehicles\n Weak vs Infantry + Icon: quadicon Health: HP: 120 Armor: @@ -154,18 +151,17 @@ QUAD: Selectable: Bounds: 30,30 -SIEGETANK: +^SIEGETANK: Inherits: ^Tank Buildable: Queue: Vehicle BuildPaletteOrder: 80 - Prerequisites: anyradar - Owner: atreides,harkonnen,ordos Valued: Cost: 600 Tooltip: Name: Siege Tank Description: Long-range artillery.\n Strong vs Infantry, Buildings\n Weak vs Tanks, Aircraft + Icon: siegetankicon Health: HP: 75 Armor: @@ -189,18 +185,17 @@ SIEGETANK: Selectable: Bounds: 30,30 -MISSILETANK: +^MISSILETANK: Inherits: ^Tank Valued: Cost: 800 Tooltip: Name: Missile Tank Description: Long range artillery.\n Strong vs Infantry, Buildings\n Weak vs Tanks, Aircraft + Icon: missiletankicon Buildable: Queue: Vehicle BuildPaletteOrder: 50 - Prerequisites: anyheavy - Owner: atreides,harkonnen,ordos Mobile: Speed: 6 Health: diff --git a/mods/d2k/tilesets/arrakis.yaml b/mods/d2k/tilesets/arrakis.yaml index 355f682020..86a8b200d9 100644 --- a/mods/d2k/tilesets/arrakis.yaml +++ b/mods/d2k/tilesets/arrakis.yaml @@ -31,6 +31,7 @@ Terrain: AcceptsSmudgeType: IsWater: False Color: 255,88,116,116 + CustomCursor: move-rough TerrainType@Concrete: Type: Concrete AcceptsSmudgeType: @@ -69,6 +70,7 @@ Templates: Id: 1 Image: BASE01 Size: 2,2 + Category: Dune PickAny: False Tiles: 0: Sand @@ -79,6 +81,7 @@ Templates: Id: 2 Image: BASE02 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 0: Rough @@ -89,6 +92,7 @@ Templates: Id: 3 Image: BASE03 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 0: Rough @@ -99,6 +103,7 @@ Templates: Id: 4 Image: BASE04 Size: 2,2 + Category: Dune PickAny: False Tiles: 0: Sand @@ -109,6 +114,7 @@ Templates: Id: 5 Image: BASE05 Size: 2,2 + Category: Dune PickAny: False Tiles: 0: Dune @@ -119,6 +125,7 @@ Templates: Id: 6 Image: BASE06 Size: 2,2 + Category: Dune PickAny: False Tiles: 1: Dune @@ -129,6 +136,7 @@ Templates: Id: 7 Image: BASE07 Size: 2,2 + Category: Dune PickAny: False Tiles: 1: Dune @@ -139,6 +147,7 @@ Templates: Id: 8 Image: BASE08 Size: 2,2 + Category: Cliff-Type-Changer PickAny: False Tiles: 1: Cliff @@ -149,6 +158,7 @@ Templates: Id: 9 Image: BASE09 Size: 1,2 + Category: SandyCliff PickAny: False Tiles: 0: Transition @@ -157,6 +167,7 @@ Templates: Id: 10 Image: BASE10 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -167,6 +178,7 @@ Templates: Id: 11 Image: BASE11 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -177,6 +189,7 @@ Templates: Id: 12 Image: BASE12 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 3: Cliff @@ -187,6 +200,7 @@ Templates: Id: 13 Image: BASE13 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 1: Cliff @@ -197,6 +211,7 @@ Templates: Id: 14 Image: BASE14 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 3: Cliff @@ -207,6 +222,7 @@ Templates: Id: 15 Image: BASE15 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -217,6 +233,7 @@ Templates: Id: 16 Image: BASE16 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 3: Cliff @@ -227,6 +244,7 @@ Templates: Id: 17 Image: BASE17 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 1: Cliff @@ -237,6 +255,7 @@ Templates: Id: 18 Image: BASE18 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 1: Cliff @@ -247,6 +266,7 @@ Templates: Id: 19 Image: BASE19 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 1: Cliff @@ -257,6 +277,7 @@ Templates: Id: 20 Image: BASE20 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 1: Cliff @@ -267,6 +288,7 @@ Templates: Id: 21 Image: BASE21 Size: 2,2 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -277,6 +299,7 @@ Templates: Id: 22 Image: BASE22 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 1: Rough @@ -287,6 +310,7 @@ Templates: Id: 23 Image: BASE23 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 1: Rough @@ -297,6 +321,7 @@ Templates: Id: 24 Image: BASE24 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 1: Cliff @@ -307,6 +332,7 @@ Templates: Id: 25 Image: BASE25 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 1: Cliff @@ -317,6 +343,7 @@ Templates: Id: 26 Image: BASE26 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 1: Cliff @@ -327,6 +354,7 @@ Templates: Id: 27 Image: BASE27 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 1: Rough @@ -337,6 +365,7 @@ Templates: Id: 28 Image: BASE28 Size: 2,2 + Category: Rock PickAny: False Tiles: 1: Rough @@ -347,6 +376,7 @@ Templates: Id: 29 Image: BASE29 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 1: Cliff @@ -357,6 +387,7 @@ Templates: Id: 30 Image: BASE30 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 1: Cliff @@ -367,6 +398,7 @@ Templates: Id: 31 Image: BASE31 Size: 2,3 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -379,6 +411,7 @@ Templates: Id: 32 Image: BASE32 Size: 2,2 + Category: Rock-SandSmooth PickAny: False Tiles: 1: Transition @@ -389,6 +422,7 @@ Templates: Id: 33 Image: BASE33 Size: 2,3 + Category: SandyCliff PickAny: False Tiles: 1: Sand @@ -401,6 +435,7 @@ Templates: Id: 34 Image: BASE34 Size: 2,3 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -413,6 +448,7 @@ Templates: Id: 35 Image: BASE35 Size: 2,3 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -425,6 +461,7 @@ Templates: Id: 36 Image: BASE36 Size: 2,2 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -435,6 +472,7 @@ Templates: Id: 37 Image: BASE37 Size: 2,2 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -445,6 +483,7 @@ Templates: Id: 38 Image: BASE38 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -455,6 +494,7 @@ Templates: Id: 39 Image: BASE39 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -465,6 +505,7 @@ Templates: Id: 40 Image: BASE40 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -475,6 +516,7 @@ Templates: Id: 41 Image: BASE41 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -485,6 +527,7 @@ Templates: Id: 42 Image: BASE42 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -495,6 +538,7 @@ Templates: Id: 43 Image: BASE43 Size: 2,2 + Category: Cliff-Type-Changer PickAny: False Tiles: 0: Cliff @@ -505,6 +549,7 @@ Templates: Id: 44 Image: BASE44 Size: 2,2 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -515,6 +560,7 @@ Templates: Id: 45 Image: BASE45 Size: 2,2 + Category: Rock-SandSmooth PickAny: False Tiles: 1: Transition @@ -525,6 +571,7 @@ Templates: Id: 46 Image: BASE46 Size: 2,2 + Category: Rock-SandSmooth PickAny: False Tiles: 3: Transition @@ -535,6 +582,7 @@ Templates: Id: 47 Image: BASE47 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 2: Cliff @@ -545,6 +593,7 @@ Templates: Id: 48 Image: BASE48 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 3: Cliff @@ -555,6 +604,7 @@ Templates: Id: 49 Image: BASE49 Size: 3,2 + Category: SandyCliff PickAny: False Tiles: 2: Cliff @@ -567,6 +617,7 @@ Templates: Id: 50 Image: BASE50 Size: 3,2 + Category: SandyCliff PickAny: False Tiles: 2: Cliff @@ -579,6 +630,7 @@ Templates: Id: 51 Image: BASE51 Size: 3,2 + Category: SandyCliff PickAny: False Tiles: 5: Sand @@ -591,6 +643,7 @@ Templates: Id: 52 Image: BASE52 Size: 3,2 + Category: SandyCliff PickAny: False Tiles: 5: Cliff @@ -603,6 +656,7 @@ Templates: Id: 53 Image: BASE53 Size: 2,2 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Sand @@ -641,6 +695,7 @@ Templates: Id: 58 Image: BASE58 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Cliff @@ -648,6 +703,7 @@ Templates: Id: 59 Image: BASE59 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -655,6 +711,7 @@ Templates: Id: 60 Image: BASE60 Size: 1,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Sand @@ -662,6 +719,7 @@ Templates: Id: 61 Image: BASE61 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -669,6 +727,7 @@ Templates: Id: 62 Image: BASE62 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -676,6 +735,7 @@ Templates: Id: 63 Image: BASE63 Size: 1,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -683,6 +743,7 @@ Templates: Id: 64 Image: BASE64 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -690,6 +751,7 @@ Templates: Id: 65 Image: BASE65 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 3: Transition @@ -700,6 +762,7 @@ Templates: Id: 66 Image: BASE66 Size: 1,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -707,6 +770,7 @@ Templates: Id: 67 Image: BASE67 Size: 1,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -714,6 +778,7 @@ Templates: Id: 68 Image: BASE68 Size: 2,1 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -722,6 +787,7 @@ Templates: Id: 69 Image: BASE69 Size: 2,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -730,6 +796,7 @@ Templates: Id: 70 Image: BASE70 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -740,6 +807,7 @@ Templates: Id: 71 Image: BASE71 Size: 1,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -747,6 +815,7 @@ Templates: Id: 72 Image: BASE72 Size: 1,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -754,6 +823,7 @@ Templates: Id: 73 Image: BASE73 Size: 1,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -761,6 +831,7 @@ Templates: Id: 74 Image: BASE74 Size: 1,2 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -769,6 +840,7 @@ Templates: Id: 75 Image: BASE75 Size: 1,2 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -777,6 +849,7 @@ Templates: Id: 76 Image: BASE76 Size: 1,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -784,6 +857,7 @@ Templates: Id: 77 Image: BASE77 Size: 2,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -792,6 +866,7 @@ Templates: Id: 78 Image: BASE78 Size: 2,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -800,6 +875,7 @@ Templates: Id: 79 Image: BASE79 Size: 2,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -808,6 +884,7 @@ Templates: Id: 80 Image: BASE80 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -815,6 +892,7 @@ Templates: Id: 81 Image: BASE81 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -822,6 +900,7 @@ Templates: Id: 82 Image: BASE82 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -829,6 +908,7 @@ Templates: Id: 83 Image: BASE83 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -836,6 +916,7 @@ Templates: Id: 84 Image: BASE84 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -843,6 +924,7 @@ Templates: Id: 85 Image: BASE85 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -850,6 +932,7 @@ Templates: Id: 86 Image: BASE86 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -857,6 +940,7 @@ Templates: Id: 87 Image: BASE87 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -864,6 +948,7 @@ Templates: Id: 88 Image: BASE88 Size: 3,1 + Category: Brick PickAny: False Tiles: 0: Concrete @@ -873,6 +958,7 @@ Templates: Id: 89 Image: BASE89 Size: 1,1 + Category: Brick PickAny: False Tiles: 0: Concrete @@ -880,6 +966,7 @@ Templates: Id: 90 Image: BASE90 Size: 3,2 + Category: Brick PickAny: False Tiles: 0: Concrete @@ -892,6 +979,7 @@ Templates: Id: 91 Image: BASE91 Size: 3,3 + Category: Brick PickAny: False Tiles: 2: Concrete @@ -907,6 +995,7 @@ Templates: Id: 92 Image: BASE92 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -914,6 +1003,7 @@ Templates: Id: 93 Image: BASE93 Size: 3,2 + Category: Brick PickAny: False Tiles: 5: Concrete @@ -926,6 +1016,7 @@ Templates: Id: 94 Image: BASE94 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 1: Rock @@ -936,6 +1027,7 @@ Templates: Id: 95 Image: BASE95 Size: 1,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -944,6 +1036,7 @@ Templates: Id: 96 Image: BASE96 Size: 3,3 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -959,6 +1052,7 @@ Templates: Id: 97 Image: BASE97 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -969,6 +1063,7 @@ Templates: Id: 98 Image: BASE98 Size: 1,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -977,6 +1072,7 @@ Templates: Id: 99 Image: BASE99 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -984,6 +1080,7 @@ Templates: Id: 100 Image: BASE100 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -991,6 +1088,7 @@ Templates: Id: 101 Image: BASE101 Size: 3,3 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -1006,6 +1104,7 @@ Templates: Id: 102 Image: BASE102 Size: 3,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -1018,6 +1117,7 @@ Templates: Id: 103 Image: BASE103 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -1028,6 +1128,7 @@ Templates: Id: 104 Image: BASE104 Size: 2,1 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -1036,6 +1137,7 @@ Templates: Id: 105 Image: BASE105 Size: 2,1 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -1044,6 +1146,7 @@ Templates: Id: 106 Image: BASE106 Size: 1,2 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -1052,6 +1155,7 @@ Templates: Id: 107 Image: BASE107 Size: 1,2 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -1060,6 +1164,7 @@ Templates: Id: 108 Image: BASE108 Size: 1,1 + Category: Z-Crap(Unusual) PickAny: False Tiles: 0: Cliff @@ -1067,6 +1172,7 @@ Templates: Id: 109 Image: BASE109 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -1074,14 +1180,16 @@ Templates: Id: 110 Image: BASE110 Size: 2,1 + Category: SandyCliff PickAny: False Tiles: - 0: Sand + 0: Cliff 1: Cliff Template@111: Id: 111 Image: BASE111 Size: 2,1 + Category: SandyCliff PickAny: False Tiles: 1: Cliff @@ -1090,6 +1198,7 @@ Templates: Id: 112 Image: BASE112 Size: 1,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -1098,6 +1207,7 @@ Templates: Id: 113 Image: BASE113 Size: 4,2 + Category: Rock-Detail PickAny: False Tiles: 3: Rough @@ -1112,6 +1222,7 @@ Templates: Id: 114 Image: BASE114 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 1: Rough @@ -1122,6 +1233,7 @@ Templates: Id: 115 Image: BASE115 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -1129,6 +1241,7 @@ Templates: Id: 116 Image: BASE116 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -1136,6 +1249,7 @@ Templates: Id: 117 Image: BASE117 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -1146,6 +1260,7 @@ Templates: Id: 118 Image: BASE118 Size: 3,2 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -1158,6 +1273,7 @@ Templates: Id: 119 Image: BASE119 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -1168,6 +1284,7 @@ Templates: Id: 120 Image: BASE120 Size: 1,2 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -1176,6 +1293,7 @@ Templates: Id: 121 Image: BASE121 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 1: Rough @@ -1184,6 +1302,7 @@ Templates: Id: 122 Image: BASE122 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 1: Rough @@ -1192,6 +1311,7 @@ Templates: Id: 123 Image: BASE123 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -1199,6 +1319,7 @@ Templates: Id: 124 Image: BASE124 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -1206,6 +1327,7 @@ Templates: Id: 125 Image: BASE125 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 1: Rough @@ -1564,6 +1686,7 @@ Templates: Id: 176 Image: BASE176 Size: 3,3 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Rock @@ -1579,6 +1702,7 @@ Templates: Id: 177 Image: BASE177 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -1589,6 +1713,7 @@ Templates: Id: 178 Image: BASE178 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -1599,6 +1724,7 @@ Templates: Id: 179 Image: BASE179 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -1609,6 +1735,7 @@ Templates: Id: 180 Image: BASE180 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -1619,6 +1746,7 @@ Templates: Id: 181 Image: BASE181 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 1: Cliff @@ -1629,6 +1757,7 @@ Templates: Id: 182 Image: BASE182 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 1: Cliff @@ -1639,6 +1768,7 @@ Templates: Id: 183 Image: BASE183 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Cliff @@ -1649,6 +1779,7 @@ Templates: Id: 184 Image: BASE184 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Cliff @@ -1659,6 +1790,7 @@ Templates: Id: 185 Image: BASE185 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -1669,6 +1801,7 @@ Templates: Id: 186 Image: BASE186 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -1679,6 +1812,7 @@ Templates: Id: 187 Image: BASE187 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 3: Rock @@ -1689,6 +1823,7 @@ Templates: Id: 188 Image: BASE188 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 3: Rock @@ -1699,6 +1834,7 @@ Templates: Id: 189 Image: BASE189 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 3: Rock @@ -1709,6 +1845,7 @@ Templates: Id: 190 Image: BASE190 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 3: Sand @@ -1719,6 +1856,7 @@ Templates: Id: 191 Image: BASE191 Size: 3,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 5: Cliff @@ -1731,6 +1869,7 @@ Templates: Id: 192 Image: BASE192 Size: 3,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 2: Cliff @@ -1743,6 +1882,7 @@ Templates: Id: 193 Image: BASE193 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 1: Transition @@ -1753,6 +1893,7 @@ Templates: Id: 194 Image: BASE194 Size: 2,3 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -1765,6 +1906,7 @@ Templates: Id: 195 Image: BASE195 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -1775,6 +1917,7 @@ Templates: Id: 196 Image: BASE196 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -1785,6 +1928,7 @@ Templates: Id: 197 Image: BASE197 Size: 2,3 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -1797,6 +1941,7 @@ Templates: Id: 198 Image: BASE198 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -1807,6 +1952,7 @@ Templates: Id: 199 Image: BASE199 Size: 2,1 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Sand @@ -1815,6 +1961,7 @@ Templates: Id: 200 Image: BASE200 Size: 2,3 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -1827,6 +1974,7 @@ Templates: Id: 201 Image: BASE201 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 1: Cliff @@ -1837,16 +1985,18 @@ Templates: Id: 202 Image: BASE202 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: - 0: Transition - 2: Transition + 0: Cliff + 2: Cliff 3: Rock 1: Transition Template@203: Id: 203 Image: BASE203 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 1: Cliff @@ -1857,6 +2007,7 @@ Templates: Id: 204 Image: BASE204 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 1: Cliff @@ -1867,6 +2018,7 @@ Templates: Id: 205 Image: BASE205 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 1: Rock @@ -1877,6 +2029,7 @@ Templates: Id: 206 Image: BASE206 Size: 2,3 + Category: BaseBorder-Cliff PickAny: False Tiles: 1: Cliff @@ -1889,6 +2042,7 @@ Templates: Id: 207 Image: BASE207 Size: 2,2 + Category: Cliff-Type-Changer PickAny: False Tiles: 0: Cliff @@ -1899,6 +2053,7 @@ Templates: Id: 208 Image: BASE208 Size: 2,2 + Category: Cliff-Type-Changer PickAny: False Tiles: 0: Cliff @@ -1909,6 +2064,7 @@ Templates: Id: 209 Image: BASE209 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -1919,6 +2075,7 @@ Templates: Id: 210 Image: BASE210 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 3: Cliff @@ -1929,6 +2086,7 @@ Templates: Id: 211 Image: BASE211 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 1: Cliff @@ -1939,6 +2097,7 @@ Templates: Id: 212 Image: BASE212 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 3: Cliff @@ -1949,6 +2108,7 @@ Templates: Id: 213 Image: BASE213 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Cliff @@ -1959,6 +2119,7 @@ Templates: Id: 214 Image: BASE214 Size: 2,3 + Category: Sand-Detail PickAny: False Tiles: 4: Rough @@ -1971,6 +2132,7 @@ Templates: Id: 215 Image: BASE215 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -1978,6 +2140,7 @@ Templates: Id: 216 Image: BASE216 Size: 2,3 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 1: Sand @@ -1990,6 +2153,7 @@ Templates: Id: 217 Image: BASE217 Size: 1,1 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Rough @@ -1997,6 +2161,7 @@ Templates: Id: 218 Image: BASE218 Size: 2,2 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 1: Rough @@ -2007,6 +2172,7 @@ Templates: Id: 219 Image: BASE219 Size: 2,2 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 1: Sand @@ -2017,6 +2183,7 @@ Templates: Id: 220 Image: BASE220 Size: 3,2 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 2: Rough @@ -2029,6 +2196,7 @@ Templates: Id: 221 Image: BASE221 Size: 3,1 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Rough @@ -2038,16 +2206,18 @@ Templates: Id: 222 Image: BASE222 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 1: Transition 3: Transition 2: Transition - 0: Transition + 0: Cliff Template@223: Id: 223 Image: BASE223 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Sand @@ -2058,6 +2228,7 @@ Templates: Id: 224 Image: BASE224 Size: 2,2 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2068,9 +2239,10 @@ Templates: Id: 225 Image: BASE225 Size: 1,1 + Category: Dune PickAny: False Tiles: - 0: Sand + 0: Dune Template@226: Id: 226 Image: BASE226 @@ -2096,6 +2268,7 @@ Templates: Id: 229 Image: BASE229 Size: 2,2 + Category: Dune PickAny: False Tiles: 1: Sand @@ -2106,6 +2279,7 @@ Templates: Id: 230 Image: BASE230 Size: 2,1 + Category: Dune PickAny: False Tiles: 1: Dune @@ -2114,6 +2288,7 @@ Templates: Id: 231 Image: BASE231 Size: 2,1 + Category: Dune PickAny: False Tiles: 1: Dune @@ -2122,6 +2297,7 @@ Templates: Id: 232 Image: BASE232 Size: 2,2 + Category: Dune PickAny: False Tiles: 1: Dune @@ -2132,6 +2308,7 @@ Templates: Id: 233 Image: BASE233 Size: 1,1 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2139,6 +2316,7 @@ Templates: Id: 234 Image: BASE234 Size: 1,1 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2146,6 +2324,7 @@ Templates: Id: 235 Image: BASE235 Size: 1,1 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2153,6 +2332,7 @@ Templates: Id: 236 Image: BASE236 Size: 1,1 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2160,6 +2340,7 @@ Templates: Id: 237 Image: BASE237 Size: 1,1 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2167,6 +2348,7 @@ Templates: Id: 238 Image: BASE238 Size: 1,1 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2174,6 +2356,7 @@ Templates: Id: 239 Image: BASE239 Size: 1,1 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2181,6 +2364,7 @@ Templates: Id: 240 Image: BASE240 Size: 1,1 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2188,6 +2372,7 @@ Templates: Id: 241 Image: BASE241 Size: 1,1 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2195,6 +2380,7 @@ Templates: Id: 242 Image: BASE242 Size: 1,1 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2202,6 +2388,7 @@ Templates: Id: 243 Image: BASE243 Size: 1,1 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2209,6 +2396,7 @@ Templates: Id: 244 Image: BASE244 Size: 1,1 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2216,6 +2404,7 @@ Templates: Id: 245 Image: BASE245 Size: 1,1 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2223,6 +2412,7 @@ Templates: Id: 246 Image: BASE246 Size: 2,2 + Category: Dune PickAny: False Tiles: 0: Dune @@ -2233,6 +2423,7 @@ Templates: Id: 247 Image: BASE247 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2243,6 +2434,7 @@ Templates: Id: 248 Image: BASE248 Size: 2,1 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 1: Sand @@ -2251,6 +2443,7 @@ Templates: Id: 249 Image: BASE249 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -2258,6 +2451,7 @@ Templates: Id: 250 Image: BASE250 Size: 1,1 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Rough @@ -2265,6 +2459,7 @@ Templates: Id: 251 Image: BASE251 Size: 2,2 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Rough @@ -2275,6 +2470,7 @@ Templates: Id: 252 Image: BASE252 Size: 2,2 + Category: Z-Crap(Unusual) PickAny: False Tiles: 0: Cliff @@ -2285,6 +2481,7 @@ Templates: Id: 253 Image: BASE253 Size: 2,2 + Category: Cliff-Type-Changer PickAny: False Tiles: 1: Cliff @@ -2295,6 +2492,7 @@ Templates: Id: 254 Image: BASE254 Size: 2,2 + Category: Cliff-Type-Changer PickAny: False Tiles: 0: Cliff @@ -2305,6 +2503,7 @@ Templates: Id: 255 Image: BASE255 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -2315,6 +2514,7 @@ Templates: Id: 256 Image: BASE256 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 2: Cliff @@ -2341,6 +2541,7 @@ Templates: Id: 258 Image: BASE258 Size: 1,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 1: Cliff @@ -2349,6 +2550,7 @@ Templates: Id: 259 Image: BASE259 Size: 1,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -2356,6 +2558,7 @@ Templates: Id: 260 Image: BASE260 Size: 1,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -2363,6 +2566,7 @@ Templates: Id: 261 Image: BASE261 Size: 1,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -2370,6 +2574,7 @@ Templates: Id: 262 Image: BASE262 Size: 1,1 + Category: Rock-SandSmooth PickAny: False Tiles: 0: Transition @@ -2377,6 +2582,7 @@ Templates: Id: 263 Image: BASE263 Size: 3,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -2389,6 +2595,7 @@ Templates: Id: 264 Image: BASE264 Size: 3,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 3: Cliff @@ -2439,6 +2646,7 @@ Templates: Id: 269 Image: BASE269 Size: 2,1 + Category: Rock-SandSmooth PickAny: False Tiles: 1: Transition @@ -2456,6 +2664,7 @@ Templates: Id: 271 Image: BAT00 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -2463,6 +2672,7 @@ Templates: Id: 272 Image: BAT01 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -2470,6 +2680,7 @@ Templates: Id: 273 Image: BAT02 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -2477,6 +2688,7 @@ Templates: Id: 274 Image: BAT03 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -2484,6 +2696,7 @@ Templates: Id: 275 Image: BAT04 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -2491,6 +2704,7 @@ Templates: Id: 276 Image: BAT05 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -2498,6 +2712,7 @@ Templates: Id: 277 Image: BAT06 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Cliff @@ -2505,6 +2720,7 @@ Templates: Id: 278 Image: BAT07 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -2512,6 +2728,7 @@ Templates: Id: 279 Image: BAT08 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -2519,6 +2736,7 @@ Templates: Id: 280 Image: BAT09 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -2526,6 +2744,7 @@ Templates: Id: 281 Image: BAT10 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -2533,6 +2752,7 @@ Templates: Id: 282 Image: BAT11 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -2540,6 +2760,7 @@ Templates: Id: 283 Image: BAT12 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -2550,6 +2771,7 @@ Templates: Id: 284 Image: BAT13 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2557,6 +2779,7 @@ Templates: Id: 285 Image: BAT14 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2564,6 +2787,7 @@ Templates: Id: 286 Image: BAT15 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2574,6 +2798,7 @@ Templates: Id: 287 Image: BAT16 Size: 2,3 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -2586,6 +2811,7 @@ Templates: Id: 288 Image: BAT17 Size: 2,3 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -2598,6 +2824,7 @@ Templates: Id: 289 Image: BAT18 Size: 2,3 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -2610,6 +2837,7 @@ Templates: Id: 290 Image: BAT19 Size: 2,3 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -2622,6 +2850,7 @@ Templates: Id: 291 Image: BAT20 Size: 1,2 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2630,6 +2859,7 @@ Templates: Id: 292 Image: BAT21 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2637,6 +2867,7 @@ Templates: Id: 293 Image: BAT22 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2644,6 +2875,7 @@ Templates: Id: 294 Image: BAT23 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2651,6 +2883,7 @@ Templates: Id: 295 Image: BAT24 Size: 1,2 + Category: Sand-Detail PickAny: False Tiles: 1: Sand @@ -2659,6 +2892,7 @@ Templates: Id: 296 Image: BAT25 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2666,6 +2900,7 @@ Templates: Id: 297 Image: BAT26 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2673,6 +2908,7 @@ Templates: Id: 298 Image: BAT27 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2680,6 +2916,7 @@ Templates: Id: 299 Image: BAT28 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2687,6 +2924,7 @@ Templates: Id: 300 Image: BAT29 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2697,6 +2935,7 @@ Templates: Id: 301 Image: BAT30 Size: 2,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -2705,6 +2944,7 @@ Templates: Id: 302 Image: BAT31 Size: 1,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -2713,6 +2953,7 @@ Templates: Id: 303 Image: BAT32 Size: 2,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -2721,6 +2962,7 @@ Templates: Id: 304 Image: BAT33 Size: 2,1 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Rough @@ -2729,6 +2971,7 @@ Templates: Id: 305 Image: BAT34 Size: 1,1 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Rough @@ -2736,6 +2979,7 @@ Templates: Id: 306 Image: BAT35 Size: 2,2 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Rough @@ -2746,6 +2990,7 @@ Templates: Id: 307 Image: BAT36 Size: 2,2 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Rough @@ -2756,6 +3001,7 @@ Templates: Id: 308 Image: BAT37 Size: 2,2 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Sand @@ -2766,6 +3012,7 @@ Templates: Id: 309 Image: BAT38 Size: 3,2 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Sand @@ -2778,6 +3025,7 @@ Templates: Id: 310 Image: BAT39 Size: 4,2 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Rough @@ -2792,6 +3040,7 @@ Templates: Id: 311 Image: BAT40 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2802,6 +3051,7 @@ Templates: Id: 312 Image: BAT41 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2809,6 +3059,7 @@ Templates: Id: 313 Image: BAT42 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2816,6 +3067,7 @@ Templates: Id: 314 Image: BAT43 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2823,6 +3075,7 @@ Templates: Id: 315 Image: BAT44 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2830,6 +3083,7 @@ Templates: Id: 316 Image: BAT45 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2837,6 +3091,7 @@ Templates: Id: 317 Image: BAT46 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2844,6 +3099,7 @@ Templates: Id: 318 Image: BAT47 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2851,6 +3107,7 @@ Templates: Id: 319 Image: BAT48 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2858,6 +3115,7 @@ Templates: Id: 320 Image: BAT49 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2866,6 +3124,7 @@ Templates: Id: 321 Image: BAT50 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2873,6 +3132,7 @@ Templates: Id: 322 Image: BAT51 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2880,6 +3140,7 @@ Templates: Id: 323 Image: BAT52 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2887,6 +3148,7 @@ Templates: Id: 324 Image: BAT53 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2894,6 +3156,7 @@ Templates: Id: 325 Image: BAT54 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2902,6 +3165,7 @@ Templates: Id: 326 Image: BAT55 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2909,6 +3173,7 @@ Templates: Id: 327 Image: BAT56 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2916,6 +3181,7 @@ Templates: Id: 328 Image: BAT57 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2923,6 +3189,7 @@ Templates: Id: 329 Image: BAT58 Size: 2,2 + Category: Rock-Detail(Cliff) PickAny: False Tiles: 0: Cliff @@ -2933,6 +3200,7 @@ Templates: Id: 330 Image: BAT59 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -2943,6 +3211,7 @@ Templates: Id: 331 Image: BAT60 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -2953,6 +3222,7 @@ Templates: Id: 332 Image: BAT61 Size: 2,3 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -2965,6 +3235,7 @@ Templates: Id: 333 Image: BAT62 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -2975,6 +3246,7 @@ Templates: Id: 334 Image: BAT63 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -2985,6 +3257,7 @@ Templates: Id: 335 Image: BAT64 Size: 1,2 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -2993,6 +3266,7 @@ Templates: Id: 336 Image: BAT65 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3000,6 +3274,7 @@ Templates: Id: 337 Image: BAT66 Size: 3,2 + Category: Sand-Detail PickAny: False Tiles: 2: Rough @@ -3012,6 +3287,7 @@ Templates: Id: 338 Image: BAT67 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 1: Rough @@ -3020,6 +3296,7 @@ Templates: Id: 339 Image: BGBS00 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -3030,6 +3307,7 @@ Templates: Id: 340 Image: BGBS01 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3040,6 +3318,7 @@ Templates: Id: 341 Image: BGBS02 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -3050,6 +3329,7 @@ Templates: Id: 342 Image: BGBS03 Size: 6,3 + Category: Rock-Detail(Cliff) PickAny: False Tiles: 5: Rock @@ -3074,6 +3354,7 @@ Templates: Id: 343 Image: BGBS04 Size: 3,3 + Category: Rock-Detail(Cliff) PickAny: False Tiles: 2: Rock @@ -3089,6 +3370,7 @@ Templates: Id: 344 Image: BGBS05 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -3099,6 +3381,7 @@ Templates: Id: 345 Image: BGBS06 Size: 2,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -3107,6 +3390,7 @@ Templates: Id: 346 Image: BGBS07 Size: 2,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -3115,6 +3399,7 @@ Templates: Id: 347 Image: BGBS08 Size: 4,2 + Category: Rock-Detail PickAny: False Tiles: 0: Cliff @@ -3129,6 +3414,7 @@ Templates: Id: 348 Image: BGBS09 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -3139,6 +3425,7 @@ Templates: Id: 349 Image: BGBS10 Size: 3,2 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3151,6 +3438,7 @@ Templates: Id: 350 Image: BGBS11 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3158,6 +3446,7 @@ Templates: Id: 351 Image: BGBS12 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -3168,6 +3457,7 @@ Templates: Id: 352 Image: BGBS13 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3175,6 +3465,7 @@ Templates: Id: 353 Image: BGBS14 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3182,6 +3473,7 @@ Templates: Id: 354 Image: BGBS15 Size: 3,3 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -3197,6 +3489,7 @@ Templates: Id: 355 Image: BGBS16 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -3207,6 +3500,7 @@ Templates: Id: 356 Image: BGBS17 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -3217,6 +3511,7 @@ Templates: Id: 357 Image: BGBS18 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -3225,6 +3520,7 @@ Templates: Id: 358 Image: BGBS19 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -3235,6 +3531,7 @@ Templates: Id: 359 Image: BGBS20 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -3245,6 +3542,7 @@ Templates: Id: 360 Image: BGBS21 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 1: Rough @@ -3253,6 +3551,7 @@ Templates: Id: 361 Image: ICE00 Size: 4,1 + Category: Sand-Detail PickAny: False Tiles: 0: Cliff @@ -3263,6 +3562,7 @@ Templates: Id: 362 Image: ICE01 Size: 3,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3272,6 +3572,7 @@ Templates: Id: 363 Image: ICE02 Size: 1,2 + Category: Ice PickAny: False Tiles: 0: Cliff @@ -3280,6 +3581,7 @@ Templates: Id: 364 Image: ICE03 Size: 2,2 + Category: Rock-Detail(Cliff) PickAny: False Tiles: 0: Cliff @@ -3290,6 +3592,7 @@ Templates: Id: 365 Image: ICE04 Size: 2,1 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3298,6 +3601,7 @@ Templates: Id: 366 Image: ICE05 Size: 4,1 + Category: Ice-Detail PickAny: False Tiles: 0: Cliff @@ -3308,6 +3612,7 @@ Templates: Id: 367 Image: ICE06 Size: 1,1 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3315,6 +3620,7 @@ Templates: Id: 368 Image: ICE07 Size: 1,1 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3322,6 +3628,7 @@ Templates: Id: 369 Image: ICE08 Size: 1,1 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3329,6 +3636,7 @@ Templates: Id: 370 Image: ICE09 Size: 1,1 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3336,6 +3644,7 @@ Templates: Id: 371 Image: ICE10 Size: 1,4 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3346,6 +3655,7 @@ Templates: Id: 372 Image: ICE11 Size: 1,2 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3354,6 +3664,7 @@ Templates: Id: 373 Image: ICE12 Size: 6,3 + Category: Ice-Detail PickAny: False Tiles: 5: Sand @@ -3378,6 +3689,7 @@ Templates: Id: 374 Image: ICE13 Size: 3,2 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3390,6 +3702,7 @@ Templates: Id: 375 Image: ICE14 Size: 1,1 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3397,6 +3710,7 @@ Templates: Id: 376 Image: ICE15 Size: 4,3 + Category: Ice PickAny: False Tiles: 0: Cliff @@ -3415,6 +3729,7 @@ Templates: Id: 377 Image: ICE16 Size: 4,1 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3425,6 +3740,7 @@ Templates: Id: 378 Image: ICE17 Size: 2,3 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3437,6 +3753,7 @@ Templates: Id: 379 Image: ICE18 Size: 1,1 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3444,6 +3761,7 @@ Templates: Id: 380 Image: ICE19 Size: 1,1 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3451,6 +3769,7 @@ Templates: Id: 381 Image: ICE20 Size: 1,1 + Category: Z-Crap(Unusual) PickAny: False Tiles: 0: Sand @@ -3458,6 +3777,7 @@ Templates: Id: 382 Image: ICE21 Size: 1,4 + Category: Z-Crap(Unusual) PickAny: False Tiles: 0: Cliff @@ -3468,6 +3788,7 @@ Templates: Id: 383 Image: ICE22 Size: 1,2 + Category: Z-Crap(Unusual) PickAny: False Tiles: 1: Cliff @@ -3476,6 +3797,7 @@ Templates: Id: 384 Image: ICE23 Size: 2,3 + Category: Sand-Detail PickAny: False Tiles: 1: Sand @@ -3488,6 +3810,7 @@ Templates: Id: 385 Image: ICE24 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3498,6 +3821,7 @@ Templates: Id: 386 Image: ICE25 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3508,6 +3832,7 @@ Templates: Id: 387 Image: ICE26 Size: 2,3 + Category: Ice PickAny: False Tiles: 0: Ice @@ -3520,6 +3845,7 @@ Templates: Id: 388 Image: ICE27 Size: 2,2 + Category: Ice PickAny: False Tiles: 0: Cliff @@ -3530,6 +3856,7 @@ Templates: Id: 389 Image: ICE28 Size: 1,1 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3537,6 +3864,7 @@ Templates: Id: 390 Image: ICE29 Size: 1,1 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3544,6 +3872,7 @@ Templates: Id: 391 Image: ICE30 Size: 1,1 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3551,6 +3880,7 @@ Templates: Id: 392 Image: ICE31 Size: 1,1 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3558,6 +3888,7 @@ Templates: Id: 393 Image: ICE32 Size: 2,2 + Category: Ice PickAny: False Tiles: 2: Cliff @@ -3568,6 +3899,7 @@ Templates: Id: 394 Image: ICE33 Size: 2,3 + Category: Ice PickAny: False Tiles: 0: Cliff @@ -3580,6 +3912,7 @@ Templates: Id: 395 Image: ICE34 Size: 2,2 + Category: Ice PickAny: False Tiles: 0: Cliff @@ -3590,6 +3923,7 @@ Templates: Id: 396 Image: ICE35 Size: 2,2 + Category: Ice PickAny: False Tiles: 0: Ice @@ -3600,6 +3934,7 @@ Templates: Id: 397 Image: ICE36 Size: 2,2 + Category: Ice PickAny: False Tiles: 0: Ice @@ -3610,6 +3945,7 @@ Templates: Id: 398 Image: ICE37 Size: 2,2 + Category: Ice PickAny: False Tiles: 0: Ice @@ -3620,6 +3956,7 @@ Templates: Id: 399 Image: ICE38 Size: 2,1 + Category: Ice-Detail PickAny: False Tiles: 0: Sand @@ -3628,6 +3965,7 @@ Templates: Id: 400 Image: ICE39 Size: 2,1 + Category: Ice-Detail PickAny: False Tiles: 1: Sand @@ -3636,6 +3974,7 @@ Templates: Id: 401 Image: ICE40 Size: 2,3 + Category: Rock-Detail(Cliff) PickAny: False Tiles: 0: Sand @@ -3648,6 +3987,7 @@ Templates: Id: 402 Image: ICE41 Size: 3,1 + Category: Z-Crap(Unusual) PickAny: False Tiles: 0: Rough @@ -3657,6 +3997,7 @@ Templates: Id: 403 Image: ICE42 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3665,6 +4006,7 @@ Templates: Id: 404 Image: ICE43 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3673,6 +4015,7 @@ Templates: Id: 405 Image: ICE44 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3681,6 +4024,7 @@ Templates: Id: 406 Image: ICE45 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3689,6 +4033,7 @@ Templates: Id: 407 Image: ICE46 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 1: Sand @@ -3697,6 +4042,7 @@ Templates: Id: 408 Image: TREE00 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3704,6 +4050,7 @@ Templates: Id: 409 Image: TREE01 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3718,6 +4065,7 @@ Templates: Id: 411 Image: TREE03 Size: 1,2 + Category: Sand-Detail PickAny: False Tiles: 0: Cliff @@ -3726,6 +4074,7 @@ Templates: Id: 412 Image: TREE04 Size: 2,2 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Rough @@ -3736,6 +4085,7 @@ Templates: Id: 413 Image: TREE05 Size: 3,2 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Rough @@ -3748,6 +4098,7 @@ Templates: Id: 414 Image: TREE06 Size: 5,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -3759,6 +4110,7 @@ Templates: Id: 415 Image: TREE07 Size: 1,2 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3767,6 +4119,7 @@ Templates: Id: 416 Image: TREE08 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3777,6 +4130,7 @@ Templates: Id: 417 Image: TREE09 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Transition @@ -3785,6 +4139,7 @@ Templates: Id: 418 Image: TREE10 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -3792,6 +4147,7 @@ Templates: Id: 419 Image: TREE11 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -3799,6 +4155,7 @@ Templates: Id: 420 Image: TREE12 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -3806,6 +4163,7 @@ Templates: Id: 421 Image: TREE13 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Sand @@ -3816,6 +4174,7 @@ Templates: Id: 422 Image: TREE14 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -3826,6 +4185,7 @@ Templates: Id: 423 Image: TREE15 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -3836,6 +4196,7 @@ Templates: Id: 424 Image: TREE16 Size: 6,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -3848,6 +4209,7 @@ Templates: Id: 425 Image: TREE17 Size: 3,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -3857,6 +4219,7 @@ Templates: Id: 426 Image: TREE18 Size: 2,1 + Category: Rock-Detail PickAny: False Tiles: 1: Rock @@ -3865,6 +4228,7 @@ Templates: Id: 427 Image: TREE19 Size: 2,2 + Category: SandyCliff PickAny: False Tiles: 0: Cliff @@ -3875,6 +4239,7 @@ Templates: Id: 428 Image: TREE20 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Transition @@ -3885,6 +4250,7 @@ Templates: Id: 429 Image: TREE21 Size: 3,3 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -3900,6 +4266,7 @@ Templates: Id: 430 Image: TREE22 Size: 1,1 + Category: Z-Crap(Unusual) PickAny: False Tiles: 0: Rough @@ -3907,6 +4274,7 @@ Templates: Id: 431 Image: TREE23 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -3917,6 +4285,7 @@ Templates: Id: 432 Image: TREE24 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -3924,6 +4293,7 @@ Templates: Id: 433 Image: TREE25 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -3931,6 +4301,7 @@ Templates: Id: 434 Image: TREE26 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 1: Rough @@ -3939,6 +4310,7 @@ Templates: Id: 435 Image: TREE27 Size: 3,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -3948,6 +4320,7 @@ Templates: Id: 436 Image: TREE28 Size: 2,3 + Category: Sand-Detail PickAny: False Tiles: 0: Rough @@ -3967,6 +4340,7 @@ Templates: Id: 438 Image: TREE30 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -3977,6 +4351,7 @@ Templates: Id: 439 Image: TREE31 Size: 3,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -3989,6 +4364,7 @@ Templates: Id: 440 Image: TREE32 Size: 2,2 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -3999,6 +4375,7 @@ Templates: Id: 441 Image: TREE33 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -4006,6 +4383,7 @@ Templates: Id: 442 Image: TREE34 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -4013,6 +4391,7 @@ Templates: Id: 443 Image: TREE35 Size: 3,2 + Category: Rock-Detail(Cliff) PickAny: False Tiles: 5: Sand @@ -4025,6 +4404,7 @@ Templates: Id: 444 Image: TREE36 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rock @@ -4032,6 +4412,7 @@ Templates: Id: 445 Image: WAST00 Size: 6,3 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -4056,6 +4437,7 @@ Templates: Id: 446 Image: WAST01 Size: 3,1 + Category: Sand-Detail PickAny: False Tiles: 0: Dune @@ -4065,6 +4447,7 @@ Templates: Id: 447 Image: WAST02 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -4073,6 +4456,7 @@ Templates: Id: 448 Image: WAST03 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 2: Dune @@ -4083,6 +4467,7 @@ Templates: Id: 449 Image: WAST04 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -4091,6 +4476,7 @@ Templates: Id: 450 Image: WAST05 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 1: Sand @@ -4099,6 +4485,7 @@ Templates: Id: 451 Image: WAST06 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -4106,6 +4493,7 @@ Templates: Id: 452 Image: WAST07 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -4113,6 +4501,7 @@ Templates: Id: 453 Image: WAST08 Size: 1,2 + Category: Sand-Detail PickAny: False Tiles: 0: Dune @@ -4121,6 +4510,7 @@ Templates: Id: 454 Image: WAST09 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -4129,6 +4519,7 @@ Templates: Id: 455 Image: WAST10 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -4137,6 +4528,7 @@ Templates: Id: 456 Image: WAST11 Size: 3,2 + Category: Sand-Detail PickAny: False Tiles: 1: Sand @@ -4149,6 +4541,7 @@ Templates: Id: 457 Image: WAST12 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -4156,6 +4549,7 @@ Templates: Id: 458 Image: WAST13 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 1: Sand @@ -4164,6 +4558,7 @@ Templates: Id: 459 Image: WAST14 Size: 2,2 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -4174,6 +4569,7 @@ Templates: Id: 460 Image: WAST15 Size: 2,2 + Category: Dead-Wurm PickAny: False Tiles: 0: Rough @@ -4184,6 +4580,7 @@ Templates: Id: 461 Image: WAST16 Size: 3,1 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Rough @@ -4193,6 +4590,7 @@ Templates: Id: 462 Image: WAST17 Size: 5,1 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Rough @@ -4204,6 +4602,7 @@ Templates: Id: 463 Image: WAST18 Size: 2,1 + Category: Sand-Detail(Rotten Base) PickAny: False Tiles: 0: Rough @@ -4212,6 +4611,7 @@ Templates: Id: 464 Image: WAST19 Size: 1,2 + Category: Dead-Wurm PickAny: False Tiles: 0: Cliff @@ -4220,6 +4620,7 @@ Templates: Id: 465 Image: WAST20 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -4227,6 +4628,7 @@ Templates: Id: 466 Image: WAST21 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -4234,6 +4636,7 @@ Templates: Id: 467 Image: WAST22 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Cliff @@ -4242,6 +4645,7 @@ Templates: Id: 468 Image: WAST23 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Cliff @@ -4249,6 +4653,7 @@ Templates: Id: 469 Image: WAST24 Size: 1,1 + Category: Sand-Detail PickAny: False Tiles: 0: Cliff @@ -4256,6 +4661,7 @@ Templates: Id: 470 Image: WAST25 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Cliff @@ -4264,6 +4670,7 @@ Templates: Id: 471 Image: WAST26 Size: 1,1 + Category: Dead-Wurm PickAny: False Tiles: 0: Sand @@ -4271,6 +4678,7 @@ Templates: Id: 472 Image: WAST27 Size: 2,1 + Category: Dead-Wurm PickAny: False Tiles: 1: Sand @@ -4279,6 +4687,7 @@ Templates: Id: 473 Image: WAST28 Size: 1,1 + Category: Dead-Wurm PickAny: False Tiles: 0: Sand @@ -4286,6 +4695,7 @@ Templates: Id: 474 Image: WAST29 Size: 4,3 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -4304,6 +4714,7 @@ Templates: Id: 475 Image: WAST30 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 3: Sand @@ -4314,6 +4725,7 @@ Templates: Id: 476 Image: WAST31 Size: 3,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -4326,6 +4738,7 @@ Templates: Id: 477 Image: WAST32 Size: 1,2 + Category: Sand-Detail PickAny: False Tiles: 0: Concrete @@ -4334,6 +4747,7 @@ Templates: Id: 478 Image: WAST33 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -4341,6 +4755,7 @@ Templates: Id: 479 Image: WAST34 Size: 1,1 + Category: Rock-Detail PickAny: False Tiles: 0: Rough @@ -4348,6 +4763,7 @@ Templates: Id: 480 Image: WAST35 Size: 4,1 + Category: Sand-Detail PickAny: False Tiles: 0: Sand @@ -4358,6 +4774,7 @@ Templates: Id: 481 Image: WAST36 Size: 2,2 + Category: BaseBorder-Cliff PickAny: False Tiles: 0: Cliff @@ -4368,7 +4785,8 @@ Templates: Id: 482 Image: WAST37 Size: 2,1 + Category: Sand-Detail PickAny: False Tiles: 0: Rough - 1: Rough \ No newline at end of file + 1: Rough diff --git a/mods/d2k/weapons.yaml b/mods/d2k/weapons.yaml index 6a8341c8c3..433a18655e 100644 --- a/mods/d2k/weapons.yaml +++ b/mods/d2k/weapons.yaml @@ -12,7 +12,7 @@ M1Carbine: Heavy: 10% Concrete: 10% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 15 Dragon: @@ -41,7 +41,7 @@ Dragon: Concrete: 20% Explosion: med_explosion WaterExplosion: med_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: SandCrater, RockCrater Damage: 50 ImpactSound: kaboom12 @@ -71,7 +71,7 @@ QuadRockets: Wood: 30% Light: 75% Heavy: 30% - InfDeath: 3 + InfDeath: 4 Explosion: med_explosion WaterExplosion: med_splash ImpactSound: kaboom12 @@ -93,7 +93,7 @@ TurretGun: Light: 75% Concrete: 50% Explosion: small_explosion - InfDeath: 3 + InfDeath: 4 SmudgeType: SandCrater, RockCrater Damage: 60 @@ -122,7 +122,7 @@ TowerMissle: Wood: 75% Light: 60% Heavy: 25% - InfDeath: 2 + InfDeath: 3 Explosion: small_explosion ImpactSound: kaboom12 SmudgeType: SandCrater, RockCrater @@ -143,7 +143,7 @@ TowerMissle: Heavy: 40% Concrete: 30% Explosion: small_explosion - InfDeath: 3 + InfDeath: 4 SmudgeType: SandCrater, RockCrater Damage: 16 @@ -162,7 +162,7 @@ TowerMissle: Light: 75% Concrete: 50% Explosion: small_explosion - InfDeath: 3 + InfDeath: 4 SmudgeType: SandCrater, RockCrater Damage: 30 @@ -183,7 +183,7 @@ TowerMissle: Light: 75% Concrete: 50% Explosion: small_explosion - InfDeath: 3 + InfDeath: 4 SmudgeType: SandCrater, RockCrater Damage: 40 @@ -203,7 +203,7 @@ TowerMissle: Light: 75% Concrete: 50% Explosion: small_explosion - InfDeath: 3 + InfDeath: 4 SmudgeType: SandCrater, RockCrater Damage: 50 @@ -232,43 +232,37 @@ TowerMissle: Wood: 75% Light: 75% Heavy: 50% - InfDeath: 3 + InfDeath: 4 Explosion: med_explosion WaterExplosion: med_splash ImpactSound: kaboom12 SmudgeType: SandCrater, RockCrater Damage: 25 -MammothTusk: - ROF: 60 +FakeMissile: + ROF: 90 Range: 8 + Burst: 1 Report: MISSLE1 - Burst: 2 - ValidTargets: Ground, Air - Projectile: Missile - Speed: 30 - Arm: 2 + Projectile: Bullet + Speed: 35 High: true - Shadow: false - Proximity: true -# Trail: smokey - ContrailLength: 10 - Inaccuracy: 3 - Image: DRAGON - ROT: 5 - RangeLimit: 40 + Angle: .2 + Inaccuracy: 70 + Image: MISSILE + Trail: smokey + ContrailLength: 30 Warhead: - Spread: 6 + Spread: 10 Versus: - None: 90% - Wood: 75% - Light: 60% - Heavy: 25% - Explosion: med_explosion - WaterExplosion: med_splash - InfDeath: 2 + Wood: 0% + Heavy: 0% + Concrete: 0% + Explosion: large_explosion + WaterExplosion: large_splash SmudgeType: SandCrater, RockCrater - Damage: 45 + Damage: 0 + ImpactSound: kaboom12 155mm: ROF: 85 @@ -292,7 +286,7 @@ MammothTusk: Concrete: 50% Explosion: large_explosion WaterExplosion: med_splash - InfDeath: 2 + InfDeath: 3 SmudgeType: SandCrater, RockCrater Damage: 220 @@ -304,7 +298,7 @@ TTankZap: Projectile: TeslaZap Warhead: Spread: 1 - InfDeath: 5 + InfDeath: 6 Damage: 100 ChainGun: @@ -323,7 +317,7 @@ ChainGun: Heavy: 25% Concrete: 25% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 20 M60mg: @@ -341,7 +335,7 @@ M60mg: Heavy: 10% Concrete: 10% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 15 Demolish: @@ -365,7 +359,7 @@ Atomic: Heavy: 25% Concrete: 50% Explosion: nuke - InfDeath: 4 + InfDeath: 5 ImpactSound: EXPLSML2 Warhead@areanuke: DamageModel: PerCell @@ -379,7 +373,7 @@ Atomic: Heavy: 25% Concrete: 50% Delay: 4 - InfDeath: 4 + InfDeath: 5 ImpactSound: EXPLLG2 CrateNuke: @@ -393,7 +387,7 @@ CrateNuke: Heavy: 25% Concrete: 50% Explosion: nuke - InfDeath: 4 + InfDeath: 5 ImpactSound: EXPLSML2 Warhead@areanuke: DamageModel: PerCell @@ -407,7 +401,7 @@ CrateNuke: Heavy: 25% Concrete: 50% Delay: 4 - InfDeath: 4 + InfDeath: 5 ImpactSound: EXPLLG2 CrateExplosion: @@ -421,7 +415,7 @@ CrateExplosion: Heavy: 25% Explosion: self_destruct WaterExplosion: self_destruct - InfDeath: 3 + InfDeath: 4 ImpactSound: EXPLSML4 UnitExplode: @@ -435,7 +429,7 @@ UnitExplode: Heavy: 25% Explosion: self_destruct WaterExplosion: large_splash - InfDeath: 3 + InfDeath: 4 ImpactSound: EXPLMD1 UnitExplodeSmall: @@ -448,7 +442,7 @@ UnitExplodeSmall: Light: 60% Heavy: 25% Explosion: large_explosion - InfDeath: 3 + InfDeath: 4 ImpactSound: EXPLSML2 WormJaw: @@ -486,7 +480,7 @@ RedEye: Light: 60% Heavy: 25% Explosion: med_explosion - InfDeath: 2 + InfDeath: 3 SmudgeType: SandCrater, RockCrater Damage: 40 @@ -504,7 +498,7 @@ Sniper: Wood: 5% Light: 5% Heavy: 5% - InfDeath: 1 + InfDeath: 2 Vulcan: ROF: 30 @@ -521,7 +515,7 @@ Vulcan: Heavy: 25% Concrete: 25% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 10 Warhead@2: Spread: 3 @@ -531,7 +525,7 @@ Vulcan: Heavy: 25% Concrete: 25% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 10 Delay: 2 Warhead@3: @@ -542,7 +536,7 @@ Vulcan: Heavy: 25% Concrete: 25% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 10 Delay: 4 Warhead@4: @@ -553,7 +547,7 @@ Vulcan: Heavy: 25% Concrete: 25% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 10 Delay: 6 Warhead@5: @@ -564,7 +558,7 @@ Vulcan: Heavy: 25% Concrete: 25% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 10 Delay: 8 Warhead@6: @@ -575,6 +569,6 @@ Vulcan: Heavy: 25% Concrete: 25% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 10 Delay: 10 \ No newline at end of file diff --git a/mods/ra/chrome/ingame.yaml b/mods/ra/chrome/ingame.yaml index 022239407c..2931692d18 100644 --- a/mods/ra/chrome/ingame.yaml +++ b/mods/ra/chrome/ingame.yaml @@ -333,11 +333,13 @@ Container@OBSERVER_ROOT: Height: 200 DrawBackground: False RemoveTime:250 + UseContrast: yes ChatEntry@CHAT_ENTRY: X:250 Y:WINDOW_BOTTOM - HEIGHT Width: 760 Height: 30 + UseContrast: yes Background@PERF_BG: ClickThrough:true Background:dialog4 diff --git a/mods/ra/cursors.yaml b/mods/ra/cursors.yaml index 24842a8825..beef006a23 100644 --- a/mods/ra/cursors.yaml +++ b/mods/ra/cursors.yaml @@ -91,6 +91,11 @@ Cursors: length: 4 x: 12 y: 12 + move-rough: + start:10 + length: 4 + x: 12 + y: 12 move-blocked: start:14 x: 12 diff --git a/mods/ra/mod.yaml b/mods/ra/mod.yaml index 142c488fb7..541f24fbc1 100644 --- a/mods/ra/mod.yaml +++ b/mods/ra/mod.yaml @@ -70,6 +70,9 @@ Weapons: Voices: mods/ra/voices.yaml + +Notifications: + mods/ra/notifications.yaml TileSets: mods/ra/tilesets/snow.yaml diff --git a/mods/ra/notifications.yaml b/mods/ra/notifications.yaml new file mode 100644 index 0000000000..1d91e750e7 --- /dev/null +++ b/mods/ra/notifications.yaml @@ -0,0 +1,30 @@ +Speech: + Notifications: + Repairing: repair1 + LowPower: lopower1 + SilosNeeded: silond1 + PrimaryBuildingSelected: pribldg1 + BuildingCannotPlaceAudio: nodeply1 + NewOptions: newopt1 + AbilityInsufficientPower: nopowr1 + Win: misnwon1 + Lose: misnlst1 + BaseAttack: baseatk1 + HarvesterAttack: + Leave: bct1 + +Sounds: + Notifications: + RadarUp: radaron2 + RadarDown: radardn1 + CashTickUp: cashup1 + CashTickDown:cashdn1 + LevelUp: hydrod1 + DisablePower: bleep11 + EnablePower: bleep12 + ChatLine: scold1 + BuildPaletteOpen: bleep13 + BuildPaletteClose: bleep13 + TabClick: ramenu1 + ClickSound: + ClickDisabledSound: \ No newline at end of file diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index 795943cd18..7c683deb15 100644 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -948,6 +948,7 @@ HPAD: Reservable: IronCurtainable: ProductionBar: + PrimaryBuilding: AFLD: Inherits: ^Building @@ -998,6 +999,7 @@ AFLD: SelectTargetSound: slcttgt1.aud ProductionBar: SupportPowerChargeBar: + PrimaryBuilding: POWR: Inherits: ^Building diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml index 54ea9beac1..349a0a6653 100644 --- a/mods/ra/rules/system.yaml +++ b/mods/ra/rules/system.yaml @@ -31,8 +31,6 @@ Player: PlaceBuilding: SupportPowerManager: ConquestVictoryConditions: - WinNotification:misnwon1.aud - LoseNotification:misnlst1.aud PowerManager: AllyRepair: PlayerResources: @@ -212,12 +210,15 @@ World: WaterChance: .2 PaletteFromCurrentTileset: Name: terrain + ShadowIndex: 4 PaletteFromFile@chrome: Name: chrome Filename: temperat.pal + ShadowIndex: 3 PaletteFromFile@effect: Name: effect Filename: temperat.pal + ShadowIndex: 4 PaletteFromRGBA@shadow: Name: shadow R: 0 @@ -293,7 +294,6 @@ World: CreateMPPlayers: MPStartLocations: SpawnMPUnits: - EvaAlerts: SpatialBins: BinSize: 4 Shroud: diff --git a/mods/ra/weapons.yaml b/mods/ra/weapons.yaml index 2957425ad7..4136cf3c29 100644 --- a/mods/ra/weapons.yaml +++ b/mods/ra/weapons.yaml @@ -12,7 +12,7 @@ Colt45: Heavy: 5% Concrete: 5% Explosion: piff - InfDeath: 1 + InfDeath: 2 Damage: 50 ZSU-23: @@ -48,7 +48,7 @@ Vulcan: Heavy: 25% Concrete: 25% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 10 Warhead@2: Spread: 3 @@ -58,7 +58,7 @@ Vulcan: Heavy: 25% Concrete: 25% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 10 Delay: 2 Warhead@3: @@ -69,7 +69,7 @@ Vulcan: Heavy: 25% Concrete: 25% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 10 Delay: 4 Warhead@4: @@ -80,7 +80,7 @@ Vulcan: Heavy: 25% Concrete: 25% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 10 Delay: 6 Warhead@5: @@ -91,7 +91,7 @@ Vulcan: Heavy: 25% Concrete: 25% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 10 Delay: 8 Warhead@6: @@ -102,7 +102,7 @@ Vulcan: Heavy: 25% Concrete: 25% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 10 Delay: 10 @@ -135,7 +135,7 @@ Maverick: Concrete: 50% Explosion: med_explosion WaterExplosion: med_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: Crater Damage: 70 @@ -157,7 +157,7 @@ FireballLauncher: Concrete: 50% Explosion: napalm WaterExplosion: napalm - InfDeath: 4 + InfDeath: 5 SmudgeType: Scorch ImpactSound: firebl3 Damage: 150 @@ -183,7 +183,7 @@ Flamer: Concrete: 50% Explosion: small_napalm WaterExplosion: small_napalm - InfDeath: 4 + InfDeath: 5 SmudgeType: Scorch ImpactSound: firebl3 Damage: 8 @@ -205,7 +205,7 @@ ChainGun: Concrete: 25% Explosion: piffs WaterExplosion: small_splash - InfDeath: 1 + InfDeath: 2 Damage: 20 ChainGun.Yak: @@ -225,7 +225,7 @@ ChainGun.Yak: Concrete: 25% Explosion: piffs WaterExplosion: small_splash - InfDeath: 1 + InfDeath: 2 Damage: 40 Pistol: @@ -242,7 +242,7 @@ Pistol: Heavy: 25% Concrete: 25% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 1 M1Carbine: @@ -259,7 +259,7 @@ M1Carbine: Heavy: 10% Concrete: 10% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 15 Dragon: @@ -288,7 +288,7 @@ Dragon: Concrete: 20% Explosion: med_explosion WaterExplosion: med_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: Crater Damage: 50 ImpactSound: kaboom12 @@ -321,7 +321,7 @@ HellfireAG: Concrete: 50% Explosion: med_explosion WaterExplosion: med_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: Crater Damage: 40 @@ -353,7 +353,7 @@ HellfireAA: Concrete: 50% Explosion: med_explosion WaterExplosion: med_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: Crater Damage: 40 @@ -376,7 +376,7 @@ Grenade: Heavy: 5% Explosion: med_explosion WaterExplosion: small_splash - InfDeath: 2 + InfDeath: 3 SmudgeType: Crater Damage: 60 ImpactSound: kaboom12 @@ -397,7 +397,7 @@ Grenade: Concrete: 30% Explosion: small_explosion WaterExplosion: small_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: Crater Damage: 16 @@ -417,7 +417,7 @@ Grenade: Concrete: 50% Explosion: small_explosion WaterExplosion: small_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: Crater Damage: 30 @@ -439,7 +439,7 @@ Grenade: Concrete: 50% Explosion: small_explosion WaterExplosion: small_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: Crater Damage: 40 @@ -460,7 +460,7 @@ Grenade: Concrete: 50% Explosion: small_explosion WaterExplosion: small_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: Crater Damage: 50 @@ -480,7 +480,7 @@ TurretGun: Concrete: 50% Explosion: small_explosion WaterExplosion: small_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: Crater Damage: 60 @@ -511,7 +511,7 @@ MammothTusk: Heavy: 25% Explosion: med_explosion WaterExplosion: med_splash - InfDeath: 2 + InfDeath: 3 SmudgeType: Crater Damage: 45 @@ -537,7 +537,7 @@ MammothTusk: Concrete: 50% Explosion: large_explosion WaterExplosion: med_splash - InfDeath: 2 + InfDeath: 3 SmudgeType: Crater Damage: 220 @@ -557,7 +557,7 @@ M60mg: Concrete: 10% Explosion: piffs WaterExplosion: small_splash - InfDeath: 1 + InfDeath: 2 Damage: 15 Napalm: @@ -578,7 +578,7 @@ Napalm: Concrete: 50% Explosion: napalm WaterExplosion: med_splash - InfDeath: 4 + InfDeath: 5 SmudgeType: Scorch ImpactSound: firebl3 Damage: 100 @@ -593,7 +593,7 @@ CrateNapalm: Concrete: 50% Explosion: napalm WaterExplosion: napalm - InfDeath: 4 + InfDeath: 5 SmudgeType: Scorch ImpactSound: firebl3 Damage: 600 @@ -609,7 +609,7 @@ CrateExplosion: Heavy: 25% Explosion: self_destruct WaterExplosion: self_destruct - InfDeath: 3 + InfDeath: 4 ImpactSound: kaboom15 CrateNuke: @@ -624,7 +624,7 @@ CrateNuke: Concrete: 50% Explosion: nuke WaterExplosion: nuke - InfDeath: 4 + InfDeath: 5 ImpactSound: kaboom1 Warhead@areanuke: DamageModel: PerCell @@ -638,7 +638,7 @@ CrateNuke: Heavy: 25% Concrete: 50% Delay: 4 - InfDeath: 4 + InfDeath: 5 ImpactSound: kaboom22 @@ -650,7 +650,7 @@ TeslaZap: Projectile: TeslaZap Warhead: Spread: 1 - InfDeath: 5 + InfDeath: 6 Damage: 100 Nike: @@ -678,7 +678,7 @@ Nike: Heavy: 50% Concrete: 0% Explosion: med_explosion - InfDeath: 2 + InfDeath: 3 SmudgeType: Crater Damage: 100 @@ -706,7 +706,7 @@ RedEye: Light: 60% Heavy: 25% Explosion: med_explosion - InfDeath: 2 + InfDeath: 3 SmudgeType: Crater Damage: 40 @@ -732,7 +732,7 @@ RedEye: Heavy: 25% Explosion: large_explosion WaterExplosion: large_splash - InfDeath: 2 + InfDeath: 3 SmudgeType: Crater Damage: 250 ImpactSound: kaboom12 @@ -760,7 +760,7 @@ SubMissile: Heavy: 30% Explosion: large_explosion WaterExplosion: large_splash - InfDeath: 2 + InfDeath: 3 SmudgeType: Crater Damage: 300 ImpactSound: kaboom12 @@ -794,7 +794,7 @@ Stinger: Concrete: 50% Explosion: med_explosion WaterExplosion: med_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: Crater Damage: 30 @@ -821,7 +821,7 @@ TorpTube: Light: 75% Concrete: 50% WaterExplosion: large_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: Crater Damage: 180 @@ -841,7 +841,7 @@ TorpTube: Concrete: 50% Explosion: small_explosion WaterExplosion: med_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: Crater Damage: 25 @@ -863,7 +863,7 @@ DepthCharge: Light: 75% Concrete: 50% WaterExplosion: large_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: Crater Damage: 80 @@ -882,7 +882,7 @@ ParaBomb: Concrete: 50% Explosion: self_destruct WaterExplosion: small_splash - InfDeath: 3 + InfDeath: 4 SmudgeType: Crater Damage: 500 ImpactSound: kaboom15 @@ -898,7 +898,7 @@ DogJaw: Light: 0% Heavy: 0% Concrete: 0% - InfDeath: 0 + InfDeath: 1 Damage: 100 Heal: @@ -914,7 +914,7 @@ Heal: Light: 0% Heavy: 0% Concrete: 0% - InfDeath: 0 + InfDeath: 1 Damage: -50 SilencedPPK: @@ -931,7 +931,7 @@ SilencedPPK: Heavy: 0% Concrete: 0% Explosion: piffs - InfDeath: 1 + InfDeath: 2 Damage: 150 SCUD: @@ -958,7 +958,7 @@ SCUD: Heavy: 25% Explosion: napalm WaterExplosion: large_splash - InfDeath: 2 + InfDeath: 3 SmudgeType: Crater Damage: 600 ImpactSound: firebl3 @@ -976,7 +976,7 @@ Atomic: Concrete: 50% Explosion: nuke WaterExplosion: nuke - InfDeath: 4 + InfDeath: 5 ImpactSound: kaboom1 Warhead@areanuke: DamageModel: PerCell @@ -990,7 +990,7 @@ Atomic: Heavy: 25% Concrete: 50% Delay: 4 - InfDeath: 4 + InfDeath: 5 ImpactSound: kaboom22 UnitExplode: @@ -1004,7 +1004,7 @@ UnitExplode: Heavy: 25% Explosion: self_destruct WaterExplosion: large_splash - InfDeath: 3 + InfDeath: 4 ImpactSound: kaboom22 UnitExplodeSmall: @@ -1017,7 +1017,7 @@ UnitExplodeSmall: Light: 60% Heavy: 25% Explosion: large_explosion - InfDeath: 3 + InfDeath: 4 ImpactSound: kaboom15 Crush: @@ -1044,7 +1044,7 @@ APMine: Heavy: 0% Concrete: 0% ImpactSound: mine1 - InfDeath: 2 + InfDeath: 3 Explosion: napalm Demolish: @@ -1061,7 +1061,7 @@ PortaTesla: Projectile: TeslaZap Warhead: Spread: 1 - InfDeath: 5 + InfDeath: 6 Damage: 45 TTankZap: @@ -1072,7 +1072,7 @@ TTankZap: Projectile: TeslaZap Warhead: Spread: 1 - InfDeath: 5 + InfDeath: 6 Damage: 100 FLAK-23: diff --git a/packaging/linux/deb/DEBIAN/control b/packaging/linux/deb/DEBIAN/control index b8dec8ad9e..4865d8731f 100644 --- a/packaging/linux/deb/DEBIAN/control +++ b/packaging/linux/deb/DEBIAN/control @@ -1,7 +1,7 @@ Package: openra Version: {VERSION} Architecture: all -Maintainer: Paul Chote +Maintainer: Chris Forbes Installed-Size: {SIZE} Depends: libopenal1, mono-runtime (>= 2.6.7), libmono-winforms2.0-cil, libfreetype6, libsdl1.2debian, libgl1-mesa-glx, libgl1-mesa-dri, libmono-i18n2.0-cil Section: games diff --git a/packaging/package-all.sh b/packaging/package-all.sh index 406af06711..b90b47e694 100755 --- a/packaging/package-all.sh +++ b/packaging/package-all.sh @@ -26,7 +26,7 @@ find . -path "*.mdb" -delete # they are now installed to the game directory instead of placed in the gac FILES="OpenRA.Game.exe OpenRA.Editor.exe OpenRA.Utility.exe OpenRA.Renderer.SdlCommon.dll OpenRA.Renderer.Cg.dll \ OpenRA.Renderer.Gl.dll OpenRA.Renderer.Null.dll OpenRA.FileFormats.dll FreeSans.ttf FreeSansBold.ttf titles.ttf \ -cg glsl mods/ra mods/cnc COPYING HACKING INSTALL CHANGELOG" +cg glsl mods/ra mods/cnc mods/d2k COPYING HACKING INSTALL CHANGELOG" echo "Copying files..." for i in $FILES; do @@ -45,6 +45,7 @@ cp OpenRA.Game/OpenRA.ico packaging/built # Update mod versions sed "s/{DEV_VERSION}/$TAG/" ./mods/ra/mod.yaml > ./packaging/built/mods/ra/mod.yaml sed "s/{DEV_VERSION}/$TAG/" ./mods/cnc/mod.yaml > ./packaging/built/mods/cnc/mod.yaml +sed "s/{DEV_VERSION}/$TAG/" ./mods/d2k/mod.yaml > ./packaging/built/mods/d2k/mod.yaml # Remove demo.mix from cnc rm ./packaging/built/mods/cnc/bits/demo.mix @@ -82,5 +83,6 @@ echo "Creating packages..." fi ) & wait +echo "Package build done." rm -rf $BUILTDIR diff --git a/packaging/windows/OpenRA.nsi b/packaging/windows/OpenRA.nsi index 06206892bc..0f271c6118 100644 --- a/packaging/windows/OpenRA.nsi +++ b/packaging/windows/OpenRA.nsi @@ -148,6 +148,22 @@ SectionGroup /e "Mods" CopyFiles /SILENT "$TEMP\cnc-packages\*.mix" "$INSTDIR\mods\cnc\packages" RMDir /r "$TEMP\cnc-packages" SectionEnd + Section "Dune 2000" D2K + CreateDirectory "$TEMP\d2k-packages" + CopyFiles /SILENT "$INSTDIR\mods\d2k\packages\*.mix" "$TEMP\d2k-packages" + RMDir /r "$INSTDIR\mods\d2k" + SetOutPath "$INSTDIR\mods\d2k" + File "${SRCDIR}\mods\d2k\*.*" + File /r "${SRCDIR}\mods\d2k\maps" + File /r "${SRCDIR}\mods\d2k\chrome" + File /r "${SRCDIR}\mods\d2k\bits" + File /r "${SRCDIR}\mods\d2k\rules" + File /r "${SRCDIR}\mods\d2k\tilesets" + File /r "${SRCDIR}\mods\d2k\uibits" + CreateDirectory "$INSTDIR\mods\d2k\packages" + CopyFiles /SILENT "$TEMP\d2k-packages\*.mix" "$INSTDIR\mods\d2k\packages" + RMDir /r "$TEMP\d2k-packages" + SectionEnd SectionGroupEnd ;*************************** @@ -293,11 +309,13 @@ SectionEnd LangString DESC_Client ${LANG_ENGLISH} "OpenRA client and dependencies" LangString DESC_RA ${LANG_ENGLISH} "Base Red Alert mod" LangString DESC_CNC ${LANG_ENGLISH} "Base Command and Conquer mod" +LangString DESC_D2K ${LANG_ENGLISH} "Base Dune 2000 mod" !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${Client} $(DESC_Client) !insertmacro MUI_DESCRIPTION_TEXT ${RA} $(DESC_RA) !insertmacro MUI_DESCRIPTION_TEXT ${CNC} $(DESC_CNC) + !insertmacro MUI_DESCRIPTION_TEXT ${D2K} $(DESC_D2K) !insertmacro MUI_FUNCTION_DESCRIPTION_END ;***************************