diff --git a/TwosideKeeper.jar b/TwosideKeeper.jar index 150006b..7283711 100644 Binary files a/TwosideKeeper.jar and b/TwosideKeeper.jar differ diff --git a/src/sig/plugin/TwosideKeeper/CustomDamage.java b/src/sig/plugin/TwosideKeeper/CustomDamage.java index 3ad6bdb..87f152c 100644 --- a/src/sig/plugin/TwosideKeeper/CustomDamage.java +++ b/src/sig/plugin/TwosideKeeper/CustomDamage.java @@ -2495,6 +2495,15 @@ public class CustomDamage { return true; //Cancel any damage events in Spectator mode or Creative Mode. } if (target.isInvulnerable()) { + if (shooter instanceof Player && shooter.hasPermission("TwosideKeeper.modifyModels")) { + Player p = (Player)shooter; + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + if (EntityUtils.isValidEntity(target) && + target instanceof ArmorStand) { + shooter.sendMessage("Selected Armor Stand "+ChatColor.GREEN+target.getUniqueId()); + pd.myStand = (ArmorStand)target; + } + } return true; //Cancel any damage events when the target is invulnerable. } if (isFlagSet(flags,IGNORE_DAMAGE_TICK)) { @@ -4201,7 +4210,7 @@ public class CustomDamage { damage = target.getMaxHealth()*dmgLimit; //TwosideKeeper.log("Damage limit reached (Hit for "+olddamage+". Lowering to "+damage, 1); } - return Math.min(damage, TwosideKeeper.CUSTOM_DAMAGE_IDENTIFIER-1); + return Math.min(damage, TwosideKeeper.CUSTOM_DAMAGE_IDENTIFIER-1); } /** @@ -4209,7 +4218,7 @@ public class CustomDamage { */ private static double getDamageLimit(LivingEntity target) { double pct = 1.0; - if (GenericFunctions.isBossMonster(target)) { + if (target!=null && !(target instanceof Player) && GenericFunctions.isBossMonster(target)) { pct = BOSS_DAMAGE_LIMIT; } return pct; diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/ArmorStandLinker.java b/src/sig/plugin/TwosideKeeper/HelperStructures/ArmorStandLinker.java new file mode 100644 index 0000000..22f13cd --- /dev/null +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/ArmorStandLinker.java @@ -0,0 +1,33 @@ +package sig.plugin.TwosideKeeper.HelperStructures; + +import org.bukkit.Location; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.EntityType; + +import sig.plugin.TwosideKeeper.HelperStructures.Common.ArmorStandProperties; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.EntityUtils; + +public class ArmorStandLinker { + ArmorStandProperties myModel; + ArmorStand ent; + Location loc; + + public ArmorStandLinker(Location loc) { + ent = (ArmorStand)loc.getWorld().spawnEntity(loc, EntityType.ARMOR_STAND); + this.loc=loc; + } + + public void run() { + if (!EntityUtils.isValidEntity(ent)) { + ent = (ArmorStand)loc.getWorld().spawnEntity(loc, EntityType.ARMOR_STAND); + } + } + + public void setLocation(Location loc) { + this.loc=loc.clone(); + } + + public Location getLocation() { + return loc; + } +} diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Common/ArmorStandProperties.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Common/ArmorStandProperties.java index 6d422b9..d68fb81 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Common/ArmorStandProperties.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Common/ArmorStandProperties.java @@ -1,15 +1,20 @@ package sig.plugin.TwosideKeeper.HelperStructures.Common; +import java.lang.reflect.Field; + import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import org.bukkit.util.EulerAngle; import org.bukkit.util.Vector; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.JavaUtils; import sig.plugin.TwosideKeeper.HelperStructures.Utils.MathUtils; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.ReflectUtils; public class ArmorStandProperties { final public static ArmorStandProperties SCEPTERBASE = new ArmorStandProperties(); final public static ArmorStandProperties SCEPTERTOP = new ArmorStandProperties(); + final public static ArmorStandProperties BLANK = new ArmorStandProperties(); boolean arms = false; boolean baseplate = false; @@ -30,11 +35,45 @@ public class ArmorStandProperties { boolean visible=true; boolean customNameVisible=false; String customName=""; + boolean gravity=false; Vector offset = new Vector(); + Vector dir = new Vector(); public ArmorStandProperties() { } + + public ArmorStandProperties clone() { + ArmorStandProperties newpos = new ArmorStandProperties(); + for (Field f : this.getClass().getDeclaredFields()) { + if (ReflectUtils.isCloneable(f)) { + try { + f.set(newpos, f.get(this)); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + } + return newpos; + } + + public Vector getFacingDirection() { + return dir; + } + + public void setFacingDirection(Vector dir) { + this.dir=dir; + } + + public void setGravity(boolean gravity) { + this.gravity=gravity; + } + + public boolean isGravityOn() { + return this.gravity; + } public boolean isArms() { return arms; diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java index 994c9b1..ec4c789 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Common/GenericFunctions.java @@ -99,6 +99,7 @@ import sig.plugin.TwosideKeeper.HelperStructures.CubeType; import sig.plugin.TwosideKeeper.HelperStructures.CustomItem; import sig.plugin.TwosideKeeper.HelperStructures.EliteMonsterLocationFinder; import sig.plugin.TwosideKeeper.HelperStructures.ItemSet; +import sig.plugin.TwosideKeeper.HelperStructures.LivingEntityDifficulty; import sig.plugin.TwosideKeeper.HelperStructures.PlayerMode; import sig.plugin.TwosideKeeper.HelperStructures.WorldShop; import sig.plugin.TwosideKeeper.HelperStructures.Effects.WindSlash; @@ -2311,12 +2312,16 @@ public class GenericFunctions { } public static boolean isBossMonster(LivingEntity m) { + LivingEntityDifficulty dif = null; + if (m!=null) { + dif = MonsterController.getLivingEntityDifficulty(m); + } if (MonsterController.isZombieLeader(m) || (m.getType()==EntityType.GUARDIAN && ((Guardian)m).isElder()) || m.getType()==EntityType.ENDER_DRAGON || m.getType()==EntityType.WITHER || - MonsterController.getLivingEntityDifficulty(m).name().contains("MINIBOSS") || + (dif!=null && dif.name().contains("MINIBOSS")) || LivingEntityStructure.GetLivingEntityStructure(m).getLeader() || LivingEntityStructure.GetLivingEntityStructure(m).getElite()) { return true; diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/CustomModel.java b/src/sig/plugin/TwosideKeeper/HelperStructures/CustomModel.java index b3c2fdf..556bf02 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/CustomModel.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/CustomModel.java @@ -1,28 +1,62 @@ package sig.plugin.TwosideKeeper.HelperStructures; +import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.UUID; +import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.EulerAngle; +import org.bukkit.util.Vector; +import sig.plugin.TwosideKeeper.TwosideKeeper; import sig.plugin.TwosideKeeper.HelperStructures.Common.ArmorStandProperties; +import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.EntityUtils; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.FileUtils; public class CustomModel { - List modelParts = new ArrayList(); - List stands = new ArrayList(); + public List modelParts = new ArrayList(); + public List stands = new ArrayList(); + Location origin; public CustomModel(Location loc, ArmorStandProperties...modelParts) { + origin = loc.clone(); for (ArmorStandProperties asp : modelParts) { - this.modelParts.add(asp); - this.stands.add(setupArmorStand(loc, asp)); + AddModelPart(asp); } } - private ArmorStand setupArmorStand(Location loc, ArmorStandProperties asp) { - ArmorStand stand = (ArmorStand)loc.getWorld().spawnEntity(loc, EntityType.ARMOR_STAND); + public static ArmorStandProperties getPropertyFromStand(UUID id) { + for (CustomModel model : TwosideKeeper.models) { + for (int i=0;i{ + AddModelPart(origin.clone().add(modelProp.getOffset()),modelProp); + },(i+1)*20); + /*modelParts.add(modelProp); + stands.add(setupArmorStand(loc,modelProp));*/ + } + } + + public ItemStack parseItemStack(String csvString) { + String[] parse = csvString.split(";"); + ItemStack item = new ItemStack(Material.valueOf(parse[0])); + boolean isEnchanted = Boolean.parseBoolean(parse[1]); + if (isEnchanted) { + item.addUnsafeEnchantment(Enchantment.values()[(int)(Math.random()*Enchantment.values().length)], 9); + } + return item; + } + + public Vector parseVector(String csvString) { + String[] parse = csvString.split(";"); + return new Vector(Double.parseDouble(parse[0]),Double.parseDouble(parse[1]),Double.parseDouble(parse[2])); + } + + public EulerAngle parseEulerAngle(String csvString) { + String[] parse = csvString.split(";"); + return new EulerAngle(Double.parseDouble(parse[0]),Double.parseDouble(parse[1]),Double.parseDouble(parse[2])); + } + + public void saveModel(String modelName) { + StringBuilder[] propertyName = new StringBuilder[]{new StringBuilder("Arms,"), + new StringBuilder("BasePlate,"), + new StringBuilder("BodyPose,"), + new StringBuilder("Boots,"), + new StringBuilder("Chestplate,"), + new StringBuilder("HeadPose,"), + new StringBuilder("Helmet,"), + new StringBuilder("ItemInHand,"), + new StringBuilder("LeftArmPose,"), + new StringBuilder("LeftLegPose,"), + new StringBuilder("Leggings,"), + new StringBuilder("Marker,"), + new StringBuilder("RighArmPose,"), + new StringBuilder("RightLegPose,"), + new StringBuilder("Small,"), + new StringBuilder("Visible,"), + new StringBuilder("CustomNameVisible,"), + new StringBuilder("CustomName,"), + new StringBuilder("Offset,"), + new StringBuilder("Direction,"), + new StringBuilder("Gravity,")}; + for (int j=0;j0)?Boolean.toString(true):Boolean.toString(false)); + } + + private String ConvertEulerAngle(EulerAngle angle) { + return angle.getX()+";"+angle.getY()+";"+angle.getZ(); + } + + private String ConvertVector(Vector angle) { + return angle.getX()+";"+angle.getY()+";"+angle.getZ(); + } + + public static void cleanup(CustomModel model) { + model.cleanup(); + TwosideKeeper.models.remove(model); + model=null; + } + + public void cleanup() { + for (ArmorStand stand : stands) { + TwosideKeeper.log("Removing entity ("+GenericFunctions.getDisplayName(stand)+")"+stand.getUniqueId(), 1); + stand.remove(); } + stands.clear(); + modelParts.clear(); } } diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/DamageLabel.java b/src/sig/plugin/TwosideKeeper/HelperStructures/DamageLabel.java index 451b825..d20a9a0 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/DamageLabel.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/DamageLabel.java @@ -16,11 +16,13 @@ public class DamageLabel{ ArmorStand aec; double spd; int duration; + Location loc; - public DamageLabel(ArmorStand aec, double spd, int duration) { + public DamageLabel(Location loc, ArmorStand aec, double spd, int duration) { this.aec=aec; this.spd=spd; this.duration=duration; + this.loc=loc; } public boolean run() { @@ -29,7 +31,11 @@ public class DamageLabel{ /*if (duration>0) { Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, new CloudRunnableRemoveLabel(aec.getLocation().add(0,spd,0).clone(),aec.getCustomName(),spd,duration), 1); }*/ - aec.teleport(aec.getLocation().add(0,spd,0)); + if (loc!=null) { + aec.teleport(loc.add(0,spd,0)); + } else { + aec.teleport(aec.getLocation().add(0,spd,0)); + } if (duration<0) { aec.remove(); return false; diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Model.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Model.java new file mode 100644 index 0000000..ee77e82 --- /dev/null +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Model.java @@ -0,0 +1,42 @@ +package sig.plugin.TwosideKeeper.HelperStructures; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Location; + +import sig.plugin.TwosideKeeper.HelperStructures.Common.ArmorStandProperties; +import utils.Utils.Vector3D; + +public class Model { + List modelParts = new ArrayList(); + List models = new ArrayList(); + + Location loc; + Vector3D offset = new Vector3D(0,0,0); + double degreeRotation = 0; + + public Model(Location loc, ArmorStandProperties...modelParts) { + this.modelParts = Arrays.asList(modelParts); + for (ArmorStandProperties prop : modelParts) { + models.add(new ArmorStandLinker(loc)); + } + this.loc=loc; + } + + public void run() { + for (ArmorStandLinker parts : models) { + parts.run(); + parts.setLocation(loc); + } + } + + public void setLocation(Location loc) { + this.loc = loc.clone(); + } + + public Location getLocation() { + return loc; + } +} diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/EntityUtils.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/EntityUtils.java index 3220238..e2caca2 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/EntityUtils.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/EntityUtils.java @@ -79,8 +79,8 @@ public class EntityUtils { public static void applyDamageIndicator(Entity e, double damage, IndicatorType type) { Location offsetloc = e.getLocation().add(Math.random()/2-0.25,0.5,Math.random()/2-0.25); if (damage>=1) { - ArmorStand aec = CreateOverlayText(offsetloc,((damage>=100)?ChatColor.BOLD+" ":"")+type.getColor()+Integer.toString((int)damage)+((damage>=100)?" ":"")); - TwosideKeeper.labelqueue.add(new DamageLabel(aec,0.1,(int)(10*Math.min(Math.max(1,(double)damage/50),2)))); + ArmorStand aec = CreateOverlayText(new Location(offsetloc.getWorld(),offsetloc.getX(),32648,offsetloc.getZ()),((damage>=100)?ChatColor.BOLD+" ":"")+type.getColor()+Integer.toString((int)damage)+((damage>=100)?" ":"")); + TwosideKeeper.labelqueue.add(new DamageLabel(offsetloc,aec,0.1,(int)(10*Math.min(Math.max(1,(double)damage/50),2)))); } } diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/FileUtils.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/FileUtils.java index 87b011a..4c2e2ea 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/FileUtils.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/FileUtils.java @@ -1,12 +1,24 @@ package sig.plugin.TwosideKeeper.HelperStructures.Utils; - import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.Reader; +import java.net.URL; +import java.nio.channels.FileChannel; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; +import org.json.JSONException; +import org.json.JSONObject; + public class FileUtils { public static String[] readFromFile(String filename) { File file = new File(filename); @@ -32,4 +44,114 @@ public class FileUtils { } return contents.toArray(new String[contents.size()]); } + + private static String readAll(Reader rd) throws IOException { + StringBuilder sb = new StringBuilder(); + int cp; + while ((cp = rd.read()) != -1) { + sb.append((char) cp); + } + return sb.toString(); + } + + public static JSONObject readJsonFromUrl(String url) throws IOException, JSONException { + InputStream is = new URL(url).openStream(); + try { + BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); + String jsonText = readAll(rd); + JSONObject json = new JSONObject(jsonText); + jsonText=null; + return json; + } finally { + is.close(); + } + } + + public static JSONObject readJsonFromFile(String file) throws IOException, JSONException { + InputStream is = new FileInputStream(new File(file)); + try { + BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); + String jsonText = readAll(rd); + JSONObject json = new JSONObject(jsonText); + jsonText=null; + return json; + } finally { + is.close(); + } + } + + public static JSONObject readJsonFromUrl(String url, String file, boolean writeToFile) throws IOException, JSONException { + InputStream is = new URL(url).openStream(); + try { + BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); + String jsonText = readAll(rd); + if (writeToFile) { + writetoFile(new String[]{jsonText},file); + } + JSONObject json = new JSONObject(jsonText); + return json; + } finally { + is.close(); + } + } + + public static void logToFile(String message, String filename) { + File file = new File(filename); + try { + + if (!file.exists()) { + file.createNewFile(); + } + + FileWriter fw = new FileWriter(file, true); + PrintWriter pw = new PrintWriter(fw); + + pw.println(message); + pw.flush(); + pw.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void writetoFile(String[] data, String filename) { + File file = new File(filename); + try { + + if (!file.exists()) { + file.createNewFile(); + } + + FileWriter fw = new FileWriter(file,false); + PrintWriter pw = new PrintWriter(fw); + + for (String s : data) { + pw.println(s); + } + pw.flush(); + pw.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void copyFile(File source, File dest) throws IOException { + FileChannel sourceChannel = null; + FileChannel destChannel = null; + try { + sourceChannel = new FileInputStream(source).getChannel(); + destChannel = new FileOutputStream(dest).getChannel(); + destChannel.transferFrom(sourceChannel, 0, sourceChannel.size()); + }finally{ + sourceChannel.close(); + destChannel.close(); + } + } + + public static void deleteFile(String filename) { + File file = new File(filename); + if (file.exists()) { + file.delete(); + } + } } diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/JavaUtils.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/JavaUtils.java new file mode 100644 index 0000000..c83afef --- /dev/null +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/JavaUtils.java @@ -0,0 +1,49 @@ +package sig.plugin.TwosideKeeper.HelperStructures.Utils; +import java.lang.reflect.Field; + +public class JavaUtils { + public JavaUtils clone() { + JavaUtils newpos = new JavaUtils(); + for (Field f : this.getClass().getDeclaredFields()) { + if (ReflectUtils.isCloneable(f)) { + try { + f.set(newpos, f.get(this)); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + } + return newpos; + } + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(this.getClass().getName()+"("); + boolean first=false; + for (Field f : this.getClass().getDeclaredFields()) { + if (!ReflectUtils.isCloneable(f)) { + if (!first) { + try { + sb.append(f.getName()+"="+f.get(this)); + first=true; + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } else { + try { + sb.append(","+f.getName()+"="+f.get(this)); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + } + } + sb.append(")"); + return sb.toString(); + } +} diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/ReflectUtils.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/ReflectUtils.java new file mode 100644 index 0000000..4857c27 --- /dev/null +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/ReflectUtils.java @@ -0,0 +1,9 @@ +package sig.plugin.TwosideKeeper.HelperStructures.Utils; +import java.lang.reflect.Field; + +public class ReflectUtils { + public static boolean isCloneable(Field f) { + int mods = f.getModifiers(); + return mods<8; + } +} diff --git a/src/sig/plugin/TwosideKeeper/TwosideKeeper.java b/src/sig/plugin/TwosideKeeper/TwosideKeeper.java index eb4c0dd..6fd1a6b 100644 --- a/src/sig/plugin/TwosideKeeper/TwosideKeeper.java +++ b/src/sig/plugin/TwosideKeeper/TwosideKeeper.java @@ -1179,6 +1179,15 @@ public class TwosideKeeper extends JavaPlugin implements Listener { return (totalregen+baseregen)*regenmult; } } + + public void SetupFolders(String...folders) { + for (String s : folders) { + File fold = new File(TwosideKeeper.plugin.getDataFolder()+"/"+s); + if (!fold.exists()) { + fold.mkdirs(); + } + } + } @Override public void onEnable() { @@ -1187,6 +1196,18 @@ public class TwosideKeeper extends JavaPlugin implements Listener { plugin=this; loadConfig(); + + SetupFolders("arrowquivers", + "books", + "debug", + "inventorybackup", + "itemcubes", + "itemrecords", + "logs", + "models", + "records", + "updates", + "users"); CustomItem.InitializeItemRecipes(); Recipes.Initialize_ItemCube_Recipes(); @@ -1526,6 +1547,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { ReplaceBlockTask.CleanupTemporaryBlock(tb); } log(ChatColor.YELLOW+" "+(System.currentTimeMillis()-betweentime)+"ms",CLEANUP_DEBUG); + betweentime = System.currentTimeMillis(); log("Resetting Mob Names ["+livingentitydata.size()+"]",CLEANUP_DEBUG); for (UUID id : livingentitydata.keySet()) { //TemporaryBlock tb = temporaryblocks.get(ss); @@ -1535,16 +1557,24 @@ public class TwosideKeeper extends JavaPlugin implements Listener { //TwosideKeeper.log("Saving unloaded monster "+les.getUnloadedName(), 0); } log(ChatColor.YELLOW+" "+(System.currentTimeMillis()-betweentime)+"ms",CLEANUP_DEBUG); + betweentime = System.currentTimeMillis(); log("Removing Instances ["+roominstances.size()+"]",CLEANUP_DEBUG); for (Room room : roominstances) { room.killWorld(); } log(ChatColor.YELLOW+" "+(System.currentTimeMillis()-betweentime)+"ms",CLEANUP_DEBUG); + betweentime = System.currentTimeMillis(); log("Removing Damage Labels ["+labelqueue.size()+"]",CLEANUP_DEBUG); for (DamageLabel label : labelqueue) { label.cleanup(); } log(ChatColor.YELLOW+" "+(System.currentTimeMillis()-betweentime)+"ms",CLEANUP_DEBUG); + betweentime = System.currentTimeMillis(); + log("Removing Models ["+models.size()+"]",CLEANUP_DEBUG); + for (CustomModel model : models) { + model.cleanup(); + } + log(ChatColor.YELLOW+" "+(System.currentTimeMillis()-betweentime)+"ms",CLEANUP_DEBUG); long endtime = System.currentTimeMillis(); log("Cleanup Maintenance completed. Total Time: "+(endtime-starttime)+"ms.",CLEANUP_DEBUG); } @@ -2871,7 +2901,14 @@ public class TwosideKeeper extends JavaPlugin implements Listener { case 19:{ Location currentloc = pd.myStand.getLocation().clone(); currentloc.add(Double.parseDouble(args[2]),Double.parseDouble(args[3]),Double.parseDouble(args[4])); - pd.myStand.teleport(currentloc); + ArmorStandProperties prop = CustomModel.getPropertyFromStand(pd.myStand.getUniqueId()); + Vector currentOffset = prop.getOffset(); + prop.setOffset(new Vector(currentOffset.getX()+Double.parseDouble(args[2]),currentOffset.getY()+Double.parseDouble(args[3]),currentOffset.getZ()+Double.parseDouble(args[4]))); + }break; + case 20:{ + ArmorStandProperties prop = CustomModel.getPropertyFromStand(pd.myStand.getUniqueId()); + Vector facingDirection = p.getLocation().getDirection(); + prop.setFacingDirection(facingDirection); }break; } }break; @@ -2925,6 +2962,36 @@ public class TwosideKeeper extends JavaPlugin implements Listener { aPlugin.API.setItem(p, p.getOpenInventory(), i, new ItemStack(Material.ACACIA_DOOR_ITEM)); } }break; + case "MODELS":{ + if (args.length==1) { + CustomModel mymod = new CustomModel(p.getLocation(),new ArmorStandProperties[]{ + ArmorStandProperties.BLANK + }); + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + pd.myModel = mymod; + models.add(pd.myModel); + } else + { + switch (args[1]) { + case "add":{ + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + pd.myModel.AddModelPart(ArmorStandProperties.BLANK); + }break; + case "save":{ + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + pd.myModel.saveModel(args[2]); + }break; + case "load":{ + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + pd.myModel.loadModel(p.getLocation(),args[2]); + }break; + case "remove":{ + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + CustomModel.cleanup(pd.myModel); + }break; + } + } + }break; } } //LivingEntity m = MonsterController.convertMonster((Monster)p.getWorld().spawnEntity(p.getLocation(),EntityType.ZOMBIE), MonsterDifficulty.ELITE); @@ -7908,8 +7975,23 @@ public class TwosideKeeper extends JavaPlugin implements Listener { } if (e instanceof ArmorStand) { ArmorStand as = (ArmorStand)e; - if (as.getRemoveWhenFarAway()) { + if (as.isInvulnerable()) { removalEntities.add(e); + CustomModel killModel = null; + for (CustomModel model : models) { + for (ArmorStand stands : model.stands) { + if (stands.getUniqueId().equals(e.getUniqueId())) { + killModel = model; + break; + } + } + if (killModel!=null) { + break; + } + } + if (killModel!=null) { + CustomModel.cleanup(killModel); + } } } } diff --git a/src/sig/plugin/TwosideKeeper/runServerTick.java b/src/sig/plugin/TwosideKeeper/runServerTick.java index 4563b3a..0e8c3da 100644 --- a/src/sig/plugin/TwosideKeeper/runServerTick.java +++ b/src/sig/plugin/TwosideKeeper/runServerTick.java @@ -33,10 +33,14 @@ public class runServerTick implements Runnable{ TwosideKeeper.labelqueue.remove(i--); } } + for (CustomModel model : TwosideKeeper.models) { + model.displayModel(); + } for (Player p : Bukkit.getOnlinePlayers()) { PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); if (!aPluginAPIWrapper.isAFK(p)) { //pd.myModel.displayModel(p.getLocation()); + //pd.myModel.displayModel(); if (pd.myPet!=null) { pd.myPet.run(); }