From 410de57b2e50cf768c87c69fc2c104225bcd1589 Mon Sep 17 00:00:00 2001 From: Dale McCoy <21223975+DaleStan@users.noreply.github.com> Date: Wed, 13 Nov 2024 09:38:30 -0500 Subject: [PATCH] feat: Add the send-to-orbit trigger I left out of #350. --- Yafc.Model/Data/DataClasses.cs | 8 +++++- Yafc.Parser/Data/FactorioDataDeserializer.cs | 26 +++++++++++++------ ...rioDataDeserializer_RecipeAndTechnology.cs | 11 ++++++++ Yafc/Widgets/ObjectTooltip.cs | 7 +++++ 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/Yafc.Model/Data/DataClasses.cs b/Yafc.Model/Data/DataClasses.cs index e0f1e180..d98caf00 100644 --- a/Yafc.Model/Data/DataClasses.cs +++ b/Yafc.Model/Data/DataClasses.cs @@ -95,9 +95,11 @@ public enum RecipeFlags { HasResearchTriggerBuildEntity = 1 << 7, /// Set when the technology has a research trigger to launch a space platform starter pack HasResearchTriggerCreateSpacePlatform = 1 << 8, + /// Set when the technology has a research trigger to launch an arbitrary item. + HasResearchTriggerSendToOrbit = 1 << 9, HasResearchTriggerMask = HasResearchTriggerCraft | HasResearchTriggerCaptureEntity | HasResearchTriggerMineEntity | HasResearchTriggerBuildEntity - | HasResearchTriggerCreateSpacePlatform, + | HasResearchTriggerCreateSpacePlatform | HasResearchTriggerSendToOrbit, } public abstract class RecipeOrTechnology : FactorioObject { @@ -773,6 +775,7 @@ public class Technology : RecipeOrTechnology { // Technology is very similar to /// /// Lazy-loaded so the database can load and correctly type (eg EntityCrafter, EntitySpawner, etc.) the entities without having to do another pass. public IReadOnlyList triggerEntities => getTriggerEntities.Value; + public Item? triggerItem { get; internal set; } /// /// Sets the value used to construct . @@ -795,6 +798,9 @@ public override void GetDependencies(IDependencyCollector collector, List i.factorioType == "space-platform-starter-pack"); collector.Add([.. items.Select(i => Database.objectsByTypeName["Mechanics.launch." + i.name])], DependencyList.Flags.Source); } + if (flags.HasFlag(RecipeFlags.HasResearchTriggerSendToOrbit)) { + collector.Add([Database.objectsByTypeName["Mechanics.launch." + triggerItem]], DependencyList.Flags.Source); + } if (hidden && !enabled) { collector.Add(Array.Empty(), DependencyList.Flags.Hidden); diff --git a/Yafc.Parser/Data/FactorioDataDeserializer.cs b/Yafc.Parser/Data/FactorioDataDeserializer.cs index 23a8fe3b..e7934c93 100644 --- a/Yafc.Parser/Data/FactorioDataDeserializer.cs +++ b/Yafc.Parser/Data/FactorioDataDeserializer.cs @@ -437,14 +437,7 @@ void readTrigger(LuaTable table) { launchProducts = []; } - var recipe = CreateSpecialRecipe(item, SpecialNames.RocketLaunch, "launched"); - recipe.ingredients = - [ - new Ingredient(item, item.stackSize), - new Ingredient(rocketLaunch, 1) - ]; - recipe.products = launchProducts; - recipe.time = 0f; // TODO what to put here? + EnsureLaunchRecipe(item, launchProducts); } if (GetRef(table, "spoil_result", out Item? spoiled)) { @@ -485,6 +478,23 @@ void readEffect(LuaTable effect) { } } + /// + /// Creates, or confirms the existence of, a recipe for launching a particular item. + /// + /// The to be launched. + /// The result of launching , if known. Otherwise , to preserve + /// the existing launch products of a preexisting recipe, or set no products for a new recipe. + private void EnsureLaunchRecipe(Item item, Product[]? launchProducts) { + Recipe recipe = CreateSpecialRecipe(item, SpecialNames.RocketLaunch, "launched"); + recipe.ingredients = + [ + new Ingredient(item, item.stackSize), + new Ingredient(rocketLaunch, 1), + ]; + recipe.products = launchProducts ?? recipe.products ?? []; + recipe.time = 0f; // TODO what to put here? + } + private Fluid SplitFluid(Fluid basic, int temperature) { logger.Information("Splitting fluid {FluidName} at {Temperature}", basic.name, temperature); basic.variants ??= [basic]; diff --git a/Yafc.Parser/Data/FactorioDataDeserializer_RecipeAndTechnology.cs b/Yafc.Parser/Data/FactorioDataDeserializer_RecipeAndTechnology.cs index d327cab3..481d958b 100644 --- a/Yafc.Parser/Data/FactorioDataDeserializer_RecipeAndTechnology.cs +++ b/Yafc.Parser/Data/FactorioDataDeserializer_RecipeAndTechnology.cs @@ -325,6 +325,17 @@ private void LoadResearchTrigger(LuaTable researchTriggerTable, ref Technology t case "create-space-platform": technology.flags = RecipeFlags.HasResearchTriggerCreateSpacePlatform; break; + case "send-item-to-orbit": + if (!researchTriggerTable.Get("item", out string? itemName)) { + errorCollector.Error($"Research trigger {type} of {technology.typeDotName} does not have an item field", ErrorSeverity.MinorDataLoss); + break; + } + Item item = GetObject(itemName); + technology.triggerItem = item; + technology.flags |= RecipeFlags.HasResearchTriggerSendToOrbit; + // Create a launch recipe for items without a `rocket_launch_products`, without altering existing launch recipes. + EnsureLaunchRecipe(item, null); + break; default: errorCollector.Error($"Research trigger of {technology.typeDotName} has an unsupported type {type}", ErrorSeverity.MinorDataLoss); break; diff --git a/Yafc/Widgets/ObjectTooltip.cs b/Yafc/Widgets/ObjectTooltip.cs index d5e61870..f85ba6f1 100644 --- a/Yafc/Widgets/ObjectTooltip.cs +++ b/Yafc/Widgets/ObjectTooltip.cs @@ -529,6 +529,7 @@ private static void BuildTechnology(Technology technology, ImGui gui) { bool isResearchTriggerMine = technology.flags.HasFlag(RecipeFlags.HasResearchTriggerMineEntity); bool isResearchTriggerBuild = technology.flags.HasFlag(RecipeFlags.HasResearchTriggerBuildEntity); bool isResearchTriggerPlatform = technology.flags.HasFlag(RecipeFlags.HasResearchTriggerCreateSpacePlatform); + bool isResearchTriggerLaunch = technology.flags.HasFlag(RecipeFlags.HasResearchTriggerSendToOrbit); if (!technology.flags.HasFlagAny(RecipeFlags.HasResearchTriggerMask)) { BuildRecipe(technology, gui); @@ -580,6 +581,12 @@ private static void BuildTechnology(Technology technology, ImGui gui) { BuildIconRow(gui, items, 2); } } + else if (isResearchTriggerLaunch) { + BuildSubHeader(gui, "Launch this item"); + using (gui.EnterGroup(contentPadding)) { + gui.BuildFactorioObjectButtonWithText(technology.triggerItem); + } + } if (technology.unlockRecipes.Count > 0) { BuildSubHeader(gui, "Unlocks recipes");