1.19 launchpad and elevator, textures by Spearkiller (#3060)

* crude launchpad functionality

* added launchpad config

* gave launchpad ingame config, now speed's changeable

* made launchpad orientable

* added block drop

* added recipe + recipe advancement

* launchpad texture by Spearkiller

* added configurable launch interval

* added sound

* cleanup

* small cleanup

* minor refactoring: static to non static

* added elevator block (with launchpad functionality)

* added elevator functionality w/o mixin

* added blank elevator GUI

* added elevator textures by Spearkiller

* implemented down travelling

* implemented up travelling

* fixed energy usage

* minor refactoring: changed from static to non-static

* improved teleport command

* improved getting world limits

* minor refactoring, code improvement, documentation

* improved sound

* made going through blocks optional

* corrected prev commit, whoopsie

* Mixin KeyBinding

* minor formatting

* removed generated block loot

Co-authored-by: ayutac <fly.high.android@gmail.com>
Co-authored-by: modmuss50 <modmuss50@gmail.com>
This commit is contained in:
Ayutac 2022-11-20 17:28:46 +01:00 committed by GitHub
parent 193be50df8
commit 34012fd6a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 1004 additions and 6 deletions

View file

@ -0,0 +1,38 @@
/*
* This file is part of RebornCore, licensed under the MIT License (MIT).
*
* Copyright (c) 2021 TeamReborn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package reborncore.client;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
public interface ClientJumpEvent {
Event<ClientJumpEvent> EVENT = EventFactory.createArrayBacked(ClientJumpEvent.class, (listeners) -> () -> {
for (ClientJumpEvent callback : listeners) {
callback.jump();
}
});
void jump();
}

View file

@ -0,0 +1,45 @@
/*
* This file is part of RebornCore, licensed under the MIT License (MIT).
*
* Copyright (c) 2021 TeamReborn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package reborncore.client.mixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.InputUtil;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import reborncore.client.ClientJumpEvent;
@Mixin(KeyBinding.class)
public abstract class MixinKeyBinding {
@Inject(method = "onKeyPressed", at = @At(value = "FIELD", target = "Lnet/minecraft/client/option/KeyBinding;timesPressed:I"), locals = LocalCapture.CAPTURE_FAILHARD)
private static void onKeyPressed(InputUtil.Key key, CallbackInfo ci, KeyBinding keyBinding) {
if (keyBinding == MinecraftClient.getInstance().options.jumpKey) {
ClientJumpEvent.EVENT.invoker().jump();
}
}
}

View file

@ -4,7 +4,8 @@
"compatibilityLevel": "JAVA_17",
"client": [
"MixinDebugRenderer",
"MixinGameRenderer"
"MixinGameRenderer",
"MixinKeyBinding"
],
"injectors": {
"defaultRequire": 1

View file

@ -22,3 +22,4 @@ accessible field net/minecraft/block/FluidBlock fluid Lnet/minecraft
accessible method net/minecraft/world/gen/foliage/FoliagePlacerType register (Ljava/lang/String;Lcom/mojang/serialization/Codec;)Lnet/minecraft/world/gen/foliage/FoliagePlacerType;
accessible method net/minecraft/recipe/RecipeManager getAllOfType (Lnet/minecraft/recipe/RecipeType;)Ljava/util/Map;
accessible field net/minecraft/screen/ScreenHandler listeners Ljava/util/List;
accessible field net/minecraft/entity/LivingEntity jumping Z

View file

@ -50,6 +50,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import org.jetbrains.annotations.Nullable;
import reborncore.client.ClientJumpEvent;
import reborncore.client.gui.builder.GuiBase;
import reborncore.client.multiblock.MultiblockRenderer;
import reborncore.common.powerSystem.RcEnergyItem;
@ -57,6 +58,7 @@ import reborncore.common.util.ItemUtils;
import team.reborn.energy.api.base.SimpleBatteryItem;
import techreborn.client.ClientGuiType;
import techreborn.client.ClientboundPacketHandlers;
import techreborn.client.events.ClientJumpHandler;
import techreborn.client.events.StackToolTipHandler;
import techreborn.client.render.DynamicBucketBakedModel;
import techreborn.client.render.DynamicCellBakedModel;
@ -245,6 +247,8 @@ public class TechRebornClient implements ClientModInitializer {
);
ClientGuiType.validate();
ClientJumpEvent.EVENT.register(new ClientJumpHandler());
}
private static <T extends Item> void registerPredicateProvider(Class<T> itemClass, Identifier identifier, ItemModelPredicateProvider<T> modelPredicateProvider) {

View file

@ -26,7 +26,6 @@ package techreborn.client;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.gui.screen.ingame.HandledScreens;
import net.minecraft.util.Identifier;
@ -45,6 +44,7 @@ import techreborn.blockentity.machine.multiblock.*;
import techreborn.blockentity.machine.tier0.block.BlockBreakerBlockEntity;
import techreborn.blockentity.machine.tier0.block.BlockPlacerBlockEntity;
import techreborn.blockentity.machine.tier1.*;
import techreborn.blockentity.machine.tier2.LaunchpadBlockEntity;
import techreborn.blockentity.machine.tier3.ChunkLoaderBlockEntity;
import techreborn.blockentity.machine.tier3.IndustrialCentrifugeBlockEntity;
import techreborn.blockentity.machine.tier3.MatterFabricatorBlockEntity;
@ -113,6 +113,8 @@ public class ClientGuiType<T extends BlockEntity> {
public static final ClientGuiType<PlayerDetectorBlockEntity> PLAYER_DETECTOR = register(GuiType.PLAYER_DETECTOR, GuiPlayerDetector::new);
public static final ClientGuiType<BlockBreakerBlockEntity> BLOCK_BREAKER = register(GuiType.BLOCK_BREAKER, GuiBlockBreaker::new);
public static final ClientGuiType<BlockPlacerBlockEntity> BLOCK_PLACER = register(GuiType.BLOCK_PLACER, GuiBlockPlacer::new);
public static final ClientGuiType<LaunchpadBlockEntity> LAUNCHPAD = register(GuiType.LAUNCHPAD, GuiLaunchpad::new);
public static final ClientGuiType<ElevatorBlockEntity> ELEVATOR = register(GuiType.ELEVATOR, GuiElevator::new);
private static <T extends BlockEntity> ClientGuiType<T> register(GuiType<T> type, GuiFactory<T> factory) {
return new ClientGuiType<>(type, factory);

View file

@ -0,0 +1,50 @@
/*
* This file is part of TechReborn, licensed under the MIT License (MIT).
*
* Copyright (c) 2020 TechReborn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package techreborn.client.events;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import reborncore.client.ClientJumpEvent;
import reborncore.client.ClientNetworkManager;
import techreborn.blockentity.machine.tier1.ElevatorBlockEntity;
import techreborn.packets.ServerboundPackets;
public class ClientJumpHandler implements ClientJumpEvent {
@Override
public void jump() {
ClientPlayerEntity player = MinecraftClient.getInstance().player;
if (player == null) {
return;
}
BlockEntity blockEntity = player.getWorld().getBlockEntity(player.getBlockPos().down());
if (blockEntity instanceof ElevatorBlockEntity) {
ClientNetworkManager.sendToServer(ServerboundPackets.createPacketJump(player.getBlockPos()));
}
}
}

View file

@ -0,0 +1,50 @@
/*
* This file is part of TechReborn, licensed under the MIT License (MIT).
*
* Copyright (c) 2020 TechReborn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package techreborn.client.gui;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerEntity;
import reborncore.client.gui.builder.GuiBase;
import reborncore.common.screen.BuiltScreenHandler;
import techreborn.blockentity.machine.tier1.ElevatorBlockEntity;
public class GuiElevator extends GuiBase<BuiltScreenHandler> {
ElevatorBlockEntity blockEntity;
public GuiElevator(int syncID, final PlayerEntity player, final ElevatorBlockEntity blockEntity) {
super(player, blockEntity, blockEntity.createScreenHandler(syncID, player));
this.blockEntity = blockEntity;
}
@Override
protected void drawForeground(MatrixStack matrixStack, final int mouseX, final int mouseY) {
super.drawForeground(matrixStack, mouseX, mouseY);
final Layer layer = Layer.FOREGROUND;
builder.drawMultiEnergyBar(matrixStack, this, 9, 19, (int) blockEntity.getEnergy(), (int) blockEntity.getMaxStoredPower(), mouseX, mouseY, 0, layer);
}
}

View file

@ -0,0 +1,79 @@
/*
* This file is part of TechReborn, licensed under the MIT License (MIT).
*
* Copyright (c) 2020 TechReborn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package techreborn.client.gui;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.text.Text;
import reborncore.client.ClientNetworkManager;
import reborncore.client.gui.builder.GuiBase;
import reborncore.client.gui.builder.widget.GuiButtonUpDown;
import reborncore.common.screen.BuiltScreenHandler;
import techreborn.blockentity.machine.tier2.LaunchpadBlockEntity;
import techreborn.packets.ServerboundPackets;
public class GuiLaunchpad extends GuiBase<BuiltScreenHandler> {
LaunchpadBlockEntity blockEntity;
public GuiLaunchpad(int syncID, final PlayerEntity player, final LaunchpadBlockEntity blockEntity) {
super(player, blockEntity, blockEntity.createScreenHandler(syncID, player));
this.blockEntity = blockEntity;
}
private void onClick(int amount) {
ClientNetworkManager.sendToServer(ServerboundPackets.createPacketLaunchpad(amount, blockEntity));
}
@Override
public void init() {
super.init();
addDrawableChild(new GuiButtonUpDown(x + 64, y + 40, this, b -> onClick(LaunchpadBlockEntity.MAX_SELECTION), GuiButtonUpDown.UpDownButtonType.FASTFORWARD));
addDrawableChild(new GuiButtonUpDown(x + 64 + 12, y + 40, this, b -> onClick(1), GuiButtonUpDown.UpDownButtonType.FORWARD));
addDrawableChild(new GuiButtonUpDown(x + 64 + 24, y + 40, this, b -> onClick(-1), GuiButtonUpDown.UpDownButtonType.REWIND));
addDrawableChild(new GuiButtonUpDown(x + 64 + 36, y + 40, this, b -> onClick(-LaunchpadBlockEntity.MAX_SELECTION), GuiButtonUpDown.UpDownButtonType.FASTREWIND));
}
@Override
protected void drawBackground(MatrixStack matrixStack, float partialTicks, int mouseX, int mouseY) {
super.drawBackground(matrixStack, partialTicks, mouseX, mouseY);
final Layer layer = Layer.BACKGROUND;
if (hideGuiElements()) return;
Text text = Text.literal("Launch Speed: ").append(Text.translatable(blockEntity.selectedTranslationKey()));
drawCentredText(matrixStack, text, 25, 4210752, layer);
}
@Override
protected void drawForeground(MatrixStack matrixStack, final int mouseX, final int mouseY) {
super.drawForeground(matrixStack, mouseX, mouseY);
final Layer layer = Layer.FOREGROUND;
builder.drawMultiEnergyBar(matrixStack, this, 9, 19, (int) blockEntity.getEnergy(), (int) blockEntity.getMaxStoredPower(), mouseX, mouseY, 0, layer);
}
}

View file

@ -56,6 +56,7 @@ import techreborn.blockentity.machine.multiblock.*;
import techreborn.blockentity.machine.tier0.block.BlockBreakerBlockEntity;
import techreborn.blockentity.machine.tier0.block.BlockPlacerBlockEntity;
import techreborn.blockentity.machine.tier1.*;
import techreborn.blockentity.machine.tier2.LaunchpadBlockEntity;
import techreborn.blockentity.machine.tier3.ChunkLoaderBlockEntity;
import techreborn.blockentity.machine.tier3.IndustrialCentrifugeBlockEntity;
import techreborn.blockentity.machine.tier3.MatterFabricatorBlockEntity;
@ -121,6 +122,8 @@ public final class GuiType<T extends BlockEntity> implements IMachineGuiHandler
public static final GuiType<PlayerDetectorBlockEntity> PLAYER_DETECTOR = register("player_detector");
public static final GuiType<BlockBreakerBlockEntity> BLOCK_BREAKER = register("block_breaker");
public static final GuiType<BlockPlacerBlockEntity> BLOCK_PLACER = register("block_placer");
public static final GuiType<LaunchpadBlockEntity> LAUNCHPAD = register("launchpad");
public static final GuiType<ElevatorBlockEntity> ELEVATOR = register("elevator");
private static <T extends BlockEntity> GuiType<T> register(String id) {
return register(new Identifier("techreborn", id));

View file

@ -0,0 +1,247 @@
/*
* This file is part of TechReborn, licensed under the MIT License (MIT).
*
* Copyright (c) 2020 TechReborn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package techreborn.blockentity.machine.tier1;
import net.fabricmc.fabric.api.dimension.v1.FabricDimensions;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.*;
import net.minecraft.world.TeleportTarget;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import reborncore.api.IToolDrop;
import reborncore.common.blockentity.MachineBaseBlockEntity;
import reborncore.common.blockentity.RedstoneConfiguration;
import reborncore.common.powerSystem.PowerAcceptorBlockEntity;
import reborncore.common.screen.BuiltScreenHandler;
import reborncore.common.screen.BuiltScreenHandlerProvider;
import reborncore.common.screen.builder.ScreenHandlerBuilder;
import techreborn.config.TechRebornConfig;
import techreborn.init.TRBlockEntities;
import techreborn.init.TRContent;
import java.util.List;
import java.util.Optional;
public class ElevatorBlockEntity extends PowerAcceptorBlockEntity implements IToolDrop, BuiltScreenHandlerProvider {
public ElevatorBlockEntity(BlockPos pos, BlockState state) {
super(TRBlockEntities.ELEVATOR, pos, state);
}
/**
* @param targetPos the position of another elevator
*/
public boolean isRunning(final BlockPos targetPos) {
// null-safe because of the following instanceof
final BlockEntity entity = getWorld().getBlockEntity(targetPos);
if (!(entity instanceof ElevatorBlockEntity)) {
return false;
}
return ((ElevatorBlockEntity)entity).getStored() > 0;
}
/**
* @param targetPos the position will be checked to be an elevator or air
*/
public boolean isAirOrElevator(final BlockPos targetPos) {
return getWorld().isAir(targetPos) || getWorld().getBlockEntity(targetPos) instanceof ElevatorBlockEntity;
}
/**
* @param targetPos the position of another elevator
*/
public boolean isFree(final BlockPos targetPos) {
return getWorld().getBlockState(targetPos.up()).isAir() && getWorld().getBlockState(targetPos.up().up()).isAir();
}
/**
* @param targetPos the position of another elevator
*/
public boolean isValidTarget(final BlockPos targetPos) {
return isRunning(targetPos) && isFree(targetPos);
}
public Optional<BlockPos> nextUpElevator() {
BlockPos upPos = getPos().up().up();
if (!TechRebornConfig.allowElevatingThroughBlocks && (!isAirOrElevator(getPos().up()) || !isAirOrElevator(getPos().up().up()))) {
return Optional.empty();
}
do {
upPos = upPos.up();
if (!TechRebornConfig.allowElevatingThroughBlocks && !isAirOrElevator(upPos)) {
return Optional.empty();
}
} while (upPos.getY() <= getWorld().getTopY() && !isValidTarget(upPos));
if (upPos.getY() < getWorld().getTopY() || isValidTarget(upPos)) {
return Optional.of(upPos);
}
return Optional.empty();
}
public Optional<BlockPos> nextDownElevator() {
BlockPos downPos = getPos().down().down();
if (!TechRebornConfig.allowElevatingThroughBlocks && (!isAirOrElevator(getPos().down()) || !isAirOrElevator(getPos().down().down()))) {
return Optional.empty();
}
do {
downPos = downPos.down();
if (!TechRebornConfig.allowElevatingThroughBlocks && !isAirOrElevator(downPos)) {
return Optional.empty();
}
} while (downPos.getY() >= getWorld().getBottomY() && !isValidTarget(downPos));
if (downPos.getY() > getWorld().getBottomY() || isValidTarget(downPos)) {
return Optional.of(downPos);
}
return Optional.empty();
}
/**
* @param targetPos the position of another elevator
*/
public int energyCost(final BlockPos targetPos) {
return Math.max(Math.abs(targetPos.getY()-getPos().getY())*TechRebornConfig.elevatorEnergyPerBlock,0);
}
/**
* @param targetPos the position <strong>over</strong> another elevator
*/
protected boolean teleport(final PlayerEntity player, final BlockPos targetPos) {
if (!(getWorld() instanceof ServerWorld)) {
return false;
}
final int energy = energyCost(targetPos);
if (getStored() < energy) {
return false;
}
playTeleportSoundAt(getPos());
FabricDimensions.teleport(player, (ServerWorld)getWorld(),
new TeleportTarget(Vec3d.ofBottomCenter(new Vec3i(targetPos.getX(), targetPos.getY(), targetPos.getZ())), Vec3d.ZERO, player.getYaw(), player.getPitch()));
useEnergy(energy);
playTeleportSoundAt(targetPos);
return true;
}
protected void playTeleportSoundAt(final BlockPos targetPos) {
getWorld().playSound(null, targetPos, SoundEvents.ENTITY_ENDERMAN_TELEPORT, SoundCategory.BLOCKS, 1f, 1f);
}
public void teleportUp(final PlayerEntity player) {
if (!this.pos.isWithinDistance(player.getPos(), 5) && player.world == this.world) {
// Ensure the player is close to the elevator and in the same world.
return;
}
Optional<BlockPos> upTarget = nextUpElevator();
if (upTarget.isEmpty()) {
return;
}
if (teleport(player, upTarget.get().up())) {
player.setJumping(false);
}
}
// PowerAcceptorBlockEntity
@Override
public void tick(World world, BlockPos pos, BlockState state, MachineBaseBlockEntity blockEntity) {
super.tick(world, pos, state, blockEntity);
if (!(world instanceof ServerWorld) || getStored() <= 0 || !isActive(RedstoneConfiguration.POWER_IO)) {
return;
}
// teleporting up must be done via mixin for now
Optional<BlockPos> downTarget = null;
List<PlayerEntity> players = world.getNonSpectatingEntities(PlayerEntity.class, new Box(0d,1d,0d,1d,2d,1d).offset(pos));
if (players.size() == 0) {
return;
}
for (PlayerEntity player : players) {
if (player.isSneaking()) {
if (downTarget == null) {
downTarget = nextDownElevator();
}
if (downTarget.isEmpty()) {
continue;
}
if (teleport(player, downTarget.get().up())) {
player.setSneaking(false);
}
}
}
}
@Override
public long getBaseMaxPower() {
return TechRebornConfig.elevatorMaxEnergy;
}
@Override
public boolean canProvideEnergy(@Nullable Direction side) {
return false;
}
@Override
public long getBaseMaxOutput() {
return 0;
}
@Override
public long getBaseMaxInput() {
return TechRebornConfig.elevatorMaxInput;
}
// MachineBaseBlockEntity
@Override
public boolean hasSlotConfig() {
return false;
}
@Override
public boolean canBeUpgraded() {
return false;
}
// IToolDrop
@Override
public ItemStack getToolDrop(PlayerEntity p0) {
return TRContent.Machine.ELEVATOR.getStack();
}
// BuiltScreenHandlerProvider
@Override
public BuiltScreenHandler createScreenHandler(int syncID, PlayerEntity player) {
return new ScreenHandlerBuilder("elevator")
.player(player.getInventory())
.inventory().hotbar().addInventory()
.blockEntity(this)
.syncEnergyValue()
.addInventory().create(this, syncID);
}
}

