Merge branch 'project-cosmetics' of https://github.com/Mineplex-LLC/Minecraft-PC into project-cosmetics
This commit is contained in:
commit
e52ff13712
@ -0,0 +1,111 @@
|
||||
package mineplex.core.common.util;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionStage;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Utilities for interleaving Bukkit scheduler operations as
|
||||
* intermediate and terminal operations in a {@link CompletionStage}
|
||||
* pipeline.
|
||||
* <p>
|
||||
* Any {@link Function}s returned by methods are suitable for use
|
||||
* in {@link CompletionStage#thenCompose(Function)}
|
||||
*
|
||||
* @see CompletableFuture#thenCompose(Function)
|
||||
*/
|
||||
public class BukkitFuture
|
||||
{
|
||||
private static final Plugin LOADING_PLUGIN = JavaPlugin.getProvidingPlugin(BukkitFuture.class);
|
||||
|
||||
private static void runBlocking(Runnable action)
|
||||
{
|
||||
Bukkit.getScheduler().runTask(LOADING_PLUGIN, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize a {@link CompletionStage} by consuming its value
|
||||
* on the main thread.
|
||||
*
|
||||
* @param action the {@link Consumer} to call on the main thread
|
||||
* @return a {@link Function} to be passed as an argument to
|
||||
* {@link CompletionStage#thenCompose(Function)}
|
||||
* @see CompletableFuture#thenCompose(Function)
|
||||
*/
|
||||
public static <T> Function<T, CompletionStage<Void>> accept(Consumer<? super T> action)
|
||||
{
|
||||
return val ->
|
||||
{
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
runBlocking(() ->
|
||||
{
|
||||
action.accept(val);
|
||||
future.complete(null);
|
||||
});
|
||||
return future;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize a {@link CompletionStage} by executing code on the
|
||||
* main thread after its completion.
|
||||
*
|
||||
* @param action the {@link Runnable} that will execute
|
||||
* @return a {@link Function} to be passed as an argument to
|
||||
* {@link CompletionStage#thenCompose(Function)}
|
||||
* @see CompletableFuture#thenCompose(Function)
|
||||
*/
|
||||
public static <T> Function<T, CompletionStage<Void>> run(Runnable action)
|
||||
{
|
||||
return val ->
|
||||
{
|
||||
CompletableFuture<Void> future = new CompletableFuture<>();
|
||||
runBlocking(() ->
|
||||
{
|
||||
action.run();
|
||||
future.complete(null);
|
||||
});
|
||||
return future;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a value contained within a {@link CompletionStage}
|
||||
* by executing a mapping {@link Function} on the main thread.
|
||||
*
|
||||
* @param fn the {@link Function} used to transform the value
|
||||
* @return a {@link Function} to be passed as an argument to
|
||||
* {@link CompletionStage#thenCompose(Function)}
|
||||
* @see CompletableFuture#thenCompose(Function)
|
||||
*/
|
||||
public static <T,U> Function<T, CompletionStage<U>> map(Function<? super T,? extends U> fn)
|
||||
{
|
||||
return val ->
|
||||
{
|
||||
CompletableFuture<U> future = new CompletableFuture<>();
|
||||
runBlocking(() -> future.complete(fn.apply(val)));
|
||||
return future;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link CompletionStage} from a supplier executed on the
|
||||
* main thread.
|
||||
*
|
||||
* @param supplier the supplier to run on the main thread
|
||||
* @return a {@link CompletionStage} whose value will be supplied
|
||||
* during the next Minecraft tick
|
||||
*/
|
||||
public static <T> CompletionStage<T> supply(Supplier<T> supplier)
|
||||
{
|
||||
CompletableFuture<T> future = new CompletableFuture<>();
|
||||
runBlocking(() -> future.complete(supplier.get()));
|
||||
return future;
|
||||
}
|
||||
}
|
@ -10,6 +10,8 @@ import org.bukkit.World.Environment;
|
||||
import org.bukkit.WorldBorder;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftEntity;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
@ -28,7 +30,12 @@ public class UtilWorld
|
||||
if (chunk == null)
|
||||
return "";
|
||||
|
||||
return chunk.getWorld().getName() + "," + chunk.getX() + "," + chunk.getZ();
|
||||
return chunkToStr(chunk.getWorld().getName(), chunk.getX(), chunk.getZ());
|
||||
}
|
||||
|
||||
public static String chunkToStr(String world, int x, int z)
|
||||
{
|
||||
return world + "," + x + "," + z;
|
||||
}
|
||||
|
||||
public static String chunkToStrClean(Chunk chunk)
|
||||
@ -289,4 +296,15 @@ public class UtilWorld
|
||||
return startX >= minX && startZ <= maxX && endX >= minZ && endZ <= maxZ;
|
||||
}
|
||||
|
||||
public static double distanceSquared(Entity a, Entity b)
|
||||
{
|
||||
if (a.getWorld() != b.getWorld())
|
||||
throw new IllegalArgumentException("Different worlds: " + a.getWorld().getName() + " and " + b.getWorld().getName());
|
||||
net.minecraft.server.v1_8_R3.Entity entityA = ((CraftEntity) a).getHandle();
|
||||
net.minecraft.server.v1_8_R3.Entity entityB = ((CraftEntity) b).getHandle();
|
||||
double dx = entityA.locX - entityB.locX;
|
||||
double dy = entityA.locY - entityB.locY;
|
||||
double dz = entityA.locZ - entityB.locZ;
|
||||
return (dx * dx) + (dy * dy) + (dz * dz);
|
||||
}
|
||||
}
|
||||
|
@ -491,7 +491,7 @@ public class CoreClientManager extends MiniPlugin
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void Quit(PlayerQuitEvent event)
|
||||
{
|
||||
// When an account is logged in to this server and the same account name logs in
|
||||
|
@ -103,6 +103,11 @@ public class Creature extends MiniPlugin
|
||||
event.setDroppedExp(0);
|
||||
List<ItemStack> drops = event.getDrops();
|
||||
|
||||
if (event.getEntity().hasMetadata("Creature.DoNotDrop"))
|
||||
{
|
||||
drops.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getEntityType() == EntityType.PLAYER)
|
||||
drops.add(ItemStackFactory.Instance.CreateStack(Material.BONE, 1));
|
||||
|
@ -0,0 +1,291 @@
|
||||
package mineplex.core.database;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import mineplex.serverdata.database.DBPool;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* A SQL-backed repository supporting {@link String} keys and
|
||||
* values of type {@link V}
|
||||
* <p>
|
||||
* Each java primitive (sans char) and String are supported by default.
|
||||
* Serializing functions for any additional types can be supplied
|
||||
* to {@link PlayerKeyValueRepository(String, Serializer, Deserializer)}.
|
||||
* For example, if {@link String} was not supported, one could use:
|
||||
* <p>
|
||||
* {@code new PlayerKeyValueRepository("tableName", PreparedStatement::setString, ResultSet::getString, "VARCHAR(255)")}
|
||||
* <p>
|
||||
* NOTE: EACH CONSTRUCTOR IS BLOCKING, and initializes a backing table
|
||||
* if one does not yet exist
|
||||
*
|
||||
* @param <V> The value type to use for this repository
|
||||
*/
|
||||
public class PlayerKeyValueRepository<V>
|
||||
{
|
||||
private static final ImmutableMap<Class<?>, ValueMapper<?>> PRIM_MAPPERS = ImmutableMap.<Class<?>, ValueMapper<?>>builder()
|
||||
.put(String.class, new ValueMapper<>(PreparedStatement::setString, ResultSet::getString, "VARCHAR(255)"))
|
||||
.put(Boolean.class, new ValueMapper<>(PreparedStatement::setBoolean, ResultSet::getBoolean, "BOOL"))
|
||||
.put(Byte.class, new ValueMapper<>(PreparedStatement::setByte, ResultSet::getByte, "TINYINT"))
|
||||
.put(Short.class, new ValueMapper<>(PreparedStatement::setShort, ResultSet::getShort, "SMALLINT"))
|
||||
.put(Integer.class, new ValueMapper<>(PreparedStatement::setInt, ResultSet::getInt, "INTEGER"))
|
||||
.put(Long.class, new ValueMapper<>(PreparedStatement::setLong, ResultSet::getLong, "BIGINT"))
|
||||
.put(Float.class, new ValueMapper<>(PreparedStatement::setFloat, ResultSet::getFloat, "REAL"))
|
||||
.put(Double.class, new ValueMapper<>(PreparedStatement::setDouble, ResultSet::getDouble, "DOUBLE"))
|
||||
.build();
|
||||
private final String _tableName;
|
||||
private final ValueMapper<V> _mapper;
|
||||
|
||||
/**
|
||||
* Build a PlayerKeyValueRepository with the given class'
|
||||
* built-in deserializer.
|
||||
*
|
||||
* @param tableName the underlying table's name
|
||||
* @param clazz the type of values to used
|
||||
* @throws IllegalArgumentException if the provided class isn't a supported type
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // java's generics are garbage.
|
||||
public PlayerKeyValueRepository(String tableName, Class<V> clazz) // we could infer the type parameter at runtime, but it's super ugly
|
||||
{
|
||||
this(tableName, (ValueMapper<V>) PRIM_MAPPERS.get(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a PlayerKeyValueRepository with an explicit deserializer.
|
||||
* This is the constructor to use if the type you're deserializing
|
||||
* isn't supported by default.
|
||||
*
|
||||
* @param tableName the underlying table's name
|
||||
* @param serializer the serializing function used to insert values
|
||||
* @param deserializer the deserializing function used to retrieve
|
||||
* values
|
||||
* @param columnDef the value type's SQL datatype declaration, e.g., {@code "VARCHAR(255)"} for Strings.
|
||||
*/
|
||||
public PlayerKeyValueRepository(String tableName, Serializer<V> serializer, Deserializer<V> deserializer, String columnDef)
|
||||
{
|
||||
this(tableName, new ValueMapper<V>(serializer, deserializer, columnDef));
|
||||
}
|
||||
|
||||
private PlayerKeyValueRepository(String tableName, ValueMapper<V> mapper)
|
||||
{
|
||||
this._tableName = tableName;
|
||||
this._mapper = mapper;
|
||||
|
||||
// Create a table to back this repository
|
||||
try (Connection conn = DBPool.getAccount().getConnection())
|
||||
{
|
||||
Statement stmt = conn.createStatement();
|
||||
stmt.executeUpdate("CREATE TABLE IF NOT EXISTS " + _tableName + "("
|
||||
+ "accountId INT NOT NULL,"
|
||||
+ "kvKey VARCHAR(255) NOT NULL,"
|
||||
+ "kvValue " + _mapper._columnDef + ","
|
||||
+ "PRIMARY KEY (accountId,kvKey),"
|
||||
+ "INDEX acc_ind (accountId),"
|
||||
+ "FOREIGN KEY (accountId) REFERENCES accounts(id) ON DELETE NO ACTION ON UPDATE NO ACTION"
|
||||
+ ")");
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all value for a player's key
|
||||
*
|
||||
* @param uuid the {@link UUID} of the player
|
||||
* @return a CompletableFuture containing all key/value pairs
|
||||
* associated with the player
|
||||
*/
|
||||
public CompletableFuture<V> get(UUID uuid, String key)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection conn = DBPool.getAccount().getConnection())
|
||||
{
|
||||
PreparedStatement stmt = conn.prepareStatement("SELECT kvValue FROM " + _tableName + " WHERE accountId = (SELECT id FROM accounts WHERE uuid=?) AND kvKey=?");
|
||||
stmt.setString(1, uuid.toString());
|
||||
stmt.setString(2, key);
|
||||
|
||||
ResultSet set = stmt.executeQuery();
|
||||
if (set.next())
|
||||
{
|
||||
return _mapper._deserializer.read(set, 1);
|
||||
}
|
||||
return null;
|
||||
} catch (SQLException ignored) {}
|
||||
|
||||
return null; // yuck
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all key/value pairs for a player
|
||||
*
|
||||
* @param uuid the {@link UUID} of the player
|
||||
* @return a CompletableFuture containing all key/value pairs
|
||||
* associated with the player
|
||||
*/
|
||||
public CompletableFuture<Map<String,V>> getAll(UUID uuid)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection conn = DBPool.getAccount().getConnection())
|
||||
{
|
||||
PreparedStatement stmt = conn.prepareStatement("SELECT kvKey, kvValue FROM " + _tableName + " WHERE accountId = (SELECT id FROM accounts WHERE uuid=?)");
|
||||
stmt.setString(1, uuid.toString());
|
||||
|
||||
ResultSet set = stmt.executeQuery();
|
||||
Map<String, V> results = new HashMap<>();
|
||||
while (set.next())
|
||||
{
|
||||
results.put(set.getString(1), _mapper._deserializer.read(set, 2));
|
||||
}
|
||||
return results;
|
||||
} catch (SQLException ignored) {}
|
||||
|
||||
return new HashMap<>(); // yuck
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a key/value pair for a player
|
||||
*
|
||||
* @param uuid the {@link UUID} of the player
|
||||
* @param key the key to insert
|
||||
* @param value the value to insert
|
||||
* @return a {@link CompletableFuture} whose value indicates
|
||||
* success or failure
|
||||
*/
|
||||
public CompletableFuture<Boolean> put(UUID uuid, String key, V value)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection conn = DBPool.getAccount().getConnection())
|
||||
{
|
||||
PreparedStatement stmt = conn.prepareStatement("REPLACE INTO " + _tableName + " (accountId, kvKey, kvValue) SELECT accounts.id, ?, ? FROM accounts WHERE uuid=?");
|
||||
stmt.setString(1, key);
|
||||
_mapper._serializer.write(stmt, 2, value);
|
||||
stmt.setString(3, uuid.toString());
|
||||
stmt.executeUpdate();
|
||||
return true;
|
||||
|
||||
} catch (SQLException ignored) {}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert many key/value pairs for a player
|
||||
*
|
||||
* @param uuid the {@link UUID} of the player
|
||||
* @param values the map whose entries will be inserted for the
|
||||
* player
|
||||
* @return a {@link CompletableFuture} whose value indicates
|
||||
* success or failure
|
||||
*/
|
||||
public CompletableFuture<Boolean> putAll(UUID uuid, Map<String,V> values)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection conn = DBPool.getAccount().getConnection())
|
||||
{
|
||||
PreparedStatement stmt = conn.prepareStatement("REPLACE INTO " + _tableName + " (accountId, kvKey, kvValue) SELECT accounts.id, ?, ? FROM accounts WHERE uuid=?");
|
||||
stmt.setString(3, uuid.toString());
|
||||
|
||||
for (Map.Entry<String, V> entry : values.entrySet())
|
||||
{
|
||||
stmt.setString(1, entry.getKey());
|
||||
_mapper._serializer.write(stmt, 2, entry.getValue());
|
||||
stmt.addBatch();
|
||||
}
|
||||
stmt.executeBatch();
|
||||
return true;
|
||||
|
||||
} catch (SQLException ignored) {}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a key's value for a player
|
||||
*
|
||||
* @param uuid the {@link UUID} of the player
|
||||
* @param key the key to remove
|
||||
* @return a {@link CompletableFuture} whose value indicates
|
||||
* success or failure
|
||||
*/
|
||||
public CompletableFuture<Boolean> remove(UUID uuid, String key)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection conn = DBPool.getAccount().getConnection())
|
||||
{
|
||||
PreparedStatement stmt = conn.prepareStatement("DELETE FROM " + _tableName + " WHERE accountId=(SELECT id FROM accounts WHERE uuid=?) AND kvKey=?");
|
||||
stmt.setString(1, uuid.toString());
|
||||
stmt.setString(2, key);
|
||||
stmt.executeUpdate();
|
||||
return true;
|
||||
|
||||
} catch (SQLException ignored) {}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all key/value pairs for a player
|
||||
*
|
||||
* @param uuid the {@link UUID} of the player
|
||||
* @return a {@link CompletableFuture} whose value indicates
|
||||
* success or failure
|
||||
*/
|
||||
public CompletableFuture<Boolean> removeAll(UUID uuid)
|
||||
{
|
||||
return CompletableFuture.supplyAsync(() ->
|
||||
{
|
||||
try (Connection conn = DBPool.getAccount().getConnection())
|
||||
{
|
||||
PreparedStatement stmt = conn.prepareStatement("DELETE FROM " + _tableName + " WHERE accountId=(SELECT id FROM accounts WHERE uuid=?)");
|
||||
stmt.setString(1, uuid.toString());
|
||||
stmt.executeUpdate();
|
||||
return true;
|
||||
|
||||
} catch (SQLException ignored) {}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
private static class ValueMapper<V>
|
||||
{
|
||||
private final Serializer<V> _serializer;
|
||||
private final Deserializer<V> _deserializer;
|
||||
private final String _columnDef;
|
||||
|
||||
private ValueMapper(Serializer<V> serializer, Deserializer<V> deserializer, String columnDef)
|
||||
{
|
||||
_serializer = serializer;
|
||||
_deserializer = deserializer;
|
||||
_columnDef = columnDef;
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Serializer<V>
|
||||
{
|
||||
void write(PreparedStatement statement, int index, V value) throws SQLException;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Deserializer<V>
|
||||
{
|
||||
V read(ResultSet resultSet, int index) throws SQLException;
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package mineplex.core.incognito.events;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/**
|
||||
* Called when an Incognito player is getting hidden from all other players.
|
||||
*/
|
||||
public class IncognitoHidePlayerEvent extends Event
|
||||
{
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private Player _player;
|
||||
private boolean _cancelled;
|
||||
|
||||
public IncognitoHidePlayerEvent(Player player)
|
||||
{
|
||||
_player = player;
|
||||
}
|
||||
|
||||
public Player getPlayer()
|
||||
{
|
||||
return _player;
|
||||
}
|
||||
|
||||
public void setCancelled(boolean cancelled)
|
||||
{
|
||||
_cancelled = cancelled;
|
||||
}
|
||||
|
||||
public boolean isCancelled()
|
||||
{
|
||||
return _cancelled;
|
||||
}
|
||||
|
||||
public HandlerList getHandlers()
|
||||
{
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList()
|
||||
{
|
||||
return handlers;
|
||||
}
|
||||
|
||||
}
|
@ -1,73 +1,72 @@
|
||||
package mineplex.game.clans;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.common.util.UtilItem;
|
||||
import mineplex.core.itemstack.ItemStackFactory;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class Farming extends MiniPlugin
|
||||
{
|
||||
private static final Set<Material> PLANTABLE = Sets.newHashSet(
|
||||
Material.WHEAT,
|
||||
Material.SUGAR_CANE_BLOCK,
|
||||
Material.PUMPKIN_STEM,
|
||||
Material.MELON_STEM,
|
||||
Material.COCOA,
|
||||
Material.CARROT,
|
||||
Material.POTATO
|
||||
);
|
||||
|
||||
public Farming(JavaPlugin plugin)
|
||||
{
|
||||
super("Farming", plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler (ignoreCancelled = true)
|
||||
public void BlockBreak(BlockBreakEvent event)
|
||||
{
|
||||
if (event.isCancelled())
|
||||
return;
|
||||
|
||||
if (event.getBlock().getType() != Material.LEAVES)
|
||||
return;
|
||||
|
||||
if (event.getPlayer().getItemInHand() != null)
|
||||
if (event.getPlayer().getItemInHand().getType() == Material.SHEARS)
|
||||
if (UtilItem.matchesMaterial(event.getPlayer().getItemInHand(), Material.SHEARS))
|
||||
return;
|
||||
|
||||
Location dropLocation = event.getBlock().getLocation().add(0.5, 0.5, 0.5);
|
||||
|
||||
if (Math.random() > 0.9)
|
||||
event.getBlock().getWorld().dropItemNaturally(
|
||||
event.getBlock().getLocation().add(0.5, 0.5, 0.5),
|
||||
ItemStackFactory.Instance.CreateStack(Material.APPLE));
|
||||
event.getBlock().getWorld().dropItemNaturally(dropLocation, ItemStackFactory.Instance.CreateStack(Material.APPLE));
|
||||
|
||||
if (Math.random() > 0.999)
|
||||
event.getBlock().getWorld().dropItemNaturally(
|
||||
event.getBlock().getLocation().add(0.5, 0.5, 0.5),
|
||||
ItemStackFactory.Instance.CreateStack(Material.GOLDEN_APPLE));
|
||||
event.getBlock().getWorld().dropItemNaturally(dropLocation, ItemStackFactory.Instance.CreateStack(Material.GOLDEN_APPLE));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@EventHandler
|
||||
@EventHandler (ignoreCancelled = true)
|
||||
public void BlockPlace(BlockPlaceEvent event)
|
||||
{
|
||||
if (event.isCancelled())
|
||||
if (!PLANTABLE.contains(event.getBlock().getType()))
|
||||
return;
|
||||
|
||||
if (
|
||||
event.getBlock().getTypeId() != 59 &&
|
||||
event.getBlock().getTypeId() != 83 &&
|
||||
event.getBlock().getTypeId() != 104 &&
|
||||
event.getBlock().getTypeId() != 105 &&
|
||||
event.getBlock().getTypeId() != 127 &&
|
||||
event.getBlock().getTypeId() != 141 &&
|
||||
event.getBlock().getTypeId() != 142
|
||||
)
|
||||
return;
|
||||
double blockY = event.getBlock().getLocation().getY();
|
||||
double seaLevel = event.getBlock().getWorld().getSeaLevel();
|
||||
|
||||
if (event.getBlock().getLocation().getY() < event.getBlock().getWorld().getSeaLevel() - 12)
|
||||
if (blockY < seaLevel - 12)
|
||||
{
|
||||
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot plant " +
|
||||
F.item(ItemStackFactory.Instance.GetName(event.getPlayer().getItemInHand(), true)) + " this deep underground."));
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
else if (event.getBlock().getLocation().getY() > event.getBlock().getWorld().getSeaLevel() + 24)
|
||||
else if (blockY > seaLevel + 24)
|
||||
{
|
||||
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot plant " +
|
||||
F.item(ItemStackFactory.Instance.GetName(event.getPlayer().getItemInHand(), true)) + " at this altitude."));
|
||||
|
@ -114,7 +114,6 @@ public class ClansAdmin
|
||||
UtilPlayer.message(caller, F.help("/c x demote <player>", "Demote Player in Mimic", Rank.CMOD));
|
||||
UtilPlayer.message(caller, F.help("/c x kick <player>", "Kick Player from Mimic", Rank.CMOD));
|
||||
UtilPlayer.message(caller, F.help("/c x ally <clan>", "Send Alliance to Mimic", Rank.CMOD));
|
||||
UtilPlayer.message(caller, F.help("/c x trust <clan>", "Give Trust to Clan", Rank.CMOD));
|
||||
UtilPlayer.message(caller, F.help("/c x neutral <clan>", "Set Neutrality", Rank.CMOD));
|
||||
UtilPlayer.message(caller, F.help("/c x enemy <clan>", "Start Invasion", Rank.CMOD));
|
||||
UtilPlayer.message(caller, F.help("/c x rename <name>", "Change the name of Mimic", Rank.CMOD));
|
||||
@ -379,12 +378,6 @@ public class ClansAdmin
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
if (target.getName().equals(caller.getName()))
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Clans Admin", "You cannot invite yourself."));
|
||||
return;
|
||||
}
|
||||
|
||||
//Inform
|
||||
clan.inform(caller.getName() + " invited " + target.getName() + " to join Clan " + clan.getName() + ".", caller.getName());
|
||||
UtilPlayer.message(caller, F.main("Clans Admin", "You invited " + target.getName() + " to join " + F.elem("Clan " + clan.getName()) + "."));
|
||||
|
@ -304,15 +304,39 @@ public class ClansGame extends MiniPlugin
|
||||
return;
|
||||
}
|
||||
|
||||
// Banners/String
|
||||
if (player.getGameMode() != GameMode.CREATIVE && player.getItemInHand() != null)
|
||||
{
|
||||
if (player.getItemInHand().getType() == Material.BANNER || player.getItemInHand().getType() == Material.STRING)
|
||||
{
|
||||
Location destLocation = event.getClickedBlock().getRelative(event.getBlockFace()).getLocation();
|
||||
ClanTerritory territory = _clans.getClanUtility().getClaim(destLocation);
|
||||
if (territory != null)
|
||||
{
|
||||
if (territory.Owner.equals("Shops") || territory.Owner.equals("Fields") || territory.Owner.equals("Spawn") || territory.Owner.equals("Borderlands")) {
|
||||
// Disallow
|
||||
event.setCancelled(true);
|
||||
|
||||
// Inform
|
||||
UtilPlayer.message(player, F.main("Clans", "You cannot place that in " + F.elem(_clans.getClanUtility().getOwnerStringRel(destLocation, player)) + "."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ClanRelation access = _clans.getClanUtility().getAccess(player, loc);
|
||||
ClanInfo clan = _clans.getClan(player);
|
||||
ClanInfo mimicClan = _clans.getClanAdmin().getMimic(player, false);
|
||||
ClanInfo blockClan = _clans.getClanUtility().getClaim(loc) == null ? null : _clans.getClan(_clans.getClanUtility().getClaim(loc).Owner);
|
||||
if (blockClan.equals(mimicClan)) access = ClanRelation.SELF;
|
||||
|
||||
// Doors, chests, & furnaces
|
||||
if (blockClan != null && !blockClan.equals(clan) && (event.getAction() == Action.RIGHT_CLICK_BLOCK && (loc.getBlock().getType().name().contains("DOOR") || UtilItem.doesHaveGUI(loc.getBlock().getType()))))
|
||||
if (blockClan != null && (!blockClan.equals(clan) && !blockClan.equals(mimicClan)) && (event.getAction() == Action.RIGHT_CLICK_BLOCK && (loc.getBlock().getType().name().contains("DOOR") || UtilItem.doesHaveGUI(loc.getBlock().getType()))))
|
||||
{
|
||||
UtilPlayer.message(player, F.main("Clans", "You are not allowed to use that here."));
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Hoe Return
|
||||
|
@ -44,7 +44,7 @@ import mineplex.game.clans.clans.commands.*;
|
||||
import mineplex.game.clans.clans.data.PlayerClan;
|
||||
import mineplex.game.clans.clans.event.ClansPlayerDeathEvent;
|
||||
import mineplex.game.clans.clans.gui.ClanShop;
|
||||
import mineplex.game.clans.clans.invsee.Invsee;
|
||||
import mineplex.game.clans.clans.invsee.InvseeManager;
|
||||
import mineplex.game.clans.clans.loot.LootManager;
|
||||
import mineplex.game.clans.clans.map.ItemMapManager;
|
||||
import mineplex.game.clans.clans.nameblacklist.ClansBlacklist;
|
||||
@ -260,7 +260,7 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
|
||||
new TntGeneratorManager(plugin, this);
|
||||
new SupplyDropManager(plugin, this);
|
||||
|
||||
new Invsee(this);
|
||||
new InvseeManager(this);
|
||||
|
||||
_explosion = new Explosion(plugin, blockRestore);
|
||||
_warPointEvasion = new WarPointEvasion(plugin);
|
||||
@ -556,19 +556,6 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerKick(PlayerKickEvent event)
|
||||
{
|
||||
// Players using wind blade should not get kicked
|
||||
if (event.getPlayer().getItemInHand() != null && event.getPlayer().getItemInHand().getItemMeta() != null && (C.cGold + "Wind Blade").equals(event.getPlayer().getItemInHand().getItemMeta().getDisplayName()))
|
||||
{
|
||||
if (event.getReason().contains("flying is not enabled"))
|
||||
{
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void StaffIncognito(IncognitoStatusChangeEvent event)
|
||||
{
|
||||
@ -1175,7 +1162,7 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
|
||||
@EventHandler
|
||||
public void hubCommand(PlayerCommandPreprocessEvent event)
|
||||
{
|
||||
if (event.getMessage().toLowerCase().startsWith("/lobby") || event.getMessage().toLowerCase().startsWith("/hub") || event.getMessage().toLowerCase().startsWith("/leave"))
|
||||
if (event.getMessage().toLowerCase().equals("/lobby") || event.getMessage().toLowerCase().equals("/hub") || event.getMessage().toLowerCase().equals("/leave"))
|
||||
{
|
||||
Portal.getInstance().sendPlayerToServer(event.getPlayer(), "Lobby");
|
||||
event.setCancelled(true);
|
||||
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Chunk;
|
||||
@ -28,6 +29,11 @@ import mineplex.game.clans.spawn.Spawn;
|
||||
|
||||
public class ClansUtility
|
||||
{
|
||||
// The maximum number of clans to search before exiting early. Inclusive
|
||||
private static final int MAX_CLAN_SEARCH = 10;
|
||||
// The maximum number of players to search before exiting early. Inclusive
|
||||
private static final int MAX_PLAYER_SEARCH = 10;
|
||||
|
||||
private ClansManager _clansManager;
|
||||
|
||||
public ClansUtility(ClansManager clans)
|
||||
@ -113,55 +119,79 @@ public class ClansUtility
|
||||
public ClanInfo searchClanPlayer(Player caller, String name, boolean inform)
|
||||
{
|
||||
// CLAN
|
||||
LinkedList<ClanInfo> clanMatchList = new LinkedList<ClanInfo>();
|
||||
List<ClanInfo> clanMatchList = new ArrayList<>(MAX_CLAN_SEARCH);
|
||||
|
||||
for (ClanInfo cur : _clansManager.getClanMap().values())
|
||||
{
|
||||
if (cur.getName().equalsIgnoreCase(name)) return cur;
|
||||
|
||||
if (cur.getName().toLowerCase().contains(name.toLowerCase())) clanMatchList.add(cur);
|
||||
|
||||
if (clanMatchList.size() > MAX_CLAN_SEARCH) break;
|
||||
}
|
||||
|
||||
if (clanMatchList.size() == 1) return clanMatchList.get(0);
|
||||
|
||||
// No / Non-Unique
|
||||
String clanMatchString = "None";
|
||||
if (clanMatchList.size() > 1)
|
||||
{
|
||||
for (ClanInfo cur : clanMatchList)
|
||||
clanMatchString += cur.getName() + " ";
|
||||
}
|
||||
|
||||
// PLAYER
|
||||
LinkedList<ClanInfo> playerMatchList = new LinkedList<ClanInfo>();
|
||||
List<ClanInfo> playerMatchList = new ArrayList<>(MAX_PLAYER_SEARCH);
|
||||
|
||||
for (ClanInfo clanInfo : _clansManager.getClanMap().values())
|
||||
outer: for (ClanInfo clanInfo : _clansManager.getClanMap().values())
|
||||
{
|
||||
for (ClansPlayer player : clanInfo.getMembers().values())
|
||||
{
|
||||
if (player.getPlayerName().equalsIgnoreCase(name)) return clanInfo;
|
||||
|
||||
if (player.getPlayerName().toLowerCase().contains(name.toLowerCase())) playerMatchList.add(clanInfo);
|
||||
if (player.getPlayerName().toLowerCase().contains(name.toLowerCase()))
|
||||
{
|
||||
playerMatchList.add(clanInfo);
|
||||
// No duplicate results please
|
||||
continue outer;
|
||||
}
|
||||
|
||||
if (playerMatchList.size() > MAX_PLAYER_SEARCH) break outer;
|
||||
}
|
||||
}
|
||||
|
||||
if (playerMatchList.size() == 1) return playerMatchList.get(0);
|
||||
|
||||
// No / Non-Unique
|
||||
String playerMatchString = "None";
|
||||
if (playerMatchList.size() > 1)
|
||||
{
|
||||
for (ClanInfo cur : playerMatchList)
|
||||
playerMatchString += cur.getName() + " ";
|
||||
}
|
||||
|
||||
if (inform)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Clan Search", "" + C.mCount + (clanMatchList.size() + playerMatchList.size()) + C.mBody + " matches for [" + C.mElem + name + C.mBody + "]."));
|
||||
|
||||
UtilPlayer.message(caller, F.desc("Matches via Clan", clanMatchString));
|
||||
UtilPlayer.message(caller, F.desc("Matches via Player", playerMatchString));
|
||||
if (clanMatchList.size() > MAX_CLAN_SEARCH)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Clan Search", "Too many clans matched. Try a more specific search"));
|
||||
}
|
||||
else if (clanMatchList.size() == 0)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Clan Search", "No clans matched. Try a more specific search"));
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder clanMatchString = new StringBuilder();
|
||||
for (ClanInfo clanInfo : clanMatchList)
|
||||
{
|
||||
clanMatchString.append(clanInfo.getName()).append(" ");
|
||||
}
|
||||
UtilPlayer.message(caller, F.desc("Matches via Clan", clanMatchString.toString()));
|
||||
}
|
||||
if (playerMatchList.size() > MAX_PLAYER_SEARCH)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Clan Search", "Too many players matched. Try a more specific search"));
|
||||
}
|
||||
else if (playerMatchList.size() == 0)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Clan Search", "No players matched. Try a more specific search"));
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder playerMatchString = new StringBuilder();
|
||||
for (ClanInfo clanInfo : playerMatchList)
|
||||
{
|
||||
playerMatchString.append(clanInfo.getName()).append(" ");
|
||||
}
|
||||
UtilPlayer.message(caller, F.desc("Matches via Player", playerMatchString.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -259,9 +289,15 @@ public class ClansUtility
|
||||
|
||||
public boolean isSafe(Location loc)
|
||||
{
|
||||
if (!_clansManager.getClaimMap().containsKey(UtilWorld.chunkToStr(loc.getChunk()))) return false;
|
||||
// Fix for PC-279
|
||||
// Do not change to getChunk
|
||||
// PlayerList#updatePlayers -> iterator -> PlayerVelocityEvent -> getChunk -> loadChunk -> loadPersistentEntities -> addTracker -> ITERATE ON SAME SET
|
||||
int chunkX = loc.getBlockX() >> 4;
|
||||
int chunkZ = loc.getBlockZ() >> 4;
|
||||
String chunkStr = UtilWorld.chunkToStr(loc.getWorld().getName(), chunkX, chunkZ);
|
||||
if (!_clansManager.getClaimMap().containsKey(chunkStr)) return false;
|
||||
|
||||
return _clansManager.getClaimMap().get(UtilWorld.chunkToStr(loc.getChunk())).isSafe(loc);
|
||||
return _clansManager.getClaimMap().get(chunkStr).isSafe(loc);
|
||||
}
|
||||
|
||||
public boolean isChunkHome(ClanInfo clan, Chunk chunk)
|
||||
|
@ -233,7 +233,6 @@ public class ClansCommand extends CommandBase<ClansManager>
|
||||
UtilPlayer.message(caller, F.help("/c neutral <clan>", "Request Neutrality with Clan", Rank.ADMIN));
|
||||
UtilPlayer.message(caller, F.help("/c enemy <clan>", "Declare ClanWar with Clan", Rank.ADMIN));
|
||||
UtilPlayer.message(caller, F.help("/c ally <clan>", "Send Alliance to Clan", Rank.ADMIN));
|
||||
UtilPlayer.message(caller, F.help("/c trust <clan>", "Give Trust to Clan", Rank.ADMIN));
|
||||
UtilPlayer.message(caller, F.help("/c claim", "Claim Territory", Rank.ADMIN));
|
||||
UtilPlayer.message(caller, F.help("/c unclaim (all)", "Unclaim Territory", Rank.ADMIN));
|
||||
|
||||
|
@ -269,6 +269,8 @@ public class ClanMainPage extends ClanPageBase
|
||||
{
|
||||
String enemyName = clanWar.getClanA().equals(clan.getName()) ? clanWar.getClanB() : clanWar.getClanA();
|
||||
final ClanInfo enemy = getPlugin().getClan(enemyName);
|
||||
if (enemy != null)
|
||||
{
|
||||
String itemName = enemyName;
|
||||
Material material = USE_RESOURCE_ICONS ? ClanIcon.WAR.getMaterial() : Material.DIAMOND_SWORD;
|
||||
byte data = USE_RESOURCE_ICONS ? ClanIcon.WAR.getData() : 0;
|
||||
@ -290,6 +292,11 @@ public class ClanMainPage extends ClanPageBase
|
||||
}
|
||||
}, warPoints);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Could not find enemy clan: " + enemyName);
|
||||
}
|
||||
}
|
||||
|
||||
private void addAllyButton(int slot, final ClanInfo ally)
|
||||
{
|
||||
|
@ -1,23 +0,0 @@
|
||||
package mineplex.game.clans.clans.invsee;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.game.clans.clans.ClansManager;
|
||||
import mineplex.game.clans.clans.invsee.commands.InvseeCommand;
|
||||
|
||||
public class Invsee extends MiniPlugin
|
||||
{
|
||||
private ClansManager _clansManager;
|
||||
|
||||
public Invsee(ClansManager clansManager)
|
||||
{
|
||||
super("Inventory Viewer", clansManager.getPlugin());
|
||||
|
||||
_clansManager = clansManager;
|
||||
}
|
||||
|
||||
public void addCommands()
|
||||
{
|
||||
addCommand(new InvseeCommand(this));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package mineplex.game.clans.clans.invsee;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.game.clans.clans.ClansManager;
|
||||
import mineplex.game.clans.clans.invsee.commands.InvseeCommand;
|
||||
import mineplex.game.clans.clans.invsee.ui.InvseeInventory;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class InvseeManager extends MiniPlugin
|
||||
{
|
||||
private final Map<UUID, InvseeInventory> _viewing = new HashMap<>();
|
||||
|
||||
public InvseeManager(ClansManager manager)
|
||||
{
|
||||
super("Invsee Manager", manager.getPlugin());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCommands()
|
||||
{
|
||||
addCommand(new InvseeCommand(this));
|
||||
}
|
||||
|
||||
public void doInvsee(OfflinePlayer target, Player requester)
|
||||
{
|
||||
InvseeInventory invseeInventory = _viewing.computeIfAbsent(target.getUniqueId(), key -> new InvseeInventory(this, target));
|
||||
invseeInventory.addAndShowViewer(requester);
|
||||
}
|
||||
|
||||
public boolean isBeingInvseen(OfflinePlayer player)
|
||||
{
|
||||
return _viewing.containsKey(player.getUniqueId());
|
||||
}
|
||||
|
||||
public boolean isInvseeing(Player player)
|
||||
{
|
||||
for (InvseeInventory invseeInventory : _viewing.values())
|
||||
{
|
||||
if (invseeInventory.isViewer(player))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void close(UUID target)
|
||||
{
|
||||
InvseeInventory invseeInventory = _viewing.remove(target);
|
||||
if (invseeInventory == null)
|
||||
{
|
||||
log("Expected non-null inventory when closing " + target);
|
||||
return;
|
||||
}
|
||||
UtilServer.Unregister(invseeInventory);
|
||||
}
|
||||
}
|
@ -1,50 +1,94 @@
|
||||
package mineplex.game.clans.clans.invsee.commands;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import mineplex.core.command.CommandBase;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.game.clans.clans.invsee.Invsee;
|
||||
import mineplex.game.clans.clans.invsee.ui.InvseeInventory;
|
||||
import mineplex.game.clans.clans.invsee.InvseeManager;
|
||||
import net.minecraft.server.v1_8_R3.MinecraftServer;
|
||||
import net.minecraft.server.v1_8_R3.NBTTagCompound;
|
||||
import net.minecraft.server.v1_8_R3.WorldNBTStorage;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class InvseeCommand extends CommandBase<Invsee>
|
||||
import java.util.UUID;
|
||||
|
||||
public class InvseeCommand extends CommandBase<InvseeManager>
|
||||
{
|
||||
public InvseeCommand(Invsee plugin)
|
||||
public InvseeCommand(InvseeManager plugin)
|
||||
{
|
||||
super(plugin, Rank.ADMIN, "invsee");
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
if (args.length == 0)
|
||||
{
|
||||
UtilPlayer.message(caller, F.help("/invsee <Player>", "View a player's inventory", Rank.ADMIN));
|
||||
UtilPlayer.message(caller, F.help("/invsee <playername/playeruuid>", "View a player's inventory", Rank.ADMIN));
|
||||
return;
|
||||
}
|
||||
else
|
||||
UUID uuid = null;
|
||||
try
|
||||
{
|
||||
String name = args[0];
|
||||
|
||||
OfflinePlayer player = Bukkit.getServer().getPlayer(name);
|
||||
|
||||
if (player == null)
|
||||
uuid = UUID.fromString(args[0]);
|
||||
}
|
||||
catch (IllegalArgumentException failed)
|
||||
{
|
||||
player = Bukkit.getServer().getOfflinePlayer(name);
|
||||
}
|
||||
|
||||
if (player == null)
|
||||
OfflinePlayer exactPlayer = Bukkit.getServer().getPlayerExact(args[0]);
|
||||
if (exactPlayer == null)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Clans", "Specified player is neither online nor offline. Perhaps they changed their name?"));
|
||||
if (uuid == null)
|
||||
{
|
||||
// We don't want to open the wrong OfflinePlayer's inventory, so if we can't fetch the UUID then abort
|
||||
GameProfile gameProfile = MinecraftServer.getServer().getUserCache().getProfile(args[0]);
|
||||
if (gameProfile == null)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Invsee", "Player is offline and we could not find the UUID. Aborting"));
|
||||
return;
|
||||
}
|
||||
uuid = gameProfile.getId();
|
||||
}
|
||||
if (uuid == null)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Invsee", "Something has gone very wrong. Please report the username/uuid you tried to look up"));
|
||||
return;
|
||||
}
|
||||
// We need to check if we actually have data on this player
|
||||
// fixme main thread file IO but it's what the server does...?
|
||||
NBTTagCompound compound = ((WorldNBTStorage) MinecraftServer.getServer().worlds.get(0).getDataManager()).getPlayerData(uuid.toString());
|
||||
if (compound == null)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Invsee", "The player exists, but has never joined this server. No inventory to show"));
|
||||
return;
|
||||
}
|
||||
exactPlayer = Bukkit.getServer().getOfflinePlayer(uuid);
|
||||
}
|
||||
if (exactPlayer == null)
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Invsee", "Could not load offline player data. Does the player exist?"));
|
||||
return;
|
||||
}
|
||||
if (exactPlayer.getUniqueId().equals(caller.getUniqueId()))
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Invsee", "You cannot invsee yourself!"));
|
||||
return;
|
||||
}
|
||||
if (Plugin.isBeingInvseen(caller))
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Invsee", "You cannot use invsee right now. Someone is invseeing you!"));
|
||||
return;
|
||||
}
|
||||
if (exactPlayer.isOnline() && Plugin.isInvseeing((Player) exactPlayer))
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Invsee", "You cannot use invsee right now. That person is currently using invsee!"));
|
||||
return;
|
||||
}
|
||||
|
||||
new InvseeInventory(player).ShowTo(caller);
|
||||
Plugin.doInvsee(exactPlayer, caller);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,99 +1,407 @@
|
||||
package mineplex.game.clans.clans.invsee.ui;
|
||||
|
||||
import mineplex.core.common.util.*;
|
||||
import mineplex.core.itemstack.ItemStackFactory;
|
||||
import mineplex.game.clans.clans.ClansManager;
|
||||
import mineplex.game.clans.clans.invsee.InvseeManager;
|
||||
import net.minecraft.server.v1_8_R3.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftInventory;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.*;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.UtilCollections;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.*;
|
||||
|
||||
public class InvseeInventory implements Listener
|
||||
{
|
||||
private OfflinePlayer _player;
|
||||
private final InvseeManager _invseeManager;
|
||||
|
||||
// This is the UUID of the target player. This should stay constant. Use this for comparison
|
||||
private final UUID _uuid;
|
||||
// This is the current player. It will switch when the player joins/quits
|
||||
private OfflinePlayer _targetPlayer;
|
||||
// This is the inventory of said player. If the player is not online then this inventory is a fake PlayerInventory
|
||||
private net.minecraft.server.v1_8_R3.PlayerInventory _playerInventory;
|
||||
// This is the set of all admins viewing this player
|
||||
private Set<Player> _viewers = new HashSet<>();
|
||||
// This is the inventory that all admins will be looking at
|
||||
private Inventory _inventory;
|
||||
// This is whether the target player should be allowed to open any inventories
|
||||
private boolean _canOpenInventory = true;
|
||||
|
||||
private boolean _online;
|
||||
|
||||
private Player _admin;
|
||||
|
||||
public InvseeInventory(OfflinePlayer player)
|
||||
public InvseeInventory(InvseeManager manager, OfflinePlayer player)
|
||||
{
|
||||
_online = (_player = player) instanceof Player;
|
||||
_invseeManager = manager;
|
||||
_uuid = player.getUniqueId();
|
||||
_targetPlayer = player;
|
||||
|
||||
_inventory = UtilServer.getServer().createInventory(null, 54, player.getName() + " " + (_online ? C.cGreen + "ONLINE" : C.cRed + "OFFLINE"));
|
||||
_inventory = UtilServer.getServer().createInventory(null, 6 * 9, player.getName());
|
||||
|
||||
for (int index = 38; index < 45; index++)
|
||||
{
|
||||
_inventory.setItem(index, ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, (byte) 14, 1, C.Bold));
|
||||
}
|
||||
_inventory.setItem(47, ItemStackFactory.Instance.CreateStack(Material.STONE_BUTTON, (byte) 0, 1, C.cGreenB + "Inventory Control", generateLore(_canOpenInventory)));
|
||||
|
||||
_inventory.setItem(48, ItemStackFactory.Instance.CreateStack(Material.STAINED_GLASS_PANE, (byte) 14, 1, C.Bold));
|
||||
|
||||
UtilServer.RegisterEvents(this);
|
||||
updateInventory();
|
||||
update(true);
|
||||
}
|
||||
|
||||
public void ShowTo(Player admin)
|
||||
private String[] generateLore(boolean canOpenInventory)
|
||||
{
|
||||
_admin = admin;
|
||||
admin.openInventory(_inventory);
|
||||
return UtilText.splitLinesToArray(new String[]{
|
||||
C.cYellow + "Left-Click" + C.cWhite + " to force close any open inventories the target has open",
|
||||
"",
|
||||
C.cYellow + "Right-Click" + C.cWhite + " to " + (canOpenInventory ? "disable inventory opening" : "enable inventory opening")
|
||||
}, LineFormat.LORE);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void quit(PlayerQuitEvent event)
|
||||
/*
|
||||
* Add the player to the list of viewers and open the inventory for him
|
||||
*/
|
||||
public void addAndShowViewer(Player requester)
|
||||
{
|
||||
if (_online && event.getPlayer().equals(_player))
|
||||
_viewers.add(requester);
|
||||
requester.openInventory(_inventory);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether the given player is currently viewing this InvseeInventory
|
||||
*/
|
||||
public boolean isViewer(Player check)
|
||||
{
|
||||
_admin.closeInventory();
|
||||
return _viewers.contains(check);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void on(PlayerJoinEvent event)
|
||||
{
|
||||
if (_uuid.equals(event.getPlayer().getUniqueId()))
|
||||
{
|
||||
_targetPlayer = event.getPlayer();
|
||||
updateInventory();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void update(UpdateEvent event)
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void on(PlayerQuitEvent event)
|
||||
{
|
||||
if (event.getType() != UpdateType.TICK)
|
||||
// If a viewer quit, this will clean it up
|
||||
_viewers.remove(event.getPlayer());
|
||||
if (_viewers.size() == 0)
|
||||
{
|
||||
_invseeManager.close(_uuid);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This should always work
|
||||
_targetPlayer = Bukkit.getOfflinePlayer(_uuid);
|
||||
updateInventory();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
|
||||
public void on(InventoryOpenEvent event)
|
||||
{
|
||||
if (event.getPlayer().getUniqueId().equals(_targetPlayer.getUniqueId()) && !_canOpenInventory)
|
||||
{
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void on(InventoryCloseEvent event)
|
||||
{
|
||||
if (_inventory.equals(event.getInventory()))
|
||||
{
|
||||
_viewers.remove(event.getPlayer());
|
||||
if (_viewers.size() == 0)
|
||||
{
|
||||
_invseeManager.close(_uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void on(InventoryDragEvent event)
|
||||
{
|
||||
if (_inventory.equals(event.getInventory()))
|
||||
{
|
||||
ClansManager.getInstance().runSync(() ->
|
||||
{
|
||||
update(false);
|
||||
saveInventory();
|
||||
});
|
||||
}
|
||||
else if (event.getWhoClicked().getUniqueId().equals(_targetPlayer.getUniqueId()))
|
||||
{
|
||||
ClansManager.getInstance().runSync(() ->
|
||||
{
|
||||
update(true);
|
||||
saveInventory();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
public void on(InventoryClickEvent event)
|
||||
{
|
||||
if (_inventory.equals(event.getClickedInventory()))
|
||||
{
|
||||
if (event.getCurrentItem() != null && event.getCurrentItem().getType() == Material.STAINED_GLASS_PANE
|
||||
&& event.getCurrentItem().getItemMeta() != null
|
||||
&& event.getCurrentItem().getItemMeta().getDisplayName() != null
|
||||
&& event.getCurrentItem().getItemMeta().getDisplayName().equals(C.Bold))
|
||||
{
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
if (event.getCurrentItem() != null && event.getCurrentItem().getType() == Material.STONE_BUTTON
|
||||
&& event.getCurrentItem().getItemMeta() != null
|
||||
&& event.getCurrentItem().getItemMeta().getDisplayName() != null
|
||||
&& event.getCurrentItem().getItemMeta().getDisplayName().equals(C.cGreenB + "Inventory Control"))
|
||||
{
|
||||
event.setCancelled(true);
|
||||
if (event.getClick() == ClickType.LEFT)
|
||||
{
|
||||
if (_targetPlayer.isOnline())
|
||||
{
|
||||
((Player) _targetPlayer).closeInventory();
|
||||
}
|
||||
}
|
||||
else if (event.getClick() == ClickType.RIGHT)
|
||||
{
|
||||
if (_targetPlayer.isOnline())
|
||||
{
|
||||
_canOpenInventory = !_canOpenInventory;
|
||||
ItemMeta meta = event.getCurrentItem().getItemMeta();
|
||||
meta.setLore(Arrays.asList(generateLore(_canOpenInventory)));
|
||||
event.getCurrentItem().setItemMeta(meta);
|
||||
if (!_canOpenInventory)
|
||||
{
|
||||
((Player) _targetPlayer).closeInventory();
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (_online)
|
||||
if (MAPPING_INVENTORY_REVERSE.containsKey(event.getRawSlot()))
|
||||
{
|
||||
if (!UtilCollections.equal(_inventory.getContents(), ((Player) _player).getInventory().getContents()))
|
||||
ClansManager.getInstance().runSync(() ->
|
||||
{
|
||||
_inventory.setContents(((Player) _player).getInventory().getContents());
|
||||
update(false);
|
||||
saveInventory();
|
||||
});
|
||||
}
|
||||
else if (MAPPING_CRAFTING_REVERSE.containsKey(event.getRawSlot()))
|
||||
{
|
||||
if (_targetPlayer.isOnline())
|
||||
{
|
||||
ClansManager.getInstance().runSync(() ->
|
||||
{
|
||||
update(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (event.getRawSlot() == 49)
|
||||
{
|
||||
if (_targetPlayer.isOnline())
|
||||
{
|
||||
ClansManager.getInstance().runSync(() ->
|
||||
{
|
||||
update(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (event.getWhoClicked().getUniqueId().equals(_targetPlayer.getUniqueId()))
|
||||
{
|
||||
ClansManager.getInstance().runSync(() ->
|
||||
{
|
||||
update(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void inventoryClick(InventoryClickEvent event)
|
||||
/*
|
||||
* Updates the inventory instance
|
||||
*/
|
||||
private void updateInventory()
|
||||
{
|
||||
if (event.getClickedInventory().equals(((Player) _player).getInventory()))
|
||||
if (_targetPlayer.isOnline())
|
||||
{
|
||||
_inventory.setContents(((Player) _player).getInventory().getContents());
|
||||
_playerInventory = ((CraftPlayer) _targetPlayer).getHandle().inventory;
|
||||
}
|
||||
else if (event.getClickedInventory().equals(_inventory))
|
||||
else
|
||||
{
|
||||
if (_online)
|
||||
NBTTagCompound compound = ((WorldNBTStorage) MinecraftServer.getServer().worlds.get(0).getDataManager()).getPlayerData(_uuid.toString());
|
||||
// Should not matter if null
|
||||
_playerInventory = new PlayerInventory(null);
|
||||
if (compound.hasKeyOfType("Inventory", 9))
|
||||
{
|
||||
((Player) _player).getInventory().setContents(_inventory.getContents());
|
||||
_playerInventory.b(compound.getList("Inventory", 10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void closeInventory(InventoryCloseEvent event)
|
||||
private void saveInventory()
|
||||
{
|
||||
if (event.getInventory().equals(_inventory))
|
||||
if (!_targetPlayer.isOnline())
|
||||
{
|
||||
UtilServer.Unregister(this);
|
||||
try
|
||||
{
|
||||
WorldNBTStorage worldNBTStorage = ((WorldNBTStorage) MinecraftServer.getServer().worlds.get(0).getDataManager());
|
||||
NBTTagCompound compound = worldNBTStorage.getPlayerData(_uuid.toString());
|
||||
compound.set("Inventory", new NBTTagList());
|
||||
_playerInventory.a(compound.getList("Inventory", 10));
|
||||
File file = new File(worldNBTStorage.getPlayerDir(), _targetPlayer.getUniqueId().toString() + ".dat.tmp");
|
||||
File file1 = new File(worldNBTStorage.getPlayerDir(), _targetPlayer.getUniqueId().toString() + ".dat");
|
||||
NBTCompressedStreamTools.a(compound, new FileOutputStream(file));
|
||||
if (file1.exists())
|
||||
{
|
||||
file1.delete();
|
||||
}
|
||||
|
||||
if (!_online)
|
||||
file.renameTo(file1);
|
||||
}
|
||||
catch (Exception var5)
|
||||
{
|
||||
// save offline inv
|
||||
_invseeManager.log("Failed to save player inventory for " + _targetPlayer.getName());
|
||||
for (Player player : _viewers)
|
||||
{
|
||||
UtilPlayer.message(player, F.main("Invsee", "Could not save inventory for " + _targetPlayer.getName()));
|
||||
}
|
||||
var5.printStackTrace(System.out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the player inventory and invsee inventory.
|
||||
*
|
||||
* @param targetClick If true, then it means the player being invseen has modified their inventory. Otherwise, it's the admin who has modified something
|
||||
*/
|
||||
private void update(boolean targetClick)
|
||||
{
|
||||
IInventory iInventoryThis = ((CraftInventory) _inventory).getInventory();
|
||||
|
||||
if (targetClick)
|
||||
{
|
||||
// Update items on hotbar
|
||||
for (int otherSlot = 0; otherSlot < 9; otherSlot++)
|
||||
{
|
||||
iInventoryThis.setItem(MAPPING_INVENTORY.get(otherSlot), _playerInventory.getItem(otherSlot));
|
||||
}
|
||||
// Update main inventory
|
||||
for (int otherSlot = 9; otherSlot < 36; otherSlot++)
|
||||
{
|
||||
iInventoryThis.setItem(MAPPING_INVENTORY.get(otherSlot), _playerInventory.getItem(otherSlot));
|
||||
}
|
||||
// Update armor
|
||||
for (int otherSlot = 36; otherSlot < 40; otherSlot++)
|
||||
{
|
||||
iInventoryThis.setItem(MAPPING_INVENTORY.get(otherSlot), _playerInventory.getItem(otherSlot));
|
||||
}
|
||||
|
||||
if (_targetPlayer.isOnline())
|
||||
{
|
||||
ContainerPlayer containerPlayer = (ContainerPlayer) ((CraftPlayer) _targetPlayer).getHandle().defaultContainer;
|
||||
for (int craftingIndex = 0; craftingIndex < 4; craftingIndex++)
|
||||
{
|
||||
iInventoryThis.setItem(MAPPING_CRAFTING.get(craftingIndex), containerPlayer.craftInventory.getItem(craftingIndex));
|
||||
}
|
||||
}
|
||||
iInventoryThis.setItem(49, _playerInventory.getCarried());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Update items on hotbar
|
||||
for (int otherSlot = 0; otherSlot < 9; otherSlot++)
|
||||
{
|
||||
_playerInventory.setItem(otherSlot, iInventoryThis.getItem(MAPPING_INVENTORY.get(otherSlot)));
|
||||
}
|
||||
// Update main inventory
|
||||
for (int otherSlot = 9; otherSlot < 36; otherSlot++)
|
||||
{
|
||||
_playerInventory.setItem(otherSlot, iInventoryThis.getItem(MAPPING_INVENTORY.get(otherSlot)));
|
||||
}
|
||||
// Update armor
|
||||
for (int otherSlot = 36; otherSlot < 40; otherSlot++)
|
||||
{
|
||||
_playerInventory.setItem(otherSlot, iInventoryThis.getItem(MAPPING_INVENTORY.get(otherSlot)));
|
||||
}
|
||||
|
||||
if (_targetPlayer.isOnline())
|
||||
{
|
||||
ContainerPlayer containerPlayer = (ContainerPlayer) ((CraftPlayer) _targetPlayer).getHandle().defaultContainer;
|
||||
for (int craftingIndex = 0; craftingIndex < 4; craftingIndex++)
|
||||
{
|
||||
containerPlayer.craftInventory.setItem(craftingIndex, iInventoryThis.getItem(MAPPING_CRAFTING.get(craftingIndex)));
|
||||
}
|
||||
}
|
||||
_playerInventory.setCarried(iInventoryThis.getItem(49));
|
||||
}
|
||||
for (Player viewing : _viewers)
|
||||
{
|
||||
viewing.updateInventory();
|
||||
}
|
||||
if (_targetPlayer.isOnline())
|
||||
{
|
||||
((Player) _targetPlayer).updateInventory();
|
||||
}
|
||||
}
|
||||
|
||||
// Maps slot indices of player inventories to slot indices of double chests
|
||||
private static final Map<Integer, Integer> MAPPING_INVENTORY = new HashMap<>();
|
||||
private static final Map<Integer, Integer> MAPPING_INVENTORY_REVERSE = new HashMap<>();
|
||||
// Maps slot indices of player inventories to slot indices of crafting window
|
||||
private static final Map<Integer, Integer> MAPPING_CRAFTING = new HashMap<>();
|
||||
private static final Map<Integer, Integer> MAPPING_CRAFTING_REVERSE = new HashMap<>();
|
||||
|
||||
static
|
||||
{
|
||||
int[] inventoryMapping = new int[]
|
||||
{
|
||||
27, 28, 29, 30, 31, 32, 33, 34, 35, //Hotbar
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, // Top row inventory
|
||||
9, 10, 11, 12, 13, 14, 15, 16, 17, //Second row inventory
|
||||
18, 19, 20, 21, 22, 23, 24, 25, 26, //Third row inventory
|
||||
53, 52, 51, 50 //Armor
|
||||
};
|
||||
int[] craftingMapping = new int[]
|
||||
{
|
||||
36, 37, //Top crafting
|
||||
45, 46 //Bottom crafting
|
||||
};
|
||||
for (int i = 0; i < inventoryMapping.length; i++)
|
||||
{
|
||||
MAPPING_INVENTORY.put(i, inventoryMapping[i]);
|
||||
MAPPING_INVENTORY_REVERSE.put(inventoryMapping[i], i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < craftingMapping.length; i++)
|
||||
{
|
||||
MAPPING_CRAFTING.put(i, craftingMapping[i]);
|
||||
MAPPING_CRAFTING_REVERSE.put(craftingMapping[i], i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,26 @@
|
||||
package mineplex.game.clans.clans.map;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import mineplex.core.common.util.*;
|
||||
import mineplex.game.clans.tutorial.TutorialManager;
|
||||
import mineplex.game.clans.tutorial.map.TutorialMapManager;
|
||||
import net.minecraft.server.v1_8_R3.*;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.CraftChunk;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.util.LongHash;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.util.LongObjectHashMap;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.entity.ItemSpawnEvent;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
@ -35,6 +31,8 @@ import org.bukkit.event.player.PlayerItemHeldEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.map.MapRenderer;
|
||||
@ -46,13 +44,6 @@ import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Multisets;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilInv;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.common.util.UtilTextBottom;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.common.util.UtilTime.TimeUnit;
|
||||
import mineplex.core.itemstack.ItemBuilder;
|
||||
import mineplex.core.portal.ServerTransferEvent;
|
||||
@ -62,27 +53,77 @@ import mineplex.game.clans.clans.ClansManager;
|
||||
import mineplex.game.clans.clans.ClansUtility;
|
||||
import mineplex.game.clans.clans.map.events.PlayerGetMapEvent;
|
||||
import mineplex.game.clans.clans.worldevent.WorldEventManager;
|
||||
import net.minecraft.server.v1_8_R3.Block;
|
||||
import net.minecraft.server.v1_8_R3.BlockPosition;
|
||||
import net.minecraft.server.v1_8_R3.Blocks;
|
||||
import net.minecraft.server.v1_8_R3.IBlockData;
|
||||
import net.minecraft.server.v1_8_R3.MaterialMapColor;
|
||||
import net.minecraft.server.v1_8_R3.PersistentCollection;
|
||||
|
||||
/*
|
||||
* This class manages what the Clans map will show.
|
||||
* It will scan all relevant chunks (eg players nearby) every <x> ticks
|
||||
*/
|
||||
public class ItemMapManager extends MiniPlugin
|
||||
{
|
||||
private int _blocksScan = 16 * 3;
|
||||
// Every BLOCK_SCAN_INTERVAL we add as a new region to scan
|
||||
private static final int BLOCK_SCAN_INTERVAL = 16 * 3;
|
||||
// 1536 is the width of the entire world from one borderland to the other
|
||||
private static final int HALF_WORLD_SIZE = 1536 / 2;
|
||||
// This slot is where the Clans Map will go by default
|
||||
private static final int CLANS_MAP_SLOT = 8;
|
||||
|
||||
private static final String[] ZOOM_INFO;
|
||||
|
||||
static
|
||||
{
|
||||
ZOOM_INFO = new String[4];
|
||||
for (int zoomLevel = 0; zoomLevel <= 3; zoomLevel++)
|
||||
{
|
||||
StringBuilder progressBar = new StringBuilder(C.cBlue);
|
||||
|
||||
boolean colorChange = false;
|
||||
for (int i = 2; i >= 0; i--)
|
||||
{
|
||||
if (!colorChange && i < zoomLevel)
|
||||
{
|
||||
progressBar.append(C.cGray);
|
||||
colorChange = true;
|
||||
}
|
||||
char c;
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
c = '█';
|
||||
break;
|
||||
case 1:
|
||||
c = '▆';
|
||||
break;
|
||||
default:
|
||||
c = '▄';
|
||||
break;
|
||||
}
|
||||
for (int a = 0; a < 4; a++)
|
||||
{
|
||||
progressBar.append(c);
|
||||
}
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
progressBar.append(" ");
|
||||
}
|
||||
}
|
||||
ZOOM_INFO[zoomLevel] = progressBar.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private ClansUtility _clansUtility;
|
||||
private Comparator<Entry<Integer, Integer>> _comparator;
|
||||
private int _halfMapSize = 1536 / 2;
|
||||
private int[][] _heightMap = new int[(_halfMapSize * 2) + 16][];
|
||||
private boolean _loadWorld = true;
|
||||
private int[][] _heightMap = new int[(HALF_WORLD_SIZE * 2) + 16][];
|
||||
private HashMap<Integer, Byte[][]> _map = new HashMap<Integer, Byte[][]>();
|
||||
private short _mapId = -1;
|
||||
private HashMap<String, MapInfo> _mapInfo = new HashMap<String, MapInfo>();
|
||||
private HashMap<Integer, Integer> _scale = new HashMap<Integer, Integer>();
|
||||
private ArrayList<Entry<Integer, Integer>> _scanList = new ArrayList<Entry<Integer, Integer>>();
|
||||
// Use LinkedList because operations are either add(Entry) which is O(1) and remove(0) which is O(1) on LinkedList but O(n) on ArrayList
|
||||
private LinkedList<Entry<Integer, Integer>> _scanList = new LinkedList<Entry<Integer, Integer>>();
|
||||
private World _world;
|
||||
private WorldServer _nmsWorld;
|
||||
private ChunkProviderServer _chunkProviderServer;
|
||||
private ChunkRegionLoader _chunkRegionLoader;
|
||||
private WorldEventManager _eventManager;
|
||||
private TutorialManager _tutorial;
|
||||
|
||||
@ -94,14 +135,10 @@ public class ItemMapManager extends MiniPlugin
|
||||
_eventManager = eventManager;
|
||||
_tutorial = tutorial;
|
||||
|
||||
_comparator = new Comparator<Entry<Integer, Integer>>()
|
||||
{
|
||||
|
||||
@Override
|
||||
public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2)
|
||||
_comparator = (o1, o2) ->
|
||||
{
|
||||
// Render the places outside the map first to speed up visual errors fixing
|
||||
int outsideMap = Boolean.compare(o1.getValue() < -_halfMapSize, o2.getValue() < -_halfMapSize);
|
||||
int outsideMap = Boolean.compare(o1.getValue() < -HALF_WORLD_SIZE, o2.getValue() < -HALF_WORLD_SIZE);
|
||||
|
||||
if (outsideMap != 0)
|
||||
{
|
||||
@ -127,17 +164,8 @@ public class ItemMapManager extends MiniPlugin
|
||||
|
||||
return Double.compare(dist1, dist2);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
for (int x = -_halfMapSize; x < _halfMapSize; x += _blocksScan)
|
||||
{
|
||||
for (int z = -_halfMapSize - 16; z < _halfMapSize; z += (z < -_halfMapSize ? 16 : _blocksScan))
|
||||
{
|
||||
_scanList.add(new HashMap.SimpleEntry(x, z));
|
||||
}
|
||||
}
|
||||
|
||||
_scale.put(0, 1);
|
||||
// _scale.put(1, 2);
|
||||
_scale.put(1, 4);
|
||||
@ -147,7 +175,7 @@ public class ItemMapManager extends MiniPlugin
|
||||
|
||||
for (Entry<Integer, Integer> entry : _scale.entrySet())
|
||||
{
|
||||
int size = (_halfMapSize * 2) / entry.getValue();
|
||||
int size = (HALF_WORLD_SIZE * 2) / entry.getValue();
|
||||
Byte[][] bytes = new Byte[size][];
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
@ -165,6 +193,23 @@ public class ItemMapManager extends MiniPlugin
|
||||
|
||||
_world = Bukkit.getWorld("world");
|
||||
|
||||
try
|
||||
{
|
||||
Field chunkLoader = ChunkProviderServer.class.getDeclaredField("chunkLoader");
|
||||
chunkLoader.setAccessible(true);
|
||||
_nmsWorld = ((CraftWorld) _world).getHandle();
|
||||
_chunkProviderServer = _nmsWorld.chunkProviderServer;
|
||||
_chunkRegionLoader = (ChunkRegionLoader) chunkLoader.get(_chunkProviderServer);
|
||||
if (_chunkRegionLoader == null)
|
||||
{
|
||||
throw new RuntimeException("Did not expect null chunkLoader");
|
||||
}
|
||||
}
|
||||
catch (ReflectiveOperationException e)
|
||||
{
|
||||
throw new RuntimeException("Could not reflectively access ChunkRegionLoader", e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
File file = new File("world/clans_map_id");
|
||||
@ -238,6 +283,58 @@ public class ItemMapManager extends MiniPlugin
|
||||
}
|
||||
|
||||
rebuildScan();
|
||||
initialScan();
|
||||
}
|
||||
|
||||
private void initialScan()
|
||||
{
|
||||
System.out.println("Beginning initial scan. There are " + _scanList.size() + " regions to scan");
|
||||
|
||||
// How many regions before logging an update (Currently set to every 20%)
|
||||
int logPer = _scanList.size() / 5;
|
||||
|
||||
while (!_scanList.isEmpty())
|
||||
{
|
||||
Entry<Integer, Integer> entry = _scanList.remove(0);
|
||||
if (_scanList.size() % logPer == 0)
|
||||
{
|
||||
System.out.println("Running initial render... " + _scanList.size() + " sections to go");
|
||||
}
|
||||
|
||||
int startingX = entry.getKey();
|
||||
int startingZ = entry.getValue();
|
||||
|
||||
boolean outsideMap = startingZ < -HALF_WORLD_SIZE;
|
||||
|
||||
scanWorldMap(startingX, startingZ, !outsideMap, true);
|
||||
|
||||
if (outsideMap)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int scale = 1; scale < _scale.size(); scale++)
|
||||
{
|
||||
if (scale == 3)
|
||||
continue;
|
||||
|
||||
drawWorldScale(scale, startingX, startingZ);
|
||||
colorWorldHeight(scale, startingX, startingZ);
|
||||
}
|
||||
|
||||
colorWorldHeight(0, startingX, startingZ);
|
||||
}
|
||||
|
||||
for (int x = -HALF_WORLD_SIZE; x < HALF_WORLD_SIZE; x += BLOCK_SCAN_INTERVAL)
|
||||
{
|
||||
for (int z = -HALF_WORLD_SIZE; z < HALF_WORLD_SIZE; z += BLOCK_SCAN_INTERVAL)
|
||||
{
|
||||
drawWorldScale(3, x, z);
|
||||
colorWorldHeight(3, x, z);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("Finished first map scan and render");
|
||||
}
|
||||
|
||||
private void setupRenderer(MapView view)
|
||||
@ -256,10 +353,7 @@ public class ItemMapManager extends MiniPlugin
|
||||
if (!(event.getRightClicked() instanceof ItemFrame))
|
||||
return;
|
||||
|
||||
ItemStack item = event.getPlayer().getItemInHand();
|
||||
|
||||
if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId
|
||||
|| item.getDurability() > _mapId + 100)
|
||||
if (!isItemClansMap(event.getPlayer().getItemInHand()))
|
||||
return;
|
||||
|
||||
event.setCancelled(true);
|
||||
@ -270,7 +364,7 @@ public class ItemMapManager extends MiniPlugin
|
||||
*/
|
||||
public int calcMapCenter(int zoom, int cord)
|
||||
{
|
||||
int mapSize = _halfMapSize / zoom; // This is how large the map is in pixels
|
||||
int mapSize = HALF_WORLD_SIZE / zoom; // This is how large the map is in pixels
|
||||
|
||||
int mapCord = cord / zoom; // This is pixels from true center of map, not held map
|
||||
|
||||
@ -309,7 +403,7 @@ public class ItemMapManager extends MiniPlugin
|
||||
Byte[][] map = _map.get(scale);
|
||||
int zoom = getZoom(scale);
|
||||
|
||||
for (int x = startingX; x < startingX + _blocksScan; x += zoom)
|
||||
for (int x = startingX; x < startingX + BLOCK_SCAN_INTERVAL; x += zoom)
|
||||
{
|
||||
double d0 = 0;
|
||||
|
||||
@ -319,10 +413,10 @@ public class ItemMapManager extends MiniPlugin
|
||||
{
|
||||
for (int addZ = 0; addZ < zoom; addZ++)
|
||||
{
|
||||
int hX = x + addX + _halfMapSize;
|
||||
int hZ = (startingZ - zoom) + addZ + _halfMapSize;
|
||||
int hX = x + addX + HALF_WORLD_SIZE;
|
||||
int hZ = (startingZ - zoom) + addZ + HALF_WORLD_SIZE;
|
||||
|
||||
if (hX >= _halfMapSize * 2 || hZ >= _halfMapSize * 2)
|
||||
if (hX >= HALF_WORLD_SIZE * 2 || hZ >= HALF_WORLD_SIZE * 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -331,7 +425,7 @@ public class ItemMapManager extends MiniPlugin
|
||||
}
|
||||
}
|
||||
|
||||
for (int z = startingZ; z < startingZ + _blocksScan; z += zoom)
|
||||
for (int z = startingZ; z < startingZ + BLOCK_SCAN_INTERVAL; z += zoom)
|
||||
{
|
||||
// Water depth colors not included
|
||||
double d1 = 0;
|
||||
@ -340,10 +434,10 @@ public class ItemMapManager extends MiniPlugin
|
||||
{
|
||||
for (int addZ = 0; addZ < zoom; addZ++)
|
||||
{
|
||||
int hX = x + addX + _halfMapSize;
|
||||
int hZ = z + addZ + _halfMapSize;
|
||||
int hX = x + addX + HALF_WORLD_SIZE;
|
||||
int hZ = z + addZ + HALF_WORLD_SIZE;
|
||||
|
||||
if (hX >= _halfMapSize * 2 || hZ >= _halfMapSize * 2)
|
||||
if (hX >= HALF_WORLD_SIZE * 2 || hZ >= HALF_WORLD_SIZE * 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -370,7 +464,7 @@ public class ItemMapManager extends MiniPlugin
|
||||
b0 = 0;
|
||||
}
|
||||
|
||||
int origColor = map[(x + _halfMapSize) / zoom][(z + _halfMapSize) / zoom] - 1;
|
||||
int origColor = map[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] - 1;
|
||||
|
||||
/*if (color < 4)
|
||||
{
|
||||
@ -388,7 +482,7 @@ public class ItemMapManager extends MiniPlugin
|
||||
}*/
|
||||
|
||||
byte color = (byte) (origColor + b0);
|
||||
map[(x + _halfMapSize) / zoom][(z + _halfMapSize) / zoom] = color;
|
||||
map[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -399,9 +493,9 @@ public class ItemMapManager extends MiniPlugin
|
||||
Byte[][] second = _map.get(scale);
|
||||
int zoom = getZoom(scale);
|
||||
|
||||
for (int x = startingX; x < startingX + _blocksScan; x += zoom)
|
||||
for (int x = startingX; x < startingX + BLOCK_SCAN_INTERVAL; x += zoom)
|
||||
{
|
||||
for (int z = startingZ; z < startingZ + _blocksScan; z += zoom)
|
||||
for (int z = startingZ; z < startingZ + BLOCK_SCAN_INTERVAL; z += zoom)
|
||||
{
|
||||
HashMultiset<Byte> hashmultiset = HashMultiset.create();
|
||||
|
||||
@ -409,8 +503,8 @@ public class ItemMapManager extends MiniPlugin
|
||||
{
|
||||
for (int addZ = 0; addZ < zoom; addZ++)
|
||||
{
|
||||
int pX = x + addX + _halfMapSize;
|
||||
int pZ = z + addZ + _halfMapSize;
|
||||
int pX = x + addX + HALF_WORLD_SIZE;
|
||||
int pZ = z + addZ + HALF_WORLD_SIZE;
|
||||
|
||||
if (pX >= first.length || pZ >= first.length)
|
||||
{
|
||||
@ -432,7 +526,7 @@ public class ItemMapManager extends MiniPlugin
|
||||
{
|
||||
color = (byte) 0;
|
||||
}
|
||||
second[(x + _halfMapSize) / zoom][(z + _halfMapSize) / zoom] = color;
|
||||
second[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -440,27 +534,18 @@ public class ItemMapManager extends MiniPlugin
|
||||
@EventHandler
|
||||
public void dropItem(ItemSpawnEvent event)
|
||||
{
|
||||
ItemStack item = event.getEntity().getItemStack();
|
||||
|
||||
if (item != null && item.getType() == Material.MAP && item.getDurability() >= _mapId
|
||||
&& item.getDurability() <= _mapId + 100)
|
||||
{
|
||||
if (isItemClansMap(event.getEntity().getItemStack()))
|
||||
event.getEntity().remove();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeMap(Player player)
|
||||
{
|
||||
for (int slot = 0; slot < player.getInventory().getSize(); slot++)
|
||||
{
|
||||
ItemStack item = player.getInventory().getItem(slot);
|
||||
|
||||
if (item != null && item.getType() == Material.MAP && item.getDurability() >= _mapId && item.getDurability() <= _mapId + 100)
|
||||
{
|
||||
if (isItemClansMap(player.getInventory().getItem(slot)))
|
||||
player.getInventory().setItem(slot, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ClansUtility getClansUtility()
|
||||
{
|
||||
@ -477,7 +562,7 @@ public class ItemMapManager extends MiniPlugin
|
||||
|
||||
private double getDistance(Entry<Integer, Integer> entry, double x1, double z1)
|
||||
{
|
||||
return getDistance(x1, z1, entry.getKey() + (_blocksScan / 2), entry.getValue() + (_blocksScan / 2));
|
||||
return getDistance(x1, z1, entry.getKey() + (BLOCK_SCAN_INTERVAL / 2), entry.getValue() + (BLOCK_SCAN_INTERVAL / 2));
|
||||
}
|
||||
|
||||
public Byte[][] getMap(int scale)
|
||||
@ -492,7 +577,7 @@ public class ItemMapManager extends MiniPlugin
|
||||
|
||||
public int getMapSize()
|
||||
{
|
||||
return _halfMapSize;
|
||||
return HALF_WORLD_SIZE;
|
||||
}
|
||||
|
||||
public int getZoom(int scale)
|
||||
@ -500,35 +585,7 @@ public class ItemMapManager extends MiniPlugin
|
||||
return _scale.get(scale);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void preventMapMoveInventories(InventoryClickEvent event)
|
||||
{
|
||||
Inventory inv = event.getClickedInventory();
|
||||
|
||||
if (inv == null)
|
||||
return;
|
||||
|
||||
// Yeah, the loop looks a little weird..
|
||||
for (ItemStack item : new ItemStack[]
|
||||
{
|
||||
event.getCurrentItem(), event.getCursor()
|
||||
})
|
||||
{
|
||||
if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId
|
||||
|| item.getDurability() > _mapId + 100)
|
||||
continue;
|
||||
|
||||
if (inv.getHolder() instanceof Player ? !event.isShiftClick() : Objects.equal(event.getCurrentItem(), item))
|
||||
continue;
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
UtilPlayer.message(event.getWhoClicked(),
|
||||
F.main("Inventory", "You cannot move " + F.item("Clans Map") + " between inventories."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//fixme So what appears to happen is that after you die, if your map is is the same then the map is frozen
|
||||
@EventHandler
|
||||
public void onDeath(PlayerDeathEvent event)
|
||||
{
|
||||
@ -542,14 +599,10 @@ public class ItemMapManager extends MiniPlugin
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
|
||||
ItemStack item = player.getInventory().getItem(event.getNewSlot());
|
||||
|
||||
if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId
|
||||
|| item.getDurability() > _mapId + 100)
|
||||
if (!isItemClansMap(player.getInventory().getItem(event.getNewSlot())))
|
||||
return;
|
||||
|
||||
showZoom(player, getMap(player));
|
||||
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@ -558,10 +611,7 @@ public class ItemMapManager extends MiniPlugin
|
||||
if (event.getAction() == Action.PHYSICAL)
|
||||
return;
|
||||
|
||||
ItemStack item = event.getItem();
|
||||
|
||||
if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId
|
||||
|| item.getDurability() > _mapId + 100)
|
||||
if (!isItemClansMap(event.getItem()))
|
||||
return;
|
||||
|
||||
event.setCancelled(true);
|
||||
@ -666,36 +716,11 @@ public class ItemMapManager extends MiniPlugin
|
||||
|
||||
private void rebuildScan()
|
||||
{
|
||||
for (int x = -_halfMapSize; x < _halfMapSize; x += _blocksScan)
|
||||
for (int x = -HALF_WORLD_SIZE; x < HALF_WORLD_SIZE; x += BLOCK_SCAN_INTERVAL)
|
||||
{
|
||||
for (int z = -_halfMapSize - 16; z < _halfMapSize; z += (z < -_halfMapSize ? 16 : _blocksScan))
|
||||
for (int z = -HALF_WORLD_SIZE - 16; z < HALF_WORLD_SIZE; z += (z < -HALF_WORLD_SIZE ? 16 : BLOCK_SCAN_INTERVAL))
|
||||
{
|
||||
_scanList.add(new HashMap.SimpleEntry(x, z));
|
||||
}
|
||||
}
|
||||
|
||||
if (!_loadWorld)
|
||||
{
|
||||
Iterator<Entry<Integer, Integer>> itel = _scanList.iterator();
|
||||
|
||||
while (itel.hasNext())
|
||||
{
|
||||
Entry<Integer, Integer> entry = itel.next();
|
||||
boolean removeEntry = true;
|
||||
|
||||
for (Player player : UtilServer.getPlayers())
|
||||
{
|
||||
if (Math.sqrt(getDistance(entry, player.getLocation().getX(), player.getLocation().getZ())) < 200)
|
||||
{
|
||||
removeEntry = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (removeEntry)
|
||||
{
|
||||
itel.remove();
|
||||
}
|
||||
_scanList.add(new HashMap.SimpleEntry<>(x, z));
|
||||
}
|
||||
}
|
||||
|
||||
@ -744,101 +769,117 @@ public class ItemMapManager extends MiniPlugin
|
||||
if (event.getType() != UpdateType.FAST)
|
||||
return;
|
||||
|
||||
if (_scanList.isEmpty())
|
||||
if (_scanList.isEmpty() && UtilServer.getPlayers().length > 0)
|
||||
{
|
||||
if (_loadWorld)
|
||||
{
|
||||
for (int x = -_halfMapSize; x < _halfMapSize; x += _blocksScan)
|
||||
{
|
||||
for (int z = -_halfMapSize; z < _halfMapSize; z += _blocksScan)
|
||||
{
|
||||
drawWorldScale(3, x, z);
|
||||
colorWorldHeight(3, x, z);
|
||||
}
|
||||
}
|
||||
|
||||
System.out.print("Finished first map scan and render");
|
||||
}
|
||||
|
||||
_loadWorld = false;
|
||||
|
||||
if (UtilServer.getPlayers().length == 0)
|
||||
return;
|
||||
|
||||
rebuildScan();
|
||||
}
|
||||
else if (_scanList.size() % 20 == 0)
|
||||
|
||||
if (_scanList.size() % 20 == 0)
|
||||
{
|
||||
Collections.sort(_scanList, _comparator);
|
||||
}
|
||||
|
||||
if (_scanList.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Entry<Integer, Integer> entry = _scanList.remove(0);
|
||||
|
||||
int startingX = entry.getKey();
|
||||
int startingZ = entry.getValue();
|
||||
|
||||
boolean outsideMap = startingZ < -_halfMapSize;
|
||||
boolean outsideMap = startingZ < -HALF_WORLD_SIZE;
|
||||
|
||||
scanWorldMap(startingX, startingZ, !outsideMap);
|
||||
scanWorldMap(startingX, startingZ, !outsideMap, false);
|
||||
|
||||
if (outsideMap)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int scale = 1; scale < _scale.size(); scale++)
|
||||
{
|
||||
if (scale == 3 && _loadWorld)
|
||||
continue;
|
||||
|
||||
if (!outsideMap)
|
||||
{
|
||||
drawWorldScale(scale, startingX, startingZ);
|
||||
}
|
||||
|
||||
colorWorldHeight(scale, startingX, startingZ);
|
||||
}
|
||||
|
||||
colorWorldHeight(0, startingX, startingZ);
|
||||
}
|
||||
|
||||
public void scanWorldMap(int startingX, int startingZ, boolean setColors)
|
||||
|
||||
// Let's not create hundreds of thousands of BlockPositions
|
||||
// Single thread = should be thread safe
|
||||
private BlockPosition.MutableBlockPosition _blockPosition = new BlockPosition.MutableBlockPosition();
|
||||
|
||||
// Maps the cached chunks which were loaded from disk to save IO operations
|
||||
private LongObjectHashMap<Chunk> _chunkCache = new LongObjectHashMap<>();
|
||||
|
||||
/*
|
||||
* Remove the cached chunks when the real chunks are loaded in
|
||||
*/
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void LoadChunk(ChunkLoadEvent event)
|
||||
{
|
||||
_chunkCache.remove(LongHash.toLong(event.getChunk().getX(), event.getChunk().getZ()));
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a particular coordinate, this method will scan up to BLOCK_SCAN_INTERVAL and record the color of ever 16th block
|
||||
* If a chunk has not been loaded, the following steps will be taken:
|
||||
* * Attempt to load the chunk from disk.
|
||||
* * If the chunk could not be loaded, generate it froms scratch
|
||||
* Otherwise, the loaded chunk will be used
|
||||
*/
|
||||
public void scanWorldMap(int startingX, int startingZ, boolean setColors, boolean isFirstScan)
|
||||
{
|
||||
Byte[][] map = _map.get(0);
|
||||
|
||||
for (int beginX = startingX; beginX < startingX + _blocksScan; beginX += 16)
|
||||
for (int beginX = startingX; beginX < startingX + BLOCK_SCAN_INTERVAL; beginX += 16)
|
||||
{
|
||||
for (int beginZ = startingZ - (startingZ > -_halfMapSize ? 16 : 0); beginZ < startingZ
|
||||
+ (setColors ? _blocksScan : 16); beginZ += 16)
|
||||
for (int beginZ = startingZ - (startingZ > -HALF_WORLD_SIZE ? 16 : 0); beginZ < startingZ
|
||||
+ (setColors ? BLOCK_SCAN_INTERVAL : 16); beginZ += 16)
|
||||
{
|
||||
Chunk chunk = _world.getChunkAt(beginX / 16, beginZ / 16);
|
||||
boolean loaded = false;
|
||||
|
||||
if (!chunk.isLoaded())
|
||||
int chunkX = beginX / 16;
|
||||
int chunkZ = beginZ / 16;
|
||||
net.minecraft.server.v1_8_R3.Chunk nmsChunk = _chunkProviderServer.getChunkIfLoaded(chunkX, chunkZ);
|
||||
if (nmsChunk == null)
|
||||
{
|
||||
if (_loadWorld)
|
||||
long key = LongHash.toLong(chunkX, chunkZ);
|
||||
nmsChunk = _chunkCache.get(key);
|
||||
if (nmsChunk == null)
|
||||
{
|
||||
loaded = chunk.load();
|
||||
}
|
||||
else
|
||||
if (!isFirstScan)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
Object[] data = _chunkRegionLoader.loadChunk(_nmsWorld, chunkX, chunkZ);
|
||||
if (data == null)
|
||||
{
|
||||
// Something is wrong with the chunk
|
||||
System.out.println("Chunk is not generated or missing level/block data. Regenerating (" + chunkX + "," + chunkZ + ")");
|
||||
nmsChunk = ((CraftChunk) _world.getChunkAt(chunkX, chunkZ)).getHandle();
|
||||
}
|
||||
else
|
||||
{
|
||||
nmsChunk = (net.minecraft.server.v1_8_R3.Chunk) data[0];
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException("Chunk is corrupt or not readable!", e);
|
||||
}
|
||||
_chunkCache.put(key, nmsChunk);
|
||||
}
|
||||
}
|
||||
|
||||
net.minecraft.server.v1_8_R3.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
|
||||
|
||||
if (!nmsChunk.isEmpty())
|
||||
{
|
||||
for (int x = beginX; x < beginX + 16; x++)
|
||||
{
|
||||
for (int z = beginZ; z < beginZ + 16; z++)
|
||||
{
|
||||
int color = 0;
|
||||
|
||||
if (!nmsChunk.isEmpty())
|
||||
{
|
||||
int k3 = x & 0xF;
|
||||
int l3 = z & 0xF;
|
||||
|
||||
@ -850,7 +891,8 @@ public class ItemMapManager extends MiniPlugin
|
||||
do
|
||||
{
|
||||
l4--;
|
||||
iblockdata= nmsChunk.getBlockData(new BlockPosition(k3, l4, l3));
|
||||
_blockPosition.c(k3, l4, l3);
|
||||
iblockdata = nmsChunk.getBlockData(_blockPosition);
|
||||
}
|
||||
while (iblockdata.getBlock().g(iblockdata) == MaterialMapColor.b && (l4 > 0));
|
||||
|
||||
@ -860,33 +902,30 @@ public class ItemMapManager extends MiniPlugin
|
||||
Block block1;
|
||||
do
|
||||
{
|
||||
block1 = nmsChunk.getType(new BlockPosition(k3, j5--, l3));
|
||||
_blockPosition.c(k3, j5--, l3);
|
||||
block1 = nmsChunk.getType(_blockPosition);
|
||||
}
|
||||
while ((j5 > 0) && (block1.getMaterial().isLiquid()));
|
||||
}
|
||||
}
|
||||
|
||||
_heightMap[x + _halfMapSize + 16][z + _halfMapSize + 16] = l4;
|
||||
_heightMap[x + HALF_WORLD_SIZE + 16][z + HALF_WORLD_SIZE + 16] = l4;
|
||||
|
||||
if (setColors)
|
||||
{
|
||||
//color = block.f(i5).M;
|
||||
IBlockData data = nmsChunk.getBlockData(new BlockPosition(k3, l4, l3));
|
||||
_blockPosition.c(k3, l4, l3);
|
||||
IBlockData data = nmsChunk.getBlockData(_blockPosition);
|
||||
color = data.getBlock().g(data).M;
|
||||
|
||||
color = (byte) ((color * 4) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (setColors && beginZ >= startingZ)
|
||||
{
|
||||
map[x + _halfMapSize][z + _halfMapSize] = (byte) color;
|
||||
map[x + HALF_WORLD_SIZE][z + HALF_WORLD_SIZE] = (byte) color;
|
||||
}
|
||||
}
|
||||
|
||||
if (loaded)
|
||||
{
|
||||
chunk.unload();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -901,7 +940,7 @@ public class ItemMapManager extends MiniPlugin
|
||||
|
||||
for (ItemStack item : UtilInv.getItems(player))
|
||||
{
|
||||
if (item.getType() == Material.MAP && (item.getDurability() >= _mapId && item.getDurability() <= _mapId + 100))
|
||||
if (isItemClansMap(item))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -909,62 +948,38 @@ public class ItemMapManager extends MiniPlugin
|
||||
|
||||
ItemStack item = new ItemBuilder(Material.MAP, 1, (short) getMap(player).getMap()).setTitle("Clans Map").build();
|
||||
|
||||
int slot = player.getInventory().firstEmpty();
|
||||
int slot = CLANS_MAP_SLOT;
|
||||
|
||||
ItemStack mapSlot = player.getInventory().getItem(slot);
|
||||
if (mapSlot != null && mapSlot.getType() != Material.AIR)
|
||||
{
|
||||
slot = player.getInventory().firstEmpty();
|
||||
}
|
||||
|
||||
if (slot >= 0)
|
||||
{
|
||||
ItemStack mapSlot = player.getInventory().getItem(8);
|
||||
|
||||
if (mapSlot == null || mapSlot.getType() == Material.AIR)
|
||||
{
|
||||
slot = 8;
|
||||
}
|
||||
|
||||
player.getInventory().setItem(slot, item);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Displays the action bar to a player given their zoom level. Implementation may change
|
||||
*/
|
||||
private void showZoom(Player player, MapInfo info)
|
||||
{
|
||||
String progressBar = C.cBlue + "";
|
||||
UtilTextBottom.display(ZOOM_INFO[info.getScale()], player);
|
||||
}
|
||||
|
||||
boolean colorChange = false;
|
||||
|
||||
for (int i = 2; i >= 0; i--)
|
||||
/*
|
||||
* Check whether an {@link ItemStack} is also a Clans Map
|
||||
*
|
||||
* @param itemStack The {@link ItemStack} to check
|
||||
* @returns Whether the {@link ItemStack} is also a Clans Map
|
||||
*/
|
||||
private boolean isItemClansMap(ItemStack itemStack)
|
||||
{
|
||||
if (!colorChange && i < info.getScale())
|
||||
{
|
||||
progressBar += C.cGray;
|
||||
colorChange = true;
|
||||
}
|
||||
|
||||
char c;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
c = '█';
|
||||
break;
|
||||
case 1:
|
||||
c = '▆';
|
||||
break;
|
||||
default:
|
||||
c = '▄';
|
||||
break;
|
||||
}
|
||||
|
||||
for (int a = 0; a < 4; a++)
|
||||
{
|
||||
progressBar += c;
|
||||
}
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
progressBar += " ";
|
||||
return UtilItem.matchesMaterial(itemStack, Material.MAP)
|
||||
&& itemStack.getDurability() >= _mapId
|
||||
&& itemStack.getDurability() <= _mapId + 100;
|
||||
}
|
||||
}
|
||||
|
||||
UtilTextBottom.display(progressBar, player);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,9 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
/*
|
||||
* This event is called when a Player is about to receive a Clans Map
|
||||
*/
|
||||
public class PlayerGetMapEvent extends Event
|
||||
{
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
@ -73,7 +73,7 @@ public class MurderManager extends MiniClientPlugin<ClientMurder>
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler (ignoreCancelled = true)
|
||||
public void onPickup(PlayerPickupItemEvent event)
|
||||
{
|
||||
refreshClient(event.getPlayer());
|
||||
|
@ -131,7 +131,7 @@ public class ObserverManager extends MiniPlugin
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler (priority = EventPriority.LOWEST)
|
||||
public void onPickup(PlayerPickupItemEvent event)
|
||||
{
|
||||
ObserverData data = _observerMap.get(event.getPlayer());
|
||||
|
@ -197,18 +197,7 @@ public class ClansRegions extends MiniPlugin
|
||||
{
|
||||
int x = chunkX + xOffset;
|
||||
int z = chunkZ + zOffset;
|
||||
Chunk chunk;
|
||||
try
|
||||
{ //Corrupted chunk will hold up whole server
|
||||
chunk = location.getWorld().getChunkAt(x, z);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
System.out.println("UNABLE TO LOAD CHUNK AT " + x + " , " + z);
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
String chunkStr = UtilWorld.chunkToStr(chunk);
|
||||
String chunkStr = location.getWorld().getName() + "," + x + "," + z;
|
||||
|
||||
if (addNegative)
|
||||
{
|
||||
|
@ -132,7 +132,7 @@ public class SiegeWeaponRepository extends MinecraftRepository
|
||||
|
||||
public void updateWeapon(SiegeWeaponToken token)
|
||||
{
|
||||
System.out.println("Siege Repo> Updating weapon " + token.UniqueId);
|
||||
// System.out.println("Siege Repo> Updating weapon " + token.UniqueId);
|
||||
|
||||
_siegeManager.runAsync(() ->
|
||||
executeUpdate(UPDATE_WEAPON,
|
||||
|
@ -27,6 +27,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.util.EulerAngle;
|
||||
import org.spigotmc.event.entity.EntityDismountEvent;
|
||||
|
||||
@ -559,6 +560,7 @@ public abstract class SiegeWeapon implements Listener
|
||||
{
|
||||
entity.setCustomName(Integer.toString(_uniqueId));
|
||||
entity.setCustomNameVisible(false);
|
||||
entity.setMetadata("Creature.DoNotDrop", new FixedMetadataValue(_clans.getPlugin(), true));
|
||||
|
||||
_comprisedOf.add(entity);
|
||||
|
||||
@ -569,6 +571,8 @@ public abstract class SiegeWeapon implements Listener
|
||||
{
|
||||
Entity entity = _entityMapping.get(uniqueName);
|
||||
|
||||
entity.removeMetadata("Creature.DoNotDrop", _clans.getPlugin());
|
||||
|
||||
_entityMapping.remove(uniqueName);
|
||||
_comprisedOf.remove(entity);
|
||||
|
||||
|
@ -113,7 +113,7 @@ public class GoldManager extends MiniPlugin
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler (ignoreCancelled = true)
|
||||
public void onPickup(PlayerPickupItemEvent event)
|
||||
{
|
||||
if (_itemSet.contains(event.getItem()))
|
||||
|
@ -868,6 +868,12 @@ public class Gameplay extends MiniPlugin
|
||||
}
|
||||
}
|
||||
|
||||
if (_blockRestore.contains(event.getClickedBlock()))
|
||||
{
|
||||
UtilPlayer.message(player, F.main("Repair", "You cannot repair using that anvil"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Repair!
|
||||
UtilPlayer.message(player, F.main("Repair", "You repaired " + F.item(item.getItemMeta().getDisplayName()) + "."));
|
||||
item.setDurability((short) 0);
|
||||
|
@ -29,7 +29,7 @@ import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||
* @author MrTwiggy
|
||||
*
|
||||
*/
|
||||
public class CustomItem
|
||||
public class CustomItem implements Listener
|
||||
{
|
||||
|
||||
private static final ChatColor TITLE_COLOR = ChatColor.GOLD; // Chat color
|
||||
@ -73,6 +73,7 @@ public class CustomItem
|
||||
_material = material;
|
||||
_attributes = new AttributeContainer();
|
||||
_uuid = UUID.randomUUID().toString();
|
||||
UtilServer.RegisterEvents(this);
|
||||
}
|
||||
|
||||
public CustomItem(Material material)
|
||||
|
@ -1,8 +1,12 @@
|
||||
package mineplex.game.clans.items.attributes;
|
||||
|
||||
import mineplex.game.clans.clans.ClansManager;
|
||||
import mineplex.game.clans.clans.ClansUtility;
|
||||
import mineplex.game.clans.items.generation.ValueDistribution;
|
||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
|
||||
@ -127,4 +131,21 @@ public abstract class ItemAttribute
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
protected boolean isTeammate(Entity attacker, Entity defender)
|
||||
{
|
||||
if (attacker == null || defender == null) return false;
|
||||
// Don't count attacks towards teammates
|
||||
if (attacker instanceof Player && defender instanceof Player)
|
||||
{
|
||||
ClansUtility.ClanRelation relation = ClansManager.getInstance().getRelation((Player) attacker, (Player) defender);
|
||||
if (relation == ClansUtility.ClanRelation.ALLY
|
||||
|| relation == ClansUtility.ClanRelation.SAFE
|
||||
|| relation == ClansUtility.ClanRelation.SELF)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ public class FlamingAttribute extends AttackAttribute
|
||||
if(attacker instanceof Player && ClansManager.getInstance().isSafe((Player) attacker)) return;
|
||||
if(defender instanceof Player && ClansManager.getInstance().isSafe((Player) defender)) return;
|
||||
if(attacker instanceof Player && ((Player)attacker).getGameMode().equals(GameMode.CREATIVE)) return;
|
||||
if (isTeammate(attacker, defender)) return;
|
||||
defender.setFireTicks(_fireDuration);
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,7 @@ public class FrostedAttribute extends ItemAttribute
|
||||
|
||||
if (victim != null)
|
||||
{
|
||||
if (isTeammate(event.GetDamagerPlayer(true), victim)) return;
|
||||
victim.addPotionEffect(generateSlowEffect()); // Slow attacking player
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ public class HasteAttribute extends AttackAttribute
|
||||
@Override
|
||||
public void triggerAttack(Entity attacker, Entity defender)
|
||||
{
|
||||
if (isTeammate(attacker, defender)) return;
|
||||
if (attacker instanceof Player)
|
||||
{
|
||||
Player player = (Player) attacker;
|
||||
|
@ -28,6 +28,7 @@ public class JaggedAttribute extends AttackAttribute {
|
||||
|
||||
@Override
|
||||
public void triggerAttack(Entity attacker, Entity defender) {
|
||||
if (isTeammate(attacker, defender)) return;
|
||||
defender.setVelocity(new Vector(0, 0, 0));
|
||||
if (defender instanceof LivingEntity)
|
||||
((LivingEntity) defender).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20, 1, false, false));
|
||||
|
@ -38,6 +38,8 @@ public class VampiricAttribute extends ItemAttribute
|
||||
{
|
||||
Player damager = event.GetDamagerPlayer(false);
|
||||
|
||||
if (isTeammate(damager, event.GetDamageePlayer())) return;
|
||||
|
||||
double damage = event.GetDamage();
|
||||
double healAmount = damage * (_healPercent / 100d);
|
||||
heal(damager, healAmount);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package mineplex.game.clans.items.legendaries;
|
||||
|
||||
import mineplex.core.recharge.Recharge;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -14,7 +15,7 @@ import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||
public class GiantsBroadsword extends LegendaryItem
|
||||
{
|
||||
public static final int SLOW_AMPLIFIER = 43;
|
||||
public static final int REGEN_AMPLIFIER = 3;
|
||||
public static final int REGEN_AMPLIFIER = 1;
|
||||
|
||||
public GiantsBroadsword()
|
||||
{
|
||||
@ -60,6 +61,7 @@ public class GiantsBroadsword extends LegendaryItem
|
||||
private void buffPlayer(Player player)
|
||||
{
|
||||
grantPotionEffect(player, PotionEffectType.SLOW, 40, SLOW_AMPLIFIER);
|
||||
grantPotionEffect(player, PotionEffectType.REGENERATION, 2, REGEN_AMPLIFIER); //Regen
|
||||
if (Recharge.Instance.use(player, "Giants Broadsword Regen", 250L, false, false, false))
|
||||
grantPotionEffect(player, PotionEffectType.REGENERATION, 5, REGEN_AMPLIFIER); //Regen
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public class HyperAxe extends LegendaryItem
|
||||
C.cWhite + "blade can rip through any opponent.",
|
||||
C.cWhite + " ",
|
||||
C.cWhite + "Hit delay is reduced by " + C.cYellow + "50%",
|
||||
C.cWhite + "Deals " + C.cYellow + "10 Damage" + C.cWhite + " with attack",
|
||||
C.cWhite + "Deals " + C.cYellow + "3 Damage" + C.cWhite + " with attack",
|
||||
C.cYellow + "Right-Click" + C.cWhite + " to use " + C.cGreen + "Dash",
|
||||
}, Material.RECORD_3);
|
||||
_speedAmount = amountGen.generateIntValue();
|
||||
|
@ -1,11 +1,6 @@
|
||||
package mineplex.game.clans.items.legendaries;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.UtilAction;
|
||||
import mineplex.core.common.util.UtilAlg;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
@ -18,6 +13,12 @@ import mineplex.core.common.util.UtilWorld;
|
||||
import mineplex.game.clans.clans.ClansManager;
|
||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class MagneticMaul extends LegendaryItem
|
||||
{
|
||||
public static final double PULL_RANGE = 10d;
|
||||
@ -28,7 +29,9 @@ public class MagneticMaul extends LegendaryItem
|
||||
public MagneticMaul()
|
||||
{
|
||||
super("Magnetic Maul", new String[] {
|
||||
|
||||
C.cWhite + "This brutal weapon allows you to pull your enemies towards you with magnetic force!"
|
||||
+ " ",
|
||||
C.cYellow + "Right-Click" + C.cWhite + " to use Maul."
|
||||
}, Material.RECORD_5);
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,6 @@
|
||||
package mineplex.game.clans.items.legendaries;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.Vector;
|
||||
import java.util.HashMap;
|
||||
|
||||
import mineplex.core.common.util.C;
|
||||
import mineplex.core.common.util.F;
|
||||
@ -20,26 +9,37 @@ import mineplex.core.common.util.RGBData;
|
||||
import mineplex.core.common.util.UtilBlock;
|
||||
import mineplex.core.common.util.UtilCollections;
|
||||
import mineplex.core.common.util.UtilColor;
|
||||
import mineplex.core.common.util.UtilEnt;
|
||||
import mineplex.core.common.util.UtilParticle;
|
||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilParticle.ViewDist;
|
||||
import mineplex.core.incognito.IncognitoManager;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.common.util.UtilShapes;
|
||||
import mineplex.core.common.util.UtilText;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.common.util.UtilTime.TimeUnit;
|
||||
import mineplex.core.recharge.Recharge;
|
||||
import mineplex.game.clans.clans.ClansManager;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public class MeridianScepter extends LegendaryItem
|
||||
{
|
||||
private long _lastFire = System.currentTimeMillis();
|
||||
private long _interactWait;
|
||||
|
||||
private RGBData[] colors = { UtilColor.RgbPurple, UtilColor.RgbPurple.Lighten(), UtilColor.RgbPurple.Darken() };
|
||||
|
||||
private int _witherDamageTimes = 5;
|
||||
private HashMap<AttackAnimation, Integer> _animations = new HashMap<AttackAnimation, Integer>();
|
||||
|
||||
public MeridianScepter()
|
||||
{
|
||||
@ -101,20 +101,13 @@ public class MeridianScepter extends LegendaryItem
|
||||
// If they are less than 0.5 blocks away
|
||||
if (player.getEyeLocation().subtract(0, .3, 0).distance(projectile) <= 2)
|
||||
{
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.WITHER, 20 * _witherDamageTimes, 0));
|
||||
AttackAnimation aa = new AttackAnimation(player, shooter);
|
||||
int i = UtilServer.getServer().getScheduler().scheduleSyncRepeatingTask(UtilServer.getPlugin(), () -> {
|
||||
aa.update();
|
||||
}, 0, 1);
|
||||
_animations.put(aa, i);
|
||||
|
||||
int time = 0;
|
||||
|
||||
for (int i = 0; i < _witherDamageTimes; i++)
|
||||
{
|
||||
UtilServer.getServer().getScheduler().scheduleSyncDelayedTask(UtilServer.getPlugin(), () -> {
|
||||
ClansManager.getInstance().getDamageManager().NewDamageEvent(player, shooter, null,
|
||||
DamageCause.CUSTOM, 1.75, false, true, true,
|
||||
shooter.getName(), "Meridian Scepter");
|
||||
}, ++time * 20);
|
||||
}
|
||||
|
||||
UtilPlayer.message(player, F.main("Clans", F.elem(player.getName()) + " hit you with a " + F.elem("Meridian Scepter") + C.mBody + "."));
|
||||
UtilPlayer.message(player, F.main("Clans", F.elem(shooter.getName()) + " hit you with a " + F.elem("Meridian Scepter") + C.mBody + "."));
|
||||
UtilPlayer.message(shooter, F.main("Clans", "You hit " + F.elem(player.getName()) + " with your " + F.elem("Meridian Scepter") + C.mBody + "."));
|
||||
}
|
||||
}
|
||||
@ -258,4 +251,68 @@ public class MeridianScepter extends LegendaryItem
|
||||
UtilParticle.PlayParticleToAll(ParticleType.RED_DUST, loc, UtilCollections.random(colors).ToVector(), 1f, 0, ViewDist.LONG);
|
||||
}
|
||||
}
|
||||
|
||||
private class AttackAnimation
|
||||
{
|
||||
private Player _hit, _shooter;
|
||||
private double _step;
|
||||
private double _radius;
|
||||
private long _start, _lastStepIncrease;
|
||||
|
||||
public AttackAnimation(Player hit, Player shooter)
|
||||
{
|
||||
_step = 0;
|
||||
_start = System.currentTimeMillis();
|
||||
_lastStepIncrease = System.currentTimeMillis();
|
||||
_hit = hit;
|
||||
_shooter = shooter;
|
||||
_radius = 2;
|
||||
}
|
||||
|
||||
public void update()
|
||||
{
|
||||
if (_hit == null)
|
||||
{
|
||||
end();
|
||||
return;
|
||||
}
|
||||
if (UtilTime.elapsed(_lastStepIncrease, UtilTime.convert(1, TimeUnit.SECONDS, TimeUnit.MILLISECONDS)))
|
||||
{
|
||||
_step++;
|
||||
_lastStepIncrease = System.currentTimeMillis();
|
||||
}
|
||||
drawHelix();
|
||||
|
||||
if (UtilTime.elapsed(_start, 4000))
|
||||
{
|
||||
_hit.getWorld().strikeLightningEffect(_hit.getLocation());
|
||||
ClansManager.getInstance().getDamageManager().NewDamageEvent(_hit, _shooter, null,
|
||||
DamageCause.CUSTOM, 6, false, true, true,
|
||||
_shooter.getName(), "Meridian Scepter");
|
||||
ClansManager.getInstance().getCondition().Factory().Blind("Meridian Scepter", _hit, _shooter, 1, 0, true, true, true);
|
||||
end();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void end()
|
||||
{
|
||||
int id = _animations.remove(this);
|
||||
Bukkit.getScheduler().cancelTask(id);
|
||||
}
|
||||
|
||||
private void drawHelix()
|
||||
{
|
||||
double height = Math.min(_step * 2, 8D);
|
||||
|
||||
for (double y = 0; y <= height; y += .5)
|
||||
{
|
||||
double x = _radius * Math.cos(y);
|
||||
double z = _radius * Math.sin(y);
|
||||
Location play = _hit.getLocation().add(x, y, z);
|
||||
|
||||
UtilParticle.PlayParticleToAll(ParticleType.WITCH_MAGIC, play, null, 0, 3, ViewDist.MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,14 @@
|
||||
package mineplex.game.clans.items.legendaries;
|
||||
|
||||
import mineplex.game.clans.items.GearManager;
|
||||
import mineplex.game.clans.items.PlayerGear;
|
||||
import net.minecraft.server.v1_8_R3.PlayerConnection;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityDamageEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import mineplex.core.common.util.C;
|
||||
@ -16,13 +21,29 @@ import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||
import mineplex.core.common.util.UtilParticle.ViewDist;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.core.common.util.UtilTextBottom;
|
||||
import mineplex.core.common.util.UtilTextMiddle;
|
||||
import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.recharge.Recharge;
|
||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class WindBlade extends LegendaryItem
|
||||
{
|
||||
private static final Field G_FIELD;
|
||||
|
||||
static
|
||||
{
|
||||
try
|
||||
{
|
||||
G_FIELD = PlayerConnection.class.getDeclaredField("g");
|
||||
G_FIELD.setAccessible(true);
|
||||
}
|
||||
catch (ReflectiveOperationException exception)
|
||||
{
|
||||
throw new RuntimeException("Could not reflectively access field", exception);
|
||||
}
|
||||
}
|
||||
|
||||
public static final double FLIGHT_VELOCITY = 0.75d;
|
||||
|
||||
private double _power;
|
||||
@ -129,12 +150,35 @@ public class WindBlade extends LegendaryItem
|
||||
event.AddMod("Wind Blade", 6);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onFall(CustomDamageEvent event)
|
||||
{
|
||||
if (event.GetDamageePlayer() != null && event.GetCause() == EntityDamageEvent.DamageCause.FALL)
|
||||
{
|
||||
PlayerGear playerGear = GearManager.getInstance().getPlayerGear(event.GetDamageePlayer());
|
||||
if (playerGear.getWeapon() instanceof WindBlade)
|
||||
{
|
||||
event.SetCancelled("Wind Blade No Fall Damage");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void propelPlayer(Player player)
|
||||
{
|
||||
Vector direction = player.getLocation().getDirection().normalize();
|
||||
direction.multiply(FLIGHT_VELOCITY);
|
||||
|
||||
player.setVelocity(direction);
|
||||
|
||||
PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection;
|
||||
try
|
||||
{
|
||||
G_FIELD.set(connection, 0);
|
||||
}
|
||||
catch (IllegalAccessException e)
|
||||
{
|
||||
new RuntimeException("Could not update g field", e).printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canPropel(Player player)
|
||||
|
@ -213,6 +213,15 @@ public class Spawn extends MiniPlugin
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void ignoreVelocity(PlayerVelocityEvent event)
|
||||
{
|
||||
if (_clansManager.getClanUtility().isSafe(event.getPlayer()))
|
||||
{
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onSkill(SkillTriggerEvent event)
|
||||
{
|
||||
@ -391,13 +400,13 @@ public class Spawn extends MiniPlugin
|
||||
if (isInSpawn(victim))
|
||||
{
|
||||
event.SetCancelled("Safe Zone");
|
||||
attemptNotify(attacker, "You cannot attack players who are in spawn!");
|
||||
attemptNotify(attacker, "You cannot attack players who are in a safe zone!");
|
||||
return;
|
||||
}
|
||||
else if (isInSpawn(attacker) && !isCombatTagged(attacker))
|
||||
{
|
||||
event.SetCancelled("Safe Zone");
|
||||
attemptNotify(attacker, "You cannot attack untagged players while in spawn!");
|
||||
attemptNotify(attacker, "You cannot attack untagged players while in a safe zone!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package mineplex.game.clans.tutorial;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
@ -25,7 +26,7 @@ public class TutorialWorldManager extends MiniPlugin
|
||||
|
||||
private final World _tutorialWorld;
|
||||
private final Schematic _schematic;
|
||||
private Stack<TutorialRegion> _regionStack;
|
||||
private LinkedList<TutorialRegion> _regionStack;
|
||||
private TutorialRegion _centerRegion;
|
||||
|
||||
public TutorialWorldManager(JavaPlugin plugin, String worldName, String schematicName) throws IOException
|
||||
@ -56,7 +57,7 @@ public class TutorialWorldManager extends MiniPlugin
|
||||
|
||||
private void populateRegionStack()
|
||||
{
|
||||
_regionStack = new Stack<>();
|
||||
_regionStack = new LinkedList<>();
|
||||
|
||||
// Populate the stack with 100 available tutorial regions
|
||||
for (int x = 0; x < 10; x++)
|
||||
|
@ -10,14 +10,16 @@ public class FinishCommand extends CommandBase<TutorialManager>
|
||||
{
|
||||
public FinishCommand(TutorialManager plugin)
|
||||
{
|
||||
super(plugin, Rank.JNR_DEV, "finish", "end");
|
||||
super(plugin, Rank.ALL, "finish", "end");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
boolean testServer = Plugin.getPlugin().getConfig().getString("serverstatus.group").equalsIgnoreCase("Testing");
|
||||
if (_commandCenter.GetClientManager().hasRank(caller, testServer ? Rank.ALL : Rank.JNR_DEV))
|
||||
{
|
||||
Plugin.finishTutorial(caller);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,17 @@
|
||||
package mineplex.game.clans.tutorial.command;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import mineplex.core.command.CommandBase;
|
||||
import mineplex.core.command.MultiCommandBase;
|
||||
import mineplex.core.common.Rank;
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import mineplex.game.clans.tutorial.TutorialManager;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class TutorialCommand extends MultiCommandBase<TutorialManager>
|
||||
{
|
||||
public TutorialCommand(TutorialManager plugin)
|
||||
{
|
||||
super(plugin, Rank.JNR_DEV, "tutorial", "tut");
|
||||
super(plugin, Rank.ALL, "tutorial", "tut");
|
||||
|
||||
AddCommand(new StartCommand(plugin));
|
||||
AddCommand(new FinishCommand(plugin));
|
||||
@ -24,4 +22,14 @@ public class TutorialCommand extends MultiCommandBase<TutorialManager>
|
||||
{
|
||||
UtilPlayer.message(caller, F.main("Tutorial", "/tutorial start <name>"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Execute(Player caller, String[] args)
|
||||
{
|
||||
boolean testServer = Plugin.getPlugin().getConfig().getString("serverstatus.group").equalsIgnoreCase("Testing");
|
||||
if (_commandCenter.GetClientManager().hasRank(caller, testServer ? Rank.ALL : Rank.JNR_DEV))
|
||||
{
|
||||
super.Execute(caller, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package mineplex.game.clans.tutorial.tutorials.clans.objective.goals.attackenemy;
|
||||
|
||||
import mineplex.core.common.util.F;
|
||||
import mineplex.core.common.util.UtilPlayer;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -8,6 +10,8 @@ import mineplex.core.common.util.UtilInv;
|
||||
import mineplex.game.clans.clans.siege.events.LoadSiegeWeaponEvent;
|
||||
import mineplex.game.clans.tutorial.objective.ObjectiveGoal;
|
||||
import mineplex.game.clans.tutorial.tutorials.clans.objective.AttackEnemyObjective;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
|
||||
public class LoadCannonGoal extends ObjectiveGoal<AttackEnemyObjective>
|
||||
{
|
||||
@ -43,4 +47,15 @@ public class LoadCannonGoal extends ObjectiveGoal<AttackEnemyObjective>
|
||||
|
||||
finish(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler (priority = EventPriority.MONITOR)
|
||||
public void onBlockPlace(BlockPlaceEvent event)
|
||||
{
|
||||
if (!contains(event.getPlayer()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
UtilPlayer.message(event.getPlayer(), F.main("Clans", "Are you sure? That's the only TNT you have!"));
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,67 @@
|
||||
package mineplex.game.clans.world;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.*;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import mineplex.core.common.util.UtilWorld;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.common.util.UtilMath;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.game.clans.clans.ClansManager;
|
||||
|
||||
public class WorldManager extends MiniPlugin
|
||||
{
|
||||
private static final Map<EntityType, Integer> CULL_LIMITS = new HashMap<>();
|
||||
private static final Set<EntityType> MINECART_TYPES = new HashSet<>();
|
||||
private static final int MIN_RANGE = 64;
|
||||
private static final int MIN_RANGE_SQUARED = MIN_RANGE * MIN_RANGE;
|
||||
|
||||
static
|
||||
{
|
||||
// Animals
|
||||
CULL_LIMITS.put(EntityType.BAT, 50);
|
||||
CULL_LIMITS.put(EntityType.CHICKEN, 150);
|
||||
CULL_LIMITS.put(EntityType.COW, 150);
|
||||
CULL_LIMITS.put(EntityType.HORSE, 50);
|
||||
CULL_LIMITS.put(EntityType.IRON_GOLEM, 50);
|
||||
CULL_LIMITS.put(EntityType.MUSHROOM_COW, 50);
|
||||
CULL_LIMITS.put(EntityType.OCELOT, 50);
|
||||
CULL_LIMITS.put(EntityType.PIG, 150);
|
||||
CULL_LIMITS.put(EntityType.RABBIT, 50);
|
||||
CULL_LIMITS.put(EntityType.SHEEP, 150);
|
||||
CULL_LIMITS.put(EntityType.WOLF, 150);
|
||||
|
||||
// Monsters
|
||||
CULL_LIMITS.put(EntityType.CAVE_SPIDER, 100);
|
||||
CULL_LIMITS.put(EntityType.CREEPER, 100);
|
||||
CULL_LIMITS.put(EntityType.ENDERMAN, 50);
|
||||
CULL_LIMITS.put(EntityType.ENDERMITE, 50);
|
||||
CULL_LIMITS.put(EntityType.SILVERFISH, 50);
|
||||
CULL_LIMITS.put(EntityType.SKELETON, 100);
|
||||
CULL_LIMITS.put(EntityType.SLIME, 50);
|
||||
CULL_LIMITS.put(EntityType.SPIDER, 100);
|
||||
CULL_LIMITS.put(EntityType.ZOMBIE, 100);
|
||||
|
||||
// Nether
|
||||
CULL_LIMITS.put(EntityType.BLAZE, 50);
|
||||
CULL_LIMITS.put(EntityType.GHAST, 50);
|
||||
CULL_LIMITS.put(EntityType.MAGMA_CUBE, 50);
|
||||
CULL_LIMITS.put(EntityType.PIG_ZOMBIE, 50);
|
||||
|
||||
MINECART_TYPES.add(EntityType.MINECART);
|
||||
MINECART_TYPES.add(EntityType.MINECART_CHEST);
|
||||
MINECART_TYPES.add(EntityType.MINECART_COMMAND);
|
||||
MINECART_TYPES.add(EntityType.MINECART_FURNACE);
|
||||
MINECART_TYPES.add(EntityType.MINECART_HOPPER);
|
||||
MINECART_TYPES.add(EntityType.MINECART_MOB_SPAWNER);
|
||||
MINECART_TYPES.add(EntityType.MINECART_TNT);
|
||||
}
|
||||
|
||||
public WorldManager(JavaPlugin plugin)
|
||||
{
|
||||
super("Clan World Manager", plugin);
|
||||
@ -33,118 +75,77 @@ public class WorldManager extends MiniPlugin
|
||||
|
||||
for (World world : getPlugin().getServer().getWorlds())
|
||||
{
|
||||
HashMap<EntityType, ArrayList<Entity>> _ents = new HashMap<EntityType, ArrayList<Entity>>();
|
||||
List<Player> players = world.getPlayers();
|
||||
Map<EntityType, Set<Entity>> entities = new HashMap<>();
|
||||
|
||||
for (EntityType type : EntityType.values())
|
||||
_ents.put(type, new ArrayList<Entity>());
|
||||
|
||||
for (Entity ent : world.getEntities())
|
||||
for (Entity entity : world.getEntities())
|
||||
{
|
||||
if (ent.getCustomName() == null)
|
||||
if (entity.getCustomName() != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
EntityType entityType = entity.getType();
|
||||
|
||||
if (entityType == EntityType.ARROW)
|
||||
{
|
||||
if (entity.getTicksLived() > 800)
|
||||
{
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
else if (entityType == EntityType.DROPPED_ITEM)
|
||||
{
|
||||
if (entity.getTicksLived() > 2400)
|
||||
{
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
else if (CULL_LIMITS.containsKey(entityType))
|
||||
{
|
||||
boolean cull = true;
|
||||
|
||||
for (Player player : world.getPlayers())
|
||||
for (Player player : players)
|
||||
{
|
||||
if (player.getLocation().distance(ent.getLocation()) <= 64)
|
||||
// Using NMS because this is going to be called quite a few times
|
||||
// and each getLocation() call creates a new Location object
|
||||
if (UtilWorld.distanceSquared(player, entity) <= MIN_RANGE_SQUARED)
|
||||
{
|
||||
cull = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cull)
|
||||
{
|
||||
_ents.get(ent.getType()).add(ent);
|
||||
entities.computeIfAbsent(entityType, key -> new HashSet<>()).add(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (EntityType type : _ents.keySet())
|
||||
else if (MINECART_TYPES.contains(entityType))
|
||||
{
|
||||
ArrayList<Entity> ents = _ents.get(type);
|
||||
|
||||
//Clean Old Arrows
|
||||
if (type == EntityType.ARROW)
|
||||
if (entity.getTicksLived() > 800)
|
||||
{
|
||||
for (Entity ent : ents)
|
||||
if (ent.getTicksLived() > 800)
|
||||
ent.remove();
|
||||
entity.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Clean Old Items
|
||||
if (type == EntityType.DROPPED_ITEM)
|
||||
for (Map.Entry<EntityType, Set<Entity>> entry : entities.entrySet())
|
||||
{
|
||||
for (Entity ent : ents)
|
||||
if (ent.getTicksLived() > 2400)
|
||||
ent.remove();
|
||||
cull(entry.getKey(), entry.getValue(), CULL_LIMITS.get(entry.getKey()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Animals
|
||||
else if (type == EntityType.BAT) cull(ents, 50);
|
||||
else if (type == EntityType.CHICKEN) cull(ents, 150);
|
||||
else if (type == EntityType.COW) cull(ents, 150);
|
||||
else if (type == EntityType.HORSE) cull(ents, 50);
|
||||
else if (type == EntityType.IRON_GOLEM) cull(ents, 50);
|
||||
else if (type == EntityType.MUSHROOM_COW) cull(ents, 50);
|
||||
else if (type == EntityType.OCELOT) cull(ents, 50);
|
||||
else if (type == EntityType.PIG) cull(ents, 150);
|
||||
else if (type == EntityType.RABBIT) cull(ents, 50);
|
||||
else if (type == EntityType.SHEEP) cull(ents, 150);
|
||||
else if (type == EntityType.WOLF) cull(ents, 150);
|
||||
|
||||
//Monster
|
||||
else if (type == EntityType.CAVE_SPIDER) cull(ents, 100);
|
||||
else if (type == EntityType.CREEPER) cull(ents, 100);
|
||||
else if (type == EntityType.ENDERMAN) cull(ents, 50);
|
||||
else if (type == EntityType.ENDERMITE) cull(ents, 50);
|
||||
else if (type == EntityType.SILVERFISH) cull(ents, 50);
|
||||
else if (type == EntityType.SKELETON) cull(ents, 100);
|
||||
else if (type == EntityType.SLIME) cull(ents, 50);
|
||||
else if (type == EntityType.SPIDER) cull(ents, 100);
|
||||
else if (type == EntityType.ZOMBIE) cull(ents, 100);
|
||||
|
||||
//Nether
|
||||
else if (type == EntityType.BLAZE) cull(ents, 50);
|
||||
else if (type == EntityType.GHAST) cull(ents, 50);
|
||||
else if (type == EntityType.MAGMA_CUBE) cull(ents, 50);
|
||||
else if (type == EntityType.PIG_ZOMBIE) cull(ents, 50);
|
||||
|
||||
//Clean Old Minecarts
|
||||
if (type == EntityType.MINECART ||
|
||||
type == EntityType.MINECART_CHEST ||
|
||||
type == EntityType.MINECART_COMMAND ||
|
||||
type == EntityType.MINECART_FURNACE ||
|
||||
type == EntityType.MINECART_HOPPER ||
|
||||
type == EntityType.MINECART_MOB_SPAWNER ||
|
||||
type == EntityType.MINECART_TNT)
|
||||
{
|
||||
for (Entity ent : ents)
|
||||
if (ent.getTicksLived() > 800)
|
||||
ent.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void cull(ArrayList<Entity> ents, int limit)
|
||||
private void cull(EntityType type, Set<Entity> ents, int limit)
|
||||
{
|
||||
Iterator<Entity> iterator = ents.iterator();
|
||||
int culled = 0;
|
||||
EntityType type = null;
|
||||
while (ents.size() > limit)
|
||||
while (iterator.hasNext() && ents.size() > limit)
|
||||
{
|
||||
Entity ent = ents.remove(UtilMath.r(ents.size()));
|
||||
|
||||
type = ent.getType();
|
||||
|
||||
ent.remove();
|
||||
|
||||
Entity entity = iterator.next();
|
||||
entity.remove();
|
||||
iterator.remove();
|
||||
culled++;
|
||||
}
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
System.out.println("Culled " + culled + " " + type);
|
||||
}
|
||||
log("Culled " + culled + " " + type);
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ public class Leap extends SkillActive
|
||||
{
|
||||
//Action
|
||||
if (!wallkick)
|
||||
UtilAction.velocity(player, 1.2, 0.2, 1, true);
|
||||
UtilAction.velocity(player, 1 + 0.15 * level, 0.2, 1, true);
|
||||
else
|
||||
{
|
||||
Vector vec = player.getLocation().getDirection();
|
||||
|
@ -60,11 +60,6 @@ public class Recall extends Skill
|
||||
{
|
||||
Player player = event.getPlayer();
|
||||
|
||||
if (!(player.getOpenInventory().getTopInventory() instanceof CraftInventoryCrafting))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int level = getLevel(player);
|
||||
if (level == 0)
|
||||
return;
|
||||
@ -92,6 +87,7 @@ public class Recall extends Skill
|
||||
if (health == null)
|
||||
return;
|
||||
|
||||
Factory.runSync(() -> {
|
||||
//Heal
|
||||
double newHealth = Math.min(health.getLast(), player.getHealth() + 3 + level);
|
||||
player.setHealth(newHealth);
|
||||
@ -117,19 +113,9 @@ public class Recall extends Skill
|
||||
ViewDist.LONGER, UtilServer.getPlayers());
|
||||
current = current.add(UtilAlg.getTrajectory(current, target).multiply(0.1));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void closeInv(InventoryCloseEvent event)
|
||||
{
|
||||
if (getLevel(event.getPlayer()) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
event.getPlayer().getInventory().addItem(event.getPlayer().getItemOnCursor());
|
||||
event.getPlayer().setItemOnCursor(null);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void storeLocation(UpdateEvent event)
|
||||
|
@ -2,6 +2,7 @@ package mineplex.minecraft.game.classcombat.Skill.Brute;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
@ -167,10 +168,12 @@ public class Takedown extends SkillActive
|
||||
int damage = 3 + (level);
|
||||
|
||||
//Damage Event
|
||||
Factory.Damage().NewDamageEvent(damagee, damager, null,
|
||||
CustomDamageEvent customDamageEvent = Factory.Damage().NewDamageEvent(damagee, damager, null,
|
||||
DamageCause.CUSTOM, damage, false, true, false,
|
||||
damager.getName(), GetName());
|
||||
|
||||
if (!customDamageEvent.IsCancelled())
|
||||
{
|
||||
//Damage Event
|
||||
Factory.Damage().NewDamageEvent(damager, damagee, null,
|
||||
DamageCause.CUSTOM, damage / 2, false, true, false,
|
||||
@ -187,6 +190,7 @@ public class Takedown extends SkillActive
|
||||
//Sound
|
||||
damager.getWorld().playSound(damager.getLocation(), Sound.ZOMBIE_WOOD, 1f, 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void Particle(UpdateEvent event)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package mineplex.minecraft.game.classcombat.Skill.Knight;
|
||||
|
||||
import mineplex.minecraft.game.core.condition.events.ConditionExpireEvent;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
@ -22,6 +23,10 @@ import mineplex.core.updater.UpdateType;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.minecraft.game.classcombat.Skill.SkillActive;
|
||||
import mineplex.minecraft.game.classcombat.Skill.SkillFactory;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class HoldPosition extends SkillActive
|
||||
{
|
||||
@ -47,10 +52,13 @@ public class HoldPosition extends SkillActive
|
||||
});
|
||||
}
|
||||
|
||||
private final Map<Player, Integer> _foodLevel = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public boolean CustomCheck(Player player, int level)
|
||||
{
|
||||
if (player.getLocation().getBlock().getTypeId() == 8 || player.getLocation().getBlock().getTypeId() == 9)
|
||||
Material type = player.getLocation().getBlock().getType();
|
||||
if (type == Material.WATER || type == Material.STATIONARY_WATER)
|
||||
{
|
||||
UtilPlayer.message(player, F.main("Skill", "You cannot use " + F.skill(GetName()) + " in water."));
|
||||
return false;
|
||||
@ -75,6 +83,8 @@ public class HoldPosition extends SkillActive
|
||||
//Effect
|
||||
player.getWorld().playSound(player.getLocation(), Sound.ENDERMAN_SCREAM, 1.5f, 0f);
|
||||
player.getWorld().playEffect(player.getLocation(), Effect.STEP_SOUND, 49);
|
||||
|
||||
_foodLevel.put(player, player.getFoodLevel());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGH)
|
||||
@ -123,6 +133,30 @@ public class HoldPosition extends SkillActive
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(ConditionExpireEvent event)
|
||||
{
|
||||
if (event.getCondition().GetReason().equals(GetName()) && event.getCondition().GetEnt() instanceof Player)
|
||||
{
|
||||
if (event.getCondition().GetType() == ConditionType.DAMAGE_RESISTANCE)
|
||||
{
|
||||
Player player = ((Player) event.getCondition().GetEnt());
|
||||
if (_foodLevel.get(player) != null)
|
||||
{
|
||||
player.setFoodLevel(_foodLevel.get(player));
|
||||
}
|
||||
// Could be null value. Sanity check
|
||||
_foodLevel.remove(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void on(PlayerQuitEvent event)
|
||||
{
|
||||
_foodLevel.remove(event.getPlayer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void Reset(Player player)
|
||||
{
|
||||
|
@ -7,6 +7,7 @@ import java.util.Map.Entry;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import mineplex.core.MiniPlugin;
|
||||
import mineplex.core.common.util.UtilServer;
|
||||
import mineplex.core.recharge.Recharge;
|
||||
import mineplex.core.updater.event.UpdateEvent;
|
||||
import mineplex.core.updater.UpdateType;
|
||||
@ -18,6 +19,7 @@ import mineplex.core.common.util.UtilTime;
|
||||
import mineplex.core.common.util.UtilTime.TimeUnit;
|
||||
import mineplex.minecraft.game.core.condition.Condition.ConditionType;
|
||||
import mineplex.minecraft.game.core.condition.events.ConditionApplyEvent;
|
||||
import mineplex.minecraft.game.core.condition.events.ConditionExpireEvent;
|
||||
import mineplex.minecraft.game.core.damage.DamageManager;
|
||||
|
||||
import org.bukkit.Material;
|
||||
@ -189,9 +191,13 @@ public class ConditionManager extends MiniPlugin
|
||||
Condition cond = conditionIterator.next();
|
||||
|
||||
if (cond.Tick())
|
||||
{
|
||||
ConditionExpireEvent conditionExpireEvent = new ConditionExpireEvent(cond);
|
||||
UtilServer.CallEvent(conditionExpireEvent);
|
||||
conditionIterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Indicators **/
|
||||
for (LivingEntity ent : _activeConditions.keySet())
|
||||
|
@ -0,0 +1,33 @@
|
||||
package mineplex.minecraft.game.core.condition.events;
|
||||
|
||||
import mineplex.minecraft.game.core.condition.Condition;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class ConditionExpireEvent extends Event
|
||||
{
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
private Condition _cond;
|
||||
|
||||
public ConditionExpireEvent(Condition cond)
|
||||
{
|
||||
_cond = cond;
|
||||
}
|
||||
|
||||
public HandlerList getHandlers()
|
||||
{
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList()
|
||||
{
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public Condition getCondition()
|
||||
{
|
||||
return _cond;
|
||||
}
|
||||
|
||||
}
|
@ -171,36 +171,38 @@ public class DamageManager extends MiniPlugin
|
||||
}
|
||||
*/
|
||||
|
||||
public void NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj,
|
||||
public CustomDamageEvent NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj,
|
||||
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
|
||||
String source, String reason)
|
||||
{
|
||||
NewDamageEvent(damagee, damager, proj,
|
||||
return NewDamageEvent(damagee, damager, proj,
|
||||
cause, damage, knockback, ignoreRate, ignoreArmor,
|
||||
source, reason, false);
|
||||
}
|
||||
|
||||
public void NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj,
|
||||
public CustomDamageEvent NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj,
|
||||
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
|
||||
String source, String reason, boolean cancelled)
|
||||
{
|
||||
NewDamageEvent(damagee, damager, proj, null, cause, damage, knockback, ignoreRate, ignoreArmor, source, reason, cancelled);
|
||||
return NewDamageEvent(damagee, damager, proj, null, cause, damage, knockback, ignoreRate, ignoreArmor, source, reason, cancelled);
|
||||
}
|
||||
|
||||
public void NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj, Location knockbackOrigin,
|
||||
public CustomDamageEvent NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj, Location knockbackOrigin,
|
||||
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
|
||||
String source, String reason)
|
||||
{
|
||||
NewDamageEvent(damagee, damager, proj, knockbackOrigin, cause, damage, knockback, ignoreRate, ignoreArmor, source,
|
||||
return NewDamageEvent(damagee, damager, proj, knockbackOrigin, cause, damage, knockback, ignoreRate, ignoreArmor, source,
|
||||
reason, false);
|
||||
}
|
||||
|
||||
public void NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj, Location knockbackOrigin,
|
||||
public CustomDamageEvent NewDamageEvent(LivingEntity damagee, LivingEntity damager, Projectile proj, Location knockbackOrigin,
|
||||
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
|
||||
String source, String reason, boolean cancelled)
|
||||
{
|
||||
_plugin.getServer().getPluginManager().callEvent(new CustomDamageEvent(damagee, damager, proj, knockbackOrigin, cause,
|
||||
damage, knockback, ignoreRate, ignoreArmor, source, reason, cancelled));
|
||||
CustomDamageEvent customDamageEvent = new CustomDamageEvent(damagee, damager, proj, knockbackOrigin, cause,
|
||||
damage, knockback, ignoreRate, ignoreArmor, source, reason, cancelled);
|
||||
_plugin.getServer().getPluginManager().callEvent(customDamageEvent);
|
||||
return customDamageEvent;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
@ -351,8 +353,15 @@ public class DamageManager extends MiniPlugin
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Debug
|
||||
/*
|
||||
* Should only be used to debug the damage event
|
||||
* No modification of the event should take place
|
||||
*/
|
||||
@EventHandler (priority = EventPriority.MONITOR)
|
||||
public void debugDamageEvent(CustomDamageEvent event)
|
||||
{
|
||||
DisplayDamage(event);
|
||||
}
|
||||
|
||||
@ -529,7 +538,7 @@ public class DamageManager extends MiniPlugin
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
@EventHandler (priority = EventPriority.MONITOR)
|
||||
public void DamageSound(CustomDamageEvent event)
|
||||
{
|
||||
if (event.IsCancelled())
|
||||
|
@ -1,8 +1,5 @@
|
||||
package nautilus.game.arcade;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import mineplex.core.common.MinecraftVersion;
|
||||
import mineplex.core.common.Pair;
|
||||
import mineplex.core.game.GameCategory;
|
||||
@ -74,7 +71,6 @@ import nautilus.game.arcade.game.games.valentines.Valentines;
|
||||
import nautilus.game.arcade.game.games.wither.WitherGame;
|
||||
import nautilus.game.arcade.game.games.wizards.Wizards;
|
||||
import nautilus.game.arcade.game.games.zombiesurvival.ZombieSurvival;
|
||||
|
||||
import org.bukkit.Material;
|
||||
|
||||
public enum GameType
|
||||
@ -100,7 +96,7 @@ public enum GameType
|
||||
DragonsTeams(DragonsTeams.class, GameDisplay.DragonsTeams),
|
||||
Draw(Draw.class, GameDisplay.Draw, new Pair[]
|
||||
{
|
||||
Pair.create(MinecraftVersion.ALL, "http://chivebox.com/mineplex/ResDrawMyThing.zip")
|
||||
Pair.create(MinecraftVersion.ALL, "http://file.mineplex.com/ResDrawMyThing.zip")
|
||||
}, true),
|
||||
ElytraRings(ElytraRings.class, GameDisplay.ElytraRings),
|
||||
Evolution(Evolution.class, GameDisplay.Evolution),
|
||||
@ -117,8 +113,8 @@ public enum GameType
|
||||
MilkCow(MilkCow.class, GameDisplay.MilkCow),
|
||||
MineStrike(MineStrike.class, GameDisplay.MineStrike, new Pair[]
|
||||
{
|
||||
Pair.create(MinecraftVersion.Version1_8, "http://chivebox.com/mineplex/ResMinestrike.zip"),
|
||||
Pair.create(MinecraftVersion.Version1_9, "http://chivebox.com/mineplex/ResMinestrike19.zip")
|
||||
Pair.create(MinecraftVersion.Version1_8, "http://file.mineplex.com/ResMinestrike.zip"),
|
||||
Pair.create(MinecraftVersion.Version1_9, "http://file.mineplex.com/ResMinestrike19.zip")
|
||||
}, true),
|
||||
MineWare(MineWare.class, GameDisplay.MineWare),
|
||||
MinecraftLeague(MinecraftLeague.class, GameDisplay.Minecraft_League),
|
||||
|
@ -140,7 +140,7 @@ public class MiscManager implements Listener
|
||||
@EventHandler
|
||||
public void HubCommand(PlayerCommandPreprocessEvent event)
|
||||
{
|
||||
if (event.getMessage().toLowerCase().startsWith("/lobby") || event.getMessage().toLowerCase().startsWith("/hub") || event.getMessage().toLowerCase().startsWith("/leave"))
|
||||
if (event.getMessage().toLowerCase().equals("/lobby") || event.getMessage().toLowerCase().equals("/hub") || event.getMessage().toLowerCase().equals("/leave"))
|
||||
{
|
||||
Manager.GetPortal().sendPlayerToServer(event.getPlayer(), "Lobby");
|
||||
event.setCancelled(true);
|
||||
|
Loading…
Reference in New Issue
Block a user