Repository: shpaass/yafc-ce
Pull request #484: Blueprint Improvements / Add support for exporting all building entities to one blueprint.
Author: login: danbopes
Created: 2025-05-13T18:24:26Z | Merged: 2025-05-14T10:43:03Z

Upgrade Blueprint classes to support new logistic filter sections
Fix issue when trying to export blueprint with modules. closes #471
Support for new burner fuel inventory
Blueprints will now be exported with burner fuel inventory set (Default enabled, but can be disabled in preferences)

Linked issue #471: Create single building blueprint fails with modules
Clicking on the "Create single building blueprint" button fails when you export a building, for example moss farm from Py, if it has modules set, for example Moss.

![Image](https://github.com/user-attachments/assets/b9d193ed-97d0-43d0-87af-d9dd2940b120)
->
![Image](https://github.com/user-attachments/assets/75819aff-6383-4f5c-a359-2c09572808d1)
->
Open Factorio and import blueprint
->
![Image](https://github.com/user-attachments/assets/f3445fb1-4465-4a05-a786-2eeedd7b8315)

Diff:
diff --git a/Yafc.Model/Blueprints/Blueprint.cs b/Yafc.Model/Blueprints/Blueprint.cs
index 2d567636..9b98ac00 100644
--- a/Yafc.Model/Blueprints/Blueprint.cs
+++ b/Yafc.Model/Blueprints/Blueprint.cs
@@ -58,13 +58,13 @@ public string ToJson() {
 
 [Serializable]
 public class Blueprint(string label) {
-    public const int VERSION = 0x01000000;
+    public const long VERSION = 562949956632577;
 
     public string item { get; set; } = "blueprint";
     public string label { get; set; } = label;
     public List<BlueprintEntity> entities { get; } = [];
     public List<BlueprintIcon> icons { get; } = [];
-    public int version { get; set; } = VERSION;
+    public long version { get; set; } = VERSION;
 }
 
 [Serializable]
@@ -98,17 +98,44 @@ public void Set(IObjectWithQuality<Goods> goods) {
 
 [Serializable]
 public class BlueprintEntity {
-    [JsonPropertyName("entity_number")] public int index { get; set; }
+    [JsonPropertyName("entity_number")]
+    public int index { get; set; }
+
     public string? name { get; set; }
     public string? quality { get; set; }
     public BlueprintPosition position { get; set; } = new BlueprintPosition();
     public int direction { get; set; }
+
+    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
     public string? recipe { get; set; }
+    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
     public string? recipe_quality { get; set; }
-    [JsonPropertyName("control_behavior")] public BlueprintControlBehavior? controlBehavior { get; set; }
+
+    [JsonPropertyName("control_behavior")]
+    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+    public BlueprintControlBehavior? controlBehavior { get; set; }
     public BlueprintConnection? connections { get; set; }
-    [JsonPropertyName("request_filters")] public List<BlueprintRequestFilter> requestFilters { get; } = [];
+
+    [JsonPropertyName("request_filters")]
+    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+    public BlueprintRequestFilterSections? requestFilters { get; set; }
     public List<BlueprintItem> items { get; } = [];
+    [JsonPropertyName("burner_fuel_inventory")]
+    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+    public BlueprintRequestFilterSection? burnerFuelInventory { get; set; }
+
+    public void SetFuel(string name, string? quality = null) {
+        BlueprintRequestFilter fuelFilter = new() {
+            index = 1,
+            comparator = "=",
+            name = name,
+            quality = quality,
+            count = 1
+        };
+
+        burnerFuelInventory = new BlueprintRequestFilterSection();
+        burnerFuelInventory.filters.Add(fuelFilter);
+    }
 
     public void Connect(BlueprintEntity other, bool red = true, bool secondPort = false, bool targetSecond = false) {
         ConnectSingle(other, red, secondPort, targetSecond);
@@ -130,6 +157,18 @@ private void ConnectSingle(BlueprintEntity other, bool red = true, bool secondPo
     }
 }
 
+[Serializable]
+public class BlueprintRequestFilterSections {
+    public List<BlueprintRequestFilterSection> sections { get; } = [];
+}
+
+[Serializable]
+public class BlueprintRequestFilterSection {
+    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+    public int? index { get; set; }
+    public List<BlueprintRequestFilter> filters { get; } = [];
+}
+
 [Serializable]
 public class BlueprintRequestFilter {
     public string? name { get; set; }
@@ -137,6 +176,8 @@ public class BlueprintRequestFilter {
     public string? comparator { get; set; }
     public int index { get; set; }
     public int count { get; set; }
+    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+    public int? max_count { get; set; }
 }
 
 [Serializable]
diff --git a/Yafc.Model/Blueprints/BlueprintUtilities.cs b/Yafc.Model/Blueprints/BlueprintUtilities.cs
index 054084bd..b6569257 100644
--- a/Yafc.Model/Blueprints/BlueprintUtilities.cs
+++ b/Yafc.Model/Blueprints/BlueprintUtilities.cs
@@ -1,5 +1,7 @@
 ﻿using System;
 using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
 using SDL2;
 using Yafc.Model;
 
@@ -63,10 +65,18 @@ public static string ExportRequesterChests(string name, IReadOnlyList<(IObjectWi
             BlueprintEntity entity = new BlueprintEntity { index = i + 1, position = { x = (i * chest.size) + offset, y = 0 }, name = chest.name };
             blueprint.blueprint.entities.Add(entity);
 
+            var section = new BlueprintRequestFilterSection {
+                index = 1,
+            };
+
+            entity.requestFilters = new BlueprintRequestFilterSections();
+            entity.requestFilters.sections.Add(section);
+
+
             for (int j = 0; j < chest.logisticSlotsCount; j++) {
                 var (item, amount) = goods[index++];
-                BlueprintRequestFilter filter = new BlueprintRequestFilter { index = j + 1, count = amount, name = item.target.name, quality = item.quality.name, comparator = "=" };
-                entity.requestFilters.Add(filter);
+                BlueprintRequestFilter filter = new BlueprintRequestFilter { index = j + 1, count = amount, max_count = amount, name = item.target.name, quality = item.quality.name, comparator = "=" };
+                section.filters.Add(filter);
 
                 if (index >= goods.Count) {
                     break;
@@ -76,4 +86,112 @@ public static string ExportRequesterChests(string name, IReadOnlyList<(IObjectWi
 
         return ExportBlueprint(blueprint, copyToClipboard);
     }
+
+    private class PlacedEntity {
+        public RecipeRow Recipe { get; }
+        public int X { get; } // Top-left X coordinate
+        public int Y { get; } // Top-left Y coordinate
+
+        public PlacedEntity(RecipeRow recipe, int x, int y) {
+            Recipe = recipe;
+            X = x;
+            Y = y;
+        }
+    }
+
+    private class LayoutResult {
+        public int TotalWidth { get; set; }
+        public int TotalHeight { get; set; }
+        public List<PlacedEntity> Placements { get; set; } = new();
+    }
+
+    public static string ExportRecipiesAsBlueprint(string name, IEnumerable<RecipeRow> recipies, bool includeFuel, bool copyToClipboard = true) {
+        // Sort buildings largest to smallest (by height then width) for better packing
+        var entities = recipies
+            .Where(r => r.entity is not null)
+            .OrderByDescending(r => r.entity!.target.size)
+            .ToList();
+
+        // Estimate total area and try square-ish dimensions
+        int totalArea = entities.Sum(r => (r.entity!.target.width + 1) * (r.entity!.target.height + 1));
+        int sideLengthEstimate = (int)Math.Ceiling(Math.Sqrt(totalArea));
+
+        // Try increasing row width until it fits all buildings efficiently
+        int bestWidth = int.MaxValue;
+        int bestHeight = int.MaxValue;
+        LayoutResult? bestResult = null;
+
+        for (int tryWidth = sideLengthEstimate; tryWidth < sideLengthEstimate * 2; tryWidth++) {
+            int x = 0, y = 0, rowHeight = 0;
+            List<PlacedEntity> placed = new();
+
+            foreach (var b in entities) {
+                if (x + b.entity!.target.width > tryWidth) {
+                    // Move to next row
+                    y += rowHeight + 1; // Add 1 for gap
+                    x = 0;
+                    rowHeight = 0;
+                }
+
+                placed.Add(new PlacedEntity(b, x, y));
+                x += b.entity!.target.width + 1; // Add gap
+                rowHeight = Math.Max(rowHeight, b.entity!.target.height);
+            }
+
+            int totalHeight = y + rowHeight;
+            int totalWidth = tryWidth;
+
+            // Evaluate how square-like it is
+            if (Math.Max(totalWidth, totalHeight) < Math.Max(bestWidth, bestHeight)) {
+                bestResult = new LayoutResult {
+                    TotalWidth = totalWidth,
+                    TotalHeight = totalHeight,
+                    Placements = placed
+                };
+                bestWidth = totalWidth;
+                bestHeight = totalHeight;
+            }
+        }
+
+        BlueprintString blueprint = new BlueprintString(name);
+        int buildingIndex = 0;
+
+        foreach (var placement in bestResult!.Placements) {
+            var recipe = placement.Recipe;
+
+            BlueprintEntity entity = new BlueprintEntity {
+                index = buildingIndex,
+                position = { x = placement.X, y = placement.Y },
+                name = recipe.entity!.target.name,
+            };
+
+            if (!recipe.recipe.Is<Mechanics>()) {
+                entity.recipe = recipe.recipe.target.name;
+                entity.recipe_quality = recipe.recipe.quality.name;
+            }
+
+            if (includeFuel && recipe.fuel is not null && !recipe.fuel.target.isPower) {
+                entity.SetFuel(recipe.fuel.target.name, recipe.fuel.quality.name);
+            }
+
+            var modules = recipe.usedModules.modules;
+
+            if (modules != null) {
+                int idx = 0;
+                foreach (var (module, count, beacon) in modules) {
+                    if (!beacon) {
+                        BlueprintItem item = new BlueprintItem { id = { name = module.target.name, quality = module.quality.name } };
+                        item.items.inInventory.AddRange(Enumerable.Range(idx, count).Select(i => new BlueprintInventoryItem { stack = i }));
+                        entity.items.Add(item);
+                        idx += count;
+                    }
+                }
+            }
+
+            blueprint.blueprint.entities.Add(entity);
+            buildingIndex += 1;
+        }
+
+        return ExportBlueprint(blueprint, copyToClipboard);
+    }
 }
diff --git a/Yafc.Model/Data/DataClasses.cs b/Yafc.Model/Data/DataClasses.cs
index 09b1ca38..d8261b66 100644
--- a/Yafc.Model/Data/DataClasses.cs
+++ b/Yafc.Model/Data/DataClasses.cs
@@ -534,6 +534,8 @@ public float Power(Quality quality)
     internal List<Entity> sourceEntities { get; set; } = null!;
     internal string? autoplaceControl { get; set; }
     public float heatingPower { get; internal set; }
+    public int width { get; internal set; }
+    public int height { get; internal set; }
     public int size { get; internal set; }
     internal override FactorioObjectSortOrder sortingOrder => FactorioObjectSortOrder.Entities;
     public override string type => "Entity";
diff --git a/Yafc.Parser/Data/FactorioDataDeserializer_Entity.cs b/Yafc.Parser/Data/FactorioDataDeserializer_Entity.cs
index 5b789665..2f9d7fa3 100644
--- a/Yafc.Parser/Data/FactorioDataDeserializer_Entity.cs
+++ b/Yafc.Parser/Data/FactorioDataDeserializer_Entity.cs
@@ -117,7 +117,7 @@ private void ReadEnergySource(LuaTable? energySource, Entity entity, float defau
         }
     }
 
-    private static int GetSize(LuaTable box) {
+    private static (int Width, int Height) GetDimensions(LuaTable box) {
         _ = box.Get(1, out LuaTable? topLeft);
         _ = box.Get(2, out LuaTable? bottomRight);
         _ = topLeft.Get(1, out float x0);
@@ -125,7 +125,7 @@ private static int GetSize(LuaTable box) {
         _ = bottomRight.Get(1, out float x1);
         _ = bottomRight.Get(2, out float y1);
 
-        return Math.Max(MathUtils.Round(x1 - x0), MathUtils.Round(y1 - y0));
+        return (MathUtils.Round(x1 - x0), MathUtils.Round(y1 - y0));
     }
 
     private static void ParseModules(LuaTable table, EntityWithModules entity, AllowedEffects def) {
@@ -584,7 +584,9 @@ void parseEffect(LuaTable effect) {
             }
         }
 
-        entity.size = table.Get("selection_box", out LuaTable? box) ? GetSize(box) : 3;
+        (entity.width, entity.height) = table.Get("selection_box", out LuaTable? box) ? GetDimensions(box) : (3, 3);
+
+        entity.size = Math.Max(entity.width, entity.height);
 
         _ = table.Get("energy_source", out LuaTable? energySource);
 
diff --git a/Yafc/Data/locale/en/yafc.cfg b/Yafc/Data/locale/en/yafc.cfg
index 27df658a..3207e03d 100644
--- a/Yafc/Data/locale/en/yafc.cfg
+++ b/Yafc/Data/locale/en/yafc.cfg
@@ -345,6 +345,7 @@ prefs-spoiling-rate=Spoiling rate:
 prefs-show-inaccessible-milestone-overlays=Show milestone overlays on inaccessible objects
 prefs-dark-mode=Dark mode
 prefs-autosave=Enable autosave (Saves when the window loses focus)
+prefs-export-entities-with-fuel-filter-set=Export all entities with fuel filter set
 prefs-goods-unit-simple=Simple Amount__1__
 prefs-goods-unit-custom=Custom: 1 unit equals
 prefs-goods-unit-from-belt=Set from belt
@@ -728,6 +729,7 @@ production-table-header-modules=Modules
 production-table-add-raw-recipe=Add raw recipe
 production-table-add-technology=Add technology
 production-table-export-to-blueprint=Export inputs and outputs to blueprint with constant combinators:
+production-table-export-entities-to-blueprint=Export entities to blueprint
 export-blueprint-amount-per=Amount per:
 export-blueprint-amount-per-second=second
 export-blueprint-amount-per-minute=minute
diff --git a/Yafc/Utils/Preferences.cs b/Yafc/Utils/Preferences.cs
index 3bccf718..319142b2 100644
--- a/Yafc/Utils/Preferences.cs
+++ b/Yafc/Utils/Preferences.cs
@@ -43,6 +43,7 @@ public void Save() {
     }
     public ProjectDefinition[] recentProjects { get; set; } = [];
     public bool darkMode { get; set; }
+    public bool exportEntitiesWithFuelFilter { get; set; } = true;
     public string language {
         get => _language;
         set {
diff --git a/Yafc/Windows/PreferencesScreen.cs b/Yafc/Windows/PreferencesScreen.cs
index db35ffdd..23142f32 100644
--- a/Yafc/Windows/PreferencesScreen.cs
+++ b/Yafc/Windows/PreferencesScreen.cs
@@ -209,6 +209,10 @@ private static void DrawGeneral(ImGui gui) {
         if (gui.BuildCheckBox(LSs.PrefsAutosave, Preferences.Instance.autosaveEnabled, out newValue)) {
             Preferences.Instance.autosaveEnabled = newValue;
         }
+
+        if (gui.BuildCheckBox(LSs.PrefsExportEntitiesWithFuelFilterSet, Preferences.Instance.exportEntitiesWithFuelFilter, out newValue)) {
+            Preferences.Instance.exportEntitiesWithFuelFilter = newValue;
+        }
     }
 
     protected override void ReturnPressed() => Close();
diff --git a/Yafc/Workspace/ProductionTable/ProductionTableView.cs b/Yafc/Workspace/ProductionTable/ProductionTableView.cs
index 64785b67..0badd512 100644
--- a/Yafc/Workspace/ProductionTable/ProductionTableView.cs
+++ b/Yafc/Workspace/ProductionTable/ProductionTableView.cs
@@ -560,6 +560,11 @@ private static void ShowEntityDropdown(ImGui gui, RecipeRow recipe) {
                                     }
                                 }
                             }
+
+                            if (Preferences.Instance.exportEntitiesWithFuelFilter && recipe.fuel is not null && !recipe.fuel.target.isPower) {
+                                entity.SetFuel(recipe.fuel.target.name, recipe.fuel.quality.name);
+                            }
+
                             BlueprintString bp = new BlueprintString(recipe.recipe.target.locName) { blueprint = { entities = { entity } } };
                             _ = SDL.SDL_SetClipboardText(bp.ToBpString());
                         }
@@ -611,6 +616,15 @@ public override void BuildMenu(ImGui gui) {
             if (gui.BuildButton(LSs.ShoppingList) && gui.CloseDropdown()) {
                 view.BuildShoppingList(null);
             }
+
+            if (gui.BuildButton(LSs.ProductionTableExportEntitiesToBlueprint) && gui.CloseDropdown()) {
+                bool includeFuel = Preferences.Instance.exportEntitiesWithFuelFilter;
+                var uniqueEntites = view
+                    .GetRecipesRecursive()
+                    .DistinctBy(row => (row.entity, row.recipe, includeFuel ? row.fuel : null));
+
+                _ = BlueprintUtilities.ExportRecipiesAsBlueprint(view.projectPage!.name, uniqueEntites, includeFuel);
+            }
         }
     }
 
diff --git a/changelog.txt b/changelog.txt
index c6244b1e..b9d88457 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -18,7 +18,12 @@
 Version: 
 Date: 
     Features:
+        - Add support for exporting all building entities to one blueprint.
+        - Support for new burner fuel inventory. Exported entities will now have burner fuel inventory slot set as filter (Configurable in preferences).
     Fixes:
+        - Fix issue when trying to export blueprint with modules (Key "count" was not found in property tree...)
+    Internal Changes:
+        - Upgrade Blueprint classes to support new logistic filter sections.
 ----------------------------------------------------------------------------------------------------------------------
 Version: 2.12.0
 Date: May 12th 2025


Reviews:
user: login: veger
body: Welcome to YAFC-CE, thank you for your contribution!

I am no blueprint expert (no idea how they are formatted/work), but the rest looks fine to me.
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-13T19:15:25Z
user: login: danbopes
state: COMMENTED
author_association: NONE
submitted_at: 2025-05-13T19:16:31Z
user: login: veger
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-13T19:27:57Z
user: login: DaleStan
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-14T05:59:43Z
user: login: shpaass
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-14T06:09:48Z
user: login: DaleStan
body: The content of the changes looks good, but it looks to me like you changed several files from exclusively CRLF line endings to a mix of CRLF and LF line endings.

I suspect this is due to your setting for `core.autocrlf`; I have it set to `true`
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-14T07:29:25Z
user: login: veger
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-14T07:39:48Z
user: login: shpaass
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-14T09:52:44Z
user: login: shpaass
body: Thank you for the feature, and welcome to the team!
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-05-14T10:42:37Z

Review comments:
diff_hunk: @@ -98,17 +98,44 @@ public void Set(IObjectWithQuality<Goods> goods) {
 
 [Serializable]
 public class BlueprintEntity {
-    [JsonPropertyName("entity_number")] public int index { get; set; }
+    [JsonPropertyName("entity_number")]
+    public int index { get; set; }
+
     public string? name { get; set; }
     public string? quality { get; set; }
     public BlueprintPosition position { get; set; } = new BlueprintPosition();
     public int direction { get; set; }
+
+    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
     public string? recipe { get; set; }
+    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
     public string? recipe_quality { get; set; }
-    [JsonPropertyName("control_behavior")] public BlueprintControlBehavior? controlBehavior { get; set; }
+
+    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+    [JsonPropertyName("control_behavior")]
+    public BlueprintControlBehavior? controlBehavior { get; set; }
     public BlueprintConnection? connections { get; set; }
-    [JsonPropertyName("request_filters")] public List<BlueprintRequestFilter> requestFilters { get; } = [];
+
+    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
+    [JsonPropertyName("request_filters")]
+    public BlueprintRequestFilterSections? requestFilters { get; set; }
     public List<BlueprintItem> items { get; } = [];
+    [JsonPropertyName("burner_fuel_inventory")]
+    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
path: Yafc.Model/Blueprints/Blueprint.cs
user: login: veger
body: ```suggestion
    [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
    [JsonPropertyName("burner_fuel_inventory")]
```

Same order as the others (I know it is a nitpick...)
created_at: 2025-05-13T19:04:48Z
author_association: COLLABORATOR
diff_hunk: @@ -32,6 +32,16 @@ Date:
         - Update documentation for changing the selected Factorio-object language.
         - Make it much harder for the user to select a folder when YAFC is expecting a file.
 ----------------------------------------------------------------------------------------------------------------------
+Version: 2.11.2
+Date: May 13th 2025
+    Features:
+        - Add support for exporting all building entities to one blueprint.
+        - Support for new burner fuel inventory. Exported entities will now have burner fuel inventory slot set as filter (Configurable in preferences).
+    Fixes:
+        - Fix issue when trying to export blueprint with modules (Key "count" was not found in property tree...)
+    Internal changes:
+        - Upgrade Blueprint classes to support new logistic filter sections.
+----------------------------------------------------------------------------------------------------------------------
path: changelog.txt
user: login: veger
body: Please append to the existing section (just above), when YAFC gets released version and date will be filled in.
created_at: 2025-05-13T19:12:34Z
author_association: COLLABORATOR
diff_hunk: @@ -32,6 +32,16 @@ Date:
         - Update documentation for changing the selected Factorio-object language.
         - Make it much harder for the user to select a folder when YAFC is expecting a file.
 ----------------------------------------------------------------------------------------------------------------------
+Version: 2.11.2
+Date: May 13th 2025
+    Features:
+        - Add support for exporting all building entities to one blueprint.
+        - Support for new burner fuel inventory. Exported entities will now have burner fuel inventory slot set as filter (Configurable in preferences).
+    Fixes:
+        - Fix issue when trying to export blueprint with modules (Key "count" was not found in property tree...)
+    Internal changes:
+        - Upgrade Blueprint classes to support new logistic filter sections.
+----------------------------------------------------------------------------------------------------------------------
path: changelog.txt
user: login: danbopes
body: Will do, sorry should have read the header more clearly 
created_at: 2025-05-13T19:16:31Z
author_association: NONE
diff_hunk: @@ -32,6 +32,16 @@ Date:
         - Update documentation for changing the selected Factorio-object language.
         - Make it much harder for the user to select a folder when YAFC is expecting a file.
 ----------------------------------------------------------------------------------------------------------------------
+Version: 2.11.2
+Date: May 13th 2025
+    Features:
+        - Add support for exporting all building entities to one blueprint.
+        - Support for new burner fuel inventory. Exported entities will now have burner fuel inventory slot set as filter (Configurable in preferences).
+    Fixes:
+        - Fix issue when trying to export blueprint with modules (Key "count" was not found in property tree...)
+    Internal changes:
+        - Upgrade Blueprint classes to support new logistic filter sections.
+----------------------------------------------------------------------------------------------------------------------
path: changelog.txt
user: login: veger
body: No problem, thanks for adjusting :+1: 
created_at: 2025-05-13T19:27:56Z
author_association: COLLABORATOR
diff_hunk: @@ -32,6 +32,16 @@ Date:
         - Update documentation for changing the selected Factorio-object language.
         - Make it much harder for the user to select a folder when YAFC is expecting a file.
 ----------------------------------------------------------------------------------------------------------------------
+Version: 2.11.2
+Date: May 13th 2025
+    Features:
+        - Add support for exporting all building entities to one blueprint.
+        - Support for new burner fuel inventory. Exported entities will now have burner fuel inventory slot set as filter (Configurable in preferences).
+    Fixes:
+        - Fix issue when trying to export blueprint with modules (Key "count" was not found in property tree...)
+    Internal changes:
+        - Upgrade Blueprint classes to support new logistic filter sections.
+----------------------------------------------------------------------------------------------------------------------
path: changelog.txt
user: login: DaleStan
body: Unfortunately, you actually need to add the changes to a new section. The currently unlabeled first section is for 2.12.0.
created_at: 2025-05-14T05:59:43Z
author_association: COLLABORATOR
diff_hunk: @@ -32,6 +32,16 @@ Date:
         - Update documentation for changing the selected Factorio-object language.
         - Make it much harder for the user to select a folder when YAFC is expecting a file.
 ----------------------------------------------------------------------------------------------------------------------
+Version: 2.11.2
+Date: May 13th 2025
+    Features:
+        - Add support for exporting all building entities to one blueprint.
+        - Support for new burner fuel inventory. Exported entities will now have burner fuel inventory slot set as filter (Configurable in preferences).
+    Fixes:
+        - Fix issue when trying to export blueprint with modules (Key "count" was not found in property tree...)
+    Internal changes:
+        - Upgrade Blueprint classes to support new logistic filter sections.
+----------------------------------------------------------------------------------------------------------------------
path: changelog.txt
user: login: shpaass
body: In the master branch, I fixed the absent version in the changelog. Apologies for the mishap.
created_at: 2025-05-14T06:09:48Z
author_association: COLLABORATOR
diff_hunk: @@ -32,6 +32,16 @@ Date:
         - Update documentation for changing the selected Factorio-object language.
         - Make it much harder for the user to select a folder when YAFC is expecting a file.
 ----------------------------------------------------------------------------------------------------------------------
+Version: 2.11.2
+Date: May 13th 2025
+    Features:
+        - Add support for exporting all building entities to one blueprint.
+        - Support for new burner fuel inventory. Exported entities will now have burner fuel inventory slot set as filter (Configurable in preferences).
+    Fixes:
+        - Fix issue when trying to export blueprint with modules (Key "count" was not found in property tree...)
+    Internal changes:
+        - Upgrade Blueprint classes to support new logistic filter sections.
+----------------------------------------------------------------------------------------------------------------------
path: changelog.txt
user: login: veger
body: Oh... I only saw the new section on top, so I assume it was yet to be released... (I was wondering about its size and the recent release but didn't check if it was the same or not)

Sorry for the confusion :disappointed: 
created_at: 2025-05-14T07:39:48Z
author_association: COLLABORATOR
diff_hunk: @@ -18,7 +18,12 @@
 Version: 
 Date: 
     Features:
+        - Add support for exporting all building entities to one blueprint.
+        - Support for new burner fuel inventory. Exported entities will now have burner fuel inventory slot set as filter (Configurable in preferences).
     Fixes:
+        - Fix issue when trying to export blueprint with modules (Key "count" was not found in property tree...)
+	Internal Changes:
path: changelog.txt
user: login: shpaass
body: Nit: formatting
created_at: 2025-05-14T09:52:44Z
author_association: COLLABORATOR

PR comments:
user: login: danbopes
created_at: 2025-05-14T08:28:46Z
body: > The content of the changes looks good, but it looks to me like you changed several files from exclusively CRLF line endings to a mix of CRLF and LF line endings.
> 
> I suspect this is due to your setting for `core.autocrlf`; I have it set to `true`

I thought I had accounted for all of the line ending misshapes, I'll fix in a bit
author_association: NONE
user: login: shpaass
created_at: 2025-05-14T09:03:43Z
body: > Merge branch 'shpaass:master' into master

I advise to use rebasing in the future instead of merging. It results in a cleaner commit history. Or you can leave it as-is and I'll `git rebase -i` later.
author_association: COLLABORATOR
user: login: danbopes
created_at: 2025-05-14T09:11:33Z
body: > > Merge branch 'shpaass:master' into master
> 
> I advise to use rebasing in the future instead of merging. It results in a cleaner commit history. Or you can leave it as-is and I'll `git rebase -i` later.

In the future, I'll rebase. Just used the GitHub interface to sync the fork and it merged instead. Not used to syncing forks.
author_association: NONE
user: login: danbopes
created_at: 2025-05-14T09:35:45Z
body: Okay, pretty sure we got the formatting/whitespace issues resolved, and I fixed/rebased everything
author_association: NONE
user: login: shpaass
created_at: 2025-05-14T09:37:45Z
body: Alright, then we wait for @DaleStan review, then either me or you squashes the fixes into relevant commits.
author_association: COLLABORATOR
user: login: shpaass
created_at: 2025-05-14T09:39:30Z
body: Hmm, DaleStan said that the content is fine. So only squashes are left to be done. Please let me know if you want me to do it.
author_association: COLLABORATOR
user: login: shpaass
created_at: 2025-05-14T10:17:16Z
body: Squashed the fix and added a commit subject.
author_association: COLLABORATOR