From 31bf3b4a56d4d23f5e154da98ee3f6d81f1b153f Mon Sep 17 00:00:00 2001
From: Jeffrey Phillips Freeman <jeffrey.freeman@syncleus.com>
Date: Mon, 19 Mar 2018 14:43:33 -0400
Subject: [PATCH] Fixed the item forage, it was broken during load.

---
 .../commands/admin/LoadItemCommand.java       |   3 +
 .../com/syncleus/aethermud/items/Forage.java  |   5 +-
 .../storage/graphdb/model/ForageData.java     | 116 ++++++++++++++++++
 .../storage/graphdb/model/ItemData.java       |  42 ++++++-
 4 files changed, 159 insertions(+), 7 deletions(-)
 create mode 100644 src/main/java/com/syncleus/aethermud/storage/graphdb/model/ForageData.java

diff --git a/src/main/java/com/syncleus/aethermud/command/commands/admin/LoadItemCommand.java b/src/main/java/com/syncleus/aethermud/command/commands/admin/LoadItemCommand.java
index 1b7036fd..4fc00fd8 100644
--- a/src/main/java/com/syncleus/aethermud/command/commands/admin/LoadItemCommand.java
+++ b/src/main/java/com/syncleus/aethermud/command/commands/admin/LoadItemCommand.java
@@ -17,12 +17,15 @@ package com.syncleus.aethermud.command.commands.admin;
 
 import com.syncleus.aethermud.command.commands.Command;
 import com.syncleus.aethermud.core.GameManager;
+import com.syncleus.aethermud.items.Forage;
 import com.syncleus.aethermud.items.Item;
 import com.syncleus.aethermud.items.ItemImpl;
 import com.syncleus.aethermud.player.PlayerRole;
 import com.google.common.collect.Sets;
 import com.syncleus.aethermud.storage.graphdb.GraphStorageFactory;
+import com.syncleus.aethermud.storage.graphdb.model.ForageData;
 import com.syncleus.aethermud.storage.graphdb.model.ItemData;
