diff --git a/CHANGELOG.md b/CHANGELOG.md
index a25f29d..d11e246 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -46,7 +46,7 @@ Fixes
### MLEM.Data
Additions
-- Added data and copy instructions to DataTextureAtlas
+- Added data, from, and copy instructions to DataTextureAtlas
Improvements
- Allow data texture atlas pivots and offsets to be negative
diff --git a/MLEM.Data/DataTextureAtlas.cs b/MLEM.Data/DataTextureAtlas.cs
index 05a0906..11fe3a0 100644
--- a/MLEM.Data/DataTextureAtlas.cs
+++ b/MLEM.Data/DataTextureAtlas.cs
@@ -27,6 +27,7 @@ namespace MLEM.Data {
/// - The (optional) off (of offset) instruction defines an offset that is added onto the location and pivot of this texture region. This is useful when duplicating a previously defined texture region to create a second region that has a constant offset. It requires two arguments: The x and y offset.
/// - The (optional and repeatable) cpy (or copy) instruction defines an additional texture region that should also be generated from the same data, but with a given offset that will be applied to the location and pivot. It requires three arguments: the copy region's name and the x and y offsets.
/// - The (optional and repeatable) dat (or data) instruction defines a custom data point that can be added to the resulting 's data. It requires two arguments: the data point's name and the data point's value, the latter of which is also stored as a string value.
+ /// - The (optional) frm (or from) instruction defines a texture region (defined before the current region) whose data should be copied. All data from the region will be copied, but adding additional instructions afterwards modifies the data. It requires one argument: the name of the region whose data to copy. If this instruction is used, the loc instruction is not required.
///
///
///
@@ -141,6 +142,19 @@ namespace MLEM.Data {
customData.Add(words[i + 1], words[i + 2]);
i += 2;
break;
+ case "frm":
+ case "from":
+ var fromRegion = atlas[words[i + 1]];
+ customData.Clear();
+ foreach (var key in fromRegion.GetDataKeys())
+ customData.Add(key, fromRegion.GetData(key));
+ location = fromRegion.Area;
+ pivot = fromRegion.PivotPixels;
+ if (pivot != Vector2.Zero && !pivotRelative)
+ pivot += location.Location.ToVector2();
+ offset = Vector2.Zero;
+ i += 1;
+ break;
default:
// if we have data for the previous regions, they're valid so we add them
AddCurrentRegions();
@@ -163,7 +177,7 @@ namespace MLEM.Data {
return atlas;
void AddCurrentRegions() {
- // the location is the only mandatory instruction, which is why we check it here
+ // the location is the only mandatory information, which is why we check it here
if (location == Rectangle.Empty || namesOffsets.Count <= 0)
return;
foreach (var (name, addedOff) in namesOffsets) {
diff --git a/Tests/Content/Texture.atlas b/Tests/Content/Texture.atlas
index ecf9128..a3c47f2 100644
--- a/Tests/Content/Texture.atlas
+++ b/Tests/Content/Texture.atlas
@@ -20,11 +20,13 @@ dat DataPoint2 3.5
dat DataPoint3 ---
LongTableUp
-piv 16 48
-loc 0 32 64 48
+piv 16 48 loc 0 32 64 48
copy Copy1 16 0
cpy Copy2 32 4
+Copy3 from
+LongTableUp off 2 4
+
LongTableRight LongTableDown LongTableLeft
location 32 30 64 48
piv 80 46
diff --git a/Tests/DataTextureAtlasTests.cs b/Tests/DataTextureAtlasTests.cs
index 0b0f722..cf4a02a 100644
--- a/Tests/DataTextureAtlasTests.cs
+++ b/Tests/DataTextureAtlasTests.cs
@@ -13,7 +13,7 @@ namespace Tests {
using var game = TestGame.Create();
using var texture = new Texture2D(game.GraphicsDevice, 1, 1);
var atlas = DataTextureAtlas.LoadAtlasData(new TextureRegion(texture), game.RawContent, "Texture.atlas");
- Assert.AreEqual(11, atlas.Regions.Count());
+ Assert.AreEqual(12, atlas.Regions.Count());
// no pivot
var plant = atlas["Plant"];
@@ -35,7 +35,7 @@ namespace Tests {
Assert.AreEqual(negativePivot.Area, new Rectangle(0, 32, 16, 16));
Assert.AreEqual(negativePivot.PivotPixels, new Vector2(-32, 46 - 32));
- // copies (pivot pixels should be identical to LongTableUp because they're region-internal)
+ // cpy (pivot pixels should be identical to LongTableUp because they're region-internal)
var copy1 = atlas["Copy1"];
Assert.AreEqual(copy1.Area, new Rectangle(0 + 16, 32, 64, 48));
Assert.AreEqual(copy1.PivotPixels, new Vector2(16, 48 - 32));
@@ -43,6 +43,11 @@ namespace Tests {
Assert.AreEqual(copy2.Area, new Rectangle(0 + 32, 32 + 4, 64, 48));
Assert.AreEqual(copy2.PivotPixels, new Vector2(16, 48 - 32));
+ // frm
+ var copy3 = atlas["Copy3"];
+ Assert.AreEqual(copy3.Area, new Rectangle(0 + 2, 32 + 4, 64, 48));
+ Assert.AreEqual(copy3.PivotPixels, new Vector2(16, 48 - 32));
+
// data
var data = atlas["DataTest"];
Assert.AreEqual("ThisIsSomeData", data.GetData("DataPoint1"));