- * Added if structure if formed and the machine is active.
- *
- * @param recipeLogic The recipe logic that provides the line
- */
- public Builder addCustomProgressLine(RecipeLogic recipeLogic) {
- if (!isStructureFormed || !isActive)
- return this;
- Component line = recipeLogic.getCustomProgressLine();
- if (line != null) {
- textList.add(line);
- }
- return this;
- }
-
- public Builder addRecipeFailReasonLine(RecipeLogic recipeLogic) {
- if (!isStructureFormed || !recipeLogic.isIdle())
- return this;
- var reasons = recipeLogic.getFailureReasons();
- if (!reasons.isEmpty()) {
- textList.add(Component.translatable("gtceu.recipe_logic.setup_fail").withStyle(ChatFormatting.RED));
- for (var reason : reasons) {
- textList.add(Component.literal(" - ").append(reason));
- }
- }
- return this;
- }
-
- public Builder addBatchModeLine(boolean batchEnabled, int batchAmount) {
- if (batchEnabled && batchAmount > 0) {
- Component runs = Component.literal(FormattingUtil.formatNumbers(batchAmount))
- .withStyle(ChatFormatting.DARK_PURPLE);
- String key = "gtceu.multiblock.batch_enabled";
- textList.add(Component.translatable(key, runs)
- .withStyle(ChatFormatting.GRAY));
- }
- return this;
- }
-
- public Builder addSubtickParallelsLine(int subtickParallels) {
- if (subtickParallels > 1) {
- Component runs = Component.literal(FormattingUtil.formatNumbers(subtickParallels))
- .withStyle(ChatFormatting.DARK_PURPLE);
- String key = "gtceu.multiblock.subtick_parallels";
- textList.add(Component.translatable(key, runs)
- .withStyle(ChatFormatting.GRAY));
- }
- return this;
- }
-
- public Builder addTotalRunsLine(int totalRuns) {
- if (totalRuns > 1) {
- Component runs = Component.literal(FormattingUtil.formatNumbers(totalRuns))
- .withStyle(ChatFormatting.DARK_PURPLE);
- String key = "gtceu.multiblock.total_runs";
- textList.add(Component.translatable(key, runs)
- .withStyle(ChatFormatting.GRAY));
- }
- return this;
- }
-
- public Builder addOutputLines(GTRecipe recipe) {
- if (!isStructureFormed || !isActive)
- return this;
- if (recipe != null) {
- int recipeTier = RecipeHelper.getPreOCRecipeEuTier(recipe);
- int chanceTier = recipeTier + recipe.ocLevel;
- var function = recipe.getType().getChanceFunction();
- double maxDurationSec = (double) recipe.duration / 20.0;
- var itemOutputs = recipe.getOutputContents(ItemRecipeCapability.CAP);
- var fluidOutputs = recipe.getOutputContents(FluidRecipeCapability.CAP);
- int runs = recipe.getTotalRuns();
-
- for (var item : itemOutputs) {
- boolean rounded = false;
- ItemStack stack;
- // number of items output by a non-ranged ingredient
- int count = 0;
- // number of items output, but stored as a double. Used for accurate items/second display.
- double countD = 1;
- // number of items output which is actually displayed. Can be either a number, or a range.
- Component displaycount;
- if (item.content() instanceof IntProviderIngredient provider) {
- rounded = true;
- stack = provider.getMaxSizeStack();
- displaycount = Component.translatable("gtceu.gui.content.range",
- provider.getCountProvider().getMinValue(),
- provider.getCountProvider().getMaxValue());
- if (item.chance() < item.maxChance()) {
- countD = countD * runs * function.getBoostedChance(item, recipeTier, chanceTier) /
- item.maxChance();
- }
- countD = countD * provider.getMidRoll();
- } else {
- var stacks = ItemRecipeCapability.CAP.of(item.content()).getItems();
- if (stacks.length == 0) continue;
- stack = stacks[0];
- count = stack.getCount();
- countD *= count;
- if (item.chance() < item.maxChance()) {
- rounded = true;
- countD = countD * runs * function.getBoostedChance(item, recipeTier, chanceTier) /
- item.maxChance();
- }
- count = Math.max(1, (int) Math.round(countD));
- displaycount = Component.literal(String.valueOf(count));
- }
- if (countD < maxDurationSec) {
- String key = "gtceu.multiblock.output_line." + (rounded ? "2" : "0");
- textList.add(Component.translatable(key, stack.getHoverName(), displaycount,
- FormattingUtil.formatNumber2Places(maxDurationSec / countD)));
- } else {
- String key = "gtceu.multiblock.output_line." + (rounded ? "3" : "1");
- textList.add(Component.translatable(key, stack.getHoverName(), displaycount,
- FormattingUtil.formatNumber2Places(countD / maxDurationSec)));
- }
- }
- for (var fluid : fluidOutputs) {
- boolean rounded = false;
- FluidStack stack;
- // amount of fluid output by a non-ranged ingredient
- int amount = 0;
- // amount of fluid output, but stored as a double. Used for accurate fluid/second display.
- double amountD = 1;
- // amount of fluid output which is actually displayed. Can be either a number, or a range.
- Component displaycount;
- if (fluid.content() instanceof IntProviderFluidIngredient provider) {
- rounded = true;
- stack = provider.getMaxSizeStack();
- displaycount = Component.translatable("gtceu.gui.content.range",
- provider.getCountProvider().getMinValue(),
- provider.getCountProvider().getMaxValue());
- if (fluid.chance() < fluid.maxChance()) {
- amountD = amountD * runs * function.getBoostedChance(fluid, recipeTier, chanceTier) /
- fluid.maxChance();
- }
- amountD = amountD * provider.getMidRoll();
- } else {
- var stacks = FluidRecipeCapability.CAP.of(fluid.content()).getStacks();
- if (stacks.length == 0) continue;
- stack = stacks[0];
- amount = stack.getAmount();
- amountD *= amount;
- if (fluid.chance() < fluid.maxChance()) {
- rounded = true;
- amountD = amountD * runs * function.getBoostedChance(fluid, recipeTier, chanceTier) /
- fluid.maxChance();
- }
- amount = Math.max(1, (int) Math.round(amountD));
- displaycount = Component.literal(String.valueOf(amount));
- }
- if (amountD < maxDurationSec) {
- String key = "gtceu.multiblock.output_line." + (rounded ? "2" : "0");
- textList.add(Component.translatable(key, stack.getDisplayName(), displaycount,
- FormattingUtil.formatNumber2Places(maxDurationSec / amountD)));
- } else {
- String key = "gtceu.multiblock.output_line." + (rounded ? "3" : "1");
- textList.add(Component.translatable(key, stack.getDisplayName(), displaycount,
- FormattingUtil.formatNumber2Places(amountD / maxDurationSec)));
- }
- }
- }
- return this;
- }
-
- /**
- * Adds a line indicating the current mode of the multi
- */
- public Builder addMachineModeLine(GTRecipeType recipeType, boolean hasMultipleModes) {
- if (!isStructureFormed || !hasMultipleModes)
- return this;
- textList.add(Component
- .translatable("gtceu.gui.machinemode",
- Component.translatable(recipeType.registryName.toLanguageKey()))
- .withStyle(ChatFormatting.AQUA));
- return this;
- }
-
- public Builder addParallelsLine(int numParallels) {
- return addParallelsLine(numParallels, false);
- }
-
- /**
- * Adds a line indicating how many parallels this multi can potentially perform.
- *
- * Added if structure is formed and the number of parallels is greater than one.
- */
- public Builder addParallelsLine(int numParallels, boolean exact) {
- if (!isStructureFormed)
- return this;
- if (numParallels > 1) {
- Component parallels = Component.literal(FormattingUtil.formatNumbers(numParallels))
- .withStyle(ChatFormatting.DARK_PURPLE);
- String key = "gtceu.multiblock.parallel";
- if (exact) key += ".exact";
- textList.add(Component.translatable(key, parallels)
- .withStyle(ChatFormatting.GRAY));
- }
- return this;
- }
-
- /**
- * Adds a warning line when the machine is low on power.
- *
- * Added if the structure is formed and if the passed parameter is true.
- */
- public Builder addLowPowerLine(boolean isLowPower) {
- if (!isStructureFormed)
- return this;
- if (isLowPower) {
- textList.add(
- Component.translatable("gtceu.multiblock.not_enough_energy").withStyle(ChatFormatting.YELLOW));
- }
- return this;
- }
-
- /**
- * Adds a warning line when the machine is low on computation.
- *
- * Added if the structure is formed and if the passed parameter is true.
- */
- public Builder addLowComputationLine(boolean isLowComputation) {
- if (!isStructureFormed)
- return this;
- if (isLowComputation) {
- textList.add(Component.translatable("gtceu.multiblock.computation.not_enough_computation")
- .withStyle(ChatFormatting.YELLOW));
- }
- return this;
- }
-
- /**
- * Adds a warning line when the machine's dynamo tier is too low for current conditions.
- *
- * Added if the structure is formed and if the passed parameter is true.
- */
- public Builder addLowDynamoTierLine(boolean isTooLow) {
- if (!isStructureFormed)
- return this;
- if (isTooLow) {
- textList.add(Component.translatable("gtceu.multiblock.not_enough_energy_output")
- .withStyle(ChatFormatting.YELLOW));
- }
- return this;
- }
-
- /**
- * Adds warning line(s) when the machine has maintenance problems.
- *
- * Added if there are any maintenance problems, one line per problem as well as a header.
- * Will check the config setting for if maintenance is enabled automatically.
- */
- public Builder addMaintenanceProblemLines(byte maintenanceProblems) {
- if (!isStructureFormed || !ConfigHolder.INSTANCE.machines.enableMaintenance)
- return this;
- if (maintenanceProblems <= 0b111111 && maintenanceProblems > 0) {
- addMaintenanceProblemHeader();
-
- // Wrench
- if ((maintenanceProblems & 1) == 0) {
- textList.add(Component.translatable("gtceu.multiblock.universal.problem.wrench")
- .withStyle(ChatFormatting.GRAY));
- }
-
- // Screwdriver
- if (((maintenanceProblems >> 1) & 1) == 0) {
- textList.add(Component.translatable("gtceu.multiblock.universal.problem.screwdriver")
- .withStyle(ChatFormatting.GRAY));
- }
-
- // Soft Mallet
- if (((maintenanceProblems >> 2) & 1) == 0) {
- textList.add(Component.translatable("gtceu.multiblock.universal.problem.soft_mallet")
- .withStyle(ChatFormatting.GRAY));
- }
-
- // Hammer
- if (((maintenanceProblems >> 3) & 1) == 0) {
- textList.add(Component.translatable("gtceu.multiblock.universal.problem.hard_hammer")
- .withStyle(ChatFormatting.GRAY));
- }
-
- // Wire Cutters
- if (((maintenanceProblems >> 4) & 1) == 0) {
- textList.add(Component.translatable("gtceu.multiblock.universal.problem.wire_cutter")
- .withStyle(ChatFormatting.GRAY));
- }
-
- // Crowbar
- if (((maintenanceProblems >> 5) & 1) == 0) {
- textList.add(Component.translatable("gtceu.multiblock.universal.problem.crowbar")
- .withStyle(ChatFormatting.GRAY));
- }
- }
- return this;
- }
-
- private void addMaintenanceProblemHeader() {
- textList.add(
- Component.translatable("gtceu.multiblock.universal.has_problems").withStyle(ChatFormatting.YELLOW));
- }
-
- /**
- * Adds two error lines when the machine's muffler hatch is obstructed.
- *
- * Added if the structure is formed and if the passed parameter is true.
- */
- public Builder addMufflerObstructedLine(boolean isObstructed) {
- if (!isStructureFormed)
- return this;
- if (isObstructed) {
- textList.add(Component.translatable("gtceu.multiblock.universal.muffler_obstructed")
- .withStyle(ChatFormatting.RED));
- textList.add(Component.translatable("gtceu.multiblock.universal.muffler_obstructed.tooltip")
- .withStyle(ChatFormatting.GRAY));
- }
- return this;
- }
-
- /**
- * Adds a fuel consumption line showing the fuel name and the number of ticks per recipe run.
- *
- * Added if structure is formed, the machine is active, and the passed fuelName parameter is not null.
- */
- public Builder addFuelNeededLine(String fuelName, int previousRecipeDuration) {
- if (!isStructureFormed || !isActive || fuelName == null)
- return this;
- Component fuelNeeded = Component.literal(fuelName).withStyle(ChatFormatting.RED);
- Component numTicks = Component.literal(FormattingUtil.formatNumbers(previousRecipeDuration))
- .withStyle(ChatFormatting.AQUA);
- textList.add(Component.translatable(
- "gtceu.multiblock.turbine.fuel_needed",
- fuelNeeded, numTicks).withStyle(ChatFormatting.GRAY));
- return this;
- }
-
- /**
- * Insert an empty line into the text list.
- */
- public Builder addEmptyLine() {
- textList.add(EMPTY_COMPONENT);
- return this;
- }
-
- /**
- * Add custom text dynamically, allowing for custom application logic.
- */
- public Builder addCustom(Consumer> customConsumer) {
- customConsumer.accept(textList);
- return this;
- }
-
- /*
- * Add a line specifying the current EU/t
- */
- public Builder addCurrentEnergyProductionLine(long euOutput) {
- textList.add(Component.translatable("gtceu.multiblock.turbine.energy_per_tick_maxed",
- FormattingUtil.formatNumbers(euOutput)).withStyle(ChatFormatting.GRAY));
- return this;
- }
- }
-}