View file

@ -0,0 +1,202 @@
/*
* This file is part of TechReborn, licensed under the MIT License (MIT).
*
* Copyright (c) 2020 TechReborn
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package techreborn.blockentity.machine.tier2;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import reborncore.api.IToolDrop;
import reborncore.common.blockentity.MachineBaseBlockEntity;
import reborncore.common.blockentity.RedstoneConfiguration;
import reborncore.common.powerSystem.PowerAcceptorBlockEntity;
import reborncore.common.screen.BuiltScreenHandler;
import reborncore.common.screen.BuiltScreenHandlerProvider;
import reborncore.common.screen.builder.ScreenHandlerBuilder;
import techreborn.config.TechRebornConfig;
import techreborn.init.TRBlockEntities;
import techreborn.init.TRContent;
import java.util.List;
public class LaunchpadBlockEntity extends PowerAcceptorBlockEntity implements IToolDrop, BuiltScreenHandlerProvider {
public static final int MAX_SELECTION = 3;
private int selection = TechRebornConfig.launchpadDefaultSelection;
public LaunchpadBlockEntity(BlockPos pos, BlockState state) {
super(TRBlockEntities.LAUNCHPAD, pos, state);
}
public void handleGuiInputFromClient(int amount) {
selection += amount;
ensureSelectionInRange();
}
public void ensureSelectionInRange() {
if (selection > MAX_SELECTION) {
selection = MAX_SELECTION;
}
if (selection <= 0) {
selection = 0;
}
}
public double selectedSpeed() {
return switch(selection) {
case 0 -> TechRebornConfig.launchpadSpeedLow;
case 1 -> TechRebornConfig.launchpadSpeedMedium;
case 2 -> TechRebornConfig.launchpadSpeedHigh;
case MAX_SELECTION -> TechRebornConfig.launchpadSpeedExtreme;
default -> throw new IllegalArgumentException("Impossible launchpad selection value!");
};
}
public int selectedEnergyCost() {
return switch(selection) {
case 0 -> TechRebornConfig.launchpadEnergyLow;
case 1 -> TechRebornConfig.launchpadEnergyMedium;
case 2 -> TechRebornConfig.launchpadEnergyHigh;
case MAX_SELECTION -> TechRebornConfig.launchpadEnergyExtreme;
default -> throw new IllegalArgumentException("Impossible launchpad selection value!");
};
}
public String selectedTranslationKey() {
return switch(selection) {
case 0 -> "techreborn.message.info.block.techreborn.launchpad.low";
case 1 -> "techreborn.message.info.block.techreborn.launchpad.medium";
case 2 -> "techreborn.message.info.block.techreborn.launchpad.high";
case MAX_SELECTION -> "techreborn.message.info.block.techreborn.launchpad.extreme";
default -> throw new IllegalArgumentException("Impossible launchpad selection value!");
};
}
// PowerAcceptorBlockEntity
@Override
public void tick(World world, BlockPos pos, BlockState state, MachineBaseBlockEntity blockEntity) {
super.tick(world, pos, state, blockEntity);
if (world == null || getStored() <= 0 || !isActive(RedstoneConfiguration.POWER_IO)) {
return;
}
if (world.getTime() % TechRebornConfig.launchpadInterval != 0) {
return;
}
ensureSelectionInRange();
final double speed = selectedSpeed();
final int energyCost = selectedEnergyCost();
if (getStored() > energyCost) {
List<Entity> entities = world.getNonSpectatingEntities(Entity.class, new Box(0d,1d,0d,1d,2d,1d).offset(pos));
if (entities.size() == 0) {
return;
}
world.playSound(null, pos, SoundEvents.BLOCK_PISTON_EXTEND, SoundCategory.BLOCKS, 1f, 1f);
for (Entity entity : entities) {
entity.addVelocity(0d, speed, 0d);
}
useEnergy(energyCost);
}
}
@Override
public long getBaseMaxPower() {
return TechRebornConfig.launchpadMaxEnergy;
}
@Override
public boolean canProvideEnergy(@Nullable Direction side) {
return false;
}
@Override
public long getBaseMaxOutput() {
return 0;
}
@Override
public long getBaseMaxInput() {
return TechRebornConfig.launchpadMaxInput;
}
@Override
public void readNbt(NbtCompound tag) {
super.readNbt(tag);
selection = tag.getInt("selection");
}
@Override
public void writeNbt(NbtCompound tag) {
super.writeNbt(tag);
tag.putInt("selection", selection);
}
// MachineBaseBlockEntity
@Override
public boolean hasSlotConfig() {
return false;
}
@Override
public boolean canBeUpgraded() {
return false;
}
// IToolDrop
@Override
public ItemStack getToolDrop(PlayerEntity p0) {
return TRContent.Machine.LAUNCHPAD.getStack();
}
// BuiltScreenHandlerProvider
@Override
public BuiltScreenHandler createScreenHandler(int syncID, PlayerEntity player) {
return new ScreenHandlerBuilder("launchpad")
.player(player.getInventory())
.inventory().hotbar().addInventory()
.blockEntity(this)
.syncEnergyValue()
.sync(this::getSelection, this::setSelection)
.addInventory().create(this, syncID);
}
public int getSelection() {
return selection;
}
public void setSelection(int selection) {
this.selection = selection;
}
}

View file

@ -585,6 +585,54 @@ public class TechRebornConfig {
@Config(config = "machines", category = "block_placer", key = "BlockPlacerBaseBreakTime", comment = "How many ticks a block of hardness 1 requires to be placed")
public static int blockPlacerBaseBreakTime = 100;
@Config(config = "machines", category = "launchpad", key = "LaunchpadMaxInput", comment = "Launchpad Max Input (Energy per tick)")
public static int launchpadMaxInput = 128;
@Config(config = "machines", category = "launchpad", key = "LaunchpadMaxEnergy", comment = "Launchpad Max Energy")
public static int launchpadMaxEnergy = 40_000;
@Config(config = "machines", category = "launchpad", key = "LaunchpadSpeedLow", comment = "Launchpad Low Speed")
public static double launchpadSpeedLow = 1d;
@Config(config = "machines", category = "launchpad", key = "LaunchpadSpeedMedium", comment = "Launchpad Medium Speed")
public static double launchpadSpeedMedium = 3d;
@Config(config = "machines", category = "launchpad", key = "LaunchpadSpeedHigh", comment = "Launchpad High Speed")
public static double launchpadSpeedHigh = 5d;
@Config(config = "machines", category = "launchpad", key = "LaunchpadSpeedExtreme", comment = "Launchpad Extreme Speed")
public static double launchpadSpeedExtreme = 10d;
@Config(config = "machines", category = "launchpad", key = "LaunchpadEnergyLow", comment = "Launchpad Low Energy")
public static int launchpadEnergyLow = 1_000;
@Config(config = "machines", category = "launchpad", key = "LaunchpadEnergyMedium", comment = "Launchpad Medium Energy")
public static int launchpadEnergyMedium = 6_000;
@Config(config = "machines", category = "launchpad", key = "LaunchpadEnergyHigh", comment = "Launchpad High Energy")
public static int launchpadEnergyHigh = 10_000;
@Config(config = "machines", category = "launchpad", key = "LaunchpadEnergyExtreme", comment = "Launchpad Extreme Energy")
public static int launchpadEnergyExtreme = 20_000;
@Config(config = "machines", category = "launchpad", key = "LaunchpadDefaultSelection", comment = "Launchpad Default Selection (0-3 for Low-Extreme)")
public static int launchpadDefaultSelection = 0;
@Config(config = "machines", category = "launchpad", key = "LaunchpadInterval", comment = "Launchpad Launch Interval in Ticks > 0")
public static int launchpadInterval = 100; // 5 seconds
@Config(config = "machines", category = "elevator", key = "ElevatorMaxInput", comment = "Elevator Max Input (Energy per tick)")
public static int elevatorMaxInput = 32;
@Config(config = "machines", category = "elevator", key = "ElevatorMaxEnergy", comment = "Elevator Max Energy")
public static int elevatorMaxEnergy = 1_000;
@Config(config = "machines", category = "elevator", key = "ElevatorEnergyPerBlock", comment = "Elevator Energy used per vertical block of transportation")
public static int elevatorEnergyPerBlock = 2;
@Config(config = "machines", category = "elevator", key = "AllowElevatingThroughBlocks", comment = "Allow elevating through blocks (i.e. non air)")
public static boolean allowElevatingThroughBlocks = true;
// Misc
@Config(config = "misc", category = "general", key = "IC2TransformersStyle", comment = "Input from dots side, output from other sides, like in IC2.")
public static boolean IC2TransformersStyle = true;

View file

@ -54,6 +54,7 @@ import techreborn.blockentity.machine.multiblock.casing.MachineCasingBlockEntity
import techreborn.blockentity.machine.tier0.block.BlockBreakerBlockEntity;
import techreborn.blockentity.machine.tier0.block.BlockPlacerBlockEntity;
import techreborn.blockentity.machine.tier1.*;
import techreborn.blockentity.machine.tier2.LaunchpadBlockEntity;
import techreborn.blockentity.machine.tier3.ChunkLoaderBlockEntity;
import techreborn.blockentity.machine.tier3.IndustrialCentrifugeBlockEntity;
import techreborn.blockentity.machine.tier3.MatterFabricatorBlockEntity;
@ -143,6 +144,8 @@ public class TRBlockEntities {
public static final BlockEntityType<GreenhouseControllerBlockEntity> GREENHOUSE_CONTROLLER = register(GreenhouseControllerBlockEntity::new, "greenhouse_controller", TRContent.Machine.GREENHOUSE_CONTROLLER);
public static final BlockEntityType<BlockBreakerBlockEntity> BLOCK_BREAKER = register(BlockBreakerBlockEntity::new, "block_breaker", TRContent.Machine.BLOCK_BREAKER);
public static final BlockEntityType<BlockPlacerBlockEntity> BLOCK_PLACER = register(BlockPlacerBlockEntity::new, "block_placer", TRContent.Machine.BLOCK_PLACER);
public static final BlockEntityType<LaunchpadBlockEntity> LAUNCHPAD = register(LaunchpadBlockEntity::new, "launchpad", TRContent.Machine.LAUNCHPAD);
public static final BlockEntityType<ElevatorBlockEntity> ELEVATOR = register(ElevatorBlockEntity::new, "elevator", TRContent.Machine.ELEVATOR);
public static <T extends BlockEntity> BlockEntityType<T> register(BiFunction<BlockPos, BlockState, T> supplier, String name, ItemConvertible... items) {
return register(supplier, name, Arrays.stream(items).map(itemConvertible -> Block.getBlockFromItem(itemConvertible.asItem())).toArray(Block[]::new));

View file

@ -61,6 +61,7 @@ import techreborn.blockentity.machine.multiblock.*;
import techreborn.blockentity.machine.tier0.block.BlockBreakerBlockEntity;
import techreborn.blockentity.machine.tier0.block.BlockPlacerBlockEntity;
import techreborn.blockentity.machine.tier1.*;
import techreborn.blockentity.machine.tier2.LaunchpadBlockEntity;
import techreborn.blockentity.machine.tier3.ChunkLoaderBlockEntity;
import techreborn.blockentity.machine.tier3.IndustrialCentrifugeBlockEntity;
import techreborn.blockentity.machine.tier3.MatterFabricatorBlockEntity;
@ -764,6 +765,8 @@ public class TRContent {
GREENHOUSE_CONTROLLER(new GenericMachineBlock(GuiType.GREENHOUSE_CONTROLLER, GreenhouseControllerBlockEntity::new)),
BLOCK_BREAKER(new GenericMachineBlock(GuiType.BLOCK_BREAKER, BlockBreakerBlockEntity::new)),
BLOCK_PLACER(new GenericMachineBlock(GuiType.BLOCK_PLACER, BlockPlacerBlockEntity::new)),
LAUNCHPAD(new GenericMachineBlock(GuiType.LAUNCHPAD, LaunchpadBlockEntity::new)),
ELEVATOR(new GenericMachineBlock(GuiType.ELEVATOR, ElevatorBlockEntity::new)),
DIESEL_GENERATOR(new GenericGeneratorBlock(GuiType.DIESEL_GENERATOR, DieselGeneratorBlockEntity::new)),
DRAGON_EGG_SYPHON(new GenericGeneratorBlock(null, DragonEggSyphonBlockEntity::new)),

View file

@ -35,8 +35,10 @@ import techreborn.TechReborn;
import techreborn.blockentity.machine.iron.IronFurnaceBlockEntity;
import techreborn.blockentity.machine.multiblock.FusionControlComputerBlockEntity;
import techreborn.blockentity.machine.tier1.AutoCraftingTableBlockEntity;
import techreborn.blockentity.machine.tier1.ElevatorBlockEntity;
import techreborn.blockentity.machine.tier1.PlayerDetectorBlockEntity;
import techreborn.blockentity.machine.tier1.RollingMachineBlockEntity;
import techreborn.blockentity.machine.tier2.LaunchpadBlockEntity;
import techreborn.blockentity.machine.tier3.ChunkLoaderBlockEntity;
import techreborn.blockentity.storage.energy.AdjustableSUBlockEntity;
import techreborn.blockentity.storage.item.StorageUnitBaseBlockEntity;
@ -54,6 +56,8 @@ public class ServerboundPackets {
public static final Identifier CHUNKLOADER = new Identifier(TechReborn.MOD_ID, "chunkloader");
public static final Identifier EXPERIENCE = new Identifier(TechReborn.MOD_ID, "experience");
public static final Identifier DETECTOR_RADIUS = new Identifier(TechReborn.MOD_ID, "detector_radius");
public static final Identifier LAUNCH_SPEED = new Identifier(TechReborn.MOD_ID, "launch_speed");
public static final Identifier JUMP = new Identifier(TechReborn.MOD_ID, "jump");
public static void init() {
NetworkManager.registerServerBoundHandler(AESU, (server, player, handler, buf, responseSender) -> {
@ -171,6 +175,29 @@ public class ServerboundPackets {
}
});
}));
NetworkManager.registerServerBoundHandler(LAUNCH_SPEED, ((server, player, handler, buf, responseSender) -> {
BlockPos pos = buf.readBlockPos();
int buttonAmount = buf.readInt();
server.execute(() -> {
BlockEntity blockEntity = player.world.getBlockEntity(pos);
if (blockEntity instanceof LaunchpadBlockEntity) {
((LaunchpadBlockEntity) blockEntity).handleGuiInputFromClient(buttonAmount);
}
});
}));
NetworkManager.registerServerBoundHandler(JUMP, (server, player, handler, buf, responseSender) -> {
BlockPos pos = buf.readBlockPos();
server.execute(() -> {
BlockEntity blockEntity = player.getWorld().getBlockEntity(pos.down());
if (blockEntity instanceof ElevatorBlockEntity elevator) {
elevator.teleportUp(player);
}
});
});
}
public static IdentifiedPacket createPacketAesu(int buttonID, boolean shift, boolean ctrl, AdjustableSUBlockEntity blockEntity) {
@ -235,4 +262,17 @@ public class ServerboundPackets {
buf.writeInt(buttonAmount);
});
}
public static IdentifiedPacket createPacketLaunchpad(int buttonAmount, LaunchpadBlockEntity blockEntity) {
return NetworkManager.createServerBoundPacket(LAUNCH_SPEED, buf -> {
buf.writeBlockPos(blockEntity.getPos());
buf.writeInt(buttonAmount);
});
}
public static IdentifiedPacket createPacketJump(BlockPos pos) {
return NetworkManager.createServerBoundPacket(JUMP, packetBuffer -> {
packetBuffer.writeBlockPos(pos);
});
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "techreborn:block/machines/tier1_machines/elevator" }
}
}

View file

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "techreborn:block/machines/tier2_machines/launchpad" }
}
}

View file

@ -32,6 +32,8 @@
"block.techreborn.matter_fabricator": "Matter Fabricator",
"block.techreborn.implosion_compressor": "Implosion Compressor",
"block.techreborn.industrial_grinder": "Industrial Grinder",
"block.techreborn.launchpad": "Launchpad",
"block.techreborn.elevator": "Elevator",
"block.techreborn.chunk_loader": "Industrial Chunkloader",
"block.techreborn.diesel_generator": "Diesel Generator",
"block.techreborn.drain": "Drain",
@ -842,6 +844,12 @@
"techreborn.message.info.block.techreborn.drain": "Pulls any fluid directly above it, pairs nicely with a tank unit underneath",
"techreborn.message.info.block.techreborn.block_breaker": "Breaks any block directly in front of it",
"techreborn.message.info.block.techreborn.block_placer": "Places blocks from its inventory directly in front of it",
"techreborn.message.info.block.techreborn.launchpad": "Launches entities into the air",
"techreborn.message.info.block.techreborn.launchpad.low": "Low",
"techreborn.message.info.block.techreborn.launchpad.medium": "Medium",
"techreborn.message.info.block.techreborn.launchpad.high": "High",
"techreborn.message.info.block.techreborn.launchpad.extreme": "Extreme",
"techreborn.message.info.block.techreborn.elevator": "Teleports player up or down to the next free elevator block",
"keys.techreborn.category": "TechReborn Category",
"keys.techreborn.config": "Config",

View file

@ -0,0 +1,9 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"up": "techreborn:block/machines/tier1_machines/elevator_end",
"down": "techreborn:block/machines/tier1_machines/elevator_end",
"side": "techreborn:block/machines/tier1_machines/elevator_side",
"front": "techreborn:block/machines/tier1_machines/elevator_side"
}
}

View file

@ -0,0 +1,9 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"up": "techreborn:block/machines/tier2_machines/launchpad_top",
"down": "techreborn:block/machines/tier2_machines/machine_bottom",
"side": "techreborn:block/machines/tier2_machines/launchpad_side",
"front": "techreborn:block/machines/tier2_machines/launchpad_side"
}
}

View file

@ -0,0 +1,3 @@
{
"parent": "techreborn:block/machines/tier1_machines/elevator"
}

View file

@ -0,0 +1,3 @@
{
"parent": "techreborn:block/machines/tier2_machines/launchpad"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

View file

@ -0,0 +1,43 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"techreborn:crafting_table/machine/elevator"
]
},
"criteria": {
"has_enderpearl_dusts": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"tag": "c:enderpearl_dusts"
}
]
}
},
"has_zinc_plate": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"tag": "c:zinc_plates"
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "techreborn:crafting_table/machine/elevator"
}
}
},
"requirements": [
[
"has_enderpearl_dusts",
"has_zinc_plate",
"has_the_recipe"
]
]
}

View file

@ -0,0 +1,43 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"techreborn:crafting_table/machine/launchpad"
]
},
"criteria": {
"has_magnalium_plates": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"tag": "c:magnalium_plates"
}
]
}
},
"has_zinc_plate": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"tag": "c:zinc_plates"
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "techreborn:crafting_table/machine/launchpad"
}
}
},
"requirements": [
[
"has_magnalium_plates",
"has_zinc_plate",
"has_the_recipe"
]
]
}

View file

@ -0,0 +1,25 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"EEE",
"PFP",
"PCP"
],
"key": {
"C": {
"item": "techreborn:electronic_circuit"
},
"E": {
"tag": "c:ender_pearl_dusts"
},
"F": {
"item": "techreborn:basic_machine_frame"
},
"P": {
"tag": "c:zinc_plates"
}
},
"result": {
"item": "techreborn:launchpad"
}
}

View file

@ -0,0 +1,28 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"MMM",
"CPC",
"ZFZ"
],
"key": {
"C": {
"item": "techreborn:advanced_circuit"
},
"F": {
"item": "techreborn:advanced_machine_frame"
},
"M": {
"tag": "c:magnalium_plates"
},
"P": {
"item": "minecraft:piston"
},
"Z": {
"tag": "c:zinc_plates"
}
},
"result": {
"item": "techreborn:launchpad"
}
}

View file

@ -22,5 +22,6 @@ accessible field net/minecraft/block/FluidBlock fluid Lnet/minecraft
accessible method net/minecraft/world/gen/foliage/FoliagePlacerType register (Ljava/lang/String;Lcom/mojang/serialization/Codec;)Lnet/minecraft/world/gen/foliage/FoliagePlacerType;
accessible method net/minecraft/recipe/RecipeManager getAllOfType (Lnet/minecraft/recipe/RecipeType;)Ljava/util/Map;
accessible field net/minecraft/screen/ScreenHandler listeners Ljava/util/List;
accessible field net/minecraft/entity/LivingEntity jumping Z
# DO NOT EDIT THIS FILE, edit the RebornCore AW, it will automatically be coped to this one.