From 05a6051f22c72862b50f8953dc0ce96f7f049c91 Mon Sep 17 00:00:00 2001 From: kuroppoi <68156848+kuroppoi@users.noreply.github.com> Date: Sat, 24 Apr 2021 20:37:57 +0200 Subject: [PATCH] Inventory persistence & jetpack sync (WIP) --- .../gameserver/entity/player/Inventory.java | 75 +++++++++++++++++-- .../entity/player/ItemContainer.java | 4 + .../gameserver/entity/player/Player.java | 15 ++-- .../gameserver/item/ItemUseType.java | 1 + 4 files changed, 85 insertions(+), 10 deletions(-) diff --git a/gameserver/src/main/java/brainwine/gameserver/entity/player/Inventory.java b/gameserver/src/main/java/brainwine/gameserver/entity/player/Inventory.java index 12c3819..262216d 100644 --- a/gameserver/src/main/java/brainwine/gameserver/entity/player/Inventory.java +++ b/gameserver/src/main/java/brainwine/gameserver/entity/player/Inventory.java @@ -1,23 +1,51 @@ package brainwine.gameserver.entity.player; +import java.beans.ConstructorProperties; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; + import brainwine.gameserver.item.Item; import brainwine.gameserver.item.ItemRegistry; +import brainwine.gameserver.item.ItemUseType; +import brainwine.gameserver.server.messages.EntityChangeMessage; import brainwine.gameserver.server.messages.InventoryMessage; public class Inventory { + @JsonProperty("items") private final Map items = new HashMap<>(); - private final ItemContainer hotbar = new ItemContainer(10); - public Inventory() { - for(Item item : ItemRegistry.getItems()) { - items.put(item, 9999); + // TODO clean up, perhaps just merge with inventory somehow. + private final ItemContainer hotbar = new ItemContainer(10); + private final ItemContainer accessories = new ItemContainer(20); + + @JsonBackReference + private Player player; + + public Inventory(Player player) { + this.player = player; + addItem(ItemRegistry.getItem("tools/pickaxe")); // default pickaxe TODO move elsewhere, this is for convenience only. + } + + @ConstructorProperties({"hotbar", "accessories"}) + private Inventory(Item[] hotbar, Item[] accessories) { + if(hotbar != null) { + for(int i = 0; i < hotbar.length; i++) { + this.hotbar.moveItem(hotbar[i], i); + } + } + + if(accessories != null) { + for(int i = 0; i < accessories.length; i++) { + this.accessories.moveItem(accessories[i], i); + } } } @@ -27,12 +55,17 @@ public class Inventory { moveItemToContainer(item, hotbar, slot); break; case ACCESSORIES: + moveItemToContainer(item, accessories, slot); break; } } public void moveItemToContainer(Item item, ItemContainer container, int slot) { container.moveItem(item, slot); + + if(container == accessories) { + player.sendMessageToPeers(new EntityChangeMessage(player.getId(), player.getStatusConfig())); + } } public void addItem(Item item) { @@ -52,7 +85,13 @@ public class Inventory { } public void setItem(Item item, int quantity) { - items.put(item, quantity); + if(quantity <= 0) { + items.remove(item); + } else { + items.put(item, quantity); + } + + player.sendMessage(new InventoryMessage(getClientConfig(item))); } public boolean hasItem(Item item) { @@ -63,6 +102,29 @@ public class Inventory { return items.getOrDefault(item, 0); } + public boolean isEmpty() { + return items.isEmpty(); + } + + public Item findJetpack() { + for(Item item : accessories.getItems()) { + if(item.hasUse(ItemUseType.FLY)) { + return item; + } + } + + return Item.AIR; + } + + @JsonValue + public Map getJsonValue() { + Map map = new HashMap<>(); + map.put("items", items); + map.put("hotbar", hotbar.getItems()); + map.put("accessories", accessories.getItems()); + return map; + } + /** * @return A {@link Map} containing all the data necessary for use in {@link InventoryMessage}. */ @@ -79,6 +141,9 @@ public class Inventory { if((slot = hotbar.getSlot(item)) != -1) { itemData.add(ContainerType.HOTBAR.getId()); itemData.add(slot); + } else if((slot = accessories.getSlot(item)) != -1) { + itemData.add(ContainerType.ACCESSORIES.getId()); + itemData.add(slot); } data.put(String.valueOf(item.getId()), itemData); diff --git a/gameserver/src/main/java/brainwine/gameserver/entity/player/ItemContainer.java b/gameserver/src/main/java/brainwine/gameserver/entity/player/ItemContainer.java index 50d7b48..c769d2f 100644 --- a/gameserver/src/main/java/brainwine/gameserver/entity/player/ItemContainer.java +++ b/gameserver/src/main/java/brainwine/gameserver/entity/player/ItemContainer.java @@ -59,4 +59,8 @@ public class ItemContainer { return -1; } + + public Item[] getItems() { + return items; + } } diff --git a/gameserver/src/main/java/brainwine/gameserver/entity/player/Player.java b/gameserver/src/main/java/brainwine/gameserver/entity/player/Player.java index 3dee8b9..20abc86 100644 --- a/gameserver/src/main/java/brainwine/gameserver/entity/player/Player.java +++ b/gameserver/src/main/java/brainwine/gameserver/entity/player/Player.java @@ -1,5 +1,6 @@ package brainwine.gameserver.entity.player; +import java.beans.ConstructorProperties; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -9,13 +10,12 @@ import java.util.Map.Entry; import java.util.Set; import com.fasterxml.jackson.annotation.JacksonInject; -import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIncludeProperties; +import com.fasterxml.jackson.annotation.JsonManagedReference; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonValue; import brainwine.gameserver.GameConfiguration; -import brainwine.gameserver.GameServer; import brainwine.gameserver.command.CommandExecutor; import brainwine.gameserver.dialog.ConfigurableDialog; import brainwine.gameserver.entity.Entity; @@ -50,9 +50,8 @@ import brainwine.gameserver.util.MathUtils; import brainwine.gameserver.zone.Chunk; import brainwine.gameserver.zone.MetaBlock; import brainwine.gameserver.zone.Zone; -import brainwine.gameserver.zone.ZoneManager; -@JsonIncludeProperties({"name", "email", "password_hash", "token_hash", "admin", "karma", "equipped_clothing", "equipped_colors"}) +@JsonIncludeProperties({"name", "email", "password_hash", "token_hash", "admin", "karma", "inventory", "equipped_clothing", "equipped_colors", "current_zone"}) public class Player extends Entity implements CommandExecutor { public static final int MAX_SKILL_LEVEL = 15; @@ -80,6 +79,10 @@ public class Player extends Entity implements CommandExecutor { @JsonProperty("karma") private int karma; + @JsonManagedReference + @JsonProperty("inventory") + private final Inventory inventory = new Inventory(this); + @JsonProperty("equipped_clothing") private final Map clothing = new HashMap<>(); @@ -535,7 +538,8 @@ public class Player extends Entity implements CommandExecutor { map.put("karma", karma); map.put("current_zone", zone.getDocumentId()); map.put("equipped_colors", colors); - map.put("equipped_clothing", clothing); + map.put("equipped_clothing", clothing); + map.put("inventory", inventory); return map; } @@ -549,6 +553,7 @@ public class Player extends Entity implements CommandExecutor { appearance.put(entry.getKey().getId(), entry.getValue()); } + appearance.put(ClothingSlot.SUIT.getId(), inventory.findJetpack().getId()); // Jetpack return appearance; } diff --git a/gameserver/src/main/java/brainwine/gameserver/item/ItemUseType.java b/gameserver/src/main/java/brainwine/gameserver/item/ItemUseType.java index c448bd6..002f40e 100644 --- a/gameserver/src/main/java/brainwine/gameserver/item/ItemUseType.java +++ b/gameserver/src/main/java/brainwine/gameserver/item/ItemUseType.java @@ -9,6 +9,7 @@ public enum ItemUseType { CREATE_DIALOG, DIALOG, CHANGE, + FLY, TELEPORT, ZONE_TELEPORT,