Merge branch 'mc1.18/0.5.1' into mc1.18/0.5.1-repolish

This commit is contained in:
simibubi 2023-03-23 14:03:37 +01:00
commit 90d6e21a60
113 changed files with 784 additions and 404 deletions

View file

@ -1061,6 +1061,7 @@
"create.minecart_coupling.removed": "Removed all couplings from minecart",
"create.minecart_coupling.too_far": "Minecarts are too far apart",
"create.contraptions.moving_container": "Moving %1$s",
"create.contraptions.movement_mode": "Movement Mode",
"create.contraptions.movement_mode.move_place": "Always Place when Stopped",
"create.contraptions.movement_mode.move_place_returned": "Place only in Starting Position",

View file

@ -0,0 +1,34 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"create:copycat_panel_from_zinc_ingot_stonecutting"
]
},
"criteria": {
"has_zinc_ingot": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"items": [
"create:zinc_ingot"
]
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "create:copycat_panel_from_zinc_ingot_stonecutting"
}
}
},
"requirements": [
[
"has_zinc_ingot",
"has_the_recipe"
]
]
}

View file

@ -0,0 +1,34 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"create:copycat_step_from_zinc_ingot_stonecutting"
]
},
"criteria": {
"has_zinc_ingot": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"items": [
"create:zinc_ingot"
]
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "create:copycat_step_from_zinc_ingot_stonecutting"
}
}
},
"requirements": [
[
"has_zinc_ingot",
"has_the_recipe"
]
]
}

View file

@ -0,0 +1,34 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"create:crafting/appliances/netherite_backtank"
]
},
"criteria": {
"has_item": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"items": [
"create:copper_backtank"
]
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "create:crafting/appliances/netherite_backtank"
}
}
},
"requirements": [
[
"has_item",
"has_the_recipe"
]
]
}

View file

@ -0,0 +1,34 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"create:crafting/appliances/netherite_diving_boots"
]
},
"criteria": {
"has_item": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"items": [
"create:copper_diving_boots"
]
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "create:crafting/appliances/netherite_diving_boots"
}
}
},
"requirements": [
[
"has_item",
"has_the_recipe"
]
]
}

View file

@ -0,0 +1,34 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"create:crafting/appliances/netherite_diving_helmet"
]
},
"criteria": {
"has_item": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"items": [
"create:copper_diving_helmet"
]
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "create:crafting/appliances/netherite_diving_helmet"
}
}
},
"requirements": [
[
"has_item",
"has_the_recipe"
]
]
}

View file

@ -0,0 +1,34 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"create:crafting/kinetics/contraption_controls"
]
},
"criteria": {
"has_item": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"items": [
"create:andesite_alloy"
]
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "create:crafting/kinetics/contraption_controls"
}
}
},
"requirements": [
[
"has_item",
"has_the_recipe"
]
]
}

View file

@ -0,0 +1,32 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"create:crafting/kinetics/elevator_pulley"
]
},
"criteria": {
"has_item": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"tag": "forge:ingots/brass"
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "create:crafting/kinetics/elevator_pulley"
}
}
},
"requirements": [
[
"has_item",
"has_the_recipe"
]
]
}

View file

@ -0,0 +1,8 @@
{
"type": "minecraft:stonecutting",
"ingredient": {
"item": "create:zinc_ingot"
},
"result": "create:copycat_panel",
"count": 4
}

View file

@ -0,0 +1,8 @@
{
"type": "minecraft:stonecutting",
"ingredient": {
"item": "create:zinc_ingot"
},
"result": "create:copycat_step",
"count": 4
}

View file

@ -0,0 +1,12 @@
{
"type": "minecraft:smithing",
"base": {
"item": "create:copper_backtank"
},
"addition": {
"tag": "forge:ingots/netherite"
},
"result": {
"item": "create:netherite_backtank"
}
}

View file

@ -0,0 +1,12 @@
{
"type": "minecraft:smithing",
"base": {
"item": "create:copper_diving_boots"
},
"addition": {
"tag": "forge:ingots/netherite"
},
"result": {
"item": "create:netherite_diving_boots"
}
}

View file

@ -0,0 +1,12 @@
{
"type": "minecraft:smithing",
"base": {
"item": "create:copper_diving_helmet"
},
"addition": {
"tag": "forge:ingots/netherite"
},
"result": {
"item": "create:netherite_diving_helmet"
}
}

