~vpzom/retail

6aee29ad0adc064acbf91d2d49c44659a292da0f — Colin Reeder 2 months ago 01c4ec8
Add Exposed Vending Block
M src/main/java/click/vpzom/mods/retail/RetailMod.java => src/main/java/click/vpzom/mods/retail/RetailMod.java +4 -1
@@ 14,13 14,16 @@ public class RetailMod implements ModInitializer {
		Registry.register(Registry.BLOCK, new Identifier(MODID, "vending_block"), VendingBlock.NORMAL);
		Registry.register(Registry.ITEM, new Identifier(MODID, "vending_block"), VendingBlock.NORMAL.ITEM);

		Registry.register(Registry.BLOCK, new Identifier(MODID, "exposed_vending_block"), VendingBlock.EXPOSED);
		Registry.register(Registry.ITEM, new Identifier(MODID, "exposed_vending_block"), VendingBlock.EXPOSED.ITEM);

		Registry.register(Registry.BLOCK, new Identifier(MODID, "creative_vending_block"), VendingBlock.CREATIVE);
		Registry.register(Registry.ITEM, new Identifier(MODID, "creative_vending_block"), VendingBlock.CREATIVE.ITEM);

		VendingBlockEntity.TYPE = Registry.register(
			Registry.BLOCK_ENTITY_TYPE,
			new Identifier(MODID, "vending_block"),
			BlockEntityType.Builder.create(VendingBlockEntity::new, VendingBlock.NORMAL, VendingBlock.CREATIVE).build(null)
			BlockEntityType.Builder.create(VendingBlockEntity::new, VendingBlock.NORMAL, VendingBlock.EXPOSED, VendingBlock.CREATIVE).build(null)
		);

		VendingBlockScreenHandler.TYPE =

M src/main/java/click/vpzom/mods/retail/RetailModClient.java => src/main/java/click/vpzom/mods/retail/RetailModClient.java +1 -0
@@ 15,6 15,7 @@ public class RetailModClient implements ClientModInitializer {
		ScreenRegistry.register(VendingBlockScreenHandler.TYPE, VendingBlockScreen::new);

		BlockRenderLayerMap.INSTANCE.putBlock(VendingBlock.NORMAL, RenderLayer.getTranslucent());
		BlockRenderLayerMap.INSTANCE.putBlock(VendingBlock.EXPOSED, RenderLayer.getTranslucent());
		BlockRenderLayerMap.INSTANCE.putBlock(VendingBlock.CREATIVE, RenderLayer.getTranslucent());

		BlockEntityRendererRegistry.INSTANCE.register(VendingBlockEntity.TYPE, VendingBlockEntityRenderer::new);

M src/main/java/click/vpzom/mods/retail/VendingBlock.java => src/main/java/click/vpzom/mods/retail/VendingBlock.java +6 -3
@@ 21,15 21,18 @@ import net.minecraft.world.BlockView;
import net.minecraft.world.World;

public class VendingBlock extends BlockWithEntity {
	public static VendingBlock NORMAL = new VendingBlock(false);
	public static VendingBlock CREATIVE = new VendingBlock(true);
	public static VendingBlock NORMAL = new VendingBlock(false, false);
	public static VendingBlock CREATIVE = new VendingBlock(true, false);
	public static VendingBlock EXPOSED = new VendingBlock(false, true);
	public final BlockItem ITEM = new BlockItem(this, new Item.Settings().group(ItemGroup.DECORATIONS));

	protected final boolean isCreative;
	protected final boolean isExposed;

	private VendingBlock(boolean isCreative) {
	private VendingBlock(boolean isCreative, boolean isExposed) {
		super(AbstractBlock.Settings.of(Material.STONE).strength(10f, 3600000).nonOpaque());
		this.isCreative = isCreative;
		this.isExposed = isExposed;
	}

	@Override

M src/main/java/click/vpzom/mods/retail/VendingBlockEntity.java => src/main/java/click/vpzom/mods/retail/VendingBlockEntity.java +189 -81
@@ 23,7 23,7 @@ import net.minecraft.util.collection.DefaultedList;

public class VendingBlockEntity extends BlockEntity implements Inventory, ExtendedScreenHandlerFactory, BlockEntityClientSerializable {
	public static final int REAL_INV_SIZE = 9;
	public static final int FULL_INV_SIZE = REAL_INV_SIZE + 2;
	public static final int UI_INV_SIZE = REAL_INV_SIZE + 2;
	public static final int PRICE_SLOT = REAL_INV_SIZE;
	public static final int GOOD_SLOT = REAL_INV_SIZE + 1;



@@ 34,91 34,14 @@ public class VendingBlockEntity extends BlockEntity implements Inventory, Extend
	protected DefaultedList<ItemStack> invStacks = DefaultedList.ofSize(REAL_INV_SIZE, ItemStack.EMPTY);
	protected UUID owner = null;

	private final RealInventory realInventory = new RealInventory();
	protected final UIInventory uiInventory = new UIInventory();

	public VendingBlockEntity() {
		super(TYPE);
	}

	@Override
	public boolean canPlayerUse(PlayerEntity player) {
		return owner == null || owner.equals(player.getUuid());
	}

	@Override
	public void setStack(int slot, ItemStack stack) {
		if(slot == PRICE_SLOT) {
			price = stack;
			sync();
			return;
		}
		if(slot == GOOD_SLOT) {
			good = stack;
			sync();
			return;
		}

		invStacks.set(slot, stack);
	}

	@Override
	public ItemStack getStack(int slot) {
		if(slot == PRICE_SLOT) return price;
		if(slot == GOOD_SLOT) return good;

		return invStacks.get(slot);
	}

	@Override
	public ItemStack removeStack(int slot, int amount) {
		if(slot == PRICE_SLOT) {
			price.split(amount);
			return ItemStack.EMPTY;
		}
		if(slot == GOOD_SLOT) {
			good.split(amount);
			return ItemStack.EMPTY;
		}

		ItemStack result = Inventories.splitStack(invStacks, slot, amount);
		if(!result.isEmpty()) markDirty();

		return result;
	}

	@Override
	public ItemStack removeStack(int slot) {
		if(slot == PRICE_SLOT) {
			price = ItemStack.EMPTY;
			sync();
			return ItemStack.EMPTY;
		}
		if(slot == GOOD_SLOT) {
			good = ItemStack.EMPTY;
			sync();
			return ItemStack.EMPTY;
		}

		return Inventories.removeStack(invStacks, slot);
	}

	@Override
	public boolean isEmpty() {
		return invStacks.stream().allMatch(ItemStack::isEmpty) && price.isEmpty() && good.isEmpty();
	}

	@Override
	public int size() {
		return FULL_INV_SIZE;
	}

	@Override
	public void clear() {
		invStacks.clear();
		price = ItemStack.EMPTY;
		good = ItemStack.EMPTY;
		sync();
	}

	@Override
	public Text getDisplayName() {
		return new TranslatableText(getCachedState().getBlock().getTranslationKey());
	}


@@ 175,6 98,11 @@ public class VendingBlockEntity extends BlockEntity implements Inventory, Extend
		return ((VendingBlock) world.getBlockState(pos).getBlock()).isCreative;
	}

	protected boolean isExposed() {
		assert world != null;
		return ((VendingBlock) world.getBlockState(pos).getBlock()).isExposed;
	}

	public boolean tryExchange(PlayerEntity player) {
		ItemStack held = player.inventory.getMainHandStack();
		if(!held.isEmpty() && held.getItem() == price.getItem() && ItemStack.areTagsEqual(held, price) && held.getCount() >= price.getCount()) {


@@ 241,4 169,184 @@ public class VendingBlockEntity extends BlockEntity implements Inventory, Extend
	public void writeScreenOpeningData(ServerPlayerEntity serverPlayerEntity, PacketByteBuf packetByteBuf) {
		packetByteBuf.writeBoolean(isCreative());
	}

	@Override
	public int size() {
		if(isExposed()) return realInventory.size();
		return 0;
	}

	@Override
	public boolean isEmpty() {
		if(isExposed()) return realInventory.isEmpty();
		return true;
	}

	@Override
	public ItemStack getStack(int slot) {
		if(isExposed()) return realInventory.getStack(slot);
		return ItemStack.EMPTY;
	}

	@Override
	public ItemStack removeStack(int slot, int amount) {
		if(isExposed()) return realInventory.removeStack(slot, amount);
		return ItemStack.EMPTY;
	}

	@Override
	public ItemStack removeStack(int slot) {
		if(isExposed()) return realInventory.removeStack(slot);
		return ItemStack.EMPTY;
	}

	@Override
	public void setStack(int slot, ItemStack stack) {
		if(isExposed()) realInventory.setStack(slot, stack);
	}

	@Override
	public boolean canPlayerUse(PlayerEntity player) {
		return realInventory.canPlayerUse(player);
	}

	@Override
	public void clear() {
		if(isExposed()) realInventory.clear();
	}

	public class UIInventory implements Inventory {
		@Override
		public int size() {
			return UI_INV_SIZE;
		}

		@Override
		public boolean isEmpty() {
			return realInventory.isEmpty() && price.isEmpty() && good.isEmpty();
		}

		@Override
		public ItemStack getStack(int slot) {
			if(slot == PRICE_SLOT) return price;
			if(slot == GOOD_SLOT) return good;

			return realInventory.getStack(slot);
		}

		@Override
		public ItemStack removeStack(int slot, int amount) {
			if(slot == PRICE_SLOT) {
				price.split(amount);
				return ItemStack.EMPTY;
			}
			if(slot == GOOD_SLOT) {
				good.split(amount);
				return ItemStack.EMPTY;
			}

			return realInventory.removeStack(slot, amount);
		}

		@Override
		public ItemStack removeStack(int slot) {
			if(slot == PRICE_SLOT) {
				price = ItemStack.EMPTY;
				sync();
				return ItemStack.EMPTY;
			}
			if(slot == GOOD_SLOT) {
				good = ItemStack.EMPTY;
				sync();
				return ItemStack.EMPTY;
			}

			return realInventory.removeStack(slot);
		}

		@Override
		public void setStack(int slot, ItemStack stack) {
			if(slot == PRICE_SLOT) {
				price = stack;
				sync();
				return;
			}
			if(slot == GOOD_SLOT) {
				good = stack;
				sync();
				return;
			}

			realInventory.setStack(slot, stack);

		}

		@Override
		public void markDirty() {
			realInventory.markDirty();
		}

		@Override
		public boolean canPlayerUse(PlayerEntity player) {
			return realInventory.canPlayerUse(player);
		}

		@Override
		public void clear() {
			price = ItemStack.EMPTY;
			good = ItemStack.EMPTY;
			realInventory.clear();
			sync();
		}
	}

	public class RealInventory implements Inventory {
		@Override
		public boolean canPlayerUse(PlayerEntity player) {
			return owner == null || owner.equals(player.getUuid());
		}

		@Override
		public void setStack(int slot, ItemStack stack) {
			invStacks.set(slot, stack);
		}

		@Override
		public void markDirty() {
			VendingBlockEntity.this.markDirty();
		}

		@Override
		public ItemStack getStack(int slot) {
			return invStacks.get(slot);
		}

		@Override
		public ItemStack removeStack(int slot, int amount) {
			ItemStack result = Inventories.splitStack(invStacks, slot, amount);
			if(!result.isEmpty()) markDirty();

			return result;
		}

		@Override
		public ItemStack removeStack(int slot) {
			return Inventories.removeStack(invStacks, slot);
		}

		@Override
		public boolean isEmpty() {
			return invStacks.stream().allMatch(ItemStack::isEmpty);
		}

		@Override
		public int size() {
			return REAL_INV_SIZE;
		}

		@Override
		public void clear() {
			invStacks.clear();
		}
	}
}

M src/main/java/click/vpzom/mods/retail/VendingBlockScreenHandler.java => src/main/java/click/vpzom/mods/retail/VendingBlockScreenHandler.java +4 -4
@@ 19,11 19,11 @@ public class VendingBlockScreenHandler extends ScreenHandler {
	private final Inventory inventory;

	public VendingBlockScreenHandler(int syncID, PlayerInventory playerInventory, PacketByteBuf buf) {
		this(syncID, playerInventory, new PartialGhostInventory(VendingBlockEntity.FULL_INV_SIZE, VendingBlockEntity.REAL_INV_SIZE), buf.readBoolean());
		this(syncID, playerInventory, new PartialGhostInventory(VendingBlockEntity.UI_INV_SIZE, VendingBlockEntity.REAL_INV_SIZE), buf.readBoolean());
	}

	public VendingBlockScreenHandler(int syncID, PlayerInventory playerInventory, VendingBlockEntity be) {
		this(syncID, playerInventory, be, be.isCreative());
		this(syncID, playerInventory, be.uiInventory, be.isCreative());
	}

	public VendingBlockScreenHandler(int syncID, PlayerInventory playerInventory, Inventory inventory, boolean isCreative) {


@@ 161,10 161,10 @@ public class VendingBlockScreenHandler extends ScreenHandler {
			if(!itemStack2.isEmpty()) {
				itemStack = itemStack2.copy();
				if (adjusted < VendingBlockEntity.REAL_INV_SIZE) {
					if (!this.insertItem(itemStack2, VendingBlockEntity.FULL_INV_SIZE, this.slots.size(), true)) {
					if (!this.insertItem(itemStack2, VendingBlockEntity.UI_INV_SIZE, this.slots.size(), true)) {
						return ItemStack.EMPTY;
					}
				} else if(adjusted < VendingBlockEntity.FULL_INV_SIZE) {
				} else if(adjusted < VendingBlockEntity.UI_INV_SIZE) {
					slot.setStack(ItemStack.EMPTY);
					return ItemStack.EMPTY;
				} else if (!this.insertItem(itemStack2, 0, VendingBlockEntity.REAL_INV_SIZE, false)) {

A src/main/resources/assets/retail/blockstates/exposed_vending_block.json => src/main/resources/assets/retail/blockstates/exposed_vending_block.json +5 -0
@@ 0,0 1,5 @@
{
	"variants": {
		"": {"model": "retail:block/exposed_vending_block"}
	}
}

M src/main/resources/assets/retail/lang/en_us.json => src/main/resources/assets/retail/lang/en_us.json +2 -1
@@ 1,4 1,5 @@
{
	"block.retail.vending_block": "Vending Block",
	"block.retail.creative_vending_block": "Creative Vending Block"
	"block.retail.creative_vending_block": "Creative Vending Block",
	"block.retail.exposed_vending_block": "Exposed Vending Block"
}

A src/main/resources/assets/retail/models/block/exposed_vending_block.json => src/main/resources/assets/retail/models/block/exposed_vending_block.json +34 -0
@@ 0,0 1,34 @@
{
	"parent": "block/block",
	"textures": {
		"base": "minecraft:block/hopper_inside",
		"box": "retail:block/shortglass",
		"top": "retail:block/smallglass",
		"particle": "#base"
	},
	"elements": [
		{
			"from": [0, 0, 0],
			"to": [16, 1, 16],
			"faces": {
				"down": {"texture": "#base"},
				"up": {"texture": "#base"},
				"north": {"texture": "#base"},
				"south": {"texture": "#base"},
				"west": {"texture": "#base"},
				"east": {"texture": "#base"}
			}
		},
		{
			"from": [1, 1, 1],
			"to": [15, 16, 15],
			"faces": {
				"up": {"texture": "#top"},
				"north": {"texture": "#box"},
				"south": {"texture": "#box"},
				"west": {"texture": "#box"},
				"east": {"texture": "#box"}
			}
		}
	]
}

A src/main/resources/assets/retail/models/item/exposed_vending_block.json => src/main/resources/assets/retail/models/item/exposed_vending_block.json +3 -0
@@ 0,0 1,3 @@
{
	"parent": "retail:block/exposed_vending_block"
}

A src/main/resources/data/retail/loot_tables/blocks/exposed_vending_block.json => src/main/resources/data/retail/loot_tables/blocks/exposed_vending_block.json +14 -0
@@ 0,0 1,14 @@
{
	"type": "minecraft:block",
	"pools": [
		{
			"rolls": 1,
			"entries": [
				{
					"type": "minecraft:item",
					"name": "retail:exposed_vending_block"
				}
			]
		}
	]
}

A src/main/resources/data/retail/recipes/exposed_vending_block.json => src/main/resources/data/retail/recipes/exposed_vending_block.json +14 -0
@@ 0,0 1,14 @@
{
	"type": "minecraft:crafting_shaped",
	"pattern": [
		"ggg",
		"gcg",
		"iii"
	],
	"key": {
		"g": {"item": "minecraft:glass"},
		"c": {"item": "minecraft:comparator"},
		"i": {"item": "minecraft:hopper"}
	},
	"result": {"item": "retail:exposed_vending_block"}
}