Merge remote-tracking branch 'origin/mc1.20.1/feature-dev' into mc1.21.1/dev

This commit is contained in:
simibubi 2025-01-30 13:35:09 +01:00
commit dd5693d51d
26 changed files with 636 additions and 439 deletions

View file

@ -1,9 +1,11 @@
------------------------------------------------------
Create 6.0.0
------------------------------------------------------
_Now using Flywheel 1.0_
Additions
#### Additions
- Chain conveyor
- Item hatch
- Packager and Re-packager
@ -26,8 +28,8 @@ Additions
- Industrial iron window
- Weathered iron block and windows
#### Art Changes
Art
- Palette and model updates to all copper-based components
- Rope and hose pulley motion now uses a scrolling texture
- Increased vertical size of train and contraption controls to a full block
@ -38,8 +40,8 @@ Art
- Updates to various UI screens and components
- Bars and window item models are now consistent with vanilla
#### Gameplay Changes
Gameplay
- Redstone links are now andesite tier
- All links now use a new ingredient item, the transmitter
- New advancement chain for high logistics components
@ -50,21 +52,25 @@ Gameplay
- Added train schedule instructions for delivering or retrieving packages
- Basins no longer limit to 16 items per slot
- Mechanical crafters waste less time on empty animation frames
- In common cobblegen scenarios, stationary drills now skip breaking blocks and just insert the result items into open inventories directly below
- In common cobblegen scenarios, stationary drills now skip breaking blocks and just insert the result items into open
inventories directly below
- Held clipboards can now copy entries from other in-world clipboards
- Metal ladders no longer require a wall if another ladder block is above them
- Bells assembled to elevator contraptions now activate when arriving at a floor
- Sliding doors placed in front of contraption-mounted sliding doors now open and clost automatically
- Sliding doors placed in front of contraption-mounted sliding doors now open and close automatically
- Fully outlined text on filter slots for better readability
- Added recipes where cardboard substitutes leather
- Play at most 4 steam engine sounds at once per side of a boiler
- Play at most four steam engine sounds at once per side of a boiler
- Increased default max rope length to 384
- Implemented a system for generating certain recipes at runtime to improve mod compat
- Boiler gauge now disappears when blocks are clipping into it
- Added a keybind that opens a radial menu for rotating blocks with the wrench
- Wood cutting recipes in mechanical saws
- Added pressing recipes for coarse dirt and rooted dirt which both produce dirt paths (#7186)
- Updated JEI integration and added potion fluids to the JEI sidebar (#6934)
#### Bug Fixes
Bug Fixes
- Deployers can no longer take a seat
- Fixed contraptions keeping pressure plates and tripwires activated (#7255)
- Steam engine placement assist now shows a normal shaft
@ -89,15 +95,42 @@ Bug Fixes
- Fixed InventorySorter able to take items from ghost/filter inventories
- Fixed typo in better end compat recipe
- FTB buttons no longer show in create screens
- Fixed mechanical arm interactions with jukeboxes (#5902)
- Fixed toolboxes not giving a comparator output signal (#6973)
- Fixed copper slabs and stairs being missing from the respective tags (#3080)
- Fix incorrect copycat panel culling when framed glass is used and sodium is installed (Fabricators-of-Create#1540)
- Fixed Fix waterlogged bracketed kinetics dropping the bracket (Fabricators-of-Create#1552)
- Switched away from using streams in ContraptionCollider fixing a rare crash (#5043)
- Fixed pumps not placing fluids into flowing fluids of the same type (#5884)
- Fixed schematicannons not consuming the right number of group items (#6983)
- Fixed backtanks getting incompatible enchants via smithing tables (#6687)
- Fixed Lectern Controllers storing ItemStacks from nbt (#7143)
- Optimized spout recipe generation by avoiding filling non-empty items (#7274)
- Fixed crash when dying nixie tubes with dye depots dyes (#6694)
- Fix enchantments getting trimmed from non-filter items (#7216)
- Fixed sandpaper polishing recipes not working in sequenced assembly recipes (#7259)
- Fixed mechanical drills and saws using the friendly creatures sound source instead of the blocks sound source (#7038)
- Fixed backtank crashing on ctrl+pick block (#7284)
- Improved memory usage of drain category in JEI (#7277)
- Fixed getSize() throwing an error on newly loaded display link peripherals (#7059)
- Fixed inability to mill cactus when Quark is installed (#7215)
- Fixed rare spout crash and offset rendering (#7025)
- Fixed deploying food resulting in missing particles and not returning the correct items (#7288)
#### API Changes
API Changes
- Versioning change: `major.minor.patch`, starting with `6.0.0`
- Ponder is now a separate library mod. It comes shipped with the create jar.
- Added `#create:chain_rideable` to mark items as valid for riding a chain with
- Added `#create:invalid_for_track_paving` for items
- New API for custom storage block behaviour on contraptions. For simple cases, create provides the `#create:simple_mounted_storage` and `#create:chest_mounted_storage` block tags.
- Added `#create:sugar_cane_variants` to allow the mechanical saw to work with custom sugarcane variants (#7263)
- New API for custom storage block behaviour on contraptions.
For simple cases, create provides the `#create:simple_mounted_storage` and `#create:chest_mounted_storage` block tags.
- Removed LangMerger and related classes
- Implemented an api to allow mods to register schematic requirements, partial safe nbt and contraption transforms without implementing interfaces (#4702)
- Implemented an api to allow mods to register schematic requirements, partial safe nbt and contraption transforms
without implementing interfaces (#4702)
- Add a method that developers can override to change the icon in goggle tooltips
- Refactored Item Attributes types, Fan processing types and Arm interaction points, all 3 now use registries
- Synced AllPortalTracks with Create Fabric
- Implemented DyeHelper api (#7265)
- Implemented api to add custom block train conductors (#7030)

View file

@ -3,7 +3,9 @@ package com.simibubi.create.compat.jei;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
@ -87,10 +89,12 @@ import mezz.jei.api.registration.ISubtypeRegistration;
import mezz.jei.api.runtime.IIngredientManager;
import net.createmod.catnip.config.ConfigBase.ConfigBool;
import net.minecraft.client.Minecraft;
import net.minecraft.core.Holder;
import net.minecraft.core.Holder.Reference;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.Potion;
@ -105,7 +109,6 @@ import net.minecraft.world.item.crafting.ShapedRecipe;
import net.minecraft.world.item.crafting.SmokingRecipe;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Blocks;
import net.neoforged.neoforge.fluids.FluidStack;
@JeiPlugin
@ -370,14 +373,27 @@ public class CreateJEI implements IModPlugin {
.listElements()
.toList();
Collection<FluidStack> potionFluids = new ArrayList<>(potions.size() * 3);
Set<Set<Holder<MobEffect>>> visitedEffects = new HashSet<>();
for (Reference<Potion> potion : potions) {
// @goshante: Ingame potion fluids always have Bottle tag that specifies
// to what bottle type this potion belongs
// Potion fluid without this tag wouldn't be recognized by other mods
for (PotionFluid.BottleType bottleType : PotionFluid.BottleType.values()) {
FluidStack potionFluid = PotionFluid.of(1000, new PotionContents(potion), bottleType);
potionFluids.add(potionFluid);
// for (PotionFluid.BottleType bottleType : PotionFluid.BottleType.values()) {
// FluidStack potionFluid = PotionFluid.of(1000, new PotionContents(potion), bottleType);
// potionFluids.add(potionFluid);
// }
PotionContents potionContents = new PotionContents(potion);
if (potionContents.hasEffects()) {
Set<Holder<MobEffect>> effectSet = new HashSet<>();
potionContents.forEachEffect(mei -> effectSet.add(mei.getEffect()));
if (!visitedEffects.add(effectSet))
continue;
}
potionFluids.add(PotionFluid.of(1000, potionContents, PotionFluid.BottleType.REGULAR));
}
registration.addExtraIngredients(NeoForgeTypes.FLUID_STACK, potionFluids);
}

View file

@ -69,7 +69,7 @@ public class CardboardArmorHandlerClient {
try {
PartialModel model = AllPartialModels.PACKAGES_TO_HIDE_AS.get(getCurrentBoxIndex(player));
PackageRenderer.renderBox(player, -interpolatedYaw + -90, ms, event.getMultiBufferSource(),
PackageRenderer.renderBox(player, interpolatedYaw, ms, event.getMultiBufferSource(),
event.getPackedLight(), model);
} catch (ExecutionException e) {
e.printStackTrace();

View file

@ -0,0 +1,58 @@
package com.simibubi.create.content.kinetics.drill;
import java.util.HashMap;
import net.createmod.catnip.levelWrappers.WrappedLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.ticks.TickPriority;
public class CobbleGenLevel extends WrappedLevel {
public HashMap<BlockPos, BlockState> blocksAdded = new HashMap<>();
public CobbleGenLevel(Level level) {
super(level);
}
public void clear() {
blocksAdded.clear();
}
@Override
public boolean setBlock(BlockPos pos, BlockState newState, int flags) {
blocksAdded.put(pos.immutable(), newState);
return true;
}
@Override
public boolean setBlockAndUpdate(BlockPos pos, BlockState state) {
return setBlock(pos, state, 0);
}
@Override
public void scheduleTick(BlockPos pos, Block block, int delay) {}
@Override
public void scheduleTick(BlockPos pos, Block block, int delay, TickPriority priority) {}
@Override
public void scheduleTick(BlockPos pos, Fluid fluid, int delay) {}
@Override
public void scheduleTick(BlockPos pos, Fluid fluid, int delay, TickPriority priority) {}
@Override
public void levelEvent(int type, BlockPos pos, int data) {}
@Override
public void levelEvent(Player player, int type, BlockPos pos, int data) {}
@Override
public void blockEvent(BlockPos pos, Block block, int eventID, int eventParam) {}
}

View file

@ -13,7 +13,6 @@ import com.simibubi.create.foundation.mixin.accessor.FluidInteractionRegistryAcc
import net.createmod.catnip.data.Iterate;
import net.createmod.catnip.data.Pair;
import net.createmod.catnip.levelWrappers.PlacementSimulationServerLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
@ -29,7 +28,7 @@ import net.neoforged.neoforge.fluids.FluidType;
public class CobbleGenOptimisation {
static PlacementSimulationServerLevel cachedLevel;
static CobbleGenLevel cachedLevel;
public record CobbleGenBlockConfiguration(List<BlockState> statesAroundDrill) {
}
@ -90,9 +89,12 @@ public class CobbleGenOptimisation {
}
}
// TODO Catnip: add empty methods to PSSL overriding levelEvent() side-effects
if (cachedLevel == null || cachedLevel.getLevel() != level)
cachedLevel = new PlacementSimulationServerLevel(level);
ServerLevel owLevel = level.getServer().getLevel(Level.OVERWORLD);
if (owLevel == null)
owLevel = level;
if (cachedLevel == null || cachedLevel.getLevel() != owLevel)
cachedLevel = new CobbleGenLevel(level);
BlockState result = Blocks.AIR.defaultBlockState();
if (interaction == null)

View file

@ -24,13 +24,18 @@ public class AddressEditBox extends EditBox {
private DestinationSuggestions destinationSuggestions;
private Consumer<String> mainResponder;
private String prevValue = "=)";
public AddressEditBox(Screen screen, Font pFont, int pX, int pY, int pWidth, int pHeight, boolean anchorToBottom) {
super(pFont, pX, pY, pWidth, pHeight, Component.empty());
destinationSuggestions = AddressEditBoxHelper.createSuggestions(screen, this, anchorToBottom);
destinationSuggestions.setAllowSuggestions(true);
destinationSuggestions.updateCommandInfo();
mainResponder = t -> destinationSuggestions.updateCommandInfo();
mainResponder = t -> {
if (t.equals(prevValue))
destinationSuggestions.updateCommandInfo();
prevValue = t;
};
setResponder(mainResponder);
setBordered(false);
setFocused(false);
@ -63,8 +68,8 @@ public class AddressEditBox extends EditBox {
boolean wasFocused = isFocused();
if (super.mouseClicked(pMouseX, pMouseY, pButton)) {
if (!wasFocused) {
setHighlightPos(getValue().length());
setCursorPosition(0);
setHighlightPos(0);
setCursorPosition(getValue().length());
}
return true;
}
@ -81,8 +86,6 @@ public class AddressEditBox extends EditBox {
@Override
public void setFocused(boolean focused) {
super.setFocused(focused);
if (!focused)
setHighlightPos(getCursorPosition());
}
@Override

View file

@ -485,7 +485,7 @@ public class FactoryPanelBehaviour extends FilteringBehaviour {
sendEffect(getPanelPosition(), true);
if (!LogisticsManager.broadcastPackageRequest(network, RequestType.RESTOCK, order,
packager.targetInventory.getInventory(), recipeAddress))
packager.targetInventory.getInventory(), recipeAddress, null))
return;
restockerPromises.add(new RequestPromise(orderedItem));
@ -613,7 +613,7 @@ public class FactoryPanelBehaviour extends FilteringBehaviour {
}
public boolean isMissingAddress() {
return !targetedBy.isEmpty() && count != 0 && recipeAddress.isBlank();
return (!targetedBy.isEmpty() || panelBE().restocker) && count != 0 && recipeAddress.isBlank();
}
@Override

View file

@ -97,9 +97,13 @@ public class FactoryPanelScreen extends AbstractSimiScreen {
return;
}
craftingIngredients = new ArrayList<>();
NonNullList<Ingredient> ingredients = availableCraftingRecipe.getIngredients();
craftingIngredients = convertRecipeToPackageOrderContext(availableCraftingRecipe, inputConfig);
}
public static List<BigItemStack> convertRecipeToPackageOrderContext(CraftingRecipe availableCraftingRecipe, List<BigItemStack> inputs) {
List<BigItemStack> craftingIngredients = new ArrayList<>();
BigItemStack emptyIngredient = new BigItemStack(ItemStack.EMPTY, 1);
NonNullList<Ingredient> ingredients = availableCraftingRecipe.getIngredients();
int width = Math.min(3, ingredients.size());
int height = Math.min(3, ingredients.size() / 3 + 1);
@ -120,11 +124,11 @@ public class FactoryPanelScreen extends AbstractSimiScreen {
BigItemStack craftingIngredient = emptyIngredient;
if (!ingredient.isEmpty())
for (BigItemStack bigItemStack : inputConfig)
for (BigItemStack bigItemStack : inputs)
if (ingredient.test(bigItemStack.stack))
craftingIngredient = bigItemStack;
craftingIngredient = new BigItemStack(bigItemStack.stack, 1);
craftingIngredients.add(craftingIngredient);
if (width < 3 && (i + 1) % width == 0)
for (int j = 0; j < 3 - width; j++)
craftingIngredients.add(emptyIngredient);
@ -132,6 +136,8 @@ public class FactoryPanelScreen extends AbstractSimiScreen {
while (craftingIngredients.size() < 9)
craftingIngredients.add(emptyIngredient);
return craftingIngredients;
}
@Override

View file

@ -101,13 +101,13 @@ public abstract class PackagePortBlockEntity extends SmartBlockEntity implements
@Override
public void invalidate() {
if (target != null)
target.deregister(this, level, worldPosition);
super.invalidate();
}
@Override
public void destroy() {
if (target != null)
target.deregister(this, level, worldPosition);
super.destroy();
for (int i = 0; i < inventory.getSlots(); i++)
drop(inventory.getStackInSlot(i));

View file

@ -56,6 +56,9 @@ public class FrogportBlockEntity extends PackagePortBlockEntity implements IHave
private boolean failedLastExport;
private FrogportSounds sounds;
private ItemStack deferAnimationStart;
private boolean deferAnimationInward;
private AdvancementBehaviour advancements;
@ -129,6 +132,11 @@ public class FrogportBlockEntity extends PackagePortBlockEntity implements IHave
@Override
public void tick() {
super.tick();
if (deferAnimationStart != null) {
startAnimation(deferAnimationStart, deferAnimationInward);
deferAnimationStart = null;
}
if (anticipationProgress.getValue() == 1)
anticipationProgress.updateChaseTarget(0);
@ -303,7 +311,7 @@ public class FrogportBlockEntity extends PackagePortBlockEntity implements IHave
protected void write(CompoundTag tag, HolderLookup.Provider registries, boolean clientPacket) {
super.write(tag, registries, clientPacket);
tag.putFloat("PlacedYaw", passiveYaw);
if (animatedPackage != null) {
if (animatedPackage != null && isAnimationInProgress()) {
tag.put("AnimatedPackage", animatedPackage.saveOptional(registries));
tag.putBoolean("Deposit", currentlyDepositing);
}
@ -322,8 +330,10 @@ public class FrogportBlockEntity extends PackagePortBlockEntity implements IHave
failedLastExport = tag.getBoolean("FailedLastExport");
if (!clientPacket)
animatedPackage = null;
if (tag.contains("AnimatedPackage"))
startAnimation(ItemStack.parseOptional(registries, tag.getCompound("AnimatedPackage")), tag.getBoolean("Deposit"));
if (tag.contains("AnimatedPackage")) {
deferAnimationInward = tag.getBoolean("Deposit");
deferAnimationStart = ItemStack.parseOptional(registries, tag.getCompound("AnimatedPackage"));
}
if (clientPacket && tag.contains("Anticipate"))
anticipate();
}

View file

@ -114,6 +114,11 @@ public class PostboxBlock extends HorizontalDirectionalBlock
return getBlockEntityOptional(pLevel, pPos).map(pbe -> pbe.getComparatorOutput())
.orElse(0);
}
@Override
public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pMovedByPiston) {
IBE.onRemove(pState, pLevel, pPos, pNewState);
}
@Override
protected @NotNull MapCodec<? extends HorizontalDirectionalBlock> codec() {

View file

@ -63,12 +63,12 @@ public class LogisticsManager {
}
public static boolean broadcastPackageRequest(UUID freqId, RequestType type, PackageOrder order,
IItemHandler ignoredHandler, String address) {
IItemHandler ignoredHandler, String address, @Nullable PackageOrder orderContext) {
if (order.isEmpty())
return false;
Multimap<PackagerBlockEntity, PackagingRequest> requests =
findPackagersForRequest(freqId, order, null, ignoredHandler, address);
findPackagersForRequest(freqId, order, orderContext, ignoredHandler, address);
// Check if packagers have accumulated too many packages already
for (PackagerBlockEntity packager : requests.keySet())

View file

@ -21,7 +21,8 @@ public class AutoRequestData {
Codec.STRING.fieldOf("encoded_target_address").forGetter(i -> i.encodedTargetAddress),
BlockPos.CODEC.fieldOf("target_offset").forGetter(i -> i.targetOffset),
Codec.STRING.fieldOf("target_dim").forGetter(i -> i.targetDim),
Codec.BOOL.fieldOf("is_valid").forGetter(i -> i.isValid)
Codec.BOOL.fieldOf("is_valid").forGetter(i -> i.isValid),
PackageOrder.CODEC.fieldOf("encoded_request_context").forGetter(i -> i.encodedRequestContext)
).apply(instance, AutoRequestData::new));
public static final StreamCodec<RegistryFriendlyByteBuf, AutoRequestData> STREAM_CODEC = StreamCodec.composite(
@ -30,10 +31,12 @@ public class AutoRequestData {
BlockPos.STREAM_CODEC, i -> i.targetOffset,
ByteBufCodecs.STRING_UTF8, i -> i.targetDim,
ByteBufCodecs.BOOL, i -> i.isValid,
PackageOrder.STREAM_CODEC, i -> i.encodedRequestContext,
AutoRequestData::new
);
public PackageOrder encodedRequest = PackageOrder.empty();
public PackageOrder encodedRequestContext = PackageOrder.empty();
public String encodedTargetAddress = "";
public BlockPos targetOffset = BlockPos.ZERO;
public String targetDim = "null";
@ -41,8 +44,9 @@ public class AutoRequestData {
public AutoRequestData() {}
public AutoRequestData(PackageOrder encodedRequest, String encodedTargetAdress, BlockPos targetOffset, String targetDim, boolean isValid) {
public AutoRequestData(PackageOrder encodedRequest, String encodedTargetAdress, BlockPos targetOffset, String targetDim, boolean isValid, PackageOrder encodedRequestContext) {
this.encodedRequest = encodedRequest;
this.encodedRequestContext = encodedRequestContext;
this.encodedTargetAddress = encodedTargetAdress;
this.targetOffset = targetOffset;
this.targetDim = targetDim;
@ -52,6 +56,7 @@ public class AutoRequestData {
public AutoRequestData copy() {
AutoRequestData data = new AutoRequestData();
data.encodedRequest = encodedRequest;
data.encodedRequestContext = encodedRequestContext;
data.encodedTargetAddress = encodedTargetAddress;
data.targetOffset = targetOffset;
data.targetDim = targetDim;

View file

@ -91,7 +91,7 @@ public class RedstoneRequesterBlock extends Block implements IBE<RedstoneRequest
}
public static void programRequester(ServerPlayer player, StockTickerBlockEntity be, PackageOrder order,
String address) {
String address, PackageOrder orderContext) {
ItemStack stack = player.getMainHandItem();
boolean isRequester = AllBlocks.REDSTONE_REQUESTER.isIn(stack);
boolean isShopCloth = AllItemTags.TABLE_CLOTHS.matches(stack);
@ -100,6 +100,7 @@ public class RedstoneRequesterBlock extends Block implements IBE<RedstoneRequest
AutoRequestData autoRequestData = new AutoRequestData();
autoRequestData.encodedRequest = order;
autoRequestData.encodedRequestContext = orderContext;
autoRequestData.encodedTargetAddress = address;
autoRequestData.targetOffset = be.getBlockPos();
autoRequestData.targetDim = player.level()
@ -148,6 +149,7 @@ public class RedstoneRequesterBlock extends Block implements IBE<RedstoneRequest
if (data == null)
return;
rrbe.encodedRequest = data.encodedRequest;
rrbe.encodedRequestContext = data.encodedRequestContext;
rrbe.encodedTargetAdress = data.encodedTargetAddress;
});
}

View file

@ -31,6 +31,7 @@ public class RedstoneRequesterBlockEntity extends StockCheckingBlockEntity imple
public boolean allowPartialRequests;
public PackageOrder encodedRequest = PackageOrder.empty();
public PackageOrder encodedRequestContext = PackageOrder.empty();
public String encodedTargetAdress = "";
public boolean lastRequestSucceeded;
@ -78,7 +79,7 @@ public class RedstoneRequesterBlockEntity extends StockCheckingBlockEntity imple
}
}
broadcastPackageRequest(RequestType.REDSTONE, encodedRequest, null, encodedTargetAdress);
broadcastPackageRequest(RequestType.REDSTONE, encodedRequest, null, encodedTargetAdress, encodedRequestContext.isEmpty() ? null : encodedRequestContext);
if (level instanceof ServerLevel serverLevel)
CatnipServices.NETWORK.sendToClientsAround(serverLevel, worldPosition, 32, new RedstoneRequesterEffectPacket(worldPosition, anySucceeded));
lastRequestSucceeded = true;
@ -91,6 +92,7 @@ public class RedstoneRequesterBlockEntity extends StockCheckingBlockEntity imple
lastRequestSucceeded = tag.getBoolean("Success");
allowPartialRequests = tag.getBoolean("AllowPartial");
encodedRequest = CatnipCodecUtils.decode(PackageOrder.CODEC, tag.getCompound("EncodedRequest")).orElse(PackageOrder.empty());
encodedRequestContext = CatnipCodecUtils.decode(PackageOrder.CODEC, tag.getCompound("EncodedRequestContext")).orElse(PackageOrder.empty());
encodedTargetAdress = tag.getString("EncodedAddress");
}
@ -100,6 +102,7 @@ public class RedstoneRequesterBlockEntity extends StockCheckingBlockEntity imple
tag.putBoolean("AllowPartial", allowPartialRequests);
tag.putString("EncodedAddress", encodedTargetAdress);
tag.put("EncodedRequest", CatnipCodecUtils.encode(PackageOrder.CODEC, encodedRequest).orElseThrow());
tag.put("EncodedRequestContext", CatnipCodecUtils.encode(PackageOrder.CODEC, encodedRequestContext).orElseThrow());
}
@Override
@ -110,6 +113,7 @@ public class RedstoneRequesterBlockEntity extends StockCheckingBlockEntity imple
tag.putBoolean("AllowPartial", allowPartialRequests);
tag.putString("EncodedAddress", encodedTargetAdress);
tag.put("EncodedRequest", CatnipCodecUtils.encode(PackageOrder.CODEC, encodedRequest).orElseThrow());
tag.put("EncodedRequestContext", CatnipCodecUtils.encode(PackageOrder.CODEC, encodedRequestContext).orElseThrow());
}
public InteractionResult use(Player player) {

View file

@ -20,18 +20,21 @@ public class PackageOrderRequestPacket extends BlockEntityConfigurationPacket<St
PackageOrder.STREAM_CODEC, packet -> packet.order,
ByteBufCodecs.STRING_UTF8, packet -> packet.address,
ByteBufCodecs.BOOL, packet -> packet.encodeRequester,
PackageOrder.STREAM_CODEC, packet -> packet.craftingRequest,
PackageOrderRequestPacket::new
);
private final PackageOrder order;
private final String address;
private final boolean encodeRequester;
private final PackageOrder craftingRequest;
public PackageOrderRequestPacket(BlockPos pos, PackageOrder order, String address, boolean encodeRequester) {
public PackageOrderRequestPacket(BlockPos pos, PackageOrder order, String address, boolean encodeRequester, PackageOrder craftingRequest) {
super(pos);
this.order = order;
this.address = address;
this.encodeRequester = encodeRequester;
this.craftingRequest = craftingRequest;
}
@Override
@ -45,7 +48,7 @@ public class PackageOrderRequestPacket extends BlockEntityConfigurationPacket<St
if (!order.isEmpty())
AllSoundEvents.CONFIRM.playOnServer(be.getLevel(), pos);
player.closeContainer();
RedstoneRequesterBlock.programRequester(player, be, order, address);
RedstoneRequesterBlock.programRequester(player, be, order, address, craftingRequest);
return;
}
@ -55,6 +58,6 @@ public class PackageOrderRequestPacket extends BlockEntityConfigurationPacket<St
WiFiEffectPacket.send(player.level(), pos);
}
be.broadcastPackageRequest(RequestType.PLAYER, order, null, address);
be.broadcastPackageRequest(RequestType.PLAYER, order, null, address, craftingRequest.isEmpty() ? null : craftingRequest);
}
}

View file

@ -2,6 +2,8 @@ package com.simibubi.create.content.logistics.stockTicker;
import java.util.List;
import javax.annotation.Nullable;
import com.simibubi.create.content.logistics.packager.InventorySummary;
import com.simibubi.create.content.logistics.packagerLink.LogisticallyLinkedBehaviour;
import com.simibubi.create.content.logistics.packagerLink.LogisticallyLinkedBehaviour.RequestType;
@ -38,7 +40,12 @@ public abstract class StockCheckingBlockEntity extends SmartBlockEntity {
public boolean broadcastPackageRequest(RequestType type, PackageOrder order, IItemHandler ignoredHandler,
String address) {
return LogisticsManager.broadcastPackageRequest(behaviour.freqId, type, order, ignoredHandler, address);
return broadcastPackageRequest(type, order, ignoredHandler, address, null);
}
public boolean broadcastPackageRequest(RequestType type, PackageOrder order, IItemHandler ignoredHandler,
String address, @Nullable PackageOrder orderContext) {
return LogisticsManager.broadcastPackageRequest(behaviour.freqId, type, order, ignoredHandler, address, orderContext);
}
}

View file

@ -28,6 +28,7 @@ import com.simibubi.create.content.contraptions.actors.seat.SeatEntity;
import com.simibubi.create.content.equipment.clipboard.ClipboardEntry;
import com.simibubi.create.content.logistics.AddressEditBox;
import com.simibubi.create.content.logistics.BigItemStack;
import com.simibubi.create.content.logistics.factoryBoard.FactoryPanelScreen;
import com.simibubi.create.content.logistics.packager.InventorySummary;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlockEntity;
@ -72,6 +73,7 @@ import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.Item.TooltipContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.phys.AABB;
@ -145,6 +147,7 @@ public class StockKeeperRequestScreen extends AbstractSimiContainerScreen<StockK
private Set<Integer> hiddenCategories;
private InventorySummary forcedEntries;
private boolean canRequestCraftingPackage;
public StockKeeperRequestScreen(StockKeeperRequestMenu container, Inventory inv, Component title) {
super(container, inv, title);
@ -166,6 +169,7 @@ public class StockKeeperRequestScreen extends AbstractSimiContainerScreen<StockK
refreshSearchNextTick = false;
moveToTopNextTick = false;
menu.screenReference = this;
canRequestCraftingPackage = false;
hiddenCategories =
new HashSet<>(blockEntity.hiddenCategoriesByPlayer.getOrDefault(menu.player.getUUID(), List.of()));
@ -241,7 +245,7 @@ public class StockKeeperRequestScreen extends AbstractSimiContainerScreen<StockK
boolean initial = addressBox == null;
String previouslyUsedAddress = initial ? blockEntity.previouslyUsedAddress : addressBox.getValue();
addressBox =
new AddressEditBox(this, new NoShadowFontWrapper(font), x + 27, y + windowHeight - 36, 90, 10, true);
new AddressEditBox(this, new NoShadowFontWrapper(font), x + 27, y + windowHeight - 36, 92, 10, true);
addressBox.setTextColor(0x714A40);
addressBox.setValue(previouslyUsedAddress);
addRenderableWidget(addressBox);
@ -1298,7 +1302,7 @@ public class StockKeeperRequestScreen extends AbstractSimiContainerScreen<StockK
public void removed() {
BlockPos pos = blockEntity.getBlockPos();
CatnipServices.NETWORK.sendToServer(new PackageOrderRequestPacket(pos, new PackageOrder(Collections.emptyList()),
addressBox.getValue(), false));
addressBox.getValue(), false, PackageOrder.empty()));
CatnipServices.NETWORK.sendToServer(new StockKeeperCategoryHidingPacket(pos, new ArrayList<>(hiddenCategories)));
super.removed();
}
@ -1317,9 +1321,14 @@ public class StockKeeperRequestScreen extends AbstractSimiContainerScreen<StockK
continue;
forcedEntries.add(toOrder.stack.copy(), -1 - Math.max(0, countOf - toOrder.count));
}
PackageOrder craftingRequest = PackageOrder.empty();
if (canRequestCraftingPackage && !itemsToOrder.isEmpty() && !recipesToOrder.isEmpty())
if (recipesToOrder.get(0).recipe instanceof CraftingRecipe cr)
craftingRequest = new PackageOrder(FactoryPanelScreen.convertRecipeToPackageOrderContext(cr, itemsToOrder));
CatnipServices.NETWORK.sendToServer(new PackageOrderRequestPacket(blockEntity.getBlockPos(), new PackageOrder(itemsToOrder),
addressBox.getValue(), encodeRequester));
addressBox.getValue(), encodeRequester, craftingRequest));
itemsToOrder = new ArrayList<>();
recipesToOrder = new ArrayList<>();
@ -1446,6 +1455,14 @@ public class StockKeeperRequestScreen extends AbstractSimiContainerScreen<StockK
}
}
}
canRequestCraftingPackage = false;
if (recipesToOrder.size() != 1)
return;
for (BigItemStack ordered : itemsToOrder)
if (usedItems.getCountOf(ordered.stack) != ordered.count)
return;
canRequestCraftingPackage = true;
}
private Pair<Integer, List<List<BigItemStack>>> maxCraftable(CraftableBigItemStack cbis, InventorySummary summary,

View file

@ -101,8 +101,8 @@ public class StockTickerBlockEntity extends StockCheckingBlockEntity implements
@Override
public boolean broadcastPackageRequest(RequestType type, PackageOrder order, IItemHandler ignoredHandler,
String address) {
boolean result = super.broadcastPackageRequest(type, order, ignoredHandler, address);
String address, @Nullable PackageOrder orderContext) {
boolean result = super.broadcastPackageRequest(type, order, ignoredHandler, address, orderContext);
previouslyUsedAddress = address;
notifyUpdate();
return result;

View file

@ -14,9 +14,9 @@ import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.blockEntity.IMergeableBE;
import com.simibubi.create.foundation.utility.BlockHelper;
import net.createmod.catnip.levelWrappers.SchematicLevel;
import net.createmod.catnip.math.BBHelper;
import net.createmod.catnip.nbt.NBTHelper;
import net.createmod.catnip.levelWrappers.SchematicLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@ -34,6 +34,7 @@ import net.minecraft.world.level.block.state.properties.DoubleBlockHalf;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraft.world.level.material.Fluids;
public class SchematicPrinter {
@ -341,4 +342,15 @@ public class SchematicPrinter {
|| BlockMovementChecks.isBrittle(state);
}
public void sendBlockUpdates(Level level) {
BoundingBox bounds = blockReader.getBounds();
BlockPos.betweenClosedStream(bounds.inflatedBy(1))
.filter(pos -> !bounds.isInside(pos))
.filter(
pos -> level.isLoaded(pos.offset(schematicAnchor)) && level.getFluidState(pos.offset(schematicAnchor))
.is(Fluids.WATER))
.forEach(
pos -> level.scheduleTick(pos.offset(schematicAnchor), Fluids.WATER, Fluids.WATER.getTickDelay(level)));
}
}

View file

@ -577,6 +577,8 @@ public class SchematicannonBlockEntity extends SmartBlockEntity implements MenuP
}
public void finishedPrinting() {
if (replaceMode == ConfigureSchematicannonPacket.Option.REPLACE_EMPTY.ordinal())
printer.sendBlockUpdates(level);
inventory.setStackInSlot(0, ItemStack.EMPTY);
inventory.setStackInSlot(1, new ItemStack(AllItems.EMPTY_SCHEMATIC.get(), inventory.getStackInSlot(1)
.getCount() + 1));

View file

@ -47,7 +47,15 @@ public class DestinationSuggestions extends CommandSuggestions {
@Override
public void updateCommandInfo() {
String value = textBox.getValue().substring(0, textBox.getCursorPosition());
String trimmed = textBox.getValue()
.substring(0, textBox.getCursorPosition());
if (!textBox.getHighlighted()
.isBlank())
trimmed = trimmed.replace(textBox.getHighlighted(), "");
final String value = trimmed;
if (value.equals(previous))
return;
if (!active) {

View file

@ -9,7 +9,6 @@ import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import com.simibubi.create.Create;
import com.tterrag.registrate.AbstractRegistrate;
import com.tterrag.registrate.builders.BlockEntityBuilder;
import com.tterrag.registrate.builders.BuilderCallback;
@ -23,6 +22,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
public class CreateBlockEntityBuilder<T extends BlockEntity, P> extends BlockEntityBuilder<T, P> {
@Nullable
@ -33,12 +33,12 @@ public class CreateBlockEntityBuilder<T extends BlockEntity, P> extends BlockEnt
new ArrayList<>();
public static <T extends BlockEntity, P> BlockEntityBuilder<T, P> create(AbstractRegistrate<?> owner, P parent,
String name, BuilderCallback callback, BlockEntityFactory<T> factory) {
String name, BuilderCallback callback, BlockEntityFactory<T> factory) {
return new CreateBlockEntityBuilder<>(owner, parent, name, callback, factory);
}
protected CreateBlockEntityBuilder(AbstractRegistrate<?> owner, P parent, String name, BuilderCallback callback,
BlockEntityFactory<T> factory) {
BlockEntityFactory<T> factory) {
super(owner, parent, name, callback, factory);
}
@ -82,7 +82,7 @@ public class CreateBlockEntityBuilder<T extends BlockEntity, P> extends BlockEnt
}
protected void registerVisualizer() {
OneTimeEventReceiver.addModListener(Create.REGISTRATE, FMLClientSetupEvent.class, $ -> {
OneTimeEventReceiver.addModListener(getOwner(), FMLClientSetupEvent.class, $ -> {
var visualFactory = this.visualFactory;
if (visualFactory != null) {
Predicate<@NotNull T> renderNormally = this.renderNormally;

View file

@ -7,7 +7,6 @@ import javax.annotation.ParametersAreNonnullByDefault;
import org.jetbrains.annotations.NotNull;
import com.simibubi.create.Create;
import com.tterrag.registrate.AbstractRegistrate;
import com.tterrag.registrate.builders.BuilderCallback;
import com.tterrag.registrate.builders.EntityBuilder;
@ -21,6 +20,7 @@ import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobCategory;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
@ParametersAreNonnullByDefault
public class CreateEntityBuilder<T extends Entity, P> extends EntityBuilder<T, P> {
@ -56,7 +56,7 @@ public class CreateEntityBuilder<T extends Entity, P> extends EntityBuilder<T, P
}
protected void registerVisualizer() {
OneTimeEventReceiver.addModListener(Create.REGISTRATE, FMLClientSetupEvent.class, $ -> {
OneTimeEventReceiver.addModListener(getOwner(), FMLClientSetupEvent.class, $ -> {
var visualFactory = this.visualFactory;
if (visualFactory != null) {
Predicate<@NotNull T> renderNormally = this.renderNormally;

View file

@ -77,9 +77,12 @@ public class RuntimeDataGenerator {
ResourceLocation buttonId = base.withSuffix("button");
ResourceLocation signId = base.withSuffix("sign");
if (!noStrippedVariant)
if (!noStrippedVariant) {
simpleWoodRecipe(nonStrippedId, itemId);
simpleWoodRecipe(TagKey.create(Registries.ITEM, nonStrippedId.withSuffix("s")), planksId, 6);
simpleWoodRecipe(itemId, planksId, 6);
} else {
simpleWoodRecipe(TagKey.create(Registries.ITEM, nonStrippedId.withSuffix("s")), planksId, 6);
}
if (!path.contains("_wood") && !path.contains("_hyphae") && BuiltInRegistries.ITEM.containsKey(planksId)) {
simpleWoodRecipe(planksId, stairsId);