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.WorldBorder;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
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 org.bukkit.util.Vector;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
@ -28,7 +30,12 @@ public class UtilWorld
|
|||||||
if (chunk == null)
|
if (chunk == null)
|
||||||
return "";
|
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)
|
public static String chunkToStrClean(Chunk chunk)
|
||||||
@ -289,4 +296,15 @@ public class UtilWorld
|
|||||||
return startX >= minX && startZ <= maxX && endX >= minZ && endZ <= maxZ;
|
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)
|
public void Quit(PlayerQuitEvent event)
|
||||||
{
|
{
|
||||||
// When an account is logged in to this server and the same account name logs in
|
// 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);
|
event.setDroppedExp(0);
|
||||||
List<ItemStack> drops = event.getDrops();
|
List<ItemStack> drops = event.getDrops();
|
||||||
|
|
||||||
|
if (event.getEntity().hasMetadata("Creature.DoNotDrop"))
|
||||||
|
{
|
||||||
|
drops.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (event.getEntityType() == EntityType.PLAYER)
|
if (event.getEntityType() == EntityType.PLAYER)
|
||||||
drops.add(ItemStackFactory.Instance.CreateStack(Material.BONE, 1));
|
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;
|
package mineplex.game.clans;
|
||||||
|
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import mineplex.core.MiniPlugin;
|
import mineplex.core.MiniPlugin;
|
||||||
|
import mineplex.core.common.util.UtilItem;
|
||||||
import mineplex.core.itemstack.ItemStackFactory;
|
import mineplex.core.itemstack.ItemStackFactory;
|
||||||
import mineplex.core.common.util.F;
|
import mineplex.core.common.util.F;
|
||||||
import mineplex.core.common.util.UtilPlayer;
|
import mineplex.core.common.util.UtilPlayer;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class Farming extends MiniPlugin
|
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)
|
public Farming(JavaPlugin plugin)
|
||||||
{
|
{
|
||||||
super("Farming", plugin);
|
super("Farming", plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler (ignoreCancelled = true)
|
||||||
public void BlockBreak(BlockBreakEvent event)
|
public void BlockBreak(BlockBreakEvent event)
|
||||||
{
|
{
|
||||||
if (event.isCancelled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (event.getBlock().getType() != Material.LEAVES)
|
if (event.getBlock().getType() != Material.LEAVES)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (event.getPlayer().getItemInHand() != null)
|
if (UtilItem.matchesMaterial(event.getPlayer().getItemInHand(), Material.SHEARS))
|
||||||
if (event.getPlayer().getItemInHand().getType() == Material.SHEARS)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Location dropLocation = event.getBlock().getLocation().add(0.5, 0.5, 0.5);
|
||||||
|
|
||||||
if (Math.random() > 0.9)
|
if (Math.random() > 0.9)
|
||||||
event.getBlock().getWorld().dropItemNaturally(
|
event.getBlock().getWorld().dropItemNaturally(dropLocation, ItemStackFactory.Instance.CreateStack(Material.APPLE));
|
||||||
event.getBlock().getLocation().add(0.5, 0.5, 0.5),
|
|
||||||
ItemStackFactory.Instance.CreateStack(Material.APPLE));
|
|
||||||
|
|
||||||
if (Math.random() > 0.999)
|
if (Math.random() > 0.999)
|
||||||
event.getBlock().getWorld().dropItemNaturally(
|
event.getBlock().getWorld().dropItemNaturally(dropLocation, ItemStackFactory.Instance.CreateStack(Material.GOLDEN_APPLE));
|
||||||
event.getBlock().getLocation().add(0.5, 0.5, 0.5),
|
|
||||||
ItemStackFactory.Instance.CreateStack(Material.GOLDEN_APPLE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@EventHandler (ignoreCancelled = true)
|
||||||
@EventHandler
|
|
||||||
public void BlockPlace(BlockPlaceEvent event)
|
public void BlockPlace(BlockPlaceEvent event)
|
||||||
{
|
{
|
||||||
if (event.isCancelled())
|
if (!PLANTABLE.contains(event.getBlock().getType()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (
|
double blockY = event.getBlock().getLocation().getY();
|
||||||
event.getBlock().getTypeId() != 59 &&
|
double seaLevel = event.getBlock().getWorld().getSeaLevel();
|
||||||
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;
|
|
||||||
|
|
||||||
if (event.getBlock().getLocation().getY() < event.getBlock().getWorld().getSeaLevel() - 12)
|
if (blockY < seaLevel - 12)
|
||||||
{
|
{
|
||||||
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot plant " +
|
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot plant " +
|
||||||
F.item(ItemStackFactory.Instance.GetName(event.getPlayer().getItemInHand(), true)) + " this deep underground."));
|
F.item(ItemStackFactory.Instance.GetName(event.getPlayer().getItemInHand(), true)) + " this deep underground."));
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
else if (blockY > seaLevel + 24)
|
||||||
else if (event.getBlock().getLocation().getY() > event.getBlock().getWorld().getSeaLevel() + 24)
|
|
||||||
{
|
{
|
||||||
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot plant " +
|
UtilPlayer.message(event.getPlayer(), F.main(getName(), "You cannot plant " +
|
||||||
F.item(ItemStackFactory.Instance.GetName(event.getPlayer().getItemInHand(), true)) + " at this altitude."));
|
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 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 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 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 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 enemy <clan>", "Start Invasion", Rank.CMOD));
|
||||||
UtilPlayer.message(caller, F.help("/c x rename <name>", "Change the name of Mimic", 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)
|
if (target == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (target.getName().equals(caller.getName()))
|
|
||||||
{
|
|
||||||
UtilPlayer.message(caller, F.main("Clans Admin", "You cannot invite yourself."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Inform
|
//Inform
|
||||||
clan.inform(caller.getName() + " invited " + target.getName() + " to join Clan " + clan.getName() + ".", caller.getName());
|
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()) + "."));
|
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;
|
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);
|
ClanRelation access = _clans.getClanUtility().getAccess(player, loc);
|
||||||
ClanInfo clan = _clans.getClan(player);
|
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);
|
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
|
// 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."));
|
UtilPlayer.message(player, F.main("Clans", "You are not allowed to use that here."));
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hoe 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.data.PlayerClan;
|
||||||
import mineplex.game.clans.clans.event.ClansPlayerDeathEvent;
|
import mineplex.game.clans.clans.event.ClansPlayerDeathEvent;
|
||||||
import mineplex.game.clans.clans.gui.ClanShop;
|
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.loot.LootManager;
|
||||||
import mineplex.game.clans.clans.map.ItemMapManager;
|
import mineplex.game.clans.clans.map.ItemMapManager;
|
||||||
import mineplex.game.clans.clans.nameblacklist.ClansBlacklist;
|
import mineplex.game.clans.clans.nameblacklist.ClansBlacklist;
|
||||||
@ -260,7 +260,7 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
|
|||||||
new TntGeneratorManager(plugin, this);
|
new TntGeneratorManager(plugin, this);
|
||||||
new SupplyDropManager(plugin, this);
|
new SupplyDropManager(plugin, this);
|
||||||
|
|
||||||
new Invsee(this);
|
new InvseeManager(this);
|
||||||
|
|
||||||
_explosion = new Explosion(plugin, blockRestore);
|
_explosion = new Explosion(plugin, blockRestore);
|
||||||
_warPointEvasion = new WarPointEvasion(plugin);
|
_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
|
@EventHandler
|
||||||
public void StaffIncognito(IncognitoStatusChangeEvent event)
|
public void StaffIncognito(IncognitoStatusChangeEvent event)
|
||||||
{
|
{
|
||||||
@ -1175,7 +1162,7 @@ public class ClansManager extends MiniClientPlugin<ClientClan>implements IRelati
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void hubCommand(PlayerCommandPreprocessEvent event)
|
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");
|
Portal.getInstance().sendPlayerToServer(event.getPlayer(), "Lobby");
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
@ -28,6 +29,11 @@ import mineplex.game.clans.spawn.Spawn;
|
|||||||
|
|
||||||
public class ClansUtility
|
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;
|
private ClansManager _clansManager;
|
||||||
|
|
||||||
public ClansUtility(ClansManager clans)
|
public ClansUtility(ClansManager clans)
|
||||||
@ -113,55 +119,79 @@ public class ClansUtility
|
|||||||
public ClanInfo searchClanPlayer(Player caller, String name, boolean inform)
|
public ClanInfo searchClanPlayer(Player caller, String name, boolean inform)
|
||||||
{
|
{
|
||||||
// CLAN
|
// CLAN
|
||||||
LinkedList<ClanInfo> clanMatchList = new LinkedList<ClanInfo>();
|
List<ClanInfo> clanMatchList = new ArrayList<>(MAX_CLAN_SEARCH);
|
||||||
|
|
||||||
for (ClanInfo cur : _clansManager.getClanMap().values())
|
for (ClanInfo cur : _clansManager.getClanMap().values())
|
||||||
{
|
{
|
||||||
if (cur.getName().equalsIgnoreCase(name)) return cur;
|
if (cur.getName().equalsIgnoreCase(name)) return cur;
|
||||||
|
|
||||||
if (cur.getName().toLowerCase().contains(name.toLowerCase())) clanMatchList.add(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);
|
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
|
// 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())
|
for (ClansPlayer player : clanInfo.getMembers().values())
|
||||||
{
|
{
|
||||||
if (player.getPlayerName().equalsIgnoreCase(name)) return clanInfo;
|
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);
|
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)
|
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.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));
|
if (clanMatchList.size() > MAX_CLAN_SEARCH)
|
||||||
UtilPlayer.message(caller, F.desc("Matches via Player", playerMatchString));
|
{
|
||||||
|
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;
|
return null;
|
||||||
@ -259,9 +289,15 @@ public class ClansUtility
|
|||||||
|
|
||||||
public boolean isSafe(Location loc)
|
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)
|
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 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 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 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 claim", "Claim Territory", Rank.ADMIN));
|
||||||
UtilPlayer.message(caller, F.help("/c unclaim (all)", "Unclaim 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();
|
String enemyName = clanWar.getClanA().equals(clan.getName()) ? clanWar.getClanB() : clanWar.getClanA();
|
||||||
final ClanInfo enemy = getPlugin().getClan(enemyName);
|
final ClanInfo enemy = getPlugin().getClan(enemyName);
|
||||||
|
if (enemy != null)
|
||||||
|
{
|
||||||
String itemName = enemyName;
|
String itemName = enemyName;
|
||||||
Material material = USE_RESOURCE_ICONS ? ClanIcon.WAR.getMaterial() : Material.DIAMOND_SWORD;
|
Material material = USE_RESOURCE_ICONS ? ClanIcon.WAR.getMaterial() : Material.DIAMOND_SWORD;
|
||||||
byte data = USE_RESOURCE_ICONS ? ClanIcon.WAR.getData() : 0;
|
byte data = USE_RESOURCE_ICONS ? ClanIcon.WAR.getData() : 0;
|
||||||
@ -290,6 +292,11 @@ public class ClanMainPage extends ClanPageBase
|
|||||||
}
|
}
|
||||||
}, warPoints);
|
}, warPoints);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
System.err.println("Could not find enemy clan: " + enemyName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void addAllyButton(int slot, final ClanInfo ally)
|
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;
|
package mineplex.game.clans.clans.invsee.commands;
|
||||||
|
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
import mineplex.core.command.CommandBase;
|
import mineplex.core.command.CommandBase;
|
||||||
import mineplex.core.common.Rank;
|
import mineplex.core.common.Rank;
|
||||||
import mineplex.core.common.util.F;
|
import mineplex.core.common.util.F;
|
||||||
import mineplex.core.common.util.UtilPlayer;
|
import mineplex.core.common.util.UtilPlayer;
|
||||||
import mineplex.game.clans.clans.invsee.Invsee;
|
import mineplex.game.clans.clans.invsee.InvseeManager;
|
||||||
import mineplex.game.clans.clans.invsee.ui.InvseeInventory;
|
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.Bukkit;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.entity.Player;
|
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");
|
super(plugin, Rank.ADMIN, "invsee");
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
@Override
|
||||||
public void Execute(Player caller, String[] args)
|
public void Execute(Player caller, String[] args)
|
||||||
{
|
{
|
||||||
if (args.length == 0)
|
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];
|
uuid = UUID.fromString(args[0]);
|
||||||
|
}
|
||||||
OfflinePlayer player = Bukkit.getServer().getPlayer(name);
|
catch (IllegalArgumentException failed)
|
||||||
|
|
||||||
if (player == null)
|
|
||||||
{
|
{
|
||||||
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new InvseeInventory(player).ShowTo(caller);
|
Plugin.doInvsee(exactPlayer, caller);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,99 +1,407 @@
|
|||||||
package mineplex.game.clans.clans.invsee.ui;
|
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.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.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
import org.bukkit.event.inventory.*;
|
||||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
import mineplex.core.common.util.C;
|
import java.io.File;
|
||||||
import mineplex.core.common.util.UtilCollections;
|
import java.io.FileOutputStream;
|
||||||
import mineplex.core.common.util.UtilServer;
|
import java.util.*;
|
||||||
import mineplex.core.updater.UpdateType;
|
|
||||||
import mineplex.core.updater.event.UpdateEvent;
|
|
||||||
|
|
||||||
public class InvseeInventory implements Listener
|
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;
|
private Inventory _inventory;
|
||||||
|
// This is whether the target player should be allowed to open any inventories
|
||||||
|
private boolean _canOpenInventory = true;
|
||||||
|
|
||||||
private boolean _online;
|
public InvseeInventory(InvseeManager manager, OfflinePlayer player)
|
||||||
|
|
||||||
private Player _admin;
|
|
||||||
|
|
||||||
public InvseeInventory(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);
|
UtilServer.RegisterEvents(this);
|
||||||
|
updateInventory();
|
||||||
|
update(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ShowTo(Player admin)
|
private String[] generateLore(boolean canOpenInventory)
|
||||||
{
|
{
|
||||||
_admin = admin;
|
return UtilText.splitLinesToArray(new String[]{
|
||||||
admin.openInventory(_inventory);
|
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
|
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||||
public void update(UpdateEvent event)
|
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;
|
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
|
private void saveInventory()
|
||||||
public void closeInventory(InventoryCloseEvent event)
|
|
||||||
{
|
{
|
||||||
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;
|
package mineplex.game.clans.clans.map;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.*;
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import mineplex.core.common.util.*;
|
||||||
import mineplex.game.clans.tutorial.TutorialManager;
|
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.apache.commons.io.FileUtils;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.craftbukkit.v1_8_R3.CraftChunk;
|
import org.bukkit.craftbukkit.v1_8_R3.CraftChunk;
|
||||||
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
|
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.ItemFrame;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.block.Action;
|
import org.bukkit.event.block.Action;
|
||||||
import org.bukkit.event.entity.ItemSpawnEvent;
|
import org.bukkit.event.entity.ItemSpawnEvent;
|
||||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
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.PlayerJoinEvent;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
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.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.map.MapRenderer;
|
import org.bukkit.map.MapRenderer;
|
||||||
@ -46,13 +44,6 @@ import com.google.common.collect.Iterables;
|
|||||||
import com.google.common.collect.Multisets;
|
import com.google.common.collect.Multisets;
|
||||||
|
|
||||||
import mineplex.core.MiniPlugin;
|
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.common.util.UtilTime.TimeUnit;
|
||||||
import mineplex.core.itemstack.ItemBuilder;
|
import mineplex.core.itemstack.ItemBuilder;
|
||||||
import mineplex.core.portal.ServerTransferEvent;
|
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.ClansUtility;
|
||||||
import mineplex.game.clans.clans.map.events.PlayerGetMapEvent;
|
import mineplex.game.clans.clans.map.events.PlayerGetMapEvent;
|
||||||
import mineplex.game.clans.clans.worldevent.WorldEventManager;
|
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
|
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 ClansUtility _clansUtility;
|
||||||
private Comparator<Entry<Integer, Integer>> _comparator;
|
private Comparator<Entry<Integer, Integer>> _comparator;
|
||||||
private int _halfMapSize = 1536 / 2;
|
private int[][] _heightMap = new int[(HALF_WORLD_SIZE * 2) + 16][];
|
||||||
private int[][] _heightMap = new int[(_halfMapSize * 2) + 16][];
|
|
||||||
private boolean _loadWorld = true;
|
|
||||||
private HashMap<Integer, Byte[][]> _map = new HashMap<Integer, Byte[][]>();
|
private HashMap<Integer, Byte[][]> _map = new HashMap<Integer, Byte[][]>();
|
||||||
private short _mapId = -1;
|
private short _mapId = -1;
|
||||||
private HashMap<String, MapInfo> _mapInfo = new HashMap<String, MapInfo>();
|
private HashMap<String, MapInfo> _mapInfo = new HashMap<String, MapInfo>();
|
||||||
private HashMap<Integer, Integer> _scale = new HashMap<Integer, Integer>();
|
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 World _world;
|
||||||
|
private WorldServer _nmsWorld;
|
||||||
|
private ChunkProviderServer _chunkProviderServer;
|
||||||
|
private ChunkRegionLoader _chunkRegionLoader;
|
||||||
private WorldEventManager _eventManager;
|
private WorldEventManager _eventManager;
|
||||||
private TutorialManager _tutorial;
|
private TutorialManager _tutorial;
|
||||||
|
|
||||||
@ -94,14 +135,10 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
_eventManager = eventManager;
|
_eventManager = eventManager;
|
||||||
_tutorial = tutorial;
|
_tutorial = tutorial;
|
||||||
|
|
||||||
_comparator = new Comparator<Entry<Integer, Integer>>()
|
_comparator = (o1, o2) ->
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(Entry<Integer, Integer> o1, Entry<Integer, Integer> o2)
|
|
||||||
{
|
{
|
||||||
// Render the places outside the map first to speed up visual errors fixing
|
// 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)
|
if (outsideMap != 0)
|
||||||
{
|
{
|
||||||
@ -127,17 +164,8 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
|
|
||||||
return Double.compare(dist1, dist2);
|
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(0, 1);
|
||||||
// _scale.put(1, 2);
|
// _scale.put(1, 2);
|
||||||
_scale.put(1, 4);
|
_scale.put(1, 4);
|
||||||
@ -147,7 +175,7 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
|
|
||||||
for (Entry<Integer, Integer> entry : _scale.entrySet())
|
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][];
|
Byte[][] bytes = new Byte[size][];
|
||||||
|
|
||||||
for (int i = 0; i < size; i++)
|
for (int i = 0; i < size; i++)
|
||||||
@ -165,6 +193,23 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
|
|
||||||
_world = Bukkit.getWorld("world");
|
_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
|
try
|
||||||
{
|
{
|
||||||
File file = new File("world/clans_map_id");
|
File file = new File("world/clans_map_id");
|
||||||
@ -238,6 +283,58 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
rebuildScan();
|
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)
|
private void setupRenderer(MapView view)
|
||||||
@ -256,10 +353,7 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
if (!(event.getRightClicked() instanceof ItemFrame))
|
if (!(event.getRightClicked() instanceof ItemFrame))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ItemStack item = event.getPlayer().getItemInHand();
|
if (!isItemClansMap(event.getPlayer().getItemInHand()))
|
||||||
|
|
||||||
if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId
|
|
||||||
|| item.getDurability() > _mapId + 100)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
@ -270,7 +364,7 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
*/
|
*/
|
||||||
public int calcMapCenter(int zoom, int cord)
|
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
|
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);
|
Byte[][] map = _map.get(scale);
|
||||||
int zoom = getZoom(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;
|
double d0 = 0;
|
||||||
|
|
||||||
@ -319,10 +413,10 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
{
|
{
|
||||||
for (int addZ = 0; addZ < zoom; addZ++)
|
for (int addZ = 0; addZ < zoom; addZ++)
|
||||||
{
|
{
|
||||||
int hX = x + addX + _halfMapSize;
|
int hX = x + addX + HALF_WORLD_SIZE;
|
||||||
int hZ = (startingZ - zoom) + addZ + _halfMapSize;
|
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;
|
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
|
// Water depth colors not included
|
||||||
double d1 = 0;
|
double d1 = 0;
|
||||||
@ -340,10 +434,10 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
{
|
{
|
||||||
for (int addZ = 0; addZ < zoom; addZ++)
|
for (int addZ = 0; addZ < zoom; addZ++)
|
||||||
{
|
{
|
||||||
int hX = x + addX + _halfMapSize;
|
int hX = x + addX + HALF_WORLD_SIZE;
|
||||||
int hZ = z + addZ + _halfMapSize;
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
@ -370,7 +464,7 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
b0 = 0;
|
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)
|
/*if (color < 4)
|
||||||
{
|
{
|
||||||
@ -388,7 +482,7 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
byte color = (byte) (origColor + b0);
|
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);
|
Byte[][] second = _map.get(scale);
|
||||||
int zoom = getZoom(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();
|
HashMultiset<Byte> hashmultiset = HashMultiset.create();
|
||||||
|
|
||||||
@ -409,8 +503,8 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
{
|
{
|
||||||
for (int addZ = 0; addZ < zoom; addZ++)
|
for (int addZ = 0; addZ < zoom; addZ++)
|
||||||
{
|
{
|
||||||
int pX = x + addX + _halfMapSize;
|
int pX = x + addX + HALF_WORLD_SIZE;
|
||||||
int pZ = z + addZ + _halfMapSize;
|
int pZ = z + addZ + HALF_WORLD_SIZE;
|
||||||
|
|
||||||
if (pX >= first.length || pZ >= first.length)
|
if (pX >= first.length || pZ >= first.length)
|
||||||
{
|
{
|
||||||
@ -432,7 +526,7 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
{
|
{
|
||||||
color = (byte) 0;
|
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
|
@EventHandler
|
||||||
public void dropItem(ItemSpawnEvent event)
|
public void dropItem(ItemSpawnEvent event)
|
||||||
{
|
{
|
||||||
ItemStack item = event.getEntity().getItemStack();
|
if (isItemClansMap(event.getEntity().getItemStack()))
|
||||||
|
|
||||||
if (item != null && item.getType() == Material.MAP && item.getDurability() >= _mapId
|
|
||||||
&& item.getDurability() <= _mapId + 100)
|
|
||||||
{
|
|
||||||
event.getEntity().remove();
|
event.getEntity().remove();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void removeMap(Player player)
|
public void removeMap(Player player)
|
||||||
{
|
{
|
||||||
for (int slot = 0; slot < player.getInventory().getSize(); slot++)
|
for (int slot = 0; slot < player.getInventory().getSize(); slot++)
|
||||||
{
|
{
|
||||||
ItemStack item = player.getInventory().getItem(slot);
|
if (isItemClansMap(player.getInventory().getItem(slot)))
|
||||||
|
|
||||||
if (item != null && item.getType() == Material.MAP && item.getDurability() >= _mapId && item.getDurability() <= _mapId + 100)
|
|
||||||
{
|
|
||||||
player.getInventory().setItem(slot, null);
|
player.getInventory().setItem(slot, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public ClansUtility getClansUtility()
|
public ClansUtility getClansUtility()
|
||||||
{
|
{
|
||||||
@ -477,7 +562,7 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
|
|
||||||
private double getDistance(Entry<Integer, Integer> entry, double x1, double z1)
|
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)
|
public Byte[][] getMap(int scale)
|
||||||
@ -492,7 +577,7 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
|
|
||||||
public int getMapSize()
|
public int getMapSize()
|
||||||
{
|
{
|
||||||
return _halfMapSize;
|
return HALF_WORLD_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getZoom(int scale)
|
public int getZoom(int scale)
|
||||||
@ -500,35 +585,7 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
return _scale.get(scale);
|
return _scale.get(scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
//fixme So what appears to happen is that after you die, if your map is is the same then the map is frozen
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onDeath(PlayerDeathEvent event)
|
public void onDeath(PlayerDeathEvent event)
|
||||||
{
|
{
|
||||||
@ -542,14 +599,10 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
{
|
{
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
ItemStack item = player.getInventory().getItem(event.getNewSlot());
|
if (!isItemClansMap(player.getInventory().getItem(event.getNewSlot())))
|
||||||
|
|
||||||
if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId
|
|
||||||
|| item.getDurability() > _mapId + 100)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
showZoom(player, getMap(player));
|
showZoom(player, getMap(player));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@ -558,10 +611,7 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
if (event.getAction() == Action.PHYSICAL)
|
if (event.getAction() == Action.PHYSICAL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ItemStack item = event.getItem();
|
if (!isItemClansMap(event.getItem()))
|
||||||
|
|
||||||
if (item == null || item.getType() != Material.MAP || item.getDurability() < _mapId
|
|
||||||
|| item.getDurability() > _mapId + 100)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
@ -666,36 +716,11 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
|
|
||||||
private void rebuildScan()
|
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));
|
_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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,101 +769,117 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
if (event.getType() != UpdateType.FAST)
|
if (event.getType() != UpdateType.FAST)
|
||||||
return;
|
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();
|
rebuildScan();
|
||||||
}
|
}
|
||||||
else if (_scanList.size() % 20 == 0)
|
|
||||||
|
if (_scanList.size() % 20 == 0)
|
||||||
{
|
{
|
||||||
Collections.sort(_scanList, _comparator);
|
Collections.sort(_scanList, _comparator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_scanList.isEmpty())
|
if (_scanList.isEmpty())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Entry<Integer, Integer> entry = _scanList.remove(0);
|
Entry<Integer, Integer> entry = _scanList.remove(0);
|
||||||
|
|
||||||
int startingX = entry.getKey();
|
int startingX = entry.getKey();
|
||||||
int startingZ = entry.getValue();
|
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)
|
if (outsideMap)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
for (int scale = 1; scale < _scale.size(); scale++)
|
for (int scale = 1; scale < _scale.size(); scale++)
|
||||||
{
|
|
||||||
if (scale == 3 && _loadWorld)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!outsideMap)
|
|
||||||
{
|
{
|
||||||
drawWorldScale(scale, startingX, startingZ);
|
drawWorldScale(scale, startingX, startingZ);
|
||||||
}
|
|
||||||
|
|
||||||
colorWorldHeight(scale, startingX, startingZ);
|
colorWorldHeight(scale, startingX, startingZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
colorWorldHeight(0, 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);
|
Byte[][] map = _map.get(0);
|
||||||
|
for (int beginX = startingX; beginX < startingX + BLOCK_SCAN_INTERVAL; beginX += 16)
|
||||||
for (int beginX = startingX; beginX < startingX + _blocksScan; beginX += 16)
|
|
||||||
{
|
{
|
||||||
for (int beginZ = startingZ - (startingZ > -_halfMapSize ? 16 : 0); beginZ < startingZ
|
for (int beginZ = startingZ - (startingZ > -HALF_WORLD_SIZE ? 16 : 0); beginZ < startingZ
|
||||||
+ (setColors ? _blocksScan : 16); beginZ += 16)
|
+ (setColors ? BLOCK_SCAN_INTERVAL : 16); beginZ += 16)
|
||||||
{
|
{
|
||||||
Chunk chunk = _world.getChunkAt(beginX / 16, beginZ / 16);
|
int chunkX = beginX / 16;
|
||||||
boolean loaded = false;
|
int chunkZ = beginZ / 16;
|
||||||
|
net.minecraft.server.v1_8_R3.Chunk nmsChunk = _chunkProviderServer.getChunkIfLoaded(chunkX, chunkZ);
|
||||||
if (!chunk.isLoaded())
|
if (nmsChunk == null)
|
||||||
{
|
{
|
||||||
if (_loadWorld)
|
long key = LongHash.toLong(chunkX, chunkZ);
|
||||||
|
nmsChunk = _chunkCache.get(key);
|
||||||
|
if (nmsChunk == null)
|
||||||
{
|
{
|
||||||
loaded = chunk.load();
|
if (!isFirstScan)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
continue;
|
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 x = beginX; x < beginX + 16; x++)
|
||||||
{
|
{
|
||||||
for (int z = beginZ; z < beginZ + 16; z++)
|
for (int z = beginZ; z < beginZ + 16; z++)
|
||||||
{
|
{
|
||||||
int color = 0;
|
int color = 0;
|
||||||
|
|
||||||
if (!nmsChunk.isEmpty())
|
|
||||||
{
|
|
||||||
int k3 = x & 0xF;
|
int k3 = x & 0xF;
|
||||||
int l3 = z & 0xF;
|
int l3 = z & 0xF;
|
||||||
|
|
||||||
@ -850,7 +891,8 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
l4--;
|
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));
|
while (iblockdata.getBlock().g(iblockdata) == MaterialMapColor.b && (l4 > 0));
|
||||||
|
|
||||||
@ -860,33 +902,30 @@ public class ItemMapManager extends MiniPlugin
|
|||||||
Block block1;
|
Block block1;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
block1 = nmsChunk.getType(new BlockPosition(k3, j5--, l3));
|
_blockPosition.c(k3, j5--, l3);
|
||||||
|
block1 = nmsChunk.getType(_blockPosition);
|
||||||
}
|
}
|
||||||
while ((j5 > 0) && (block1.getMaterial().isLiquid()));
|
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)
|
if (setColors)
|
||||||
{
|
{
|
||||||
//color = block.f(i5).M;
|
//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 = data.getBlock().g(data).M;
|
||||||
|
|
||||||
color = (byte) ((color * 4) + 1);
|
color = (byte) ((color * 4) + 1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (setColors && beginZ >= startingZ)
|
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))
|
for (ItemStack item : UtilInv.getItems(player))
|
||||||
{
|
{
|
||||||
if (item.getType() == Material.MAP && (item.getDurability() >= _mapId && item.getDurability() <= _mapId + 100))
|
if (isItemClansMap(item))
|
||||||
{
|
{
|
||||||
return;
|
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();
|
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)
|
if (slot >= 0)
|
||||||
{
|
{
|
||||||
ItemStack mapSlot = player.getInventory().getItem(8);
|
|
||||||
|
|
||||||
if (mapSlot == null || mapSlot.getType() == Material.AIR)
|
|
||||||
{
|
|
||||||
slot = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
player.getInventory().setItem(slot, item);
|
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)
|
private void showZoom(Player player, MapInfo info)
|
||||||
{
|
{
|
||||||
String progressBar = C.cBlue + "";
|
UtilTextBottom.display(ZOOM_INFO[info.getScale()], player);
|
||||||
|
}
|
||||||
|
|
||||||
boolean colorChange = false;
|
/*
|
||||||
|
* Check whether an {@link ItemStack} is also a Clans Map
|
||||||
for (int i = 2; i >= 0; i--)
|
*
|
||||||
|
* @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())
|
return UtilItem.matchesMaterial(itemStack, Material.MAP)
|
||||||
{
|
&& itemStack.getDurability() >= _mapId
|
||||||
progressBar += C.cGray;
|
&& itemStack.getDurability() <= _mapId + 100;
|
||||||
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 += " ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UtilTextBottom.display(progressBar, player);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,9 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This event is called when a Player is about to receive a Clans Map
|
||||||
|
*/
|
||||||
public class PlayerGetMapEvent extends Event
|
public class PlayerGetMapEvent extends Event
|
||||||
{
|
{
|
||||||
private static final HandlerList handlers = new HandlerList();
|
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)
|
public void onPickup(PlayerPickupItemEvent event)
|
||||||
{
|
{
|
||||||
refreshClient(event.getPlayer());
|
refreshClient(event.getPlayer());
|
||||||
|
@ -131,7 +131,7 @@ public class ObserverManager extends MiniPlugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler (priority = EventPriority.LOWEST)
|
||||||
public void onPickup(PlayerPickupItemEvent event)
|
public void onPickup(PlayerPickupItemEvent event)
|
||||||
{
|
{
|
||||||
ObserverData data = _observerMap.get(event.getPlayer());
|
ObserverData data = _observerMap.get(event.getPlayer());
|
||||||
|
@ -197,18 +197,7 @@ public class ClansRegions extends MiniPlugin
|
|||||||
{
|
{
|
||||||
int x = chunkX + xOffset;
|
int x = chunkX + xOffset;
|
||||||
int z = chunkZ + zOffset;
|
int z = chunkZ + zOffset;
|
||||||
Chunk chunk;
|
String chunkStr = location.getWorld().getName() + "," + x + "," + z;
|
||||||
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);
|
|
||||||
|
|
||||||
if (addNegative)
|
if (addNegative)
|
||||||
{
|
{
|
||||||
|
@ -132,7 +132,7 @@ public class SiegeWeaponRepository extends MinecraftRepository
|
|||||||
|
|
||||||
public void updateWeapon(SiegeWeaponToken token)
|
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(() ->
|
_siegeManager.runAsync(() ->
|
||||||
executeUpdate(UPDATE_WEAPON,
|
executeUpdate(UPDATE_WEAPON,
|
||||||
|
@ -27,6 +27,7 @@ import org.bukkit.event.player.PlayerInteractEvent;
|
|||||||
import org.bukkit.event.world.ChunkUnloadEvent;
|
import org.bukkit.event.world.ChunkUnloadEvent;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
import org.bukkit.util.EulerAngle;
|
import org.bukkit.util.EulerAngle;
|
||||||
import org.spigotmc.event.entity.EntityDismountEvent;
|
import org.spigotmc.event.entity.EntityDismountEvent;
|
||||||
|
|
||||||
@ -559,6 +560,7 @@ public abstract class SiegeWeapon implements Listener
|
|||||||
{
|
{
|
||||||
entity.setCustomName(Integer.toString(_uniqueId));
|
entity.setCustomName(Integer.toString(_uniqueId));
|
||||||
entity.setCustomNameVisible(false);
|
entity.setCustomNameVisible(false);
|
||||||
|
entity.setMetadata("Creature.DoNotDrop", new FixedMetadataValue(_clans.getPlugin(), true));
|
||||||
|
|
||||||
_comprisedOf.add(entity);
|
_comprisedOf.add(entity);
|
||||||
|
|
||||||
@ -569,6 +571,8 @@ public abstract class SiegeWeapon implements Listener
|
|||||||
{
|
{
|
||||||
Entity entity = _entityMapping.get(uniqueName);
|
Entity entity = _entityMapping.get(uniqueName);
|
||||||
|
|
||||||
|
entity.removeMetadata("Creature.DoNotDrop", _clans.getPlugin());
|
||||||
|
|
||||||
_entityMapping.remove(uniqueName);
|
_entityMapping.remove(uniqueName);
|
||||||
_comprisedOf.remove(entity);
|
_comprisedOf.remove(entity);
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ public class GoldManager extends MiniPlugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler (ignoreCancelled = true)
|
||||||
public void onPickup(PlayerPickupItemEvent event)
|
public void onPickup(PlayerPickupItemEvent event)
|
||||||
{
|
{
|
||||||
if (_itemSet.contains(event.getItem()))
|
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!
|
// Repair!
|
||||||
UtilPlayer.message(player, F.main("Repair", "You repaired " + F.item(item.getItemMeta().getDisplayName()) + "."));
|
UtilPlayer.message(player, F.main("Repair", "You repaired " + F.item(item.getItemMeta().getDisplayName()) + "."));
|
||||||
item.setDurability((short) 0);
|
item.setDurability((short) 0);
|
||||||
|
@ -29,7 +29,7 @@ import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
|||||||
* @author MrTwiggy
|
* @author MrTwiggy
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class CustomItem
|
public class CustomItem implements Listener
|
||||||
{
|
{
|
||||||
|
|
||||||
private static final ChatColor TITLE_COLOR = ChatColor.GOLD; // Chat color
|
private static final ChatColor TITLE_COLOR = ChatColor.GOLD; // Chat color
|
||||||
@ -73,6 +73,7 @@ public class CustomItem
|
|||||||
_material = material;
|
_material = material;
|
||||||
_attributes = new AttributeContainer();
|
_attributes = new AttributeContainer();
|
||||||
_uuid = UUID.randomUUID().toString();
|
_uuid = UUID.randomUUID().toString();
|
||||||
|
UtilServer.RegisterEvents(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CustomItem(Material material)
|
public CustomItem(Material material)
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
package mineplex.game.clans.items.attributes;
|
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.game.clans.items.generation.ValueDistribution;
|
||||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
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.entity.EntityDamageByEntityEvent;
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
|
||||||
@ -127,4 +131,21 @@ public abstract class ItemAttribute
|
|||||||
}
|
}
|
||||||
return s;
|
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(attacker instanceof Player && ClansManager.getInstance().isSafe((Player) attacker)) return;
|
||||||
if(defender instanceof Player && ClansManager.getInstance().isSafe((Player) defender)) return;
|
if(defender instanceof Player && ClansManager.getInstance().isSafe((Player) defender)) return;
|
||||||
if(attacker instanceof Player && ((Player)attacker).getGameMode().equals(GameMode.CREATIVE)) return;
|
if(attacker instanceof Player && ((Player)attacker).getGameMode().equals(GameMode.CREATIVE)) return;
|
||||||
|
if (isTeammate(attacker, defender)) return;
|
||||||
defender.setFireTicks(_fireDuration);
|
defender.setFireTicks(_fireDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ public class FrostedAttribute extends ItemAttribute
|
|||||||
|
|
||||||
if (victim != null)
|
if (victim != null)
|
||||||
{
|
{
|
||||||
|
if (isTeammate(event.GetDamagerPlayer(true), victim)) return;
|
||||||
victim.addPotionEffect(generateSlowEffect()); // Slow attacking player
|
victim.addPotionEffect(generateSlowEffect()); // Slow attacking player
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ public class HasteAttribute extends AttackAttribute
|
|||||||
@Override
|
@Override
|
||||||
public void triggerAttack(Entity attacker, Entity defender)
|
public void triggerAttack(Entity attacker, Entity defender)
|
||||||
{
|
{
|
||||||
|
if (isTeammate(attacker, defender)) return;
|
||||||
if (attacker instanceof Player)
|
if (attacker instanceof Player)
|
||||||
{
|
{
|
||||||
Player player = (Player) attacker;
|
Player player = (Player) attacker;
|
||||||
|
@ -28,6 +28,7 @@ public class JaggedAttribute extends AttackAttribute {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void triggerAttack(Entity attacker, Entity defender) {
|
public void triggerAttack(Entity attacker, Entity defender) {
|
||||||
|
if (isTeammate(attacker, defender)) return;
|
||||||
defender.setVelocity(new Vector(0, 0, 0));
|
defender.setVelocity(new Vector(0, 0, 0));
|
||||||
if (defender instanceof LivingEntity)
|
if (defender instanceof LivingEntity)
|
||||||
((LivingEntity) defender).addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 20, 1, false, false));
|
((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);
|
Player damager = event.GetDamagerPlayer(false);
|
||||||
|
|
||||||
|
if (isTeammate(damager, event.GetDamageePlayer())) return;
|
||||||
|
|
||||||
double damage = event.GetDamage();
|
double damage = event.GetDamage();
|
||||||
double healAmount = damage * (_healPercent / 100d);
|
double healAmount = damage * (_healPercent / 100d);
|
||||||
heal(damager, healAmount);
|
heal(damager, healAmount);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package mineplex.game.clans.items.legendaries;
|
package mineplex.game.clans.items.legendaries;
|
||||||
|
|
||||||
|
import mineplex.core.recharge.Recharge;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -14,7 +15,7 @@ import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
|||||||
public class GiantsBroadsword extends LegendaryItem
|
public class GiantsBroadsword extends LegendaryItem
|
||||||
{
|
{
|
||||||
public static final int SLOW_AMPLIFIER = 43;
|
public static final int SLOW_AMPLIFIER = 43;
|
||||||
public static final int REGEN_AMPLIFIER = 3;
|
public static final int REGEN_AMPLIFIER = 1;
|
||||||
|
|
||||||
public GiantsBroadsword()
|
public GiantsBroadsword()
|
||||||
{
|
{
|
||||||
@ -60,6 +61,7 @@ public class GiantsBroadsword extends LegendaryItem
|
|||||||
private void buffPlayer(Player player)
|
private void buffPlayer(Player player)
|
||||||
{
|
{
|
||||||
grantPotionEffect(player, PotionEffectType.SLOW, 40, SLOW_AMPLIFIER);
|
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 + "blade can rip through any opponent.",
|
||||||
C.cWhite + " ",
|
C.cWhite + " ",
|
||||||
C.cWhite + "Hit delay is reduced by " + C.cYellow + "50%",
|
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",
|
C.cYellow + "Right-Click" + C.cWhite + " to use " + C.cGreen + "Dash",
|
||||||
}, Material.RECORD_3);
|
}, Material.RECORD_3);
|
||||||
_speedAmount = amountGen.generateIntValue();
|
_speedAmount = amountGen.generateIntValue();
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
package mineplex.game.clans.items.legendaries;
|
package mineplex.game.clans.items.legendaries;
|
||||||
|
|
||||||
import org.bukkit.Location;
|
import mineplex.core.common.util.C;
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.LivingEntity;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.util.Vector;
|
|
||||||
|
|
||||||
import mineplex.core.common.util.UtilAction;
|
import mineplex.core.common.util.UtilAction;
|
||||||
import mineplex.core.common.util.UtilAlg;
|
import mineplex.core.common.util.UtilAlg;
|
||||||
import mineplex.core.common.util.UtilMath;
|
import mineplex.core.common.util.UtilMath;
|
||||||
@ -18,6 +13,12 @@ import mineplex.core.common.util.UtilWorld;
|
|||||||
import mineplex.game.clans.clans.ClansManager;
|
import mineplex.game.clans.clans.ClansManager;
|
||||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
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 class MagneticMaul extends LegendaryItem
|
||||||
{
|
{
|
||||||
public static final double PULL_RANGE = 10d;
|
public static final double PULL_RANGE = 10d;
|
||||||
@ -27,8 +28,10 @@ public class MagneticMaul extends LegendaryItem
|
|||||||
|
|
||||||
public MagneticMaul()
|
public MagneticMaul()
|
||||||
{
|
{
|
||||||
super("Magnetic Maul", new String[]{
|
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);
|
}, Material.RECORD_5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,6 @@
|
|||||||
package mineplex.game.clans.items.legendaries;
|
package mineplex.game.clans.items.legendaries;
|
||||||
|
|
||||||
import org.bukkit.GameMode;
|
import java.util.HashMap;
|
||||||
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 mineplex.core.common.util.C;
|
import mineplex.core.common.util.C;
|
||||||
import mineplex.core.common.util.F;
|
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.UtilBlock;
|
||||||
import mineplex.core.common.util.UtilCollections;
|
import mineplex.core.common.util.UtilCollections;
|
||||||
import mineplex.core.common.util.UtilColor;
|
import mineplex.core.common.util.UtilColor;
|
||||||
import mineplex.core.common.util.UtilEnt;
|
|
||||||
import mineplex.core.common.util.UtilParticle;
|
import mineplex.core.common.util.UtilParticle;
|
||||||
import mineplex.core.common.util.UtilParticle.ParticleType;
|
import mineplex.core.common.util.UtilParticle.ParticleType;
|
||||||
import mineplex.core.common.util.UtilParticle.ViewDist;
|
import mineplex.core.common.util.UtilParticle.ViewDist;
|
||||||
import mineplex.core.incognito.IncognitoManager;
|
|
||||||
import mineplex.core.common.util.UtilPlayer;
|
import mineplex.core.common.util.UtilPlayer;
|
||||||
import mineplex.core.common.util.UtilServer;
|
import mineplex.core.common.util.UtilServer;
|
||||||
import mineplex.core.common.util.UtilShapes;
|
import mineplex.core.common.util.UtilShapes;
|
||||||
import mineplex.core.common.util.UtilText;
|
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.core.recharge.Recharge;
|
||||||
import mineplex.game.clans.clans.ClansManager;
|
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
|
public class MeridianScepter extends LegendaryItem
|
||||||
{
|
{
|
||||||
private long _lastFire = System.currentTimeMillis();
|
|
||||||
private long _interactWait;
|
private long _interactWait;
|
||||||
|
|
||||||
private RGBData[] colors = { UtilColor.RgbPurple, UtilColor.RgbPurple.Lighten(), UtilColor.RgbPurple.Darken() };
|
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()
|
public MeridianScepter()
|
||||||
{
|
{
|
||||||
@ -101,20 +101,13 @@ public class MeridianScepter extends LegendaryItem
|
|||||||
// If they are less than 0.5 blocks away
|
// If they are less than 0.5 blocks away
|
||||||
if (player.getEyeLocation().subtract(0, .3, 0).distance(projectile) <= 2)
|
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;
|
UtilPlayer.message(player, F.main("Clans", F.elem(shooter.getName()) + " hit you with a " + F.elem("Meridian Scepter") + C.mBody + "."));
|
||||||
|
|
||||||
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(shooter, F.main("Clans", "You hit " + F.elem(player.getName()) + " with your " + 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);
|
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;
|
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.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
|
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
|
||||||
import org.bukkit.entity.Player;
|
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 org.bukkit.util.Vector;
|
||||||
|
|
||||||
import mineplex.core.common.util.C;
|
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.UtilParticle.ViewDist;
|
||||||
import mineplex.core.common.util.UtilPlayer;
|
import mineplex.core.common.util.UtilPlayer;
|
||||||
import mineplex.core.common.util.UtilTextBottom;
|
import mineplex.core.common.util.UtilTextBottom;
|
||||||
import mineplex.core.common.util.UtilTextMiddle;
|
|
||||||
import mineplex.core.common.util.UtilTime;
|
import mineplex.core.common.util.UtilTime;
|
||||||
import mineplex.core.recharge.Recharge;
|
import mineplex.core.recharge.Recharge;
|
||||||
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
public class WindBlade extends LegendaryItem
|
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;
|
public static final double FLIGHT_VELOCITY = 0.75d;
|
||||||
|
|
||||||
private double _power;
|
private double _power;
|
||||||
@ -32,7 +53,7 @@ public class WindBlade extends LegendaryItem
|
|||||||
|
|
||||||
public WindBlade()
|
public WindBlade()
|
||||||
{
|
{
|
||||||
super("Wind Blade", new String[] {
|
super("Wind Blade", new String[]{
|
||||||
C.cWhite + "Long ago, a race of cloud dwellers",
|
C.cWhite + "Long ago, a race of cloud dwellers",
|
||||||
C.cWhite + "terrorized the skies. A remnant of",
|
C.cWhite + "terrorized the skies. A remnant of",
|
||||||
C.cWhite + "their tyranny, this airy blade is",
|
C.cWhite + "their tyranny, this airy blade is",
|
||||||
@ -129,12 +150,35 @@ public class WindBlade extends LegendaryItem
|
|||||||
event.AddMod("Wind Blade", 6);
|
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)
|
private void propelPlayer(Player player)
|
||||||
{
|
{
|
||||||
Vector direction = player.getLocation().getDirection().normalize();
|
Vector direction = player.getLocation().getDirection().normalize();
|
||||||
direction.multiply(FLIGHT_VELOCITY);
|
direction.multiply(FLIGHT_VELOCITY);
|
||||||
|
|
||||||
player.setVelocity(direction);
|
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)
|
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
|
@EventHandler
|
||||||
public void onSkill(SkillTriggerEvent event)
|
public void onSkill(SkillTriggerEvent event)
|
||||||
{
|
{
|
||||||
@ -391,13 +400,13 @@ public class Spawn extends MiniPlugin
|
|||||||
if (isInSpawn(victim))
|
if (isInSpawn(victim))
|
||||||
{
|
{
|
||||||
event.SetCancelled("Safe Zone");
|
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;
|
return;
|
||||||
}
|
}
|
||||||
else if (isInSpawn(attacker) && !isCombatTagged(attacker))
|
else if (isInSpawn(attacker) && !isCombatTagged(attacker))
|
||||||
{
|
{
|
||||||
event.SetCancelled("Safe Zone");
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package mineplex.game.clans.tutorial;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -25,7 +26,7 @@ public class TutorialWorldManager extends MiniPlugin
|
|||||||
|
|
||||||
private final World _tutorialWorld;
|
private final World _tutorialWorld;
|
||||||
private final Schematic _schematic;
|
private final Schematic _schematic;
|
||||||
private Stack<TutorialRegion> _regionStack;
|
private LinkedList<TutorialRegion> _regionStack;
|
||||||
private TutorialRegion _centerRegion;
|
private TutorialRegion _centerRegion;
|
||||||
|
|
||||||
public TutorialWorldManager(JavaPlugin plugin, String worldName, String schematicName) throws IOException
|
public TutorialWorldManager(JavaPlugin plugin, String worldName, String schematicName) throws IOException
|
||||||
@ -56,7 +57,7 @@ public class TutorialWorldManager extends MiniPlugin
|
|||||||
|
|
||||||
private void populateRegionStack()
|
private void populateRegionStack()
|
||||||
{
|
{
|
||||||
_regionStack = new Stack<>();
|
_regionStack = new LinkedList<>();
|
||||||
|
|
||||||
// Populate the stack with 100 available tutorial regions
|
// Populate the stack with 100 available tutorial regions
|
||||||
for (int x = 0; x < 10; x++)
|
for (int x = 0; x < 10; x++)
|
||||||
|
@ -10,14 +10,16 @@ public class FinishCommand extends CommandBase<TutorialManager>
|
|||||||
{
|
{
|
||||||
public FinishCommand(TutorialManager plugin)
|
public FinishCommand(TutorialManager plugin)
|
||||||
{
|
{
|
||||||
super(plugin, Rank.JNR_DEV, "finish", "end");
|
super(plugin, Rank.ALL, "finish", "end");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void Execute(Player caller, String[] args)
|
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);
|
Plugin.finishTutorial(caller);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
package mineplex.game.clans.tutorial.command;
|
package mineplex.game.clans.tutorial.command;
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import mineplex.core.command.CommandBase;
|
|
||||||
import mineplex.core.command.MultiCommandBase;
|
import mineplex.core.command.MultiCommandBase;
|
||||||
import mineplex.core.common.Rank;
|
import mineplex.core.common.Rank;
|
||||||
import mineplex.core.common.util.F;
|
import mineplex.core.common.util.F;
|
||||||
import mineplex.core.common.util.UtilPlayer;
|
import mineplex.core.common.util.UtilPlayer;
|
||||||
import mineplex.game.clans.tutorial.TutorialManager;
|
import mineplex.game.clans.tutorial.TutorialManager;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public class TutorialCommand extends MultiCommandBase<TutorialManager>
|
public class TutorialCommand extends MultiCommandBase<TutorialManager>
|
||||||
{
|
{
|
||||||
public TutorialCommand(TutorialManager plugin)
|
public TutorialCommand(TutorialManager plugin)
|
||||||
{
|
{
|
||||||
super(plugin, Rank.JNR_DEV, "tutorial", "tut");
|
super(plugin, Rank.ALL, "tutorial", "tut");
|
||||||
|
|
||||||
AddCommand(new StartCommand(plugin));
|
AddCommand(new StartCommand(plugin));
|
||||||
AddCommand(new FinishCommand(plugin));
|
AddCommand(new FinishCommand(plugin));
|
||||||
@ -24,4 +22,14 @@ public class TutorialCommand extends MultiCommandBase<TutorialManager>
|
|||||||
{
|
{
|
||||||
UtilPlayer.message(caller, F.main("Tutorial", "/tutorial start <name>"));
|
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;
|
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.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
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.clans.siege.events.LoadSiegeWeaponEvent;
|
||||||
import mineplex.game.clans.tutorial.objective.ObjectiveGoal;
|
import mineplex.game.clans.tutorial.objective.ObjectiveGoal;
|
||||||
import mineplex.game.clans.tutorial.tutorials.clans.objective.AttackEnemyObjective;
|
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>
|
public class LoadCannonGoal extends ObjectiveGoal<AttackEnemyObjective>
|
||||||
{
|
{
|
||||||
@ -43,4 +47,15 @@ public class LoadCannonGoal extends ObjectiveGoal<AttackEnemyObjective>
|
|||||||
|
|
||||||
finish(event.getPlayer());
|
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;
|
package mineplex.game.clans.world;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import mineplex.core.common.util.UtilWorld;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Item;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import mineplex.core.MiniPlugin;
|
import mineplex.core.MiniPlugin;
|
||||||
import mineplex.core.common.util.UtilMath;
|
|
||||||
import mineplex.core.updater.UpdateType;
|
import mineplex.core.updater.UpdateType;
|
||||||
import mineplex.core.updater.event.UpdateEvent;
|
import mineplex.core.updater.event.UpdateEvent;
|
||||||
import mineplex.game.clans.clans.ClansManager;
|
|
||||||
|
|
||||||
public class WorldManager extends MiniPlugin
|
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)
|
public WorldManager(JavaPlugin plugin)
|
||||||
{
|
{
|
||||||
super("Clan World Manager", plugin);
|
super("Clan World Manager", plugin);
|
||||||
@ -33,118 +75,77 @@ public class WorldManager extends MiniPlugin
|
|||||||
|
|
||||||
for (World world : getPlugin().getServer().getWorlds())
|
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())
|
for (Entity entity : world.getEntities())
|
||||||
_ents.put(type, new ArrayList<Entity>());
|
|
||||||
|
|
||||||
for (Entity ent : 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;
|
boolean cull = true;
|
||||||
|
for (Player player : players)
|
||||||
for (Player player : world.getPlayers())
|
|
||||||
{
|
{
|
||||||
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;
|
cull = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cull)
|
if (cull)
|
||||||
{
|
{
|
||||||
_ents.get(ent.getType()).add(ent);
|
entities.computeIfAbsent(entityType, key -> new HashSet<>()).add(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else if (MINECART_TYPES.contains(entityType))
|
||||||
|
|
||||||
for (EntityType type : _ents.keySet())
|
|
||||||
{
|
{
|
||||||
ArrayList<Entity> ents = _ents.get(type);
|
if (entity.getTicksLived() > 800)
|
||||||
|
|
||||||
//Clean Old Arrows
|
|
||||||
if (type == EntityType.ARROW)
|
|
||||||
{
|
{
|
||||||
for (Entity ent : ents)
|
entity.remove();
|
||||||
if (ent.getTicksLived() > 800)
|
}
|
||||||
ent.remove();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Clean Old Items
|
for (Map.Entry<EntityType, Set<Entity>> entry : entities.entrySet())
|
||||||
if (type == EntityType.DROPPED_ITEM)
|
|
||||||
{
|
{
|
||||||
for (Entity ent : ents)
|
cull(entry.getKey(), entry.getValue(), CULL_LIMITS.get(entry.getKey()));
|
||||||
if (ent.getTicksLived() > 2400)
|
}
|
||||||
ent.remove();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Animals
|
private void cull(EntityType type, Set<Entity> ents, int limit)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
Iterator<Entity> iterator = ents.iterator();
|
||||||
int culled = 0;
|
int culled = 0;
|
||||||
EntityType type = null;
|
while (iterator.hasNext() && ents.size() > limit)
|
||||||
while (ents.size() > limit)
|
|
||||||
{
|
{
|
||||||
Entity ent = ents.remove(UtilMath.r(ents.size()));
|
Entity entity = iterator.next();
|
||||||
|
entity.remove();
|
||||||
type = ent.getType();
|
iterator.remove();
|
||||||
|
|
||||||
ent.remove();
|
|
||||||
|
|
||||||
culled++;
|
culled++;
|
||||||
}
|
}
|
||||||
|
log("Culled " + culled + " " + type);
|
||||||
if (type != null)
|
|
||||||
{
|
|
||||||
System.out.println("Culled " + culled + " " + type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ public class Leap extends SkillActive
|
|||||||
{
|
{
|
||||||
//Action
|
//Action
|
||||||
if (!wallkick)
|
if (!wallkick)
|
||||||
UtilAction.velocity(player, 1.2, 0.2, 1, true);
|
UtilAction.velocity(player, 1 + 0.15 * level, 0.2, 1, true);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Vector vec = player.getLocation().getDirection();
|
Vector vec = player.getLocation().getDirection();
|
||||||
|
@ -60,11 +60,6 @@ public class Recall extends Skill
|
|||||||
{
|
{
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
if (!(player.getOpenInventory().getTopInventory() instanceof CraftInventoryCrafting))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int level = getLevel(player);
|
int level = getLevel(player);
|
||||||
if (level == 0)
|
if (level == 0)
|
||||||
return;
|
return;
|
||||||
@ -92,6 +87,7 @@ public class Recall extends Skill
|
|||||||
if (health == null)
|
if (health == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Factory.runSync(() -> {
|
||||||
//Heal
|
//Heal
|
||||||
double newHealth = Math.min(health.getLast(), player.getHealth() + 3 + level);
|
double newHealth = Math.min(health.getLast(), player.getHealth() + 3 + level);
|
||||||
player.setHealth(newHealth);
|
player.setHealth(newHealth);
|
||||||
@ -117,19 +113,9 @@ public class Recall extends Skill
|
|||||||
ViewDist.LONGER, UtilServer.getPlayers());
|
ViewDist.LONGER, UtilServer.getPlayers());
|
||||||
current = current.add(UtilAlg.getTrajectory(current, target).multiply(0.1));
|
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
|
@EventHandler
|
||||||
public void storeLocation(UpdateEvent event)
|
public void storeLocation(UpdateEvent event)
|
||||||
|
@ -2,6 +2,7 @@ package mineplex.minecraft.game.classcombat.Skill.Brute;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
@ -167,18 +168,20 @@ public class Takedown extends SkillActive
|
|||||||
int damage = 3 + (level);
|
int damage = 3 + (level);
|
||||||
|
|
||||||
//Damage Event
|
//Damage Event
|
||||||
Factory.Damage().NewDamageEvent(damagee, damager, null,
|
CustomDamageEvent customDamageEvent = Factory.Damage().NewDamageEvent(damagee, damager, null,
|
||||||
DamageCause.CUSTOM, damage, false, true, false,
|
DamageCause.CUSTOM, damage, false, true, false,
|
||||||
damager.getName(), GetName());
|
damager.getName(), GetName());
|
||||||
|
|
||||||
|
if (!customDamageEvent.IsCancelled())
|
||||||
|
{
|
||||||
//Damage Event
|
//Damage Event
|
||||||
Factory.Damage().NewDamageEvent(damager, damagee, null,
|
Factory.Damage().NewDamageEvent(damager, damagee, null,
|
||||||
DamageCause.CUSTOM, damage/2, false, true, false,
|
DamageCause.CUSTOM, damage / 2, false, true, false,
|
||||||
damager.getName(), GetName() + " Recoil");
|
damager.getName(), GetName() + " Recoil");
|
||||||
|
|
||||||
//Conditions
|
//Conditions
|
||||||
Factory.Condition().Factory().Slow(GetName(), damagee, damager, 2.5 + 0.5*level, 3, false, true, true, true);
|
Factory.Condition().Factory().Slow(GetName(), damagee, damager, 2.5 + 0.5 * level, 3, false, true, true, true);
|
||||||
Factory.Condition().Factory().Slow(GetName(), damager, damager, 2.5 + 0.5*level, 3, false, true, true, true);
|
Factory.Condition().Factory().Slow(GetName(), damager, damager, 2.5 + 0.5 * level, 3, false, true, true, true);
|
||||||
|
|
||||||
//Inform
|
//Inform
|
||||||
UtilPlayer.message(damager, F.main(GetClassType().name(), "You hit " + F.name(UtilEnt.getName(damagee)) + " with " + F.skill(GetName(level)) + "."));
|
UtilPlayer.message(damager, F.main(GetClassType().name(), "You hit " + F.name(UtilEnt.getName(damagee)) + " with " + F.skill(GetName(level)) + "."));
|
||||||
@ -187,6 +190,7 @@ public class Takedown extends SkillActive
|
|||||||
//Sound
|
//Sound
|
||||||
damager.getWorld().playSound(damager.getLocation(), Sound.ZOMBIE_WOOD, 1f, 0.5f);
|
damager.getWorld().playSound(damager.getLocation(), Sound.ZOMBIE_WOOD, 1f, 0.5f);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void Particle(UpdateEvent event)
|
public void Particle(UpdateEvent event)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package mineplex.minecraft.game.classcombat.Skill.Knight;
|
package mineplex.minecraft.game.classcombat.Skill.Knight;
|
||||||
|
|
||||||
|
import mineplex.minecraft.game.core.condition.events.ConditionExpireEvent;
|
||||||
import org.bukkit.Effect;
|
import org.bukkit.Effect;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
@ -22,6 +23,10 @@ import mineplex.core.updater.UpdateType;
|
|||||||
import mineplex.core.updater.event.UpdateEvent;
|
import mineplex.core.updater.event.UpdateEvent;
|
||||||
import mineplex.minecraft.game.classcombat.Skill.SkillActive;
|
import mineplex.minecraft.game.classcombat.Skill.SkillActive;
|
||||||
import mineplex.minecraft.game.classcombat.Skill.SkillFactory;
|
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
|
public class HoldPosition extends SkillActive
|
||||||
{
|
{
|
||||||
@ -47,10 +52,13 @@ public class HoldPosition extends SkillActive
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Map<Player, Integer> _foodLevel = new HashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean CustomCheck(Player player, int level)
|
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."));
|
UtilPlayer.message(player, F.main("Skill", "You cannot use " + F.skill(GetName()) + " in water."));
|
||||||
return false;
|
return false;
|
||||||
@ -75,6 +83,8 @@ public class HoldPosition extends SkillActive
|
|||||||
//Effect
|
//Effect
|
||||||
player.getWorld().playSound(player.getLocation(), Sound.ENDERMAN_SCREAM, 1.5f, 0f);
|
player.getWorld().playSound(player.getLocation(), Sound.ENDERMAN_SCREAM, 1.5f, 0f);
|
||||||
player.getWorld().playEffect(player.getLocation(), Effect.STEP_SOUND, 49);
|
player.getWorld().playEffect(player.getLocation(), Effect.STEP_SOUND, 49);
|
||||||
|
|
||||||
|
_foodLevel.put(player, player.getFoodLevel());
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGH)
|
@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
|
@Override
|
||||||
public void Reset(Player player)
|
public void Reset(Player player)
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,7 @@ import java.util.Map.Entry;
|
|||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import mineplex.core.MiniPlugin;
|
import mineplex.core.MiniPlugin;
|
||||||
|
import mineplex.core.common.util.UtilServer;
|
||||||
import mineplex.core.recharge.Recharge;
|
import mineplex.core.recharge.Recharge;
|
||||||
import mineplex.core.updater.event.UpdateEvent;
|
import mineplex.core.updater.event.UpdateEvent;
|
||||||
import mineplex.core.updater.UpdateType;
|
import mineplex.core.updater.UpdateType;
|
||||||
@ -18,6 +19,7 @@ import mineplex.core.common.util.UtilTime;
|
|||||||
import mineplex.core.common.util.UtilTime.TimeUnit;
|
import mineplex.core.common.util.UtilTime.TimeUnit;
|
||||||
import mineplex.minecraft.game.core.condition.Condition.ConditionType;
|
import mineplex.minecraft.game.core.condition.Condition.ConditionType;
|
||||||
import mineplex.minecraft.game.core.condition.events.ConditionApplyEvent;
|
import mineplex.minecraft.game.core.condition.events.ConditionApplyEvent;
|
||||||
|
import mineplex.minecraft.game.core.condition.events.ConditionExpireEvent;
|
||||||
import mineplex.minecraft.game.core.damage.DamageManager;
|
import mineplex.minecraft.game.core.damage.DamageManager;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -189,9 +191,13 @@ public class ConditionManager extends MiniPlugin
|
|||||||
Condition cond = conditionIterator.next();
|
Condition cond = conditionIterator.next();
|
||||||
|
|
||||||
if (cond.Tick())
|
if (cond.Tick())
|
||||||
|
{
|
||||||
|
ConditionExpireEvent conditionExpireEvent = new ConditionExpireEvent(cond);
|
||||||
|
UtilServer.CallEvent(conditionExpireEvent);
|
||||||
conditionIterator.remove();
|
conditionIterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Indicators **/
|
/** Indicators **/
|
||||||
for (LivingEntity ent : _activeConditions.keySet())
|
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,
|
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
|
||||||
String source, String reason)
|
String source, String reason)
|
||||||
{
|
{
|
||||||
NewDamageEvent(damagee, damager, proj,
|
return NewDamageEvent(damagee, damager, proj,
|
||||||
cause, damage, knockback, ignoreRate, ignoreArmor,
|
cause, damage, knockback, ignoreRate, ignoreArmor,
|
||||||
source, reason, false);
|
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,
|
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
|
||||||
String source, String reason, boolean cancelled)
|
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,
|
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
|
||||||
String source, String reason)
|
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);
|
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,
|
DamageCause cause, double damage, boolean knockback, boolean ignoreRate, boolean ignoreArmor,
|
||||||
String source, String reason, boolean cancelled)
|
String source, String reason, boolean cancelled)
|
||||||
{
|
{
|
||||||
_plugin.getServer().getPluginManager().callEvent(new CustomDamageEvent(damagee, damager, proj, knockbackOrigin, cause,
|
CustomDamageEvent customDamageEvent = new CustomDamageEvent(damagee, damager, proj, knockbackOrigin, cause,
|
||||||
damage, knockback, ignoreRate, ignoreArmor, source, reason, cancelled));
|
damage, knockback, ignoreRate, ignoreArmor, source, reason, cancelled);
|
||||||
|
_plugin.getServer().getPluginManager().callEvent(customDamageEvent);
|
||||||
|
return customDamageEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOW)
|
@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);
|
DisplayDamage(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,7 +538,7 @@ public class DamageManager extends MiniPlugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler (priority = EventPriority.MONITOR)
|
||||||
public void DamageSound(CustomDamageEvent event)
|
public void DamageSound(CustomDamageEvent event)
|
||||||
{
|
{
|
||||||
if (event.IsCancelled())
|
if (event.IsCancelled())
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
package nautilus.game.arcade;
|
package nautilus.game.arcade;
|
||||||
|
|
||||||
import java.util.AbstractMap;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import mineplex.core.common.MinecraftVersion;
|
import mineplex.core.common.MinecraftVersion;
|
||||||
import mineplex.core.common.Pair;
|
import mineplex.core.common.Pair;
|
||||||
import mineplex.core.game.GameCategory;
|
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.wither.WitherGame;
|
||||||
import nautilus.game.arcade.game.games.wizards.Wizards;
|
import nautilus.game.arcade.game.games.wizards.Wizards;
|
||||||
import nautilus.game.arcade.game.games.zombiesurvival.ZombieSurvival;
|
import nautilus.game.arcade.game.games.zombiesurvival.ZombieSurvival;
|
||||||
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
|
||||||
public enum GameType
|
public enum GameType
|
||||||
@ -100,7 +96,7 @@ public enum GameType
|
|||||||
DragonsTeams(DragonsTeams.class, GameDisplay.DragonsTeams),
|
DragonsTeams(DragonsTeams.class, GameDisplay.DragonsTeams),
|
||||||
Draw(Draw.class, GameDisplay.Draw, new Pair[]
|
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),
|
}, true),
|
||||||
ElytraRings(ElytraRings.class, GameDisplay.ElytraRings),
|
ElytraRings(ElytraRings.class, GameDisplay.ElytraRings),
|
||||||
Evolution(Evolution.class, GameDisplay.Evolution),
|
Evolution(Evolution.class, GameDisplay.Evolution),
|
||||||
@ -117,8 +113,8 @@ public enum GameType
|
|||||||
MilkCow(MilkCow.class, GameDisplay.MilkCow),
|
MilkCow(MilkCow.class, GameDisplay.MilkCow),
|
||||||
MineStrike(MineStrike.class, GameDisplay.MineStrike, new Pair[]
|
MineStrike(MineStrike.class, GameDisplay.MineStrike, new Pair[]
|
||||||
{
|
{
|
||||||
Pair.create(MinecraftVersion.Version1_8, "http://chivebox.com/mineplex/ResMinestrike.zip"),
|
Pair.create(MinecraftVersion.Version1_8, "http://file.mineplex.com/ResMinestrike.zip"),
|
||||||
Pair.create(MinecraftVersion.Version1_9, "http://chivebox.com/mineplex/ResMinestrike19.zip")
|
Pair.create(MinecraftVersion.Version1_9, "http://file.mineplex.com/ResMinestrike19.zip")
|
||||||
}, true),
|
}, true),
|
||||||
MineWare(MineWare.class, GameDisplay.MineWare),
|
MineWare(MineWare.class, GameDisplay.MineWare),
|
||||||
MinecraftLeague(MinecraftLeague.class, GameDisplay.Minecraft_League),
|
MinecraftLeague(MinecraftLeague.class, GameDisplay.Minecraft_League),
|
||||||
|
@ -140,7 +140,7 @@ public class MiscManager implements Listener
|
|||||||
@EventHandler
|
@EventHandler
|
||||||
public void HubCommand(PlayerCommandPreprocessEvent event)
|
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");
|
Manager.GetPortal().sendPlayerToServer(event.getPlayer(), "Lobby");
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
Loading…
Reference in New Issue
Block a user