This commit is contained in:
parent
d63ba796c3
commit
a7a1794ba0
@ -19,6 +19,9 @@ Combine a Small Backpack with a Gold Ingot in the Smithing Table.
|
|||||||
### Dye Backpack Recipe
|
### Dye Backpack Recipe
|
||||||
Combine a Backpack with a dye in the Crafting Table.
|
Combine a Backpack with a dye in the Crafting Table.
|
||||||
|
|
||||||
|
## End Rods
|
||||||
|
Most hostile mobs are afraid of End Rods.
|
||||||
|
|
||||||
## Glowing Obsidian
|
## Glowing Obsidian
|
||||||
Glowing Obsidian heals monsters and hurts everything else. It naturally generates in small patches underground.
|
Glowing Obsidian heals monsters and hurts everything else. It naturally generates in small patches underground.
|
||||||
|
|
||||||
@ -30,7 +33,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, 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.
|
Right-Click a Boat with a Chest to place it in the Boat, you can also use an Ender Chest, Trapped Chest, Barrel, Crafting Table, 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.
|
||||||
@ -57,9 +60,6 @@ Each player has a "personal" stage of an area, the highest online player's diffi
|
|||||||
### Technical Details
|
### Technical Details
|
||||||
Each player has a 6-element long list in their data. Each element in the list has a chunk position and time value. Every tick the player will first, find the stage element its current position is in, and increase the time value of that stage element. If the time value when increased is over 24,000 ticks the next stage element will have its chunk set to the players current position, have its time value reset, the old stage element will have the next stage element's old chunk, and have its time value reset. To determine if a player is in a stage element, it checks if the player is within 16 chunks of the stage element's chunk, it starts searching at the last element, ending at the first. The "effective" stage element of a chunk can be found by searching every **online** player for their stage element for the chunk and then picking the highest value.
|
Each player has a 6-element long list in their data. Each element in the list has a chunk position and time value. Every tick the player will first, find the stage element its current position is in, and increase the time value of that stage element. If the time value when increased is over 24,000 ticks the next stage element will have its chunk set to the players current position, have its time value reset, the old stage element will have the next stage element's old chunk, and have its time value reset. To determine if a player is in a stage element, it checks if the player is within 16 chunks of the stage element's chunk, it starts searching at the last element, ending at the first. The "effective" stage element of a chunk can be found by searching every **online** player for their stage element for the chunk and then picking the highest value.
|
||||||
|
|
||||||
## End Rods
|
|
||||||
Most hostile mobs are afraid of End Rods.
|
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
[View Changelog](CHANGELOG.md)
|
[View Changelog](CHANGELOG.md)
|
||||||
|
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
package com.thebrokenrail.twine;
|
package com.thebrokenrail.twine;
|
||||||
|
|
||||||
import com.thebrokenrail.twine.advancement.BarrelBoatCriterion;
|
import com.thebrokenrail.twine.advancement.BoatCriterion;
|
||||||
import com.thebrokenrail.twine.advancement.ChestBoatCriterion;
|
|
||||||
import com.thebrokenrail.twine.advancement.EnderChestBoatCriterion;
|
|
||||||
import com.thebrokenrail.twine.advancement.ShulkerBoxBoatCriterion;
|
|
||||||
import com.thebrokenrail.twine.block.CreativeItemSpawnerBlock;
|
import com.thebrokenrail.twine.block.CreativeItemSpawnerBlock;
|
||||||
import com.thebrokenrail.twine.block.GlowingObsidianBlock;
|
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.backpack.BackpackScreenHandler;
|
import com.thebrokenrail.twine.util.backpack.gui.BackpackScreenHandler;
|
||||||
|
import com.thebrokenrail.twine.util.boat.gui.BoatCraftingScreenHandler;
|
||||||
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;
|
||||||
@ -19,6 +17,7 @@ import net.minecraft.item.BlockItem;
|
|||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemGroup;
|
import net.minecraft.item.ItemGroup;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.screen.CraftingScreenHandler;
|
||||||
import net.minecraft.screen.GenericContainerScreenHandler;
|
import net.minecraft.screen.GenericContainerScreenHandler;
|
||||||
import net.minecraft.screen.ScreenHandlerType;
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
import net.minecraft.tag.Tag;
|
import net.minecraft.tag.Tag;
|
||||||
@ -34,7 +33,6 @@ public class Twine implements ModInitializer {
|
|||||||
|
|
||||||
public static final ItemGroup ITEM_GROUP = FabricItemGroupBuilder.build(new Identifier(NAMESPACE, "item_group"), () -> new ItemStack(GLOWING_OBSIDIAN));
|
public static final ItemGroup ITEM_GROUP = FabricItemGroupBuilder.build(new Identifier(NAMESPACE, "item_group"), () -> new ItemStack(GLOWING_OBSIDIAN));
|
||||||
|
|
||||||
private static final Identifier BACKPACK_SCREEN = new Identifier(NAMESPACE, "backpack");
|
|
||||||
public static final Item SMALL_BACKPACK = new BackpackItem(false);
|
public static final Item SMALL_BACKPACK = new BackpackItem(false);
|
||||||
public static final Item LARGE_BACKPACK = new BackpackItem(true);
|
public static final Item LARGE_BACKPACK = new BackpackItem(true);
|
||||||
|
|
||||||
@ -46,15 +44,14 @@ public class Twine implements ModInitializer {
|
|||||||
public static final int STAGE_TIME = 24000;
|
public static final int STAGE_TIME = 24000;
|
||||||
|
|
||||||
public static ScreenHandlerType<? extends GenericContainerScreenHandler> BACKPACK_SCREEN_TYPE;
|
public static ScreenHandlerType<? extends GenericContainerScreenHandler> BACKPACK_SCREEN_TYPE;
|
||||||
|
public static ScreenHandlerType<? extends CraftingScreenHandler> BOAT_CRAFTING_SCREEN_TYPE;
|
||||||
|
|
||||||
public static ChestBoatCriterion CHEST_BOAT_CRITERION = CriteriaHook.callRegister(new ChestBoatCriterion());
|
public static BoatCriterion BOAT_CRITERION = CriteriaHook.callRegister(new BoatCriterion());
|
||||||
public static EnderChestBoatCriterion ENDER_CHEST_BOAT_CRITERION = CriteriaHook.callRegister(new EnderChestBoatCriterion());
|
|
||||||
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() {
|
||||||
BACKPACK_SCREEN_TYPE = ScreenHandlerRegistry.registerExtended(BACKPACK_SCREEN, BackpackScreenHandler::new);
|
BACKPACK_SCREEN_TYPE = ScreenHandlerRegistry.registerExtended(new Identifier(NAMESPACE, "backpack"), BackpackScreenHandler::new);
|
||||||
|
BOAT_CRAFTING_SCREEN_TYPE = ScreenHandlerRegistry.registerSimple(new Identifier(NAMESPACE, "boat_crafting"), BoatCraftingScreenHandler::new);
|
||||||
|
|
||||||
Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "small_backpack"), SMALL_BACKPACK);
|
Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "small_backpack"), SMALL_BACKPACK);
|
||||||
Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "large_backpack"), LARGE_BACKPACK);
|
Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "large_backpack"), LARGE_BACKPACK);
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.thebrokenrail.twine.advancement;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
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.block.Block;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer;
|
||||||
|
import net.minecraft.predicate.entity.EntityPredicate;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.tag.Tag;
|
||||||
|
import net.minecraft.tag.TagContainers;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BoatCriterion extends AbstractCriterion<BoatCriterion.Conditions> {
|
||||||
|
private static final Identifier ID = new Identifier(Twine.NAMESPACE, "boat");
|
||||||
|
|
||||||
|
public void trigger(ServerPlayerEntity player, Block block) {
|
||||||
|
this.test(player, conditions -> conditions.getBlock().contains(block));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Conditions conditionsFromJson(JsonObject obj, EntityPredicate.Extended playerPredicate, AdvancementEntityPredicateDeserializer predicateDeserializer) {
|
||||||
|
JsonElement str = obj.get("block");
|
||||||
|
List<Block> block = null;
|
||||||
|
if (str != null) {
|
||||||
|
String id = str.getAsString();
|
||||||
|
if (id.startsWith("#")) {
|
||||||
|
Tag<Block> tag = TagContainers.instance().blocks().get(new Identifier(id.substring(1)));
|
||||||
|
if (tag != null) {
|
||||||
|
block = tag.values();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
block = Collections.singletonList(Registry.BLOCK.get(new Identifier(id)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (block == null) {
|
||||||
|
block = Collections.singletonList(Blocks.AIR);
|
||||||
|
}
|
||||||
|
return new Conditions(ID, playerPredicate, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier getId() {
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Conditions extends AbstractCriterionConditions {
|
||||||
|
private final List<Block> block;
|
||||||
|
|
||||||
|
public Conditions(Identifier id, EntityPredicate.Extended playerPredicate, List<Block> block) {
|
||||||
|
super(id, playerPredicate);
|
||||||
|
this.block = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Block> getBlock() {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,29 +0,0 @@
|
|||||||
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 ChestBoatCriterion extends AbstractCriterion<AbstractCriterionConditions> {
|
|
||||||
private static final Identifier ID = new Identifier(Twine.NAMESPACE, "chest_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,29 +0,0 @@
|
|||||||
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 EnderChestBoatCriterion extends AbstractCriterion<AbstractCriterionConditions> {
|
|
||||||
private static final Identifier ID = new Identifier(Twine.NAMESPACE, "ender_chest_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,29 +0,0 @@
|
|||||||
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 ShulkerBoxBoatCriterion extends AbstractCriterion<AbstractCriterionConditions> {
|
|
||||||
private static final Identifier ID = new Identifier(Twine.NAMESPACE, "shulker_box_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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,6 +6,7 @@ import net.fabricmc.api.EnvType;
|
|||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
|
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
|
||||||
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry;
|
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry;
|
||||||
|
import net.minecraft.client.gui.screen.ingame.CraftingScreen;
|
||||||
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
|
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
|
||||||
import net.minecraft.item.DyeableItem;
|
import net.minecraft.item.DyeableItem;
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ public class TwineClient implements ClientModInitializer {
|
|||||||
@Override
|
@Override
|
||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
ScreenRegistry.register(Twine.BACKPACK_SCREEN_TYPE, GenericContainerScreen::new);
|
ScreenRegistry.register(Twine.BACKPACK_SCREEN_TYPE, GenericContainerScreen::new);
|
||||||
|
ScreenRegistry.register(Twine.BOAT_CRAFTING_SCREEN_TYPE, CraftingScreen::new);
|
||||||
ColorProviderRegistry.ITEM.register((stack, tintIndex) -> tintIndex > 0 ? -1 : ((DyeableItem) stack.getItem()).getColor(stack), Twine.SMALL_BACKPACK, Twine.LARGE_BACKPACK);
|
ColorProviderRegistry.ITEM.register((stack, tintIndex) -> tintIndex > 0 ? -1 : ((DyeableItem) stack.getItem()).getColor(stack), Twine.SMALL_BACKPACK, Twine.LARGE_BACKPACK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.backpack.BackpackScreenHandler;
|
import com.thebrokenrail.twine.util.backpack.gui.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,4 +1,4 @@
|
|||||||
package com.thebrokenrail.twine.util.backpack;
|
package com.thebrokenrail.twine.util.backpack.gui;
|
||||||
|
|
||||||
import com.thebrokenrail.twine.Twine;
|
import com.thebrokenrail.twine.Twine;
|
||||||
import com.thebrokenrail.twine.util.backpack.inventory.BackpackInventory;
|
import com.thebrokenrail.twine.util.backpack.inventory.BackpackInventory;
|
@ -1,5 +1,6 @@
|
|||||||
package com.thebrokenrail.twine.util.boat;
|
package com.thebrokenrail.twine.util.boat;
|
||||||
|
|
||||||
|
import com.thebrokenrail.twine.Twine;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
@ -11,7 +12,6 @@ import net.minecraft.sound.SoundEvent;
|
|||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.function.Consumer;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class BoatChestMode {
|
public class BoatChestMode {
|
||||||
@ -26,18 +26,15 @@ public class BoatChestMode {
|
|||||||
private final BoatScreenHandlerFactory screenHandlerFactory;
|
private final BoatScreenHandlerFactory screenHandlerFactory;
|
||||||
private final Function<ItemStack, Text> screenHandlerNameFactory;
|
private final Function<ItemStack, Text> screenHandlerNameFactory;
|
||||||
|
|
||||||
private final Consumer<ServerPlayerEntity> advancementTrigger;
|
|
||||||
|
|
||||||
private final int id;
|
private final int id;
|
||||||
|
|
||||||
private final SoundEvent openSound;
|
private final SoundEvent openSound;
|
||||||
private final SoundEvent closeSound;
|
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) {
|
BoatChestMode(Block block, boolean hasItems, boolean containsItems, int size, BoatScreenHandlerFactory screenHandlerFactory, Function<ItemStack, Text> screenHandlerNameFactory, SoundEvent openSound, SoundEvent closeSound) {
|
||||||
this.screenHandlerFactory = screenHandlerFactory;
|
this.screenHandlerFactory = screenHandlerFactory;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.screenHandlerNameFactory = screenHandlerNameFactory;
|
this.screenHandlerNameFactory = screenHandlerNameFactory;
|
||||||
this.advancementTrigger = advancementTrigger;
|
|
||||||
this.openSound = openSound;
|
this.openSound = openSound;
|
||||||
this.closeSound = closeSound;
|
this.closeSound = closeSound;
|
||||||
this.id = values.size();
|
this.id = values.size();
|
||||||
@ -47,8 +44,8 @@ public class BoatChestMode {
|
|||||||
values.add(this);
|
values.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BoatChestMode(Block block, BoatScreenHandlerFactory screenHandlerFactory, Function<ItemStack, Text> screenHandlerNameFactory, Consumer<ServerPlayerEntity> advancementTrigger, SoundEvent openSound, SoundEvent closeSound) {
|
public BoatChestMode(Block block, BoatScreenHandlerFactory screenHandlerFactory, Function<ItemStack, Text> screenHandlerNameFactory, SoundEvent openSound, SoundEvent closeSound) {
|
||||||
this(block, false, false, 0, screenHandlerFactory, screenHandlerNameFactory, advancementTrigger, openSound, closeSound);
|
this(block, false, false, 0, screenHandlerFactory, screenHandlerNameFactory, openSound, closeSound);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BoatChestMode valueOf(Block block) {
|
public static BoatChestMode valueOf(Block block) {
|
||||||
@ -78,9 +75,7 @@ public class BoatChestMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void triggerAdvancement(ServerPlayerEntity player) {
|
public void triggerAdvancement(ServerPlayerEntity player) {
|
||||||
if (advancementTrigger != null) {
|
Twine.BOAT_CRITERION.trigger(player, getBlock());
|
||||||
advancementTrigger.accept(player);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SoundEvent getOpenSound() {
|
public SoundEvent getOpenSound() {
|
||||||
|
@ -1,45 +1,52 @@
|
|||||||
package com.thebrokenrail.twine.util.boat;
|
package com.thebrokenrail.twine.util.boat;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.thebrokenrail.twine.Twine;
|
import com.thebrokenrail.twine.util.boat.gui.BoatCraftingScreenHandler;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.EnderChestBlock;
|
import net.minecraft.block.EnderChestBlock;
|
||||||
import net.minecraft.block.ShulkerBoxBlock;
|
import net.minecraft.block.ShulkerBoxBlock;
|
||||||
import net.minecraft.block.entity.BarrelBlockEntity;
|
import net.minecraft.block.entity.BarrelBlockEntity;
|
||||||
import net.minecraft.block.entity.ChestBlockEntity;
|
import net.minecraft.block.entity.ChestBlockEntity;
|
||||||
import net.minecraft.block.entity.ShulkerBoxBlockEntity;
|
import net.minecraft.block.entity.ShulkerBoxBlockEntity;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.screen.GenericContainerScreenHandler;
|
import net.minecraft.screen.GenericContainerScreenHandler;
|
||||||
import net.minecraft.screen.ShulkerBoxScreenHandler;
|
import net.minecraft.screen.ShulkerBoxScreenHandler;
|
||||||
import net.minecraft.sound.SoundEvents;
|
import net.minecraft.sound.SoundEvents;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.text.TranslatableText;
|
||||||
import net.minecraft.util.DyeColor;
|
import net.minecraft.util.DyeColor;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class BoatChestModes {
|
public class BoatChestModes {
|
||||||
public static final BoatChestMode NONE = new BoatChestMode(Blocks.AIR, null, null, null, null, null);
|
public static final BoatChestMode NONE = new BoatChestMode(Blocks.AIR, null, null, null, null);
|
||||||
|
|
||||||
static void register() {
|
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);
|
new BoatChestMode(Blocks.ENDER_CHEST, (i, playerInventory, playerEntity, boat, inventoryWrapper) -> GenericContainerScreenHandler.createGeneric9x3(i, playerInventory, inventoryWrapper.apply(playerEntity.getEnderChestInventory())), stack -> EnderChestBlock.CONTAINER_NAME, SoundEvents.BLOCK_ENDER_CHEST_OPEN, SoundEvents.BLOCK_ENDER_CHEST_CLOSE);
|
||||||
|
|
||||||
BoatChestMode.BoatScreenHandlerFactory chestScreenHandler = (i, playerInventory, playerEntity, boat, inventoryWrapper) -> GenericContainerScreenHandler.createGeneric9x3(i, playerInventory, boat.getChestInventory());
|
BoatChestMode.BoatScreenHandlerFactory chestScreenHandler = (i, playerInventory, playerEntity, boat, inventoryWrapper) -> GenericContainerScreenHandler.createGeneric9x3(i, playerInventory, boat.getChestInventory());
|
||||||
ChestBlockEntity chest = new ChestBlockEntity();
|
ChestBlockEntity chest = new ChestBlockEntity();
|
||||||
Function<ItemStack, Text> chestScreenHandlerName = stack -> stack.hasCustomName() ? stack.getName() : chest.getName();
|
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.CHEST, true, false, 27, chestScreenHandler, chestScreenHandlerName, 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);
|
new BoatChestMode(Blocks.TRAPPED_CHEST, true, false, 27, chestScreenHandler, chestScreenHandlerName, SoundEvents.BLOCK_CHEST_OPEN, SoundEvents.BLOCK_CHEST_CLOSE);
|
||||||
|
|
||||||
BarrelBlockEntity barrel = new BarrelBlockEntity();
|
BarrelBlockEntity barrel = new BarrelBlockEntity();
|
||||||
Function<ItemStack, Text> barrelScreenHandlerName = stack -> stack.hasCustomName() ? stack.getName() : barrel.getName();
|
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);
|
new BoatChestMode(Blocks.BARREL, true, false, 27, chestScreenHandler, barrelScreenHandlerName, SoundEvents.BLOCK_BARREL_OPEN, SoundEvents.BLOCK_BARREL_CLOSE);
|
||||||
|
|
||||||
ShulkerBoxBlockEntity shulker = new ShulkerBoxBlockEntity();
|
ShulkerBoxBlockEntity shulker = new ShulkerBoxBlockEntity();
|
||||||
List<DyeColor> colors = Lists.asList(null, DyeColor.values());
|
List<DyeColor> colors = Lists.asList(null, DyeColor.values());
|
||||||
for (DyeColor value : colors) {
|
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);
|
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(), SoundEvents.BLOCK_SHULKER_BOX_OPEN, SoundEvents.BLOCK_SHULKER_BOX_CLOSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new BoatChestMode(Blocks.CRAFTING_TABLE, (i, playerInventory, playerEntity, boat, inventoryWrapper) -> {
|
||||||
|
BoatChestMode mode = boat.getChestMode();
|
||||||
|
return new BoatCraftingScreenHandler(i, playerInventory, player -> BoatUtil.canPlayerUse(player, (Entity) boat, mode));
|
||||||
|
}, stack -> new TranslatableText("container.crafting"), null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,10 @@ public interface BoatUtil {
|
|||||||
return player.squaredDistanceTo(entity.getPos().getX(), entity.getPos().getY(), entity.getPos().getZ()) <= 64d;
|
return player.squaredDistanceTo(entity.getPos().getX(), entity.getPos().getY(), entity.getPos().getZ()) <= 64d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean canPlayerUse(PlayerEntity player, Entity entity, BoatChestMode mode) {
|
||||||
|
return BoatUtil.canReachEntity(player, entity) && entity.isAlive() && ((BoatUtil) entity).getChestMode() == mode;
|
||||||
|
}
|
||||||
|
|
||||||
static void playSound(Entity vehicle, SoundEvent sound) {
|
static void playSound(Entity vehicle, SoundEvent sound) {
|
||||||
Vec3d pos = vehicle.getPos();
|
Vec3d pos = vehicle.getPos();
|
||||||
vehicle.getEntityWorld().playSound(null, pos.getX(), pos.getY(), pos.getZ(), sound, SoundCategory.BLOCKS, 0.5F, vehicle.getEntityWorld().random.nextFloat() * 0.1F + 0.9F);
|
vehicle.getEntityWorld().playSound(null, pos.getX(), pos.getY(), pos.getZ(), sound, SoundCategory.BLOCKS, 0.5F, vehicle.getEntityWorld().random.nextFloat() * 0.1F + 0.9F);
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package com.thebrokenrail.twine.util.boat.gui;
|
||||||
|
|
||||||
|
import com.thebrokenrail.twine.Twine;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.screen.CraftingScreenHandler;
|
||||||
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
public class BoatCraftingScreenHandler extends CraftingScreenHandler {
|
||||||
|
private final Predicate<PlayerEntity> canUse;
|
||||||
|
|
||||||
|
public BoatCraftingScreenHandler(int syncId, PlayerInventory playerInventory, Predicate<PlayerEntity> canUse) {
|
||||||
|
super(syncId, playerInventory);
|
||||||
|
this.canUse = canUse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoatCraftingScreenHandler(int syncId, PlayerInventory playerInventory) {
|
||||||
|
this(syncId, playerInventory, player -> true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canUse(PlayerEntity player) {
|
||||||
|
return canUse.test(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScreenHandlerType<?> getType() {
|
||||||
|
return Twine.BOAT_CRAFTING_SCREEN_TYPE;
|
||||||
|
}
|
||||||
|
}
|
@ -55,7 +55,7 @@ public class BoatInventoryWrapper implements Inventory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canPlayerUse(PlayerEntity player) {
|
public boolean canPlayerUse(PlayerEntity player) {
|
||||||
return BoatUtil.canReachEntity(player, entity) && entity.isAlive() && ((BoatUtil) entity).getChestMode() == mode;
|
return BoatUtil.canPlayerUse(player, entity, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -11,14 +11,11 @@
|
|||||||
"advancements.twine.root.title": "Twine",
|
"advancements.twine.root.title": "Twine",
|
||||||
"advancements.twine.root.description": "A simple survival mod for Minecraft encouraging a nomadic lifestyle",
|
"advancements.twine.root.description": "A simple survival mod for Minecraft encouraging a nomadic lifestyle",
|
||||||
|
|
||||||
"advancements.twine.chest_boat.title": "TEAM SWAMP!",
|
"advancements.twine.boat.title": "TEAM SWAMP!",
|
||||||
"advancements.twine.chest_boat.description": "Put a Chest in a Boat",
|
"advancements.twine.boat.description": "Put a block in a Boat",
|
||||||
|
|
||||||
"advancements.twine.ender_chest_boat.title": "Why Not?",
|
"advancements.twine.all_boats.title": "Seafaring Utilities",
|
||||||
"advancements.twine.ender_chest_boat.description": "Put an Ender Chest in a Boat",
|
"advancements.twine.all_boats.description": "Put all possible block in a Boat",
|
||||||
|
|
||||||
"advancements.twine.shulker_box_boat.title": "Why? Just Why?",
|
|
||||||
"advancements.twine.shulker_box_boat.description": "Put a Shulker Box in a Boat",
|
|
||||||
|
|
||||||
"advancements.twine.small_backpack.title": "On The Go!",
|
"advancements.twine.small_backpack.title": "On The Go!",
|
||||||
"advancements.twine.small_backpack.description": "Construct a Small Backpack with a Crafting Table",
|
"advancements.twine.small_backpack.description": "Construct a Small Backpack with a Crafting Table",
|
||||||
@ -26,9 +23,6 @@
|
|||||||
"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 Master",
|
"advancements.twine.diviner.title": "Divination Master",
|
||||||
"advancements.twine.diviner.description": "Construct a Diviner with a Crafting Table",
|
"advancements.twine.diviner.description": "Construct a Diviner with a Crafting Table",
|
||||||
|
|
||||||
|
76
src/main/resources/data/twine/advancements/all_boats.json
Normal file
76
src/main/resources/data/twine/advancements/all_boats.json
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"display": {
|
||||||
|
"icon": {
|
||||||
|
"item": "minecraft:oak_boat"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"translate": "advancements.twine.all_boats.title"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"translate": "advancements.twine.all_boats.description"
|
||||||
|
},
|
||||||
|
"frame": "challenge"
|
||||||
|
},
|
||||||
|
"parent": "twine:boat",
|
||||||
|
"rewards": {
|
||||||
|
"experience": 100
|
||||||
|
},
|
||||||
|
"criteria": {
|
||||||
|
"chest_boat": {
|
||||||
|
"trigger": "twine:boat",
|
||||||
|
"conditions": {
|
||||||
|
"block": "minecraft:chest"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"trapped_chest_boat": {
|
||||||
|
"trigger": "twine:boat",
|
||||||
|
"conditions": {
|
||||||
|
"block": "minecraft:trapped_chest"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ender_chest_boat": {
|
||||||
|
"trigger": "twine:boat",
|
||||||
|
"conditions": {
|
||||||
|
"block": "minecraft:ender_chest"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"shulker_box_boat": {
|
||||||
|
"trigger": "twine:boat",
|
||||||
|
"conditions": {
|
||||||
|
"block": "#minecraft:shulker_boxes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"barrel_boat": {
|
||||||
|
"trigger": "twine:boat",
|
||||||
|
"conditions": {
|
||||||
|
"block": "minecraft:barrel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"crafting_table_boat": {
|
||||||
|
"trigger": "twine:boat",
|
||||||
|
"conditions": {
|
||||||
|
"block": "minecraft:crafting_table"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"chest_boat"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"trapped_chest_boat"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"ender_chest_boat"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"shulker_box_boat"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"barrel_boat"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"crafting_table_boat"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
62
src/main/resources/data/twine/advancements/boat.json
Normal file
62
src/main/resources/data/twine/advancements/boat.json
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"display": {
|
||||||
|
"icon": {
|
||||||
|
"item": "minecraft:oak_boat"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"translate": "advancements.twine.boat.title"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"translate": "advancements.twine.boat.description"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parent": "twine:root",
|
||||||
|
"criteria": {
|
||||||
|
"chest_boat": {
|
||||||
|
"trigger": "twine:boat",
|
||||||
|
"conditions": {
|
||||||
|
"block": "minecraft:chest"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"trapped_chest_boat": {
|
||||||
|
"trigger": "twine:boat",
|
||||||
|
"conditions": {
|
||||||
|
"block": "minecraft:trapped_chest"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ender_chest_boat": {
|
||||||
|
"trigger": "twine:boat",
|
||||||
|
"conditions": {
|
||||||
|
"block": "minecraft:ender_chest"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"shulker_box_boat": {
|
||||||
|
"trigger": "twine:boat",
|
||||||
|
"conditions": {
|
||||||
|
"block": "#minecraft:shulker_boxes"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"barrel_boat": {
|
||||||
|
"trigger": "twine:boat",
|
||||||
|
"conditions": {
|
||||||
|
"block": "minecraft:barrel"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"crafting_table_boat": {
|
||||||
|
"trigger": "twine:boat",
|
||||||
|
"conditions": {
|
||||||
|
"block": "minecraft:crafting_table"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"chest_boat",
|
||||||
|
"trapped_chest_boat",
|
||||||
|
"ender_chest_boat",
|
||||||
|
"shulker_box_boat",
|
||||||
|
"barrel_boat",
|
||||||
|
"crafting_table_boat"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"display": {
|
|
||||||
"icon": {
|
|
||||||
"item": "minecraft:oak_boat"
|
|
||||||
},
|
|
||||||
"title": {
|
|
||||||
"translate": "advancements.twine.chest_boat.title"
|
|
||||||
},
|
|
||||||
"description": {
|
|
||||||
"translate": "advancements.twine.chest_boat.description"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"parent": "twine:root",
|
|
||||||
"criteria": {
|
|
||||||
"chest_boat": {
|
|
||||||
"trigger": "twine:chest_boat"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"display": {
|
|
||||||
"icon": {
|
|
||||||
"item": "minecraft:oak_boat"
|
|
||||||
},
|
|
||||||
"title": {
|
|
||||||
"translate": "advancements.twine.ender_chest_boat.title"
|
|
||||||
},
|
|
||||||
"description": {
|
|
||||||
"translate": "advancements.twine.ender_chest_boat.description"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"parent": "twine:chest_boat",
|
|
||||||
"criteria": {
|
|
||||||
"chest_boat": {
|
|
||||||
"trigger": "twine:ender_chest_boat"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"display": {
|
|
||||||
"icon": {
|
|
||||||
"item": "minecraft:oak_boat"
|
|
||||||
},
|
|
||||||
"title": {
|
|
||||||
"translate": "advancements.twine.shulker_box_boat.title"
|
|
||||||
},
|
|
||||||
"description": {
|
|
||||||
"translate": "advancements.twine.shulker_box_boat.description"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"parent": "twine:chest_boat",
|
|
||||||
"criteria": {
|
|
||||||
"chest_boat": {
|
|
||||||
"trigger": "twine:shulker_box_boat"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user