|
@ -2,8 +2,10 @@ package cx.sfy.LagAssist.stacker; |
|
|
|
|
|
|
|
|
import java.util.ArrayList; |
|
|
import java.util.ArrayList; |
|
|
import java.util.HashMap; |
|
|
import java.util.HashMap; |
|
|
|
|
|
import java.util.HashSet; |
|
|
import java.util.List; |
|
|
import java.util.List; |
|
|
import java.util.Map; |
|
|
import java.util.Map; |
|
|
|
|
|
import java.util.Set; |
|
|
import java.util.regex.Matcher; |
|
|
import java.util.regex.Matcher; |
|
|
import java.util.regex.Pattern; |
|
|
import java.util.regex.Pattern; |
|
|
|
|
|
|
|
@ -17,6 +19,7 @@ import org.bukkit.entity.EntityType; |
|
|
import org.bukkit.entity.LivingEntity; |
|
|
import org.bukkit.entity.LivingEntity; |
|
|
import org.bukkit.event.entity.EntityDeathEvent; |
|
|
import org.bukkit.event.entity.EntityDeathEvent; |
|
|
import org.bukkit.inventory.ItemStack; |
|
|
import org.bukkit.inventory.ItemStack; |
|
|
|
|
|
import org.bukkit.metadata.FixedMetadataValue; |
|
|
|
|
|
|
|
|
import cx.sfy.LagAssist.Main; |
|
|
import cx.sfy.LagAssist.Main; |
|
|
import cx.sfy.LagAssist.utils.MathUtils; |
|
|
import cx.sfy.LagAssist.utils.MathUtils; |
|
@ -31,22 +34,22 @@ public class StackChunk { |
|
|
public static String regexpat = ""; |
|
|
public static String regexpat = ""; |
|
|
private static int splits = 8; |
|
|
private static int splits = 8; |
|
|
|
|
|
|
|
|
private Map<EntityType, ArrayList<Entity>>[] ents; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Map<EntityType, HashSet<Entity>>[] ents; |
|
|
|
|
|
|
|
|
public static void Enabler() { |
|
|
public static void Enabler() { |
|
|
splits = Main.config.getInt("smart-stacker.technical.splits"); |
|
|
splits = Main.config.getInt("smart-stacker.technical.splits"); |
|
|
nameformat = ChatColor.translateAlternateColorCodes('&', |
|
|
nameformat = ChatColor.translateAlternateColorCodes('&', |
|
|
Main.config.getString("smart-stacker.gameplay.tag-format")); |
|
|
Main.config.getString("smart-stacker.gameplay.tag-format")); |
|
|
regexpat = nameformat.replace("{size}", "(.*.)"); |
|
|
regexpat = nameformat.replace("{size}", "(.*.)"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
@SuppressWarnings("unchecked") |
|
|
public StackChunk(Chunk chk) { |
|
|
public StackChunk(Chunk chk) { |
|
|
|
|
|
|
|
|
ents = (Map<EntityType, ArrayList<Entity>>[]) new HashMap[256 / splits]; |
|
|
|
|
|
|
|
|
ents = (Map<EntityType, HashSet<Entity>>[]) new HashMap[256 / splits]; |
|
|
|
|
|
|
|
|
for (int i = 0; i < 256 / splits; i++) { |
|
|
for (int i = 0; i < 256 / splits; i++) { |
|
|
ents[i] = new HashMap<EntityType, ArrayList<Entity>>(); |
|
|
|
|
|
|
|
|
ents[i] = new HashMap<EntityType, HashSet<Entity>>(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -54,7 +57,7 @@ public class StackChunk { |
|
|
// kept alive.
|
|
|
// kept alive.
|
|
|
public static boolean tryStacking(Location loc, EntityType type, Entity optional) { |
|
|
public static boolean tryStacking(Location loc, EntityType type, Entity optional) { |
|
|
Chunk chk = loc.getChunk(); |
|
|
Chunk chk = loc.getChunk(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
StackChunk stchk; |
|
|
StackChunk stchk; |
|
|
|
|
|
|
|
|
if (chunks.containsKey(chk)) { |
|
|
if (chunks.containsKey(chk)) { |
|
@ -82,7 +85,7 @@ public class StackChunk { |
|
|
Entity free = getMatch(stchk.ents[split], loc, type, optional); |
|
|
Entity free = getMatch(stchk.ents[split], loc, type, optional); |
|
|
|
|
|
|
|
|
size += getStack(free); |
|
|
size += getStack(free); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Main.sendDebug("FINAL SIZE: " + size, 2); |
|
|
Main.sendDebug("FINAL SIZE: " + size, 2); |
|
|
|
|
|
|
|
|
consumed = (free.equals(optional)) ? false : true; |
|
|
consumed = (free.equals(optional)) ? false : true; |
|
@ -116,47 +119,55 @@ public class StackChunk { |
|
|
return consumed; |
|
|
return consumed; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private static Entity getMatch(Map<EntityType, ArrayList<Entity>> ents, Location loc, EntityType type, |
|
|
|
|
|
|
|
|
private static Entity getMatch(Map<EntityType, HashSet<Entity>> ents, Location loc, EntityType type, |
|
|
Entity optional) { |
|
|
Entity optional) { |
|
|
|
|
|
|
|
|
if (!ents.containsKey(type)) { |
|
|
if (!ents.containsKey(type)) { |
|
|
ents.put(type, new ArrayList<Entity>()); |
|
|
|
|
|
|
|
|
ents.put(type, new HashSet<Entity>()); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
List<Entity> list = ents.get(type); |
|
|
|
|
|
|
|
|
Set<Entity> list = ents.get(type); |
|
|
|
|
|
|
|
|
Entity ideal = null; |
|
|
Entity ideal = null; |
|
|
|
|
|
|
|
|
if (optional == null) { |
|
|
if (optional == null) { |
|
|
if (list.isEmpty()) { |
|
|
|
|
|
|
|
|
if (list.isEmpty() || isUnderMinimum(list)) { |
|
|
ideal = loc.getWorld().spawnEntity(loc, type); |
|
|
ideal = loc.getWorld().spawnEntity(loc, type); |
|
|
list.add(ideal); |
|
|
list.add(ideal); |
|
|
return ideal; |
|
|
return ideal; |
|
|
} else { |
|
|
} else { |
|
|
return list.get(0); |
|
|
|
|
|
|
|
|
return list.iterator().next(); |
|
|
} |
|
|
} |
|
|
|
|
|
} else if (isUnderMinimum(list)) { |
|
|
|
|
|
list.add(optional); |
|
|
|
|
|
return optional; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (Entity ent : list) { |
|
|
for (Entity ent : list) { |
|
|
boolean similar = StackComparer.isSimilar(ent, optional); |
|
|
boolean similar = StackComparer.isSimilar(ent, optional); |
|
|
if (similar) { |
|
|
if (similar) { |
|
|
return ent; |
|
|
return ent; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
list.add(optional); |
|
|
list.add(optional); |
|
|
return optional; |
|
|
return optional; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public static int getStack(Entity ent) { |
|
|
public static int getStack(Entity ent) { |
|
|
if (!StackManager.smartstacker) { |
|
|
if (!StackManager.smartstacker) { |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ent == null) { |
|
|
if (ent == null) { |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ent.hasMetadata("lagassist.stacksize")) { |
|
|
|
|
|
return ent.getMetadata("lagassist.stacksize").get(0).asInt(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
String name = ent.getCustomName(); |
|
|
String name = ent.getCustomName(); |
|
|
|
|
|
|
|
|
if (name == null) { |
|
|
if (name == null) { |
|
@ -165,7 +176,7 @@ public class StackChunk { |
|
|
|
|
|
|
|
|
Pattern pat = Pattern.compile(regexpat.replace("{type}", Others.firstHighcase(ent.getType().toString())), |
|
|
Pattern pat = Pattern.compile(regexpat.replace("{type}", Others.firstHighcase(ent.getType().toString())), |
|
|
Pattern.MULTILINE); |
|
|
Pattern.MULTILINE); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Matcher match = pat.matcher(name); |
|
|
Matcher match = pat.matcher(name); |
|
|
|
|
|
|
|
|
if (!match.find()) { |
|
|
if (!match.find()) { |
|
@ -185,6 +196,7 @@ public class StackChunk { |
|
|
String formatted = nameformat.replace("{type}", Others.firstHighcase(ent.getType().toString())) |
|
|
String formatted = nameformat.replace("{type}", Others.firstHighcase(ent.getType().toString())) |
|
|
.replace("{size}", "" + Math.min(size, Main.config.getInt("smart-stacker.technical.max-stack"))); |
|
|
.replace("{size}", "" + Math.min(size, Main.config.getInt("smart-stacker.technical.max-stack"))); |
|
|
|
|
|
|
|
|
|
|
|
ent.setMetadata("lagassist.stacksize", new FixedMetadataValue(Main.p, size)); |
|
|
ent.setCustomName(formatted); |
|
|
ent.setCustomName(formatted); |
|
|
ent.setCustomNameVisible(Main.config.getBoolean("smart-stacker.gameplay.tag-visibility")); |
|
|
ent.setCustomNameVisible(Main.config.getBoolean("smart-stacker.gameplay.tag-visibility")); |
|
|
} |
|
|
} |
|
@ -201,7 +213,7 @@ public class StackChunk { |
|
|
if (stack < 2) { |
|
|
if (stack < 2) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<ItemStack> drops = new ArrayList<ItemStack>(); |
|
|
List<ItemStack> drops = new ArrayList<ItemStack>(); |
|
|
|
|
|
|
|
|
for (ItemStack itm : e.getDrops()) { |
|
|
for (ItemStack itm : e.getDrops()) { |
|
@ -216,7 +228,7 @@ public class StackChunk { |
|
|
|
|
|
|
|
|
e.getDrops().clear(); |
|
|
e.getDrops().clear(); |
|
|
e.getDrops().addAll(drops); |
|
|
e.getDrops().addAll(drops); |
|
|
e.setDroppedExp(e.getDroppedExp()*stack); |
|
|
|
|
|
|
|
|
e.setDroppedExp(e.getDroppedExp() * stack); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public static void runShutdown() { |
|
|
public static void runShutdown() { |
|
@ -225,7 +237,7 @@ public class StackChunk { |
|
|
} |
|
|
} |
|
|
for (StackChunk chk : chunks.values()) { |
|
|
for (StackChunk chk : chunks.values()) { |
|
|
for (int i = 0; i < splits; i++) { |
|
|
for (int i = 0; i < splits; i++) { |
|
|
for (List<Entity> elist : chk.ents[i].values()) { |
|
|
|
|
|
|
|
|
for (Set<Entity> elist : chk.ents[i].values()) { |
|
|
for (Entity ent : elist) { |
|
|
for (Entity ent : elist) { |
|
|
ent.remove(); |
|
|
ent.remove(); |
|
|
} |
|
|
} |
|
@ -262,25 +274,50 @@ public class StackChunk { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void unloadChunk(Chunk chk) { |
|
|
public static void unloadChunk(Chunk chk) { |
|
|
StackChunk stack = chunks.get(chk); |
|
|
StackChunk stack = chunks.get(chk); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (stack == null) { |
|
|
if (stack == null) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
for (Map<EntityType, ArrayList<Entity>> m : stack.ents) { |
|
|
|
|
|
for (ArrayList<Entity> types : m.values()) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (Map<EntityType, HashSet<Entity>> m : stack.ents) { |
|
|
|
|
|
for (HashSet<Entity> types : m.values()) { |
|
|
for (Entity ent : types) { |
|
|
for (Entity ent : types) { |
|
|
ent.remove(); |
|
|
ent.remove(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
chunks.remove(chk); |
|
|
chunks.remove(chk); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
* Implement min stack feature in beta. |
|
|
|
|
|
* |
|
|
|
|
|
* TODO: TEST FUNCTIONALITY |
|
|
|
|
|
*/ |
|
|
|
|
|
protected static boolean isUnderMinimum(Set<Entity> ents) { |
|
|
|
|
|
int minstack = Main.config.getInt("smart-stacker.technical.min-stack"); |
|
|
|
|
|
|
|
|
|
|
|
if (minstack <= 1) { |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int stacktotal = getStackTotal(ents); |
|
|
|
|
|
|
|
|
|
|
|
return minstack > 0 && stacktotal < minstack; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static int getStackTotal(Set<Entity> ents) { |
|
|
|
|
|
int total = 0; |
|
|
|
|
|
for (Entity ent : ents) { |
|
|
|
|
|
total += getStack(ent); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return total; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Setting clean to true makes it force it;
|
|
|
// Setting clean to true makes it force it;
|
|
@ -291,7 +328,7 @@ public class StackChunk { |
|
|
|
|
|
|
|
|
StackChunk stchk = chunks.get(chk); |
|
|
StackChunk stchk = chunks.get(chk); |
|
|
|
|
|
|
|
|
if (!stchk.ents[split].containsKey(ent)) { |
|
|
|
|
|
|
|
|
if (!stchk.ents[split].containsKey(ent) || isUnderMinimum(stchk.ents[split].get(ent))) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|