Skip to content

Commit

Permalink
feat: implement Pouch and Backpack
Browse files Browse the repository at this point in the history
  • Loading branch information
oddlama committed Sep 15, 2022
1 parent 48e74b0 commit fc63db5
Show file tree
Hide file tree
Showing 17 changed files with 442 additions and 11 deletions.
Binary file added contrib/assets/backpack/backpack.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added contrib/assets/pouch/pouch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
public class RecipeList implements ConfigDictSerializable {
private List<RecipeDefinition> recipes = new ArrayList<>();

public RecipeList() { }
public RecipeList(List<RecipeDefinition> recipes) {
this.recipes = recipes;
}

public List<RecipeDefinition> recipes() {
return recipes;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,19 +100,28 @@ private void write_translations(final ZipOutputStream zip) throws IOException {

private JSONObject create_item_model_handheld(NamespacedKey texture) {
// Create model json
final var textures = new JSONObject();
// FIXME: hardcoded fix for compasses. better rewrite RP generator
final var model = new JSONObject();

// FIXME: hardcoded fixes. better rewrite RP generator
// and use static files for all items. just language should be generated.
if (texture.getNamespace().equals("minecraft") && texture.getKey().equals("compass")) {
textures.put("layer0", texture.getNamespace() + ":item/compass_16");
if (texture.getNamespace().equals("minecraft") && texture.getKey().equals("dropper")) {
model.put("parent", "minecraft:block/dropper");
} else if (texture.getNamespace().equals("minecraft") && texture.getKey().endsWith("shulker_box")) {
model.put("parent", "minecraft:item/template_shulker_box");
final var textures = new JSONObject();
textures.put("particle", "minecraft:block/" + texture.getKey());
model.put("textures", textures);
} else {
textures.put("layer0", texture.getNamespace() + ":item/" + texture.getKey());
model.put("parent", "minecraft:item/handheld");
final var textures = new JSONObject();
if (texture.getNamespace().equals("minecraft") && texture.getKey().equals("compass")) {
textures.put("layer0", texture.getNamespace() + ":item/compass_16");
} else {
textures.put("layer0", texture.getNamespace() + ":item/" + texture.getKey());
}
model.put("textures", textures);
}

final var model = new JSONObject();
model.put("parent", "minecraft:item/handheld");
model.put("textures", textures);

return model;
}

Expand Down
4 changes: 4 additions & 0 deletions vane-core/src/main/java/org/oddlama/vane/util/BlockUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,10 @@ public static RaytraceDominantFaceResult raytrace_dominant_face(final LivingEnti

public static String texture_from_skull(final Skull skull) {
final var profile = skull.getPlayerProfile();
if (profile == null) {
return null;
}

for (final var property : profile.getProperties()) {
if ("textures".equals(property.getName())) {
return property.getValue();
Expand Down
211 changes: 211 additions & 0 deletions vane-trifles/src/main/java/org/oddlama/vane/trifles/StorageGroup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
package org.oddlama.vane.trifles;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang3.tuple.Pair;
import org.bukkit.Nameable;
import org.bukkit.block.Container;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.oddlama.vane.annotation.lang.LangMessage;
import org.oddlama.vane.core.Listener;
import org.oddlama.vane.core.lang.TranslatedMessage;
import org.oddlama.vane.core.module.Context;

import net.kyori.adventure.text.Component;

public class StorageGroup extends Listener<Trifles> {
private Map<Inventory, Pair<UUID, ItemStack>> open_block_state_inventories = Collections
.synchronizedMap(new HashMap<Inventory, Pair<UUID, ItemStack>>());

@LangMessage
public TranslatedMessage lang_open_stacked_item;

public StorageGroup(Context<Trifles> context) {
super(context.group("storage", "Extensions to storage related stuff will be grouped under here."));
}

@SuppressWarnings("deprecation")
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void on_place_item_in_storage_inventory(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player player)) {
return;
}

// Only if no block state inventory is open, else we could delete items by accident
final var owner_and_item = open_block_state_inventories.get(event.getInventory());
if (owner_and_item != null) {
return;
}

// Put non-storage items in a right-clicked storage item
if (event.getClick() == ClickType.RIGHT && event.getAction() == InventoryAction.SWAP_WITH_CURSOR
&& is_storage_item(event.getCurrentItem())) {

// Allow putting in any items that are not a storage item, or storage items that have nothing in them.
if (!(is_storage_item(event.getCursor()) && event.getCursor().hasItemMeta())) {
final var custom_item = get_module().core.item_registry().get(event.getCurrentItem());

// Only if the clicked storage item is a custom item
if (custom_item != null) {
event.getCurrentItem().editMeta(BlockStateMeta.class, meta -> {
final var block_state = meta.getBlockState();
if (block_state instanceof Container container) {
final var leftovers = container.getInventory().addItem(event.getCursor());
if (leftovers.size() == 0) {
event.setCursor(null);
} else {
event.setCursor(leftovers.get(0));
}
meta.setBlockState(block_state);
}
});
}
}

// right-clicking a storage item to swap is never "allowed".
event.setCancelled(true);
return;
}
}

@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void on_inventory_click(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player player)) {
return;
}

final var owner_and_item = open_block_state_inventories.get(event.getInventory());
if (owner_and_item == null || !owner_and_item.getLeft().equals(player.getUniqueId())) {
return;
}

// Prevent putting non-empty storage items in other storage items
if (is_storage_item(event.getCurrentItem()) || (is_storage_item(event.getCursor()) && event.getCursor().hasItemMeta())) {
event.setCancelled(true);
return;
}
}

@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void on_inventory_drag(InventoryDragEvent event) {
if (!(event.getWhoClicked() instanceof Player player)) {
return;
}

final var owner_and_item = open_block_state_inventories.get(event.getInventory());
if (owner_and_item == null || !owner_and_item.getLeft().equals(player.getUniqueId())) {
return;
}

// Prevent putting storage items in other storage items
for (final var item_stack : event.getNewItems().values()) {
if (is_storage_item(item_stack)) {
event.setCancelled(true);
return;
}
}
}

@EventHandler(priority = EventPriority.MONITOR)
public void save_after_click(InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player player)) {
return;
}

final var owner_and_item = open_block_state_inventories.get(event.getInventory());
if (owner_and_item == null || !owner_and_item.getLeft().equals(player.getUniqueId())) {
return;
}

update_storage_item(owner_and_item.getRight(), event.getInventory());
}

@EventHandler(priority = EventPriority.MONITOR)
public void save_after_drag(InventoryDragEvent event) {
if (!(event.getWhoClicked() instanceof Player player)) {
return;
}

final var owner_and_item = open_block_state_inventories.get(event.getInventory());
if (owner_and_item == null || !owner_and_item.getLeft().equals(player.getUniqueId())) {
return;
}

update_storage_item(owner_and_item.getRight(), event.getInventory());
}

@EventHandler(priority = EventPriority.MONITOR)
public void save_after_close(InventoryCloseEvent event) {
final var owner_and_item = open_block_state_inventories.get(event.getInventory());
if (owner_and_item == null || !owner_and_item.getLeft().equals(event.getPlayer().getUniqueId())) {
return;
}

update_storage_item(owner_and_item.getRight(), event.getInventory());
open_block_state_inventories.remove(event.getInventory());
}

private boolean is_storage_item(@Nullable ItemStack item) {
// Any item that has a container block state as the meta is a container to us.
// If the item has no meta (i.e. is empty) it doesnt count.
return item != null
&& item.getItemMeta() instanceof BlockStateMeta meta
&& meta.getBlockState() instanceof Container;
}

private void update_storage_item(@NotNull ItemStack item, @NotNull Inventory inventory) {
item.editMeta(BlockStateMeta.class, meta -> {
final var block_state = meta.getBlockState();
if (block_state instanceof Container container) {
container.getInventory().setContents(inventory.getContents());
meta.setBlockState(block_state);
}
});
}

public boolean open_block_state_inventory(@NotNull final Player player, @NotNull ItemStack item) {
// Require correct block state meta
if (!(item.getItemMeta() instanceof BlockStateMeta meta)
|| !(meta.getBlockState() instanceof Container container)) {
return false;
}

// Only if the stack size is 1.
if (item.getAmount() != 1) {
get_module().storage_group.lang_open_stacked_item.send_action_bar(player);
return false;
}

// Transfer item name to block-state
Component name = null;
if (meta.getBlockState() instanceof Nameable nameable) {
name = meta.hasDisplayName() ? meta.displayName() : null;
nameable.customName(name);
}

// Create transient inventory
final var transient_inventory = get_module().getServer().createInventory(player,
container.getInventory().getType(), name);
transient_inventory.setContents(container.getInventory().getContents());

// Open inventory
open_block_state_inventories.put(transient_inventory, Pair.of(player.getUniqueId(), item));
player.openInventory(transient_inventory);
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ public class Trifles extends Module<Trifles> {
public final HashMap<UUID, Long> last_xp_bottle_consume_time = new HashMap<>();
public XpBottles xp_bottles;
public ItemFinder item_finder;
public StorageGroup storage_group;

public Trifles() {
var fast_walking_group = new FastWalkingGroup(this);
final var fast_walking_group = new FastWalkingGroup(this);
new FastWalkingListener(fast_walking_group);
new DoubleDoorListener(this);
new HarvestListener(this);
Expand All @@ -37,5 +38,9 @@ public Trifles() {
new org.oddlama.vane.trifles.items.Trowel(this);
new org.oddlama.vane.trifles.items.NorthCompass(this);
new org.oddlama.vane.trifles.items.SlimeBucket(this);

storage_group = new StorageGroup(this);
new org.oddlama.vane.trifles.items.storage.Pouch(storage_group.get_context());
new org.oddlama.vane.trifles.items.storage.Backpack(storage_group.get_context());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.oddlama.vane.annotation.item.VaneItem;
import org.oddlama.vane.core.item.CustomItem;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.oddlama.vane.trifles.items;

import static org.oddlama.vane.util.ItemUtil.damage_item;
import static org.oddlama.vane.util.PlayerUtil.swing_arm;

import java.util.ArrayList;
Expand Down Expand Up @@ -231,6 +232,7 @@ public void on_player_interact_block(final PlayerInteractEvent event) {

if (result.consumesAction()) {
swing_arm(player, EquipmentSlot.HAND);
damage_item(player, item_in_hand, 1);
if (sound_type != null) {
nms_world.playSound(null, block_pos, sound_type.getPlaceSound(), SoundSource.BLOCKS, (sound_type.getVolume() + 1.0F) / 2.0F, sound_type.getPitch() * 0.8F);
}
Expand Down
Loading

0 comments on commit fc63db5

Please sign in to comment.