Save and load items
This commit is contained in:
parent
627e533e9c
commit
d12bf53972
8 changed files with 245 additions and 53 deletions
|
@ -2,12 +2,19 @@ package me.unurled.sacredrealms.sr.components.item;
|
||||||
|
|
||||||
import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
import static me.unurled.sacredrealms.sr.utils.Component.comp;
|
||||||
import static me.unurled.sacredrealms.sr.utils.Items.lore;
|
import static me.unurled.sacredrealms.sr.utils.Items.lore;
|
||||||
|
import static me.unurled.sacredrealms.sr.utils.Logger.error;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
import me.unurled.sacredrealms.sr.components.attributes.Attribute;
|
||||||
import me.unurled.sacredrealms.sr.components.item.abilities.Ability;
|
import me.unurled.sacredrealms.sr.components.item.abilities.Ability;
|
||||||
import me.unurled.sacredrealms.sr.components.item.enchantments.Enchantment;
|
import me.unurled.sacredrealms.sr.components.item.enchantments.Enchantment;
|
||||||
|
import me.unurled.sacredrealms.sr.data.gson.AbilityDeserializer;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
@ -38,7 +45,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
* */
|
* */
|
||||||
public class Item {
|
public class Item {
|
||||||
|
|
||||||
@NotNull private final String ID;
|
@NotNull private String ID;
|
||||||
|
|
||||||
@NotNull private String name;
|
@NotNull private String name;
|
||||||
|
|
||||||
|
@ -50,12 +57,27 @@ public class Item {
|
||||||
|
|
||||||
@NotNull private Rarity rarity;
|
@NotNull private Rarity rarity;
|
||||||
|
|
||||||
|
@NotNull private ItemType type;
|
||||||
|
|
||||||
@NotNull private HashMap<Attribute, Double> attributes;
|
@NotNull private HashMap<Attribute, Double> attributes;
|
||||||
|
|
||||||
@NotNull private HashMap<Enchantment, Integer> enchantments;
|
@NotNull private HashMap<Enchantment, Integer> enchantments;
|
||||||
|
|
||||||
@NotNull private List<Ability> abilities;
|
@NotNull private List<Ability> abilities;
|
||||||
|
|
||||||
|
public Item() {
|
||||||
|
this.ID = "";
|
||||||
|
this.name = "";
|
||||||
|
this.material = Material.AIR;
|
||||||
|
this.description = "";
|
||||||
|
this.rarity = Rarity.COMMON;
|
||||||
|
this.customModelData = 0;
|
||||||
|
this.abilities = List.of();
|
||||||
|
this.attributes = new HashMap<>();
|
||||||
|
this.enchantments = new HashMap<>();
|
||||||
|
this.type = ItemType.MISC;
|
||||||
|
}
|
||||||
|
|
||||||
public Item(@NotNull String ID, @NotNull String name, @NotNull Material material) {
|
public Item(@NotNull String ID, @NotNull String name, @NotNull Material material) {
|
||||||
this.ID = ID;
|
this.ID = ID;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -66,6 +88,7 @@ public class Item {
|
||||||
this.abilities = List.of();
|
this.abilities = List.of();
|
||||||
this.attributes = new HashMap<>();
|
this.attributes = new HashMap<>();
|
||||||
this.enchantments = new HashMap<>();
|
this.enchantments = new HashMap<>();
|
||||||
|
this.type = ItemType.MISC;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @NotNull String getID() {
|
public @NotNull String getID() {
|
||||||
|
@ -189,24 +212,55 @@ public class Item {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "{"
|
return "{"
|
||||||
+ "ID: "
|
+ "\"id\": \""
|
||||||
+ ID
|
+ ID
|
||||||
+ ", name: "
|
+ "\", \"name\": \""
|
||||||
+ name
|
+ name
|
||||||
+ ", material: "
|
+ "\", \"material\": \""
|
||||||
+ material
|
+ material
|
||||||
+ ", description: "
|
+ "\", \"description\": \""
|
||||||
+ description
|
+ description
|
||||||
+ ", customModelData: "
|
+ "\", \"customModelData\": "
|
||||||
+ customModelData
|
+ customModelData
|
||||||
+ ", rarity: "
|
+ "\", \"rarity\": \""
|
||||||
+ rarity
|
+ rarity
|
||||||
+ ", attributes: "
|
+ "\", \"type\": \""
|
||||||
|
+ type
|
||||||
|
+ "\", \"attributes\": \""
|
||||||
+ attributes
|
+ attributes
|
||||||
+ ", enchantments: "
|
+ "\", \"enchantments\": \""
|
||||||
+ enchantments
|
+ enchantments
|
||||||
+ ", abilities: "
|
+ "\", \"abilities\": \""
|
||||||
+ abilities
|
+ abilities
|
||||||
+ "}";
|
+ "\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fromString(String item) {
|
||||||
|
// extract every information from the string (it follows the same format as the toString method)
|
||||||
|
Gson gson =
|
||||||
|
new GsonBuilder().registerTypeAdapter(Ability.class, new AbilityDeserializer()).create();
|
||||||
|
try {
|
||||||
|
Map<String, Object> map =
|
||||||
|
gson.fromJson(item, new TypeToken<Map<String, Object>>() {}.getType());
|
||||||
|
|
||||||
|
this.ID = (String) map.get("id");
|
||||||
|
this.name = (String) map.get("name");
|
||||||
|
this.material = Material.valueOf((String) map.get("material"));
|
||||||
|
this.description = (String) map.get("description");
|
||||||
|
this.customModelData = ((Double) map.get("customModelData")).intValue();
|
||||||
|
this.rarity = Rarity.valueOf((String) map.get("rarity"));
|
||||||
|
this.type = ItemType.valueOf((String) map.get("type"));
|
||||||
|
|
||||||
|
Type attributeType = new TypeToken<HashMap<Attribute, Double>>() {}.getType();
|
||||||
|
this.attributes = gson.fromJson((String) map.get("attributes"), attributeType);
|
||||||
|
|
||||||
|
Type enchantmentType = new TypeToken<HashMap<Enchantment, Integer>>() {}.getType();
|
||||||
|
this.enchantments = gson.fromJson((String) map.get("enchantments"), enchantmentType);
|
||||||
|
|
||||||
|
Type abilityType = new TypeToken<List<Ability>>() {}.getType();
|
||||||
|
this.abilities = gson.fromJson((String) map.get("abilities"), abilityType);
|
||||||
|
} catch (Exception e) {
|
||||||
|
error("Failed to parse item from string: " + item + "\n" + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
package me.unurled.sacredrealms.sr.components.item;
|
package me.unurled.sacredrealms.sr.components.item;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import me.unurled.sacredrealms.sr.data.DataHandler;
|
||||||
|
import me.unurled.sacredrealms.sr.data.DataManager;
|
||||||
|
import me.unurled.sacredrealms.sr.data.gson.ItemDeserializer;
|
||||||
|
import me.unurled.sacredrealms.sr.data.gson.ItemStackSerializer;
|
||||||
import me.unurled.sacredrealms.sr.managers.Manager;
|
import me.unurled.sacredrealms.sr.managers.Manager;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
@ -17,14 +23,41 @@ public class ItemManager extends Manager {
|
||||||
items = new HashMap<>();
|
items = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Register all the items */
|
|
||||||
private void registerItems() {}
|
|
||||||
|
|
||||||
/** Load the manager */
|
/** Load the manager */
|
||||||
@Override
|
@Override
|
||||||
public void load() {
|
public void load() {
|
||||||
super.load();
|
super.load();
|
||||||
registerItems();
|
}
|
||||||
|
|
||||||
|
/** Save the data */
|
||||||
|
@Override
|
||||||
|
public void saveData() {
|
||||||
|
DataManager dm = DataManager.getInstance(DataManager.class);
|
||||||
|
DataHandler dh = dm.getDataHandler();
|
||||||
|
|
||||||
|
Gson gson =
|
||||||
|
new GsonBuilder().registerTypeAdapter(Item.class, new ItemStackSerializer()).create();
|
||||||
|
|
||||||
|
items.forEach(
|
||||||
|
(id, item) -> {
|
||||||
|
dh.set("sr.items." + id, gson.toJson(item));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Load the data */
|
||||||
|
@Override
|
||||||
|
public void loadData() {
|
||||||
|
DataManager dm = DataManager.getInstance(DataManager.class);
|
||||||
|
DataHandler dh = dm.getDataHandler();
|
||||||
|
|
||||||
|
Gson gson = new GsonBuilder().registerTypeAdapter(Item.class, new ItemDeserializer()).create();
|
||||||
|
|
||||||
|
dh.getKeysAll("sr.items")
|
||||||
|
.forEach(
|
||||||
|
key -> {
|
||||||
|
Item item = gson.fromJson(dh.get(key), Item.class);
|
||||||
|
items.put(item.getID(), item);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addItem(Item item) {
|
public void addItem(Item item) {
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package me.unurled.sacredrealms.sr.components.item;
|
||||||
|
|
||||||
|
public enum ItemType {
|
||||||
|
WEAPON,
|
||||||
|
ARMOR,
|
||||||
|
CONSUMABLE,
|
||||||
|
MISC
|
||||||
|
}
|
|
@ -1,41 +1,26 @@
|
||||||
package me.unurled.sacredrealms.sr.components.item.abilities;
|
package me.unurled.sacredrealms.sr.components.item.abilities;
|
||||||
|
|
||||||
|
|
||||||
/** Represents an ability that an item can have. TODO: Implement this class */
|
/** Represents an ability that an item can have. TODO: Implement this class */
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class Ability {
|
public record Ability(
|
||||||
|
|
||||||
private final String name;
|
|
||||||
private final String description;
|
|
||||||
private final Integer cooldown;
|
|
||||||
private final Integer manaCost;
|
|
||||||
private final Integer damage;
|
|
||||||
|
|
||||||
public Ability(
|
|
||||||
String name, String description, Integer cooldown, Integer manaCost, Integer damage) {
|
String name, String description, Integer cooldown, Integer manaCost, Integer damage) {
|
||||||
this.name = name;
|
|
||||||
this.description = description;
|
|
||||||
this.cooldown = cooldown;
|
|
||||||
this.manaCost = manaCost;
|
|
||||||
this.damage = damage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
@Override
|
||||||
return name;
|
public String toString() {
|
||||||
}
|
return "Ability{"
|
||||||
|
+ "name='"
|
||||||
public String getDescription() {
|
+ name
|
||||||
return description;
|
+ '\''
|
||||||
}
|
+ ", description='"
|
||||||
|
+ description
|
||||||
public Integer getCooldown() {
|
+ '\''
|
||||||
return cooldown;
|
+ ", cooldown="
|
||||||
}
|
+ cooldown
|
||||||
|
+ ", manaCost="
|
||||||
public Integer getManaCost() {
|
+ manaCost
|
||||||
return manaCost;
|
+ ", damage="
|
||||||
}
|
+ damage
|
||||||
|
+ '}';
|
||||||
public Integer getDamage() {
|
|
||||||
return damage;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package me.unurled.sacredrealms.sr.data.gson;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import me.unurled.sacredrealms.sr.components.item.abilities.Ability;
|
||||||
|
|
||||||
|
public class AbilityDeserializer implements JsonDeserializer<Ability> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gson invokes this call-back method during deserialization when it encounters a field of the
|
||||||
|
* specified type.
|
||||||
|
*
|
||||||
|
* <p>In the implementation of this call-back method, you should consider invoking {@link
|
||||||
|
* JsonDeserializationContext#deserialize(JsonElement, Type)} method to create objects for any
|
||||||
|
* non-trivial field of the returned object. However, you should never invoke it on the same type
|
||||||
|
* passing {@code json} since that will cause an infinite loop (Gson will call your call-back
|
||||||
|
* method again).
|
||||||
|
*
|
||||||
|
* @param json The Json data being deserialized
|
||||||
|
* @param typeOfT The type of the Object to deserialize to
|
||||||
|
* @param context
|
||||||
|
* @return a deserialized object of the specified type typeOfT which is a subclass of {@code T}
|
||||||
|
* @throws JsonParseException if json is not in the expected format of {@code typeofT}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Ability deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
try {
|
||||||
|
JsonObject jsonObject = json.getAsJsonObject();
|
||||||
|
|
||||||
|
String name = jsonObject.get("name").getAsString();
|
||||||
|
String description = jsonObject.get("description").getAsString();
|
||||||
|
Integer cooldown = jsonObject.get("cooldown").getAsInt();
|
||||||
|
Integer manaCost = jsonObject.get("manaCost").getAsInt();
|
||||||
|
Integer damage = jsonObject.get("damage").getAsInt();
|
||||||
|
|
||||||
|
return new Ability(name, description, cooldown, manaCost, damage);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new JsonParseException("Error deserializing Ability: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package me.unurled.sacredrealms.sr.data.gson;
|
||||||
|
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import me.unurled.sacredrealms.sr.components.item.Item;
|
||||||
|
|
||||||
|
public class ItemDeserializer implements JsonDeserializer<Item> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gson invokes this call-back method during deserialization when it encounters a field of the
|
||||||
|
* specified type.
|
||||||
|
*
|
||||||
|
* <p>In the implementation of this call-back method, you should consider invoking {@link
|
||||||
|
* JsonDeserializationContext#deserialize(JsonElement, Type)} method to create objects for any
|
||||||
|
* non-trivial field of the returned object. However, you should never invoke it on the same type
|
||||||
|
* passing {@code json} since that will cause an infinite loop (Gson will call your call-back
|
||||||
|
* method again).
|
||||||
|
*
|
||||||
|
* @param json The Json data being deserialized
|
||||||
|
* @param typeOfT The type of the Object to deserialize to
|
||||||
|
* @param context
|
||||||
|
* @return a deserialized object of the specified type typeOfT which is a subclass of {@code T}
|
||||||
|
* @throws JsonParseException if json is not in the expected format of {@code typeofT}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Item deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
Item item = new Item();
|
||||||
|
item.fromString(json.getAsString());
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package me.unurled.sacredrealms.sr.data.gson;
|
||||||
|
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonPrimitive;
|
||||||
|
import com.google.gson.JsonSerializationContext;
|
||||||
|
import com.google.gson.JsonSerializer;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import me.unurled.sacredrealms.sr.components.item.Item;
|
||||||
|
|
||||||
|
public class ItemSerializer implements JsonSerializer<Item> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gson invokes this call-back method during serialization when it encounters a field of the
|
||||||
|
* specified type.
|
||||||
|
*
|
||||||
|
* <p>In the implementation of this call-back method, you should consider invoking {@link
|
||||||
|
* JsonSerializationContext#serialize(Object, Type)} method to create JsonElements for any
|
||||||
|
* non-trivial field of the {@code src} object. However, you should never invoke it on the {@code
|
||||||
|
* src} object itself since that will cause an infinite loop (Gson will call your call-back method
|
||||||
|
* again).
|
||||||
|
*
|
||||||
|
* @param src the object that needs to be converted to Json.
|
||||||
|
* @param typeOfSrc the actual type (fully genericized version) of the source object.
|
||||||
|
* @param context
|
||||||
|
* @return a JsonElement corresponding to the specified object.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public JsonElement serialize(Item src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src.toString());
|
||||||
|
}
|
||||||
|
}
|
|
@ -102,10 +102,10 @@ public class Items {
|
||||||
item.getAbilities()
|
item.getAbilities()
|
||||||
.forEach(
|
.forEach(
|
||||||
a -> {
|
a -> {
|
||||||
lore.add(comp(" <gray>➤ " + a.getName() + ",<yellow> " + a.getDescription()));
|
lore.add(comp(" <gray>➤ " + a.name() + ",<yellow> " + a.description()));
|
||||||
lore.add(comp(" <dark_gray>cooldown: " + a.getCooldown() + "s,"));
|
lore.add(comp(" <dark_gray>cooldown: " + a.cooldown() + "s,"));
|
||||||
lore.add(comp(" <dark_gray>damage: " + a.getDamage() + ","));
|
lore.add(comp(" <dark_gray>damage: " + a.damage() + ","));
|
||||||
lore.add(comp(" <dark_gray>mana cost: <dark_aqua>" + a.getManaCost()));
|
lore.add(comp(" <dark_gray>mana cost: <dark_aqua>" + a.manaCost()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!item.getEnchantments().isEmpty()) {
|
if (!item.getEnchantments().isEmpty()) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue