Merge branch 'util-refactoring'

This commit is contained in:
main() 2012-01-28 15:41:58 +01:00
commit eec765bc48
32 changed files with 1572 additions and 94 deletions

View File

@ -7,6 +7,7 @@
package com.onarandombox.MultiverseCore; package com.onarandombox.MultiverseCore;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.configuration.ConfigPropertyFactory; import com.onarandombox.MultiverseCore.configuration.ConfigPropertyFactory;
import com.onarandombox.MultiverseCore.configuration.MVActiveConfigProperty; import com.onarandombox.MultiverseCore.configuration.MVActiveConfigProperty;
@ -14,9 +15,7 @@ import com.onarandombox.MultiverseCore.configuration.MVConfigProperty;
import com.onarandombox.MultiverseCore.enums.EnglishChatColor; import com.onarandombox.MultiverseCore.enums.EnglishChatColor;
import com.onarandombox.MultiverseCore.event.MVWorldPropertyChangeEvent; import com.onarandombox.MultiverseCore.event.MVWorldPropertyChangeEvent;
import com.onarandombox.MultiverseCore.exceptions.PropertyDoesNotExistException; import com.onarandombox.MultiverseCore.exceptions.PropertyDoesNotExistException;
import com.onarandombox.MultiverseCore.utils.BlockSafety; import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.utils.LocationManipulation;
import com.onarandombox.MultiverseCore.utils.SafeTTeleporter;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Difficulty; import org.bukkit.Difficulty;
import org.bukkit.GameMode; import org.bukkit.GameMode;
@ -33,7 +32,6 @@ import org.bukkit.permissions.PermissionDefault;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -433,7 +431,7 @@ public class MVWorld implements MultiverseWorld {
} else { } else {
this.world.setSpawnFlags(true, this.world.getAllowAnimals()); this.world.setSpawnFlags(true, this.world.getAllowAnimals());
} }
this.plugin.getMVWorldManager().getWorldPurger().purgeWorld(null, this); this.plugin.getMVWorldManager().getTheWorldPurger().purgeWorld(this);
} }
/** /**
@ -986,8 +984,8 @@ public class MVWorld implements MultiverseWorld {
// Set the worldspawn to our configspawn // Set the worldspawn to our configspawn
w.setSpawnLocation(configLocation.getBlockX(), configLocation.getBlockY(), configLocation.getBlockZ()); w.setSpawnLocation(configLocation.getBlockX(), configLocation.getBlockY(), configLocation.getBlockZ());
SafeTTeleporter teleporter = this.plugin.getTeleporter(); SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
BlockSafety bs = new BlockSafety(); BlockSafety bs = this.plugin.getBlockSafety();
// Verify that location was safe // Verify that location was safe
if (!bs.playerCanSpawnHereSafely(configLocation)) { if (!bs.playerCanSpawnHereSafely(configLocation)) {
if (!this.getAdjustSpawn()) { if (!this.getAdjustSpawn()) {
@ -999,7 +997,7 @@ public class MVWorld implements MultiverseWorld {
} }
// If it's not, find a better one. // If it's not, find a better one.
this.plugin.log(Level.WARNING, "Spawn location from world.dat file was unsafe. Adjusting..."); this.plugin.log(Level.WARNING, "Spawn location from world.dat file was unsafe. Adjusting...");
this.plugin.log(Level.WARNING, "Original Location: " + LocationManipulation.strCoordsRaw(spawnLocation)); this.plugin.log(Level.WARNING, "Original Location: " + plugin.getLocationManipulation().strCoordsRaw(spawnLocation));
Location newSpawn = teleporter.getSafeLocation(spawnLocation, Location newSpawn = teleporter.getSafeLocation(spawnLocation,
SPAWN_LOCATION_SEARCH_TOLERANCE, SPAWN_LOCATION_SEARCH_RADIUS); SPAWN_LOCATION_SEARCH_TOLERANCE, SPAWN_LOCATION_SEARCH_RADIUS);
// I think we could also do this, as I think this is what Notch does. // I think we could also do this, as I think this is what Notch does.
@ -1008,7 +1006,8 @@ public class MVWorld implements MultiverseWorld {
if (newSpawn != null) { if (newSpawn != null) {
this.setSpawnLocation(newSpawn); this.setSpawnLocation(newSpawn);
configLocation = this.getSpawnLocation(); configLocation = this.getSpawnLocation();
this.plugin.log(Level.INFO, "New Spawn for '" + this.getName() + "' is Located at: " + LocationManipulation.locationToString(configLocation)); this.plugin.log(Level.INFO, "New Spawn for '" + this.getName()
+ "' is Located at: " + plugin.getLocationManipulation().locationToString(configLocation));
} else { } else {
// If it's a standard end world, let's check in a better place: // If it's a standard end world, let's check in a better place:
Location newerSpawn; Location newerSpawn;
@ -1017,7 +1016,7 @@ public class MVWorld implements MultiverseWorld {
this.setSpawnLocation(newerSpawn); this.setSpawnLocation(newerSpawn);
configLocation = this.getSpawnLocation(); configLocation = this.getSpawnLocation();
this.plugin.log(Level.INFO, "New Spawn for '" + this.getName() this.plugin.log(Level.INFO, "New Spawn for '" + this.getName()
+ "' is Located at: " + LocationManipulation.locationToString(configLocation)); + "' is Located at: " + plugin.getLocationManipulation().locationToString(configLocation));
} else { } else {
this.plugin.log(Level.SEVERE, "New safe spawn NOT found!!!"); this.plugin.log(Level.SEVERE, "New safe spawn NOT found!!!");
} }

View File

@ -9,10 +9,14 @@ package com.onarandombox.MultiverseCore;
import com.fernferret.allpay.AllPay; import com.fernferret.allpay.AllPay;
import com.fernferret.allpay.GenericBank; import com.fernferret.allpay.GenericBank;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.Core; import com.onarandombox.MultiverseCore.api.Core;
import com.onarandombox.MultiverseCore.api.LocationManipulation;
import com.onarandombox.MultiverseCore.api.MVPlugin; import com.onarandombox.MultiverseCore.api.MVPlugin;
import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseMessaging;
import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.commands.*; import com.onarandombox.MultiverseCore.commands.*;
import com.onarandombox.MultiverseCore.destination.AnchorDestination; import com.onarandombox.MultiverseCore.destination.AnchorDestination;
import com.onarandombox.MultiverseCore.destination.BedDestination; import com.onarandombox.MultiverseCore.destination.BedDestination;
@ -26,14 +30,7 @@ import com.onarandombox.MultiverseCore.listeners.MVEntityListener;
import com.onarandombox.MultiverseCore.listeners.MVPlayerListener; import com.onarandombox.MultiverseCore.listeners.MVPlayerListener;
import com.onarandombox.MultiverseCore.listeners.MVPluginListener; import com.onarandombox.MultiverseCore.listeners.MVPluginListener;
import com.onarandombox.MultiverseCore.listeners.MVWeatherListener; import com.onarandombox.MultiverseCore.listeners.MVWeatherListener;
import com.onarandombox.MultiverseCore.utils.AnchorManager; import com.onarandombox.MultiverseCore.utils.*;
import com.onarandombox.MultiverseCore.utils.DebugLog;
import com.onarandombox.MultiverseCore.utils.MVMessaging;
import com.onarandombox.MultiverseCore.utils.MVPermissions;
import com.onarandombox.MultiverseCore.utils.MVPlayerSession;
import com.onarandombox.MultiverseCore.utils.SafeTTeleporter;
import com.onarandombox.MultiverseCore.utils.SpoutInterface;
import com.onarandombox.MultiverseCore.utils.WorldManager;
import com.pneumaticraft.commandhandler.CommandHandler; import com.pneumaticraft.commandhandler.CommandHandler;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
@ -168,7 +165,10 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
private SpoutInterface spoutInterface = null; private SpoutInterface spoutInterface = null;
private static final double ALLPAY_VERSION = 5; private static final double ALLPAY_VERSION = 5;
private static final double CH_VERSION = 4; private static final double CH_VERSION = 4;
private MVMessaging messaging; private MultiverseMessaging messaging;
private BlockSafety blockSafety;
private LocationManipulation locationManipulation;
private SafeTTeleporter safeTTeleporter;
private File serverFolder = new File(System.getProperty("user.dir")); private File serverFolder = new File(System.getProperty("user.dir"));
@ -178,6 +178,12 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
getDataFolder().mkdirs(); getDataFolder().mkdirs();
// Setup our Debug Log // Setup our Debug Log
debugLog = new DebugLog("Multiverse-Core", getDataFolder() + File.separator + "debug.log"); debugLog = new DebugLog("Multiverse-Core", getDataFolder() + File.separator + "debug.log");
// Setup our BlockSafety
this.blockSafety = new SimpleBlockSafety(this);
// Setup our LocationManipulation
this.locationManipulation = new SimpleLocationManipulation();
// Setup our SafeTTeleporter
this.safeTTeleporter = new SimpleSafeTTeleporter(this);
} }
/** /**
@ -375,7 +381,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public MVMessaging getMessaging() { public MultiverseMessaging getMessaging() {
return this.messaging; return this.messaging;
} }
@ -445,10 +451,13 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
/** /**
* {@inheritDoc} * {@inheritDoc}
*
* @deprecated This is deprecated.
*/ */
@Override @Override
public SafeTTeleporter getTeleporter() { @Deprecated
return new SafeTTeleporter(this); public com.onarandombox.MultiverseCore.utils.SafeTTeleporter getTeleporter() {
return new com.onarandombox.MultiverseCore.utils.SafeTTeleporter(this);
} }
/** /**
@ -637,7 +646,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
*/ */
public void teleportPlayer(CommandSender teleporter, Player p, Location l) { public void teleportPlayer(CommandSender teleporter, Player p, Location l) {
// This command is the override, and MUST NOT TELEPORT SAFELY // This command is the override, and MUST NOT TELEPORT SAFELY
this.getTeleporter().safelyTeleport(teleporter, p, l, false); this.getSafeTTeleporter().safelyTeleport(teleporter, p, l, false);
} }
/** /**
@ -779,7 +788,7 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
} }
if (this.worldManager.deleteWorld(name, false)) { if (this.worldManager.deleteWorld(name, false)) {
this.worldManager.loadWorlds(false); this.worldManager.loadWorlds(false);
SafeTTeleporter teleporter = this.getTeleporter(); SafeTTeleporter teleporter = this.getSafeTTeleporter();
Location newSpawn = this.getServer().getWorld(name).getSpawnLocation(); Location newSpawn = this.getServer().getWorld(name).getSpawnLocation();
// Send all players that were in the old world, BACK to it! // Send all players that were in the old world, BACK to it!
for (Player p : ps) { for (Player p : ps) {
@ -798,4 +807,51 @@ public class MultiverseCore extends JavaPlugin implements MVPlugin, Core {
return this.anchorManager; return this.anchorManager;
} }
/**
* {@inheritDoc}
*/
@Override
public BlockSafety getBlockSafety() {
return blockSafety;
}
/**
* {@inheritDoc}
*/
@Override
public void setBlockSafety(BlockSafety bs) {
this.blockSafety = bs;
}
/**
* {@inheritDoc}
*/
@Override
public LocationManipulation getLocationManipulation() {
return locationManipulation;
}
/**
* {@inheritDoc}
*/
@Override
public void setLocationManipulation(LocationManipulation locationManipulation) {
this.locationManipulation = locationManipulation;
}
/**
* {@inheritDoc}
*/
@Override
public SafeTTeleporter getSafeTTeleporter() {
return safeTTeleporter;
}
/**
* {@inheritDoc}
*/
@Override
public void setSafeTTeleporter(SafeTTeleporter safeTTeleporter) {
this.safeTTeleporter = safeTTeleporter;
}
} }

View File

@ -0,0 +1,72 @@
package com.onarandombox.MultiverseCore.api;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Vehicle;
/**
* Used to get block/location-related information.
*/
public interface BlockSafety {
/**
* This function checks whether the block at the given coordinates are above air or not.
* @param l The {@link Location} of the block.
* @return True if the block at that {@link Location} is above air.
*/
boolean isBlockAboveAir(Location l);
/**
* Checks if a player can spawn safely at the given coordinates.
* @param world The {@link World}.
* @param x The x-coordinate.
* @param y The y-coordinate.
* @param z The z-coordinate.
* @return True if a player can spawn safely at the given coordinates.
*/
boolean playerCanSpawnHereSafely(World world, double x, double y, double z);
/**
* This function checks whether the block at the coordinates given is safe or not by checking for Lava/Fire/Air
* etc. This also ensures there is enough space for a player to spawn!
*
* @param l The {@link Location}
* @return Whether the player can spawn safely at the given {@link Location}
*/
boolean playerCanSpawnHereSafely(Location l);
/**
* Gets the location of the top block at the specified {@link Location}.
* @param l Any {@link Location}.
* @return The {@link Location} of the top-block.
*/
Location getTopBlock(Location l);
/**
* Gets the location of the top block at the specified {@link Location}.
* @param l Any {@link Location}.
* @return The {@link Location} of the top-block.
*/
Location getBottomBlock(Location l);
/**
* Checks if an entity would be on track at the specified {@link Location}.
* @param l The {@link Location}.
* @return True if an entity would be on tracks at the specified {@link Location}.
*/
boolean isEntitiyOnTrack(Location l);
/**
* Checks if the specified {@link Minecart} can spawn safely.
* @param cart The {@link Minecart}.
* @return True if the minecart can spawn safely.
*/
boolean canSpawnCartSafely(Minecart cart);
/**
* Checks if the specified {@link Vehicle} can spawn safely.
* @param vehicle The {@link Vehicle}.
* @return True if the vehicle can spawn safely.
*/
boolean canSpawnVehicleSafely(Vehicle vehicle);
}

View File

@ -46,9 +46,9 @@ public interface Core {
* Gets the Multiverse message system. This allows you to send messages * Gets the Multiverse message system. This allows you to send messages
* to users at specified intervals. * to users at specified intervals.
* *
* @return The loaded {@link MVMessaging}. * @return The loaded {@link MultiverseMessaging}.
*/ */
MVMessaging getMessaging(); MultiverseMessaging getMessaging();
/** /**
* Gets the {@link MVPlayerSession} for the given player. * Gets the {@link MVPlayerSession} for the given player.
@ -66,8 +66,11 @@ public interface Core {
* safe teleports. * safe teleports.
* *
* @return A non-null {@link SafeTTeleporter}. * @return A non-null {@link SafeTTeleporter}.
*
* @deprecated Use {@link #getSafeTTeleporter()} instead.
*/ */
SafeTTeleporter getTeleporter(); @Deprecated
com.onarandombox.MultiverseCore.utils.SafeTTeleporter getTeleporter();
/** /**
* Multiverse uses an advanced permissions setup, this object * Multiverse uses an advanced permissions setup, this object
@ -163,4 +166,53 @@ public interface Core {
* @return The readable authors-{@link String} * @return The readable authors-{@link String}
*/ */
String getAuthors(); String getAuthors();
/**
* Gets the {@link BlockSafety} this {@link Core} is using.
* @return The {@link BlockSafety} this {@link Core} is using.
* @see BlockSafety
* @see SimpleBlockSafety
*/
BlockSafety getBlockSafety();
/**
* Sets the {@link BlockSafety} this {@link Core} is using.
* @param blockSafety The new {@link BlockSafety}.
* @see BlockSafety
* @see SimpleBlockSafety
*/
void setBlockSafety(BlockSafety blockSafety);
/**
* Gets the {@link LocationManipulation} this {@link Core} is using.
* @return The {@link LocationManipulation} this {@link Core} is using.
* @see LocationManipulation
* @see SimpleLocationManipulation
*/
LocationManipulation getLocationManipulation();
/**
* Sets the {@link LocationManipulation} this {@link Core} is using.
* @param locationManipulation The new {@link LocationManipulation}.
* @see LocationManipulation
* @see SimpleLocationManipulation
*/
void setLocationManipulation(LocationManipulation locationManipulation);
/**
* Gets the {@link SafeTTeleporter} this {@link Core} is using.
* @return The {@link SafeTTeleporter} this {@link Core} is using.
* @see SafeTTeleporter
* @see SimpleSafeTTeleporter
*/
SafeTTeleporter getSafeTTeleporter();
/**
* Sets the {@link SafeTTeleporter} this {@link Core} is using.
* @param safeTTeleporter The new {@link SafeTTeleporter}.
* @see SafeTTeleporter
* @see SimpleSafeTTeleporter
*/
void setSafeTTeleporter(SafeTTeleporter safeTTeleporter);
} }

View File

@ -0,0 +1,99 @@
package com.onarandombox.MultiverseCore.api;
import org.bukkit.Location;
import org.bukkit.entity.Vehicle;
import org.bukkit.util.Vector;
/**
* Used to manipulate locations.
*/
public interface LocationManipulation {
/**
* Convert a Location into a Colon separated string to allow us to store it in text.
* <p>
* WORLD:X,Y,Z:yaw:pitch
* <p>
* The corresponding String2Loc function is {@link #stringToLocation}
*
* @param location The Location to save.
* @return The location as a string in this format: WORLD:x,y,z:yaw:pitch
*/
String locationToString(Location location);
/**
* This method simply does some rounding, rather than forcing a call to the server to get the blockdata.
*
* @param l The location to round to the block location
* @return A rounded location.
*/
Location getBlockLocation(Location l);
/**
* Returns a new location from a given string. The format is as follows:
* <p>
* WORLD:X,Y,Z:yaw:pitch
* <p>
* The corresponding Location2String function is {@link #stringToLocation}
*
* @param locationString The location represented as a string (WORLD:X,Y,Z:yaw:pitch)
* @return A new location defined by the string or null if the string was invalid.
*/
Location stringToLocation(String locationString);
/**
* Returns a colored string with the coords.
*
* @param l The {@link Location}
* @return The {@link String}
*/
String strCoords(Location l);
/**
* Converts a location to a printable readable formatted string including pitch/yaw.
*
* @param l The {@link Location}
* @return The {@link String}
*/
String strCoordsRaw(Location l);
/**
* Return the NESW Direction a Location is facing.
*
* @param location The {@link Location}
* @return The NESW Direction
*/
String getDirection(Location location);
/**
* Returns the float yaw position for the given cardinal direction.
*
* @param orientation The cardinal direction
* @return The yaw
*/
float getYaw(String orientation);
/**
* Returns a speed float from a given vector.
*
* @param v The {@link Vector}
* @return The speed
*/
float getSpeed(Vector v);
/**
* Returns a translated vector from the given direction.
*
* @param v The old {@link Vector}
* @param direction The new direction
* @return The translated {@link Vector}
*/
Vector getTranslatedVector(Vector v, String direction);
/**
* Returns the next Location that a {@link Vehicle} is traveling at.
*
* @param v The {@link Vehicle}
* @return The {@link Location}
*/
Location getNextBlock(Vehicle v);
}

View File

@ -8,6 +8,8 @@
package com.onarandombox.MultiverseCore.api; package com.onarandombox.MultiverseCore.api;
import com.onarandombox.MultiverseCore.utils.PurgeWorlds; import com.onarandombox.MultiverseCore.utils.PurgeWorlds;
import com.onarandombox.MultiverseCore.utils.SimpleWorldPurger;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.World.Environment; import org.bukkit.World.Environment;
import org.bukkit.WorldType; import org.bukkit.WorldType;
@ -168,9 +170,21 @@ public interface MVWorldManager {
* Return the World Purger. * Return the World Purger.
* *
* @return A valid {@link PurgeWorlds}. * @return A valid {@link PurgeWorlds}.
* @deprecated {@link PurgeWorlds} is deprecated!
*/ */
@Deprecated
PurgeWorlds getWorldPurger(); PurgeWorlds getWorldPurger();
/**
* Gets the {@link WorldPurger}.
* <p>
* TODO: Remove {@link #getWorldPurger()} and replace it with this method.
* @return The {@link WorldPurger} this {@link MVWorldManager} is using.
* @see WorldPurger
* @see SimpleWorldPurger
*/
WorldPurger getTheWorldPurger();
/** /**
* Gets the world players will spawn in on first join. * Gets the world players will spawn in on first join.
* Currently this always returns worlds.get(0) from Bukkit. * Currently this always returns worlds.get(0) from Bukkit.

View File

@ -0,0 +1,56 @@
package com.onarandombox.MultiverseCore.api;
import java.util.Collection;
import org.bukkit.command.CommandSender;
/**
* Multiverse-messaging.
*/
public interface MultiverseMessaging {
/**
* Sets the message-cooldown.
* @param milliseconds The new message-cooldown in milliseconds.
*/
void setCooldown(int milliseconds);
/**
* Sends a message to the specified sender if the cooldown has passed.
*
* @param sender The person/console to send the message to.
* @param message The message to send.
* @param ignoreCooldown If true this message will always be sent. Useful for things like menus
* @return true if the message was sent, false if not.
*/
boolean sendMessage(CommandSender sender, String message, boolean ignoreCooldown);
/**
* Sends a group of messages to the specified sender if the cooldown has passed.
* This method is needed, since sending many messages in quick succession would violate
* the cooldown.
*
* @param sender The person/console to send the message to.
* @param messages The messages to send.
* @param ignoreCooldown If true these messages will always be sent. Useful for things like menus
* @return true if the message was sent, false if not.
*/
boolean sendMessages(CommandSender sender, String[] messages, boolean ignoreCooldown);
/**
* Sends a group of messages to the specified sender if the cooldown has passed.
* This method is needed, since sending many messages in quick succession would violate
* the cooldown.
*
* @param sender The person/console to send the message to.
* @param messages The messages to send.
* @param ignoreCooldown If true these messages will always be sent. Useful for things like menus
* @return true if the message was sent, false if not.
*/
boolean sendMessages(CommandSender sender, Collection<String> messages, boolean ignoreCooldown);
/**
* Gets the message-cooldown.
* @return The message-cooldown.
*/
int getCooldown();
}

View File

@ -0,0 +1,71 @@
package com.onarandombox.MultiverseCore.api;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import com.onarandombox.MultiverseCore.enums.TeleportResult;
/**
* Used to safely teleport people.
*/
public interface SafeTTeleporter {
/**
* Gets the next safe location around the given location.
* @param l A {@link Location}.
* @return A safe {@link Location}.
*/
Location getSafeLocation(Location l);
/**
* Gets the next safe location around the given location.
* @param l A {@link Location}.
* @param tolerance The tolerance.
* @param radius The radius.
* @return A safe {@link Location}.
*/
Location getSafeLocation(Location l, int tolerance, int radius);
/**
* Safely teleport the entity to the MVDestination. This will perform checks to see if the place is safe, and if
* it's not, will adjust the final destination accordingly.
*
* @param teleporter Person who performed the teleport command.
* @param teleportee Entity to teleport
* @param d Destination to teleport them to
* @return true for success, false for failure
*/
TeleportResult safelyTeleport(CommandSender teleporter, Entity teleportee, MVDestination d);
/**
* Safely teleport the entity to the Location. This may perform checks to
* see if the place is safe, and if
* it's not, will adjust the final destination accordingly.
*
* @param teleporter Person who issued the teleport command.
* @param teleportee Entity to teleport.
* @param location Location to teleport them to.
* @param safely Should the destination be checked for safety before teleport?
* @return true for success, false for failure.
*/
TeleportResult safelyTeleport(CommandSender teleporter, Entity teleportee, Location location,
boolean safely);
/**
* Returns a safe location for the entity to spawn at.
*
* @param e The entity to spawn
* @param d The MVDestination to take the entity to.
* @return A new location to spawn the entity at.
*/
Location getSafeLocation(Entity e, MVDestination d);
/**
* Finds a portal-block next to the specified {@link Location}.
* @param l The {@link Location}
* @return The next portal-block's {@link Location}.
*/
Location findPortalBlockNextTo(Location l);
}

View File

@ -0,0 +1,49 @@
package com.onarandombox.MultiverseCore.api;
import java.util.List;
import org.bukkit.command.CommandSender;
/**
* Used to remove animals from worlds that don't belong there.
*/
public interface WorldPurger {
/**
* Synchronizes the given world with it's settings.
*
* @param worlds A list of {@link MultiverseWorld}
*/
void purgeWorlds(List<MultiverseWorld> worlds);
/**
* Convenience method for {@link #purgeWorld(CommandSender, MultiverseWorld, List, boolean, boolean)} that takes the settings from the world-config.
*
* @param world The {@link MultiverseWorld}.
*/
void purgeWorld(MultiverseWorld world);
/**
* Clear all animals/monsters that do not belong to a world according to the config.
*
* @param mvworld The {@link MultiverseWorld}.
* @param thingsToKill A {@link List} of animals/monsters to be killed.
* @param negateAnimals Whether the monsters in the list should be negated.
* @param negateMonsters Whether the animals in the list should be negated.
*/
void purgeWorld(MultiverseWorld mvworld, List<String> thingsToKill, boolean negateAnimals,
boolean negateMonsters);
/**
* Clear all animals/monsters that do not belong to a world according to the config.
*
* @param mvworld The {@link MultiverseWorld}.
* @param thingsToKill A {@link List} of animals/monsters to be killed.
* @param negateAnimals Whether the monsters in the list should be negated.
* @param negateMonsters Whether the animals in the list should be negated.
* @param sender The {@link CommandSender} that initiated the action. He will/should be notified.
*/
void purgeWorld(MultiverseWorld mvworld, List<String> thingsToKill, boolean negateAnimals,
boolean negateMonsters, CommandSender sender);
}

View File

@ -10,7 +10,6 @@ package com.onarandombox.MultiverseCore.commands;
import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.utils.LocationManipulation;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
@ -61,8 +60,8 @@ public class CoordCommand extends MultiverseCommand {
DecimalFormat df = new DecimalFormat(); DecimalFormat df = new DecimalFormat();
df.setMinimumFractionDigits(0); df.setMinimumFractionDigits(0);
df.setMaximumFractionDigits(2); df.setMaximumFractionDigits(2);
p.sendMessage(ChatColor.AQUA + "Coordinates: " + ChatColor.WHITE + LocationManipulation.strCoords(p.getLocation())); p.sendMessage(ChatColor.AQUA + "Coordinates: " + ChatColor.WHITE + plugin.getLocationManipulation().strCoords(p.getLocation()));
p.sendMessage(ChatColor.AQUA + "Direction: " + ChatColor.WHITE + LocationManipulation.getDirection(p.getLocation())); p.sendMessage(ChatColor.AQUA + "Direction: " + ChatColor.WHITE + plugin.getLocationManipulation().getDirection(p.getLocation()));
p.sendMessage(ChatColor.AQUA + "Block: " + ChatColor.WHITE + Material.getMaterial(world.getBlockTypeIdAt(p.getLocation()))); p.sendMessage(ChatColor.AQUA + "Block: " + ChatColor.WHITE + Material.getMaterial(world.getBlockTypeIdAt(p.getLocation())));
} else { } else {
sender.sendMessage("This command needs to be used from a Player."); sender.sendMessage("This command needs to be used from a Player.");

View File

@ -14,7 +14,6 @@ import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.utils.FancyColorScheme; import com.onarandombox.MultiverseCore.utils.FancyColorScheme;
import com.onarandombox.MultiverseCore.utils.FancyHeader; import com.onarandombox.MultiverseCore.utils.FancyHeader;
import com.onarandombox.MultiverseCore.utils.FancyMessage; import com.onarandombox.MultiverseCore.utils.FancyMessage;
import com.onarandombox.MultiverseCore.utils.LocationManipulation;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -113,7 +112,7 @@ public class InfoCommand extends MultiverseCommand {
message.add(new FancyMessage("World Type: ", world.getWorldType().toString(), colors)); message.add(new FancyMessage("World Type: ", world.getWorldType().toString(), colors));
//message.add(new FancyMessage("Game Mode: ", StringUtils.capitalize(world.getGameMode().toString()), colors)); //message.add(new FancyMessage("Game Mode: ", StringUtils.capitalize(world.getGameMode().toString()), colors));
Location spawn = world.getSpawnLocation(); Location spawn = world.getSpawnLocation();
message.add(new FancyMessage("Spawn Location: ", LocationManipulation.strCoords(spawn), colors)); message.add(new FancyMessage("Spawn Location: ", plugin.getLocationManipulation().strCoords(spawn), colors));
message.add(new FancyMessage("World Scale: ", world.getScaling() + "", colors)); message.add(new FancyMessage("World Scale: ", world.getScaling() + "", colors));
if (world.getPrice() > 0) { if (world.getPrice() > 0) {
message.add(new FancyMessage("Price to enter this world: ", message.add(new FancyMessage("Price to enter this world: ",

View File

@ -8,7 +8,7 @@
package com.onarandombox.MultiverseCore.commands; package com.onarandombox.MultiverseCore.commands;
import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.utils.MVMessaging; import com.onarandombox.MultiverseCore.api.MultiverseMessaging;
import com.pneumaticraft.commandhandler.Command; import com.pneumaticraft.commandhandler.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -24,9 +24,9 @@ public abstract class MultiverseCommand extends Command {
*/ */
protected MultiverseCore plugin; protected MultiverseCore plugin;
/** /**
* The reference to {@link MVMessaging}. * The reference to {@link MultiverseMessaging}.
*/ */
protected MVMessaging messaging; protected MultiverseMessaging messaging;
public MultiverseCommand(MultiverseCore plugin) { public MultiverseCommand(MultiverseCore plugin) {
super(plugin); super(plugin);

View File

@ -10,7 +10,7 @@ package com.onarandombox.MultiverseCore.commands;
import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.utils.PurgeWorlds; import com.onarandombox.MultiverseCore.api.WorldPurger;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -78,7 +78,7 @@ public class PurgeCommand extends MultiverseCommand {
worldsToRemoveEntitiesFrom.add(this.worldManager.getMVWorld(worldName)); worldsToRemoveEntitiesFrom.add(this.worldManager.getMVWorld(worldName));
} }
PurgeWorlds purger = this.worldManager.getWorldPurger(); WorldPurger purger = this.worldManager.getTheWorldPurger();
ArrayList<String> thingsToKill = new ArrayList<String>(); ArrayList<String> thingsToKill = new ArrayList<String>();
if (deathName.equalsIgnoreCase("all") || deathName.equalsIgnoreCase("animals") || deathName.equalsIgnoreCase("monsters")) { if (deathName.equalsIgnoreCase("all") || deathName.equalsIgnoreCase("animals") || deathName.equalsIgnoreCase("monsters")) {
thingsToKill.add(deathName.toUpperCase()); thingsToKill.add(deathName.toUpperCase());
@ -86,7 +86,7 @@ public class PurgeCommand extends MultiverseCommand {
Collections.addAll(thingsToKill, deathName.toUpperCase().split(",")); Collections.addAll(thingsToKill, deathName.toUpperCase().split(","));
} }
for (MultiverseWorld w : worldsToRemoveEntitiesFrom) { for (MultiverseWorld w : worldsToRemoveEntitiesFrom) {
purger.purgeWorld(sender, w, thingsToKill, false, false); purger.purgeWorld(w, thingsToKill, false, false, sender);
} }
} }
} }

View File

@ -8,9 +8,8 @@
package com.onarandombox.MultiverseCore.commands; package com.onarandombox.MultiverseCore.commands;
import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.utils.BlockSafety;
import com.onarandombox.MultiverseCore.utils.LocationManipulation;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
@ -56,7 +55,7 @@ public class SetSpawnCommand extends MultiverseCommand {
MultiverseWorld foundWorld = this.plugin.getMVWorldManager().getMVWorld(w.getName()); MultiverseWorld foundWorld = this.plugin.getMVWorldManager().getMVWorld(w.getName());
if (foundWorld != null) { if (foundWorld != null) {
foundWorld.setSpawnLocation(p.getLocation()); foundWorld.setSpawnLocation(p.getLocation());
BlockSafety bs = new BlockSafety(); BlockSafety bs = this.plugin.getBlockSafety();
if (!bs.playerCanSpawnHereSafely(p.getLocation()) && foundWorld.getAdjustSpawn()) { if (!bs.playerCanSpawnHereSafely(p.getLocation()) && foundWorld.getAdjustSpawn()) {
sender.sendMessage("It looks like that location would normally be unsafe. But I trust you."); sender.sendMessage("It looks like that location would normally be unsafe. But I trust you.");
sender.sendMessage("I'm turning off the Safe-T-Teleporter for spawns to this world."); sender.sendMessage("I'm turning off the Safe-T-Teleporter for spawns to this world.");
@ -64,7 +63,7 @@ public class SetSpawnCommand extends MultiverseCommand {
sender.sendMessage(ChatColor.AQUA + "/mvm set adjustspawn true " + foundWorld.getAlias()); sender.sendMessage(ChatColor.AQUA + "/mvm set adjustspawn true " + foundWorld.getAlias());
foundWorld.setAdjustSpawn(false); foundWorld.setAdjustSpawn(false);
} }
sender.sendMessage("Spawn was set to: " + LocationManipulation.strCoords(p.getLocation())); sender.sendMessage("Spawn was set to: " + plugin.getLocationManipulation().strCoords(p.getLocation()));
} else { } else {
w.setSpawnLocation(l.getBlockX(), l.getBlockY(), l.getBlockZ()); w.setSpawnLocation(l.getBlockX(), l.getBlockY(), l.getBlockZ());
sender.sendMessage("Multiverse does not know about this world, only X,Y and Z set. Please import it to set the spawn fully (Pitch/Yaws)."); sender.sendMessage("Multiverse does not know about this world, only X,Y and Z set. Please import it to set the spawn fully (Pitch/Yaws).");

View File

@ -85,6 +85,6 @@ public class SpawnCommand extends MultiverseCommand {
} else { } else {
spawnLocation = player.getWorld().getSpawnLocation(); spawnLocation = player.getWorld().getSpawnLocation();
} }
this.plugin.getTeleporter().safelyTeleport(player, player, spawnLocation, false); this.plugin.getSafeTTeleporter().safelyTeleport(player, player, spawnLocation, false);
} }
} }

View File

@ -14,8 +14,7 @@ import com.onarandombox.MultiverseCore.destination.InvalidDestination;
import com.onarandombox.MultiverseCore.destination.WorldDestination; import com.onarandombox.MultiverseCore.destination.WorldDestination;
import com.onarandombox.MultiverseCore.enums.TeleportResult; import com.onarandombox.MultiverseCore.enums.TeleportResult;
import com.onarandombox.MultiverseCore.event.MVTeleportEvent; import com.onarandombox.MultiverseCore.event.MVTeleportEvent;
import com.onarandombox.MultiverseCore.utils.LocationManipulation; import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.utils.SafeTTeleporter;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
@ -43,7 +42,7 @@ public class TeleportCommand extends MultiverseCommand {
this.setArgRange(1, 2); this.setArgRange(1, 2);
this.addKey("mvtp"); this.addKey("mvtp");
this.addKey("mv tp"); this.addKey("mv tp");
this.playerTeleporter = new SafeTTeleporter(this.plugin); this.playerTeleporter = this.plugin.getSafeTTeleporter();
this.setPermission(menu); this.setPermission(menu);
} }
@ -163,7 +162,8 @@ public class TeleportCommand extends MultiverseCommand {
} }
TeleportResult result = this.playerTeleporter.safelyTeleport(teleporter, teleportee, d); TeleportResult result = this.playerTeleporter.safelyTeleport(teleporter, teleportee, d);
if (result == TeleportResult.FAIL_UNSAFE) { if (result == TeleportResult.FAIL_UNSAFE) {
this.plugin.log(Level.FINE, "Could not teleport " + teleportee.getName() + " to " + LocationManipulation.strCoordsRaw(d.getLocation(teleportee))); this.plugin.log(Level.FINE, "Could not teleport " + teleportee.getName()
+ " to " + plugin.getLocationManipulation().strCoordsRaw(d.getLocation(teleportee)));
this.plugin.log(Level.FINE, "Queueing Command"); this.plugin.log(Level.FINE, "Queueing Command");
Class<?>[] paramTypes = { CommandSender.class, Player.class, Location.class }; Class<?>[] paramTypes = { CommandSender.class, Player.class, Location.class };
List<Object> items = new ArrayList<Object>(); List<Object> items = new ArrayList<Object>();

View File

@ -61,6 +61,7 @@ public class LocationConfigProperty implements MVActiveConfigProperty<Location>
*/ */
@Override @Override
public boolean parseValue(String value) { public boolean parseValue(String value) {
// TODO: oh my god, what should we do here?
Location parsed = LocationManipulation.stringToLocation(value); Location parsed = LocationManipulation.stringToLocation(value);
return this.setValue(parsed); return this.setValue(parsed);
} }
@ -108,6 +109,7 @@ public class LocationConfigProperty implements MVActiveConfigProperty<Location>
double yaw = this.section.getDouble(this.configNode + ".yaw", defaultValue.getYaw()); double yaw = this.section.getDouble(this.configNode + ".yaw", defaultValue.getYaw());
String w = this.section.getString(this.configNode + ".world", defaultValue.getWorld().getName()); String w = this.section.getString(this.configNode + ".world", defaultValue.getWorld().getName());
Location found = LocationManipulation.stringToLocation(w + ":" + x + "," + y + "," + z + ":" + yaw + ":" + pitch); Location found = LocationManipulation.stringToLocation(w + ":" + x + "," + y + "," + z + ":" + yaw + ":" + pitch);
// TODO: oh my god, what should we do here?
if (found != null) { if (found != null) {
return found; return found;
} }
@ -116,6 +118,7 @@ public class LocationConfigProperty implements MVActiveConfigProperty<Location>
@Override @Override
public String toString() { public String toString() {
// TODO: oh my god, what should we do here?
return LocationManipulation.strCoordsRaw(this.value); return LocationManipulation.strCoordsRaw(this.value);
} }

View File

@ -8,9 +8,9 @@
package com.onarandombox.MultiverseCore.destination; package com.onarandombox.MultiverseCore.destination;
import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.Core;
import com.onarandombox.MultiverseCore.api.MVDestination; import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.utils.LocationManipulation;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@ -93,6 +93,9 @@ public class WorldDestination implements MVDestination {
*/ */
@Override @Override
public void setDestination(JavaPlugin plugin, String destination) { public void setDestination(JavaPlugin plugin, String destination) {
// TODO Taking a JavaPlugin here is rather useless, if we keep casting it up to MultiverseCore.
// We should change that.
Core core = (Core) plugin;
String[] items = destination.split(":"); String[] items = destination.split(":");
if (items.length > 3) { if (items.length > 3) {
isValid = false; isValid = false;
@ -100,19 +103,20 @@ public class WorldDestination implements MVDestination {
} }
if (items.length == 1 && ((MultiverseCore) plugin).getMVWorldManager().isMVWorld(items[0])) { if (items.length == 1 && ((MultiverseCore) plugin).getMVWorldManager().isMVWorld(items[0])) {
isValid = true; isValid = true;
this.world = ((MultiverseCore) plugin).getMVWorldManager().getMVWorld(items[0]); this.world = core.getMVWorldManager().getMVWorld(items[0]);
return; return;
} }
if (items.length == 2 && ((MultiverseCore) plugin).getMVWorldManager().isMVWorld(items[0])) { if (items.length == 2 && ((MultiverseCore) plugin).getMVWorldManager().isMVWorld(items[0])) {
this.world = ((MultiverseCore) plugin).getMVWorldManager().getMVWorld(items[0]); this.world = core.getMVWorldManager().getMVWorld(items[0]);
this.yaw = LocationManipulation.getYaw(items[1]); this.yaw = core.getLocationManipulation().getYaw(items[1]);
return; return;
} }
if (items[0].equalsIgnoreCase("w") && ((MultiverseCore) plugin).getMVWorldManager().isMVWorld(items[1])) { if (items[0].equalsIgnoreCase("w") && ((MultiverseCore) plugin).getMVWorldManager().isMVWorld(items[1])) {
this.world = ((MultiverseCore) plugin).getMVWorldManager().getMVWorld(items[1]); this.world = ((MultiverseCore) plugin).getMVWorldManager().getMVWorld(items[1]);
isValid = true; isValid = true;
if (items.length == 3) { if (items.length == 3) {
this.yaw = LocationManipulation.getYaw(items[2]); // TODO: oh my god, what should we do here?
this.yaw = core.getLocationManipulation().getYaw(items[2]);
} }
} }
} }

View File

@ -8,6 +8,7 @@
package com.onarandombox.MultiverseCore.event; package com.onarandombox.MultiverseCore.event;
import com.onarandombox.MultiverseCore.api.MVDestination; import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;

View File

@ -12,7 +12,6 @@ import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.event.MVRespawnEvent; import com.onarandombox.MultiverseCore.event.MVRespawnEvent;
import com.onarandombox.MultiverseCore.utils.PermissionTools; import com.onarandombox.MultiverseCore.utils.PermissionTools;
import com.onarandombox.MultiverseCore.utils.SafeTTeleporter;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
@ -225,7 +224,7 @@ public class MVPlayerListener implements Listener {
// REMEMBER! getTo MAY be NULL HERE!!! // REMEMBER! getTo MAY be NULL HERE!!!
// If the player was actually outside of the portal, adjust the from location // If the player was actually outside of the portal, adjust the from location
if (event.getFrom().getWorld().getBlockAt(event.getFrom()).getType() != Material.PORTAL) { if (event.getFrom().getWorld().getBlockAt(event.getFrom()).getType() != Material.PORTAL) {
Location newloc = SafeTTeleporter.findPortalBlockNextTo(event.getFrom()); Location newloc = this.plugin.getSafeTTeleporter().findPortalBlockNextTo(event.getFrom());
// TODO: Fix this. Currently, we only check for PORTAL blocks. I'll have to figure out what // TODO: Fix this. Currently, we only check for PORTAL blocks. I'll have to figure out what
// TODO: we want to do here. // TODO: we want to do here.
if (newloc != null) { if (newloc != null) {

View File

@ -48,7 +48,7 @@ public class AnchorManager {
Set<String> anchorKeys = anchorsSection.getKeys(false); Set<String> anchorKeys = anchorsSection.getKeys(false);
for (String key : anchorKeys) { for (String key : anchorKeys) {
//world:x,y,z:pitch:yaw //world:x,y,z:pitch:yaw
Location anchorLocation = LocationManipulation.stringToLocation(anchorsSection.getString(key, "")); Location anchorLocation = plugin.getLocationManipulation().stringToLocation(anchorsSection.getString(key, ""));
if (anchorLocation != null) { if (anchorLocation != null) {
MultiverseCore.staticLog(Level.INFO, "Loading anchor: '" + key + "'..."); MultiverseCore.staticLog(Level.INFO, "Loading anchor: '" + key + "'...");
this.anchors.put(key, anchorLocation); this.anchors.put(key, anchorLocation);
@ -98,7 +98,7 @@ public class AnchorManager {
* @return True if the anchor was successfully saved. * @return True if the anchor was successfully saved.
*/ */
public boolean saveAnchorLocation(String anchor, String location) { public boolean saveAnchorLocation(String anchor, String location) {
Location parsed = LocationManipulation.stringToLocation(location); Location parsed = plugin.getLocationManipulation().stringToLocation(location);
return parsed != null && this.saveAnchorLocation(anchor, parsed); return parsed != null && this.saveAnchorLocation(anchor, parsed);
} }
@ -112,7 +112,7 @@ public class AnchorManager {
if (l == null) { if (l == null) {
return false; return false;
} }
this.anchorConfig.set("anchors." + anchor, LocationManipulation.locationToString(l)); this.anchorConfig.set("anchors." + anchor, plugin.getLocationManipulation().locationToString(l));
this.anchors.put(anchor, l); this.anchors.put(anchor, l);
return this.saveAnchors(); return this.saveAnchors();
} }

View File

@ -18,7 +18,10 @@ import java.util.logging.Level;
/** /**
* Used to determine block/location-related facts. * Used to determine block/location-related facts.
*
* @deprecated Use instead: {@link com.onarandombox.MultiverseCore.api.BlockSafety} and {@link SimpleBlockSafety}.
*/ */
@Deprecated
public class BlockSafety { public class BlockSafety {
/** /**

View File

@ -22,7 +22,10 @@ import java.util.Map;
/** /**
* Utility class to manipulate locations. * Utility class to manipulate locations.
*
* @deprecated Use instead: {@link com.onarandombox.MultiverseCore.api.LocationManipulation} and {@link SimpleLocationManipulation}.
*/ */
@Deprecated
public class LocationManipulation { public class LocationManipulation {
private LocationManipulation() { } private LocationManipulation() { }

View File

@ -10,14 +10,16 @@ package com.onarandombox.MultiverseCore.utils;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import com.onarandombox.MultiverseCore.api.MultiverseMessaging;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
* Utility-class for messaging. * The default-implementation of {@link MultiverseMessaging}.
*/ */
public class MVMessaging { public class MVMessaging implements MultiverseMessaging {
private Map<String, Long> sentList; private Map<String, Long> sentList;
private int cooldown; private int cooldown;
@ -27,35 +29,25 @@ public class MVMessaging {
} }
/** /**
* Sets the message-cooldown. * {@inheritDoc}
* @param milliseconds The new message-cooldown in milliseconds.
*/ */
@Override
public void setCooldown(int milliseconds) { public void setCooldown(int milliseconds) {
this.cooldown = milliseconds; this.cooldown = milliseconds;
} }
/** /**
* Sends a message to the specified sender if the cooldown has passed. * {@inheritDoc}
*
* @param sender The person/console to send the message to.
* @param message The message to send.
* @param ignoreCooldown If true this message will always be sent. Useful for things like menus
* @return true if the message was sent, false if not.
*/ */
@Override
public boolean sendMessage(CommandSender sender, String message, boolean ignoreCooldown) { public boolean sendMessage(CommandSender sender, String message, boolean ignoreCooldown) {
return this.sendMessages(sender, new String[]{ message }, ignoreCooldown); return this.sendMessages(sender, new String[]{ message }, ignoreCooldown);
} }
/** /**
* Sends a group of messages to the specified sender if the cooldown has passed. * {@inheritDoc}
* This method is needed, since sending many messages in quick succession would violate
* the cooldown.
*
* @param sender The person/console to send the message to.
* @param messages The messages to send.
* @param ignoreCooldown If true these messages will always be sent. Useful for things like menus
* @return true if the message was sent, false if not.
*/ */
@Override
public boolean sendMessages(CommandSender sender, String[] messages, boolean ignoreCooldown) { public boolean sendMessages(CommandSender sender, String[] messages, boolean ignoreCooldown) {
if (!(sender instanceof Player) || ignoreCooldown) { if (!(sender instanceof Player) || ignoreCooldown) {
@ -78,15 +70,9 @@ public class MVMessaging {
} }
/** /**
* Sends a group of messages to the specified sender if the cooldown has passed. * {@inheritDoc}
* This method is needed, since sending many messages in quick succession would violate
* the cooldown.
*
* @param sender The person/console to send the message to.
* @param messages The messages to send.
* @param ignoreCooldown If true these messages will always be sent. Useful for things like menus
* @return true if the message was sent, false if not.
*/ */
@Override
public boolean sendMessages(CommandSender sender, Collection<String> messages, boolean ignoreCooldown) { public boolean sendMessages(CommandSender sender, Collection<String> messages, boolean ignoreCooldown) {
return this.sendMessages(sender, messages.toArray(new String[0]), ignoreCooldown); return this.sendMessages(sender, messages.toArray(new String[0]), ignoreCooldown);
} }
@ -98,9 +84,9 @@ public class MVMessaging {
} }
/** /**
* Gets the message-cooldown. * {@inheritDoc}
* @return The message-cooldown.
*/ */
@Override
public int getCooldown() { public int getCooldown() {
return cooldown; return cooldown;
} }

View File

@ -9,6 +9,7 @@ package com.onarandombox.MultiverseCore.utils;
import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVDestination; import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.destination.CannonDestination; import com.onarandombox.MultiverseCore.destination.CannonDestination;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.TravelAgent; import org.bukkit.TravelAgent;
@ -106,7 +107,7 @@ public class MVTravelAgent implements TravelAgent {
if (this.destination instanceof CannonDestination) { if (this.destination instanceof CannonDestination) {
this.core.log(Level.FINE, "Using Stock TP method. This cannon will have 0 velocity"); this.core.log(Level.FINE, "Using Stock TP method. This cannon will have 0 velocity");
} }
SafeTTeleporter teleporter = new SafeTTeleporter(this.core); SafeTTeleporter teleporter = this.core.getSafeTTeleporter();
Location newLoc = this.destination.getLocation(this.player); Location newLoc = this.destination.getLocation(this.player);
if (this.destination.useSafeTeleporter()) { if (this.destination.useSafeTeleporter()) {
newLoc = teleporter.getSafeLocation(this.player, this.destination); newLoc = teleporter.getSafeLocation(this.player, this.destination);

View File

@ -9,6 +9,7 @@ package com.onarandombox.MultiverseCore.utils;
import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Animals; import org.bukkit.entity.Animals;
@ -25,7 +26,10 @@ import java.util.logging.Level;
/** /**
* Utility class that removes animals from worlds that don't belong there. * Utility class that removes animals from worlds that don't belong there.
*
* @deprecated Use instead: {@link WorldPurger} and {@link SimpleWorldPurger}.
*/ */
@Deprecated
public class PurgeWorlds { public class PurgeWorlds {
private MultiverseCore plugin; private MultiverseCore plugin;

View File

@ -8,9 +8,11 @@
package com.onarandombox.MultiverseCore.utils; package com.onarandombox.MultiverseCore.utils;
import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.MVDestination; import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.destination.InvalidDestination; import com.onarandombox.MultiverseCore.destination.InvalidDestination;
import com.onarandombox.MultiverseCore.enums.TeleportResult; import com.onarandombox.MultiverseCore.enums.TeleportResult;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -26,7 +28,10 @@ import java.util.logging.Level;
/** /**
* The {@link SafeTTeleporter}. * The {@link SafeTTeleporter}.
*
* @deprecated Use instead: {@link com.onarandombox.MultiverseCore.api.SafeTTeleporter} and {@link SimpleSafeTTeleporter}.
*/ */
@Deprecated
public class SafeTTeleporter { public class SafeTTeleporter {
private MultiverseCore plugin; private MultiverseCore plugin;
@ -34,7 +39,7 @@ public class SafeTTeleporter {
public SafeTTeleporter(MultiverseCore plugin) { public SafeTTeleporter(MultiverseCore plugin) {
this.plugin = plugin; this.plugin = plugin;
this.bs = new BlockSafety(); this.bs = plugin.getBlockSafety();
} }
private static final int DEFAULT_TOLERANCE = 6; private static final int DEFAULT_TOLERANCE = 6;
@ -63,7 +68,7 @@ public class SafeTTeleporter {
if (safe != null) { if (safe != null) {
safe.setX(safe.getBlockX() + .5); // SUPPRESS CHECKSTYLE: MagicNumberCheck safe.setX(safe.getBlockX() + .5); // SUPPRESS CHECKSTYLE: MagicNumberCheck
safe.setZ(safe.getBlockZ() + .5); // SUPPRESS CHECKSTYLE: MagicNumberCheck safe.setZ(safe.getBlockZ() + .5); // SUPPRESS CHECKSTYLE: MagicNumberCheck
this.plugin.log(Level.FINE, "Hey! I found one: " + LocationManipulation.strCoordsRaw(safe)); this.plugin.log(Level.FINE, "Hey! I found one: " + plugin.getLocationManipulation().strCoordsRaw(safe));
} else { } else {
this.plugin.log(Level.FINE, "Uh oh! No safe place found!"); this.plugin.log(Level.FINE, "Uh oh! No safe place found!");
} }
@ -77,7 +82,7 @@ public class SafeTTeleporter {
} }
// We want half of it, so we can go up and down // We want half of it, so we can go up and down
tolerance /= 2; tolerance /= 2;
this.plugin.log(Level.FINER, "Given Location of: " + LocationManipulation.strCoordsRaw(l)); this.plugin.log(Level.FINER, "Given Location of: " + plugin.getLocationManipulation().strCoordsRaw(l));
this.plugin.log(Level.FINER, "Checking +-" + tolerance + " with a radius of " + radius); this.plugin.log(Level.FINER, "Checking +-" + tolerance + " with a radius of " + radius);
// For now this will just do a straight up block. // For now this will just do a straight up block.

View File

@ -0,0 +1,254 @@
/******************************************************************************
* Multiverse 2 Copyright (c) the Multiverse Team 2011. *
* Multiverse 2 is licensed under the BSD License. *
* For more information please check the README.md file included *
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.utils;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.BlockSafety;
import com.onarandombox.MultiverseCore.api.Core;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Vehicle;
import java.util.logging.Level;
/**
* The default-implementation of {@link BlockSafety}.
*/
public class SimpleBlockSafety implements BlockSafety {
private final Core plugin;
public SimpleBlockSafety(Core plugin) {
this.plugin = plugin;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isBlockAboveAir(Location l) {
Location downOne = l.clone();
downOne.setY(downOne.getY() - 1);
return (downOne.getBlock().getType() == Material.AIR);
}
/**
* {@inheritDoc}
*/
@Override
public boolean playerCanSpawnHereSafely(World world, double x, double y, double z) {
Location l = new Location(world, x, y, z);
return playerCanSpawnHereSafely(l);
}
/**
* {@inheritDoc}
*/
@Override
public boolean playerCanSpawnHereSafely(Location l) {
if (l == null) {
// Can't safely spawn at a null location!
return false;
}
World world = l.getWorld();
Location actual = l.clone();
Location upOne = l.clone();
Location downOne = l.clone();
upOne.setY(upOne.getY() + 1);
downOne.setY(downOne.getY() - 1);
if (this.isSolidBlock(world.getBlockAt(actual).getType())
|| this.isSolidBlock(upOne.getBlock().getType())) {
MultiverseCore.staticLog(Level.FINER, "Error Here (Actual)? ("
+ actual.getBlock().getType() + ")[" + this.isSolidBlock(actual.getBlock().getType()) + "]");
MultiverseCore.staticLog(Level.FINER, "Error Here (upOne)? ("
+ upOne.getBlock().getType() + ")[" + this.isSolidBlock(upOne.getBlock().getType()) + "]");
return false;
}
if (downOne.getBlock().getType() == Material.LAVA || downOne.getBlock().getType() == Material.STATIONARY_LAVA) {
MultiverseCore.staticLog(Level.FINER, "Error Here (downOne)? ("
+ downOne.getBlock().getType() + ")[" + this.isSolidBlock(downOne.getBlock().getType()) + "]");
return false;
}
if (downOne.getBlock().getType() == Material.FIRE) {
MultiverseCore.staticLog(Level.FINER, "There's fire below! ("
+ actual.getBlock().getType() + ")[" + this.isSolidBlock(actual.getBlock().getType()) + "]");
return false;
}
if (isBlockAboveAir(actual)) {
MultiverseCore.staticLog(Level.FINER, "Is block above air [" + isBlockAboveAir(actual) + "]");
MultiverseCore.staticLog(Level.FINER, "Has 2 blocks of water below [" + this.hasTwoBlocksofWaterBelow(actual) + "]");
return this.hasTwoBlocksofWaterBelow(actual);
}
return true;
}
/**
* {@inheritDoc}
*/
@Override
public Location getTopBlock(Location l) {
Location check = l.clone();
check.setY(127); // SUPPRESS CHECKSTYLE: MagicNumberCheck
while (check.getY() > 0) {
if (this.playerCanSpawnHereSafely(check)) {
return check;
}
check.setY(check.getY() - 1);
}
return null;
}
/**
* {@inheritDoc}
*/
@Override
public Location getBottomBlock(Location l) {
Location check = l.clone();
check.setY(0);
while (check.getY() < 127) { // SUPPRESS CHECKSTYLE: MagicNumberCheck
if (this.playerCanSpawnHereSafely(check)) {
return check;
}
check.setY(check.getY() + 1);
}
return null;
}
/*
* If someone has a better way of this... Please either tell us, or submit a pull request!
*/
private boolean isSolidBlock(Material type) {
switch (type) {
case AIR:
return false;
case SNOW:
return false;
case TRAP_DOOR:
return false;
case TORCH:
return false;
case YELLOW_FLOWER:
return false;
case RED_ROSE:
return false;
case RED_MUSHROOM:
return false;
case BROWN_MUSHROOM:
return false;
case REDSTONE:
return false;
case REDSTONE_WIRE:
return false;
case RAILS:
return false;
case POWERED_RAIL:
return false;
case REDSTONE_TORCH_ON:
return false;
case REDSTONE_TORCH_OFF:
return false;
case DEAD_BUSH:
return false;
case SAPLING:
return false;
case STONE_BUTTON:
return false;
case LEVER:
return false;
case LONG_GRASS:
return false;
case PORTAL:
return false;
case STONE_PLATE:
return false;
case WOOD_PLATE:
return false;
case SEEDS:
return false;
case SUGAR_CANE_BLOCK:
return false;
case WALL_SIGN:
return false;
case SIGN_POST:
return false;
case WOODEN_DOOR:
return false;
case STATIONARY_WATER:
return false;
case WATER:
return false;
default:
return true;
}
}
/**
* {@inheritDoc}
*/
@Override
public boolean isEntitiyOnTrack(Location l) {
Material currentBlock = l.getBlock().getType();
return (currentBlock == Material.POWERED_RAIL || currentBlock == Material.DETECTOR_RAIL || currentBlock == Material.RAILS);
}
/**
* Checks recursively below a {@link Location} for 2 blocks of water.
*
* @param l The {@link Location}
* @return Whether there are 2 blocks of water
*/
private boolean hasTwoBlocksofWaterBelow(Location l) {
if (l.getBlockY() < 0) {
return false;
}
Location oneBelow = l.clone();
oneBelow.subtract(0, 1, 0);
if (oneBelow.getBlock().getType() == Material.WATER || oneBelow.getBlock().getType() == Material.STATIONARY_WATER) {
Location twoBelow = oneBelow.clone();
twoBelow.subtract(0, 1, 0);
return (oneBelow.getBlock().getType() == Material.WATER || oneBelow.getBlock().getType() == Material.STATIONARY_WATER);
}
if (oneBelow.getBlock().getType() != Material.AIR) {
return false;
}
return hasTwoBlocksofWaterBelow(oneBelow);
}
/**
* {@inheritDoc}
*/
@Override
public boolean canSpawnCartSafely(Minecart cart) {
if (this.isBlockAboveAir(cart.getLocation())) {
return true;
}
if (this.isEntitiyOnTrack(plugin.getLocationManipulation().getNextBlock(cart))) {
return true;
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public boolean canSpawnVehicleSafely(Vehicle vehicle) {
if (this.isBlockAboveAir(vehicle.getLocation())) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,251 @@
/******************************************************************************
* Multiverse 2 Copyright (c) the Multiverse Team 2011. *
* Multiverse 2 is licensed under the BSD License. *
* For more information please check the README.md file included *
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.utils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Vehicle;
import org.bukkit.util.Vector;
import com.onarandombox.MultiverseCore.api.LocationManipulation;
import java.text.DecimalFormat;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* The default-implementation of {@link LocationManipulation}.
*/
public class SimpleLocationManipulation implements LocationManipulation {
private static final Map<String, Integer> ORIENTATION_INTS;
static {
Map<String, Integer> orientationInts = new HashMap<String, Integer>();
// BEGIN CHECKSTYLE-SUPPRESSION: MagicNumberCheck
orientationInts.put("n", 180);
orientationInts.put("ne", 225);
orientationInts.put("e", 270);
orientationInts.put("se", 315);
orientationInts.put("s", 0);
orientationInts.put("sw", 45);
orientationInts.put("w", 90);
orientationInts.put("nw", 135);
// "freeze" the map:
ORIENTATION_INTS = Collections.unmodifiableMap(orientationInts);
// END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
}
/**
* {@inheritDoc}
*/
@Override
public String locationToString(Location location) {
if (location == null) {
return "";
}
return String.format("%s:%.2f,%.2f,%.2f:%.2f:%.2f", location.getWorld().getName(),
location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
}
/**
* {@inheritDoc}
*/
@Override
public Location getBlockLocation(Location l) {
l.setX(l.getBlockX());
l.setY(l.getBlockY());
l.setZ(l.getBlockZ());
return l;
}
/**
* {@inheritDoc}
*/
@Override
public Location stringToLocation(String locationString) {
//format:
//world:x,y,z:pitch:yaw
if (locationString == null) {
return null;
}
// Split the whole string, format is:
// {'world', 'x,y,z'[, 'pitch', 'yaw']}
String[] split = locationString.split(":");
if (split.length < 2 || split.length > 4) { // SUPPRESS CHECKSTYLE: MagicNumberCheck
return null;
}
// Split the xyz string, format is:
// {'x', 'y', 'z'}
String[] xyzsplit = split[1].split(",");
if (xyzsplit.length != 3) {
return null;
}
// Verify the world is valid
World w = Bukkit.getWorld(split[0]);
if (w == null) {
return null;
}
try {
float pitch = 0;
float yaw = 0;
if (split.length >= 3) {
yaw = (float) Double.parseDouble(split[2]);
}
if (split.length == 4) { // SUPPRESS CHECKSTYLE: MagicNumberCheck
pitch = (float) Double.parseDouble(split[3]);
}
return new Location(w, Double.parseDouble(xyzsplit[0]), Double.parseDouble(xyzsplit[1]), Double.parseDouble(xyzsplit[2]), yaw, pitch);
} catch (NumberFormatException e) {
return null;
}
}
/**
* {@inheritDoc}
*/
@Override
public String strCoords(Location l) {
String result = "";
DecimalFormat df = new DecimalFormat();
df.setMinimumFractionDigits(0);
df.setMaximumFractionDigits(2);
result += ChatColor.WHITE + "X: " + ChatColor.AQUA + df.format(l.getX()) + " ";
result += ChatColor.WHITE + "Y: " + ChatColor.AQUA + df.format(l.getY()) + " ";
result += ChatColor.WHITE + "Z: " + ChatColor.AQUA + df.format(l.getZ()) + " ";
result += ChatColor.WHITE + "P: " + ChatColor.GOLD + df.format(l.getPitch()) + " ";
result += ChatColor.WHITE + "Y: " + ChatColor.GOLD + df.format(l.getYaw()) + " ";
return result;
}
/**
* {@inheritDoc}
*/
@Override
public String strCoordsRaw(Location l) {
if (l == null) {
return "null";
}
String result = "";
DecimalFormat df = new DecimalFormat();
df.setMinimumFractionDigits(0);
df.setMaximumFractionDigits(2);
result += "X: " + df.format(l.getX()) + " ";
result += "Y: " + df.format(l.getY()) + " ";
result += "Z: " + df.format(l.getZ()) + " ";
result += "P: " + df.format(l.getPitch()) + " ";
result += "Y: " + df.format(l.getYaw()) + " ";
return result;
}
/**
* {@inheritDoc}
*/
@Override
public String getDirection(Location location) {
// BEGIN CHECKSTYLE-SUPPRESSION: MagicNumberCheck
double r = (location.getYaw() % 360) + 180;
// Remember, these numbers are every 45 degrees with a 22.5 offset, to detect boundaries.
String dir;
if (r < 22.5)
dir = "n";
else if (r < 67.5)
dir = "ne";
else if (r < 112.5)
dir = "e";
else if (r < 157.5)
dir = "se";
else if (r < 202.5)
dir = "s";
else if (r < 247.5)
dir = "sw";
else if (r < 292.5)
dir = "w";
else if (r < 337.5)
dir = "nw";
else
dir = "n";
// END CHECKSTYLE-SUPPRESSION: MagicNumberCheck
return dir;
}
/**
* {@inheritDoc}
*/
@Override
public float getYaw(String orientation) {
if (orientation == null) {
return 0;
}
if (ORIENTATION_INTS.containsKey(orientation.toLowerCase())) {
return ORIENTATION_INTS.get(orientation.toLowerCase());
}
return 0;
}
/**
* {@inheritDoc}
*/
@Override
public float getSpeed(Vector v) {
return (float) Math.sqrt(v.getX() * v.getX() + v.getZ() * v.getZ());
}
// X, Y, Z
// -W/+E,0, -N/+S
/**
* {@inheritDoc}
*/
@Override
public Vector getTranslatedVector(Vector v, String direction) {
if (direction == null) {
return v;
}
float speed = getSpeed(v);
float halfSpeed = (float) (speed / 2.0);
// TODO: Mathmatacize this:
if (direction.equalsIgnoreCase("n")) {
return new Vector(0, 0, -1 * speed);
} else if (direction.equalsIgnoreCase("ne")) {
return new Vector(halfSpeed, 0, -1 * halfSpeed);
} else if (direction.equalsIgnoreCase("e")) {
return new Vector(speed, 0, 0);
} else if (direction.equalsIgnoreCase("se")) {
return new Vector(halfSpeed, 0, halfSpeed);
} else if (direction.equalsIgnoreCase("s")) {
return new Vector(0, 0, speed);
} else if (direction.equalsIgnoreCase("sw")) {
return new Vector(-1 * halfSpeed, 0, halfSpeed);
} else if (direction.equalsIgnoreCase("w")) {
return new Vector(-1 * speed, 0, 0);
} else if (direction.equalsIgnoreCase("nw")) {
return new Vector(-1 * halfSpeed, 0, -1 * halfSpeed);
}
return v;
}
/**
* {@inheritDoc}
*/
@Override
public Location getNextBlock(Vehicle v) {
Vector vector = v.getVelocity();
Location location = v.getLocation();
int x = vector.getX() < 0 ? vector.getX() == 0 ? 0 : -1 : 1;
int z = vector.getZ() < 0 ? vector.getZ() == 0 ? 0 : -1 : 1;
return location.add(x, 0, z);
}
}

View File

@ -0,0 +1,334 @@
/******************************************************************************
* Multiverse 2 Copyright (c) the Multiverse Team 2011. *
* Multiverse 2 is licensed under the BSD License. *
* For more information please check the README.md file included *
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.utils;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.api.MVDestination;
import com.onarandombox.MultiverseCore.destination.InvalidDestination;
import com.onarandombox.MultiverseCore.enums.TeleportResult;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
import org.bukkit.util.Vector;
import java.util.logging.Level;
/**
* The default-implementation of {@link SafeTTeleporter}.
*/
public class SimpleSafeTTeleporter implements SafeTTeleporter {
private MultiverseCore plugin;
public SimpleSafeTTeleporter(MultiverseCore plugin) {
this.plugin = plugin;
}
private static final int DEFAULT_TOLERANCE = 6;
private static final int DEFAULT_RADIUS = 9;
/**
* {@inheritDoc}
*/
@Override
public Location getSafeLocation(Location l) {
return this.getSafeLocation(l, DEFAULT_TOLERANCE, DEFAULT_RADIUS);
}
/**
* {@inheritDoc}
*/
@Override
public Location getSafeLocation(Location l, int tolerance, int radius) {
// Check around the player first in a configurable radius:
// TODO: Make this configurable
Location safe = checkAboveAndBelowLocation(l, tolerance, radius);
if (safe != null) {
safe.setX(safe.getBlockX() + .5); // SUPPRESS CHECKSTYLE: MagicNumberCheck
safe.setZ(safe.getBlockZ() + .5); // SUPPRESS CHECKSTYLE: MagicNumberCheck
this.plugin.log(Level.FINE, "Hey! I found one: " + plugin.getLocationManipulation().strCoordsRaw(safe));
} else {
this.plugin.log(Level.FINE, "Uh oh! No safe place found!");
}
return safe;
}
private Location checkAboveAndBelowLocation(Location l, int tolerance, int radius) {
// Tolerance must be an even number:
if (tolerance % 2 != 0) {
tolerance += 1;
}
// We want half of it, so we can go up and down
tolerance /= 2;
this.plugin.log(Level.FINER, "Given Location of: " + plugin.getLocationManipulation().strCoordsRaw(l));
this.plugin.log(Level.FINER, "Checking +-" + tolerance + " with a radius of " + radius);
// For now this will just do a straight up block.
Location locToCheck = l.clone();
// Check the main level
Location safe = this.checkAroundLocation(locToCheck, radius);
if (safe != null) {
return safe;
}
// We've already checked zero right above this.
int currentLevel = 1;
while (currentLevel <= tolerance) {
// Check above
locToCheck = l.clone();
locToCheck.add(0, currentLevel, 0);
safe = this.checkAroundLocation(locToCheck, radius);
if (safe != null) {
return safe;
}
// Check below
locToCheck = l.clone();
locToCheck.subtract(0, currentLevel, 0);
safe = this.checkAroundLocation(locToCheck, radius);
if (safe != null) {
return safe;
}
currentLevel++;
}
return null;
}
/*
* For my crappy algorithm, radius MUST be odd.
*/
private Location checkAroundLocation(Location l, int diameter) {
if (diameter % 2 == 0) {
diameter += 1;
}
Location checkLoc = l.clone();
// Start at 3, the min diameter around a block
int loopcounter = 3;
while (loopcounter <= diameter) {
boolean foundSafeArea = checkAroundSpecificDiameter(checkLoc, loopcounter);
// If a safe area was found:
if (foundSafeArea) {
// Return the checkLoc, it is the safe location.
return checkLoc;
}
// Otherwise, let's reset our location
checkLoc = l.clone();
// And increment the radius
loopcounter += 2;
}
return null;
}
private boolean checkAroundSpecificDiameter(Location checkLoc, int circle) {
// Adjust the circle to get how many blocks to step out.
// A radius of 3 makes the block step 1
// A radius of 5 makes the block step 2
// A radius of 7 makes the block step 3
// ...
int adjustedCircle = ((circle - 1) / 2);
checkLoc.add(adjustedCircle, 0, 0);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
return true;
}
// Now we go to the right that adjustedCircle many
for (int i = 0; i < adjustedCircle; i++) {
checkLoc.add(0, 0, 1);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
// Then down adjustedCircle *2
for (int i = 0; i < adjustedCircle * 2; i++) {
checkLoc.add(-1, 0, 0);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
// Then left adjustedCircle *2
for (int i = 0; i < adjustedCircle * 2; i++) {
checkLoc.add(0, 0, -1);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
// Then up Then left adjustedCircle *2
for (int i = 0; i < adjustedCircle * 2; i++) {
checkLoc.add(1, 0, 0);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
// Then finish up by doing adjustedCircle - 1
for (int i = 0; i < adjustedCircle - 1; i++) {
checkLoc.add(0, 0, 1);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(checkLoc)) {
return true;
}
}
return false;
}
/**
* {@inheritDoc}
*/
@Override
public TeleportResult safelyTeleport(CommandSender teleporter, Entity teleportee, MVDestination d) {
if (d instanceof InvalidDestination) {
this.plugin.log(Level.FINER, "Entity tried to teleport to an invalid destination");
return TeleportResult.FAIL_INVALID;
}
Player teleporteePlayer = null;
if (teleportee instanceof Player) {
teleporteePlayer = ((Player) teleportee);
} else if (teleportee.getPassenger() instanceof Player) {
teleporteePlayer = ((Player) teleportee.getPassenger());
}
if (teleporteePlayer == null) {
return TeleportResult.FAIL_INVALID;
}
MultiverseCore.addPlayerToTeleportQueue(teleporter.getName(), teleporteePlayer.getName());
Location safeLoc = d.getLocation(teleportee);
if (d.useSafeTeleporter()) {
safeLoc = this.getSafeLocation(teleportee, d);
}
if (safeLoc != null) {
if (teleportee.teleport(safeLoc)) {
if (!d.getVelocity().equals(new Vector(0, 0, 0))) {
teleportee.setVelocity(d.getVelocity());
}
return TeleportResult.SUCCESS;
}
return TeleportResult.FAIL_OTHER;
}
return TeleportResult.FAIL_UNSAFE;
}
/**
* {@inheritDoc}
*/
@Override
public TeleportResult safelyTeleport(CommandSender teleporter, Entity teleportee, Location location, boolean safely) {
if (safely) {
location = this.getSafeLocation(location);
}
if (location != null) {
if (teleportee.teleport(location)) {
return TeleportResult.SUCCESS;
}
return TeleportResult.FAIL_OTHER;
}
return TeleportResult.FAIL_UNSAFE;
}
/**
* {@inheritDoc}
*/
@Override
public Location getSafeLocation(Entity e, MVDestination d) {
Location l = d.getLocation(e);
if (plugin.getBlockSafety().playerCanSpawnHereSafely(l)) {
plugin.log(Level.FINE, "The first location you gave me was safe.");
return l;
}
if (e instanceof Minecart) {
Minecart m = (Minecart) e;
if (!plugin.getBlockSafety().canSpawnCartSafely(m)) {
return null;
}
} else if (e instanceof Vehicle) {
Vehicle v = (Vehicle) e;
if (!plugin.getBlockSafety().canSpawnVehicleSafely(v)) {
return null;
}
}
Location safeLocation = this.getSafeLocation(l);
if (safeLocation != null) {
// Add offset to account for a vehicle on dry land!
if (e instanceof Minecart && !plugin.getBlockSafety().isEntitiyOnTrack(safeLocation)) {
safeLocation.setY(safeLocation.getBlockY() + .5);
this.plugin.log(Level.FINER, "Player was inside a minecart. Offsetting Y location.");
}
this.plugin.log(Level.FINE, "Had to look for a bit, but I found a safe place for ya!");
return safeLocation;
}
if (e instanceof Player) {
Player p = (Player) e;
this.plugin.getMessaging().sendMessage(p, "No safe locations found!", false);
this.plugin.log(Level.FINER, "No safe location found for " + p.getName());
} else if (e.getPassenger() instanceof Player) {
Player p = (Player) e.getPassenger();
this.plugin.getMessaging().sendMessage(p, "No safe locations found!", false);
this.plugin.log(Level.FINER, "No safe location found for " + p.getName());
}
this.plugin.log(Level.FINE, "Sorry champ, you're basically trying to teleport into a minefield. I should just kill you now.");
return null;
}
/**
* {@inheritDoc}
*/
@Override
public Location findPortalBlockNextTo(Location l) {
Block b = l.getWorld().getBlockAt(l);
Location foundLocation = null;
if (b.getType() == Material.PORTAL) {
return l;
}
if (b.getRelative(BlockFace.NORTH).getType() == Material.PORTAL) {
foundLocation = getCloserBlock(l, b.getRelative(BlockFace.NORTH).getLocation(), foundLocation);
}
if (b.getRelative(BlockFace.SOUTH).getType() == Material.PORTAL) {
foundLocation = getCloserBlock(l, b.getRelative(BlockFace.SOUTH).getLocation(), foundLocation);
}
if (b.getRelative(BlockFace.EAST).getType() == Material.PORTAL) {
foundLocation = getCloserBlock(l, b.getRelative(BlockFace.EAST).getLocation(), foundLocation);
}
if (b.getRelative(BlockFace.WEST).getType() == Material.PORTAL) {
foundLocation = getCloserBlock(l, b.getRelative(BlockFace.WEST).getLocation(), foundLocation);
}
return foundLocation;
}
private static Location getCloserBlock(Location source, Location blockA, Location blockB) {
// If B wasn't given, return a.
if (blockB == null) {
return blockA;
}
// Center our calculations
blockA.add(.5, 0, .5);
blockB.add(.5, 0, .5);
// Retrieve the distance to the normalized blocks
double testA = source.distance(blockA);
double testB = source.distance(blockB);
// Compare and return
if (testA <= testB) {
return blockA;
}
return blockB;
}
}

View File

@ -0,0 +1,153 @@
/******************************************************************************
* Multiverse 2 Copyright (c) the Multiverse Team 2011. *
* Multiverse 2 is licensed under the BSD License. *
* For more information please check the README.md file included *
* with this project. *
******************************************************************************/
package com.onarandombox.MultiverseCore.utils;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.api.WorldPurger;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Animals;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Ghast;
import org.bukkit.entity.Monster;
import org.bukkit.entity.Slime;
import org.bukkit.entity.Squid;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
/**
* Utility class that removes animals from worlds that don't belong there.
*/
public class SimpleWorldPurger implements WorldPurger {
private MultiverseCore plugin;
public SimpleWorldPurger(MultiverseCore plugin) {
this.plugin = plugin;
}
/**
* {@inheritDoc}
*/
@Override
public void purgeWorlds(List<MultiverseWorld> worlds) {
if (worlds == null || worlds.isEmpty()) {
return;
}
for (MultiverseWorld world : worlds) {
this.purgeWorld(world);
}
}
/**
* {@inheritDoc}
*/
@Override
public void purgeWorld(MultiverseWorld world) {
if (world == null) {
return;
}
ArrayList<String> allMobs = new ArrayList<String>(world.getAnimalList());
allMobs.addAll(world.getMonsterList());
purgeWorld(world, allMobs, !world.canAnimalsSpawn(), !world.canMonstersSpawn());
}
/**
* {@inheritDoc}
*/
@Override
public void purgeWorld(MultiverseWorld mvworld, List<String> thingsToKill,
boolean negateAnimals, boolean negateMonsters, CommandSender sender) {
if (mvworld == null) {
return;
}
World world = this.plugin.getServer().getWorld(mvworld.getName());
if (world == null) {
return;
}
int entitiesKilled = 0;
for (Entity e : world.getEntities()) {
this.plugin.log(Level.FINEST, "Entity list (aval for purge) from WORLD < " + mvworld.getName() + " >: " + e.toString());
// Check against Monsters
if (killMonster(mvworld, e, thingsToKill, negateMonsters)) {
entitiesKilled++;
continue;
}
// Check against Animals
if (this.killCreature(mvworld, e, thingsToKill, negateAnimals)) {
entitiesKilled++;
}
}
if (sender != null) {
sender.sendMessage(entitiesKilled + " entities purged from the world '" + world.getName() + "'");
}
}
/**
* {@inheritDoc}
*/
@Override
public void purgeWorld(MultiverseWorld mvworld, List<String> thingsToKill, boolean negateAnimals, boolean negateMonsters) {
purgeWorld(mvworld, thingsToKill, negateAnimals, negateMonsters, null);
}
private boolean killCreature(MultiverseWorld mvworld, Entity e, List<String> creaturesToKill, boolean negate) {
String entityName = e.toString().replaceAll("Craft", "").toUpperCase();
if (e instanceof Squid || e instanceof Animals) {
if (creaturesToKill.contains(entityName) || creaturesToKill.contains("ALL") || creaturesToKill.contains("ANIMALS")) {
if (!negate) {
e.remove();
return true;
}
} else {
if (negate) {
e.remove();
return true;
}
}
}
return false;
}
/*
* Will kill the monster if it's in the list UNLESS the NEGATE boolean is set, then it will kill it if it's NOT.
*/
private boolean killMonster(MultiverseWorld mvworld, Entity e, List<String> creaturesToKill, boolean negate) {
String entityName = "";
//TODO: Fixme once either Rigby puts his awesome thing in OR Enderdragon gets a toString, OR both.
if (e instanceof EnderDragon) {
entityName = "ENDERDRAGON";
} else {
entityName = e.toString().replaceAll("Craft", "").toUpperCase();
}
if (e instanceof Slime || e instanceof Monster || e instanceof Ghast || e instanceof EnderDragon) {
this.plugin.log(Level.FINER, "Looking at a monster: " + e);
if (creaturesToKill.contains(entityName) || creaturesToKill.contains("ALL") || creaturesToKill.contains("MONSTERS")) {
if (!negate) {
this.plugin.log(Level.FINEST, "Removing a monster: " + e);
e.remove();
return true;
}
} else {
if (negate) {
this.plugin.log(Level.FINEST, "Removing a monster: " + e);
e.remove();
return true;
}
}
}
return false;
}
}

View File

@ -11,6 +11,8 @@ import com.onarandombox.MultiverseCore.MVWorld;
import com.onarandombox.MultiverseCore.MultiverseCore; import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorldManager; import com.onarandombox.MultiverseCore.api.MVWorldManager;
import com.onarandombox.MultiverseCore.api.MultiverseWorld; import com.onarandombox.MultiverseCore.api.MultiverseWorld;
import com.onarandombox.MultiverseCore.api.SafeTTeleporter;
import com.onarandombox.MultiverseCore.api.WorldPurger;
import com.onarandombox.MultiverseCore.commands.EnvironmentCommand; import com.onarandombox.MultiverseCore.commands.EnvironmentCommand;
import com.onarandombox.MultiverseCore.event.MVWorldDeleteEvent; import com.onarandombox.MultiverseCore.event.MVWorldDeleteEvent;
import org.bukkit.World; import org.bukkit.World;
@ -41,7 +43,7 @@ import java.util.logging.Level;
*/ */
public class WorldManager implements MVWorldManager { public class WorldManager implements MVWorldManager {
private MultiverseCore plugin; private MultiverseCore plugin;
private PurgeWorlds worldPurger; private WorldPurger worldPurger;
private Map<String, MultiverseWorld> worlds; private Map<String, MultiverseWorld> worlds;
private List<String> unloadedWorlds; private List<String> unloadedWorlds;
private FileConfiguration configWorlds = null; private FileConfiguration configWorlds = null;
@ -52,7 +54,7 @@ public class WorldManager implements MVWorldManager {
this.plugin = core; this.plugin = core;
this.worlds = new HashMap<String, MultiverseWorld>(); this.worlds = new HashMap<String, MultiverseWorld>();
this.unloadedWorlds = new ArrayList<String>(); this.unloadedWorlds = new ArrayList<String>();
this.worldPurger = new PurgeWorlds(this.plugin); this.worldPurger = new SimpleWorldPurger(plugin);
} }
/** /**
@ -139,7 +141,7 @@ public class WorldManager implements MVWorldManager {
MultiverseWorld mvworld = new MVWorld(world, this.configWorlds, this.plugin, MultiverseWorld mvworld = new MVWorld(world, this.configWorlds, this.plugin,
this.plugin.getServer().getWorld(name).getSeed(), generator, useSpawnAdjust); this.plugin.getServer().getWorld(name).getSeed(), generator, useSpawnAdjust);
this.worldPurger.purgeWorld(null, mvworld); this.worldPurger.purgeWorld(mvworld);
this.worlds.put(name, mvworld); this.worlds.put(name, mvworld);
if (this.unloadedWorlds.contains(name)) { if (this.unloadedWorlds.contains(name)) {
this.unloadedWorlds.remove(name); this.unloadedWorlds.remove(name);
@ -371,7 +373,7 @@ public class WorldManager implements MVWorldManager {
if (w != null) { if (w != null) {
World safeWorld = this.plugin.getServer().getWorlds().get(0); World safeWorld = this.plugin.getServer().getWorlds().get(0);
List<Player> ps = w.getPlayers(); List<Player> ps = w.getPlayers();
SafeTTeleporter teleporter = this.plugin.getTeleporter(); SafeTTeleporter teleporter = this.plugin.getSafeTTeleporter();
for (Player p : ps) { for (Player p : ps) {
// We're removing players forcefully from a world, they'd BETTER spawn safely. // We're removing players forcefully from a world, they'd BETTER spawn safely.
teleporter.safelyTeleport(null, p, safeWorld.getSpawnLocation(), true); teleporter.safelyTeleport(null, p, safeWorld.getSpawnLocation(), true);
@ -575,10 +577,20 @@ public class WorldManager implements MVWorldManager {
/** /**
* {@inheritDoc} * {@inheritDoc}
* @deprecated This is deprecated!
*/ */
@Override @Override
@Deprecated
public PurgeWorlds getWorldPurger() { public PurgeWorlds getWorldPurger() {
return this.worldPurger; return new PurgeWorlds(plugin);
}
/**
* {@inheritDoc}
*/
@Override
public WorldPurger getTheWorldPurger() {
return worldPurger;
} }
/** /**