diff --git a/TwosideKeeper.jar b/TwosideKeeper.jar index 05723b3..530e3dc 100644 Binary files a/TwosideKeeper.jar and b/TwosideKeeper.jar differ diff --git a/src/sig/plugin/TwosideKeeper/Boss/Arena.java b/src/sig/plugin/TwosideKeeper/Boss/Arena.java new file mode 100644 index 0000000..5376cd1 --- /dev/null +++ b/src/sig/plugin/TwosideKeeper/Boss/Arena.java @@ -0,0 +1,289 @@ +package sig.plugin.TwosideKeeper.Boss; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Chunk; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Player; +import org.bukkit.inventory.InventoryHolder; + +import sig.plugin.TwosideKeeper.TwosideKeeper; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.SoundUtils; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.Classes.Box; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.Classes.MaterialData; + +/** + * Holds data about an arena. + */ +public class Arena { + HashMap oldblocklist = new HashMap(); + List wallmats = new ArrayList(); + List floormats = new ArrayList(); + List roofmats = new ArrayList(); + List insidemats = new ArrayList(); + List temporarychunks = new ArrayList(); + List arenaplayers = new ArrayList(); + Box box; + World world; + + public Arena(World world, int x, int y, int z, int w, int h, int d,Material arena_mat) { + this.world = world; + this.box = new Box(x,y,z,w,h,d); + this.wallmats.add(arena_mat); + this.floormats.add(arena_mat); + this.roofmats.add(arena_mat); + } + + public Arena(World world, int x, int y, int z, int w, int h, int d,Material...arena_mats) { + this.world = world; + this.box = new Box(x,y,z,w,h,d); + for (Material mat : arena_mats) { + this.wallmats.add(mat); + this.floormats.add(mat); + this.roofmats.add(mat); + } + } + + public Arena(World world, int x, int y, int z, int w, int h, int d,Material insidemat, Material...arena_mats) { + this.world = world; + this.box = new Box(x,y,z,w,h,d); + for (Material mat : arena_mats) { + this.wallmats.add(mat); + this.floormats.add(mat); + this.roofmats.add(mat); + } + this.insidemats.add(insidemat); + } + + public Arena(World world, int x, int y, int z, int w, int h, int d,Material insidemat, Material wallmat, Material floormat, Material roofmat) { + this.world = world; + this.box = new Box(x,y,z,w,h,d); + this.wallmats.add(wallmat); + this.floormats.add(floormat); + this.roofmats.add(roofmat); + this.insidemats.add(insidemat); + } + + public Arena(World world, int x, int y, int z, int w, int h, int d, Material[] insidemats, Material[] wallmats, Material[] floormats, Material[] roofmats) { + this.world = world; + this.box = new Box(x,y,z,w,h,d); + for (Material mat : wallmats) { + this.wallmats.add(mat); + } + for (Material mat : floormats) { + this.floormats.add(mat); + } + for (Material mat : roofmats) { + this.roofmats.add(mat); + } + for (Material mat : insidemats) { + this.insidemats.add(mat); + } + } + + public void runTick() { + for (Player p : arenaplayers) { + if (p==null || !p.isValid()) { + TwosideKeeper.ScheduleRemoval(arenaplayers,p); + } + } + for (Player p : Bukkit.getOnlinePlayers()) { + if (p.getGameMode()==GameMode.SURVIVAL) { + if (arenaplayers.contains(p)) { + if (!insideBoundaries(p)) { + p.teleport(new Location(world,box.getX()+(box.getWidth()/2),box.getY()+(box.getHeight()/2),box.getZ()+(box.getDepth()/2))); + p.sendMessage(ChatColor.GREEN+"You cannot leave this arena!"); + } + } else { + if (insideBoundaries(p)) { + p.teleport(new Location(world,box.getX()+(box.getWidth()/2),box.getY()+(box.getHeight()*2),box.getZ()+(box.getDepth()/2))); + p.sendMessage(ChatColor.GREEN+"You cannot enter this arena!"); + } + } + } + } + } + + private boolean insideBoundaries(Player p) { + int x = p.getLocation().getBlockX(); + int y = p.getLocation().getBlockY(); + int z = p.getLocation().getBlockZ(); + return (x>=box.getX() && x<=box.getX()+box.getWidth() && + y>=box.getY() && y<=box.getY()+box.getHeight() && + z>=box.getZ() && z<=box.getZ()+box.getDepth()); + } + + public void AddPlayers(Player...players) { + for (Player p : players) { + arenaplayers.add(p); + } + } + + public void RemovePlayers(Player...players) { + for (Player p : players) { + arenaplayers.remove(p); + } + } + + public void AssembleArena() { + final int x = box.getX(); + final int y = box.getY(); + final int z = box.getZ(); + AssembleArena(x,y,z,box.clone()); + } + + public void DisassembleArena() { + DisassembleArena(-1); + } + + public void DisassembleArena(int amt) { + //amt is how many blocks to process in one tick. + int processed=0; + for (Block b : oldblocklist.keySet()) { + Chunk c = b.getChunk(); + if (!TwosideKeeper.temporary_chunks.contains(c)) { + TwosideKeeper.temporary_chunks.add(c); + } + c.load(); + if (!temporarychunks.contains(c)) { + temporarychunks.add(c); + } + MaterialData dat = oldblocklist.get(b); + if (b.getType()!=dat.getType() || b.getData()!=dat.getData()) { + b.setType(dat.getType()); + b.setData(dat.getData()); + } + if (amt!=-1) {TwosideKeeper.ScheduleRemoval(oldblocklist, b);} + processed++; + if (processed>amt && amt!=-1) { + break; + } + } + if (amt!=-1 && oldblocklist.size()>0) { + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{DisassembleArena(amt);}, 1); + } + } + + private void AssembleArena(int curx, int cury, int curz, Box box) { + for (int i=0;i<8;i++) { + Block b = world.getBlockAt(curx, cury, curz); + Chunk c = b.getChunk(); + if (!TwosideKeeper.temporary_chunks.contains(c)) { + TwosideKeeper.temporary_chunks.add(c); + } + c.load(); + if (!temporarychunks.contains(c)) { + temporarychunks.add(c); + } + while (b.getState()!=null && b.getState() instanceof InventoryHolder) { + if (curx>box.getX()+box.getWidth()) { + curx=box.getX(); + cury++; + } + if (cury>box.getY()+box.getHeight()) { + cury=box.getY(); + curz++; + } + if (curzbox.getX()+box.getWidth()) { + curx=box.getX(); + cury++; + } + if (cury>box.getY()+box.getHeight()) { + cury=box.getY(); + curz++; + } + if (curz{ + AssembleArena(x,y,z,box); + }, 1); + } else { + ClearAllTemporaryChunks(); + } + } + + private void ResetBlock(int curx, int cury, int curz, Box box, Block b) { + if (oldblocklist.containsKey(b)) { + MaterialData dat = oldblocklist.get(b); + if (b.getType()!=dat.getType() || b.getData()!=dat.getData()) { + b.setType(dat.getType()); + b.setData(dat.getData()); + } + oldblocklist.remove(b); + } + } + + public void ConvertBlock(int curx, int cury, int curz, Box box, Block b) { + if (isWallBlock(curx,cury,curz,box)) { + oldblocklist.put(b,new MaterialData(b.getType(),b.getData())); + b.setType(wallmats.get((int)(Math.random()*wallmats.size()))); + } else + if (isRoofBlock(curx,cury,curz,box)) { + oldblocklist.put(b,new MaterialData(b.getType(),b.getData())); + b.setType(roofmats.get((int)(Math.random()*roofmats.size()))); + } else + if (isFloorBlock(curx,cury,curz,box)) { + oldblocklist.put(b,new MaterialData(b.getType(),b.getData())); + b.setType(floormats.get((int)(Math.random()*floormats.size()))); + } else + { + oldblocklist.put(b,new MaterialData(b.getType(),b.getData())); + if (insidemats.size()>0) { + if (b.getType()!=Material.AIR && !b.isLiquid()) { + SoundUtils.playGlobalSound(b.getLocation(), Sound.BLOCK_METAL_BREAK, 0.3f, 0.3f); + } + b.setType(insidemats.get((int)(Math.random()*insidemats.size()))); + } else { + b.setType(Material.AIR); + } + } + /*final int x = curx++; + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{ + AssembleArena(x,cury,curz,box); + }, 1);*/ + } + + private boolean isFloorBlock(int curx, int cury, int curz, Box box2) { + return cury==box.getY(); + } + + private boolean isRoofBlock(int curx, int cury, int curz, Box box2) { + return cury==box.getY()+box.getHeight(); + } + + private boolean isWallBlock(int curx, int cury, int curz, Box box) { + return curx==box.getX() || curx==box.getWidth()+box.getX() || + curz==box.getZ() || curz==box.getZ()+box.getDepth(); + } + + public void Cleanup() { + //ClearAllTemporaryChunks(); + DisassembleArena(); + } + + private void ClearAllTemporaryChunks() { + TwosideKeeper.temporary_chunks.removeAll(temporarychunks); + temporarychunks.clear(); + } +} diff --git a/src/sig/plugin/TwosideKeeper/Boss/EliteGuardian.java b/src/sig/plugin/TwosideKeeper/Boss/EliteGuardian.java index 40232d7..a457811 100644 --- a/src/sig/plugin/TwosideKeeper/Boss/EliteGuardian.java +++ b/src/sig/plugin/TwosideKeeper/Boss/EliteGuardian.java @@ -4,6 +4,7 @@ import java.util.List; import org.bukkit.GameMode; import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Monster; import org.bukkit.entity.Player; @@ -11,6 +12,7 @@ import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; import sig.plugin.TwosideKeeper.EliteMonster; +import sig.plugin.TwosideKeeper.TwosideKeeper; import sig.plugin.TwosideKeeper.HelperStructures.Common.Camera; import sig.plugin.TwosideKeeper.HelperStructures.Common.GenericFunctions; @@ -20,6 +22,7 @@ public class EliteGuardian extends EliteMonster{ STATE state = STATE.WAITINGFORCUTSCENE; int cutscenetimer=0; Camera cam; + Arena arena; public EliteGuardian(Monster m) { super(m); @@ -37,8 +40,15 @@ public class EliteGuardian extends EliteMonster{ if (m.isValid() && targetlist.size()>0) { getGlow(); } + runArenaTick(); } + private void runArenaTick() { + if (arena!=null) { + arena.runTick(); + } + } + private void runStateMachine() { switch (state) { case PASSIVE: @@ -49,32 +59,54 @@ public class EliteGuardian extends EliteMonster{ m.setInvulnerable(true); List nearby = GenericFunctions.getNearbyPlayers(m.getLocation(), 4); if (nearby.size()>0) { - List nearby2 = GenericFunctions.getNearbyPlayers(m.getLocation(), 16); - //Play the cutscene for all of these players. - for (Player p : nearby2) { - p.setVelocity(new Vector(0,0,0)); - targetlist.add(p); - if (cutscenetimer==0) { - p.setGameMode(GameMode.SPECTATOR); - p.setSpectatorTarget(m); + boolean hasLineOfSight=false; + for (Player p : nearby) { + if (p.hasLineOfSight(m)) { + hasLineOfSight=true; + break; } } - if (cutscenetimer==0) { - GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.BLINDNESS, 40, 1, m); - } - cutscenetimer++; - if (cutscenetimer>20) { - state=STATE.PASSIVE; + if (hasLineOfSight) { + List nearby2 = GenericFunctions.getNearbyPlayers(m.getLocation(), 16); //Play the cutscene for all of these players. - for (Player p : targetlist) { - if (p!=null && p.isValid() && p.isOnline()) { - p.setGameMode(GameMode.SURVIVAL); + /*for (Player p : nearby2) { + p.setVelocity(new Vector(0,0,0)); + targetlist.add(p); + if (cutscenetimer==0) { + p.setGameMode(GameMode.SPECTATOR); + p.setSpectatorTarget(m); } } + if (cutscenetimer==0) { + GenericFunctions.logAndApplyPotionEffectToEntity(PotionEffectType.BLINDNESS, 40, 1, m); + }*/ + cam = new Camera(m.getLocation(),nearby2.toArray(new Player[nearby2.size()])); + targetlist.addAll(nearby2); + TwosideKeeper.cameras.add(cam); + cutscenetimer=0; + state = STATE.RUNNINGCUTSCENE; + TwosideKeeper.log("Monster Location: "+m.getLocation(),5); + cam.rotateAroundPointWithZoom(0.55, 350, m.getLocation(), 8, 0.04, 1, 4); + //cam.rotateAroundPoint(0.55, 200, m.getLocation(), 8, 4); + arena = new Arena(m.getWorld(), + m.getLocation().getBlockX()-10,m.getLocation().getBlockY()-2,m.getLocation().getBlockZ()-10, + 20,7,20, + Material.PRISMARINE); + arena.AddPlayers(nearby2.toArray(new Player[nearby2.size()])); + arena.AssembleArena(); + TwosideKeeper.arenas.add(arena); } } m.setAI(false); break; + case RUNNINGCUTSCENE: + cutscenetimer++; + if (cutscenetimer>60) { + state=STATE.PASSIVE; + cam.Cleanup(); + } + m.setAI(false); + break; default: break; } @@ -93,9 +125,31 @@ public class EliteGuardian extends EliteMonster{ public void runHitEvent(LivingEntity damager, double dmg) { super.runHitEvent(damager,dmg); } + + public void Cleanup() { + super.Cleanup(); + if (arena!=null) { + arena.DisassembleArena(); + TwosideKeeper.arenas.remove(arena); + } + } + + public void AnnounceFailedTakedown() { + super.AnnounceFailedTakedown(); + if (dpslist.size()>0 && !m.isDead()) { + if (arena!=null) { + arena.DisassembleArena(); + TwosideKeeper.arenas.remove(arena); + arena=null; + } + state=STATE.WAITINGFORCUTSCENE; + cutscenetimer=0; + } + } enum STATE { PASSIVE, //Just works like vanilla Minecraft behavior. WAITINGFORCUTSCENE, //A mode where the game is waiting for a cutscene to occur. The Elite Guardian does not move during this time. + RUNNINGCUTSCENE, } } diff --git a/src/sig/plugin/TwosideKeeper/EliteMonster.java b/src/sig/plugin/TwosideKeeper/EliteMonster.java index 528285c..fbc9c65 100644 --- a/src/sig/plugin/TwosideKeeper/EliteMonster.java +++ b/src/sig/plugin/TwosideKeeper/EliteMonster.java @@ -162,7 +162,7 @@ public class EliteMonster { } } - private void AnnounceFailedTakedown() { + public void AnnounceFailedTakedown() { if (dpslist.size()>0 && !m.isDead()) { Bukkit.getServer().broadcastMessage(GenericFunctions.getDisplayName(m)+" Takedown Failed..."); Bukkit.getServer().broadcastMessage(ChatColor.YELLOW+"DPS Breakdown:"); diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Common/Camera.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Common/Camera.java index 48b9d83..c4efc2a 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Common/Camera.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Common/Camera.java @@ -5,67 +5,154 @@ import java.util.List; import java.util.UUID; import org.bukkit.Bukkit; +import org.bukkit.Chunk; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; +import org.bukkit.util.Vector; import sig.plugin.TwosideKeeper.TwosideKeeper; +import sig.plugin.TwosideKeeper.HelperStructures.Utils.MovementUtils; public class Camera { - ArmorStand camera_ent; - HashMap camera_viewerlocs; + //ArmorStand camera_ent; + double degrees=0; + HashMap camera_viewerlocs = new HashMap(); + Chunk startingchunk; + Location startedat; public Camera(Location startingloc,Player...viewers) { - camera_ent = (ArmorStand)startingloc.getWorld().spawnEntity(startingloc, EntityType.ARMOR_STAND); - camera_ent.setGravity(false); - camera_ent.setVisible(false); - camera_ent.setInvulnerable(true); - camera_ent.setArms(false); + startingchunk = startingloc.getChunk(); + startedat=startingloc.clone(); + TwosideKeeper.temporary_chunks.add(startingchunk); + startingchunk.load(); for (Player p : viewers) { AddCameraViewer(p); } } + public boolean containsViewer(Player p) { + return (camera_viewerlocs.containsKey(p.getUniqueId())); + } public void AddCameraViewer(Player p) { - camera_viewerlocs.put(p.getUniqueId(), p.getLocation()); + camera_viewerlocs.put(p.getUniqueId(), p.getLocation().clone()); + //TwosideKeeper.log("Set starting loc of "+p.getName()+" to "+camera_viewerlocs.get(p.getUniqueId()), 1); p.setGameMode(GameMode.SPECTATOR); - p.setSpectatorTarget(camera_ent); + p.setSpectatorTarget(null); + } + public Location getStartingLoc(Player p) { + if (containsViewer(p)) { + return camera_viewerlocs.get(p.getUniqueId()); + } else { + return null; + } } public void removeCameraViewer(Player p) { if (camera_viewerlocs.containsKey(p.getUniqueId())) { + p.setSpectatorTarget(null); p.setGameMode(GameMode.SURVIVAL); p.teleport(camera_viewerlocs.get(p.getUniqueId())); + //TwosideKeeper.log("Teleporting player "+p.getName()+" to "+camera_viewerlocs.get(p.getUniqueId()), 1); camera_viewerlocs.remove(p.getUniqueId()); } } public boolean runTick() { - if (camera_ent==null || !camera_ent.isValid() || camera_viewerlocs.size()==0) { + if (camera_viewerlocs.size()==0) { return false; } for (UUID id : camera_viewerlocs.keySet()) { Player p = Bukkit.getPlayer(id); if (p!=null && p.isValid()) { p.setGameMode(GameMode.SPECTATOR); - if (p.getSpectatorTarget()==null || !(p.getSpectatorTarget() instanceof ArmorStand)) { - //If this player is on multiple cameras for some reason, we don't want to overwrite the previous camera. - p.setSpectatorTarget(camera_ent); - } + p.setFlying(true); + p.setSpectatorTarget(p); } else { TwosideKeeper.ScheduleRemoval(camera_viewerlocs, p); } + //TwosideKeeper.log("offset: "+camera_ent.getLocation().subtract(startedat)+" || Player offset: "+p.getLocation().subtract(startedat), 0); } return true; } - public ArmorStand getEnt() { - return camera_ent; - } public void Cleanup() { + Cleanup(false); + } + public void Cleanup(boolean isShuttingDown) { for (UUID id : camera_viewerlocs.keySet()) { Player p = Bukkit.getPlayer(id); if (p!=null && p.isValid()) { + p.setSpectatorTarget(null); p.setGameMode(GameMode.SURVIVAL); p.teleport(camera_viewerlocs.get(id)); + if (!isShuttingDown) { + TwosideKeeper.ScheduleRemoval(camera_viewerlocs, p); + } + } else { + if (!isShuttingDown) { + TwosideKeeper.ScheduleRemoval(camera_viewerlocs, p); + } + } + } + if (!isShuttingDown) { + TwosideKeeper.temporary_chunks.remove(startingchunk); + } + removeAllCameraViewers(); + } + + private void removeAllCameraViewers() { + camera_viewerlocs.clear(); + } + public void pointCameraToLocation(Location fromLoc, Location toLoc) { + //Points a camera to the target location. + if (fromLoc!=null && toLoc!=null && toLoc.getWorld().equals(fromLoc.getWorld())) { + Vector dir = MovementUtils.pointTowardsLocation(fromLoc, toLoc); + Location currloc = fromLoc.clone(); + currloc.setDirection(dir); + teleportViewers(currloc); + } + } + + private void teleportViewers(Location loc) { + for (UUID id : camera_viewerlocs.keySet()) { + Player p = Bukkit.getPlayer(id); + if (p!=null && p.isValid()) { + p.teleport(loc); } } } + public void setCameraAroundCircle(double radius, double degrees, Location loc, double yoffset) { + double velx = Math.cos(Math.toRadians(degrees)); + //double vely = Math.sin(Math.toRadians(degrees)); + double velz = Math.sin(Math.toRadians(degrees)); + Vector newvector = new Vector(-velx,0,-velz); + newvector.multiply(radius*2); + Location finalloc = loc.clone().add(newvector).add(0,yoffset,0); + //TwosideKeeper.log("offset: "+camera_ent.getLocation().subtract(startedat)+" -> "+finalloc.subtract(startedat),0); + //camera_ent.teleport(finalloc); + teleportViewers(finalloc); + pointCameraToLocation(finalloc,loc); + } + + public void rotateAroundPoint(double spd, int duration, Location loc, double radius, double yoffset) { + duration--; + setCameraAroundCircle(radius,degrees,loc,yoffset); + degrees+=spd; + if (duration>0) { + final int dur = duration; + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{rotateAroundPoint(spd,dur,loc,radius,yoffset);}, 1); + } + } + + public void rotateAroundPointWithZoom(double spd, int duration, Location loc, double startzoom, double zoomspd, double maxzoom, double yoffset) { + duration--; + setCameraAroundCircle(startzoom,degrees,loc,yoffset); + degrees+=spd; + startzoom = Math.max(maxzoom,startzoom-zoomspd); + yoffset = Math.min(yoffset,startzoom); + if (duration>0) { + final int dur = duration; + final double zoom = startzoom; + final double y = yoffset; + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{rotateAroundPointWithZoom(spd,dur,loc,zoom,zoomspd,maxzoom,y);}, 1); + } + } } diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/Classes/Box.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/Classes/Box.java new file mode 100644 index 0000000..e9b7a7e --- /dev/null +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/Classes/Box.java @@ -0,0 +1,34 @@ +package sig.plugin.TwosideKeeper.HelperStructures.Utils.Classes; + +public class Box { + int x,y,z,w,h,d; + public Box(int x, int y, int z, int w, int h, int d) { + this.x=x; + this.y=y; + this.z=z; + this.w=w; + this.h=h; + this.d=d; + } + public int getX() { + return x; + } + public int getY() { + return y; + } + public int getZ() { + return z; + } + public int getWidth() { + return w; + } + public int getHeight() { + return h; + } + public int getDepth() { + return d; + } + public Box clone() { + return new Box(x,y,z,w,h,d); + } +} diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/Classes/MaterialData.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/Classes/MaterialData.java new file mode 100644 index 0000000..bb8916e --- /dev/null +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/Classes/MaterialData.java @@ -0,0 +1,31 @@ +package sig.plugin.TwosideKeeper.HelperStructures.Utils.Classes; + +import org.bukkit.Material; + +public class MaterialData { + Material type; + Byte data; + + public MaterialData(Material type, Byte data) { + this.type=type; + this.data=data; + } + + public Material getType() { + return type; + } + + public void setType(Material type) { + this.type = type; + } + + public Byte getData() { + return data; + } + + public void setData(Byte data) { + this.data = data; + } + + +} diff --git a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/MovementUtils.java b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/MovementUtils.java index 047f29b..721d4fd 100644 --- a/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/MovementUtils.java +++ b/src/sig/plugin/TwosideKeeper/HelperStructures/Utils/MovementUtils.java @@ -17,11 +17,34 @@ public class MovementUtils { double c = currloc.getY()-targetloc.getY(); double b = currloc.getZ()-targetloc.getZ(); double angle = Math.atan2(b, a); - double angle2 = Math.atan2(c, a); + double angle2 = Math.atan2(c, Math.sqrt(Math.pow(a,2)+Math.pow(b, 2))); double velz = spd * Math.sin(angle); double velx = spd * Math.cos(angle); double vely = spd * Math.sin(angle2); //TwosideKeeper.log("New angle is "+angle, 0); return new Vector(-velx,-vely,-velz); } + /** + * Returns a vector pointing from the given location to the target location. + */ + public static Vector pointTowardsLocation(Location currloc, Location targetloc) { + /*double deltax = currloc.getX()-targetloc.getX(); + double deltay = currloc.getY()-targetloc.getY(); + double deltaz = currloc.getZ()-targetloc.getZ(); + //Move at max speed in each direction until it matches the delta. + double velx = Math.min(Math.abs(deltax), spd)*Math.signum(deltax); + double vely = Math.min(Math.abs(deltax), spd)*Math.signum(deltay); + double velz = Math.min(Math.abs(deltax), spd)*Math.signum(deltaz); + return new Vector(-velx,-vely,-velz); //Flip the sign so we're moving towards the point instead of away from it.*/ + double a = currloc.getX()-targetloc.getX(); + double c = currloc.getY()-targetloc.getY(); + double b = currloc.getZ()-targetloc.getZ(); + double angle = Math.atan2(b, a); + double angle2 = Math.atan2(c, Math.sqrt(Math.pow(a,2)+Math.pow(b, 2))); + double velz = Math.sin(angle); + double velx = Math.cos(angle); + double vely = Math.sin(angle2); + //TwosideKeeper.log("New angle is "+angle, 0); + return new Vector(-velx,-vely,-velz); + } } diff --git a/src/sig/plugin/TwosideKeeper/PlayerStructure.java b/src/sig/plugin/TwosideKeeper/PlayerStructure.java index e2b935b..f39a240 100644 --- a/src/sig/plugin/TwosideKeeper/PlayerStructure.java +++ b/src/sig/plugin/TwosideKeeper/PlayerStructure.java @@ -192,6 +192,7 @@ public class PlayerStructure { public boolean vacuumsuckup=true; public boolean equipweapons=true; public boolean equiparmor=true; + public Location restartLoc = null; //Set to a value when the player has to be re-teleported after being controlled by a camera. List equipmentset = new ArrayList(); @@ -289,6 +290,13 @@ public class PlayerStructure { } } + Bukkit.getScheduler().runTaskLater(TwosideKeeper.plugin, ()->{ + if (this.restartLoc!=null) { + p.teleport(this.restartLoc); + this.restartLoc=null; + } + }, 5); + //Joined always gets set to new time. this.joined = serverTickTime; setDefaultCooldowns(p); @@ -386,6 +394,14 @@ public class PlayerStructure { workable.set("COOLDOWN_lastmock", last_mock); workable.set("COOLDOWN_lastassassinatetime", lastassassinatetime); workable.set("COOLDOWN_lastlifesavertime", lastlifesavertime); + if (restartLoc!=null) { + workable.set("restartloc_x", restartLoc.getX()); + workable.set("restartloc_y", restartLoc.getY()); + workable.set("restartloc_z", restartLoc.getZ()); + workable.set("restartloc_world", restartLoc.getWorld().getName()); + } else { + workable.set("restartloc_world", "null"); + } try { workable.save(config); @@ -512,6 +528,10 @@ public class PlayerStructure { this.vacuumsuckup = workable.getBoolean("vacuumsuckup"); this.equipweapons = workable.getBoolean("equipweapons"); this.equiparmor = workable.getBoolean("equiparmor"); + String tempworld = workable.getString("restartloc_world"); + if (tempworld!=null && !tempworld.equalsIgnoreCase("null")) { + this.restartLoc = new Location(Bukkit.getWorld(tempworld),workable.getDouble("restartloc_x"),workable.getDouble("restartloc_y"),workable.getDouble("restartloc_z")); + } if (this.hasDied) { List deathlootlist = new ArrayList(); diff --git a/src/sig/plugin/TwosideKeeper/TwosideKeeper.java b/src/sig/plugin/TwosideKeeper/TwosideKeeper.java index 5f06e79..f1c12b1 100644 --- a/src/sig/plugin/TwosideKeeper/TwosideKeeper.java +++ b/src/sig/plugin/TwosideKeeper/TwosideKeeper.java @@ -193,6 +193,7 @@ import net.md_5.bungee.api.chat.TextComponent; import net.minecraft.server.v1_9_R1.EnumParticle; import net.minecraft.server.v1_9_R1.MinecraftServer; 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.PlayerDodgeEvent; @@ -471,6 +472,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { public static List blockqueue = new ArrayList(); public static List jobrecipes = new ArrayList(); public static List cameras = new ArrayList(); + public static List arenas = new ArrayList(); long LastClearStructureTime = 0; public static final Set isNatural = ImmutableSet.of(Material.CLAY, Material.DIRT, Material.GRASS, @@ -514,7 +516,7 @@ public class TwosideKeeper extends JavaPlugin implements Listener { public final static boolean CHRISTMASEVENT_ACTIVATED=false; public final static boolean CHRISTMASLINGERINGEVENT_ACTIVATED=false; //Limited Christmas drops/functionality remain while the majority of it is turned off. - public final static boolean ELITEGUARDIANS_ACTIVATED=false; + public final static boolean ELITEGUARDIANS_ACTIVATED=true; public static final Set LIVING_ENTITY_TYPES = ImmutableSet.of( EntityType.BAT,EntityType.BLAZE,EntityType.CAVE_SPIDER,EntityType.CHICKEN, @@ -1117,6 +1119,17 @@ public class TwosideKeeper extends JavaPlugin implements Listener { BlockModifyQueue.Cleanup(blockqueue); log(ChatColor.YELLOW+" "+(System.currentTimeMillis()-betweentime)+"ms",CLEANUP_DEBUG); betweentime = System.currentTimeMillis(); + log("Cleaning up Cameras ["+cameras.size()+"]",CLEANUP_DEBUG); + for (Camera cam : cameras) { + cam.Cleanup(true); + } + log(ChatColor.YELLOW+" "+(System.currentTimeMillis()-betweentime)+"ms",CLEANUP_DEBUG); + betweentime = System.currentTimeMillis(); + log("Cleaning up Arenas ["+arenas.size()+"]",CLEANUP_DEBUG); + for (Arena arena : arenas) { + arena.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); } @@ -1386,7 +1399,8 @@ public class TwosideKeeper extends JavaPlugin implements Listener { w.setHealth(10); }break; case "ELITE":{ - LivingEntity m = MonsterController.convertLivingEntity((LivingEntity)p.getWorld().spawnEntity(p.getLocation(),EntityType.ZOMBIE), LivingEntityDifficulty.ELITE); + Guardian m = (Guardian)MonsterController.convertLivingEntity((LivingEntity)p.getWorld().spawnEntity(p.getLocation(),EntityType.GUARDIAN), LivingEntityDifficulty.ELITE); + m.setElder(true); }break; case "VACUUM":{ ItemStack[] remaining = InventoryUtils.insertItemsInVacuumCube(p, new ItemStack(Material.ENDER_PEARL,16), new ItemStack(Material.IRON_PICKAXE,1), new ItemStack(Material.GOLDEN_APPLE,64)); @@ -1691,7 +1705,26 @@ public class TwosideKeeper extends JavaPlugin implements Listener { }break; case "SETTIER":{ ItemUtils.ModifyLoreLineContainingSubstring(p.getEquipment().getItemInMainHand(), ChatColor.GOLD+""+ChatColor.BOLD+"T", ChatColor.GOLD+""+ChatColor.BOLD+"T"+Integer.parseInt(args[1])+" Artifact"); - } + }break; + case "TESTCAMERA":{ + if (args.length==1) { + Camera c = new Camera(new Location(Bukkit.getWorld("world"),0,100,0),p); + TwosideKeeper.cameras.add(c); + //c.rotateAroundPoint(1, 400, new Location(Bukkit.getWorld("world"),0,100,0), 20, 5); + c.rotateAroundPointWithZoom(1, 400, new Location(Bukkit.getWorld("world"),-10,100,0), 20, 0.06, 1, 5); + } else + if (args.length==4) { + //TwosideKeeper.cameras.add(new Camera(p.getLocation(),p)); + Camera c = TwosideKeeper.cameras.get(0); + c.pointCameraToLocation(new Location(Bukkit.getWorld("world"),0,100,0),p.getLocation().add(Integer.parseInt(args[1]),Integer.parseInt(args[2]),Integer.parseInt(args[3]))); + } else + if (args.length==3) { + //TwosideKeeper.cameras.add(new Camera(p.getLocation(),p)); + Camera c = TwosideKeeper.cameras.get(0); + //c.pointCameraToLocation(p.getLocation().add(Integer.parseInt(args[1]),Integer.parseInt(args[2]),Integer.parseInt(args[3]))); + c.setCameraAroundCircle(Double.parseDouble(args[1]), Double.parseDouble(args[2]), new Location(Bukkit.getWorld("world"),0,64,0), 5); + } + }break; } } //LivingEntity m = MonsterController.convertMonster((Monster)p.getWorld().spawnEntity(p.getLocation(),EntityType.ZOMBIE), MonsterDifficulty.ELITE); @@ -2463,15 +2496,20 @@ public class TwosideKeeper extends JavaPlugin implements Listener { public void onPlayerLeave(PlayerQuitEvent ev) { Player p = ev.getPlayer(); - if (p.getGameMode()==GameMode.SPECTATOR) { - p.setGameMode(GameMode.SURVIVAL); - } TwosideSpleefGames.PassEvent(ev); for (EliteMonster em : elitemonsters) { em.runPlayerLeaveEvent(ev.getPlayer()); } + for (Camera c : cameras) { + if (c.containsViewer(p)) { + PlayerStructure pd = PlayerStructure.GetPlayerStructure(p); + pd.restartLoc = c.getStartingLoc(p); + c.removeCameraViewer(p); + } + } + for (UUID id : livingentitydata.keySet()) { LivingEntityStructure les = LivingEntityStructure.getLivingEntityStructure(livingentitydata.get(id).m); les.setGlow(ev.getPlayer(), null);