diff --git a/.classpath b/.classpath index f80780e..cee3862 100644 --- a/.classpath +++ b/.classpath @@ -1,6 +1,7 @@ + diff --git a/.project b/.project index ac434fe..78d9189 100644 --- a/.project +++ b/.project @@ -24,4 +24,11 @@ org.eclipse.jdt.core.javanature + + + jgrapht + 2 + D:/Data/jgrapht-1.0.1/jgrapht-1.0.1/source/jgrapht-core/src/main/java + + diff --git a/TwosideKeeper.jar b/TwosideKeeper.jar index e78d94a..509e57b 100644 Binary files a/TwosideKeeper.jar and b/TwosideKeeper.jar differ diff --git a/src/sig/plugin/TwosideKeeper/Events/InventoryUpdateEvent.java b/src/sig/plugin/TwosideKeeper/Events/InventoryUpdateEvent.java new file mode 100644 index 0000000..3c7ae5a --- /dev/null +++ b/src/sig/plugin/TwosideKeeper/Events/InventoryUpdateEvent.java @@ -0,0 +1,55 @@ +package sig.plugin.TwosideKeeper.Events; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +import sig.plugin.TwosideKeeper.TwosideKeeper; + +public class InventoryUpdateEvent extends Event{ + private Player p; + private ItemStack item; + private static final HandlerList handlers = new HandlerList(); + private UpdateReason reason; + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + public InventoryUpdateEvent(Player p, ItemStack item, UpdateReason reason) { + this.p=p; + this.item=item; + this.reason=reason; + } + + public Player getPlayer() { + return p; + } + + public ItemStack getItemStack() { + return item; + } + + public UpdateReason getReason() { + return reason; + } + + public static void TriggerUpdateInventoryEvent(Player p, ItemStack item, UpdateReason reason) { + InventoryUpdateEvent ev = new InventoryUpdateEvent(p, item, reason); + Bukkit.getPluginManager().callEvent(ev); + //TwosideKeeper.log("Triggered because of "+reason, 0); + } + + public enum UpdateReason { + INVENTORYUPDATE, + PICKEDUPITEM, + DROPPEDITEM + } +} \ No newline at end of file diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java index 3a45908..fa22c72 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java @@ -5122,10 +5122,11 @@ public class GenericFunctions { return PlayerStructure.GetPlayerStructure(p).blockscanlist; } - public static boolean itemCanBeSuckedUp(Item ent) { + public static boolean itemCanBeSuckedUp(Item ent, Player p) { ItemStack item = ent.getItemStack(); //TwosideKeeper.log(item.toString()+": "+ent.getTicksLived()+".."+ent.getPickupDelay()+".."+((Item)ent).getName()+".."+((Item)ent).isCustomNameVisible()+".."+((Item)ent).getCustomName(), 0); - if (ent.getPickupDelay()>=0) { + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + if (ent.getPickupDelay()>=0 || pd.ignoreItemsList.contains(ent.getUniqueId())) { return false; } return true; diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/CustomRecipe.java b/src/sig/plugin/TwosideKeeper/HelperStructures/CustomRecipe.java index 24149da..e080b0f 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/CustomRecipe.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/CustomRecipe.java @@ -91,7 +91,7 @@ public enum CustomRecipe { ev.getInventory().getItem(i).getType()!=Material.AIR && (ev.getInventory().getItem(i).getType()==Material.ENDER_CHEST)) && !CustomItem.isVacuumCube(ev.getInventory().getItem(i))) { ItemMeta inventory_itemMeta1=ev.getInventory().getItem(i).getItemMeta(); - if (inventory_itemMeta1.hasLore() && inventory_itemMeta1.getLore().size()==4) { + if (inventory_itemMeta1.hasLore() && inventory_itemMeta1.getLore().size()>=4) { String loreitem = inventory_itemMeta1.getLore().get(3); if (loreitem!=null && loreitem.contains(ChatColor.DARK_PURPLE+"ID#")) { //log("This is an Item Cube. Invalidate recipe.",4); diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/FilterCubeItem.java b/src/sig/plugin/TwosideKeeper/HelperStructures/FilterCubeItem.java new file mode 100644 index 0000000..785017c --- /dev/null +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/FilterCubeItem.java @@ -0,0 +1,63 @@ +package sig.plugin.TwosideKeeper.HelperStructures; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.block.Hopper; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import sig.plugin.TwosideKeeper.PlayerStructure; +import sig.plugin.TwosideKeeper.TwosideKeeper; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.ItemCubeUtils; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.TextUtils; + +public class FilterCubeItem { + public static void populateFilterCubeItemList(Player p) { + HashMap> structure = GrabFilterCubeStructure(p); + structure.clear(); + + for (ItemStack item : p.getInventory().getContents()) { + if (item!=null && CustomItem.isFilterCube(item)) { + Hopper h = ItemCubeUtils.getFilterCubeHopper(ItemCubeUtils.getItemCubeID(item)); + for (ItemStack it : h.getInventory()) { + if (it!=null) { + int id = ItemCubeUtils.getItemCubeID(item); + if (structure.containsKey(it.getType())) { + List filterCubes = structure.get(it.getType()); + filterCubes.add(id); + } else { + List filterCubeList = new ArrayList(); + filterCubeList.add(id); + structure.put(it.getType(), filterCubeList); + } + } + } + } + } + + //TwosideKeeper.log("New Map: \n"+TextUtils.outputHashmap(structure), 0); + } + + public static HashMap> GrabFilterCubeStructure(Player p) { + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + HashMap> structure = pd.filtercubestructure; + return structure; + } + + public static boolean ItemHasFilterCube(ItemStack item, Player p) { + HashMap> structure = GrabFilterCubeStructure(p); + return structure.containsKey(item.getType()); + } + + public static List getFilterCubeIDsToInsertItem(ItemStack item, Player p) { + HashMap> structure = GrabFilterCubeStructure(p); + if (structure.containsKey(item.getType())) { + return structure.get(item.getType()); + } else { + return new ArrayList(); + } + } +} diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/ItemCube.java b/src/sig/plugin/TwosideKeeper/HelperStructures/ItemCube.java index 92e9131..5a7e6b7 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/ItemCube.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/ItemCube.java @@ -5,8 +5,12 @@ import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.jgrapht.graph.DefaultEdge; +import sig.plugin.TwosideKeeper.PlayerStructure; +import sig.plugin.TwosideKeeper.TwosideKeeper; import sig.plugin.TwosideKeeper.HelperStructures.Utils.InventoryUtils; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.ItemCubeUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.SoundUtils; public class ItemCube { @@ -35,6 +39,41 @@ public class ItemCube { } return null; //Didn't find anything. } + /** + * @deprecated Redundant and unnecessary. + */ + @Deprecated + public static void addItemCubeToAllViewerGraphs(int id, ItemStack cursor, Player checker) { + for (Player p : Bukkit.getOnlinePlayers()) { + if (checker==null || !p.equals(checker)) { + if (p.getOpenInventory()!=null && p.getOpenInventory().getTitle().contains("Item Cube #"+id) && + ItemCubeUtils.isItemCube(cursor)) { + int itemcubeID = ItemCubeUtils.getItemCubeID(cursor); + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + TwosideKeeper.itemCubeGraph.addVertex(itemcubeID); + DefaultEdge edge = TwosideKeeper.itemCubeGraph.addEdge(id, itemcubeID); + TwosideKeeper.log("Added edge "+edge+" for player "+p.getName(), 0); + } + } + } + } + /** + * @deprecated Redundant and unnecessary. + */ + @Deprecated + public static void removeItemCubeFromAllViewerGraphs(int id, ItemStack cursor, Player checker) { + for (Player p : Bukkit.getOnlinePlayers()) { + if (checker==null || !p.equals(checker)) { + if (p.getOpenInventory()!=null && p.getOpenInventory().getTitle().contains("Item Cube #"+id) && + ItemCubeUtils.isItemCube(cursor)) { + int itemcubeID = ItemCubeUtils.getItemCubeID(cursor); + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + DefaultEdge edge = TwosideKeeper.itemCubeGraph.removeEdge(id, itemcubeID); + TwosideKeeper.log("Removed edge "+edge+" for player "+p.getName(), 0); + } + } + } + } public static void displayErrorMessage(Player p) { SoundUtils.playLocalSound(p, Sound.BLOCK_NOTE_PLING, 0.6f, 4.0f); p.sendMessage("Someone is currently using this Item Cube! Please wait for them to finish."); diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/InventoryUtils.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/InventoryUtils.java index cfb6576..0f59d8b 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/InventoryUtils.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/InventoryUtils.java @@ -15,6 +15,7 @@ import org.bukkit.inventory.ItemStack; import sig.plugin.TwosideKeeper.TwosideKeeper; import sig.plugin.TwosideKeeper.HelperStructures.CubeType; import sig.plugin.TwosideKeeper.HelperStructures.CustomItem; +import sig.plugin.TwosideKeeper.HelperStructures.FilterCubeItem; import sig.plugin.TwosideKeeper.HelperStructures.ItemCube; import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions; import sig.plugin.TwosideKeeper.HelperStructures.Common.ItemContainer; @@ -48,6 +49,7 @@ public class InventoryUtils { List itemcube_list = new ArrayList(); for (int i=0;i itemCubeContents = TwosideKeeper.itemCube_loadConfig(id); + Inventory virtualinventory = Bukkit.createInventory(p, 27); + for (int i=0;i remainingitems = ItemCubeUtils.AttemptingToAddItemToFilterCube(id,virtualinventory,remaining); + + GenericFunctions.UpdateItemLore(remaining[j]); + remaining = remainingitems.values().toArray(new ItemStack[0]); + } + } } return remaining; } @@ -144,6 +169,15 @@ public class InventoryUtils { } return true; } + public static boolean hasFullInventory(Inventory inv) { + ItemStack[] inventory = inv.getContents(); + for (ItemStack i : inventory) { + if (i==null || i.getType()==Material.AIR) { + return false; + } + } + return true; + } public static boolean hasEmptyInventory(Inventory inv) { ItemStack[] inventory = inv.getContents(); for (ItemStack i : inventory) { diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/ItemCubeUtils.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/ItemCubeUtils.java index b00d63d..3031ff0 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/ItemCubeUtils.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/ItemCubeUtils.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; +import java.util.Set; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -16,10 +17,15 @@ import org.bukkit.block.Hopper; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.jgrapht.Graph; +import org.jgrapht.UndirectedGraph; +import org.jgrapht.graph.DefaultEdge; +import sig.plugin.TwosideKeeper.PlayerStructure; import sig.plugin.TwosideKeeper.TwosideKeeper; import sig.plugin.TwosideKeeper.HelperStructures.CubeType; import sig.plugin.TwosideKeeper.HelperStructures.ItemCube; @@ -29,7 +35,10 @@ public class ItemCubeUtils { public final static String SUCTION_STRING = ChatColor.GRAY+"Block Collection: "; public final static String FILTER_STRING = ChatColor.GRAY+"Filter Blocks: "; public static int getItemCubeID(ItemStack item) { - return Integer.parseInt(ItemUtils.GetLoreLineContainingSubstring(item, ChatColor.DARK_PURPLE+"ID#").split("#")[1]); + if (isItemCube(item)) { + return Integer.parseInt(ItemUtils.GetLoreLineContainingSubstring(item, ChatColor.DARK_PURPLE+"ID#").split("#")[1]); + } + return -1; } public static Location getFilterCubeLoc(int id) { int posx = id % 960; @@ -84,6 +93,8 @@ public class ItemCubeUtils { TwosideKeeper.itemCube_saveConfig(id, itemslist); TwosideKeeper.itemcube_updates.put(id, itemcube_list);//This Item Cube can be saved. } + + ItemCubeUtils.addItemCubeToGraphFromCube(id, it, (Player)cube_inv.getHolder()); } else { for (ItemStack i : extras.values()) { reject_items.put(reject_items.size(), i); @@ -409,4 +420,165 @@ public class ItemCubeUtils { } TwosideKeeper.itemcube_updates.put(ItemCubeUtils.getItemCubeID(item), itemcube_list); } + public static void populateItemCubeGraph(Player p) { + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + UndirectedGraph graph = TwosideKeeper.itemCubeGraph; + + graph.addVertex(PlayerStructure.getPlayerNegativeHash(p)); //Root Vertex. + + for (ItemStack it : p.getInventory().getContents()) { + if (ItemUtils.isValidItem(it) && isItemCube(it)) { + int id = getItemCubeID(it); + graph.addVertex(id); + graph.addEdge(PlayerStructure.getPlayerNegativeHash(p), id); + IterateAndAddToGraph(id,graph); + } + } + + for (DefaultEdge edge : graph.edgeSet()) { + TwosideKeeper.log(" "+edge.toString(), 0); + } + } + public static void IterateAndAddToGraph(int id, UndirectedGraph graph) { + List contents = getItemCubeContents(id); + for (ItemStack it : contents) { + if (ItemUtils.isValidItem(it) && isItemCube(it)) { + int newid = getItemCubeID(it); + if (id!=newid) { //We don't need to link to itself. + graph.addVertex(newid); + graph.addEdge(id, newid); + IterateAndAddToGraph(newid,graph); + } + } + } + } + + public static void pickupAndAddItemCubeToGraph(ItemStack item, Player p) { + if (ItemCubeUtils.isItemCube(item)) { + int id = ItemCubeUtils.getItemCubeID(item); + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + UndirectedGraph graph = TwosideKeeper.itemCubeGraph; + graph.addVertex(id); + DefaultEdge edge = graph.addEdge(PlayerStructure.getPlayerNegativeHash(p), id); + //TwosideKeeper.log("Added edge "+edge, 0); + ItemCubeUtils.IterateAndAddToGraph(id, graph); + } + } + + public static void addItemCubeToGraphFromCube(int sourceCubeID, ItemStack item, Player p) { + if (ItemCubeUtils.isItemCube(item)) { + int id = ItemCubeUtils.getItemCubeID(item); + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + UndirectedGraph graph = TwosideKeeper.itemCubeGraph; + graph.addVertex(id); + DefaultEdge edge = graph.addEdge(sourceCubeID, id); + //TwosideKeeper.log("Added edge "+edge, 0); + ItemCubeUtils.IterateAndAddToGraph(id, graph); + } + } + + public static void removeAndUpdateAllEdgesDroppedItem(int id, Player p) { + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + UndirectedGraph graph = TwosideKeeper.itemCubeGraph; + DestroyAllSourceEdges(PlayerStructure.getPlayerNegativeHash(p), graph); + reestablishAllRootEdges(p, graph); + } + + public static void removeAndUpdateAllEdges(int id, Player p) { + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + UndirectedGraph graph = TwosideKeeper.itemCubeGraph; + DestroyAllSourceEdges(id, graph); + reestablishAllEdges(id, graph); + } + + private static void reestablishAllEdges(int id, UndirectedGraph graph) { + List contents = getItemCubeContents(id); + for (ItemStack it : contents) { + if (ItemUtils.isValidItem(it) && isItemCube(it)) { + int newid = getItemCubeID(it); + if (id!=newid) { //We don't need to link to itself. + graph.addVertex(newid); + DefaultEdge edge = graph.addEdge(id, newid); + //TwosideKeeper.log("Reconnected edge "+edge, 0); + } + } + } + } + + private static void reestablishAllRootEdges(Player p, UndirectedGraph graph) { + for (ItemStack it : p.getInventory().getContents()) { + if (ItemUtils.isValidItem(it) && isItemCube(it)) { + int newid = getItemCubeID(it); + graph.addVertex(newid); + DefaultEdge edge = graph.addEdge(PlayerStructure.getPlayerNegativeHash(p), newid); + //TwosideKeeper.log("Reconnected edge "+edge, 0); + } + } + } + public static void DestroyAllSourceEdges(int id, UndirectedGraph graph) { + Set edges = graph.edgesOf(id); + List destroyed = new ArrayList(); + for (DefaultEdge e : edges) { + if (graph.getEdgeSource(e)==id) { + destroyed.add(e); + } + } + while (destroyed.size()>0) { + DefaultEdge edge = destroyed.remove(0); + //TwosideKeeper.log("Destroyed edge "+edge, 0); + graph.removeEdge(edge); + } + } + public static void DestroyAllTargetEdges(int id, UndirectedGraph graph) { + Set edges = graph.edgesOf(id); + List destroyed = new ArrayList(); + for (DefaultEdge e : edges) { + if (graph.getEdgeTarget(e)==id) { + destroyed.add(e); + } + } + while (destroyed.size()>0) { + DefaultEdge edge = destroyed.remove(0); + //TwosideKeeper.log("Destroyed edge "+edge, 0); + graph.removeEdge(edge); + } + } + + /*public static void removeItemCubeFromGraph(int sourceCubeID, ItemStack item, Player p) { + + }*/ + /*public static void handleInventoryClickWithGraphs(InventoryClickEvent ev) { + Player p = (Player)ev.getWhoClicked(); + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + boolean isViewingItemCube = pd.isViewingItemCube; + Inventory inv = ev.getClickedInventory(); + + if (inv.getType()==InventoryType.CHEST) { + if (isViewingItemCube && + inv.getTitle()!=null && inv.getTitle().contains("Item Cube #")) { + + } + } + }*/ + + public static boolean isConnectedToRootNode(Graph g, Integer vertex) { + Set edges = g.edgesOf(vertex); + for (DefaultEdge e : edges) { + Integer target = g.getEdgeTarget(e); + Integer newvertex = g.getEdgeSource(e); + //TwosideKeeper.log("Vertex: "+vertex+" - "+newvertex+" : "+target,0); + if (Integer.compare(target, vertex)==0) { + TwosideKeeper.log(e.toString(),0); + if (Integer.compare(newvertex,vertex)==0) { + return false; + } + if (newvertex<0) { + return true; + } else { + return isConnectedToRootNode(g,newvertex); + } + } + } + return false; + } } diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/TextUtils.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/TextUtils.java index 8b7ecdc..2c6bef0 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/TextUtils.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/TextUtils.java @@ -1,5 +1,8 @@ package sig.plugin.TwosideKeeper.HelperStructures.Utils; +import java.util.HashMap; +import java.util.List; + import org.bukkit.ChatColor; public class TextUtils { @@ -44,4 +47,27 @@ public class TextUtils { return ChatColor.DARK_RED; } } + + public static String outputHashmap(HashMap map) { + StringBuilder builder = new StringBuilder(); + for (Object o : map.keySet()) { + Object val = map.get(o); + builder.append(o.toString()+": "); + if (val instanceof List) { + builder.append("\n"); + boolean first=true; + for (Object obj : (List)val) { + if (first) { + builder.append(" "+obj.toString()); + } else { + builder.append("\n "+obj.toString()); + } + } + } else { + builder.append(val.toString()); + } + builder.append("\n"); + } + return builder.toString(); + } } diff --git a/src/sig/plugin/TwosideKeeper/PlayerStructure.java b/src/sig/plugin/TwosideKeeper/PlayerStructure.java index 4b82d12..d88a81c 100644 --- a/src/sig/plugin/TwosideKeeper/PlayerStructure.java +++ b/src/sig/plugin/TwosideKeeper/PlayerStructure.java @@ -20,9 +20,13 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.BookMeta; import org.bukkit.potion.PotionEffect; +import org.jgrapht.UndirectedGraph; +import org.jgrapht.graph.DefaultEdge; +import org.jgrapht.graph.SimpleGraph; import sig.plugin.TwosideKeeper.HelperStructures.BowMode; import sig.plugin.TwosideKeeper.HelperStructures.DeathStructure; +import sig.plugin.TwosideKeeper.HelperStructures.FilterCubeItem; import sig.plugin.TwosideKeeper.HelperStructures.PlayerMode; import sig.plugin.TwosideKeeper.HelperStructures.ServerType; import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions; @@ -197,6 +201,9 @@ public class PlayerStructure { List equipmentset = new ArrayList(); + public HashMap> filtercubestructure = new HashMap>(); + public List ignoreItemsList = new ArrayList(); + //Needs the instance of the player object to get all other info. Only to be called at the beginning. @SuppressWarnings("deprecation") public PlayerStructure(Player p, long serverTickTime) { @@ -559,4 +566,8 @@ public class PlayerStructure { return TwosideKeeper.playerdata.put(p.getUniqueId(), new PlayerStructure(p,TwosideKeeper.getServerTickTime())); } } + + public static int getPlayerNegativeHash(Player p) { + return Math.min(p.getUniqueId().hashCode(), -p.getUniqueId().hashCode()); + } } diff --git a/src/sig/plugin/TwosideKeeper/TwosideKeeper.java b/src/sig/plugin/TwosideKeeper/TwosideKeeper.java index ddfde51..50300c8 100644 --- a/src/sig/plugin/TwosideKeeper/TwosideKeeper.java +++ b/src/sig/plugin/TwosideKeeper/TwosideKeeper.java @@ -119,8 +119,10 @@ import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.CraftItemEvent; +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.event.inventory.InventoryMoveItemEvent; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.event.inventory.InventoryPickupItemEvent; @@ -178,6 +180,9 @@ import org.bukkit.potion.PotionEffectTypeWrapper; import org.bukkit.potion.PotionType; import org.bukkit.util.Vector; import org.inventivetalent.glow.GlowAPI; +import org.jgrapht.UndirectedGraph; +import org.jgrapht.graph.DefaultEdge; +import org.jgrapht.graph.SimpleGraph; import com.google.common.collect.ImmutableSet; @@ -186,6 +191,7 @@ import com.google.common.collect.ImmutableSet; import aPlugin.API.Chests; import events.PlayerGainItemEvent; +import events.PlayerManualPickupItemEvent; import events.PluginLoadEvent; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ComponentBuilder; @@ -197,6 +203,8 @@ import sig.plugin.AutoPluginUpdate.AnnounceUpdateEvent; import sig.plugin.TwosideKeeper.Boss.Arena; import sig.plugin.TwosideKeeper.Boss.SendMiningFatigueToAllNearbyElderGuardians; import sig.plugin.TwosideKeeper.Events.EntityDamagedEvent; +import sig.plugin.TwosideKeeper.Events.InventoryUpdateEvent; +import sig.plugin.TwosideKeeper.Events.InventoryUpdateEvent.UpdateReason; import sig.plugin.TwosideKeeper.Events.PlayerDodgeEvent; import sig.plugin.TwosideKeeper.HelperStructures.AnvilItem; import sig.plugin.TwosideKeeper.HelperStructures.ArtifactAbility; @@ -209,6 +217,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.CustomItem; import sig.plugin.TwosideKeeper.HelperStructures.CustomPotion; import sig.plugin.TwosideKeeper.HelperStructures.CustomRecipe; import sig.plugin.TwosideKeeper.HelperStructures.DamageStructure; +import sig.plugin.TwosideKeeper.HelperStructures.FilterCubeItem; import sig.plugin.TwosideKeeper.HelperStructures.ItemCube; import sig.plugin.TwosideKeeper.HelperStructures.ItemSet; import sig.plugin.TwosideKeeper.HelperStructures.LivingEntityDifficulty; @@ -559,6 +568,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener { boolean lamps_are_turned_on = false; public static boolean PLAYERJOINTOGGLE=false; + + public static UndirectedGraph itemCubeGraph = new SimpleGraph<>(DefaultEdge.class); private final class GivePlayerPurchasedItems implements Runnable { @@ -802,9 +813,11 @@ public class TwosideKeeper extends JavaPlugin implements Listener { TwosideKeeper.HeartbeatLogger.AddEntry("Lava Plume Handling", (int)(System.nanoTime()-time));time=System.nanoTime(); for (Player p : Bukkit.getOnlinePlayers()) { long time1 = System.nanoTime(); - runServerHeartbeat.runFilterCubeCollection(p); + List itemsIgnored = new ArrayList(); + runServerHeartbeat.runFilterCubeCollection(p,itemsIgnored); TwosideKeeper.HeartbeatLogger.AddEntry("Player Cycle Handling->Filter Cube Handling", (int)(System.nanoTime()-time1));time1=System.nanoTime(); - runServerHeartbeat.runVacuumCubeSuckup(p); + runServerHeartbeat.runVacuumCubeSuckup(p,itemsIgnored); + TwosideKeeper.HeartbeatLogger.AddEntry("Player Cycle Handling->Vacuum Cube Handling", (int)(System.nanoTime()-time1));time1=System.nanoTime(); if (PlayerStructure.GetPlayerStructure(p).last_rejuvenate+200>TwosideKeeper.getServerTickTime()) { GenericFunctions.HealEntity(p, 5); @@ -1221,6 +1234,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener { int ite2 = GetFullStructureMap("ite"); int las = GetFullStructureMap("las"); int blo2 = GetFullStructureMap("blo2"); + int graphedge = itemCubeGraph.edgeSet().size(); + int graphvert = itemCubeGraph.vertexSet().size(); DecimalFormat df = new DecimalFormat("0.00"); sender.sendMessage(ChatColor.WHITE+"TPS: "+GetTPSColor(tps)+df.format(tps)); sender.sendMessage(ChatColor.WHITE+Display("SNO",sno)+Display("PLA",pla)+Display("LIV",liv)); @@ -1234,6 +1249,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { sender.sendMessage(ChatColor.WHITE+Display("ITE",ite)+Display("PRI",pri)+Display("P-OPE",ope)); sender.sendMessage(ChatColor.WHITE+Display("P-DEA",dea)+Display("P-HIT",hit)+Display("P-ITE2",ite2)); sender.sendMessage(ChatColor.WHITE+Display("P-LAS",las)+Display("P-BLO2",blo2)+Display("P-DAM",dam)); + sender.sendMessage(ChatColor.WHITE+Display("G-EDG",graphedge)+Display("G-VERT",graphvert)); sender.sendMessage(ChatColor.WHITE+DisplayPlayerBar()); sender.sendMessage(ChatColor.WHITE+"To view a specific player's usage, use "+ChatColor.GREEN+"\"/debugreport \""); sender.sendMessage(ChatColor.WHITE+"To view specific entities' usage, use "+ChatColor.GREEN+"\"/debugreport ALLENTS\""); @@ -2520,6 +2536,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener { ev.getPlayer().getScoreboard().getTeam(ev.getPlayer().getName().toLowerCase()).setSuffix(createHealthbar(((ev.getPlayer().getHealth())/ev.getPlayer().getMaxHealth())*100,ev.getPlayer())); ev.getPlayer().getScoreboard().getTeam(ev.getPlayer().getName().toLowerCase()).setPrefix(GenericFunctions.PlayerModePrefix(ev.getPlayer())); ev.getPlayer().getAttribute(Attribute.GENERIC_ATTACK_SPEED).setBaseValue(4.0d); + + ItemCubeUtils.populateItemCubeGraph(ev.getPlayer()); } public static void AnnounceDealOfTheDay(Player p) { @@ -3038,8 +3056,6 @@ public class TwosideKeeper extends JavaPlugin implements Listener { @EventHandler(priority=EventPriority.LOW) public void onPlayerInteract(PlayerInteractEntityEvent ev) { - log("Clicked with "+ ev.getHand().name(),5); - log("Clicked on: "+ev.getRightClicked().getName(),5); Player p = ev.getPlayer(); PlayerStructure pd = PlayerStructure.GetPlayerStructure(ev.getPlayer()); if (ev.getRightClicked() instanceof LivingEntity && @@ -3148,10 +3164,6 @@ public class TwosideKeeper extends JavaPlugin implements Listener { LinkPlayerToOtherPlayer(p,pl); } } - /*if (ev.getRightClicked() instanceof Monster) { - TwosideKeeperAPI.DealDamageToEntity(TwosideKeeperAPI.getFinalDamage(500.0, ev.getPlayer(), (Monster)ev.getRightClicked(), true, "ROFL"), (Monster)ev.getRightClicked(), ev.getPlayer()); - }*/ - ///if (ev.getHand()==EquipmentSlot.OFF_HAND) {aPlugin.API.swingOffHand(ev.getPlayer());}; } private void LinkPlayerToOtherPlayer(Player p, Player pl) { @@ -4735,6 +4747,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener { @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) public void onPlayerDropItem(PlayerDropItemEvent ev) { + InventoryUpdateEvent.TriggerUpdateInventoryEvent(ev.getPlayer(),ev.getItemDrop().getItemStack(),UpdateReason.DROPPEDITEM); + if (GenericFunctions.isArtifactEquip(ev.getItemDrop().getItemStack())) { ev.getItemDrop().setInvulnerable(true); } @@ -4865,6 +4879,20 @@ public class TwosideKeeper extends JavaPlugin implements Listener { ev.setCancelled(true); } } + + if (ItemCubeUtils.isItemCube(ev.getItemDrop().getItemStack())) { + ItemCubeUtils.removeAndUpdateAllEdgesDroppedItem(ItemCubeUtils.getItemCubeID(ev.getItemDrop().getItemStack()),ev.getPlayer()); + + if (ev.getPlayer().getOpenInventory()!=null && + ev.getPlayer().getOpenInventory().getTitle()!=null && + ev.getPlayer().getOpenInventory().getTitle().contains("Item Cube #") && + PlayerStructure.GetPlayerStructure(ev.getPlayer()).isViewingItemCube) { + //We are viewing an item cube. Update it. + int id = Integer.parseInt(ev.getPlayer().getOpenInventory().getTitle().split("#")[1]); + ItemCubeUtils.removeAndUpdateAllEdges(id,ev.getPlayer()); + } + } + return; } @@ -4947,6 +4975,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { CubeType cub = p.getOpenInventory().getTopInventory().getSize()==9?CubeType.NORMAL:p.getOpenInventory().getTopInventory().getSize()==54?CubeType.VACUUM:CubeType.LARGE; SoundUtils.playLocalSound(p, Sound.BLOCK_CHEST_CLOSE, 1.0f, 1.0f); itemCube_saveConfig(id,itemcube_contents,cub); + ItemCubeUtils.removeAndUpdateAllEdges(id,p); itemcube_updates.put(id, itemcube_list);//This Item Cube can be saved. if (!pd.opened_another_cube) { ItemCubeWindow.removeAllItemCubeWindows(p); @@ -5111,8 +5140,19 @@ public class TwosideKeeper extends JavaPlugin implements Listener { ev.setResult(item.renameItemProperly()); } } + + @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) + public void onInventoryUpdate(InventoryUpdateEvent ev) { + FilterCubeItem.populateFilterCubeItemList(ev.getPlayer()); + ClearOutIgnoredUUIDs(ev.getPlayer()); + } - @SuppressWarnings("deprecation") + private void ClearOutIgnoredUUIDs(Player p) { + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + pd.ignoreItemsList.clear(); + } + + @SuppressWarnings("deprecation") @EventHandler(priority=EventPriority.LOW,ignoreCancelled = true) public void onInventoryClick(InventoryClickEvent ev) { final Player player = (Player)ev.getWhoClicked(); @@ -5122,6 +5162,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener { log("Slot Type: "+ev.getSlotType().name(),5); //5,6,7,8 for gear slots. ////////////////////////DO NOT PUT ANYTHING HERE! DEATH STRUCTURE NEEDS TO OVERRIDE ALL BEHAVIORS. + + InventoryUpdateEvent.TriggerUpdateInventoryEvent(player,ev.getCursor(),UpdateReason.INVENTORYUPDATE); if (DeathManager.deathStructureExists(player) && ev.getInventory().getTitle().equalsIgnoreCase("Death Loot")) { //See how many items are in our inventory. Determine final balance. @@ -5433,7 +5475,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { //We clicked an item cube. Check its ID. int clicked_id = Integer.parseInt(ev.getCurrentItem().getItemMeta().getLore().get(i).split("#")[1]); log("ID is "+clicked_id+" and we are viewing "+itemcubeid,5); - if (clicked_id==itemcubeid) { + /*if (clicked_id==itemcubeid) { //The inventory we are viewing is the same as the item cube we have clicked on! //Stop this before the player does something dumb! //Player p = ((Player)ev.getWhoClicked()); @@ -5441,7 +5483,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { //TwosideKeeper.log("In here Item Cubes..", 0); ev.setCancelled(true); return; - } + }*/ } } } @@ -5524,6 +5566,23 @@ public class TwosideKeeper extends JavaPlugin implements Listener { //Make sure we are not already inside the cube we're placing into. { CubeType cub = clicked_size==9?CubeType.NORMAL:clicked_size==54?CubeType.VACUUM:CubeType.LARGE; + + if (ItemCubeUtils.isItemCube(ev.getCursor())) { + //We need to see if this is allowed then. + //idnumb is the ID we're inserting into. + int id = ItemCubeUtils.getItemCubeID(ev.getCursor()); + //TwosideKeeper.itemCubeGraph.addEdge(idnumb, id); + //Does this make a root connection? + if (!ItemCubeUtils.isConnectedToRootNode(TwosideKeeper.itemCubeGraph, idnumb)) { + //This is not allowed! + TwosideKeeper.log("No ROOT NODE found! Do not allow this.", 0); + //TwosideKeeper.itemCubeGraph.removeEdge(idnumb, id); + ev.setCursor(ev.getCursor()); + ev.setCancelled(true); + return; + } + } + /*if (cub==CubeType.VACUUM) { //A Vacuum Cube only accepts blocks, not items. TwosideKeeper.log("Cursor is "+ev.getCursor(), 5); @@ -5706,46 +5765,204 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } } } + + if (ev.getClickedInventory()!=null) { + Player p = (Player)ev.getWhoClicked(); + if (ev.getAction()==InventoryAction.HOTBAR_SWAP || ev.getAction()==InventoryAction.HOTBAR_MOVE_AND_READD) { + Inventory clickedinv = p.getOpenInventory().getTopInventory(); + ItemStack item1 = p.getInventory().getItem(ev.getHotbarButton()); //Bottom to Top + ItemStack item2 = p.getOpenInventory().getItem(ev.getRawSlot()); //Top to Bottom + TwosideKeeper.log(item1+" ||| "+item2, 0); + if (clickedinv!=null && clickedinv.getTitle()!=null && clickedinv.getTitle().contains("Item Cube #") && + ev.getRawSlot()=clickedinv.getSize()) { + int clickedid = ItemCubeUtils.getItemCubeID(item); + try { + DefaultEdge edge = TwosideKeeper.itemCubeGraph.addEdge(PlayerStructure.getPlayerNegativeHash(p), clickedid); + TwosideKeeper.log("Added edge "+edge, 0); + } catch (IllegalArgumentException ex) { + ev.setCancelled(true); + ev.setCursor(ev.getCursor()); + return; + } + } + } + } } - }*/ - - //TODO Implement Graphs. - /*private void ContinueBuildingItemCubeGraph(int id, Player p) { - PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); - CubeType size = ItemCubeUtils.getCubeType(id); - int slots = CubeType.getSlotsFromType(size); - Inventory virtualinventory = null; - virtualinventory = ItemCube.getViewingItemCubeInventory(id, p); - if (virtualinventory==null) { - virtualinventory = Bukkit.createInventory(p, slots); - List items = itemCube_loadConfig(id); - for (int i=0;i ignoredItems) { if (InventoryUtils.hasFullInventory(p) && InventoryUtils.isCarryingFilterCube(p)) { List ents = p.getNearbyEntities(1, 1, 1); int count=0; for (Entity ent : ents) { - if (ent instanceof Item && GenericFunctions.itemCanBeSuckedUp((Item)ent)) { + if (ent instanceof Item && GenericFunctions.itemCanBeSuckedUp((Item)ent,p)) { Item it = (Item)ent; if (it.getPickupDelay()<=0) { events.PlayerManualPickupItemEvent ev = new events.PlayerManualPickupItemEvent(p, it.getItemStack()); @@ -636,20 +638,26 @@ final class runServerHeartbeat implements Runnable { if (!handled) { ItemStack[] remaining = InventoryUtils.insertItemsInFilterCube(p, it.getItemStack()); if (remaining.length==0) { + InventoryUpdateEvent.TriggerUpdateInventoryEvent(ev.getPlayer(),ev.getItemStack(),UpdateReason.PICKEDUPITEM); SoundUtils.playGlobalSound(p.getLocation(), Sound.ENTITY_ITEM_PICKUP, 0.6f, SoundUtils.DetermineItemPitch(it.getItemStack())); TwosideKeeper.PlayPickupParticle(p,it); it.remove(); } } else { + InventoryUpdateEvent.TriggerUpdateInventoryEvent(ev.getPlayer(),ev.getItemStack(),UpdateReason.PICKEDUPITEM); TwosideKeeper.PlayPickupParticle(p,it); it.remove(); } } else { + TwosideKeeper.PlayPickupParticle(p,it); it.remove(); } } + if (it.isValid()) { + ignoredItems.add(it.getUniqueId()); + } count++; - if (count>8) { + if (count>=8) { return; } } @@ -657,14 +665,14 @@ final class runServerHeartbeat implements Runnable { } } - public static void runVacuumCubeSuckup(Player p) { + public static void runVacuumCubeSuckup(Player p, List ignoredItems) { if (InventoryUtils.isCarryingVacuumCube(p)) { //Suck up nearby item entities. PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); List ents = p.getNearbyEntities(6, 6, 6); int count=0; for (Entity ent : ents) { - if (ent instanceof Item && GenericFunctions.itemCanBeSuckedUp((Item)ent)) { + if (ent instanceof Item && GenericFunctions.itemCanBeSuckedUp((Item)ent,p)) { //Pull towards the player. double SPD = 0.2; double deltax = ent.getLocation().getX()-p.getLocation().getX(); @@ -701,14 +709,16 @@ final class runServerHeartbeat implements Runnable { events.PlayerManualPickupItemEvent ev = new events.PlayerManualPickupItemEvent(p, ((Item) ent).getItemStack()); Bukkit.getPluginManager().callEvent(ev); if (!ev.isCancelled()) { - ItemStack[] remaining = InventoryUtils.insertItemsInVacuumCube(p, ((Item) ent).getItemStack()); + ItemStack[] remaining = InventoryUtils.insertItemsInVacuumCube(p, ((Item) ent).getItemStack()); if (remaining.length==0) { SoundUtils.playGlobalSound(p.getLocation(), Sound.ENTITY_ITEM_PICKUP, 0.6f, SoundUtils.DetermineItemPitch(((Item) ent).getItemStack())); TwosideKeeper.PlayPickupParticle(p,(Item)ent); + InventoryUpdateEvent.TriggerUpdateInventoryEvent(ev.getPlayer(),ev.getItemStack(),UpdateReason.PICKEDUPITEM); ent.remove(); return; } } else { + InventoryUpdateEvent.TriggerUpdateInventoryEvent(ev.getPlayer(),ev.getItemStack(),UpdateReason.PICKEDUPITEM); ent.remove(); return; } @@ -722,6 +732,11 @@ final class runServerHeartbeat implements Runnable { ent.setVelocity(new Vector(xvel,yvel,zvel)); } } + if (ent.isValid()) { + if (ignoredItems.contains(ent.getUniqueId())) { + pd.ignoreItemsList.add(ent.getUniqueId()); + } + } /*if (ent.getLocation().getX()