This commit is contained in:
parent
c41c42c5cc
commit
6d74e6b663
@ -30,7 +30,7 @@ Glowing Obsidian heals monsters and hurts everything else. It naturally generate
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
## Chest Boats
|
## Chest Boats
|
||||||
Right-Click a Boat with a Chest to place it in the Boat, you can also use an Ender Chest, Trapped Chest, or Shulker Box. Shift-Right-Click the Boat to open the Chest. You can also open the Chest inside the Boat by opening your inventory.
|
Right-Click a Boat with a Chest to place it in the Boat, you can also use an Ender Chest, Trapped Chest, Barrel, or Shulker Box. Shift-Right-Click the Boat to open the Chest. You can also open the Chest inside the Boat by opening your inventory.
|
||||||
|
|
||||||
## Difficulty Stages
|
## Difficulty Stages
|
||||||
Each player has a "personal" stage of an area, the highest online player's difficulty stage in an area will be the "effective" difficulty stage of that area.
|
Each player has a "personal" stage of an area, the highest online player's difficulty stage in an area will be the "effective" difficulty stage of that area.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.thebrokenrail.twine;
|
package com.thebrokenrail.twine;
|
||||||
|
|
||||||
|
import com.thebrokenrail.twine.advancement.BarrelBoatCriterion;
|
||||||
import com.thebrokenrail.twine.advancement.ChestBoatCriterion;
|
import com.thebrokenrail.twine.advancement.ChestBoatCriterion;
|
||||||
import com.thebrokenrail.twine.advancement.EnderChestBoatCriterion;
|
import com.thebrokenrail.twine.advancement.EnderChestBoatCriterion;
|
||||||
import com.thebrokenrail.twine.advancement.ShulkerBoxBoatCriterion;
|
import com.thebrokenrail.twine.advancement.ShulkerBoxBoatCriterion;
|
||||||
@ -8,7 +9,7 @@ import com.thebrokenrail.twine.block.GlowingObsidianBlock;
|
|||||||
import com.thebrokenrail.twine.item.BackpackItem;
|
import com.thebrokenrail.twine.item.BackpackItem;
|
||||||
import com.thebrokenrail.twine.item.DivinerItem;
|
import com.thebrokenrail.twine.item.DivinerItem;
|
||||||
import com.thebrokenrail.twine.mixin.CriteriaHook;
|
import com.thebrokenrail.twine.mixin.CriteriaHook;
|
||||||
import com.thebrokenrail.twine.util.BackpackScreenHandler;
|
import com.thebrokenrail.twine.util.backpack.BackpackScreenHandler;
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
|
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
|
||||||
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
|
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
|
||||||
@ -49,6 +50,7 @@ public class Twine implements ModInitializer {
|
|||||||
public static ChestBoatCriterion CHEST_BOAT_CRITERION = CriteriaHook.callRegister(new ChestBoatCriterion());
|
public static ChestBoatCriterion CHEST_BOAT_CRITERION = CriteriaHook.callRegister(new ChestBoatCriterion());
|
||||||
public static EnderChestBoatCriterion ENDER_CHEST_BOAT_CRITERION = CriteriaHook.callRegister(new EnderChestBoatCriterion());
|
public static EnderChestBoatCriterion ENDER_CHEST_BOAT_CRITERION = CriteriaHook.callRegister(new EnderChestBoatCriterion());
|
||||||
public static ShulkerBoxBoatCriterion SHULKER_BOX_BOAT_CRITERION = CriteriaHook.callRegister(new ShulkerBoxBoatCriterion());
|
public static ShulkerBoxBoatCriterion SHULKER_BOX_BOAT_CRITERION = CriteriaHook.callRegister(new ShulkerBoxBoatCriterion());
|
||||||
|
public static BarrelBoatCriterion BARREL_BOAT_CRITERION = CriteriaHook.callRegister(new BarrelBoatCriterion());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.thebrokenrail.twine.advancement;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.thebrokenrail.twine.Twine;
|
||||||
|
import net.minecraft.advancement.criterion.AbstractCriterion;
|
||||||
|
import net.minecraft.advancement.criterion.AbstractCriterionConditions;
|
||||||
|
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
|
||||||
|
import net.minecraft.predicate.entity.EntityPredicate;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class BarrelBoatCriterion extends AbstractCriterion<AbstractCriterionConditions> {
|
||||||
|
private static final Identifier ID = new Identifier(Twine.NAMESPACE, "barrel_boat");
|
||||||
|
|
||||||
|
public void trigger(ServerPlayerEntity player) {
|
||||||
|
this.test(player, conditions -> true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AbstractCriterionConditions conditionsFromJson(JsonObject obj, EntityPredicate.Extended playerPredicate, AdvancementEntityPredicateDeserializer predicateDeserializer) {
|
||||||
|
return new AbstractCriterionConditions(ID, playerPredicate) {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier getId() {
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package com.thebrokenrail.twine.item;
|
package com.thebrokenrail.twine.item;
|
||||||
|
|
||||||
import com.thebrokenrail.twine.Twine;
|
import com.thebrokenrail.twine.Twine;
|
||||||
import com.thebrokenrail.twine.util.BackpackScreenHandler;
|
import com.thebrokenrail.twine.util.backpack.BackpackScreenHandler;
|
||||||
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
|
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package com.thebrokenrail.twine.mixin;
|
package com.thebrokenrail.twine.mixin;
|
||||||
|
|
||||||
import com.thebrokenrail.twine.util.BoatChestMode;
|
import com.thebrokenrail.twine.util.boat.BoatChestMode;
|
||||||
import com.thebrokenrail.twine.util.BoatInventory;
|
import com.thebrokenrail.twine.util.boat.BoatChestModes;
|
||||||
import com.thebrokenrail.twine.util.BoatUtil;
|
import com.thebrokenrail.twine.util.boat.BoatUtil;
|
||||||
|
import com.thebrokenrail.twine.util.boat.inventory.BoatInventory;
|
||||||
|
import com.thebrokenrail.twine.util.boat.inventory.BoatInventoryWrapper;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
@ -38,19 +40,19 @@ public class MixinBoatEntity implements BoatUtil {
|
|||||||
|
|
||||||
@Inject(at = @At("RETURN"), method = "initDataTracker")
|
@Inject(at = @At("RETURN"), method = "initDataTracker")
|
||||||
public void initDataTracker(CallbackInfo info) {
|
public void initDataTracker(CallbackInfo info) {
|
||||||
((BoatEntity) (Object) this).getDataTracker().startTracking(CHEST_MODE, BoatChestMode.NONE.getID());
|
((BoatEntity) (Object) this).getDataTracker().startTracking(CHEST_MODE, BoatChestModes.NONE.getID());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(at = @At("HEAD"), method = "canAddPassenger", cancellable = true)
|
@Inject(at = @At("HEAD"), method = "canAddPassenger", cancellable = true)
|
||||||
public void canAddPassenger(Entity passenger, CallbackInfoReturnable<Boolean> info) {
|
public void canAddPassenger(Entity passenger, CallbackInfoReturnable<Boolean> info) {
|
||||||
if (((BoatEntity) (Object) this).getPassengerList().size() > 0 && getChestMode() != BoatChestMode.NONE) {
|
if (((BoatEntity) (Object) this).getPassengerList().size() > 0 && getChestMode() != BoatChestModes.NONE) {
|
||||||
info.setReturnValue(false);
|
info.setReturnValue(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Redirect(at = @At(value = "INVOKE", target = "Ljava/util/List;size()I"), method = "updatePassengerPosition", allow = 2, require = 2)
|
@Redirect(at = @At(value = "INVOKE", target = "Ljava/util/List;size()I"), method = "updatePassengerPosition", allow = 2, require = 2)
|
||||||
public int updatePassengerPosition(List<Entity> list) {
|
public int updatePassengerPosition(List<Entity> list) {
|
||||||
if (getChestMode() != BoatChestMode.NONE) {
|
if (getChestMode() != BoatChestModes.NONE) {
|
||||||
return list.size() + 1;
|
return list.size() + 1;
|
||||||
} else {
|
} else {
|
||||||
return list.size();
|
return list.size();
|
||||||
@ -64,7 +66,7 @@ public class MixinBoatEntity implements BoatUtil {
|
|||||||
|
|
||||||
BoatChestMode newMode = BoatChestMode.valueOf(Block.getBlockFromItem(itemStack.getItem()));
|
BoatChestMode newMode = BoatChestMode.valueOf(Block.getBlockFromItem(itemStack.getItem()));
|
||||||
|
|
||||||
if (newMode != BoatChestMode.NONE && mode == BoatChestMode.NONE) {
|
if (newMode != BoatChestModes.NONE && mode == BoatChestModes.NONE) {
|
||||||
List<Entity> passengers = ((BoatEntity) (Object) this).getPassengerList();
|
List<Entity> passengers = ((BoatEntity) (Object) this).getPassengerList();
|
||||||
for (int i = 1; i < passengers.size(); i++) {
|
for (int i = 1; i < passengers.size(); i++) {
|
||||||
passengers.get(i).stopRiding();
|
passengers.get(i).stopRiding();
|
||||||
@ -129,7 +131,7 @@ public class MixinBoatEntity implements BoatUtil {
|
|||||||
@Unique
|
@Unique
|
||||||
private void updateInventory() {
|
private void updateInventory() {
|
||||||
BoatChestMode mode = getChestMode();
|
BoatChestMode mode = getChestMode();
|
||||||
items = mode.hasItems() ? new BoatInventory((BoatEntity) (Object) this, mode.getSize(), stack, mode.getOpenSound(), mode.getCloseSound()) : null;
|
items = mode.hasItems() ? new BoatInventory((BoatEntity) (Object) this, mode.getSize(), stack, mode) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Unique
|
@Unique
|
||||||
@ -194,6 +196,6 @@ public class MixinBoatEntity implements BoatUtil {
|
|||||||
@Override
|
@Override
|
||||||
public void openInventory(PlayerEntity player) {
|
public void openInventory(PlayerEntity player) {
|
||||||
BoatChestMode mode = getChestMode();
|
BoatChestMode mode = getChestMode();
|
||||||
player.openHandledScreen(new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) -> mode.getScreenHandlerFactory().createMenu(i, playerInventory, playerEntity, MixinBoatEntity.this), mode.getScreenHandlerName(stack)));
|
player.openHandledScreen(new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) -> mode.getScreenHandlerFactory().createMenu(i, playerInventory, playerEntity, MixinBoatEntity.this, inventory -> new BoatInventoryWrapper((Entity) (Object) this, inventory, mode)), mode.getScreenHandlerName(stack)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package com.thebrokenrail.twine.mixin;
|
package com.thebrokenrail.twine.mixin;
|
||||||
|
|
||||||
import com.thebrokenrail.twine.util.BoatUtil;
|
import com.thebrokenrail.twine.util.boat.BoatUtil;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
import net.minecraft.block.BlockRenderType;
|
import net.minecraft.block.BlockRenderType;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.thebrokenrail.twine.mixin;
|
package com.thebrokenrail.twine.mixin;
|
||||||
|
|
||||||
import com.thebrokenrail.twine.util.BoatChestMode;
|
import com.thebrokenrail.twine.util.boat.BoatChestModes;
|
||||||
import com.thebrokenrail.twine.util.BoatUtil;
|
import com.thebrokenrail.twine.util.boat.BoatUtil;
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
@ -24,7 +24,7 @@ public class MixinClientPlayerInteractionManager {
|
|||||||
@Inject(at = @At("HEAD"), method = "hasRidingInventory", cancellable = true)
|
@Inject(at = @At("HEAD"), method = "hasRidingInventory", cancellable = true)
|
||||||
public void hasRidingInventory(CallbackInfoReturnable<Boolean> info) {
|
public void hasRidingInventory(CallbackInfoReturnable<Boolean> info) {
|
||||||
assert client.player != null;
|
assert client.player != null;
|
||||||
if (client.player.hasVehicle() && client.player.getVehicle() instanceof BoatEntity && ((BoatUtil) client.player.getVehicle()).getChestMode() != BoatChestMode.NONE) {
|
if (client.player.hasVehicle() && client.player.getVehicle() instanceof BoatEntity && ((BoatUtil) client.player.getVehicle()).getChestMode() != BoatChestModes.NONE) {
|
||||||
info.setReturnValue(true);
|
info.setReturnValue(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.thebrokenrail.twine.mixin;
|
package com.thebrokenrail.twine.mixin;
|
||||||
|
|
||||||
import com.thebrokenrail.twine.util.BoatChestMode;
|
import com.thebrokenrail.twine.util.boat.BoatChestModes;
|
||||||
import com.thebrokenrail.twine.util.BoatUtil;
|
import com.thebrokenrail.twine.util.boat.BoatUtil;
|
||||||
import net.minecraft.entity.vehicle.BoatEntity;
|
import net.minecraft.entity.vehicle.BoatEntity;
|
||||||
import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket;
|
import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket;
|
||||||
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||||
@ -19,7 +19,7 @@ public class MixinServerPlayNetworkHandler {
|
|||||||
|
|
||||||
@Inject(at = @At("TAIL"), method = "onClientCommand")
|
@Inject(at = @At("TAIL"), method = "onClientCommand")
|
||||||
public void onClientCommand(ClientCommandC2SPacket packet, CallbackInfo info) {
|
public void onClientCommand(ClientCommandC2SPacket packet, CallbackInfo info) {
|
||||||
if (packet.getMode() == ClientCommandC2SPacket.Mode.OPEN_INVENTORY && player.hasVehicle() && player.getVehicle() instanceof BoatEntity && ((BoatUtil) player.getVehicle()).getChestMode() != BoatChestMode.NONE) {
|
if (packet.getMode() == ClientCommandC2SPacket.Mode.OPEN_INVENTORY && player.hasVehicle() && player.getVehicle() instanceof BoatEntity && ((BoatUtil) player.getVehicle()).getChestMode() != BoatChestModes.NONE) {
|
||||||
((BoatUtil) player.getVehicle()).openInventory(player);
|
((BoatUtil) player.getVehicle()).openInventory(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.thebrokenrail.twine.mixin;
|
package com.thebrokenrail.twine.mixin;
|
||||||
|
|
||||||
import com.thebrokenrail.twine.item.BackpackItem;
|
import com.thebrokenrail.twine.item.BackpackItem;
|
||||||
import com.thebrokenrail.twine.util.BackpackInventory;
|
import com.thebrokenrail.twine.util.backpack.inventory.BackpackInventory;
|
||||||
import net.minecraft.inventory.Inventory;
|
import net.minecraft.inventory.Inventory;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.screen.slot.Slot;
|
import net.minecraft.screen.slot.Slot;
|
||||||
|
@ -1,143 +0,0 @@
|
|||||||
package com.thebrokenrail.twine.util;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.thebrokenrail.twine.Twine;
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.EnderChestBlock;
|
|
||||||
import net.minecraft.block.ShulkerBoxBlock;
|
|
||||||
import net.minecraft.block.entity.ChestBlockEntity;
|
|
||||||
import net.minecraft.block.entity.ShulkerBoxBlockEntity;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.screen.GenericContainerScreenHandler;
|
|
||||||
import net.minecraft.screen.ScreenHandler;
|
|
||||||
import net.minecraft.screen.ShulkerBoxScreenHandler;
|
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
|
||||||
import net.minecraft.sound.SoundEvent;
|
|
||||||
import net.minecraft.sound.SoundEvents;
|
|
||||||
import net.minecraft.text.Text;
|
|
||||||
import net.minecraft.util.DyeColor;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public class BoatChestMode {
|
|
||||||
public interface BoatScreenHandlerFactory {
|
|
||||||
ScreenHandler createMenu(int syncId, PlayerInventory inv, PlayerEntity player, BoatUtil boat);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final ArrayList<BoatChestMode> values = new ArrayList<>();
|
|
||||||
|
|
||||||
public static final BoatChestMode NONE = new BoatChestMode(Blocks.AIR, null, null, null);
|
|
||||||
|
|
||||||
static {
|
|
||||||
BoatScreenHandlerFactory chestScreenHandler = (i, playerInventory, playerEntity, boat) -> GenericContainerScreenHandler.createGeneric9x3(i, playerInventory, boat.getChestInventory());
|
|
||||||
ChestBlockEntity chest = new ChestBlockEntity();
|
|
||||||
Function<ItemStack, Text> chestScreenHandlerName = stack -> stack.hasCustomName() ? stack.getName() : chest.getName();
|
|
||||||
|
|
||||||
new BoatChestMode(Blocks.ENDER_CHEST, (i, playerInventory, playerEntity, boat) -> GenericContainerScreenHandler.createGeneric9x3(i, playerInventory, new EnderChestInventoryWrapper((Entity) boat, playerEntity.getEnderChestInventory())), stack -> EnderChestBlock.CONTAINER_NAME, player -> Twine.ENDER_CHEST_BOAT_CRITERION.trigger(player));
|
|
||||||
new BoatChestMode(Blocks.CHEST, true, false, 27, chestScreenHandler, chestScreenHandlerName, player -> Twine.CHEST_BOAT_CRITERION.trigger(player), SoundEvents.BLOCK_CHEST_OPEN, SoundEvents.BLOCK_CHEST_CLOSE);
|
|
||||||
new BoatChestMode(Blocks.TRAPPED_CHEST, true, false, 27, chestScreenHandler, chestScreenHandlerName, player -> Twine.CHEST_BOAT_CRITERION.trigger(player), SoundEvents.BLOCK_CHEST_OPEN, SoundEvents.BLOCK_CHEST_CLOSE);
|
|
||||||
|
|
||||||
ShulkerBoxBlockEntity shulker = new ShulkerBoxBlockEntity();
|
|
||||||
List<DyeColor> colors = Lists.asList(null, DyeColor.values());
|
|
||||||
for (DyeColor value : colors) {
|
|
||||||
new BoatChestMode(ShulkerBoxBlock.get(value), true, true, 27, (i, playerInventory, playerEntity, boat) -> new ShulkerBoxScreenHandler(i, playerInventory, boat.getChestInventory()), stack -> stack.hasCustomName() ? stack.getName() : shulker.getName(), player -> Twine.SHULKER_BOX_BOAT_CRITERION.trigger(player), SoundEvents.BLOCK_SHULKER_BOX_OPEN, SoundEvents.BLOCK_SHULKER_BOX_CLOSE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Block block;
|
|
||||||
private final boolean hasItems;
|
|
||||||
private final boolean containsItems;
|
|
||||||
|
|
||||||
private final int size;
|
|
||||||
|
|
||||||
private final BoatScreenHandlerFactory screenHandlerFactory;
|
|
||||||
private final Function<ItemStack, Text> screenHandlerNameFactory;
|
|
||||||
|
|
||||||
private final Consumer<ServerPlayerEntity> advancementTrigger;
|
|
||||||
|
|
||||||
private final int id;
|
|
||||||
|
|
||||||
private final SoundEvent openSound;
|
|
||||||
private final SoundEvent closeSound;
|
|
||||||
|
|
||||||
private BoatChestMode(Block block, boolean hasItems, boolean containsItems, int size, BoatScreenHandlerFactory screenHandlerFactory, Function<ItemStack, Text> screenHandlerNameFactory, Consumer<ServerPlayerEntity> advancementTrigger, SoundEvent openSound, SoundEvent closeSound) {
|
|
||||||
this.screenHandlerFactory = screenHandlerFactory;
|
|
||||||
this.size = size;
|
|
||||||
this.screenHandlerNameFactory = screenHandlerNameFactory;
|
|
||||||
this.advancementTrigger = advancementTrigger;
|
|
||||||
this.openSound = openSound;
|
|
||||||
this.closeSound = closeSound;
|
|
||||||
this.id = values.size();
|
|
||||||
this.block = block;
|
|
||||||
this.hasItems = hasItems;
|
|
||||||
this.containsItems = containsItems;
|
|
||||||
values.add(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BoatChestMode(Block block, BoatScreenHandlerFactory screenHandlerFactory, Function<ItemStack, Text> screenHandlerNameFactory, Consumer<ServerPlayerEntity> advancementTrigger) {
|
|
||||||
this(block,false, false, 0, screenHandlerFactory, screenHandlerNameFactory, advancementTrigger, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSize() {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BoatScreenHandlerFactory getScreenHandlerFactory() {
|
|
||||||
return screenHandlerFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Text getScreenHandlerName(ItemStack stack) {
|
|
||||||
return screenHandlerNameFactory.apply(stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void triggerAdvancement(ServerPlayerEntity player) {
|
|
||||||
if (advancementTrigger != null) {
|
|
||||||
advancementTrigger.accept(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public SoundEvent getOpenSound() {
|
|
||||||
return openSound;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SoundEvent getCloseSound() {
|
|
||||||
return closeSound;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Block getBlock() {
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasItems() {
|
|
||||||
return hasItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean containsItems() {
|
|
||||||
return containsItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getID() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BoatChestMode valueOf(Block block) {
|
|
||||||
for (BoatChestMode mode : values) {
|
|
||||||
if (mode.getBlock() == block) {
|
|
||||||
return mode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static BoatChestMode valueOf(int index) {
|
|
||||||
BoatChestMode mode = values.get(index);
|
|
||||||
return mode != null ? mode : NONE;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package com.thebrokenrail.twine.util;
|
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.sound.SoundEvent;
|
|
||||||
|
|
||||||
public class BoatInventory extends ItemInventory {
|
|
||||||
private final Entity entity;
|
|
||||||
|
|
||||||
private final SoundEvent openSound;
|
|
||||||
private final SoundEvent closeSound;
|
|
||||||
|
|
||||||
public BoatInventory(Entity entity, int size, ItemStack stack, SoundEvent openSound, SoundEvent closeSound) {
|
|
||||||
super(size, stack);
|
|
||||||
this.entity = entity;
|
|
||||||
this.openSound = openSound;
|
|
||||||
this.closeSound = closeSound;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlayerUse(PlayerEntity player) {
|
|
||||||
return BoatUtil.canReachEntity(player, entity) && entity.isAlive() && ((BoatUtil) entity).getChestMode().hasItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onOpen(PlayerEntity player) {
|
|
||||||
if (openSound != null) {
|
|
||||||
BoatUtil.playSound(entity, openSound);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClose(PlayerEntity player) {
|
|
||||||
if (closeSound != null) {
|
|
||||||
BoatUtil.playSound(entity, closeSound);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
package com.thebrokenrail.twine.util;
|
package com.thebrokenrail.twine.util.backpack;
|
||||||
|
|
||||||
import com.thebrokenrail.twine.Twine;
|
import com.thebrokenrail.twine.Twine;
|
||||||
|
import com.thebrokenrail.twine.util.backpack.inventory.BackpackInventory;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.inventory.Inventory;
|
import net.minecraft.inventory.Inventory;
|
||||||
import net.minecraft.network.PacketByteBuf;
|
import net.minecraft.network.PacketByteBuf;
|
@ -1,5 +1,6 @@
|
|||||||
package com.thebrokenrail.twine.util;
|
package com.thebrokenrail.twine.util.backpack.inventory;
|
||||||
|
|
||||||
|
import com.thebrokenrail.twine.util.inventory.ItemInventory;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
|
|
@ -0,0 +1,117 @@
|
|||||||
|
package com.thebrokenrail.twine.util.boat;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.inventory.Inventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.screen.ScreenHandler;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.sound.SoundEvent;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class BoatChestMode {
|
||||||
|
public interface BoatScreenHandlerFactory {
|
||||||
|
ScreenHandler createMenu(int syncId, PlayerInventory inv, PlayerEntity player, BoatUtil boat, Function<Inventory, Inventory> inventoryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ArrayList<BoatChestMode> values = new ArrayList<>();
|
||||||
|
|
||||||
|
private final Block block;
|
||||||
|
private final boolean hasItems;
|
||||||
|
private final boolean containsItems;
|
||||||
|
|
||||||
|
private final int size;
|
||||||
|
|
||||||
|
private final BoatScreenHandlerFactory screenHandlerFactory;
|
||||||
|
private final Function<ItemStack, Text> screenHandlerNameFactory;
|
||||||
|
|
||||||
|
private final Consumer<ServerPlayerEntity> advancementTrigger;
|
||||||
|
|
||||||
|
private final int id;
|
||||||
|
|
||||||
|
private final SoundEvent openSound;
|
||||||
|
private final SoundEvent closeSound;
|
||||||
|
|
||||||
|
BoatChestMode(Block block, boolean hasItems, boolean containsItems, int size, BoatScreenHandlerFactory screenHandlerFactory, Function<ItemStack, Text> screenHandlerNameFactory, Consumer<ServerPlayerEntity> advancementTrigger, SoundEvent openSound, SoundEvent closeSound) {
|
||||||
|
this.screenHandlerFactory = screenHandlerFactory;
|
||||||
|
this.size = size;
|
||||||
|
this.screenHandlerNameFactory = screenHandlerNameFactory;
|
||||||
|
this.advancementTrigger = advancementTrigger;
|
||||||
|
this.openSound = openSound;
|
||||||
|
this.closeSound = closeSound;
|
||||||
|
this.id = values.size();
|
||||||
|
this.block = block;
|
||||||
|
this.hasItems = hasItems;
|
||||||
|
this.containsItems = containsItems;
|
||||||
|
values.add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoatChestMode(Block block, BoatScreenHandlerFactory screenHandlerFactory, Function<ItemStack, Text> screenHandlerNameFactory, Consumer<ServerPlayerEntity> advancementTrigger, SoundEvent openSound, SoundEvent closeSound) {
|
||||||
|
this(block, false, false, 0, screenHandlerFactory, screenHandlerNameFactory, advancementTrigger, openSound, closeSound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoatScreenHandlerFactory getScreenHandlerFactory() {
|
||||||
|
return screenHandlerFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Text getScreenHandlerName(ItemStack stack) {
|
||||||
|
return screenHandlerNameFactory.apply(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void triggerAdvancement(ServerPlayerEntity player) {
|
||||||
|
if (advancementTrigger != null) {
|
||||||
|
advancementTrigger.accept(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SoundEvent getOpenSound() {
|
||||||
|
return openSound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SoundEvent getCloseSound() {
|
||||||
|
return closeSound;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block getBlock() {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasItems() {
|
||||||
|
return hasItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsItems() {
|
||||||
|
return containsItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getID() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BoatChestMode valueOf(Block block) {
|
||||||
|
for (BoatChestMode mode : values) {
|
||||||
|
if (mode.getBlock() == block) {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return BoatChestModes.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static BoatChestMode valueOf(int index) {
|
||||||
|
BoatChestMode mode = values.get(index);
|
||||||
|
return mode != null ? mode : BoatChestModes.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
BoatChestModes.register();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.thebrokenrail.twine.util.boat;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.thebrokenrail.twine.Twine;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.EnderChestBlock;
|
||||||
|
import net.minecraft.block.ShulkerBoxBlock;
|
||||||
|
import net.minecraft.block.entity.BarrelBlockEntity;
|
||||||
|
import net.minecraft.block.entity.ChestBlockEntity;
|
||||||
|
import net.minecraft.block.entity.ShulkerBoxBlockEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.screen.GenericContainerScreenHandler;
|
||||||
|
import net.minecraft.screen.ShulkerBoxScreenHandler;
|
||||||
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.DyeColor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class BoatChestModes {
|
||||||
|
public static final BoatChestMode NONE = new BoatChestMode(Blocks.AIR, null, null, null, null, null);
|
||||||
|
|
||||||
|
static void register() {
|
||||||
|
new BoatChestMode(Blocks.ENDER_CHEST, (i, playerInventory, playerEntity, boat, inventoryWrapper) -> GenericContainerScreenHandler.createGeneric9x3(i, playerInventory, inventoryWrapper.apply(playerEntity.getEnderChestInventory())), stack -> EnderChestBlock.CONTAINER_NAME, player -> Twine.ENDER_CHEST_BOAT_CRITERION.trigger(player), SoundEvents.BLOCK_ENDER_CHEST_OPEN, SoundEvents.BLOCK_ENDER_CHEST_CLOSE);
|
||||||
|
|
||||||
|
BoatChestMode.BoatScreenHandlerFactory chestScreenHandler = (i, playerInventory, playerEntity, boat, inventoryWrapper) -> GenericContainerScreenHandler.createGeneric9x3(i, playerInventory, boat.getChestInventory());
|
||||||
|
ChestBlockEntity chest = new ChestBlockEntity();
|
||||||
|
Function<ItemStack, Text> chestScreenHandlerName = stack -> stack.hasCustomName() ? stack.getName() : chest.getName();
|
||||||
|
|
||||||
|
new BoatChestMode(Blocks.CHEST, true, false, 27, chestScreenHandler, chestScreenHandlerName, player -> Twine.CHEST_BOAT_CRITERION.trigger(player), SoundEvents.BLOCK_CHEST_OPEN, SoundEvents.BLOCK_CHEST_CLOSE);
|
||||||
|
new BoatChestMode(Blocks.TRAPPED_CHEST, true, false, 27, chestScreenHandler, chestScreenHandlerName, player -> Twine.CHEST_BOAT_CRITERION.trigger(player), SoundEvents.BLOCK_CHEST_OPEN, SoundEvents.BLOCK_CHEST_CLOSE);
|
||||||
|
|
||||||
|
BarrelBlockEntity barrel = new BarrelBlockEntity();
|
||||||
|
Function<ItemStack, Text> barrelScreenHandlerName = stack -> stack.hasCustomName() ? stack.getName() : barrel.getName();
|
||||||
|
|
||||||
|
new BoatChestMode(Blocks.BARREL, true, false, 27, chestScreenHandler, barrelScreenHandlerName, player -> Twine.BARREL_BOAT_CRITERION.trigger(player), SoundEvents.BLOCK_BARREL_OPEN, SoundEvents.BLOCK_BARREL_CLOSE);
|
||||||
|
|
||||||
|
ShulkerBoxBlockEntity shulker = new ShulkerBoxBlockEntity();
|
||||||
|
List<DyeColor> colors = Lists.asList(null, DyeColor.values());
|
||||||
|
for (DyeColor value : colors) {
|
||||||
|
new BoatChestMode(ShulkerBoxBlock.get(value), true, true, 27, (i, playerInventory, playerEntity, boat, inventoryWrapper) -> new ShulkerBoxScreenHandler(i, playerInventory, boat.getChestInventory()), stack -> stack.hasCustomName() ? stack.getName() : shulker.getName(), player -> Twine.SHULKER_BOX_BOAT_CRITERION.trigger(player), SoundEvents.BLOCK_SHULKER_BOX_OPEN, SoundEvents.BLOCK_SHULKER_BOX_CLOSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.thebrokenrail.twine.util;
|
package com.thebrokenrail.twine.util.boat;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.thebrokenrail.twine.util.boat.inventory;
|
||||||
|
|
||||||
|
import com.thebrokenrail.twine.util.boat.BoatChestMode;
|
||||||
|
import com.thebrokenrail.twine.util.inventory.ItemInventory;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
public class BoatInventory extends BoatInventoryWrapper {
|
||||||
|
public BoatInventory(Entity entity, int size, ItemStack stack, BoatChestMode mode) {
|
||||||
|
super(entity, new ItemInventory(size, stack), mode);
|
||||||
|
}
|
||||||
|
}
|
@ -1,20 +1,21 @@
|
|||||||
package com.thebrokenrail.twine.util;
|
package com.thebrokenrail.twine.util.boat.inventory;
|
||||||
|
|
||||||
import net.minecraft.block.Blocks;
|
import com.thebrokenrail.twine.util.boat.BoatChestMode;
|
||||||
|
import com.thebrokenrail.twine.util.boat.BoatUtil;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.inventory.EnderChestInventory;
|
|
||||||
import net.minecraft.inventory.Inventory;
|
import net.minecraft.inventory.Inventory;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.sound.SoundEvents;
|
|
||||||
|
|
||||||
public class EnderChestInventoryWrapper implements Inventory {
|
public class BoatInventoryWrapper implements Inventory {
|
||||||
private final EnderChestInventory inventory;
|
private final Inventory inventory;
|
||||||
private final Entity entity;
|
private final Entity entity;
|
||||||
|
private final BoatChestMode mode;
|
||||||
|
|
||||||
public EnderChestInventoryWrapper(Entity entity, EnderChestInventory inventory) {
|
public BoatInventoryWrapper(Entity entity, Inventory inventory, BoatChestMode mode) {
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
this.inventory = inventory;
|
this.inventory = inventory;
|
||||||
|
this.mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -54,17 +55,21 @@ public class EnderChestInventoryWrapper implements Inventory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canPlayerUse(PlayerEntity player) {
|
public boolean canPlayerUse(PlayerEntity player) {
|
||||||
return BoatUtil.canReachEntity(player, entity) && entity.isAlive() && ((BoatUtil) entity).getChestMode().getBlock() == Blocks.ENDER_CHEST;
|
return BoatUtil.canReachEntity(player, entity) && entity.isAlive() && ((BoatUtil) entity).getChestMode() == mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOpen(PlayerEntity player) {
|
public void onOpen(PlayerEntity player) {
|
||||||
BoatUtil.playSound(entity, SoundEvents.BLOCK_ENDER_CHEST_OPEN);
|
if (mode.getOpenSound() != null) {
|
||||||
|
BoatUtil.playSound(entity, mode.getOpenSound());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClose(PlayerEntity player) {
|
public void onClose(PlayerEntity player) {
|
||||||
BoatUtil.playSound(entity, SoundEvents.BLOCK_ENDER_CHEST_CLOSE);
|
if (mode.getCloseSound() != null) {
|
||||||
|
BoatUtil.playSound(entity, mode.getCloseSound());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -1,4 +1,4 @@
|
|||||||
package com.thebrokenrail.twine.util;
|
package com.thebrokenrail.twine.util.inventory;
|
||||||
|
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.inventory.Inventories;
|
import net.minecraft.inventory.Inventories;
|
||||||
@ -6,7 +6,7 @@ import net.minecraft.inventory.Inventory;
|
|||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.collection.DefaultedList;
|
import net.minecraft.util.collection.DefaultedList;
|
||||||
|
|
||||||
public abstract class ItemInventory implements Inventory {
|
public class ItemInventory implements Inventory {
|
||||||
private final int size;
|
private final int size;
|
||||||
private final ItemStack stack;
|
private final ItemStack stack;
|
||||||
private final DefaultedList<ItemStack> inv;
|
private final DefaultedList<ItemStack> inv;
|
||||||
@ -73,7 +73,9 @@ public abstract class ItemInventory implements Inventory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract boolean canPlayerUse(PlayerEntity player);
|
public boolean canPlayerUse(PlayerEntity player) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
@ -26,6 +26,9 @@
|
|||||||
"advancements.twine.large_backpack.title": "Go big or go home!",
|
"advancements.twine.large_backpack.title": "Go big or go home!",
|
||||||
"advancements.twine.large_backpack.description": "Construct a Large Backpack by combing a Small Backpack and a Gold Ingot in a Smithing Table",
|
"advancements.twine.large_backpack.description": "Construct a Large Backpack by combing a Small Backpack and a Gold Ingot in a Smithing Table",
|
||||||
|
|
||||||
|
"advancements.twine.barrel_boat.title": "Off-Brand Chest-Boat",
|
||||||
|
"advancements.twine.barrel_boat.description": "Put a Barrel in a Boat",
|
||||||
|
|
||||||
"advancements.twine.diviner.title": "Divination",
|
"advancements.twine.diviner.title": "Divination",
|
||||||
"advancements.twine.diviner.description": "Construct a Diviner with a Crafting Table",
|
"advancements.twine.diviner.description": "Construct a Diviner with a Crafting Table",
|
||||||
|
|
||||||
|
19
src/main/resources/data/twine/advancements/barrel_boat.json
Normal file
19
src/main/resources/data/twine/advancements/barrel_boat.json
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"display": {
|
||||||
|
"icon": {
|
||||||
|
"item": "minecraft:oak_boat"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"translate": "advancements.twine.barrel_boat.title"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"translate": "advancements.twine.barrel_boat.description"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parent": "twine:chest_boat",
|
||||||
|
"criteria": {
|
||||||
|
"chest_boat": {
|
||||||
|
"trigger": "twine:barrel_boat"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user