|
@@ -1,29 +1,19 @@
|
|
|
package org.leumasjaffe.charsheet.model.inventory;
|
|
package org.leumasjaffe.charsheet.model.inventory;
|
|
|
|
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
|
-import java.util.Collections;
|
|
|
|
|
-import java.util.EnumMap;
|
|
|
|
|
-import java.util.List;
|
|
|
|
|
-import java.util.Map;
|
|
|
|
|
|
|
+import java.util.*;
|
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
+import org.leumasjaffe.charsheet.config.Constants;
|
|
|
import org.leumasjaffe.observer.Observable;
|
|
import org.leumasjaffe.observer.Observable;
|
|
|
|
|
|
|
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
|
import com.fasterxml.jackson.annotation.JsonValue;
|
|
import com.fasterxml.jackson.annotation.JsonValue;
|
|
|
|
|
|
|
|
-import lombok.AccessLevel;
|
|
|
|
|
-import lombok.AllArgsConstructor;
|
|
|
|
|
-import lombok.EqualsAndHashCode;
|
|
|
|
|
-import lombok.Getter;
|
|
|
|
|
-import lombok.NonNull;
|
|
|
|
|
-import lombok.Setter;
|
|
|
|
|
-import lombok.ToString;
|
|
|
|
|
|
|
+import lombok.*;
|
|
|
import lombok.experimental.FieldDefaults;
|
|
import lombok.experimental.FieldDefaults;
|
|
|
|
|
+import lombok.experimental.NonFinal;
|
|
|
|
|
|
|
|
-@Getter
|
|
|
|
|
-@Setter
|
|
|
|
|
-@ToString
|
|
|
|
|
|
|
+@Getter @Setter @ToString
|
|
|
@EqualsAndHashCode(callSuper=false)
|
|
@EqualsAndHashCode(callSuper=false)
|
|
|
@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
|
|
@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
|
|
|
public class DDInventory extends Observable {
|
|
public class DDInventory extends Observable {
|
|
@@ -31,66 +21,83 @@ public class DDInventory extends Observable {
|
|
|
public static class Serializable {
|
|
public static class Serializable {
|
|
|
@NonNull List<DDItem> items;
|
|
@NonNull List<DDItem> items;
|
|
|
@NonNull Map<EquipmentSlot, String> equipment;
|
|
@NonNull Map<EquipmentSlot, String> equipment;
|
|
|
|
|
+ @NonNull Map<String, Map<EquipmentSlot, String>> favorites;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- @NonNull List<DDItem> items;
|
|
|
|
|
- @NonNull Map<EquipmentSlot, DDItem> equipment;
|
|
|
|
|
|
|
+ // Serializable properties
|
|
|
|
|
+ @NonNull List<DDItem> items = new ArrayList<>();
|
|
|
|
|
+ @NonNull Map<EquipmentSlot, DDItem> equipment = new EnumMap<>(EquipmentSlot.class);
|
|
|
|
|
+ @NonNull Map<String, Map<EquipmentSlot, String>> favorites = new TreeMap<>();
|
|
|
|
|
+ // Transient/Record-Keeping properties
|
|
|
|
|
+ @NonNull Map<String, DDItem> named = new HashMap<>();
|
|
|
|
|
+ @NonFinal Map<EquipmentSlot, String> previous = null;
|
|
|
|
|
|
|
|
- public DDInventory() {
|
|
|
|
|
- items = new ArrayList<>();
|
|
|
|
|
- equipment = new EnumMap<>(EquipmentSlot.class);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ public DDInventory() {}
|
|
|
|
|
|
|
|
@JsonCreator
|
|
@JsonCreator
|
|
|
- public DDInventory(DDInventory.Serializable data) {
|
|
|
|
|
- items = new ArrayList<>(data.items);
|
|
|
|
|
- equipment = new EnumMap<>(EquipmentSlot.class);
|
|
|
|
|
- final Map<String, DDItem> named = items.stream().collect(
|
|
|
|
|
- Collectors.toMap(DDItem::getName, i -> i));
|
|
|
|
|
- data.equipment.entrySet().stream().forEach(
|
|
|
|
|
- e -> equipment.put(e.getKey(), named.get(e.getValue())));
|
|
|
|
|
|
|
+ private DDInventory(DDInventory.Serializable data) {
|
|
|
|
|
+ items.addAll(data.items);
|
|
|
|
|
+ named.putAll(items.stream().collect(Collectors.toMap(DDItem::getName, i -> i)));
|
|
|
|
|
+ fromSerializableEquipment(data.equipment);
|
|
|
|
|
+ favorites.putAll(data.favorites);
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
@JsonValue
|
|
@JsonValue
|
|
|
private DDInventory.Serializable getSerial() {
|
|
private DDInventory.Serializable getSerial() {
|
|
|
- final Map<EquipmentSlot, String> m = new EnumMap<>(EquipmentSlot.class);
|
|
|
|
|
- equipment.entrySet().stream().forEach(
|
|
|
|
|
- e -> m.put(e.getKey(), e.getValue().getName())
|
|
|
|
|
- );
|
|
|
|
|
- return new DDInventory.Serializable(items, m);
|
|
|
|
|
|
|
+ return new DDInventory.Serializable(items, getSerializableEquipment(), favorites);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public void load(final String name) {
|
|
|
|
|
+ final @NonNull Map<EquipmentSlot, String> chosen;
|
|
|
|
|
+ if (name.equals(Constants.PREVIOUS_LOADOUT)) { chosen = previous; }
|
|
|
|
|
+ else { chosen = favorites.get(name); }
|
|
|
|
|
+ previous = getSerializableEquipment();
|
|
|
|
|
+ fromSerializableEquipment(chosen);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public void save(final String name) {
|
|
|
|
|
+ favorites.put(name, getSerializableEquipment());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public Map<String, Map<EquipmentSlot, String>> getFavorites() {
|
|
|
|
|
+ return Collections.unmodifiableMap(favorites);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public Map<EquipmentSlot, DDItem> getEquipment() {
|
|
public Map<EquipmentSlot, DDItem> getEquipment() {
|
|
|
return Collections.unmodifiableMap(equipment);
|
|
return Collections.unmodifiableMap(equipment);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public boolean canEquip( final DDItem item ) {
|
|
|
|
|
- return canEquip( item.getSlot() );
|
|
|
|
|
|
|
+ public boolean hasItem(final String itemName) {
|
|
|
|
|
+ return named.containsKey(itemName);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- private boolean canEquip( final EquipmentSlot slot ) {
|
|
|
|
|
- switch ( slot ) {
|
|
|
|
|
|
|
+ public boolean canEquip(final DDItem item) {
|
|
|
|
|
+ return canEquip(item.getSlot());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private boolean canEquip(final EquipmentSlot slot) {
|
|
|
|
|
+ switch (slot) {
|
|
|
case NONE: return false;
|
|
case NONE: return false;
|
|
|
- case TWO_HANDS: return canEquip( EquipmentSlot.MAIN_HAND ) &&
|
|
|
|
|
- canEquip( EquipmentSlot.OFF_HAND );
|
|
|
|
|
- case ONE_HAND: return canEquip( EquipmentSlot.MAIN_HAND ) ||
|
|
|
|
|
- canEquip( EquipmentSlot.OFF_HAND );
|
|
|
|
|
- case RING: return canEquip( EquipmentSlot.RING1 ) ||
|
|
|
|
|
- canEquip( EquipmentSlot.RING2 );
|
|
|
|
|
|
|
+ case TWO_HANDS: return canEquip(EquipmentSlot.MAIN_HAND) &&
|
|
|
|
|
+ canEquip(EquipmentSlot.OFF_HAND);
|
|
|
|
|
+ case ONE_HAND: return canEquip(EquipmentSlot.MAIN_HAND) ||
|
|
|
|
|
+ canEquip(EquipmentSlot.OFF_HAND);
|
|
|
|
|
+ case RING: return canEquip(EquipmentSlot.RING1) ||
|
|
|
|
|
+ canEquip(EquipmentSlot.RING2);
|
|
|
default:
|
|
default:
|
|
|
return !equipment.containsKey(slot);
|
|
return !equipment.containsKey(slot);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public void equip( final EquipmentSlot slot, final DDItem item ) {
|
|
|
|
|
|
|
+ public void equip(final EquipmentSlot slot, final DDItem item) {
|
|
|
switch ( slot ) {
|
|
switch ( slot ) {
|
|
|
case NONE:
|
|
case NONE:
|
|
|
case ONE_HAND:
|
|
case ONE_HAND:
|
|
|
case RING:
|
|
case RING:
|
|
|
throw new IllegalArgumentException("Cannot equip directly to slot:" + slot);
|
|
throw new IllegalArgumentException("Cannot equip directly to slot:" + slot);
|
|
|
case TWO_HANDS:
|
|
case TWO_HANDS:
|
|
|
- equip( EquipmentSlot.MAIN_HAND, item );
|
|
|
|
|
- equip( EquipmentSlot.OFF_HAND, item );
|
|
|
|
|
|
|
+ equip(EquipmentSlot.MAIN_HAND, item);
|
|
|
|
|
+ equip(EquipmentSlot.OFF_HAND, item);
|
|
|
break;
|
|
break;
|
|
|
default:
|
|
default:
|
|
|
equipment.put(slot, item);
|
|
equipment.put(slot, item);
|
|
@@ -98,15 +105,15 @@ public class DDInventory extends Observable {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public void unequip( final EquipmentSlot slot ) {
|
|
|
|
|
- switch ( slot ) {
|
|
|
|
|
|
|
+ public void unequip(final EquipmentSlot slot) {
|
|
|
|
|
+ switch (slot) {
|
|
|
case NONE:
|
|
case NONE:
|
|
|
case ONE_HAND:
|
|
case ONE_HAND:
|
|
|
case RING:
|
|
case RING:
|
|
|
throw new IllegalArgumentException("Cannot unequip directly to slot:" + slot);
|
|
throw new IllegalArgumentException("Cannot unequip directly to slot:" + slot);
|
|
|
case TWO_HANDS:
|
|
case TWO_HANDS:
|
|
|
- unequip( EquipmentSlot.MAIN_HAND );
|
|
|
|
|
- unequip( EquipmentSlot.OFF_HAND );
|
|
|
|
|
|
|
+ unequip(EquipmentSlot.MAIN_HAND);
|
|
|
|
|
+ unequip(EquipmentSlot.OFF_HAND);
|
|
|
break;
|
|
break;
|
|
|
default:
|
|
default:
|
|
|
equipment.remove(slot);
|
|
equipment.remove(slot);
|
|
@@ -114,27 +121,41 @@ public class DDInventory extends Observable {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public void equipNext( final DDItem item ) {
|
|
|
|
|
- switch ( item.getSlot() ) {
|
|
|
|
|
|
|
+ public void equipNext(final DDItem item) {
|
|
|
|
|
+ switch (item.getSlot()) {
|
|
|
case NONE:
|
|
case NONE:
|
|
|
throw new IllegalArgumentException("Cannot equip unequippable item");
|
|
throw new IllegalArgumentException("Cannot equip unequippable item");
|
|
|
case ONE_HAND:
|
|
case ONE_HAND:
|
|
|
- if ( canEquip( EquipmentSlot.MAIN_HAND ) ) {
|
|
|
|
|
- equip( EquipmentSlot.MAIN_HAND, item );
|
|
|
|
|
|
|
+ if (canEquip(EquipmentSlot.MAIN_HAND)) {
|
|
|
|
|
+ equip(EquipmentSlot.MAIN_HAND, item);
|
|
|
} else {
|
|
} else {
|
|
|
- equip( EquipmentSlot.OFF_HAND, item );
|
|
|
|
|
|
|
+ equip(EquipmentSlot.OFF_HAND, item);
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
case RING:
|
|
case RING:
|
|
|
- if ( canEquip( EquipmentSlot.RING1 ) ) {
|
|
|
|
|
- equip( EquipmentSlot.RING1, item );
|
|
|
|
|
|
|
+ if (canEquip(EquipmentSlot.RING1) ) {
|
|
|
|
|
+ equip(EquipmentSlot.RING1, item);
|
|
|
} else {
|
|
} else {
|
|
|
- equip( EquipmentSlot.RING2, item );
|
|
|
|
|
|
|
+ equip(EquipmentSlot.RING2, item);
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
default:
|
|
default:
|
|
|
- equip( item.getSlot(), item );
|
|
|
|
|
|
|
+ equip(item.getSlot(), item);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ private Map<EquipmentSlot, String> getSerializableEquipment() {
|
|
|
|
|
+ final Map<EquipmentSlot, String> m = new EnumMap<>(EquipmentSlot.class);
|
|
|
|
|
+ equipment.entrySet().stream().forEach(e -> m.put(e.getKey(), e.getValue().getName()));
|
|
|
|
|
+ return Collections.unmodifiableMap(m);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private void fromSerializableEquipment(@NonNull Map<EquipmentSlot, String> data) {
|
|
|
|
|
+ equipment.clear();
|
|
|
|
|
+ data.entrySet().stream().forEach(e -> {
|
|
|
|
|
+ @NonNull DDItem item = named.get(e.getValue()); // Throws NPE if item d/n exist any more
|
|
|
|
|
+ equipment.put(e.getKey(), item);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|