Compare commits
10 Commits
v0.2.99-rc
...
feautre/pl
Author | SHA1 | Date | |
---|---|---|---|
669fab22cd | |||
221539001e | |||
61d0af1a05 | |||
75087b23e1 | |||
8af0909110 | |||
9944a7bcdb | |||
e21115cc65 | |||
51fdc80542 | |||
ff70dd255b | |||
b5a28e40cf |
11
pom.xml
11
pom.xml
@ -4,7 +4,7 @@
|
||||
<groupId>us.camin.regions</groupId>
|
||||
<artifactId>Regions</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<version>0.2.99-rc6</version>
|
||||
<version>0.3.1</version>
|
||||
<name>regions</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
<properties>
|
||||
@ -20,7 +20,7 @@
|
||||
<dependency>
|
||||
<groupId>com.comphenix.protocol</groupId>
|
||||
<artifactId>ProtocolLib</artifactId>
|
||||
<version>4.6.0</version>
|
||||
<version>4.7.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -51,12 +51,6 @@
|
||||
<artifactId>commons-codec</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.10</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<extensions>
|
||||
@ -177,6 +171,7 @@
|
||||
<id>papermc</id>
|
||||
<url>http://papermc.io/repo/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository><id>pl3x-repo</id><url>http://repo.pl3x.net/</url></repository>
|
||||
<repository><id>dynmap-repo</id><url>http://repo.mikeprimm.com/</url></repository>
|
||||
<repository><id>imagej</id><url>http://maven.imagej.net/content/repositories/public/</url></repository>
|
||||
</repositories>
|
||||
|
@ -71,7 +71,7 @@ public class DynmapEventRelay implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
public void updatePolygons(World world) {
|
||||
private void updatePolygons(World world) {
|
||||
List<GenericMarker> oldMarkers = m_borderMarkers.get(world);
|
||||
if (oldMarkers != null) {
|
||||
for(GenericMarker marker : oldMarkers) {
|
||||
|
@ -34,6 +34,7 @@ import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.TitleAction;
|
||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||
import com.comphenix.protocol.utility.MinecraftProtocolVersion;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ -49,9 +50,64 @@ public class PlayerNotifier implements Listener {
|
||||
Logger log = Logger.getLogger("Regions.PlayerNotifier");
|
||||
RegionManager m_manager;
|
||||
Plugin m_plugin;
|
||||
ProtocolManager m_protocolManager;
|
||||
int m_protoVersion = 0;
|
||||
|
||||
public PlayerNotifier(Plugin plugin, RegionManager manager) {
|
||||
m_manager = manager;
|
||||
m_plugin = plugin;
|
||||
m_protocolManager = ProtocolLibrary.getProtocolManager();
|
||||
|
||||
if (m_protocolManager != null) {
|
||||
m_protoVersion = MinecraftProtocolVersion.getCurrentVersion();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendTitle(Player player, WrappedChatComponent title, WrappedChatComponent subtitle) {
|
||||
// Title packet format changed in 1.17
|
||||
if (m_protoVersion < 755) {
|
||||
PacketContainer setTitle = m_protocolManager.createPacket(PacketType.Play.Server.TITLE);
|
||||
setTitle.getChatComponents().write(0, title);
|
||||
PacketContainer setSubtitle = m_protocolManager.createPacket(PacketType.Play.Server.TITLE);
|
||||
setSubtitle.getChatComponents().write(0, subtitle);
|
||||
setSubtitle.getTitleActions().write(0, TitleAction.SUBTITLE);
|
||||
try {
|
||||
m_protocolManager.sendServerPacket(player, setTitle);
|
||||
m_protocolManager.sendServerPacket(player, setSubtitle);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
} else {
|
||||
PacketContainer setTitle = m_protocolManager.createPacket(PacketType.Play.Server.SET_TITLE_TEXT);
|
||||
setTitle.getChatComponents().write(0, title);
|
||||
PacketContainer setSubtitle = m_protocolManager.createPacket(PacketType.Play.Server.SET_SUBTITLE_TEXT);
|
||||
setSubtitle.getChatComponents().write(0, subtitle);
|
||||
|
||||
try {
|
||||
m_protocolManager.sendServerPacket(player, setTitle);
|
||||
m_protocolManager.sendServerPacket(player, setSubtitle);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendActionBar(Player player, WrappedChatComponent text) {
|
||||
// Title packet format changed in 1.17
|
||||
if (m_protoVersion < 755) {
|
||||
PacketContainer setActionBar = m_protocolManager.createPacket(PacketType.Play.Server.TITLE);
|
||||
setActionBar.getChatComponents().write(0, text);
|
||||
setActionBar.getTitleActions().write(0, TitleAction.ACTIONBAR);
|
||||
try {
|
||||
m_protocolManager.sendServerPacket(player, setActionBar);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
} else {
|
||||
PacketContainer setActionBar = m_protocolManager.createPacket(PacketType.Play.Server.SET_ACTION_BAR_TEXT);
|
||||
setActionBar.getChatComponents().write(0, text);
|
||||
try {
|
||||
m_protocolManager.sendServerPacket(player, setActionBar);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -71,30 +127,16 @@ public class PlayerNotifier implements Listener {
|
||||
int pop = m_plugin.playerWatcher().playersInRegion(event.newRegion).size();
|
||||
Location center = event.newRegion.location();
|
||||
int altitude = center.getBlockY();
|
||||
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
|
||||
if (protocolManager != null) {
|
||||
PacketContainer chatMessage = protocolManager.createPacket(PacketType.Play.Server.TITLE);
|
||||
if (m_protocolManager != null) {
|
||||
String colorHex = "#" + String.format("%06X", event.newRegion.color().getColor().asRGB());
|
||||
chatMessage.getChatComponents().write(0, WrappedChatComponent.fromJson("{text:\"" + event.newRegion.name() + "\", color: \""+colorHex+"\"}"));
|
||||
try {
|
||||
protocolManager.sendServerPacket(event.player, chatMessage);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
chatMessage = protocolManager.createPacket(PacketType.Play.Server.TITLE);
|
||||
chatMessage.getChatComponents().write(0, WrappedChatComponent.fromJson("{text:\"Population: " + pop + " Altitude: "+ altitude + "\", color: \"#ffffff\"}"));
|
||||
chatMessage.getTitleActions().write(0, TitleAction.SUBTITLE);
|
||||
try {
|
||||
protocolManager.sendServerPacket(event.player, chatMessage);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
chatMessage = protocolManager.createPacket(PacketType.Play.Server.TITLE);
|
||||
chatMessage.getChatComponents().write(0, WrappedChatComponent.fromJson("{text:\"Now entering " + event.newRegion.name() + "\", color: \""+colorHex+"\"}"));
|
||||
chatMessage.getTitleActions().write(0, TitleAction.ACTIONBAR);
|
||||
try {
|
||||
protocolManager.sendServerPacket(event.player, chatMessage);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
WrappedChatComponent titleComponent = WrappedChatComponent.fromJson("{text:\"" + event.newRegion.name() + "\", color: \""+colorHex+"\"}");
|
||||
WrappedChatComponent subtitleComponent = WrappedChatComponent.fromJson("{text:\"Population: " + pop + " Altitude: "+ altitude + "\", color: \"#ffffff\"}");
|
||||
WrappedChatComponent actionBarComponent = WrappedChatComponent.fromJson("{text:\"Now entering " + event.newRegion.name() + "\", color: \""+colorHex+"\"}");
|
||||
sendTitle(event.player, titleComponent, subtitleComponent);
|
||||
sendActionBar(event.player, actionBarComponent);
|
||||
|
||||
} else {
|
||||
// Fallback to approximated colors
|
||||
event.player.sendTitle(event.newRegion.coloredName(), "Population: " + pop + " Altitude: " + altitude);
|
||||
}
|
||||
}
|
||||
@ -106,25 +148,16 @@ public class PlayerNotifier implements Listener {
|
||||
if (event.region.markSeenByPlayer(event.player)) {
|
||||
event.player.playSound(event.region.location(), Sound.UI_TOAST_CHALLENGE_COMPLETE, (float)1, (float)1);
|
||||
|
||||
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
|
||||
|
||||
if (protocolManager != null) {
|
||||
PacketContainer chatMessage = protocolManager.createPacket(PacketType.Play.Server.TITLE);
|
||||
if (m_protocolManager != null) {
|
||||
String colorHex = "#" + String.format("%06X", event.region.color().getColor().asRGB());
|
||||
chatMessage.getChatComponents().write(0, WrappedChatComponent.fromJson("{text:\"Region discovered\", color: \""+colorHex+"\"}"));
|
||||
try {
|
||||
protocolManager.sendServerPacket(event.player, chatMessage);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
chatMessage = protocolManager.createPacket(PacketType.Play.Server.TITLE);
|
||||
chatMessage.getChatComponents().write(0, WrappedChatComponent.fromJson("{text:\"You discovered the region " + event.region.name() + "\", color: \""+colorHex+"\"}"));
|
||||
chatMessage.getTitleActions().write(0, TitleAction.SUBTITLE);
|
||||
try {
|
||||
protocolManager.sendServerPacket(event.player, chatMessage);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
WrappedChatComponent discoverTitle = WrappedChatComponent.fromJson("{text:\"Region discovered\", color: \""+colorHex+"\"}");
|
||||
WrappedChatComponent discoverSubtitle = WrappedChatComponent.fromJson("{text:\"You discovered the region " + event.region.name() + "\", color: \""+colorHex+"\"}");
|
||||
sendTitle(event.player, discoverTitle, discoverSubtitle);
|
||||
|
||||
} else {
|
||||
//FIXME: also show pop/alt subtitle
|
||||
// Fallback to approximated colors
|
||||
// TODO: Apply region color to the rest of the title and subtitle
|
||||
// text
|
||||
event.player.sendTitle("Region Discovered", "You discovered the region " + event.region.coloredName());
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,7 @@ public class Plugin extends JavaPlugin {
|
||||
if (markerAPI != null) {
|
||||
DynmapEventRelay regionHandler = new DynmapEventRelay (this, markerAPI);
|
||||
getServer().getPluginManager().registerEvents(regionHandler, this);
|
||||
log.info("Dynmap support enabled.");
|
||||
} else {
|
||||
log.info("Dynmap marker API not found. Disabling map support.");
|
||||
}
|
||||
|
@ -151,8 +151,8 @@ public class Region {
|
||||
public int getTravelCost(Region destination) {
|
||||
int baseCost = getBaseTravelCost(destination);
|
||||
if (destination.isHub()) {
|
||||
// Travel *to* a hub is 50% cheaper, before charges applied
|
||||
baseCost /= 2;
|
||||
// Travel *to* a hub is always 1
|
||||
baseCost = 1;
|
||||
}
|
||||
return Math.max(1, (int)(baseCost / (Math.min(4, m_charges + 1))));
|
||||
}
|
||||
@ -166,7 +166,7 @@ public class Region {
|
||||
return 1;
|
||||
}
|
||||
double distance = teleportLocation().distance(destination.teleportLocation());
|
||||
double blocksPerXP = 500;
|
||||
double blocksPerXP = 768;
|
||||
return Math.max(1, (int)(distance / blocksPerXP));
|
||||
}
|
||||
|
||||
|
@ -53,8 +53,8 @@ public class RegionPostItemWatcher implements Listener {
|
||||
NamespacedKey chargeKey = new NamespacedKey(m_plugin, "region_post_charge");
|
||||
ShapedRecipe chargeRecipe = new ShapedRecipe(chargeKey, m_theChargeItem);
|
||||
chargeRecipe.shape("DDD", "DGD", "DDD");
|
||||
chargeRecipe.setIngredient('D', Material.GLOWSTONE_DUST);
|
||||
chargeRecipe.setIngredient('G', Material.GHAST_TEAR);
|
||||
chargeRecipe.setIngredient('D', Material.PURPUR_BLOCK);
|
||||
chargeRecipe.setIngredient('G', Material.QUARTZ);
|
||||
|
||||
NamespacedKey anchorKey = new NamespacedKey(m_plugin, "region_post_anchor");
|
||||
ShapedRecipe anchorRecipe = new ShapedRecipe(anchorKey, m_theAnchor);
|
||||
@ -67,7 +67,7 @@ public class RegionPostItemWatcher implements Listener {
|
||||
// Uses four fewer charges, slightly cheaper.
|
||||
// TODO: Maybe we just want this to be glowstone instead of effectively 4
|
||||
// ghast tears?
|
||||
compassRecipe.shape(" D ", "DGD", " D ");
|
||||
compassRecipe.shape(" D ", " G ", " ");
|
||||
compassRecipe.setIngredient('D', new RecipeChoice.ExactChoice(m_theChargeItem));
|
||||
compassRecipe.setIngredient('G', Material.COMPASS);
|
||||
|
||||
|
@ -24,35 +24,11 @@ public class BorderMesh {
|
||||
Map<Region, Polygon> m_polygons;
|
||||
Map<Region, Set<Region>> m_neighbors;
|
||||
|
||||
// TODO: Probably need to cache the neighbors after doing all this
|
||||
// intersection work! Should be generated during triangulate()
|
||||
public Collection<Region> neighbors(Region region) {
|
||||
Collection<Region> ret = new ArrayList<Region>();
|
||||
if (m_neighbors.containsKey(region)) {
|
||||
Collection<Region> allNeighbors = m_neighbors.get(region);
|
||||
for(Region neighbor : allNeighbors) {
|
||||
int crossings = 0;
|
||||
Vector2D start = new Vector2D(region.location().getBlockX(), region.location().getBlockZ());
|
||||
Vector2D neighborEnd = new Vector2D(neighbor.location().getBlockX(), neighbor.location().getBlockZ());
|
||||
for(Region distantNeighbor : m_regions) {
|
||||
if (distantNeighbor.equals(neighbor)) {
|
||||
continue;
|
||||
}
|
||||
Polygon poly = m_polygons.get(distantNeighbor);
|
||||
for(Polygon.Segment edge : poly.segments()) {
|
||||
// Check if the line from region->neighbor intersects with
|
||||
// any polygon
|
||||
if (doIntersect(start, neighborEnd, edge.start, edge.end)) {
|
||||
crossings++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (crossings == 1 || crossings == 0) {
|
||||
ret.add(neighbor);
|
||||
}
|
||||
}
|
||||
return m_neighbors.get(region);
|
||||
}
|
||||
return ret;
|
||||
return new ArrayList<Region>();
|
||||
}
|
||||
|
||||
public BorderMesh(Collection<Region> regions) {
|
||||
@ -191,10 +167,12 @@ public class BorderMesh {
|
||||
}
|
||||
}
|
||||
|
||||
HashMap<Region, Set<Region>> allNeighborSet = new HashMap<Region, Set<Region>>();
|
||||
|
||||
// Now we go back through our region mesh to generate vornoi points
|
||||
for(Region region : m_regions) {
|
||||
ArrayList<Vector2D> points = new ArrayList<Vector2D>();
|
||||
HashSet<Region> neighbors = new HashSet<Region>();
|
||||
HashSet<Region> allNeighbors = new HashSet<Region>();
|
||||
log.info("Executing voronoi transform...");
|
||||
for(Triangle tri : triangleSoup) {
|
||||
if (tri.region == region) {
|
||||
@ -205,36 +183,58 @@ public class BorderMesh {
|
||||
Location neighborLoc = neighbor.location();
|
||||
Vector2D neighborCenter = new Vector2D(neighborLoc.getBlockX(), neighborLoc.getBlockZ());
|
||||
if (vecEquals(tri.a, neighborCenter) || vecEquals(tri.b, neighborCenter) || vecEquals(tri.c, neighborCenter)) {
|
||||
neighbors.add(neighbor);
|
||||
allNeighbors.add(neighbor);
|
||||
}
|
||||
}
|
||||
points.add(tri.circumcenter());
|
||||
}
|
||||
}
|
||||
|
||||
allNeighborSet.put(region, allNeighbors);
|
||||
|
||||
// Sort points into a renderable polygon based on direction to center
|
||||
Location loc = region.location();
|
||||
Vector2D regionCenter = new Vector2D(loc.getBlockX(), loc.getBlockZ());
|
||||
points.sort((Vector2D a, Vector2D b) -> Double.compare(direction(a, regionCenter), direction(b, regionCenter)));
|
||||
log.info("Border for " + region.name() + " is defined by " + points.size() + " points");
|
||||
log.fine("Border for " + region.name() + " is defined by " + points.size() + " points");
|
||||
Polygon polygon = new Polygon(points);
|
||||
m_polygons.put(region, polygon);
|
||||
m_neighbors.put(region, neighbors);
|
||||
|
||||
}
|
||||
|
||||
// Now that we have the borders, we generate valid routes that cross
|
||||
// zero or one border lines at most.
|
||||
for(Region region : m_regions) {
|
||||
Set<Region> routedNeighbors = new HashSet<Region>();
|
||||
for(Region neighbor : allNeighborSet.get(region)) {
|
||||
int crossings = 0;
|
||||
Vector2D start = new Vector2D(region.location().getBlockX(), region.location().getBlockZ());
|
||||
Vector2D neighborEnd = new Vector2D(neighbor.location().getBlockX(), neighbor.location().getBlockZ());
|
||||
for(Region distantNeighbor : m_regions) {
|
||||
if (distantNeighbor.equals(neighbor) || distantNeighbor.equals(region)) {
|
||||
continue;
|
||||
}
|
||||
Polygon poly = m_polygons.get(distantNeighbor);
|
||||
for(Polygon.Segment edge : poly.segments()) {
|
||||
// Check if the line from region->neighbor intersects with
|
||||
// any polygon
|
||||
if (doIntersect(start, neighborEnd, edge.start, edge.end)) {
|
||||
log.fine("Intersect " + distantNeighbor.name());
|
||||
crossings++;
|
||||
}
|
||||
}
|
||||
}
|
||||
log.fine("Route: " + region.name() + " -> " + neighbor.name() + "\t" + crossings);
|
||||
if (crossings == 1 || crossings == 0) {
|
||||
routedNeighbors.add(neighbor);
|
||||
}
|
||||
}
|
||||
|
||||
m_neighbors.put(region, routedNeighbors);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*public boolean validNeighbors(Region regionA, Region regionB) {
|
||||
Polygon polyA = polygonForRegion(regionA);
|
||||
Polygon polyB = polygonForRegion(regionA);
|
||||
Location center = region.location();
|
||||
if (poly.contains(center.getBlockX(), center.getBlockZ())) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
|
||||
private boolean vecEquals(Vector2D a, Vector2D b) {
|
||||
return a.x == b.x && a.y == b.y;
|
||||
}
|
||||
|
BIN
src/main/resources/lantern.png
Normal file
BIN
src/main/resources/lantern.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
@ -4,7 +4,7 @@ author: Torrie Fischer <tdfischer@hackerbots.net>
|
||||
website: http://hackerbots.net/
|
||||
version: ${version}
|
||||
api-version: 1.16
|
||||
softdepend: [dynmap, ProtocolLib]
|
||||
softdepend: [dynmap, ProtocolLib, Pl3xMap]
|
||||
commands:
|
||||
regions:
|
||||
description: "List available regions."
|
||||
|
Reference in New Issue
Block a user