From 185ac9fc05b3b1d06d38950cf12786b54c43cc23 Mon Sep 17 00:00:00 2001 From: cnr Date: Sun, 18 Jun 2017 11:23:16 -0500 Subject: [PATCH 1/3] Allow youtubers into full clans servers --- .../src/mineplex/game/clans/clans/ClansManager.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java index 1794c63e5..fc98e0c23 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java @@ -1273,10 +1273,9 @@ public class ClansManager extends MiniClientPluginimplements IRelati online++; } - if (online >= UtilServer.getServer().getMaxPlayers() && !rank.has(Rank.ADMIN) && !event.getPlayer().isWhitelisted() && !event.getPlayer().isOp()) + if (online >= UtilServer.getServer().getMaxPlayers() && !rank.has(Rank.ADMIN) && rank != Rank.YOUTUBE && rank != Rank.YOUTUBE_SMALL && !event.getPlayer().isWhitelisted() && !event.getPlayer().isOp()) { event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "This Clans server is full! Try again soon"); - event.setKickMessage("This Clans server is full! Try again soon"); } else { From 7868287ace86498936501ed94d3c3b807d5277f4 Mon Sep 17 00:00:00 2001 From: AlexTheCoder Date: Mon, 19 Jun 2017 18:53:34 -0400 Subject: [PATCH 2/3] Temporarily disable clans maps --- .../mineplex/game/clans/clans/ClansGame.java | 2 +- .../game/clans/clans/ClansManager.java | 14 +++++------ .../clans/clans/commands/ClansCommand.java | 24 +++++++++---------- .../game/clans/clans/commands/MapCommand.java | 2 +- .../clans/clans/nether/NetherManager.java | 14 +++++------ .../clans/worldevent/raid/RaidManager.java | 22 ++++++++--------- .../tutorials/clans/ClansMainTutorial.java | 2 +- 7 files changed, 40 insertions(+), 40 deletions(-) diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansGame.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansGame.java index e9116153c..15b9df83f 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansGame.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansGame.java @@ -377,7 +377,7 @@ public class ClansGame extends MiniPlugin @EventHandler public void respawn(PlayerRespawnEvent event) { - _clans.getItemMapManager().setMap(event.getPlayer()); + //_clans.getItemMapManager().setMap(event.getPlayer()); } @EventHandler(priority = EventPriority.LOW) diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java index fc98e0c23..8d872a932 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java @@ -221,7 +221,7 @@ public class ClansManager extends MiniClientPluginimplements IRelati private ProjectileManager _projectileManager; private WorldEventManager _worldEvent; private Chat _chat; - private ItemMapManager _itemMapManager; +// private ItemMapManager _itemMapManager; private DisguiseManager _disguiseManager; private NpcManager _npcManager; private Explosion _explosion; @@ -305,7 +305,7 @@ public class ClansManager extends MiniClientPluginimplements IRelati _clanGame = new ClansGame(plugin, this); _clanUtility = new ClansUtility(this); _tutorial = new TutorialManager(plugin, clientManager, donationManager, chat, hologramManager, this, _npcManager, _taskManager); - _itemMapManager = new ItemMapManager(this, _tutorial, _worldEvent); +// _itemMapManager = new ItemMapManager(this, _tutorial, _worldEvent); new TntGeneratorManager(plugin, this); new SupplyDropManager(plugin, this); @@ -492,7 +492,7 @@ public class ClansManager extends MiniClientPluginimplements IRelati addCommand(new ClansChatCommand(this)); addCommand(new ClansAllyChatCommand(this)); addCommand(new ClanManagementCommand(this)); - addCommand(new MapCommand(this)); +// addCommand(new MapCommand(this)); addCommand(new SpeedCommand(this)); } @@ -563,10 +563,10 @@ public class ClansManager extends MiniClientPluginimplements IRelati return _inventoryManager; } - public ItemMapManager getItemMapManager() - { - return _itemMapManager; - } +// public ItemMapManager getItemMapManager() +// { +// return _itemMapManager; +// } public Explosion getExplosion() { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java index e3c90587a..aaa084382 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java @@ -987,18 +987,18 @@ public class ClansCommand extends CommandBase Plugin.getClanUtility().unclaimAll(caller); } - public void map(Player caller, String[] args) - { - ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "map"); - UtilServer.getServer().getPluginManager().callEvent(event); - - if (event.isCancelled()) - { - return; - } - - Plugin.getItemMapManager().setMap(caller); - } +// public void map(Player caller, String[] args) +// { +// ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "map"); +// UtilServer.getServer().getPluginManager().callEvent(event); +// +// if (event.isCancelled()) +// { +// return; +// } +// +// Plugin.getItemMapManager().setMap(caller); +// } public void home(final Player caller, String[] args) { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/MapCommand.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/MapCommand.java index ed8b9a0e7..e9d8b13ba 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/MapCommand.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/MapCommand.java @@ -33,6 +33,6 @@ public class MapCommand extends CommandBase @Override public void Execute(Player caller, String[] args) { - Plugin.getItemMapManager().setMap(caller); + //Plugin.getItemMapManager().setMap(caller); } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java index bca2c1acc..fdbe13146 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/nether/NetherManager.java @@ -469,13 +469,13 @@ public class NetherManager extends MiniPlugin } } - UtilServer.getPlayersCollection() - .stream() - .filter(player -> isInNether(player)) - .forEach(player -> - { - ClansManager.getInstance().getItemMapManager().removeMap(player); - }); +// UtilServer.getPlayersCollection() +// .stream() +// .filter(player -> isInNether(player)) +// .forEach(player -> +// { +// ClansManager.getInstance().getItemMapManager().removeMap(player); +// }); } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidManager.java index 06e29d9de..f4363b0f5 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/worldevent/raid/RaidManager.java @@ -157,17 +157,17 @@ public class RaidManager extends MiniPlugin @EventHandler public void update(UpdateEvent event) { - if (event.getType() == UpdateType.TICK) - { - UtilServer.getPlayersCollection() - .stream() - .filter(player -> isInRaid(player.getLocation())) - .forEach(player -> - { - ClansManager.getInstance().getItemMapManager().removeMap(player); - }); - return; - } +// if (event.getType() == UpdateType.TICK) +// { +// UtilServer.getPlayersCollection() +// .stream() +// .filter(player -> isInRaid(player.getLocation())) +// .forEach(player -> +// { +// ClansManager.getInstance().getItemMapManager().removeMap(player); +// }); +// return; +// } if (event.getType() != UpdateType.SEC) { return; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/ClansMainTutorial.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/ClansMainTutorial.java index 558ac863d..e75da28b3 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/ClansMainTutorial.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/tutorials/clans/ClansMainTutorial.java @@ -128,7 +128,7 @@ public class ClansMainTutorial extends Tutorial player.teleport(Spawn.getNorthSpawn()); UtilInv.Clear(player); - ClansManager.getInstance().getItemMapManager().setMap(player); +// ClansManager.getInstance().getItemMapManager().setMap(player); }, 20 * 10L); player.setWalkSpeed(0.2F); From 31605b02b09cc190f73c7825e158e77c7c6f4d9e Mon Sep 17 00:00:00 2001 From: cnr Date: Mon, 19 Jun 2017 18:26:03 -0500 Subject: [PATCH 3/3] Use polygon geometry for MOBA Boss AI boundaries --- .../mineplex/core/common/geom/Point2D.java | 79 +++++++++++++++++ .../mineplex/core/common/geom/Polygon2D.java | 68 ++++++++++++++ .../arcade/game/games/moba/ai/MobaAI.java | 26 ++++-- .../arcade/game/games/moba/util/MobaUtil.java | 88 ++++++++----------- 4 files changed, 201 insertions(+), 60 deletions(-) create mode 100644 Plugins/Mineplex.Core.Common/src/mineplex/core/common/geom/Point2D.java create mode 100644 Plugins/Mineplex.Core.Common/src/mineplex/core/common/geom/Polygon2D.java diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/geom/Point2D.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/geom/Point2D.java new file mode 100644 index 000000000..07bdad517 --- /dev/null +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/geom/Point2D.java @@ -0,0 +1,79 @@ +package mineplex.core.common.geom; + +import javax.annotation.Nonnull; +import java.util.Comparator; + +import org.bukkit.Location; + +public class Point2D implements Comparable +{ + private static final Comparator COMPARE_BY_Y_THEN_X = + Comparator.comparingDouble(Point2D::getY).thenComparingDouble(Point2D::getX); + private final double _x; + private final double _y; + + private Point2D(double x, double y) + { + _x = x; + _y = y; + } + + public static Point2D of(double x, double y) + { + return new Point2D(x, y); + } + + public static Point2D of(Location location) + { + return new Point2D(location.getX(), location.getZ()); + } + + public double getX() + { + return _x; + } + + public double getY() + { + return _y; + } + + public Comparator polarOrder() + { + return (p2, p3) -> + { + double dx1 = p2._x - _x; + double dy1 = p2._y - _y; + double dx2 = p3._x - _x; + double dy2 = p3._y - _y; + + if (dy1 >= 0 && dy2 < 0) return -1; // p2 above; p3 below + else if (dy2 >= 0 && dy1 < 0) return 1; // p2 below; p3 above + else if (dy1 == 0 && dy2 == 0) { // 3-collinear and horizontal + if (dx1 >= 0 && dx2 < 0) return -1; // p2 right; p3 left + else if (dx2 >= 0 && dx1 < 0) return 1; // p2 left ; p3 right + else return 0; // all the same point + } + else return -ccw(Point2D.this, p2, p3); // both above or below + }; + } + + public static int ccw(Point2D a, Point2D b, Point2D c) { + double area2 = (b._x-a._x)*(c._y-a._y) - (b._y-a._y)*(c._x-a._x); + if (area2 < 0) return -1; + else if (area2 > 0) return 1; + else return 0; + } + + @Override + public int compareTo(@Nonnull Point2D that) + { + return COMPARE_BY_Y_THEN_X.compare(this, that); + } + + @Override + public String toString() + { + return "Point2D{_x=" + _x + ",_y=" + _y + "}"; + } +} diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/geom/Polygon2D.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/geom/Polygon2D.java new file mode 100644 index 000000000..73a834d45 --- /dev/null +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/geom/Polygon2D.java @@ -0,0 +1,68 @@ +package mineplex.core.common.geom; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Stack; + +public class Polygon2D +{ + private final List _points; + + private Polygon2D(List points) + { + _points = points; + // Ensure points[points.size-1] = points[0] + if (!_points.get(0).equals(points.get(_points.size()-1))) + { + _points.add(points.get(0)); + } + } + + public boolean contains(Point2D point) + { + boolean result = false; + for (int i = 0, j = _points.size() - 1; i < _points.size(); j = i++) + { + if ((_points.get(i).getY() > point.getY()) != (_points.get(j).getY() > point.getY()) && + (point.getX() < (_points.get(j).getX() - _points.get(i).getX()) * (point.getY() - _points.get(i).getY()) / (_points.get(j).getY() - _points.get(i).getY()) + _points.get(i).getX())) + { + result = !result; + } + } + return result; + } + + public static Polygon2D fromUnorderedPoints(List points) + { + Stack hull = new Stack<>(); + + Collections.sort(points); + points.subList(1, points.size()).sort(points.get(0).polarOrder()); + + hull.push(points.get(0)); + hull.push(points.get(1)); + + // find first extreme point (not collinear with first and second elements) + int extreme; + for (extreme = 2; extreme < points.size(); extreme++) + if (Point2D.ccw(points.get(0), points.get(1), points.get(extreme)) != 0) break; + + for (int i = extreme; i < points.size(); i++) + { + Point2D top = hull.pop(); + while (Point2D.ccw(hull.peek(), top, points.get(i)) <= 0) { + top = hull.pop(); + } + hull.push(top); + hull.push(points.get(i)); + } + + return new Polygon2D(new ArrayList<>(hull)); + } + + public static Polygon2D fromPoints(List points) + { + return new Polygon2D(new ArrayList<>(points)); + } +} diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/ai/MobaAI.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/ai/MobaAI.java index 15f4e9e49..5b89b9884 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/ai/MobaAI.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/ai/MobaAI.java @@ -1,14 +1,19 @@ package nautilus.game.arcade.game.games.moba.ai; +import java.util.List; +import java.util.stream.Collectors; + +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; + +import mineplex.core.common.geom.Point2D; +import mineplex.core.common.geom.Polygon2D; + import nautilus.game.arcade.game.GameTeam; import nautilus.game.arcade.game.games.moba.Moba; import nautilus.game.arcade.game.games.moba.ai.goal.MobaAIMethod; import nautilus.game.arcade.game.games.moba.util.MobaUtil; -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.entity.LivingEntity; - -import java.util.List; public class MobaAI { @@ -16,7 +21,7 @@ public class MobaAI private final GameTeam _owner; private final float _speedTarget; private final float _speedHome; - private final List _boundaries; + private final Polygon2D _boundaries; private LivingEntity _entity; private LivingEntity _target; @@ -32,7 +37,12 @@ public class MobaAI _entity = entity; _home = home; _aiMethod = aiMethod; - _boundaries = host.WorldData.GetDataLocs(getBoundaryKey()); + + List boundaryPoints = host.WorldData.GetDataLocs(getBoundaryKey()).stream() + .map(Point2D::of) + .collect(Collectors.toList()); + + _boundaries = Polygon2D.fromUnorderedPoints(boundaryPoints); } public void updateTarget() @@ -80,7 +90,7 @@ public class MobaAI return _target; } - public List getBoundaries() + public Polygon2D getBoundaries() { return _boundaries; } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/util/MobaUtil.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/util/MobaUtil.java index ac09e9aac..54bf4ee50 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/util/MobaUtil.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/util/MobaUtil.java @@ -1,28 +1,32 @@ package nautilus.game.arcade.game.games.moba.util; -import mineplex.core.common.util.C; -import mineplex.core.common.util.UtilAlg; -import mineplex.core.common.util.UtilEnt; -import mineplex.core.common.util.UtilMath; -import mineplex.core.common.util.UtilServer; -import nautilus.game.arcade.game.GameTeam; -import nautilus.game.arcade.game.games.moba.Moba; -import nautilus.game.arcade.game.games.moba.kit.hp.MobaHPRegenEvent; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.metadata.FixedMetadataValue; -import org.bukkit.util.Vector; - import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map.Entry; import java.util.Set; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.metadata.FixedMetadataValue; + +import mineplex.core.common.geom.Point2D; +import mineplex.core.common.geom.Polygon2D; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilEnt; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; + +import nautilus.game.arcade.game.GameTeam; +import nautilus.game.arcade.game.games.moba.Moba; +import nautilus.game.arcade.game.games.moba.kit.hp.MobaHPRegenEvent; + public class MobaUtil { @@ -66,12 +70,12 @@ public class MobaUtil return highest; } - public static boolean isInBoundary(GameTeam owner, LivingEntity source, Location center, List boundaries, LivingEntity target) + public static boolean isInBoundary(GameTeam owner, LivingEntity source, Location center, Polygon2D boundaries, LivingEntity target) { return getEntitiesInBoundary(owner, source, center, boundaries).contains(target); } - public static LivingEntity getBestEntityTarget(GameTeam owner, LivingEntity source, Location center, List boundaries) + public static LivingEntity getBestEntityTarget(GameTeam owner, LivingEntity source, Location center, Polygon2D boundaries) { LivingEntity best = null; double bestDist = Double.MAX_VALUE; @@ -90,9 +94,8 @@ public class MobaUtil return best; } - public static Set getEntitiesInBoundary(GameTeam owner, LivingEntity source, Location center, List boundaries) + public static Set getEntitiesInBoundary(GameTeam owner, LivingEntity source, Location center, Polygon2D boundaries) { - Set entities = new HashSet<>(); List ignored = new ArrayList<>(); if (owner != null) @@ -101,45 +104,26 @@ public class MobaUtil ignored.addAll(owner.GetPlayers(true)); } - // For each boundary - for (Location boundary : boundaries) + Set result = new HashSet<>(); + + for (Entity cur : center.getWorld().getEntities()) // TODO: narrow down to specific chunks contained in the polygon? { - Location checking = center.clone(); - // Get direction from center to boundary - Vector direction = UtilAlg.getTrajectory(center, boundary); - // Store the checked distance - double checkedDist = 0; - // Get the distance squared from the center to the boundary - double maxDist = UtilMath.offsetSquared(center, boundary); + if (!(cur instanceof LivingEntity) || UtilPlayer.isSpectator(cur)) + continue; - // Keep advancing the distance until it hits the boundary - while (checkedDist * checkedDist < maxDist) + LivingEntity ent = (LivingEntity)cur; + + if (boundaries.contains(Point2D.of(ent.getLocation()))) { - // Advance the location - checking.add(direction); - - // Check for nearby entities - for (LivingEntity entity : UtilEnt.getInRadius(checking, 3).keySet()) + if ((owner != null && isTeamEntity(ent, owner)) || source.equals(ent) || ignored.contains(ent)) { - if (source.equals(entity) || ignored.contains(entity)) - { - continue; - } - - // Check for team entities - if (owner != null && isTeamEntity(entity, owner)) - { - continue; - } - - entities.add(entity); + continue; } - - checkedDist++; + result.add(ent); } } - return entities; + return result; } public static String getHealthBar(LivingEntity entity, int bars)