Trapped Chest Boats
Twine/pipeline/head This commit looks good Details

This commit is contained in:
TheBrokenRail 2020-06-15 20:25:12 -04:00
parent 4d14fe7487
commit 4ebd156bdc
9 changed files with 58 additions and 53 deletions

View File

@ -30,7 +30,7 @@ Glowing Obsidian heals monsters and hurts everything else. It naturally generate
</table>
## Chest Boats
Right-Click a Boat with a Chest to place it in the Boat, you can also use an Ender Chest. 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 or Trapped Chest. Shift-Right-Click the Boat to open the Chest. You can also open the Chest inside the Boat by opening your inventory.
## 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.

View File

@ -4,7 +4,7 @@ org.gradle.jvmargs = -Xmx1G
# Fabric Properties
# check these on https://fabricmc.net/use
minecraft_version = 1.16-pre6
curseforge_id = 390000
curseforge_id = 390028
simple_minecraft_version = 1.16-Snapshot
yarn_build = 3
fabric_loader_version = 0.8.7+build.201

View File

@ -1,7 +1,6 @@
package com.thebrokenrail.twine.mixin;
import com.thebrokenrail.twine.Twine;
import com.thebrokenrail.twine.advancement.ChestBoatCriterion;
import com.thebrokenrail.twine.util.BoatInventory;
import com.thebrokenrail.twine.util.BoatUtil;
import com.thebrokenrail.twine.util.EnderChestInventoryWrapper;
@ -13,9 +12,7 @@ import net.minecraft.entity.damage.DamageSource;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.vehicle.BoatEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.screen.GenericContainerScreenHandler;
@ -44,14 +41,14 @@ public class MixinBoatEntity implements BoatUtil {
@Inject(at = @At("HEAD"), method = "canAddPassenger", cancellable = true)
public void canAddPassenger(Entity passenger, CallbackInfoReturnable<Boolean> info) {
if (((BoatEntity) (Object) this).getPassengerList().size() > 0 && hasChest() != BoatChestMode.NONE) {
if (((BoatEntity) (Object) this).getPassengerList().size() > 0 && getChestMode() != BoatChestMode.NONE) {
info.setReturnValue(false);
}
}
@Redirect(at = @At(value = "INVOKE", target = "Ljava/util/List;size()I"), method = "updatePassengerPosition", allow = 2, require = 2)
public int updatePassengerPosition(List<Entity> list) {
if (hasChest() != BoatChestMode.NONE) {
if (getChestMode() != BoatChestMode.NONE) {
return list.size() + 1;
} else {
return list.size();
@ -60,21 +57,21 @@ public class MixinBoatEntity implements BoatUtil {
@Inject(at = @At("HEAD"), method = "interact", cancellable = true)
public void interact(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResult> info) {
BoatChestMode hasChest = hasChest();
BoatChestMode hasChest = getChestMode();
ItemStack stack = player.getStackInHand(hand);
if ((stack.getItem() == Items.CHEST || stack.getItem() == Items.ENDER_CHEST) && hasChest == BoatChestMode.NONE) {
BoatChestMode newMode = BoatChestMode.valueOF(stack.getItem());
if (newMode != BoatChestMode.NONE && hasChest == BoatChestMode.NONE) {
List<Entity> passengers = ((BoatEntity) (Object) this).getPassengerList();
for (int i = 1; i < passengers.size(); i++) {
passengers.get(i).stopRiding();
}
if (!player.getEntityWorld().isClient()) {
if (stack.getItem() == Items.CHEST) {
if (newMode.hasItems()) {
Twine.CHEST_BOAT_CRITERION.trigger((ServerPlayerEntity) player);
setHasChest(BoatChestMode.CHEST);
} else {
} else if (newMode == BoatChestMode.ENDER_CHEST) {
Twine.ENDER_CHEST_BOAT_CRITERION.trigger((ServerPlayerEntity) player);
setHasChest(BoatChestMode.ENDER_CHEST);
}
setChestMode(newMode);
updateInventory();
}
if (!player.isCreative()) {
@ -90,30 +87,15 @@ public class MixinBoatEntity implements BoatUtil {
}
@Unique
private void setHasChest(BoatChestMode mode) {
private void setChestMode(BoatChestMode mode) {
((BoatEntity) (Object) this).getDataTracker().set(BoatUtil.HAS_CHEST, mode.name());
}
@Override
public Item getChestItem() {
switch (hasChest()) {
case CHEST: {
return Items.CHEST;
}
case ENDER_CHEST: {
return Items.ENDER_CHEST;
}
default: {
return Items.AIR;
}
}
}
@Unique
private void dropItemsOnDestroy(boolean isCreative) {
if (((BoatEntity) (Object) this).getEntityWorld().getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) {
if (!isCreative) {
((BoatEntity) (Object) this).dropStack(new ItemStack(getChestItem()));
((BoatEntity) (Object) this).dropStack(new ItemStack(getChestMode().getItem()));
}
dropItems();
}
@ -134,7 +116,7 @@ public class MixinBoatEntity implements BoatUtil {
@Unique
private void updateInventory() {
items = hasChest() == BoatChestMode.CHEST ? new BoatInventory((BoatEntity) (Object) this, 27) : null;
items = getChestMode().hasItems() ? new BoatInventory((BoatEntity) (Object) this, 27) : null;
}
@Unique
@ -151,9 +133,9 @@ public class MixinBoatEntity implements BoatUtil {
@Inject(at = @At("RETURN"), method = "writeCustomDataToTag")
public void writeCustomDataToTag(CompoundTag tag, CallbackInfo info) {
BoatChestMode hasChest = hasChest();
BoatChestMode hasChest = getChestMode();
tag.putString("HasChest", hasChest.name());
if (hasChest == BoatChestMode.CHEST) {
if (hasChest.hasItems()) {
ListTag listTag = new ListTag();
for (int i = 2; i < this.items.size(); ++i) {
@ -178,9 +160,9 @@ public class MixinBoatEntity implements BoatUtil {
} catch (IllegalArgumentException e) {
hasChest = BoatChestMode.NONE;
}
setHasChest(hasChest);
setChestMode(hasChest);
updateInventory();
if (hasChest == BoatChestMode.CHEST) {
if (hasChest.hasItems()) {
ListTag listTag = tag.getList("Items", 10);
for (int i = 0; i < listTag.size(); ++i) {
@ -194,7 +176,7 @@ public class MixinBoatEntity implements BoatUtil {
}
@Override
public BoatChestMode hasChest() {
public BoatChestMode getChestMode() {
try {
return BoatChestMode.valueOf(((BoatEntity) (Object) this).getDataTracker().get(BoatUtil.HAS_CHEST));
} catch (IllegalArgumentException e) {
@ -203,14 +185,14 @@ public class MixinBoatEntity implements BoatUtil {
}
@Override
public Inventory getInventory() {
public Inventory getChestInventory() {
return items;
}
@Override
public void openInventory(PlayerEntity player) {
if (hasChest() == BoatUtil.BoatChestMode.CHEST) {
player.openHandledScreen(new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) -> GenericContainerScreenHandler.createGeneric9x3(i, playerInventory, getInventory()), ((BoatEntity) (Object) this).getDisplayName()));
if (getChestMode().hasItems()) {
player.openHandledScreen(new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) -> GenericContainerScreenHandler.createGeneric9x3(i, playerInventory, getChestInventory()), ((BoatEntity) (Object) this).getDisplayName()));
} else {
player.openHandledScreen(new SimpleNamedScreenHandlerFactory((i, playerInventory, playerEntity) -> GenericContainerScreenHandler.createGeneric9x3(i, playerInventory, new EnderChestInventoryWrapper((BoatEntity) (Object) this, player.getEnderChestInventory())), EnderChestBlock.CONTAINER_NAME));
}

View File

@ -23,7 +23,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
public class MixinBoatEntityRenderer {
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;pop()V"), method = "render", allow = 1)
public void render(BoatEntity boatEntity, float f, float g, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo info) {
BlockState blockState = Block.getBlockFromItem(((BoatUtil) boatEntity).getChestItem()).getDefaultState();
BlockState blockState = Block.getBlockFromItem(((BoatUtil) boatEntity).getChestMode().getItem()).getDefaultState();
if (blockState.getRenderType() != BlockRenderType.INVISIBLE) {
matrixStack.push();
matrixStack.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(180.0f));

View File

@ -23,7 +23,7 @@ public class MixinClientPlayerInteractionManager {
@Inject(at = @At("HEAD"), method = "hasRidingInventory", cancellable = true)
public void hasRidingInventory(CallbackInfoReturnable<Boolean> info) {
assert client.player != null;
if (client.player.hasVehicle() && client.player.getVehicle() instanceof BoatEntity && ((BoatUtil) client.player.getVehicle()).hasChest() != BoatUtil.BoatChestMode.NONE) {
if (client.player.hasVehicle() && client.player.getVehicle() instanceof BoatEntity && ((BoatUtil) client.player.getVehicle()).getChestMode() != BoatUtil.BoatChestMode.NONE) {
info.setReturnValue(true);
}
}

View File

@ -18,7 +18,7 @@ public class MixinServerPlayNetworkHandler {
@Inject(at = @At("TAIL"), method = "onClientCommand")
public void onClientCommand(ClientCommandC2SPacket packet, CallbackInfo info) {
if (packet.getMode() == ClientCommandC2SPacket.Mode.OPEN_INVENTORY && player.hasVehicle() && player.getVehicle() instanceof BoatEntity && ((BoatUtil) player.getVehicle()).hasChest() != BoatUtil.BoatChestMode.NONE) {
if (packet.getMode() == ClientCommandC2SPacket.Mode.OPEN_INVENTORY && player.hasVehicle() && player.getVehicle() instanceof BoatEntity && ((BoatUtil) player.getVehicle()).getChestMode() != BoatUtil.BoatChestMode.NONE) {
((BoatUtil) player.getVehicle()).openInventory(player);
}
}

View File

@ -15,7 +15,7 @@ public class BoatInventory extends SimpleInventory {
@Override
public boolean canPlayerUse(PlayerEntity player) {
return BoatUtil.canReachEntity(player, entity) && entity.isAlive() && ((BoatUtil) entity).hasChest() == BoatUtil.BoatChestMode.CHEST && super.canPlayerUse(player);
return BoatUtil.canReachEntity(player, entity) && entity.isAlive() && ((BoatUtil) entity).getChestMode() == BoatUtil.BoatChestMode.CHEST && super.canPlayerUse(player);
}
@Override

View File

@ -8,20 +8,17 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.vehicle.BoatEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvent;
import net.minecraft.util.math.Vec3d;
import java.util.Objects;
public interface BoatUtil {
TrackedData<String> HAS_CHEST = DataTracker.registerData(BoatEntity.class, TrackedDataHandlerRegistry.STRING);
Item getChestItem();
BoatChestMode getChestMode();
BoatChestMode hasChest();
Inventory getInventory();
Inventory getChestInventory();
void openInventory(PlayerEntity player);
@ -30,9 +27,35 @@ public interface BoatUtil {
}
enum BoatChestMode {
ENDER_CHEST,
CHEST,
NONE
ENDER_CHEST(Items.ENDER_CHEST, false),
CHEST(Items.CHEST, true),
TRAPPED_CHEST(Items.TRAPPED_CHEST, true),
NONE(Items.AIR, false);
private final Item item;
private final boolean hasItems;
BoatChestMode(Item item, boolean hasItems) {
this.item = item;
this.hasItems = hasItems;
}
public Item getItem() {
return item;
}
public boolean hasItems() {
return hasItems;
}
public static BoatChestMode valueOF(Item item) {
for (BoatChestMode mode : values()) {
if (mode.getItem() == item) {
return mode;
}
}
return NONE;
}
}
static void playSound(Entity vehicle, SoundEvent sound) {

View File

@ -53,7 +53,7 @@ public class EnderChestInventoryWrapper implements Inventory {
@Override
public boolean canPlayerUse(PlayerEntity player) {
return BoatUtil.canReachEntity(player, entity) && entity.isAlive() && ((BoatUtil) entity).hasChest() == BoatUtil.BoatChestMode.ENDER_CHEST;
return BoatUtil.canReachEntity(player, entity) && entity.isAlive() && ((BoatUtil) entity).getChestMode() == BoatUtil.BoatChestMode.ENDER_CHEST;
}
@Override