View file

@ -0,0 +1,22 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"B",
"C",
"I"
],
"key": {
"B": {
"tag": "minecraft:buttons"
},
"C": {
"item": "create:andesite_casing"
},
"I": {
"item": "create:electron_tube"
}
},
"result": {
"item": "create:contraption_controls"
}
}

View file

@ -0,0 +1,22 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"B",
"C",
"I"
],
"key": {
"B": {
"item": "create:brass_casing"
},
"C": {
"item": "minecraft:dried_kelp_block"
},
"I": {
"tag": "forge:plates/iron"
}
},
"result": {
"item": "create:elevator_pulley"
}
}

View file

@ -0,0 +1,4 @@
{
"replace": false,
"values": []
}

View file

@ -1779,6 +1779,7 @@ public class AllBlocks {
.transform(BuilderTransformers.copycat())
.onRegister(CreateRegistrate.blockModel(() -> CopycatStepModel::new))
.item()
.recipe((c, p) -> p.stonecutting(DataIngredient.items(AllItems.ZINC_INGOT), c::get, 4))
.transform(customItemModel("copycat_base", "step"))
.register();
@ -1787,6 +1788,7 @@ public class AllBlocks {
.transform(BuilderTransformers.copycat())
.onRegister(CreateRegistrate.blockModel(() -> CopycatPanelModel::new))
.item()
.recipe((c, p) -> p.stonecutting(DataIngredient.items(AllItems.ZINC_INGOT), c::get, 4))
.transform(customItemModel("copycat_base", "panel"))
.register();
@ -2121,6 +2123,10 @@ public class AllBlocks {
});
// Materials
static {
REGISTRATE.creativeModeTab(() -> AllCreativeModeTabs.PALETTES_CREATIVE_TAB);
}
public static final BlockEntry<Block> ZINC_ORE = REGISTRATE.block("zinc_ore", Block::new)
.initialProperties(() -> Blocks.GOLD_ORE)

View file

@ -93,7 +93,7 @@ public class AllPartialModels {
ARM_HEAD = block("mechanical_arm/head"), ARM_CLAW_BASE = block("mechanical_arm/claw_base"),
ARM_CLAW_GRIP = block("mechanical_arm/claw_grip"),
MECHANICAL_PUMP_ARROW = block("mechanical_pump/arrow"), MECHANICAL_PUMP_COG = block("mechanical_pump/cog"),
MECHANICAL_PUMP_COG = block("mechanical_pump/cog"),
FLUID_PIPE_CASING = block("fluid_pipe/casing"), FLUID_VALVE_POINTER = block("fluid_valve/pointer"),
SPOUT_TOP = block("spout/top"), SPOUT_MIDDLE = block("spout/middle"), SPOUT_BOTTOM = block("spout/bottom"),

View file

@ -110,7 +110,7 @@ public class AllShapes {
.add(5, -1, 6, 11, 0, 8)
.forHorizontal(SOUTH),
PUMP = shape(2, 0, 2, 14, 5, 14).add(4, 0, 4, 12, 16, 12)
.add(3, 12, 3, 13, 16, 13)
.add(3, 11, 3, 13, 16, 13)
.forDirectional(Direction.UP),
CRUSHING_WHEEL_CONTROLLER_COLLISION = shape(0, 0, 0, 16, 13, 16).forDirectional(Direction.DOWN),

View file

@ -87,6 +87,7 @@ public class AllTags {
WRENCH_PICKUP,
COPYCAT_ALLOW,
COPYCAT_DENY,
CONTRAPTION_INVENTORY_DENY,
RELOCATION_NOT_SUPPORTED(FORGE),
WG_STONE(FORGE),

View file

@ -83,10 +83,9 @@ public class Create {
public static final CreateRegistrate REGISTRATE = CreateRegistrate.create(ID);
static {
// TODO 0.5.1: choose color palette
REGISTRATE.setTooltipModifierFactory(item -> {
return new ItemDescription.Modifier(item, Palette.BLUE)
.andThen(TooltipModifier.mapNull(KineticStats.create(item)));
return new ItemDescription.Modifier(item, Palette.STANDARD_CREATE)
.andThen(TooltipModifier.mapNull(KineticStats.create(item)));
});
}

View file

@ -84,7 +84,7 @@ public abstract class PortableStorageInterfaceBlockEntity extends SmartBlockEnti
}
}
transferTimer = Math.min(transferTimer, ANIMATION * 2 + getTransferTimeout());
transferTimer = Math.min(transferTimer, ANIMATION * 2 + timeUnit);
boolean timerCanDecrement = transferTimer > ANIMATION || transferTimer > 0 && keepAlive == 0
&& (isVirtual() || !level.isClientSide || transferTimer != ANIMATION);
@ -180,7 +180,7 @@ public abstract class PortableStorageInterfaceBlockEntity extends SmartBlockEnti
}
public void startConnecting() {
transferTimer = getTransferTimeout() + ANIMATION * 2;
transferTimer = 6 + ANIMATION * 2;
}
public void onContentTransferred() {

View file

@ -278,9 +278,12 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
InteractionHand interactionHand) {
int indexOfSeat = contraption.getSeats()
.indexOf(localPos);
if (indexOfSeat == -1 || AllItems.WRENCH.isIn(player.getItemInHand(interactionHand)))
return contraption.interactors.containsKey(localPos) && contraption.interactors.get(localPos)
.handlePlayerInteraction(player, interactionHand, localPos, this);
if (indexOfSeat == -1 || AllItems.WRENCH.isIn(player.getItemInHand(interactionHand))) {
if (contraption.interactors.containsKey(localPos))
return contraption.interactors.get(localPos)
.handlePlayerInteraction(player, interactionHand, localPos, this);
return contraption.storage.handlePlayerStorageInteraction(contraption, player, localPos);
}
if (player.isPassenger())
return false;

View file

@ -1,6 +1,7 @@
package com.simibubi.create.content.contraptions.components.structureMovement;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllTags.AllBlockTags;
import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterBlockEntity;
import com.simibubi.create.content.contraptions.processing.ProcessingInventory;
import com.simibubi.create.content.logistics.block.inventories.BottomlessItemHandler;
@ -15,6 +16,7 @@ import net.minecraft.world.level.block.entity.BarrelBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.ChestBlockEntity;
import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
@ -47,9 +49,30 @@ public class MountedStorage {
if (be instanceof ItemVaultBlockEntity)
return true;
LazyOptional<IItemHandler> capability = be.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY);
IItemHandler handler = capability.orElse(null);
return handler instanceof ItemStackHandler && !(handler instanceof ProcessingInventory);
try {
LazyOptional<IItemHandler> capability = be.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY);
IItemHandler handler = capability.orElse(null);
if (handler instanceof ItemStackHandler)
return !(handler instanceof ProcessingInventory);
return canUseModdedInventory(be, handler);
} catch (Exception e) {
return false;
}
}
public static boolean canUseModdedInventory(BlockEntity be, IItemHandler handler) {
if (!(handler instanceof IItemHandlerModifiable validItemHandler))
return false;
BlockState blockState = be.getBlockState();
if (AllBlockTags.CONTRAPTION_INVENTORY_DENY.matches(blockState))
return false;
// There doesn't appear to be much of a standard for tagging chests/barrels
String blockId = blockState.getBlock()
.getRegistryName()
.getPath();
return blockId.endsWith("_chest") || blockId.endsWith("_barrel");
}
public MountedStorage(BlockEntity be) {
@ -182,7 +205,7 @@ public class MountedStorage {
public boolean isValid() {
return valid;
}
public boolean canUseForFuel() {
return !noFuel;
}

View file

@ -0,0 +1,68 @@
package com.simibubi.create.content.contraptions.components.structureMovement;
import java.util.List;
import java.util.function.Supplier;
import com.google.common.collect.ImmutableList;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.network.chat.Component;
import net.minecraft.util.Mth;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ChestMenu;
import net.minecraft.world.inventory.MenuType;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.RecipeWrapper;
public class MountedStorageInteraction {
public static final List<MenuType<?>> menus = ImmutableList.of(MenuType.GENERIC_9x1, MenuType.GENERIC_9x2,
MenuType.GENERIC_9x3, MenuType.GENERIC_9x4, MenuType.GENERIC_9x5, MenuType.GENERIC_9x6);
public static MenuProvider createMenuProvider(Component displayName, IItemHandlerModifiable handler,
int slotCount, Supplier<Boolean> stillValid) {
int rows = Mth.clamp(slotCount / 9, 1, 6);
MenuType<?> menuType = menus.get(rows - 1);
Component menuName = Lang.translateDirect("contraptions.moving_container", displayName);
return new MenuProvider() {
@Override
public AbstractContainerMenu createMenu(int pContainerId, Inventory pPlayerInventory, Player pPlayer) {
return new ChestMenu(menuType, pContainerId, pPlayerInventory, new StorageInteractionContainer(handler, stillValid),
rows);
}
@Override
public Component getDisplayName() {
return menuName;
}
};
}
public static class StorageInteractionContainer extends RecipeWrapper {
private Supplier<Boolean> stillValid;
public StorageInteractionContainer(IItemHandlerModifiable inv, Supplier<Boolean> stillValid) {
super(inv);
this.stillValid = stillValid;
}
@Override
public boolean stillValid(Player player) {
return stillValid.get();
}
@Override
public int getMaxStackSize() {
return 64;
}
}
}

View file

@ -6,27 +6,38 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption.ContraptionInvWrapper;
import com.simibubi.create.content.contraptions.fluids.tank.FluidTankBlockEntity;
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.ChestBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.properties.ChestType;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.templates.FluidTank;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
public class MountedStorageManager {
@ -202,4 +213,50 @@ public class MountedStorageManager {
return fluidInventory;
}
public boolean handlePlayerStorageInteraction(Contraption contraption, Player player, BlockPos localPos) {
if (player.level.isClientSide()) {
BlockEntity localBE = contraption.presentBlockEntities.get(localPos);
return MountedStorage.canUseAsStorage(localBE);
}
MountedStorageManager storageManager = contraption.getStorageForSpawnPacket();
MountedStorage storage = storageManager.storage.get(localPos);
if (storage == null || storage.getItemHandler() == null)
return false;
IItemHandlerModifiable handler = storage.getItemHandler();
StructureBlockInfo info = contraption.getBlocks()
.get(localPos);
if (info != null && info.state.hasProperty(ChestBlock.TYPE)) {
ChestType chestType = info.state.getValue(ChestBlock.TYPE);
Direction facing = info.state.getOptionalValue(ChestBlock.FACING)
.orElse(Direction.SOUTH);
Direction connectedDirection =
chestType == ChestType.LEFT ? facing.getClockWise() : facing.getCounterClockWise();
if (chestType != ChestType.SINGLE) {
MountedStorage storage2 = storageManager.storage.get(localPos.relative(connectedDirection));
if (storage2 != null && storage2.getItemHandler() != null)
handler = chestType == ChestType.RIGHT ? new CombinedInvWrapper(handler, storage2.getItemHandler())
: new CombinedInvWrapper(storage2.getItemHandler(), handler);
}
}
int slotCount = handler.getSlots();
if (slotCount == 0)
return false;
if (slotCount % 9 != 0)
return false;
Supplier<Boolean> stillValid = () -> contraption.entity.isAlive()
&& player.distanceToSqr(contraption.entity.toGlobalVector(Vec3.atCenterOf(localPos), 0)) < 64;
Component name = info != null ? info.state.getBlock()
.getName() : Components.literal("Container");
player.openMenu(MountedStorageInteraction.createMenuProvider(name, handler, slotCount, stillValid));
Vec3 soundPos = contraption.entity.toGlobalVector(Vec3.atCenterOf(localPos), 0);
player.level.playSound(null, new BlockPos(soundPos), SoundEvents.BARREL_OPEN, SoundSource.BLOCKS, 0.75f, 1f);
return true;
}
}

View file

@ -90,9 +90,13 @@ public class ElevatorContactBlock extends WrenchableDirectionalBlock
if (pState.getValue(CALLING))
return;
ElevatorColumn elevatorColumn = ElevatorColumn.getOrCreate(pLevel, getColumnCoords(pLevel, pPos));
callToContactAndUpdate(elevatorColumn, pState, pLevel, pPos);
}
public void callToContactAndUpdate(ElevatorColumn elevatorColumn, BlockState pState, Level pLevel, BlockPos pPos) {
pLevel.setBlock(pPos, pState.cycle(CALLING), 2);
ElevatorColumn elevatorColumn = ElevatorColumn.getOrCreate(pLevel, getColumnCoords(pLevel, pPos));
for (BlockPos otherPos : elevatorColumn.getContacts()) {
if (otherPos.equals(pPos))
continue;

View file

@ -1,6 +1,5 @@
package com.simibubi.create.content.contraptions.components.structureMovement.elevator;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
import com.simibubi.create.foundation.networking.SimplePacketBase;
@ -41,7 +40,7 @@ public class ElevatorTargetFloorPacket extends SimplePacketBase {
.getEntity(entityId);
if (!(entityByID instanceof AbstractContraptionEntity ace))
return;
if (!(ace.getContraption()instanceof ElevatorContraption ec))
if (!(ace.getContraption() instanceof ElevatorContraption ec))
return;
if (ace.distanceToSqr(sender) > 50 * 50)
return;
@ -53,18 +52,12 @@ public class ElevatorTargetFloorPacket extends SimplePacketBase {
if (ec.isTargetUnreachable(targetY))
return;
for (BlockPos otherPos : elevatorColumn.getContacts()) {
BlockState otherState = level.getBlockState(otherPos);
if (!AllBlocks.ELEVATOR_CONTACT.has(otherState))
continue;
level.setBlock(otherPos, otherState.setValue(ElevatorContactBlock.CALLING, otherPos.getY() == targetY),
2);
AllBlocks.ELEVATOR_CONTACT.get()
.scheduleActivation(level, otherPos);
}
BlockPos pos = elevatorColumn.contactAt(targetY);
BlockState blockState = level.getBlockState(pos);
if (!(blockState.getBlock() instanceof ElevatorContactBlock ecb))
return;
elevatorColumn.target(targetY);
elevatorColumn.markDirty();
ecb.callToContactAndUpdate(elevatorColumn, blockState, level, pos);
});
return true;
}

View file

@ -201,7 +201,7 @@ public class PipeConnection {
particleSplashNextTick = false;
}
float flowSpeed = 1 / 32f + Mth.clamp(pressure.get(flow.inbound) / 512f, 0, 1) * 31 / 32f;
float flowSpeed = 1 / 32f + Mth.clamp(pressure.get(flow.inbound) / 128f, 0, 1) * 31 / 32f;
flow.progress.setValue(Math.min(flow.progress.getValue() + flowSpeed, 1));
if (flow.progress.getValue() >= 1)
flow.complete = true;

View file

@ -32,6 +32,7 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.ticks.TickPriority;
@ -107,20 +108,33 @@ public class PumpBlock extends DirectionalKineticBlock
Player player = context.getPlayer();
toPlace = ProperWaterloggedBlock.withWater(level, toPlace, pos);
if (player != null && player.isSteppingCarefully())
return toPlace;
Direction nearestLookingDirection = context.getNearestLookingDirection();
Direction targetDirection = context.getPlayer() != null && context.getPlayer()
.isShiftKeyDown() ? nearestLookingDirection : nearestLookingDirection.getOpposite();
Direction bestConnectedDirection = null;
double bestDistance = Double.MAX_VALUE;
for (Direction d : Iterate.directions) {
BlockPos adjPos = pos.relative(d);
BlockState adjState = level.getBlockState(adjPos);
if (!FluidPipeBlock.canConnectTo(level, adjPos, adjState, d))
continue;
toPlace = toPlace.setValue(FACING, d);
if (context.getClickedFace() == d.getOpposite())
break;
double distance = Vec3.atLowerCornerOf(d.getNormal())
.distanceTo(Vec3.atLowerCornerOf(targetDirection.getNormal()));
if (distance > bestDistance)
continue;
bestDistance = distance;
bestConnectedDirection = d;
}
return toPlace;
if (bestConnectedDirection == null)
return toPlace;
if (bestConnectedDirection.getAxis() == targetDirection.getAxis())
return toPlace;
if (player.isSteppingCarefully() && bestConnectedDirection.getAxis() != targetDirection.getAxis())
return toPlace;
return toPlace.setValue(FACING, bestConnectedDirection);
}
public static boolean isPump(BlockState state) {

View file

@ -21,8 +21,6 @@ import com.simibubi.create.foundation.utility.BlockFace;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Pair;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@ -38,15 +36,14 @@ import net.minecraftforge.fluids.capability.IFluidHandler;
public class PumpBlockEntity extends KineticBlockEntity {
LerpedFloat arrowDirection;
Couple<MutableBoolean> sidesToUpdate;
boolean pressureUpdate;
boolean reversed;
// Backcompat- flips any pump blockstate that loads with reversed=true
boolean scheduleFlip;
public PumpBlockEntity(BlockEntityType<?> typeIn, BlockPos pos, BlockState state) {
super(typeIn, pos, state);
arrowDirection = LerpedFloat.linear()
.startWithValue(1);
sidesToUpdate = Couple.create(MutableBoolean::new);
}
@ -58,55 +55,36 @@ public class PumpBlockEntity extends KineticBlockEntity {
registerAwardables(behaviours, AllAdvancements.PUMP);
}
@Override
public void initialize() {
super.initialize();
reversed = getSpeed() < 0;
}
@Override
public void tick() {
super.tick();
float speed = getSpeed();
if (level.isClientSide) {
if (speed == 0)
return;
arrowDirection.chase(speed >= 0 ? 1 : -1, .5f, Chaser.EXP);
arrowDirection.tickChaser();
if (!isVirtual())
return;
if (level.isClientSide && !isVirtual())
return;
if (scheduleFlip) {
level.setBlockAndUpdate(worldPosition,
getBlockState().setValue(PumpBlock.FACING, getBlockState().getValue(PumpBlock.FACING)
.getOpposite()));
scheduleFlip = false;
}
// if (pressureUpdate)
// updatePressureChange();
sidesToUpdate.forEachWithContext((update, isFront) -> {
if (update.isFalse())
return;
update.setFalse();
distributePressureTo(isFront ? getFront() : getFront().getOpposite());
});
if (speed == 0)
return;
if (speed < 0 != reversed) {
reversed = speed < 0;
updatePressureChange();
return;
}
}
@Override
public void onSpeedChanged(float previousSpeed) {
super.onSpeedChanged(previousSpeed);
if (previousSpeed == getSpeed())
if (Math.abs(previousSpeed) == Math.abs(getSpeed()))
return;
if (speed != 0) {
reversed = speed < 0;
if (speed != 0)
award(AllAdvancements.PUMP);
}
if (level.isClientSide && !isVirtual())
return;
@ -126,6 +104,13 @@ public class PumpBlockEntity extends KineticBlockEntity {
sidesToUpdate.forEach(MutableBoolean::setTrue);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
if (compound.getBoolean("Reversed"))
scheduleFlip = true;
}
protected void distributePressureTo(Direction side) {
if (getSpeed() == 0)
return;
@ -216,7 +201,7 @@ public class PumpBlockEntity extends KineticBlockEntity {
float pressure = Math.abs(getSpeed());
for (Set<BlockFace> set : validFaces.values()) {
int parallelBranches = set.size();
int parallelBranches = Math.max(1, set.size() - 1);
for (BlockFace face : set) {
BlockPos pipePos = face.getPos();
Direction pipeSide = face.getFace();
@ -309,18 +294,6 @@ public class PumpBlockEntity extends KineticBlockEntity {
return FluidPropagator.isOpenEnd(world, blockFace.getPos(), face);
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
compound.putBoolean("Reversed", reversed);
super.write(compound, clientPacket);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
reversed = compound.getBoolean("Reversed");
super.read(compound, clientPacket);
}
public void updatePipesOnSide(Direction side) {
if (!isSideAccessible(side))
return;
@ -359,7 +332,7 @@ public class PumpBlockEntity extends KineticBlockEntity {
}
public boolean isPullingOnSide(boolean front) {
return front == reversed;
return !front;
}
class PumpFluidTransferBehaviour extends FluidTransportBehaviour {

View file

@ -3,74 +3,28 @@ package com.simibubi.create.content.contraptions.fluids;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.materials.model.ModelData;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
import com.simibubi.create.content.contraptions.base.flwdata.RotatingData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class PumpCogInstance extends SingleRotatingInstance<PumpBlockEntity> implements DynamicInstance {
private final ModelData[] arrows = new ModelData[2];
private final Direction direction = blockState.getValue(PumpBlock.FACING);
public PumpCogInstance(MaterialManager materialManager, PumpBlockEntity blockEntity) {
super(materialManager, blockEntity);
}
@Override
public void init() {
super.init();
materialManager.defaultSolid()
.material(Materials.TRANSFORMED)
.getModel(AllPartialModels.MECHANICAL_PUMP_ARROW, blockState)
.createInstances(arrows);
public PumpCogInstance(MaterialManager materialManager, PumpBlockEntity blockEntity) {
super(materialManager, blockEntity);
}
@Override
public void beginFrame() {}
@Override
public void beginFrame() {
float angle = Mth.lerp(blockEntity.arrowDirection.getValue(AnimationTickHolder.getPartialTicks()), 0, 90) - 90;
for (int i = 0, arrowsLength = arrows.length; i < arrowsLength; i++) {
arrows[i].loadIdentity()
.translate(getInstancePosition())
.centre()
.rotateY(AngleHelper.horizontalAngle(direction) + 180)
.rotateX(-AngleHelper.verticalAngle(direction) - 90)
.unCentre()
.translate(.5, 14 / 16f, .5)
.rotateY(90 * i)
.rotateZ(angle)
.translateBack(.5, 14 / 16f, .5);
}
}
@Override
public void updateLight() {
super.updateLight();
relight(pos, arrows);
}
@Override
protected Instancer<RotatingData> getModel() {
protected Instancer<RotatingData> getModel() {
BlockState referenceState = blockEntity.getBlockState();
Direction facing = referenceState.getValue(BlockStateProperties.FACING);
return getRotatingMaterial().getModel(AllPartialModels.MECHANICAL_PUMP_COG, referenceState, facing);
}
@Override
public void remove() {
super.remove();
for (ModelData arrow : arrows) {
arrow.delete();
}
}
}

View file

@ -1,20 +1,12 @@
package com.simibubi.create.content.contraptions.fluids;
import com.jozufozu.flywheel.backend.Backend;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.base.KineticBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AngleHelper;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
public class PumpRenderer extends KineticBlockEntityRenderer<PumpBlockEntity> {
@ -22,30 +14,6 @@ public class PumpRenderer extends KineticBlockEntityRenderer<PumpBlockEntity> {
super(context);
}
@Override
protected void renderSafe(PumpBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) {
super.renderSafe(be, partialTicks, ms, buffer, light, overlay);
if (Backend.canUseInstancing(be.getLevel())) return;
Vec3 rotationOffset = new Vec3(.5, 14 / 16f, .5);
BlockState blockState = be.getBlockState();
float angle = Mth.lerp(be.arrowDirection.getValue(partialTicks), 0, 90) - 90;
SuperByteBuffer arrow = CachedBufferer.partial(AllPartialModels.MECHANICAL_PUMP_ARROW, blockState);
for (float yRot : new float[] { 0, 90 }) {
Direction direction = blockState.getValue(PumpBlock.FACING);
arrow.centre()
.rotateY(AngleHelper.horizontalAngle(direction) + 180)
.rotateX(-AngleHelper.verticalAngle(direction) - 90)
.unCentre()
.translate(rotationOffset)
.rotateY(yRot)
.rotateZ(angle)
.translateBack(rotationOffset)
.light(light)
.renderInto(ms, buffer.getBuffer(RenderType.solid()));
}
}
@Override
protected SuperByteBuffer getRotatedModel(PumpBlockEntity be, BlockState state) {
return CachedBufferer.partialFacing(AllPartialModels.MECHANICAL_PUMP_COG, state);

View file

@ -38,7 +38,6 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.core.NonNullList;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
@ -48,7 +47,6 @@ import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
@ -104,11 +102,6 @@ public class BeltBlock extends HorizontalKineticBlock implements IBE<BeltBlockEn
consumer.accept(new RenderProperties());
}
@Override
public void fillItemCategory(CreativeModeTab p_149666_1_, NonNullList<ItemStack> p_149666_2_) {
p_149666_2_.add(AllItems.BELT_CONNECTOR.asStack());
}
@Override
protected boolean areStatesKineticallyEquivalent(BlockState oldState, BlockState newState) {
return super.areStatesKineticallyEquivalent(oldState, newState)

Some files were not shown because too many files have changed in this diff Show more