Merge remote-tracking branch 'refs/remotes/origin/develop' into feature/moba

This commit is contained in:
Sam 2017-06-21 13:57:12 +01:00
commit 0fe2c52500
11 changed files with 242 additions and 102 deletions

View File

@ -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<Point2D>
{
private static final Comparator<Point2D> 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<Point2D> 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 + "}";
}
}

View File

@ -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<Point2D> _points;
private Polygon2D(List<Point2D> 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<Point2D> points)
{
Stack<Point2D> 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<Point2D> points)
{
return new Polygon2D(new ArrayList<>(points));
}
}

View File

@ -377,7 +377,7 @@ public class ClansGame extends MiniPlugin
@EventHandler @EventHandler
public void respawn(PlayerRespawnEvent event) public void respawn(PlayerRespawnEvent event)
{ {
_clans.getItemMapManager().setMap(event.getPlayer()); //_clans.getItemMapManager().setMap(event.getPlayer());
} }
@EventHandler(priority = EventPriority.LOW) @EventHandler(priority = EventPriority.LOW)

View File

@ -221,7 +221,7 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
private ProjectileManager _projectileManager; private ProjectileManager _projectileManager;
private WorldEventManager _worldEvent; private WorldEventManager _worldEvent;
private Chat _chat; private Chat _chat;
private ItemMapManager _itemMapManager; // private ItemMapManager _itemMapManager;
private DisguiseManager _disguiseManager; private DisguiseManager _disguiseManager;
private NpcManager _npcManager; private NpcManager _npcManager;
private Explosion _explosion; private Explosion _explosion;
@ -305,7 +305,7 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
_clanGame = new ClansGame(plugin, this); _clanGame = new ClansGame(plugin, this);
_clanUtility = new ClansUtility(this); _clanUtility = new ClansUtility(this);
_tutorial = new TutorialManager(plugin, clientManager, donationManager, chat, hologramManager, this, _npcManager, _taskManager); _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 TntGeneratorManager(plugin, this);
new SupplyDropManager(plugin, this); new SupplyDropManager(plugin, this);
@ -492,7 +492,7 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
addCommand(new ClansChatCommand(this)); addCommand(new ClansChatCommand(this));
addCommand(new ClansAllyChatCommand(this)); addCommand(new ClansAllyChatCommand(this));
addCommand(new ClanManagementCommand(this)); addCommand(new ClanManagementCommand(this));
addCommand(new MapCommand(this)); // addCommand(new MapCommand(this));
addCommand(new SpeedCommand(this)); addCommand(new SpeedCommand(this));
} }
@ -563,10 +563,10 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
return _inventoryManager; return _inventoryManager;
} }
public ItemMapManager getItemMapManager() // public ItemMapManager getItemMapManager()
{ // {
return _itemMapManager; // return _itemMapManager;
} // }
public Explosion getExplosion() public Explosion getExplosion()
{ {
@ -1273,10 +1273,9 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
online++; 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.disallow(PlayerLoginEvent.Result.KICK_OTHER, "This Clans server is full! Try again soon");
event.setKickMessage("This Clans server is full! Try again soon");
} }
else else
{ {

View File

@ -987,18 +987,18 @@ public class ClansCommand extends CommandBase<ClansManager>
Plugin.getClanUtility().unclaimAll(caller); Plugin.getClanUtility().unclaimAll(caller);
} }
public void map(Player caller, String[] args) // public void map(Player caller, String[] args)
{ // {
ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "map"); // ClansCommandExecutedEvent event = new ClansCommandExecutedEvent(caller, "map");
UtilServer.getServer().getPluginManager().callEvent(event); // UtilServer.getServer().getPluginManager().callEvent(event);
//
if (event.isCancelled()) // if (event.isCancelled())
{ // {
return; // return;
} // }
//
Plugin.getItemMapManager().setMap(caller); // Plugin.getItemMapManager().setMap(caller);
} // }
public void home(final Player caller, String[] args) public void home(final Player caller, String[] args)
{ {

View File

@ -33,6 +33,6 @@ public class MapCommand extends CommandBase<ClansManager>
@Override @Override
public void Execute(Player caller, String[] args) public void Execute(Player caller, String[] args)
{ {
Plugin.getItemMapManager().setMap(caller); //Plugin.getItemMapManager().setMap(caller);
} }
} }

View File

@ -469,13 +469,13 @@ public class NetherManager extends MiniPlugin
} }
} }
UtilServer.getPlayersCollection() // UtilServer.getPlayersCollection()
.stream() // .stream()
.filter(player -> isInNether(player)) // .filter(player -> isInNether(player))
.forEach(player -> // .forEach(player ->
{ // {
ClansManager.getInstance().getItemMapManager().removeMap(player); // ClansManager.getInstance().getItemMapManager().removeMap(player);
}); // });
} }
} }

View File

