Skip to content

Commit

Permalink
Suppress ender crystal drops in a radius around the end portal (end s…
Browse files Browse the repository at this point in the history
…ide) to prevent their recovery when the dragon has already started spawning.
  • Loading branch information
totemo committed Jun 13, 2016
1 parent 02ae9c5 commit 0ebfda6
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 3 deletions.
10 changes: 10 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
end-portal:
radius: 7.0
location:
==: org.bukkit.Location
world: world_the_end
x: 0.0
y: 62.0
z: 0.0
pitch: 0.0
yaw: 0.0
3 changes: 2 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>nu.nerd</groupId>
<name>SafeCrystals</name>
<artifactId>${project.name}</artifactId>
<version>0.1.0</version>
<version>1.0.0</version>
<packaging>jar</packaging>
<description>Prevent Ender Crystals from exploding and breaking blocks or damaging entities.</description>
<url>https://github.com/totemo/${project.name}</url>
Expand Down Expand Up @@ -48,6 +48,7 @@
<directory>${basedir}</directory>
<includes>
<include>plugin.yml</include>
<include>config.yml</include>
</includes>
</resource>
</resources>
Expand Down
30 changes: 30 additions & 0 deletions src/nu/nerd/safecrystals/Configuration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package nu.nerd.safecrystals;

import org.bukkit.Location;

// ----------------------------------------------------------------------------
/**
* Configuration wrapper.
*/
public class Configuration {
/**
* Radius around END_PORTAL_LOCATION where broken ender crystals don't drop.
*/
public double END_PORTAL_RADIUS;

/**
* Location of the (assumed only) end-side end portal.
*/
public Location END_PORTAL_LOCATION;

// ------------------------------------------------------------------------
/**
* Reload the configuration.
*/
public void reload() {
SafeCrystals.PLUGIN.reloadConfig();

END_PORTAL_RADIUS = SafeCrystals.PLUGIN.getConfig().getDouble("end-portal.radius");
END_PORTAL_LOCATION = (Location) SafeCrystals.PLUGIN.getConfig().get("end-portal.location");
}
} // class Configuration
47 changes: 45 additions & 2 deletions src/nu/nerd/safecrystals/SafeCrystals.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,26 @@
* Ender Crystal in a region.
*/
public class SafeCrystals extends JavaPlugin implements Listener {
/**
* Singleton-like reference to this plugin.
*/
public static SafeCrystals PLUGIN;

/**
* Configuration instance.
*/
public static Configuration CONFIG = new Configuration();

// ------------------------------------------------------------------------
/**
* @see org.bukkit.plugin.java.JavaPlugin#onEnable()
*/
@Override
public void onEnable() {
PLUGIN = this;
saveDefaultConfig();
CONFIG.reload();

_worldGuard = (WorldGuardPlugin) getServer().getPluginManager().getPlugin("WorldGuard");
Bukkit.getPluginManager().registerEvents(this, this);
}
Expand Down Expand Up @@ -110,13 +123,43 @@ protected void tryBreakEnderCrystal(Entity crystal, Player player) {
Location loc = crystal.getLocation();
if (_worldGuard.canBuild(player, loc)) {
crystal.remove();
loc.getWorld().dropItemNaturally(loc, new ItemStack(Material.END_CRYSTAL));
String suppressed;
if (isDragonSpawningCrystal(loc)) {
suppressed = " - drop suppressed because dragon may spawn";
} else {
loc.getWorld().dropItemNaturally(loc, new ItemStack(Material.END_CRYSTAL));
suppressed = "";
}
getLogger().info(player.getName() + " broke an Ender Crystal at " +
loc.getWorld().getName() + ", " +
loc.getBlockX() + ", " + loc.getBlockY() + ", " + loc.getBlockZ());
loc.getBlockX() + ", " + loc.getBlockY() + ", " + loc.getBlockZ() + suppressed);
}
}

// ------------------------------------------------------------------------
/**
* Return true if the crystal is in a position that can be used to summon
* the dragon.
*
* When summoning the dragon, players can break the crystals on the frame
* before the dragon CreatureSpawnEvent (reason DEFAULT) occurs, and
* potentially recover them, if they don't burn up in the fire underneath.
* This method is used to detect that situation and prevent recovery of the
* crystals.
*
* Getting delicate about the exact coordinates of the crystal won't work
* because a determined player will move the crystals with pistons
* (verified). Any crystals too close to the portal would normally be blown
* up by the explosion when the dragon spawns, anyway.
*
* @param loc the location of the crystal.
* @return true if the crystal is in a position that can be used to summon
* the dragon.
*/
protected boolean isDragonSpawningCrystal(Location loc) {
return (loc.distance(CONFIG.END_PORTAL_LOCATION) < CONFIG.END_PORTAL_RADIUS);
}

// ------------------------------------------------------------------------
/**
* Reference to WorldGuard.
Expand Down

0 comments on commit 0ebfda6

Please sign in to comment.