+import com.syncleus.aethermud.world.model.Area;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.HttpClient;
diff --git a/src/main/java/com/syncleus/aethermud/items/Forage.java b/src/main/java/com/syncleus/aethermud/items/Forage.java
index 13f509be..7d6f85fc 100644
--- a/src/main/java/com/syncleus/aethermud/items/Forage.java
+++ b/src/main/java/com/syncleus/aethermud/items/Forage.java
@@ -33,7 +33,10 @@ public class Forage extends AetherMudEntity {
     private int coolDownTicksLeft;
     private final Set<Area> forageAreas;
 
-    protected Forage(String internalItemName, int minLevel, double pctOfSuccess, int minAmt, int maxAmt, int forageExperience, int coolDownTicks, Set<Area> forageAreas) {
+    public Forage(String internalItemName, int minLevel, double pctOfSuccess, int minAmt, int maxAmt, int forageExperience, int coolDownTicks, Set<Area> forageAreas) {
+        if( forageAreas == null || forageAreas.isEmpty() )
+            throw new IllegalArgumentException((internalItemName == null ? "(null)" : internalItemName) + ": forageAreas must not be null and must have at least one value.");
+
         this.internalItemName = internalItemName;
         this.minLevel = minLevel;
         this.pctOfSuccess = pctOfSuccess;
diff --git a/src/main/java/com/syncleus/aethermud/storage/graphdb/model/ForageData.java b/src/main/java/com/syncleus/aethermud/storage/graphdb/model/ForageData.java
new file mode 100644
index 00000000..f0d63c2f
--- /dev/null
+++ b/src/main/java/com/syncleus/aethermud/storage/graphdb/model/ForageData.java
@@ -0,0 +1,116 @@
+/**
+ * Copyright 2017 Syncleus, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.syncleus.aethermud.storage.graphdb.model;
+
+import com.syncleus.aethermud.items.Forage;
+import com.syncleus.aethermud.player.PlayerRole;
+import com.syncleus.aethermud.spawner.SpawnRule;
+import com.syncleus.aethermud.world.model.Area;
+import com.syncleus.ferma.annotations.GraphElement;
+import com.syncleus.ferma.annotations.Property;
+import com.syncleus.ferma.ext.AbstractInterceptingVertexFrame;
+import org.apache.commons.beanutils.PropertyUtils;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+
+@GraphElement
+public abstract class ForageData extends AbstractInterceptingVertexFrame {
+    public Set<Area> getForageAreas() {
+        HashSet<Area> areas = new HashSet<>();
+        Collection<String> areasText = this.getProperty("forageAreas", Collection.class);
+        if( areasText == null )
+            return null;
+        for(final String areaText : areasText)
+            areas.add(Area.valueOf(areaText));
+        return Collections.unmodifiableSet(areas);
+    }
+
+    public void setForageAreas(Collection<Area> forageAreas) {
+        if( forageAreas != null ) {
+            ArrayList<String> newProperty = new ArrayList<String>();
+            for (Area area : forageAreas) {
+                newProperty.add(area.toString());
+            }
+            this.setProperty("forageAreas", newProperty);
+        }
+        else {
+            this.setProperty("forageAreas", null);
+        }
+    }
+
+    @Property("internalItemName")
+    public abstract String getInternalItemName();
+
+    @Property("minLevel")
+    public abstract int getMinLevel();
+
+    @Property("pctOfSuccess")
+    public abstract double getPctOfSuccess();
+
+    @Property("minAmt")
+    public abstract int getMinAmt();
+
+    @Property("maxAmt")
+    public abstract int getMaxAmt();
+
+    @Property("coolDownTicks")
+    public abstract int getCoolDownTicks();
+
+    @Property("forageExperience")
+    public abstract int getForageExperience();
+
+    @Property("coolDownTicksLeft")
+    public abstract int getCoolDownTicksLeft();
+
+    @Property("coolDownTicksLeft")
+    public abstract void setCoolDownTicksLeft(int coolDownTicksLeft);
+
+    @Property("internalItemName")
+    public abstract void setInternalItemName(String internalItemName);
+
+    @Property("minLevel")
+    public abstract void setMinLevel(int minLevel);
+
+    @Property("pctOfSuccess")
+    public abstract void setPctOfSuccess(double pctOfSuccess);
+
+    @Property("minAmt")
+    public abstract void setMinAmt(int minAmt);
+
+    @Property("maxAmt")
+    public abstract void setMaxAmt(int maxAmt);
+
+    @Property("forageExperience")
+    public abstract void setForageExperience(int forageExperience);
+
+    @Property("coolDownTicks")
+    public abstract void setCoolDownTicks(int coolDownTicks);
+
+    public static void copyForage(ForageData dest, Forage src) {
+        try {
+            PropertyUtils.copyProperties(dest, src);
+            if( src.getForageAreas() != null || (!src.getForageAreas().isEmpty()) )
+                dest.setForageAreas(src.getForageAreas());
+        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+            throw new IllegalStateException("Could not copy properties", e);
+        }
+    }
+
+    public static Forage copyForage(ForageData src) {
+        return new Forage(src.getInternalItemName(), src.getMinLevel(), src.getPctOfSuccess(), src.getMinAmt(), src.getMaxAmt(), src.getForageExperience(), src.getCoolDownTicks(), src.getForageAreas());
+    }
+}
diff --git a/src/main/java/com/syncleus/aethermud/storage/graphdb/model/ItemData.java b/src/main/java/com/syncleus/aethermud/storage/graphdb/model/ItemData.java
index 7f3ebcf6..758a21aa 100644
--- a/src/main/java/com/syncleus/aethermud/storage/graphdb/model/ItemData.java
+++ b/src/main/java/com/syncleus/aethermud/storage/graphdb/model/ItemData.java
@@ -109,11 +109,28 @@ public abstract class ItemData extends AbstractInterceptingVertexFrame {
     @Property("disposable")
     public abstract void setDisposable(boolean disposable);
 
-    @Property("forage")
-    public abstract Set<Forage> getForages();
+    @Adjacency(label = "forage", direction = Direction.OUT)
+    public abstract <N extends ForageData> Iterator<? extends N> getForageDataIterator(Class<? extends N> type);
 
-    @Property("forage")
-    public abstract void setForages(Set<Forage> forages);
+    public List<ForageData> getForageDatas() {
+        return Collections.unmodifiableList(Lists.newArrayList(this.getForageDataIterator(ForageData.class)));
+    }
+
+    @Adjacency(label = "forage", direction = Direction.OUT)
+    public abstract void addForageData(ForageData forageData);
+
+    @Adjacency(label = "forage", direction = Direction.OUT)
+    public abstract void removeForageData(ForageData forageData);
+
+    public void setForageDatas(List<ForageData> forageDatas) {
+        DataUtils.setAllElements(forageDatas, () -> this.getForageDataIterator(ForageData.class), forageData -> this.addForageData(forageData), () -> {} );
+    }
+
+    public ForageData createForageData() {
+        final ForageData forageData = this.getGraph().addFramedVertex(ForageData.class);
+        this.addForageData(forageData);
+        return forageData;
+    }
 
     @Adjacency(label = "spawnRule", direction = Direction.OUT)
     public abstract <N extends SpawnRuleData> Iterator<? extends N> getSpawnRulesDataIterator(Class<? extends N> type);
@@ -278,6 +295,12 @@ public abstract class ItemData extends AbstractInterceptingVertexFrame {
                 for(SpawnRule spawnRule : src.getSpawnRules())
                     SpawnRuleData.copySpawnRule(dest.createSpawnRuleData(), spawnRule);
 
+            for(ForageData data : dest.getForageDatas())
+                data.remove();
+            if( src.getForages() != null )
+                for(Forage forage : src.getForages())
+                    ForageData.copyForage(dest.createForageData(), forage);
+
             if( src.getItemApplyStats() != null )
                 StatData.copyStats((dest.getItemApplyStatData() != null ? dest.getItemApplyStatData() : dest.createItemApplyStatData()), src.getItemApplyStats());
             if(src.getLoot() != null )
@@ -301,10 +324,17 @@ public abstract class ItemData extends AbstractInterceptingVertexFrame {
             PropertyUtils.copyProperties(retVal, src);
 
             Set<SpawnRule> rules = new HashSet<>();
-            for(SpawnRuleData spawnRuleData : src.getSpawnRuleDatas())
-                rules.add(SpawnRuleData.copySpawnRule(spawnRuleData));
+            if( src.getSpawnRuleDatas() != null )
+                for(SpawnRuleData spawnRuleData : src.getSpawnRuleDatas())
+                    rules.add(SpawnRuleData.copySpawnRule(spawnRuleData));
             retVal.setSpawnRules(Collections.unmodifiableSet(rules));
 
+            Set<Forage> forages = new HashSet<>();
+            if( src.getForageDatas() != null )
+                for(ForageData forageData : src.getForageDatas())
+                    forages.add(ForageData.copyForage(forageData));
+            retVal.setForages(Collections.unmodifiableSet(forages));
+
             EquipmentData equipmentData = src.getEquipmentData();
             if(equipmentData != null)
                 retVal.setEquipment(EquipmentData.copyEquipment(equipmentData));
-- 
GitLab