@ -157,17 +157,17 @@ public class RaidManager extends MiniPlugin
@EventHandler @EventHandler
public void update(UpdateEvent event) public void update(UpdateEvent event)
{ {
if (event.getType() == UpdateType.TICK) // if (event.getType() == UpdateType.TICK)
{ // {
UtilServer.getPlayersCollection() // UtilServer.getPlayersCollection()
.stream() // .stream()
.filter(player -> isInRaid(player.getLocation())) // .filter(player -> isInRaid(player.getLocation()))
.forEach(player -> // .forEach(player ->
{ // {
ClansManager.getInstance().getItemMapManager().removeMap(player); // ClansManager.getInstance().getItemMapManager().removeMap(player);
}); // });
return; // return;
} // }
if (event.getType() != UpdateType.SEC) if (event.getType() != UpdateType.SEC)
{ {
return; return;

View File

@ -128,7 +128,7 @@ public class ClansMainTutorial extends Tutorial
player.teleport(Spawn.getNorthSpawn()); player.teleport(Spawn.getNorthSpawn());
UtilInv.Clear(player); UtilInv.Clear(player);
ClansManager.getInstance().getItemMapManager().setMap(player); // ClansManager.getInstance().getItemMapManager().setMap(player);
}, 20 * 10L); }, 20 * 10L);
player.setWalkSpeed(0.2F); player.setWalkSpeed(0.2F);

View File

@ -1,14 +1,19 @@
package nautilus.game.arcade.game.games.moba.ai; 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.GameTeam;
import nautilus.game.arcade.game.games.moba.Moba; 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.ai.goal.MobaAIMethod;
import nautilus.game.arcade.game.games.moba.util.MobaUtil; 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 public class MobaAI
{ {
@ -16,7 +21,7 @@ public class MobaAI
private final GameTeam _owner; private final GameTeam _owner;
private final float _speedTarget; private final float _speedTarget;
private final float _speedHome; private final float _speedHome;
private final List<Location> _boundaries; private final Polygon2D _boundaries;
private LivingEntity _entity; private LivingEntity _entity;
private LivingEntity _target; private LivingEntity _target;
@ -32,7 +37,12 @@ public class MobaAI
_entity = entity; _entity = entity;
_home = home; _home = home;
_aiMethod = aiMethod; _aiMethod = aiMethod;
_boundaries = host.WorldData.GetDataLocs(getBoundaryKey());
List<Point2D> boundaryPoints = host.WorldData.GetDataLocs(getBoundaryKey()).stream()
.map(Point2D::of)
.collect(Collectors.toList());
_boundaries = Polygon2D.fromUnorderedPoints(boundaryPoints);
} }
public void updateTarget() public void updateTarget()
@ -80,7 +90,7 @@ public class MobaAI
return _target; return _target;
} }
public List<Location> getBoundaries() public Polygon2D getBoundaries()
{ {
return _boundaries; return _boundaries;
} }

View File

@ -1,28 +1,32 @@
package nautilus.game.arcade.game.games.moba.util; 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.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; 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 public class MobaUtil
{ {
@ -66,12 +70,12 @@ public class MobaUtil
return highest; return highest;
} }
public static boolean isInBoundary(GameTeam owner, LivingEntity source, Location center, List<Location> 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); return getEntitiesInBoundary(owner, source, center, boundaries).contains(target);
} }
public static LivingEntity getBestEntityTarget(GameTeam owner, LivingEntity source, Location center, List<Location> boundaries) public static LivingEntity getBestEntityTarget(GameTeam owner, LivingEntity source, Location center, Polygon2D boundaries)
{ {
LivingEntity best = null; LivingEntity best = null;
double bestDist = Double.MAX_VALUE; double bestDist = Double.MAX_VALUE;
@ -90,9 +94,8 @@ public class MobaUtil
return best; return best;
} }
public static Set<LivingEntity> getEntitiesInBoundary(GameTeam owner, LivingEntity source, Location center, List<Location> boundaries) public static Set<LivingEntity> getEntitiesInBoundary(GameTeam owner, LivingEntity source, Location center, Polygon2D boundaries)
{ {
Set<LivingEntity> entities = new HashSet<>();
List<Player> ignored = new ArrayList<>(); List<Player> ignored = new ArrayList<>();
if (owner != null) if (owner != null)
@ -101,45 +104,26 @@ public class MobaUtil
ignored.addAll(owner.GetPlayers(true)); ignored.addAll(owner.GetPlayers(true));
} }
// For each boundary Set<LivingEntity> result = new HashSet<>();
for (Location boundary : boundaries)
{
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);
// Keep advancing the distance until it hits the boundary for (Entity cur : center.getWorld().getEntities()) // TODO: narrow down to specific chunks contained in the polygon?
while (checkedDist * checkedDist < maxDist)
{ {
// Advance the location if (!(cur instanceof LivingEntity) || UtilPlayer.isSpectator(cur))
checking.add(direction); continue;
// Check for nearby entities LivingEntity ent = (LivingEntity)cur;
for (LivingEntity entity : UtilEnt.getInRadius(checking, 3).keySet())
if (boundaries.contains(Point2D.of(ent.getLocation())))
{ {
if (source.equals(entity) || ignored.contains(entity)) if ((owner != null && isTeamEntity(ent, owner)) || source.equals(ent) || ignored.contains(ent))
{ {
continue; continue;
} }
result.add(ent);
// Check for team entities
if (owner != null && isTeamEntity(entity, owner))
{
continue;
}
entities.add(entity);
}
checkedDist++;
} }
} }
return entities; return result;
} }
public static String getHealthBar(LivingEntity entity, int bars) public static String getHealthBar(LivingEntity entity, int bars)