mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-29 04:28:21 +01:00
Merge remote-tracking branch 'origin/master' into block-types
This commit is contained in:
commit
fcc0f5e035
12
build.gradle
12
build.gradle
@ -35,17 +35,15 @@ dependencies {
|
||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||
|
||||
// https://mvnrepository.com/artifact/io.netty/netty-all
|
||||
api group: 'io.netty', name: 'netty-all', version: '4.1.48.Final'
|
||||
api group: 'io.netty', name: 'netty-all', version: '4.1.50.Final'
|
||||
|
||||
api 'com.github.jhg023:Pbbl:1.0.1'
|
||||
api 'com.github.jhg023:Pbbl:1.0.2'
|
||||
|
||||
// https://mvnrepository.com/artifact/it.unimi.dsi/fastutil
|
||||
api group: 'it.unimi.dsi', name: 'fastutil', version: '8.3.0'
|
||||
|
||||
api 'com.github.Querz:NBT:4.1'
|
||||
|
||||
// https://mvnrepository.com/artifact/com.google.code.gson/gson
|
||||
api group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
|
||||
api group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
|
||||
|
||||
api 'com.github.TheMode:CommandBuilder:f893cfbfe4'
|
||||
|
||||
@ -66,4 +64,8 @@ dependencies {
|
||||
api 'net.kyori:text-serializer-legacy:3.0.3'
|
||||
api 'net.kyori:text-serializer-gson:3.0.3'
|
||||
api 'net.kyori:text-serializer-plain:3.0.3'
|
||||
|
||||
// Pathfinding
|
||||
implementation 'com.github.MadMartian:hydrazine-path-finding:1.02'
|
||||
|
||||
}
|
||||
|
71
src/main/java/fr/themode/demo/MainDemo.java
Normal file
71
src/main/java/fr/themode/demo/MainDemo.java
Normal file
@ -0,0 +1,71 @@
|
||||
package fr.themode.demo;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.event.player.PlayerLoginEvent;
|
||||
import net.minestom.server.event.player.PlayerSpawnEvent;
|
||||
import net.minestom.server.instance.*;
|
||||
import net.minestom.server.instance.batch.ChunkBatch;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.network.ConnectionManager;
|
||||
import net.minestom.server.utils.Position;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class MainDemo {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Initialization
|
||||
MinecraftServer minecraftServer = MinecraftServer.init();
|
||||
|
||||
InstanceManager instanceManager = MinecraftServer.getInstanceManager();
|
||||
// Create the instance
|
||||
InstanceContainer instanceContainer = instanceManager.createInstanceContainer();
|
||||
// Set the ChunkGenerator
|
||||
instanceContainer.setChunkGenerator(new GeneratorDemo());
|
||||
// Enable the auto chunk loading (when players come close)
|
||||
instanceContainer.enableAutoChunkLoad(true);
|
||||
|
||||
// Add event listeners
|
||||
ConnectionManager connectionManager = MinecraftServer.getConnectionManager();
|
||||
connectionManager.addPlayerInitialization(player -> {
|
||||
// Set the spawning instance
|
||||
player.addEventCallback(PlayerLoginEvent.class, event -> {
|
||||
event.setSpawningInstance(instanceContainer);
|
||||
});
|
||||
|
||||
// Teleport the player at spawn
|
||||
player.addEventCallback(PlayerSpawnEvent.class, event -> {
|
||||
player.teleport(new Position(0, 45, 0));
|
||||
});
|
||||
});
|
||||
|
||||
// Start the server
|
||||
minecraftServer.start("localhost", 55555);
|
||||
}
|
||||
|
||||
private static class GeneratorDemo extends ChunkGenerator {
|
||||
|
||||
@Override
|
||||
public void generateChunkData(ChunkBatch batch, int chunkX, int chunkZ) {
|
||||
// Set chunk blocks
|
||||
for (byte x = 0; x < Chunk.CHUNK_SIZE_X; x++)
|
||||
for (byte z = 0; z < Chunk.CHUNK_SIZE_Z; z++) {
|
||||
for (byte y = 0; y < 40; y++) {
|
||||
batch.setBlock(x, y, z, Block.STONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillBiomes(Biome[] biomes, int chunkX, int chunkZ) {
|
||||
Arrays.fill(biomes, Biome.PLAINS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChunkPopulator> getPopulators() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -4,6 +4,7 @@ import fr.themode.demo.entity.ChickenCreature;
|
||||
import fr.themode.demo.generator.ChunkGeneratorDemo;
|
||||
import fr.themode.demo.generator.NoiseTestGenerator;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.attribute.Attribute;
|
||||
import net.minestom.server.benchmark.BenchmarkManager;
|
||||
import net.minestom.server.benchmark.ThreadResult;
|
||||
import net.minestom.server.entity.*;
|
||||
@ -39,6 +40,11 @@ import java.util.UUID;
|
||||
|
||||
public class PlayerInit {
|
||||
|
||||
private static String textures = "ewogICJ0aW1lc3RhbXAiIDogMTU5MDg1NTI3NjIwNCwKICAicHJvZmlsZUlkIiA6ICI0NTY2ZTY5ZmM5MDc0OGVlOGQ3MWQ3YmE1YWEwMGQyMCIsCiAgInByb2ZpbGVOYW1lIiA6ICJUaGlua29mZGVhdGgiLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzRkMWUwOGIwYmI3ZTlmNTkwYWYyNzc1ODEyNWJiZWQxNzc4YWM2Y2VmNzI5YWVkZmNiOTYxM2U5OTExYWU3NSIKICAgIH0sCiAgICAiQ0FQRSIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYjBjYzA4ODQwNzAwNDQ3MzIyZDk1M2EwMmI5NjVmMWQ2NWExM2E2MDNiZjY0YjE3YzgwM2MyMTQ0NmZlMTYzNSIKICAgIH0KICB9Cn0=";
|
||||
private static String signature = "rCVVwVpLF9ovy+Hm4cOXOLSPOMjNo5WoBfHo9K2OcTUPqcZJ1P/1k4lAnQkChD/Ri11iJ84PejWJzDkHMXM8196Wh+jf12d2GJVhca9/SRLms0cFJjdZZjs72+82AdX0OtO3+qzwKRHzHoEYb+ZVZLfgx37ZKKo4DD3IKmaSnwEjOVJ4BOhnsXLmcNW37kdZUmv2/hlg7ZuWZaayWPhadCYEMnkpVtDIpnpzAeV9EcRfg/ysQoynO2v6WEW0RtnfFEczMN6vXtfiuC8UqyA2SK9aiLnBgpGaehDfFIq/0dpo2uFilVDS/Il6uQ1JSwq7yNT5lNF+i1AlH9SGf1VVy5mT9ShmkVmRxCXX5cSNLXZD0acsNNJb/GAuDHuXpE32GsfgKxWAXMHLw0GnbADbFDfdl5nQyQTDS7FRfUjsFpF8a8Z83muFXaty2WLFy1zxy2JEkI/q+ltLaEG6mQbWI2zhOS7ARvK0OmPz4lDYVInfrwL93AIdMUg2Re817hsapkN6Dm1ND+iirvayR90gqQ9C9J0dMMBlSyTSoKBQeLsi8qETS+7LuhvletPTDFolnTIvP8hj2bWLmQ7LfXJ2arJCUw86YEavVYuF0gYrBuKcEYTC4DA0kO4yLj63gwEgOj9dEigCgyqUcenzmZBffSZ365/QF0cGrG7HC7HmF0w=";
|
||||
|
||||
private static PlayerSkin skin = new PlayerSkin(textures, signature);
|
||||
|
||||
private static volatile InstanceContainer instanceContainer;
|
||||
private static volatile InstanceContainer netherTest;
|
||||
|
||||
@ -95,16 +101,15 @@ public class PlayerInit {
|
||||
benchmarkMessage += "&e" + MathUtils.round(result.getCpuPercentage(), 2) + "% CPU ";
|
||||
benchmarkMessage += "&c" + MathUtils.round(result.getUserPercentage(), 2) + "% USER ";
|
||||
benchmarkMessage += "&d" + MathUtils.round(result.getBlockedPercentage(), 2) + "% BLOCKED ";
|
||||
benchmarkMessage += "&a" + MathUtils.round(result.getWaitedPercentage(), 2) + "% WAITED ";
|
||||
benchmarkMessage += "\n";
|
||||
}
|
||||
// if (benchmarkMessage.length() > 0)
|
||||
// System.out.println(benchmarkMessage);
|
||||
|
||||
for (Player player : connectionManager.getOnlinePlayers()) {
|
||||
player.sendHeaderFooter("RAM USAGE: " + ramUsage + " MB", benchmarkMessage, '&');
|
||||
}
|
||||
}
|
||||
}, new UpdateOption(5, TimeUnit.TICK));
|
||||
}, new UpdateOption(10, TimeUnit.TICK));
|
||||
|
||||
connectionManager.addPacketConsumer((player, packetController, packet) -> {
|
||||
// Listen to all received packet
|
||||
@ -137,10 +142,10 @@ public class PlayerInit {
|
||||
return;
|
||||
|
||||
if (event.getBlockId() == Block.STONE.getBlockId()) {
|
||||
event.setCustomBlockId((short) 2); // custom stone block
|
||||
event.setCustomBlock((short) 2); // custom stone block
|
||||
}
|
||||
if (event.getBlockId() == Block.TORCH.getBlockId()) {
|
||||
event.setCustomBlockId((short) 3); // custom torch block
|
||||
event.setCustomBlock((short) 3); // custom torch block
|
||||
}
|
||||
|
||||
/*for (Player p : player.getInstance().getPlayers()) {
|
||||
@ -150,6 +155,7 @@ public class PlayerInit {
|
||||
|
||||
ChickenCreature chickenCreature = new ChickenCreature(player.getPosition());
|
||||
chickenCreature.setInstance(player.getInstance());
|
||||
chickenCreature.setAttribute(Attribute.MOVEMENT_SPEED, 0.4f);
|
||||
|
||||
/*FakePlayer fakePlayer = new FakePlayer(UUID.randomUUID(), "test");
|
||||
fakePlayer.addEventCallback(EntityDeathEvent.class, e -> {
|
||||
@ -211,19 +217,24 @@ public class PlayerInit {
|
||||
scoreboard.setTitle("test");*/
|
||||
});
|
||||
|
||||
player.addEventCallback(PlayerSkinInitEvent.class, event -> {
|
||||
event.setSkin(skin);
|
||||
});
|
||||
|
||||
player.addEventCallback(PlayerSpawnEvent.class, event -> {
|
||||
player.setGameMode(GameMode.CREATIVE);
|
||||
player.teleport(new Position(0, 45, 0));
|
||||
player.teleport(new Position(0, 41f, 0));
|
||||
|
||||
player.setGlowing(true);
|
||||
|
||||
ItemStack item = new ItemStack(Material.STONE_SWORD, (byte) 1);
|
||||
item.setDisplayName("Item name");
|
||||
item.getLore().add("a lore line");
|
||||
item.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
|
||||
item.setEnchantment(Enchantment.SHARPNESS, (short) 2);
|
||||
item.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
||||
item.setEnchantment(Enchantment.SHARPNESS, (short) 50);
|
||||
player.getInventory().addItemStack(item);
|
||||
|
||||
inventory.addItemStack(item.clone());
|
||||
player.openInventory(inventory);
|
||||
|
||||
player.getInventory().addItemStack(new ItemStack(Material.STONE, (byte) 100));
|
||||
@ -256,7 +267,7 @@ public class PlayerInit {
|
||||
});
|
||||
|
||||
player.addEventCallback(PlayerRespawnEvent.class, event -> {
|
||||
event.setRespawnPosition(new Position(0f, 45f, 0f));
|
||||
event.setRespawnPosition(new Position(0f, 41f, 0f));
|
||||
});
|
||||
|
||||
player.addEventCallback(PlayerUseItemEvent.class, useEvent -> {
|
||||
@ -301,7 +312,7 @@ public class PlayerInit {
|
||||
|
||||
public static ResponseDataConsumer getResponseDataConsumer() {
|
||||
return (playerConnection, responseData) -> {
|
||||
responseData.setMaxPlayer(100);
|
||||
responseData.setMaxPlayer(0);
|
||||
responseData.setOnline(MinecraftServer.getConnectionManager().getOnlinePlayers().size());
|
||||
responseData.addPlayer("A name", UUID.randomUUID());
|
||||
responseData.addPlayer("Could be some message", UUID.randomUUID());
|
||||
|
@ -2,6 +2,7 @@ package fr.themode.demo.commands;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.command.CommandProcessor;
|
||||
import net.minestom.server.command.CommandSender;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.world.Dimension;
|
||||
@ -20,22 +21,27 @@ public class DimensionCommand implements CommandProcessor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(Player player, String command, String[] args) {
|
||||
public boolean process(CommandSender sender, String command, String[] args) {
|
||||
|
||||
if (!(sender instanceof Player))
|
||||
return false;
|
||||
Player player = (Player) sender;
|
||||
|
||||
Instance instance = player.getInstance();
|
||||
|
||||
Dimension targetDimension = Dimension.NETHER;
|
||||
if(instance.getDimension() == Dimension.NETHER) {
|
||||
if (instance.getDimension() == Dimension.NETHER) {
|
||||
targetDimension = Dimension.OVERWORLD;
|
||||
}
|
||||
|
||||
Dimension finalTargetDimension = targetDimension;
|
||||
Optional<Instance> targetInstance = MinecraftServer.getInstanceManager().getInstances().stream().filter(in -> in.getDimension() == finalTargetDimension).findFirst();
|
||||
if(targetInstance.isPresent()) {
|
||||
player.sendMessage("You were in "+instance.getDimension());
|
||||
if (targetInstance.isPresent()) {
|
||||
player.sendMessage("You were in " + instance.getDimension());
|
||||
player.setInstance(targetInstance.get());
|
||||
player.sendMessage("You are now in "+targetDimension);
|
||||
player.sendMessage("You are now in " + targetDimension);
|
||||
} else {
|
||||
player.sendMessage("Could not find instance with dimension "+targetDimension);
|
||||
player.sendMessage("Could not find instance with dimension " + targetDimension);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -4,6 +4,7 @@ import fr.themode.command.Arguments;
|
||||
import fr.themode.command.Command;
|
||||
import fr.themode.command.arguments.Argument;
|
||||
import fr.themode.command.arguments.ArgumentType;
|
||||
import net.minestom.server.command.CommandSender;
|
||||
import net.minestom.server.entity.GameMode;
|
||||
import net.minestom.server.entity.Player;
|
||||
|
||||
@ -12,7 +13,7 @@ import java.util.Optional;
|
||||
/**
|
||||
* Command that make a player change gamemode
|
||||
*/
|
||||
public class GamemodeCommand extends Command<Player> {
|
||||
public class GamemodeCommand extends Command<CommandSender> {
|
||||
public GamemodeCommand() {
|
||||
super("gamemode", "g", "gm");
|
||||
|
||||
@ -35,11 +36,13 @@ public class GamemodeCommand extends Command<Player> {
|
||||
addSyntax(this::executeOnOther, player, mode);
|
||||
}
|
||||
|
||||
private void usage(Player player, Arguments arguments) {
|
||||
player.sendMessage("Usage: /gamemode [player] <gamemode>");
|
||||
private void usage(CommandSender sender, Arguments arguments) {
|
||||
sender.sendMessage("Usage: /gamemode [player] <gamemode>");
|
||||
}
|
||||
|
||||
private void executeOnSelf(Player player, Arguments arguments) {
|
||||
private void executeOnSelf(CommandSender sender, Arguments arguments) {
|
||||
Player player = (Player) sender;
|
||||
|
||||
String gamemodeName = arguments.getWord("mode");
|
||||
GameMode mode = GameMode.valueOf(gamemodeName.toUpperCase());
|
||||
assert mode != null; // mode is not supposed to be null, because gamemodeName will be valid
|
||||
@ -47,7 +50,9 @@ public class GamemodeCommand extends Command<Player> {
|
||||
player.sendMessage("You are now playing in " + gamemodeName);
|
||||
}
|
||||
|
||||
private void executeOnOther(Player player, Arguments arguments) {
|
||||
private void executeOnOther(CommandSender sender, Arguments arguments) {
|
||||
Player player = (Player) sender;
|
||||
|
||||
String gamemodeName = arguments.getWord("mode");
|
||||
String targetName = arguments.getWord("player");
|
||||
GameMode mode = GameMode.valueOf(gamemodeName.toUpperCase());
|
||||
@ -61,11 +66,15 @@ public class GamemodeCommand extends Command<Player> {
|
||||
}
|
||||
}
|
||||
|
||||
private void gameModeCallback(Player player, String gamemode, int error) {
|
||||
player.sendMessage("'" + gamemode + "' is not a valid gamemode!");
|
||||
private void gameModeCallback(CommandSender sender, String gamemode, int error) {
|
||||
sender.sendMessage("'" + gamemode + "' is not a valid gamemode!");
|
||||
}
|
||||
|
||||
private boolean isAllowed(Player player) {
|
||||
return true; // TODO: permissions
|
||||
private boolean isAllowed(CommandSender sender) {
|
||||
if (!(sender instanceof Player)) {
|
||||
sender.sendMessage("The command is only available for player");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,10 @@ import fr.themode.command.Command;
|
||||
import fr.themode.command.arguments.Argument;
|
||||
import fr.themode.command.arguments.ArgumentType;
|
||||
import fr.themode.command.arguments.number.ArgumentNumber;
|
||||
import net.minestom.server.command.CommandSender;
|
||||
import net.minestom.server.entity.Player;
|
||||
|
||||
public class HealthCommand extends Command<Player> {
|
||||
public class HealthCommand extends Command<CommandSender> {
|
||||
|
||||
public HealthCommand() {
|
||||
super("health", "h", "healthbar");
|
||||
@ -27,39 +28,39 @@ public class HealthCommand extends Command<Player> {
|
||||
addSyntax(this::execute2, arg0, arg1);
|
||||
}
|
||||
|
||||
private boolean condition(Player player) {
|
||||
boolean hasPerm = true;
|
||||
if (!hasPerm) {
|
||||
player.sendMessage("You do not have permission !");
|
||||
private boolean condition(CommandSender sender) {
|
||||
if (!(sender instanceof Player)) {
|
||||
sender.sendMessage("The command is only available for player");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void defaultExecutor(Player player, Arguments args) {
|
||||
player.sendMessage("Correct usage: health [set/add] [number]");
|
||||
private void defaultExecutor(CommandSender sender, Arguments args) {
|
||||
sender.sendMessage("Correct usage: health [set/add] [number]");
|
||||
}
|
||||
|
||||
private void modeCallback(Player player, String value, int error) {
|
||||
player.sendMessage("SYNTAX ERROR: '" + value + "' should be replaced by 'set' or 'add'");
|
||||
private void modeCallback(CommandSender sender, String value, int error) {
|
||||
sender.sendMessage("SYNTAX ERROR: '" + value + "' should be replaced by 'set' or 'add'");
|
||||
}
|
||||
|
||||
private void valueCallback(Player player, String value, int error) {
|
||||
private void valueCallback(CommandSender sender, String value, int error) {
|
||||
switch (error) {
|
||||
case ArgumentNumber.NOT_NUMBER_ERROR:
|
||||
player.sendMessage("SYNTAX ERROR: '" + value + "' isn't a number!");
|
||||
sender.sendMessage("SYNTAX ERROR: '" + value + "' isn't a number!");
|
||||
break;
|
||||
case ArgumentNumber.RANGE_ERROR:
|
||||
player.sendMessage("SYNTAX ERROR: " + value + " is not between 0 and 100");
|
||||
sender.sendMessage("SYNTAX ERROR: " + value + " is not between 0 and 100");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void execute(Player player, Arguments args) {
|
||||
player.sendMessage("/health " + args.getWord("mode") + " [Integer]");
|
||||
private void execute(CommandSender sender, Arguments args) {
|
||||
sender.sendMessage("/health " + args.getWord("mode") + " [Integer]");
|
||||
}
|
||||
|
||||
private void execute2(Player player, Arguments args) {
|
||||
private void execute2(CommandSender sender, Arguments args) {
|
||||
Player player = (Player) sender;
|
||||
String mode = args.getWord("mode");
|
||||
int value = args.getInteger("value");
|
||||
|
||||
|
@ -1,7 +1,15 @@
|
||||
package fr.themode.demo.commands;
|
||||
|
||||
import com.extollit.gaming.ai.path.HydrazinePathFinder;
|
||||
import com.extollit.gaming.ai.path.model.PathObject;
|
||||
import com.extollit.linalg.immutable.Vec3i;
|
||||
import fr.themode.demo.entity.ChickenCreature;
|
||||
import net.minestom.server.command.CommandProcessor;
|
||||
import net.minestom.server.command.CommandSender;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.instance.Instance;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
public class SimpleCommand implements CommandProcessor {
|
||||
@Override
|
||||
@ -15,7 +23,11 @@ public class SimpleCommand implements CommandProcessor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean process(Player player, String command, String[] args) {
|
||||
public boolean process(CommandSender sender, String command, String[] args) {
|
||||
|
||||
if (!(sender instanceof Player))
|
||||
return false;
|
||||
Player player = (Player) sender;
|
||||
|
||||
/*for (Player p : MinecraftServer.getConnectionManager().getOnlinePlayers()) {
|
||||
if (!(p instanceof FakePlayer))
|
||||
@ -35,9 +47,33 @@ public class SimpleCommand implements CommandProcessor {
|
||||
break;
|
||||
}*/
|
||||
|
||||
System.gc();
|
||||
player.sendMessage("Garbage collector called");
|
||||
/*for (EntityCreature entityCreature : player.getInstance().getCreatures()) {
|
||||
entityCreature.setPathTo(player.getPosition().clone());
|
||||
//entityCreature.jump(1);
|
||||
}
|
||||
|
||||
System.gc();
|
||||
player.sendMessage("Garbage collector called");*/
|
||||
|
||||
Instance instance = player.getInstance();
|
||||
|
||||
ChickenCreature chickenCreature = new ChickenCreature(player.getPosition());
|
||||
chickenCreature.setInstance(instance);
|
||||
/*
|
||||
PFPathingEntity pathingEntity = new PFPathingEntity(chickenCreature);
|
||||
PFInstanceSpace instanceSpace = new PFInstanceSpace(instance);
|
||||
|
||||
final HydrazinePathFinder pathFinder = new HydrazinePathFinder(pathingEntity, instanceSpace);
|
||||
|
||||
final PathObject path = pathFinder.initiatePathTo(-10, 42, -10);
|
||||
|
||||
for (Iterator<Vec3i> it = path.iterator(); it.hasNext(); ) {
|
||||
Vec3i ite = it.next();
|
||||
|
||||
System.out.println("test: " + ite);
|
||||
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,16 @@
|
||||
package fr.themode.demo.entity;
|
||||
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.EntityCreature;
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.entity.type.EntityChicken;
|
||||
import net.minestom.server.entity.vehicle.PlayerVehicleInformation;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.Vector;
|
||||
|
||||
public class ChickenCreature extends EntityCreature {
|
||||
public class ChickenCreature extends EntityChicken {
|
||||
|
||||
public ChickenCreature(Position defaultPosition) {
|
||||
super(EntityType.CHICKEN, defaultPosition);
|
||||
|
||||
setBoundingBox(0.4f, 0.7f, 0.4f);
|
||||
super(defaultPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -22,8 +19,8 @@ public class ChickenCreature extends EntityCreature {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
public void update(long time) {
|
||||
super.update(time);
|
||||
float speed = 0.075f;
|
||||
|
||||
if (hasPassenger()) {
|
||||
@ -80,10 +77,7 @@ public class ChickenCreature extends EntityCreature {
|
||||
move(x, 0, z, updateView);
|
||||
}
|
||||
} else {
|
||||
//move(0.5f * speed, 0, 0.5f * speed, true);
|
||||
//move(-0.5f * speed, 0, 0.5f * speed, true);
|
||||
}
|
||||
|
||||
//Player player = MinecraftServer.getConnectionManager().getPlayer("TheMode911");
|
||||
//moveTo(player.getPosition().clone());
|
||||
}
|
||||
}
|
||||
|
@ -14,16 +14,6 @@ public class TestArrow extends ObjectEntity {
|
||||
this.shooter = shooter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawn() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getObjectData() {
|
||||
return shooter.getEntityId() + 1;
|
||||
|
@ -9,22 +9,15 @@ import net.minestom.server.instance.block.Block;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class ChunkGeneratorDemo extends ChunkGenerator {
|
||||
|
||||
private final Random random = new Random();
|
||||
|
||||
@Override
|
||||
public void generateChunkData(ChunkBatch batch, int chunkX, int chunkZ) {
|
||||
for (byte x = 0; x < Chunk.CHUNK_SIZE_X; x++)
|
||||
for (byte z = 0; z < Chunk.CHUNK_SIZE_Z; z++) {
|
||||
for (byte y = 0; y < 65; y++) {
|
||||
if (random.nextInt(100) > 10) {
|
||||
batch.setCustomBlock(x, y, z, "custom_block");
|
||||
} else {
|
||||
batch.setBlock(x, y, z, Block.DIAMOND_BLOCK);
|
||||
}
|
||||
for (byte y = 0; y < 40; y++) {
|
||||
batch.setBlock(x, y, z, Block.STONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,6 @@ public class MinecraftServer {
|
||||
public static final String THREAD_NAME_BENCHMARK = "Ms-Benchmark";
|
||||
|
||||
public static final String THREAD_NAME_MAIN_UPDATE = "Ms-MainUpdate";
|
||||
public static final int THREAD_COUNT_MAIN_UPDATE = 1; // Keep it to 1
|
||||
|
||||
public static final String THREAD_NAME_PACKET_WRITER = "Ms-PacketWriterPool";
|
||||
public static final int THREAD_COUNT_PACKET_WRITER = 2;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.minestom.server;
|
||||
|
||||
import net.kyori.text.TextComponent;
|
||||
import net.kyori.text.format.TextColor;
|
||||
import net.minestom.server.entity.EntityManager;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.instance.InstanceManager;
|
||||
@ -10,19 +12,27 @@ import net.minestom.server.utils.thread.MinestomThread;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
public class UpdateManager {
|
||||
public final class UpdateManager {
|
||||
|
||||
private ExecutorService mainUpdate = new MinestomThread(MinecraftServer.THREAD_COUNT_MAIN_UPDATE, MinecraftServer.THREAD_NAME_MAIN_UPDATE);
|
||||
private static final long KEEP_ALIVE_DELAY = 10_000;
|
||||
private static final long KEEP_ALIVE_KICK = 30_000;
|
||||
|
||||
private ExecutorService mainUpdate = new MinestomThread(1, MinecraftServer.THREAD_NAME_MAIN_UPDATE);
|
||||
private boolean stopRequested;
|
||||
|
||||
/**
|
||||
* Should only be created in MinecraftServer
|
||||
*/
|
||||
protected UpdateManager() {
|
||||
}
|
||||
|
||||
public void start() {
|
||||
mainUpdate.execute(() -> {
|
||||
|
||||
ConnectionManager connectionManager = MinecraftServer.getConnectionManager();
|
||||
EntityManager entityManager = MinecraftServer.getEntityManager();
|
||||
InstanceManager instanceManager = MinecraftServer.getInstanceManager();
|
||||
SchedulerManager schedulerManager = MinecraftServer.getSchedulerManager();
|
||||
final ConnectionManager connectionManager = MinecraftServer.getConnectionManager();
|
||||
final EntityManager entityManager = MinecraftServer.getEntityManager();
|
||||
final InstanceManager instanceManager = MinecraftServer.getInstanceManager();
|
||||
final SchedulerManager schedulerManager = MinecraftServer.getSchedulerManager();
|
||||
|
||||
final long tickDistance = MinecraftServer.TICK_MS * 1000000;
|
||||
long currentTime;
|
||||
@ -30,12 +40,17 @@ public class UpdateManager {
|
||||
currentTime = System.nanoTime();
|
||||
|
||||
// Keep Alive Handling
|
||||
final long time = System.currentTimeMillis();
|
||||
final KeepAlivePacket keepAlivePacket = new KeepAlivePacket(time);
|
||||
for (Player player : connectionManager.getOnlinePlayers()) {
|
||||
long time = System.currentTimeMillis();
|
||||
if (time - player.getLastKeepAlive() > 10000) {
|
||||
final long lastKeepAlive = time - player.getLastKeepAlive();
|
||||
if (lastKeepAlive > KEEP_ALIVE_DELAY && player.didAnswerKeepAlive()) {
|
||||
player.refreshKeepAlive(time);
|
||||
KeepAlivePacket keepAlivePacket = new KeepAlivePacket(time);
|
||||
player.getPlayerConnection().sendPacket(keepAlivePacket);
|
||||
} else if (lastKeepAlive >= KEEP_ALIVE_KICK) {
|
||||
TextComponent textComponent = TextComponent.of("Timeout")
|
||||
.color(TextColor.RED);
|
||||
player.kick(textComponent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.minestom.server.entity.property;
|
||||
package net.minestom.server.attribute;
|
||||
|
||||
public enum Attribute {
|
||||
|
||||
@ -37,4 +37,12 @@ public enum Attribute {
|
||||
public float getMaxVanillaValue() {
|
||||
return maxVanillaValue;
|
||||
}
|
||||
|
||||
public static Attribute fromKey(String key) {
|
||||
for (Attribute attribute : values()) {
|
||||
if (attribute.getKey().equals(key))
|
||||
return attribute;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package net.minestom.server.attribute;
|
||||
|
||||
public enum AttributeOperation {
|
||||
ADDITION(0),
|
||||
MULTIPLY_BASE(1),
|
||||
MULTIPLY_TOTAL(2);
|
||||
|
||||
private static final AttributeOperation[] VALUES = new AttributeOperation[]{ADDITION, MULTIPLY_BASE, MULTIPLY_TOTAL};
|
||||
private final int id;
|
||||
|
||||
AttributeOperation(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static AttributeOperation byId(int id) {
|
||||
if (id >= 0 && id < VALUES.length) {
|
||||
return VALUES[id];
|
||||
} else {
|
||||
throw new IllegalArgumentException("No operation with value " + id);
|
||||
}
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ public class BenchmarkManager {
|
||||
|
||||
private Map<Long, Long> lastCpuTimeMap = new HashMap<>();
|
||||
private Map<Long, Long> lastUserTimeMap = new HashMap<>();
|
||||
private Map<Long, Long> lastWaitedMap = new HashMap<>();
|
||||
private Map<Long, Long> lastBlockedMap = new HashMap<>();
|
||||
|
||||
private Map<String, ThreadResult> resultMap = new ConcurrentHashMap<>();
|
||||
@ -100,26 +101,30 @@ public class BenchmarkManager {
|
||||
|
||||
long lastCpuTime = lastCpuTimeMap.getOrDefault(id, 0L);
|
||||
long lastUserTime = lastUserTimeMap.getOrDefault(id, 0L);
|
||||
long lastWaitedTime = lastWaitedMap.getOrDefault(id, 0L);
|
||||
long lastBlockedTime = lastBlockedMap.getOrDefault(id, 0L);
|
||||
|
||||
long blockedTime = threadInfo2.getBlockedTime();
|
||||
//long waitedTime = threadInfo2.getWaitedTime();
|
||||
long waitedTime = threadInfo2.getWaitedTime();
|
||||
long cpuTime = threadMXBean.getThreadCpuTime(id);
|
||||
long userTime = threadMXBean.getThreadUserTime(id);
|
||||
|
||||
lastCpuTimeMap.put(id, cpuTime);
|
||||
lastUserTimeMap.put(id, userTime);
|
||||
lastWaitedMap.put(id, waitedTime);
|
||||
lastBlockedMap.put(id, blockedTime);
|
||||
|
||||
double totalCpuTime = (double) (cpuTime - lastCpuTime) / 1000000D;
|
||||
double totalUserTime = (double) (userTime - lastUserTime) / 1000000D;
|
||||
long totalBlocked = blockedTime - lastBlockedTime;
|
||||
long totalWaited = waitedTime - lastWaitedTime;
|
||||
|
||||
double cpuPercentage = totalCpuTime / (double) time * 100L;
|
||||
double userPercentage = totalUserTime / (double) time * 100L;
|
||||
double waitedPercentage = totalWaited / (double) time * 100L;
|
||||
double blockedPercentage = totalBlocked / (double) time * 100L;
|
||||
|
||||
ThreadResult threadResult = new ThreadResult(cpuPercentage, userPercentage, blockedPercentage);
|
||||
ThreadResult threadResult = new ThreadResult(cpuPercentage, userPercentage, waitedPercentage, blockedPercentage);
|
||||
resultMap.put(name, threadResult);
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,12 @@ package net.minestom.server.benchmark;
|
||||
|
||||
public class ThreadResult {
|
||||
|
||||
private double cpuPercentage, userPercentage, blockedPercentage;
|
||||
private double cpuPercentage, userPercentage, waitedPercentage, blockedPercentage;
|
||||
|
||||
protected ThreadResult(double cpuPercentage, double userPercentage, double blockedPercentage) {
|
||||
protected ThreadResult(double cpuPercentage, double userPercentage, double waitedPercentage, double blockedPercentage) {
|
||||
this.cpuPercentage = cpuPercentage;
|
||||
this.userPercentage = userPercentage;
|
||||
this.waitedPercentage = waitedPercentage;
|
||||
this.blockedPercentage = blockedPercentage;
|
||||
}
|
||||
|
||||
@ -18,6 +19,10 @@ public class ThreadResult {
|
||||
return userPercentage;
|
||||
}
|
||||
|
||||
public double getWaitedPercentage() {
|
||||
return waitedPercentage;
|
||||
}
|
||||
|
||||
public double getBlockedPercentage() {
|
||||
return blockedPercentage;
|
||||
}
|
||||
|
@ -4,12 +4,17 @@ import net.minestom.server.Viewable;
|
||||
import net.minestom.server.chat.Chat;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.packet.server.play.BossBarPacket;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
/**
|
||||
* Represent a bossbar which can be showed to any player {@link #addViewer(Player)}
|
||||
*/
|
||||
public class BossBar implements Viewable {
|
||||
|
||||
private UUID uuid = UUID.randomUUID();
|
||||
@ -48,41 +53,87 @@ public class BossBar implements Viewable {
|
||||
return Collections.unmodifiableSet(viewers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bossbar title
|
||||
*
|
||||
* @return the current title of the bossbar
|
||||
*/
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the bossbar title
|
||||
*
|
||||
* @param title the new title of the bossbar
|
||||
*/
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bossbar progress
|
||||
*
|
||||
* @return the current progress of the bossbar
|
||||
*/
|
||||
public float getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the bossbar progress
|
||||
*
|
||||
* @param progress the new progress bar percentage
|
||||
* @throws IllegalArgumentException if {@code progress} is not between 0 and 1
|
||||
*/
|
||||
public void setProgress(float progress) {
|
||||
Check.argCondition(!MathUtils.isBetween(progress, 0, 1),
|
||||
"BossBar progress percentage should be between 0 and 1");
|
||||
this.progress = progress;
|
||||
updateProgress();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bossbar color
|
||||
*
|
||||
* @return the current bossbar color
|
||||
*/
|
||||
public BarColor getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the bossbar color
|
||||
*
|
||||
* @param color the new color of the bossbar
|
||||
*/
|
||||
public void setColor(BarColor color) {
|
||||
this.color = color;
|
||||
updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bossbar division
|
||||
*
|
||||
* @return the current bossbar division
|
||||
*/
|
||||
public BarDivision getDivision() {
|
||||
return division;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the bossbar division
|
||||
*
|
||||
* @param division the new bossbar division count
|
||||
*/
|
||||
public void setDivision(BarDivision division) {
|
||||
this.division = division;
|
||||
updateStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the boss bar and remove all of its viewers
|
||||
*/
|
||||
public void delete() {
|
||||
BossBarPacket bossBarPacket = new BossBarPacket();
|
||||
bossBarPacket.uuid = uuid;
|
||||
|
@ -21,12 +21,24 @@ public class BoundingBox {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to know if two BoundingBox intersect with each other
|
||||
*
|
||||
* @param boundingBox the bounding box to check
|
||||
* @return true if the two BoundingBox intersect with each other, false otherwise
|
||||
*/
|
||||
public boolean intersect(BoundingBox boundingBox) {
|
||||
return (getMinX() <= boundingBox.getMaxX() && getMaxX() >= boundingBox.getMinX()) &&
|
||||
(getMinY() <= boundingBox.getMaxY() && getMaxY() >= boundingBox.getMinY()) &&
|
||||
(getMinZ() <= boundingBox.getMaxZ() && getMaxZ() >= boundingBox.getMinZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to know if the bounding box intersects with a block (can be air)
|
||||
*
|
||||
* @param blockPosition the position to check
|
||||
* @return true if the bounding box intersects with the position, false otherwise
|
||||
*/
|
||||
public boolean intersect(BlockPosition blockPosition) {
|
||||
|
||||
final float x = blockPosition.getX();
|
||||
@ -62,10 +74,22 @@ public class BoundingBox {
|
||||
return intersect(position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x the X offset
|
||||
* @param y the Y offset
|
||||
* @param z the Z offset
|
||||
* @return a new bounding box expanded
|
||||
*/
|
||||
public BoundingBox expand(float x, float y, float z) {
|
||||
return new BoundingBox(entity, this.x + x, this.y + y, this.z + z);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x the X offset
|
||||
* @param y the Y offset
|
||||
* @param z the Z offset
|
||||
* @return a new bounding box contracted
|
||||
*/
|
||||
public BoundingBox contract(float x, float y, float z) {
|
||||
return new BoundingBox(entity, this.x - x, this.y - y, this.z - z);
|
||||
}
|
||||
@ -107,7 +131,7 @@ public class BoundingBox {
|
||||
}
|
||||
|
||||
public Vector[] getBottomFace() {
|
||||
return new Vector[] {
|
||||
return new Vector[]{
|
||||
new Vector(getMinX(), getMinY(), getMinZ()),
|
||||
new Vector(getMaxX(), getMinY(), getMinZ()),
|
||||
new Vector(getMaxX(), getMinY(), getMaxZ()),
|
||||
@ -116,7 +140,7 @@ public class BoundingBox {
|
||||
}
|
||||
|
||||
public Vector[] getTopFace() {
|
||||
return new Vector[] {
|
||||
return new Vector[]{
|
||||
new Vector(getMinX(), getMaxY(), getMinZ()),
|
||||
new Vector(getMaxX(), getMaxY(), getMinZ()),
|
||||
new Vector(getMaxX(), getMaxY(), getMaxZ()),
|
||||
@ -125,7 +149,7 @@ public class BoundingBox {
|
||||
}
|
||||
|
||||
public Vector[] getLeftFace() {
|
||||
return new Vector[] {
|
||||
return new Vector[]{
|
||||
new Vector(getMinX(), getMinY(), getMinZ()),
|
||||
new Vector(getMinX(), getMaxY(), getMinZ()),
|
||||
new Vector(getMinX(), getMaxY(), getMaxZ()),
|
||||
@ -134,7 +158,7 @@ public class BoundingBox {
|
||||
}
|
||||
|
||||
public Vector[] getRightFace() {
|
||||
return new Vector[] {
|
||||
return new Vector[]{
|
||||
new Vector(getMaxX(), getMinY(), getMinZ()),
|
||||
new Vector(getMaxX(), getMaxY(), getMinZ()),
|
||||
new Vector(getMaxX(), getMaxY(), getMaxZ()),
|
||||
@ -143,7 +167,7 @@ public class BoundingBox {
|
||||
}
|
||||
|
||||
public Vector[] getFrontFace() {
|
||||
return new Vector[] {
|
||||
return new Vector[]{
|
||||
new Vector(getMinX(), getMinY(), getMinZ()),
|
||||
new Vector(getMaxX(), getMinY(), getMinZ()),
|
||||
new Vector(getMaxX(), getMaxY(), getMinZ()),
|
||||
@ -152,7 +176,7 @@ public class BoundingBox {
|
||||
}
|
||||
|
||||
public Vector[] getBackFace() {
|
||||
return new Vector[] {
|
||||
return new Vector[]{
|
||||
new Vector(getMinX(), getMinY(), getMaxZ()),
|
||||
new Vector(getMaxX(), getMinY(), getMaxZ()),
|
||||
new Vector(getMaxX(), getMaxY(), getMaxZ()),
|
||||
|
@ -9,19 +9,33 @@ import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
|
||||
import net.minestom.server.utils.ArrayUtils;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class CommandManager {
|
||||
|
||||
private String commandPrefix = "/";
|
||||
|
||||
private CommandDispatcher<Player> dispatcher = new CommandDispatcher<>();
|
||||
private ConsoleSender consoleSender = new ConsoleSender();
|
||||
|
||||
private CommandDispatcher<CommandSender> dispatcher = new CommandDispatcher<>();
|
||||
private Map<String, CommandProcessor> commandProcessorMap = new HashMap<>();
|
||||
|
||||
public void register(Command<Player> command) {
|
||||
public CommandManager() {
|
||||
// Setup console thread
|
||||
new Thread(() -> {
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
while (true) {
|
||||
String command = scanner.nextLine();
|
||||
if (!command.startsWith(commandPrefix))
|
||||
continue;
|
||||
command = command.replaceFirst(commandPrefix, "");
|
||||
execute(consoleSender, command);
|
||||
|
||||
}
|
||||
}, "ConsoleCommand-Thread").start();
|
||||
}
|
||||
|
||||
public void register(Command<CommandSender> command) {
|
||||
this.dispatcher.register(command);
|
||||
}
|
||||
|
||||
@ -29,20 +43,24 @@ public class CommandManager {
|
||||
this.commandProcessorMap.put(commandProcessor.getCommandName().toLowerCase(), commandProcessor);
|
||||
}
|
||||
|
||||
public boolean execute(Player source, String command) {
|
||||
Check.notNull(source, "Source cannot be null");
|
||||
public boolean execute(CommandSender sender, String command) {
|
||||
Check.notNull(sender, "Source cannot be null");
|
||||
Check.notNull(command, "Command string cannot be null");
|
||||
|
||||
PlayerCommandEvent playerCommandEvent = new PlayerCommandEvent(source, command);
|
||||
source.callEvent(PlayerCommandEvent.class, playerCommandEvent);
|
||||
if (sender instanceof Player) {
|
||||
Player player = (Player) sender;
|
||||
|
||||
if (playerCommandEvent.isCancelled())
|
||||
return false;
|
||||
PlayerCommandEvent playerCommandEvent = new PlayerCommandEvent(player, command);
|
||||
player.callEvent(PlayerCommandEvent.class, playerCommandEvent);
|
||||
|
||||
command = playerCommandEvent.getCommand();
|
||||
if (playerCommandEvent.isCancelled())
|
||||
return false;
|
||||
|
||||
command = playerCommandEvent.getCommand();
|
||||
}
|
||||
|
||||
try {
|
||||
this.dispatcher.execute(source, command);
|
||||
this.dispatcher.execute(sender, command);
|
||||
return true;
|
||||
} catch (NullPointerException e) {
|
||||
String[] splitted = command.split(" ");
|
||||
@ -53,7 +71,7 @@ public class CommandManager {
|
||||
|
||||
String[] args = command.substring(command.indexOf(" ") + 1).split(" ");
|
||||
|
||||
return commandProcessor.process(source, commandName, args);
|
||||
return commandProcessor.process(sender, commandName, args);
|
||||
|
||||
}
|
||||
}
|
||||
@ -66,6 +84,10 @@ public class CommandManager {
|
||||
this.commandPrefix = commandPrefix;
|
||||
}
|
||||
|
||||
public ConsoleSender getConsoleSender() {
|
||||
return consoleSender;
|
||||
}
|
||||
|
||||
public DeclareCommandsPacket createDeclareCommandsPacket(Player player) {
|
||||
return buildPacket(player);
|
||||
}
|
||||
@ -74,7 +96,7 @@ public class CommandManager {
|
||||
DeclareCommandsPacket declareCommandsPacket = new DeclareCommandsPacket();
|
||||
|
||||
List<String> commands = new ArrayList<>();
|
||||
for (Command<Player> command : dispatcher.getCommands()) {
|
||||
for (Command<CommandSender> command : dispatcher.getCommands()) {
|
||||
CommandCondition<Player> commandCondition = command.getCondition();
|
||||
if (commandCondition != null) {
|
||||
// Do not show command if return false
|
||||
|
@ -8,7 +8,7 @@ public interface CommandProcessor {
|
||||
|
||||
String[] getAliases();
|
||||
|
||||
boolean process(Player player, String command, String[] args);
|
||||
boolean process(CommandSender sender, String command, String[] args);
|
||||
|
||||
boolean hasAccess(Player player);
|
||||
}
|
||||
|
13
src/main/java/net/minestom/server/command/CommandSender.java
Normal file
13
src/main/java/net/minestom/server/command/CommandSender.java
Normal file
@ -0,0 +1,13 @@
|
||||
package net.minestom.server.command;
|
||||
|
||||
public interface CommandSender {
|
||||
|
||||
void sendMessage(String message);
|
||||
|
||||
default void sendMessage(String[] messages) {
|
||||
for (String message : messages) {
|
||||
sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package net.minestom.server.command;
|
||||
|
||||
public class ConsoleSender implements CommandSender {
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
System.out.println(message);
|
||||
}
|
||||
}
|
@ -8,7 +8,8 @@ public class Data {
|
||||
|
||||
public static final Data EMPTY = new Data() {
|
||||
@Override
|
||||
public <T> void set(String key, T value, Class<T> type) {}
|
||||
public <T> void set(String key, T value, Class<T> type) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T get(String key) {
|
||||
@ -41,6 +42,8 @@ public class Data {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the data has a key
|
||||
*
|
||||
* @param key
|
||||
* @return true if the data contains the key, false otherwise
|
||||
*/
|
||||
@ -49,6 +52,8 @@ public class Data {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of data keys
|
||||
*
|
||||
* @return an unmodifiable set containing all keys
|
||||
*/
|
||||
public Set<String> getKeys() {
|
||||
@ -56,12 +61,19 @@ public class Data {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the data is empty or not
|
||||
*
|
||||
* @return true if the data does not contain anything, false otherwise
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return data.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone this data
|
||||
*
|
||||
* @return a cloned data object
|
||||
*/
|
||||
public Data clone() {
|
||||
Data data = new Data();
|
||||
data.data = new ConcurrentHashMap<>(this.data);
|
||||
|
@ -6,11 +6,13 @@ import net.minestom.server.data.type.array.*;
|
||||
import net.minestom.server.inventory.Inventory;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.utils.PrimitiveConversion;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class DataManager {
|
||||
public final class DataManager {
|
||||
|
||||
private Map<Class, DataType> dataTypeMap = new HashMap<>();
|
||||
|
||||
@ -42,6 +44,8 @@ public class DataManager {
|
||||
registerType(String.class, new StringData());
|
||||
registerType(String[].class, new StringArrayData());
|
||||
|
||||
registerType(UUID.class, new UuidType());
|
||||
|
||||
registerType(SerializableData.class, new SerializableDataData());
|
||||
|
||||
registerType(ItemStack.class, new ItemStackData());
|
||||
@ -50,14 +54,27 @@ public class DataManager {
|
||||
registerType(Inventory.class, new InventoryData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new data type
|
||||
*
|
||||
* @param clazz the data class
|
||||
* @param dataType the data type associated
|
||||
* @param <T> the data type
|
||||
*/
|
||||
public <T> void registerType(Class<T> clazz, DataType<T> dataType) {
|
||||
clazz = PrimitiveConversion.getObjectClass(clazz);
|
||||
if (dataTypeMap.containsKey(clazz))
|
||||
throw new UnsupportedOperationException("Type " + clazz.getName() + " has already been registed");
|
||||
Check.stateCondition(dataTypeMap.containsKey(clazz),
|
||||
"Type " + clazz.getName() + " has already been registered");
|
||||
|
||||
this.dataTypeMap.put(clazz, dataType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clazz the data class
|
||||
* @param <T> the data type
|
||||
* @return the {@link DataType} associated to the class
|
||||
* @throws NullPointerException if none is found
|
||||
*/
|
||||
public <T> DataType<T> getDataType(Class<T> clazz) {
|
||||
return dataTypeMap.get(PrimitiveConversion.getObjectClass(clazz));
|
||||
}
|
||||
|
19
src/main/java/net/minestom/server/data/type/UuidType.java
Normal file
19
src/main/java/net/minestom/server/data/type/UuidType.java
Normal file
@ -0,0 +1,19 @@
|
||||
package net.minestom.server.data.type;
|
||||
|
||||
import net.minestom.server.data.DataType;
|
||||
import net.minestom.server.network.packet.PacketReader;
|
||||
import net.minestom.server.network.packet.PacketWriter;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class UuidType extends DataType<UUID> {
|
||||
@Override
|
||||
public void encode(PacketWriter packetWriter, UUID value) {
|
||||
packetWriter.writeUuid(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID decode(PacketReader packetReader) {
|
||||
return packetReader.readUuid();
|
||||
}
|
||||
}
|
@ -14,9 +14,7 @@ import net.minestom.server.event.entity.EntitySpawnEvent;
|
||||
import net.minestom.server.event.entity.EntityTickEvent;
|
||||
import net.minestom.server.event.entity.EntityVelocityEvent;
|
||||
import net.minestom.server.event.handler.EventHandler;
|
||||
import net.minestom.server.instance.Chunk;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.instance.WorldBorder;
|
||||
import net.minestom.server.instance.*;
|
||||
import net.minestom.server.instance.block.CustomBlock;
|
||||
import net.minestom.server.network.packet.PacketWriter;
|
||||
import net.minestom.server.network.packet.server.play.*;
|
||||
@ -50,12 +48,15 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
protected static final byte METADATA_BOOLEAN = 7;
|
||||
protected static final byte METADATA_ROTATION = 8;
|
||||
protected static final byte METADATA_POSITION = 9;
|
||||
protected static final byte METADATA_PARTICLE = 15;
|
||||
protected static final byte METADATA_POSE = 18;
|
||||
|
||||
protected Instance instance;
|
||||
protected Position position;
|
||||
protected float lastX, lastY, lastZ;
|
||||
protected float cacheX, cacheY, cacheZ; // Used to synchronize with #getPosition
|
||||
protected float lastYaw, lastPitch;
|
||||
protected float cacheYaw, cachePitch;
|
||||
private int id;
|
||||
|
||||
private BoundingBox boundingBox;
|
||||
@ -140,8 +141,10 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
|
||||
/**
|
||||
* Called each tick
|
||||
*
|
||||
* @param time the time of update in milliseconds
|
||||
*/
|
||||
public abstract void update();
|
||||
public abstract void update(long time);
|
||||
|
||||
/**
|
||||
* Called when a new instance is set
|
||||
@ -205,6 +208,39 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
teleport(position, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the view of the entity
|
||||
*
|
||||
* @param yaw the new yaw
|
||||
* @param pitch the new pitch
|
||||
*/
|
||||
public void setView(float yaw, float pitch) {
|
||||
refreshView(yaw, pitch);
|
||||
|
||||
EntityRotationPacket entityRotationPacket = new EntityRotationPacket();
|
||||
entityRotationPacket.entityId = getEntityId();
|
||||
entityRotationPacket.yaw = yaw;
|
||||
entityRotationPacket.pitch = pitch;
|
||||
entityRotationPacket.onGround = onGround;
|
||||
|
||||
EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
|
||||
entityHeadLookPacket.entityId = getEntityId();
|
||||
entityHeadLookPacket.yaw = yaw;
|
||||
|
||||
sendPacketToViewersAndSelf(entityHeadLookPacket);
|
||||
sendPacketToViewersAndSelf(entityRotationPacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the view of the entity
|
||||
* Only the yaw and pitch is used
|
||||
*
|
||||
* @param position the new view
|
||||
*/
|
||||
public void setView(Position position) {
|
||||
setView(position.getYaw(), position.getPitch());
|
||||
}
|
||||
|
||||
/**
|
||||
* When set to true, the entity will automatically get new viewers when they come too close
|
||||
* This can be use to complete control over which player can see it, without having to deal with
|
||||
@ -231,6 +267,8 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
public boolean addViewer(Player player) {
|
||||
Check.notNull(player, "Viewer cannot be null");
|
||||
boolean result = this.viewers.add(player);
|
||||
if (!result)
|
||||
return false;
|
||||
player.viewableEntities.add(this);
|
||||
return result;
|
||||
}
|
||||
@ -263,6 +301,11 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the entity, called every tick
|
||||
*
|
||||
* @param time update time in milliseconds
|
||||
*/
|
||||
public void tick(long time) {
|
||||
if (instance == null)
|
||||
return;
|
||||
@ -286,6 +329,21 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
return;
|
||||
}
|
||||
|
||||
// Synchronization with updated fields in #getPosition()
|
||||
{
|
||||
// X/Y/Z axis
|
||||
if (cacheX != position.getX() ||
|
||||
cacheY != position.getY() ||
|
||||
cacheZ != position.getZ()) {
|
||||
teleport(position);
|
||||
}
|
||||
// Yaw/Pitch
|
||||
if (cacheYaw != position.getYaw() ||
|
||||
cachePitch != position.getPitch()) {
|
||||
setView(position);
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldUpdate(time)) {
|
||||
this.lastUpdate = time;
|
||||
|
||||
@ -393,16 +451,16 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
handleVoid();
|
||||
|
||||
// Call the abstract update method
|
||||
update();
|
||||
update(time);
|
||||
|
||||
ticks++;
|
||||
callEvent(EntityTickEvent.class, tickEvent); // reuse tickEvent to avoid recreating it each tick
|
||||
}
|
||||
|
||||
// Scheduled synchronization
|
||||
if (time - lastSynchronizationTime >= synchronizationDelay) {
|
||||
lastSynchronizationTime = time;
|
||||
sendSynchronization();
|
||||
}
|
||||
// Scheduled synchronization
|
||||
if (time - lastSynchronizationTime >= synchronizationDelay) {
|
||||
lastSynchronizationTime = time;
|
||||
sendSynchronization();
|
||||
}
|
||||
|
||||
if (shouldRemove()) {
|
||||
@ -411,9 +469,9 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of ticks this entity has been active for
|
||||
* Get the number of ticks this entity has been active for
|
||||
*
|
||||
* @return
|
||||
* @return the number of ticks this entity has been active for
|
||||
*/
|
||||
public long getAliveTicks() {
|
||||
return ticks;
|
||||
@ -438,6 +496,15 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
this.eventCallbacks.put(eventClass, callbacks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends Event> void removeEventCallback(Class<E> eventClass, EventCallback<E> eventCallback) {
|
||||
Check.notNull(eventClass, "Event class cannot be null");
|
||||
Check.notNull(eventCallback, "Event callback cannot be null");
|
||||
List<EventCallback> callbacks = getEventCallbacks(eventClass);
|
||||
callbacks.remove(eventCallback);
|
||||
this.eventCallbacks.put(eventClass, callbacks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends Event> List<EventCallback> getEventCallbacks(Class<E> eventClass) {
|
||||
Check.notNull(eventClass, "Event class cannot be null");
|
||||
@ -454,30 +521,73 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the entity type id, can convert using {@link EntityType#fromId(int)}
|
||||
*
|
||||
* @return the entity type id
|
||||
*/
|
||||
public int getEntityType() {
|
||||
return entityType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity UUID
|
||||
*
|
||||
* @return the entity UUID
|
||||
*/
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return false just after instantiation, set to true after calling {@link #setInstance(Instance)}
|
||||
*
|
||||
* @return true if the entity has been linked to an instance, false otherwise
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return isActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is used to check collision with coordinates or other blocks/entities
|
||||
*
|
||||
* @return the entity bounding box
|
||||
*/
|
||||
public BoundingBox getBoundingBox() {
|
||||
return boundingBox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the internal entity bounding box
|
||||
* <p>
|
||||
* WARNING: this does not change the entity hit-box which is client-side
|
||||
*
|
||||
* @param x the bounding box X size
|
||||
* @param y the bounding box Y size
|
||||
* @param z the bounding box Z size
|
||||
*/
|
||||
public void setBoundingBox(float x, float y, float z) {
|
||||
this.boundingBox = new BoundingBox(this, x, y, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity current instance
|
||||
*
|
||||
* @return the entity instance
|
||||
*/
|
||||
public Instance getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the entity instance
|
||||
*
|
||||
* @param instance the new instance of the entity
|
||||
* @throws NullPointerException if {@code instance} is null
|
||||
* @throws IllegalStateException if {@code instance} has not been registered in
|
||||
* {@link InstanceManager#createInstanceContainer()} or
|
||||
* {@link InstanceManager#createSharedInstance(InstanceContainer)}
|
||||
*/
|
||||
public void setInstance(Instance instance) {
|
||||
Check.notNull(instance, "instance cannot be null!");
|
||||
Check.stateCondition(!MinecraftServer.getInstanceManager().getInstances().contains(instance),
|
||||
@ -495,16 +605,22 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
callEvent(EntitySpawnEvent.class, entitySpawnEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity current velocity
|
||||
*
|
||||
* @return the entity current velocity
|
||||
*/
|
||||
public Vector getVelocity() {
|
||||
return velocity;
|
||||
}
|
||||
|
||||
public boolean hasVelocity() {
|
||||
return velocity.getX() != 0 ||
|
||||
velocity.getY() != 0 ||
|
||||
velocity.getZ() != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the entity velocity and calls {@link EntityVelocityEvent}.
|
||||
* <p>
|
||||
* The final velocity can be cancelled or modified by the event
|
||||
*
|
||||
* @param velocity the new entity velocity
|
||||
*/
|
||||
public void setVelocity(Vector velocity) {
|
||||
EntityVelocityEvent entityVelocityEvent = new EntityVelocityEvent(this, velocity);
|
||||
callCancellableEvent(EntityVelocityEvent.class, entityVelocityEvent, () -> {
|
||||
@ -513,19 +629,51 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if velocity is not set to 0
|
||||
*/
|
||||
public boolean hasVelocity() {
|
||||
return velocity.getX() != 0 ||
|
||||
velocity.getY() != 0 ||
|
||||
velocity.getZ() != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the gravity of the entity
|
||||
*
|
||||
* @param gravityDragPerTick
|
||||
*/
|
||||
public void setGravity(float gravityDragPerTick) {
|
||||
this.gravityDragPerTick = gravityDragPerTick;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the distance between two entities
|
||||
*
|
||||
* @param entity the entity to get the distance from
|
||||
* @return the distance between this and {@code entity}
|
||||
*/
|
||||
public float getDistance(Entity entity) {
|
||||
Check.notNull(entity, "Entity cannot be null");
|
||||
return getPosition().getDistance(entity.getPosition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity vehicle or null
|
||||
*
|
||||
* @return the entity vehicle, or null if there is not any
|
||||
*/
|
||||
public Entity getVehicle() {
|
||||
return vehicle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new passenger to this entity
|
||||
*
|
||||
* @param entity the new passenger
|
||||
* @throws NullPointerException if {@code entity} is null
|
||||
* @throws IllegalStateException if {@link #getInstance()} returns null
|
||||
*/
|
||||
public void addPassenger(Entity entity) {
|
||||
Check.notNull(entity, "Passenger cannot be null");
|
||||
Check.stateCondition(instance == null, "You need to set an instance using Entity#setInstance");
|
||||
@ -540,6 +688,13 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
sendPacketToViewersAndSelf(getPassengersPacket());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a passenger to this entity
|
||||
*
|
||||
* @param entity the passenger to remove
|
||||
* @throws NullPointerException if {@code entity} is null
|
||||
* @throws IllegalStateException if {@link #getInstance()} returns null
|
||||
*/
|
||||
public void removePassenger(Entity entity) {
|
||||
Check.notNull(entity, "Passenger cannot be null");
|
||||
Check.stateCondition(instance == null, "You need to set an instance using Entity#setInstance");
|
||||
@ -550,11 +705,18 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
sendPacketToViewersAndSelf(getPassengersPacket());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the entity has any passenger
|
||||
*
|
||||
* @return true if the entity has any passenger, false otherwise
|
||||
*/
|
||||
public boolean hasPassenger() {
|
||||
return !passengers.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity passengers
|
||||
*
|
||||
* @return an unmodifiable list containing all the entity passengers
|
||||
*/
|
||||
public Set<Entity> getPassengers() {
|
||||
@ -588,6 +750,8 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the entity is on fire
|
||||
*
|
||||
* @return true if the entity is in fire, false otherwise
|
||||
*/
|
||||
public boolean isOnFire() {
|
||||
@ -607,40 +771,79 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
sendMetadataIndex(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the entity is invisible or not
|
||||
*
|
||||
* @return true if the entity is invisible, false otherwise
|
||||
*/
|
||||
public boolean isInvisible() {
|
||||
return invisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the internal invisible value and send a {@link EntityMetaDataPacket}
|
||||
* to make visible or invisible the entity to its viewers
|
||||
*
|
||||
* @param invisible true to set the entity invisible, false otherwise
|
||||
*/
|
||||
public void setInvisible(boolean invisible) {
|
||||
this.invisible = invisible;
|
||||
sendMetadataIndex(0);
|
||||
}
|
||||
|
||||
public void setGlowing(boolean glowing) {
|
||||
this.glowing = glowing;
|
||||
sendMetadataIndex(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the entity is glowing or not
|
||||
*
|
||||
* @return true if the entity is glowing, false otherwise
|
||||
*/
|
||||
public boolean isGlowing() {
|
||||
return glowing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or remove the entity glowing effect
|
||||
*
|
||||
* @param glowing true to make the entity glows, false otherwise
|
||||
*/
|
||||
public void setGlowing(boolean glowing) {
|
||||
this.glowing = glowing;
|
||||
sendMetadataIndex(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity custom name
|
||||
*
|
||||
* @return the custom name of the entity, null if there is not
|
||||
*/
|
||||
public String getCustomName() {
|
||||
return customName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the entity custom name
|
||||
*
|
||||
* @param customName the custom name of the entity, null to remove it
|
||||
*/
|
||||
public void setCustomName(String customName) {
|
||||
this.customName = customName;
|
||||
sendMetadataIndex(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the custom name visible metadata field
|
||||
*
|
||||
* @return true if the custom name is visible, false otherwise
|
||||
*/
|
||||
public boolean isCustomNameVisible() {
|
||||
return customNameVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the internal custom name visible field and send a {@link EntityMetaDataPacket}
|
||||
* to update the entity state to its viewers
|
||||
*
|
||||
* @param customNameVisible true to make the custom name visible, false otherwise
|
||||
*/
|
||||
public void setCustomNameVisible(boolean customNameVisible) {
|
||||
this.customNameVisible = customNameVisible;
|
||||
sendMetadataIndex(3);
|
||||
@ -656,6 +859,8 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the noGravity metadata field and change the gravity behaviour accordingly
|
||||
*
|
||||
* @param noGravity should the entity ignore gravity
|
||||
*/
|
||||
public void setNoGravity(boolean noGravity) {
|
||||
@ -664,6 +869,8 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the noGravity metadata field
|
||||
*
|
||||
* @return true if the entity ignore gravity, false otherwise
|
||||
*/
|
||||
public boolean hasNoGravity() {
|
||||
@ -689,6 +896,9 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
position.setX(x);
|
||||
position.setY(y);
|
||||
position.setZ(z);
|
||||
this.cacheX = x;
|
||||
this.cacheY = y;
|
||||
this.cacheZ = z;
|
||||
|
||||
if (hasPassenger()) {
|
||||
for (Entity passenger : getPassengers()) {
|
||||
@ -710,6 +920,10 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param position the new position
|
||||
* @see #refreshPosition(float, float, float)
|
||||
*/
|
||||
public void refreshPosition(Position position) {
|
||||
refreshPosition(position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
@ -765,11 +979,21 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the entity view internally
|
||||
* <p>
|
||||
* Warning: you probably want to use {@link #setView(float, float)}
|
||||
*
|
||||
* @param yaw the yaw
|
||||
* @param pitch the pitch
|
||||
*/
|
||||
public void refreshView(float yaw, float pitch) {
|
||||
this.lastYaw = position.getYaw();
|
||||
this.lastPitch = position.getPitch();
|
||||
position.setYaw(yaw);
|
||||
position.setPitch(pitch);
|
||||
this.cacheYaw = yaw;
|
||||
this.cachePitch = pitch;
|
||||
}
|
||||
|
||||
public void refreshSneaking(boolean sneaking) {
|
||||
@ -785,21 +1009,35 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity position
|
||||
*
|
||||
* @return the current position of the entity
|
||||
*/
|
||||
public Position getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity eye height
|
||||
*
|
||||
* @return the entity eye height
|
||||
*/
|
||||
public float getEyeHeight() {
|
||||
return eyeHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the entity eye height
|
||||
*
|
||||
* @param eyeHeight the entity eye eight
|
||||
*/
|
||||
public void setEyeHeight(float eyeHeight) {
|
||||
this.eyeHeight = eyeHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if this entity is in the same chunk as the specified position
|
||||
*
|
||||
* @param position the checked position chunk
|
||||
* @return true if the entity is in the same chunk as {@code position}
|
||||
*/
|
||||
@ -815,6 +1053,12 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
return chunkX1 == chunkX2 && chunkZ1 == chunkZ2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the entity is in the same chunk as another
|
||||
*
|
||||
* @param entity the entity to check
|
||||
* @return true if both entities are in the same chunk, false otherwise
|
||||
*/
|
||||
public boolean sameChunk(Entity entity) {
|
||||
return sameChunk(entity.getPosition());
|
||||
}
|
||||
@ -847,6 +1091,8 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the entity removal is scheduled
|
||||
*
|
||||
* @return true if {@link #scheduleRemove(long, TimeUnit)} has been called, false otherwise
|
||||
*/
|
||||
public boolean isRemoveScheduled() {
|
||||
@ -1015,7 +1261,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask for a synchronization (position) to happen during next entity update
|
||||
* Ask for a synchronization (position) to happen during next entity tick
|
||||
*/
|
||||
public void askSynchronization() {
|
||||
this.lastSynchronizationTime = 0;
|
||||
@ -1025,7 +1271,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
return (float) (time - lastUpdate) >= MinecraftServer.TICK_MS * 0.9f; // Margin of error
|
||||
}
|
||||
|
||||
public enum Pose {
|
||||
private enum Pose {
|
||||
STANDING,
|
||||
FALL_FLYING,
|
||||
SLEEPING,
|
||||
|
@ -1,8 +1,9 @@
|
||||
package net.minestom.server.entity;
|
||||
|
||||
import net.minestom.server.attribute.Attribute;
|
||||
import net.minestom.server.collision.CollisionUtils;
|
||||
import net.minestom.server.entity.pathfinding.EntityPathFinder;
|
||||
import net.minestom.server.entity.property.Attribute;
|
||||
import net.minestom.server.event.entity.EntityAttackEvent;
|
||||
import net.minestom.server.event.item.ArmorEquipEvent;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.network.packet.server.play.*;
|
||||
@ -48,24 +49,11 @@ public abstract class EntityCreature extends LivingEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
super.update();
|
||||
public void update(long time) {
|
||||
super.update(time);
|
||||
|
||||
// Path finding
|
||||
if (blockPositions != null) {
|
||||
if (targetPosition != null) {
|
||||
float distance = getPosition().getDistance(targetPosition);
|
||||
//System.out.println("test: "+distance);
|
||||
if (distance < 0.7f) {
|
||||
setNextPathPosition();
|
||||
//System.out.println("END TARGET");
|
||||
} else {
|
||||
moveTowards(targetPosition, getAttributeValue(Attribute.MOVEMENT_SPEED));
|
||||
//System.out.println("MOVE TOWARD " + targetPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pathProgress();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,9 +82,9 @@ public abstract class EntityCreature extends LivingEntity {
|
||||
float yaw = (float) (radians * (180.0 / Math.PI)) - 90;
|
||||
float pitch = position.getPitch(); // TODO
|
||||
|
||||
short deltaX = (short) ((newX * 32 - position.getX() * 32) * 128);
|
||||
short deltaY = (short) ((newY * 32 - position.getY() * 32) * 128);
|
||||
short deltaZ = (short) ((newZ * 32 - position.getZ() * 32) * 128);
|
||||
final short deltaX = (short) ((newX * 32 - position.getX() * 32) * 128);
|
||||
final short deltaY = (short) ((newY * 32 - position.getY() * 32) * 128);
|
||||
final short deltaZ = (short) ((newZ * 32 - position.getZ() * 32) * 128);
|
||||
|
||||
if (updateView) {
|
||||
EntityPositionAndRotationPacket entityPositionAndRotationPacket = new EntityPositionAndRotationPacket();
|
||||
@ -119,11 +107,7 @@ public abstract class EntityCreature extends LivingEntity {
|
||||
}
|
||||
|
||||
if (lastYaw != yaw) {
|
||||
EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket();
|
||||
entityHeadLookPacket.entityId = getEntityId();
|
||||
entityHeadLookPacket.yaw = yaw;
|
||||
sendPacketToViewers(entityHeadLookPacket);
|
||||
refreshView(yaw, pitch);
|
||||
setView(yaw, pitch);
|
||||
}
|
||||
|
||||
refreshPosition(newX, newY, newZ);
|
||||
@ -145,6 +129,9 @@ public abstract class EntityCreature extends LivingEntity {
|
||||
@Override
|
||||
public boolean addViewer(Player player) {
|
||||
boolean result = super.addViewer(player);
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
PlayerConnection playerConnection = player.getPlayerConnection();
|
||||
|
||||
EntityPacket entityPacket = new EntityPacket();
|
||||
@ -163,7 +150,7 @@ public abstract class EntityCreature extends LivingEntity {
|
||||
playerConnection.sendPacket(getMetadataPacket());
|
||||
|
||||
// Equipments synchronization
|
||||
syncEquipments();
|
||||
syncEquipments(playerConnection);
|
||||
|
||||
if (hasPassenger()) {
|
||||
playerConnection.sendPacket(getPassengersPacket());
|
||||
@ -238,9 +225,33 @@ public abstract class EntityCreature extends LivingEntity {
|
||||
syncEquipment(EntityEquipmentPacket.Slot.BOOTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a {@link EntityAttackEvent} with this entity as the source and {@code target} as the target.
|
||||
*
|
||||
* @param target the entity target
|
||||
* @param swingHand true to swing the entity main hand, false otherwise
|
||||
*/
|
||||
public void attack(Entity target, boolean swingHand) {
|
||||
if (swingHand)
|
||||
swingMainHand();
|
||||
EntityAttackEvent attackEvent = new EntityAttackEvent(this, target);
|
||||
callEvent(EntityAttackEvent.class, attackEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a {@link EntityAttackEvent} with this entity as the source and {@code target} as the target.
|
||||
* <p>
|
||||
* This does not trigger the hand animation
|
||||
*
|
||||
* @param target the entity target
|
||||
*/
|
||||
public void attack(Entity target) {
|
||||
attack(target, false);
|
||||
}
|
||||
|
||||
public void jump(float height) {
|
||||
// FIXME magic value
|
||||
Vector velocity = new Vector(0, height * 10, 0);
|
||||
Vector velocity = new Vector(0, height * 5, 0);
|
||||
setVelocity(velocity);
|
||||
}
|
||||
|
||||
@ -271,7 +282,7 @@ public abstract class EntityCreature extends LivingEntity {
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to move the entity toward {@code direction} in the axis X and Z
|
||||
* Used to move the entity toward {@code direction} in the X and Z axis
|
||||
* Gravity is still applied but the entity will not attempt to jump
|
||||
*
|
||||
* @param direction the targeted position
|
||||
@ -294,11 +305,27 @@ public abstract class EntityCreature extends LivingEntity {
|
||||
}
|
||||
|
||||
this.targetPosition = blockPosition.toPosition();//.add(0.5f, 0, 0.5f);
|
||||
// FIXME: jump support
|
||||
if (blockPosition.getY() > getPosition().getY())
|
||||
jump(1);
|
||||
}
|
||||
|
||||
private void pathProgress() {
|
||||
if (blockPositions != null) {
|
||||
if (targetPosition != null) {
|
||||
float distance = getPosition().getDistance(targetPosition);
|
||||
//System.out.println("test: "+distance);
|
||||
if (distance < 1f) {
|
||||
setNextPathPosition();
|
||||
pathProgress();
|
||||
//System.out.println("END TARGET");
|
||||
} else {
|
||||
moveTowards(targetPosition, getAttributeValue(Attribute.MOVEMENT_SPEED));
|
||||
//System.out.println("MOVE TOWARD " + targetPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ItemStack getEquipmentItem(ItemStack itemStack, ArmorEquipEvent.ArmorSlot armorSlot) {
|
||||
itemStack = ItemStackUtils.notNull(itemStack);
|
||||
|
||||
|
@ -12,7 +12,7 @@ import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
public class EntityManager {
|
||||
public final class EntityManager {
|
||||
|
||||
private static InstanceManager instanceManager = MinecraftServer.getInstanceManager();
|
||||
|
||||
@ -24,6 +24,9 @@ public class EntityManager {
|
||||
|
||||
private ConcurrentLinkedQueue<Player> waitingPlayers = new ConcurrentLinkedQueue<>();
|
||||
|
||||
/**
|
||||
* Execute a whole entity server tick
|
||||
*/
|
||||
public void update() {
|
||||
final long time = System.currentTimeMillis();
|
||||
|
||||
@ -164,7 +167,7 @@ public class EntityManager {
|
||||
playersPool.execute(() -> {
|
||||
playerCache.init();
|
||||
|
||||
PlayerLoginEvent loginEvent = new PlayerLoginEvent();
|
||||
PlayerLoginEvent loginEvent = new PlayerLoginEvent(playerCache);
|
||||
playerCache.callEvent(PlayerLoginEvent.class, loginEvent);
|
||||
Instance spawningInstance = loginEvent.getSpawningInstance();
|
||||
|
||||
@ -179,10 +182,16 @@ public class EntityManager {
|
||||
this.waitingPlayers.add(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current entity update type
|
||||
*/
|
||||
public UpdateType getUpdateType() {
|
||||
return updateType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param updateType the new entity update type
|
||||
*/
|
||||
public void setUpdateType(UpdateType updateType) {
|
||||
this.updateType = updateType;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ public class ExperienceOrb extends Entity {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
public void update(long time) {
|
||||
// TODO slide toward nearest player
|
||||
}
|
||||
|
||||
|
@ -6,13 +6,28 @@ import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.item.StackingRule;
|
||||
import net.minestom.server.network.packet.PacketWriter;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.time.CooldownUtils;
|
||||
import net.minestom.server.utils.time.TimeUnit;
|
||||
import net.minestom.server.utils.time.UpdateOption;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Represent an item on the ground
|
||||
*/
|
||||
public class ItemEntity extends ObjectEntity {
|
||||
|
||||
/**
|
||||
* Used to slow down the merge check delay
|
||||
*/
|
||||
private static UpdateOption mergeUpdateOption = new UpdateOption(10, TimeUnit.TICK);
|
||||
|
||||
/**
|
||||
* The last time that this item has checked his neighbors for merge
|
||||
*/
|
||||
private long lastMergeCheck;
|
||||
|
||||
private ItemStack itemStack;
|
||||
|
||||
private boolean pickable = true;
|
||||
@ -26,12 +41,33 @@ public class ItemEntity extends ObjectEntity {
|
||||
super(EntityType.ITEM, spawnPosition);
|
||||
this.itemStack = itemStack;
|
||||
setBoundingBox(0.25f, 0.25f, 0.25f);
|
||||
setGravity(0.025f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the update option for the merging feature
|
||||
*
|
||||
* @return the merge update option
|
||||
*/
|
||||
public static UpdateOption getMergeUpdateOption() {
|
||||
return mergeUpdateOption;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the merge update option.
|
||||
* Can be set to null to entirely remove the delay
|
||||
*
|
||||
* @param mergeUpdateOption the new merge update option
|
||||
*/
|
||||
public static void setMergeUpdateOption(UpdateOption mergeUpdateOption) {
|
||||
ItemEntity.mergeUpdateOption = mergeUpdateOption;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
if (isMergeable() && isPickable()) {
|
||||
public void update(long time) {
|
||||
if (isMergeable() && isPickable() &&
|
||||
(mergeUpdateOption == null || !CooldownUtils.hasCooldown(time, lastMergeCheck, mergeUpdateOption))) {
|
||||
this.lastMergeCheck = time;
|
||||
|
||||
Chunk chunk = instance.getChunkAt(getPosition());
|
||||
Set<Entity> entities = instance.getChunkEntities(chunk);
|
||||
for (Entity entity : entities) {
|
||||
@ -49,30 +85,30 @@ public class ItemEntity extends ObjectEntity {
|
||||
if (getDistance(itemEntity) > mergeRange)
|
||||
continue;
|
||||
|
||||
synchronized (this) {
|
||||
synchronized (itemEntity) {
|
||||
ItemStack itemStackEntity = itemEntity.getItemStack();
|
||||
// Use the class as a monitor to prevent deadlock
|
||||
// Shouldn't happen too often to be an issue
|
||||
synchronized (ItemEntity.class) {
|
||||
final ItemStack itemStackEntity = itemEntity.getItemStack();
|
||||
|
||||
StackingRule stackingRule = itemStack.getStackingRule();
|
||||
boolean canStack = stackingRule.canBeStacked(itemStack, itemStackEntity);
|
||||
final StackingRule stackingRule = itemStack.getStackingRule();
|
||||
final boolean canStack = stackingRule.canBeStacked(itemStack, itemStackEntity);
|
||||
|
||||
if (!canStack)
|
||||
continue;
|
||||
if (!canStack)
|
||||
continue;
|
||||
|
||||
int totalAmount = stackingRule.getAmount(itemStack) + stackingRule.getAmount(itemStackEntity);
|
||||
boolean canApply = stackingRule.canApply(itemStack, totalAmount);
|
||||
final int totalAmount = stackingRule.getAmount(itemStack) + stackingRule.getAmount(itemStackEntity);
|
||||
final boolean canApply = stackingRule.canApply(itemStack, totalAmount);
|
||||
|
||||
if (!canApply)
|
||||
continue;
|
||||
if (!canApply)
|
||||
continue;
|
||||
|
||||
EntityItemMergeEvent entityItemMergeEvent = new EntityItemMergeEvent(this, itemEntity);
|
||||
callCancellableEvent(EntityItemMergeEvent.class, entityItemMergeEvent, () -> {
|
||||
ItemStack result = stackingRule.apply(itemStack.clone(), totalAmount);
|
||||
setItemStack(result);
|
||||
itemEntity.remove();
|
||||
});
|
||||
final ItemStack result = stackingRule.apply(itemStack.clone(), totalAmount);
|
||||
|
||||
}
|
||||
EntityItemMergeEvent entityItemMergeEvent = new EntityItemMergeEvent(this, itemEntity, result);
|
||||
callCancellableEvent(EntityItemMergeEvent.class, entityItemMergeEvent, () -> {
|
||||
setItemStack(entityItemMergeEvent.getResult());
|
||||
itemEntity.remove();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package net.minestom.server.entity;
|
||||
|
||||
import net.minestom.server.attribute.Attribute;
|
||||
import net.minestom.server.collision.BoundingBox;
|
||||
import net.minestom.server.entity.damage.DamageType;
|
||||
import net.minestom.server.entity.property.Attribute;
|
||||
import net.minestom.server.event.entity.EntityDamageEvent;
|
||||
import net.minestom.server.event.entity.EntityDeathEvent;
|
||||
import net.minestom.server.event.entity.EntityFireEvent;
|
||||
@ -12,6 +12,7 @@ import net.minestom.server.inventory.EquipmentHandler;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.network.packet.PacketWriter;
|
||||
import net.minestom.server.network.packet.server.play.*;
|
||||
import net.minestom.server.network.player.PlayerConnection;
|
||||
import net.minestom.server.sound.Sound;
|
||||
import net.minestom.server.sound.SoundCategory;
|
||||
import net.minestom.server.utils.Position;
|
||||
@ -64,14 +65,14 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
public void update(long time) {
|
||||
if (isOnFire()) {
|
||||
if (System.currentTimeMillis() > fireExtinguishTime) {
|
||||
if (time > fireExtinguishTime) {
|
||||
setOnFire(false);
|
||||
} else {
|
||||
if (System.currentTimeMillis() - lastFireDamageTime > fireDamagePeriod) {
|
||||
if (time - lastFireDamageTime > fireDamagePeriod) {
|
||||
damage(DamageType.ON_FIRE, 1.0f);
|
||||
lastFireDamageTime = System.currentTimeMillis();
|
||||
lastFireDamageTime = time;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -91,6 +92,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
ItemEntity itemEntity = (ItemEntity) entity;
|
||||
if (!itemEntity.isPickable())
|
||||
continue;
|
||||
|
||||
BoundingBox itemBoundingBox = itemEntity.getBoundingBox();
|
||||
if (livingBoundingBox.intersect(itemBoundingBox)) {
|
||||
synchronized (itemEntity) {
|
||||
@ -149,10 +151,20 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the amount of arrows in the entity
|
||||
*
|
||||
* @return the arrow count
|
||||
*/
|
||||
public int getArrowCount() {
|
||||
return arrowCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the amount of arrow stuck in the entity
|
||||
*
|
||||
* @param arrowCount the arrow count
|
||||
*/
|
||||
public void setArrowCount(int arrowCount) {
|
||||
this.arrowCount = arrowCount;
|
||||
sendMetadataIndex(11);
|
||||
@ -214,6 +226,8 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
* @return true if damage has been applied, false if it didn't
|
||||
*/
|
||||
public boolean damage(DamageType type, float value) {
|
||||
if (isDead())
|
||||
return false;
|
||||
if (isImmune(type)) {
|
||||
return false;
|
||||
}
|
||||
@ -273,10 +287,20 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity health
|
||||
*
|
||||
* @return the entity health
|
||||
*/
|
||||
public float getHealth() {
|
||||
return health;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the entity health, kill it if {@code health} is <= 0 and is not dead yet
|
||||
*
|
||||
* @param health the new entity health
|
||||
*/
|
||||
public void setHealth(float health) {
|
||||
health = Math.min(health, getMaxHealth());
|
||||
|
||||
@ -287,6 +311,11 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
sendMetadataIndex(8); // Health metadata index
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity max health from {@link #getAttributeValue(Attribute)} {@link Attribute#MAX_HEALTH}
|
||||
*
|
||||
* @return the entity max health
|
||||
*/
|
||||
public float getMaxHealth() {
|
||||
return getAttributeValue(Attribute.MAX_HEALTH);
|
||||
}
|
||||
@ -320,6 +349,15 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
}
|
||||
|
||||
// Equipments
|
||||
public void syncEquipments(PlayerConnection connection) {
|
||||
for (EntityEquipmentPacket.Slot slot : EntityEquipmentPacket.Slot.values()) {
|
||||
EntityEquipmentPacket entityEquipmentPacket = getEquipmentPacket(slot);
|
||||
if (entityEquipmentPacket == null)
|
||||
return;
|
||||
connection.sendPacket(entityEquipmentPacket);
|
||||
}
|
||||
}
|
||||
|
||||
public void syncEquipments() {
|
||||
for (EntityEquipmentPacket.Slot slot : EntityEquipmentPacket.Slot.values()) {
|
||||
syncEquipment(slot);
|
||||
@ -345,6 +383,8 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the entity is dead or not
|
||||
*
|
||||
* @return true if the entity is dead, false otherwise
|
||||
*/
|
||||
public boolean isDead() {
|
||||
@ -352,6 +392,8 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the entity is able to pickup items
|
||||
*
|
||||
* @return true if the entity is able to pickup items
|
||||
*/
|
||||
public boolean canPickupItem() {
|
||||
@ -373,6 +415,28 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
this.expandedBoundingBox = getBoundingBox().expand(1, 0.5f, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link EntityAnimationPacket} to swing the main hand
|
||||
* (can be used for attack animation)
|
||||
*/
|
||||
public void swingMainHand() {
|
||||
EntityAnimationPacket animationPacket = new EntityAnimationPacket();
|
||||
animationPacket.entityId = getEntityId();
|
||||
animationPacket.animation = EntityAnimationPacket.Animation.SWING_MAIN_ARM;
|
||||
sendPacketToViewers(animationPacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link EntityAnimationPacket} to swing the off hand
|
||||
* (can be used for attack animation)
|
||||
*/
|
||||
public void swingOffHand() {
|
||||
EntityAnimationPacket animationPacket = new EntityAnimationPacket();
|
||||
animationPacket.entityId = getEntityId();
|
||||
animationPacket.animation = EntityAnimationPacket.Animation.SWING_OFF_HAND;
|
||||
sendPacketToViewers(animationPacket);
|
||||
}
|
||||
|
||||
public void refreshActiveHand(boolean isHandActive, boolean offHand, boolean riptideSpinAttack) {
|
||||
this.isHandActive = isHandActive;
|
||||
this.offHand = offHand;
|
||||
@ -392,14 +456,14 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
int length = Attribute.values().length;
|
||||
EntityPropertiesPacket.Property[] properties = new EntityPropertiesPacket.Property[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
Attribute attribute = Attribute.values()[i];
|
||||
EntityPropertiesPacket.Property property = new EntityPropertiesPacket.Property();
|
||||
float maxValue = attribute.getMaxVanillaValue();
|
||||
float value = getAttributeValue(attribute);
|
||||
value = value > maxValue ? maxValue : value; // Bypass vanilla limit client-side if needed (by sending the max value allowed)
|
||||
|
||||
property.key = attribute.getKey();
|
||||
Attribute attribute = Attribute.values()[i];
|
||||
float value = getAttributeValue(attribute);
|
||||
|
||||
property.attribute = attribute;
|
||||
property.value = value;
|
||||
|
||||
properties[i] = property;
|
||||
}
|
||||
|
||||
@ -421,11 +485,23 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time in ms between two fire damage applications
|
||||
*
|
||||
* @return the time in ms
|
||||
*/
|
||||
public long getFireDamagePeriod() {
|
||||
return fireDamagePeriod;
|
||||
}
|
||||
|
||||
public void setFireDamagePeriod(long fireDamagePeriod) {
|
||||
/**
|
||||
* Change the delay between two fire damage applications
|
||||
*
|
||||
* @param fireDamagePeriod the delay
|
||||
* @param timeUnit the time unit
|
||||
*/
|
||||
public void setFireDamagePeriod(long fireDamagePeriod, TimeUnit timeUnit) {
|
||||
fireDamagePeriod = timeUnit.toMilliseconds(fireDamagePeriod);
|
||||
this.fireDamagePeriod = fireDamagePeriod;
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public abstract class ObjectEntity extends Entity {
|
||||
public abstract int getObjectData();
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
public void update(long time) {
|
||||
|
||||
}
|
||||
|
||||
@ -30,6 +30,10 @@ public abstract class ObjectEntity extends Entity {
|
||||
|
||||
@Override
|
||||
public boolean addViewer(Player player) {
|
||||
boolean result = super.addViewer(player);
|
||||
if (!result)
|
||||
return false;
|
||||
|
||||
PlayerConnection playerConnection = player.getPlayerConnection();
|
||||
|
||||
SpawnEntityPacket spawnEntityPacket = new SpawnEntityPacket();
|
||||
@ -46,7 +50,7 @@ public abstract class ObjectEntity extends Entity {
|
||||
playerConnection.sendPacket(getPassengersPacket());
|
||||
}
|
||||
|
||||
return super.addViewer(player); // Add player to viewers list
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
94
src/main/java/net/minestom/server/entity/PlayerSkin.java
Normal file
94
src/main/java/net/minestom/server/entity/PlayerSkin.java
Normal file
@ -0,0 +1,94 @@
|
||||
package net.minestom.server.entity;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import net.minestom.server.utils.url.URLUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Contains all the data required to store a skin
|
||||
*/
|
||||
public class PlayerSkin {
|
||||
|
||||
private String textures;
|
||||
private String signature;
|
||||
|
||||
public PlayerSkin(String textures, String signature) {
|
||||
this.textures = textures;
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the skin textures value
|
||||
*
|
||||
* @return the textures value
|
||||
*/
|
||||
public String getTextures() {
|
||||
return textures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the skin signature
|
||||
*
|
||||
* @return the skin signature
|
||||
*/
|
||||
public String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a skin from a Mojang UUID
|
||||
*
|
||||
* @param uuid Mojang UUID
|
||||
* @return a player skin based on the UUID
|
||||
*/
|
||||
public static PlayerSkin fromUuid(String uuid) {
|
||||
final String url = "https://sessionserver.mojang.com/session/minecraft/profile/" + uuid + "?unsigned=false";
|
||||
|
||||
try {
|
||||
final String response = URLUtils.getText(url);
|
||||
JsonObject jsonObject = (new JsonParser()).parse(response).getAsJsonObject();
|
||||
JsonArray propertiesArray = jsonObject.get("properties").getAsJsonArray();
|
||||
|
||||
Iterator<JsonElement> iterator = propertiesArray.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
JsonObject propertyObject = iterator.next().getAsJsonObject();
|
||||
final String name = propertyObject.get("name").getAsString();
|
||||
if (!name.equals("textures"))
|
||||
continue;
|
||||
final String textureValue = propertyObject.get("value").getAsString();
|
||||
final String signatureValue = propertyObject.get("signature").getAsString();
|
||||
return new PlayerSkin(textureValue, signatureValue);
|
||||
}
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a skin from a Minecraft username
|
||||
*
|
||||
* @param username the Minecraft username
|
||||
* @return a skin based on a Minecraft username
|
||||
*/
|
||||
public static PlayerSkin fromUsername(String username) {
|
||||
final String url = "https://api.mojang.com/users/profiles/minecraft/" + username;
|
||||
|
||||
try {
|
||||
final String response = URLUtils.getText(url);
|
||||
JsonObject jsonObject = (new JsonParser()).parse(response).getAsJsonObject();
|
||||
final String uuid = jsonObject.get("id").getAsString();
|
||||
return fromUuid(uuid);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -39,10 +39,14 @@ public class DamageType {
|
||||
return TranslatableComponent.of("death." + identifier, TextComponent.of(killed.getUsername()));
|
||||
}
|
||||
|
||||
public static DamageType fromPlayer(Player player) {
|
||||
public static EntityDamage fromPlayer(Player player) {
|
||||
return new EntityDamage(player);
|
||||
}
|
||||
|
||||
public static EntityDamage fromEntity(Entity entity) {
|
||||
return new EntityDamage(entity);
|
||||
}
|
||||
|
||||
public Component buildDeathScreenMessage(Player killed) {
|
||||
return buildChatMessage(killed);
|
||||
}
|
||||
|
@ -14,6 +14,9 @@ public class EntityDamage extends DamageType {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the source of the damage
|
||||
*/
|
||||
public Entity getSource() {
|
||||
return source;
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ public class FakePlayer extends Player {
|
||||
public FakePlayer(UUID uuid, String username, boolean addInCache) {
|
||||
super(uuid, username, new FakePlayerConnection());
|
||||
|
||||
this.fakePlayerController = new FakePlayerController(this);
|
||||
|
||||
this.registered = addInCache;
|
||||
|
||||
if (registered) {
|
||||
@ -39,13 +41,6 @@ public class FakePlayer extends Player {
|
||||
this(uuid, username, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void playerConnectionInit() {
|
||||
FakePlayerConnection playerConnection = (FakePlayerConnection) getPlayerConnection();
|
||||
playerConnection.setFakePlayer(this);
|
||||
this.fakePlayerController = new FakePlayerController(this);
|
||||
}
|
||||
|
||||
public FakePlayerController getController() {
|
||||
return fakePlayerController;
|
||||
}
|
||||
|
@ -0,0 +1,118 @@
|
||||
package net.minestom.server.entity.type;
|
||||
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.entity.ObjectEntity;
|
||||
import net.minestom.server.network.packet.PacketWriter;
|
||||
import net.minestom.server.particle.Particle;
|
||||
import net.minestom.server.utils.Position;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class EntityAreaEffectCloud extends ObjectEntity {
|
||||
|
||||
public Consumer<PacketWriter> particleDataConsumer;
|
||||
private float radius;
|
||||
private int color;
|
||||
private boolean ignoreRadius;
|
||||
private Particle particle;
|
||||
|
||||
public EntityAreaEffectCloud(Position spawnPosition) {
|
||||
super(EntityType.AREA_EFFECT_CLOUD, spawnPosition);
|
||||
setRadius(0.5f);
|
||||
setColor(0);
|
||||
setIgnoreRadius(false);
|
||||
setParticle(Particle.EFFECT);
|
||||
setParticleDataConsumer(packetWriter -> {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Consumer<PacketWriter> getMetadataConsumer() {
|
||||
return packet -> {
|
||||
super.getMetadataConsumer().accept(packet);
|
||||
fillMetadataIndex(packet, 7);
|
||||
fillMetadataIndex(packet, 8);
|
||||
fillMetadataIndex(packet, 9);
|
||||
fillMetadataIndex(packet, 10);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillMetadataIndex(PacketWriter packet, int index) {
|
||||
super.fillMetadataIndex(packet, index);
|
||||
if (index == 7) {
|
||||
packet.writeByte((byte) 7);
|
||||
packet.writeByte(METADATA_FLOAT);
|
||||
packet.writeFloat(radius);
|
||||
} else if (index == 8) {
|
||||
packet.writeByte((byte) 8);
|
||||
packet.writeByte(METADATA_VARINT);
|
||||
packet.writeVarInt(color);
|
||||
} else if (index == 9) {
|
||||
packet.writeByte((byte) 9);
|
||||
packet.writeByte(METADATA_BOOLEAN);
|
||||
packet.writeBoolean(ignoreRadius);
|
||||
} else if (index == 10) {
|
||||
packet.writeByte((byte) 10);
|
||||
packet.writeByte(METADATA_PARTICLE);
|
||||
packet.writeVarInt(particle.getId());
|
||||
particleDataConsumer.accept(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getObjectData() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public float getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
public void setRadius(float radius) {
|
||||
this.radius = radius;
|
||||
setBoundingBox(2 * radius, 0.5f, 2 * radius);
|
||||
sendMetadataIndex(7);
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(int color) {
|
||||
this.color = color;
|
||||
sendMetadataIndex(8);
|
||||
}
|
||||
|
||||
public boolean isIgnoreRadius() {
|
||||
return ignoreRadius;
|
||||
}
|
||||
|
||||
public void setIgnoreRadius(boolean ignoreRadius) {
|
||||
this.ignoreRadius = ignoreRadius;
|
||||
sendMetadataIndex(9);
|
||||
}
|
||||
|
||||
public Particle getParticle() {
|
||||
return particle;
|
||||
}
|
||||
|
||||
public void setParticle(Particle particle) {
|
||||
this.particle = particle;
|
||||
sendMetadataIndex(10);
|
||||
}
|
||||
|
||||
public Consumer<PacketWriter> getParticleDataConsumer() {
|
||||
return particleDataConsumer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to add data to the particle
|
||||
*
|
||||
* @param particleDataConsumer the particle data consumer
|
||||
* @see @see <a href="https://wiki.vg/Data_types#Particle">Particle data</a>
|
||||
*/
|
||||
public void setParticleDataConsumer(Consumer<PacketWriter> particleDataConsumer) {
|
||||
this.particleDataConsumer = particleDataConsumer;
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ import net.minestom.server.inventory.EquipmentHandler;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.network.packet.PacketWriter;
|
||||
import net.minestom.server.network.packet.server.play.EntityEquipmentPacket;
|
||||
import net.minestom.server.network.player.PlayerConnection;
|
||||
import net.minestom.server.utils.Position;
|
||||
import net.minestom.server.utils.Vector;
|
||||
import net.minestom.server.utils.item.ItemStackUtils;
|
||||
@ -63,7 +64,7 @@ public class EntityArmorStand extends ObjectEntity implements EquipmentHandler {
|
||||
@Override
|
||||
public boolean addViewer(Player player) {
|
||||
boolean result = super.addViewer(player);
|
||||
syncEquipments();
|
||||
syncEquipments(player.getPlayerConnection());
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -316,6 +317,15 @@ public class EntityArmorStand extends ObjectEntity implements EquipmentHandler {
|
||||
}
|
||||
|
||||
// Equipments
|
||||
public void syncEquipments(PlayerConnection connection) {
|
||||
for (EntityEquipmentPacket.Slot slot : EntityEquipmentPacket.Slot.values()) {
|
||||
EntityEquipmentPacket entityEquipmentPacket = getEquipmentPacket(slot);
|
||||
if (entityEquipmentPacket == null)
|
||||
return;
|
||||
connection.sendPacket(entityEquipmentPacket);
|
||||
}
|
||||
}
|
||||
|
||||
public void syncEquipments() {
|
||||
for (EntityEquipmentPacket.Slot slot : EntityEquipmentPacket.Slot.values()) {
|
||||
syncEquipment(slot);
|
||||
|
@ -13,6 +13,7 @@ public class EntityBat extends EntityCreature {
|
||||
|
||||
public EntityBat(Position spawnPosition) {
|
||||
super(EntityType.BAT, spawnPosition);
|
||||
setBoundingBox(0.5f, 0.9f, 0.5f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -11,6 +11,7 @@ public class EntityBlaze extends EntityCreature {
|
||||
|
||||
public EntityBlaze(Position spawnPosition) {
|
||||
super(EntityType.BLAZE, spawnPosition);
|
||||
setBoundingBox(0.6f, 1.8f, 0.6f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -22,16 +22,6 @@ public class EntityBoat extends ObjectEntity {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawn() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Consumer<PacketWriter> getMetadataConsumer() {
|
||||
return packet -> {
|
||||
|
@ -0,0 +1,12 @@
|
||||
package net.minestom.server.entity.type;
|
||||
|
||||
import net.minestom.server.entity.EntityCreature;
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.utils.Position;
|
||||
|
||||
public class EntityCaveSpider extends EntityCreature {
|
||||
public EntityCaveSpider(Position spawnPosition) {
|
||||
super(EntityType.CAVE_SPIDER, spawnPosition);
|
||||
setBoundingBox(0.7f, 0.5f, 0.7f);
|
||||
}
|
||||
}
|
@ -7,5 +7,6 @@ import net.minestom.server.utils.Position;
|
||||
public class EntityChicken extends EntityCreature {
|
||||
public EntityChicken(Position spawnPosition) {
|
||||
super(EntityType.CHICKEN, spawnPosition);
|
||||
setBoundingBox(0.4f, 0.7f, 0.4f);
|
||||
}
|
||||
}
|
||||
|
@ -7,5 +7,6 @@ import net.minestom.server.utils.Position;
|
||||
public class EntityCow extends EntityCreature {
|
||||
public EntityCow(Position spawnPosition) {
|
||||
super(EntityType.COW, spawnPosition);
|
||||
setBoundingBox(0.9f, 1.4f, 0.9f);
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ public class EntityCreeper extends EntityCreature {
|
||||
|
||||
public EntityCreeper(Position spawnPosition) {
|
||||
super(EntityType.CREEPER, spawnPosition);
|
||||
setBoundingBox(0.6f, 1.7f, 0.6f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -7,5 +7,6 @@ import net.minestom.server.utils.Position;
|
||||
public class EntityEndermite extends EntityCreature {
|
||||
public EntityEndermite(Position spawnPosition) {
|
||||
super(EntityType.ENDERMITE, spawnPosition);
|
||||
setBoundingBox(0.4f, 0.3f, 0.4f);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ public class EntityGhast extends EntityCreature {
|
||||
|
||||
public EntityGhast(Position spawnPosition) {
|
||||
super(EntityType.GHAST, spawnPosition);
|
||||
setBoundingBox(4, 4, 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -7,5 +7,6 @@ import net.minestom.server.utils.Position;
|
||||
public class EntityGiant extends EntityCreature {
|
||||
public EntityGiant(Position spawnPosition) {
|
||||
super(EntityType.GIANT, spawnPosition);
|
||||
setBoundingBox(3.6f, 10.8f, 3.6f);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
package net.minestom.server.entity.type;
|
||||
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.EntityCreature;
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.network.packet.PacketWriter;
|
||||
import net.minestom.server.utils.Position;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class EntityGuardian extends EntityCreature {
|
||||
|
||||
private boolean retractingSpikes;
|
||||
private Entity target;
|
||||
|
||||
public EntityGuardian(Position spawnPosition) {
|
||||
super(EntityType.GUARDIAN, spawnPosition);
|
||||
setBoundingBox(0.85f, 0.85f, 0.85f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Consumer<PacketWriter> getMetadataConsumer() {
|
||||
return packet -> {
|
||||
super.getMetadataConsumer().accept(packet);
|
||||
fillMetadataIndex(packet, 15);
|
||||
fillMetadataIndex(packet, 16);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillMetadataIndex(PacketWriter packet, int index) {
|
||||
super.fillMetadataIndex(packet, index);
|
||||
if (index == 15) {
|
||||
packet.writeByte((byte) 15);
|
||||
packet.writeByte(METADATA_BOOLEAN);
|
||||
packet.writeBoolean(retractingSpikes);
|
||||
} else if (index == 16) {
|
||||
packet.writeByte((byte) 16);
|
||||
packet.writeByte(METADATA_VARINT);
|
||||
packet.writeVarInt(target == null ? 0 : target.getEntityId());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRetractingSpikes() {
|
||||
return retractingSpikes;
|
||||
}
|
||||
|
||||
public void setRetractingSpikes(boolean retractingSpikes) {
|
||||
this.retractingSpikes = retractingSpikes;
|
||||
}
|
||||
|
||||
public Entity getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
||||
public void setTarget(Entity target) {
|
||||
this.target = target;
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ public class EntityIronGolem extends EntityCreature {
|
||||
|
||||
public EntityIronGolem(Position spawnPosition) {
|
||||
super(EntityType.IRON_GOLEM, spawnPosition);
|
||||
setBoundingBox(1.4f, 2.7f, 1.4f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -13,6 +13,7 @@ public class EntityMooshroom extends EntityCreature {
|
||||
|
||||
public EntityMooshroom(Position spawnPosition) {
|
||||
super(EntityType.MOOSHROOM, spawnPosition);
|
||||
setBoundingBox(0.9f, 1.4f, 0.9f);
|
||||
setMooshroomType(MooshroomType.RED);
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ public class EntityPhantom extends EntityCreature {
|
||||
|
||||
public EntityPhantom(Position spawnPosition) {
|
||||
super(EntityType.PHANTOM, spawnPosition);
|
||||
setBoundingBox(0.9f, 0.5f, 0.9f); // TODO change based on size
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -13,6 +13,7 @@ public class EntityPig extends EntityCreature {
|
||||
|
||||
public EntityPig(Position spawnPosition) {
|
||||
super(EntityType.PIG, spawnPosition);
|
||||
setBoundingBox(0.9f, 0.9f, 0.9f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,61 @@
|
||||
package net.minestom.server.entity.type;
|
||||
|
||||
import net.minestom.server.entity.EntityCreature;
|
||||
import net.minestom.server.entity.EntityType;
|
||||
import net.minestom.server.network.packet.PacketWriter;
|
||||
import net.minestom.server.utils.Position;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class EntityPigZombie extends EntityCreature {
|
||||
|
||||
private boolean baby;
|
||||
private boolean becomingDrowned;
|
||||
|
||||
public EntityPigZombie(Position spawnPosition) {
|
||||
super(EntityType.ZOMBIE_PIGMAN, spawnPosition);
|
||||
setBoundingBox(0.6f, 1.95f, 0.6f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Consumer<PacketWriter> getMetadataConsumer() {
|
||||
return packet -> {
|
||||
super.getMetadataConsumer().accept(packet);
|
||||
fillMetadataIndex(packet, 15);
|
||||
fillMetadataIndex(packet, 17);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillMetadataIndex(PacketWriter packet, int index) {
|
||||
super.fillMetadataIndex(packet, index);
|
||||
if (index == 15) {
|
||||
packet.writeByte((byte) 15);
|
||||
packet.writeByte(METADATA_BOOLEAN);
|
||||
packet.writeBoolean(baby);
|
||||
} else if (index == 17) {
|
||||
packet.writeByte((byte) 17);
|
||||
packet.writeByte(METADATA_BOOLEAN);
|
||||
packet.writeBoolean(becomingDrowned);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isBaby() {
|
||||
return baby;
|
||||
}
|
||||
|
||||
public void setBaby(boolean baby) {
|
||||
this.baby = baby;
|
||||
sendMetadataIndex(15);
|
||||
}
|
||||
|
||||
public boolean isBecomingDrowned() {
|
||||
return becomingDrowned;
|
||||
}
|
||||
|
||||
public void setBecomingDrowned(boolean becomingDrowned) {
|
||||
this.becomingDrowned = becomingDrowned;
|
||||
sendMetadataIndex(17);
|
||||
}
|
||||
|
||||
}
|
@ -13,6 +13,7 @@ public class EntityPolarBear extends EntityCreature {
|
||||
|
||||
public EntityPolarBear(Position spawnPosition) {
|
||||
super(EntityType.POLAR_BEAR, spawnPosition);
|
||||
setBoundingBox(1.3f, 1.4f, 1.3f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -14,6 +14,7 @@ public class EntityPotion extends ObjectEntity {
|
||||
|
||||
public EntityPotion(Position spawnPosition, ItemStack potion) {
|
||||
super(EntityType.POTION, spawnPosition);
|
||||
setBoundingBox(0.25f, 0.25f, 0.25f);
|
||||
setPotion(potion);
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ public class EntityRabbit extends EntityCreature {
|
||||
|
||||
public EntityRabbit(Position spawnPosition) {
|
||||
super(EntityType.RABBIT, spawnPosition);
|
||||
setBoundingBox(0.4f, 0.5f, 0.4f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -7,5 +7,6 @@ import net.minestom.server.utils.Position;
|
||||
public class EntitySilverfish extends EntityCreature {
|
||||
public EntitySilverfish(Position spawnPosition) {
|
||||
super(EntityType.SILVERFISH, spawnPosition);
|
||||
setBoundingBox(0.4f, 0.3f, 0.4f);
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ public class EntitySlime extends EntityCreature {
|
||||
|
||||
public void setSize(int size) {
|
||||
this.size = size;
|
||||
final float boxSize = 0.51000005f * size;
|
||||
setBoundingBox(boxSize, boxSize, boxSize);
|
||||
sendMetadataIndex(15);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ public class EntitySnowman extends EntityCreature {
|
||||
|
||||
public EntitySnowman(Position spawnPosition) {
|
||||
super(EntityType.SNOW_GOLEM, spawnPosition);
|
||||
setBoundingBox(0.7f, 1.9f, 0.7f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -13,6 +13,7 @@ public class EntitySpider extends EntityCreature {
|
||||
|
||||
public EntitySpider(Position spawnPosition) {
|
||||
super(EntityType.SPIDER, spawnPosition);
|
||||
setBoundingBox(1.4f, 0.9f, 1.4f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -13,6 +13,7 @@ public class EntityWitch extends EntityCreature {
|
||||
|
||||
public EntityWitch(Position spawnPosition) {
|
||||
super(EntityType.WITCH, spawnPosition);
|
||||
setBoundingBox(0.6f, 1.95f, 0.6f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -14,6 +14,7 @@ public class EntityZombie extends EntityCreature {
|
||||
|
||||
public EntityZombie(Position spawnPosition) {
|
||||
super(EntityType.ZOMBIE, spawnPosition);
|
||||
setBoundingBox(0.6f, 1.95f, 0.6f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -4,10 +4,16 @@ public class CancellableEvent extends Event {
|
||||
|
||||
private boolean cancelled;
|
||||
|
||||
/**
|
||||
* @return true if the event should be cancelled, false otherwise
|
||||
*/
|
||||
public boolean isCancelled() {
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cancel true if the event should be cancelled, false otherwise
|
||||
*/
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
|
@ -3,6 +3,10 @@ package net.minestom.server.event.entity;
|
||||
import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.event.Event;
|
||||
|
||||
/**
|
||||
* Called when a player does a left click on an entity or with
|
||||
* {@link net.minestom.server.entity.EntityCreature#attack(Entity)}
|
||||
*/
|
||||
public class EntityAttackEvent extends Event {
|
||||
|
||||
private Entity source;
|
||||
@ -13,10 +17,16 @@ public class EntityAttackEvent extends Event {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the source of the attack
|
||||
*/
|
||||
public Entity getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the target of the attack
|
||||
*/
|
||||
public Entity getTarget() {
|
||||
return target;
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ package net.minestom.server.event.entity;
|
||||
import net.minestom.server.entity.damage.DamageType;
|
||||
import net.minestom.server.event.CancellableEvent;
|
||||
|
||||
/**
|
||||
* Called with {@link net.minestom.server.entity.LivingEntity#damage(DamageType, float)}
|
||||
*/
|
||||
public class EntityDamageEvent extends CancellableEvent {
|
||||
|
||||
private DamageType damageType;
|
||||
@ -13,14 +16,23 @@ public class EntityDamageEvent extends CancellableEvent {
|
||||
this.damage = damage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the damage type
|
||||
*/
|
||||
public DamageType getDamageType() {
|
||||
return damageType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the damage amount
|
||||
*/
|
||||
public float getDamage() {
|
||||
return damage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param damage the new damage amount
|
||||
*/
|
||||
public void setDamage(float damage) {
|
||||
this.damage = damage;
|
||||
}
|
||||
|
@ -12,6 +12,9 @@ public class EntityDeathEvent extends Event {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entity that died
|
||||
*/
|
||||
public Entity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
@ -2,22 +2,61 @@ package net.minestom.server.event.entity;
|
||||
|
||||
import net.minestom.server.entity.ItemEntity;
|
||||
import net.minestom.server.event.CancellableEvent;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
|
||||
/**
|
||||
* Called when two {@link ItemEntity} are merging their ItemStack together to form a sole entity
|
||||
*/
|
||||
public class EntityItemMergeEvent extends CancellableEvent {
|
||||
|
||||
private ItemEntity source;
|
||||
private ItemEntity merged;
|
||||
|
||||
public EntityItemMergeEvent(ItemEntity source, ItemEntity merged) {
|
||||
private ItemStack result;
|
||||
|
||||
public EntityItemMergeEvent(ItemEntity source, ItemEntity merged, ItemStack result) {
|
||||
this.source = source;
|
||||
this.merged = merged;
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity who is receiving {@link #getMerged()} ItemStack
|
||||
* <p>
|
||||
* This can be used to get the final ItemEntity position
|
||||
*
|
||||
* @return the source ItemEntity
|
||||
*/
|
||||
public ItemEntity getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity who will be merged
|
||||
* <p>
|
||||
* This entity will be removed after the event
|
||||
*
|
||||
* @return the merged ItemEntity
|
||||
*/
|
||||
public ItemEntity getMerged() {
|
||||
return merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the final item stack on the ground
|
||||
*
|
||||
* @return the item stack
|
||||
*/
|
||||
public ItemStack getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the item stack which will appear on the ground
|
||||
*
|
||||
* @param result the new item stack
|
||||
*/
|
||||
public void setResult(ItemStack result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ package net.minestom.server.event.entity;
|
||||
import net.minestom.server.event.Event;
|
||||
import net.minestom.server.instance.Instance;
|
||||
|
||||
/**
|
||||
* Called when a new instance is set for an entity
|
||||
*/
|
||||
public class EntitySpawnEvent extends Event {
|
||||
|
||||
private Instance spawnInstance;
|
||||
@ -11,6 +14,11 @@ public class EntitySpawnEvent extends Event {
|
||||
this.spawnInstance = spawnInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity new instance
|
||||
*
|
||||
* @return the instance
|
||||
*/
|
||||
public Instance getSpawnInstance() {
|
||||
return spawnInstance;
|
||||
}
|
||||
|
@ -14,14 +14,23 @@ public class EntityVelocityEvent extends CancellableEvent {
|
||||
this.velocity = velocity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the entity who the velocity is applied to
|
||||
*/
|
||||
public Entity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the velocity which will be applied
|
||||
*/
|
||||
public Vector getVelocity() {
|
||||
return velocity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param velocity the new velocity to applies
|
||||
*/
|
||||
public void setVelocity(Vector velocity) {
|
||||
this.velocity = velocity;
|
||||
}
|
||||
|
@ -17,6 +17,15 @@ public interface EventHandler {
|
||||
*/
|
||||
<E extends Event> void addEventCallback(Class<E> eventClass, EventCallback<E> eventCallback);
|
||||
|
||||
/**
|
||||
* Remove an event callback
|
||||
*
|
||||
* @param eventClass the event class
|
||||
* @param eventCallback the event callback
|
||||
* @param <E> the event type
|
||||
*/
|
||||
<E extends Event> void removeEventCallback(Class<E> eventClass, EventCallback<E> eventCallback);
|
||||
|
||||
/**
|
||||
* @param eventClass
|
||||
* @param <E>
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.minestom.server.event.inventory;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.Event;
|
||||
import net.minestom.server.inventory.Inventory;
|
||||
import net.minestom.server.inventory.click.ClickType;
|
||||
@ -7,13 +8,14 @@ import net.minestom.server.item.ItemStack;
|
||||
|
||||
public class InventoryClickEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
private Inventory inventory;
|
||||
private int slot;
|
||||
private ClickType clickType;
|
||||
private ItemStack clickedItem;
|
||||
private ItemStack cursorItem;
|
||||
|
||||
public InventoryClickEvent(Inventory inventory, int slot, ClickType clickType, ItemStack clicked, ItemStack cursor) {
|
||||
public InventoryClickEvent(Player player, Inventory inventory, int slot, ClickType clickType, ItemStack clicked, ItemStack cursor) {
|
||||
this.inventory = inventory;
|
||||
this.slot = slot;
|
||||
this.clickType = clickType;
|
||||
@ -21,6 +23,15 @@ public class InventoryClickEvent extends Event {
|
||||
this.cursorItem = cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who clicked in the inventory
|
||||
*
|
||||
* @return the player who clicked in the inventory
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be null if the clicked inventory is the player one
|
||||
*
|
||||
@ -30,18 +41,38 @@ public class InventoryClickEvent extends Event {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the clicked slot number
|
||||
*
|
||||
* @return the clicked slot number
|
||||
*/
|
||||
public int getSlot() {
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the click type
|
||||
*
|
||||
* @return the click type
|
||||
*/
|
||||
public ClickType getClickType() {
|
||||
return clickType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the clicked item
|
||||
*
|
||||
* @return the clicked item
|
||||
*/
|
||||
public ItemStack getClickedItem() {
|
||||
return clickedItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item in the player cursor
|
||||
*
|
||||
* @return the cursor item
|
||||
*/
|
||||
public ItemStack getCursorItem() {
|
||||
return cursorItem;
|
||||
}
|
||||
|
@ -1,24 +1,43 @@
|
||||
package net.minestom.server.event.inventory;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.Event;
|
||||
import net.minestom.server.inventory.Inventory;
|
||||
|
||||
public class InventoryCloseEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
private Inventory inventory;
|
||||
private Inventory newInventory;
|
||||
|
||||
public InventoryCloseEvent(Inventory inventory) {
|
||||
public InventoryCloseEvent(Player player, Inventory inventory) {
|
||||
this.player = player;
|
||||
this.inventory = inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who closed the inventory
|
||||
*
|
||||
* @return the player who closed the inventory
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the closed inventory
|
||||
*
|
||||
* @return the closed inventory, null if this is the player inventory
|
||||
*/
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the new inventory to open
|
||||
*
|
||||
* @return the new inventory to open, null if there isn't any
|
||||
*/
|
||||
public Inventory getNewInventory() {
|
||||
return newInventory;
|
||||
}
|
||||
@ -26,7 +45,7 @@ public class InventoryCloseEvent extends Event {
|
||||
/**
|
||||
* Can be used to open a new inventory after closing the previous one
|
||||
*
|
||||
* @param newInventory the inventory to open, can be null
|
||||
* @param newInventory the inventory to open, null to do not open any
|
||||
*/
|
||||
public void setNewInventory(Inventory newInventory) {
|
||||
this.newInventory = newInventory;
|
||||
|
@ -3,7 +3,6 @@ package net.minestom.server.event.inventory;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.CancellableEvent;
|
||||
import net.minestom.server.inventory.Inventory;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
|
||||
public class InventoryOpenEvent extends CancellableEvent {
|
||||
|
||||
@ -15,16 +14,32 @@ public class InventoryOpenEvent extends CancellableEvent {
|
||||
this.inventory = inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who opens the inventory
|
||||
*
|
||||
* @return the player who opens the inventory
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the inventory to open, this could have been change by the {@link #setInventory(Inventory)}
|
||||
*
|
||||
* @return the inventory to open
|
||||
*/
|
||||
public Inventory getInventory() {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the inventory to open.
|
||||
* to do not open any inventory see {@link #setCancelled(boolean)}
|
||||
*
|
||||
* @param inventory the inventory to open
|
||||
* @throws NullPointerException if {@code inventory} is null
|
||||
*/
|
||||
public void setInventory(Inventory inventory) {
|
||||
Check.notNull(inventory, "Inventory cannot be null!");
|
||||
this.inventory = inventory;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.minestom.server.event.inventory;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.CancellableEvent;
|
||||
import net.minestom.server.inventory.Inventory;
|
||||
import net.minestom.server.inventory.click.ClickType;
|
||||
@ -8,13 +9,15 @@ import net.minestom.server.utils.item.ItemStackUtils;
|
||||
|
||||
public class InventoryPreClickEvent extends CancellableEvent {
|
||||
|
||||
private Player player;
|
||||
private Inventory inventory;
|
||||
private int slot;
|
||||
private ClickType clickType;
|
||||
private ItemStack clickedItem;
|
||||
private ItemStack cursorItem;
|
||||
|
||||
public InventoryPreClickEvent(Inventory inventory, int slot, ClickType clickType, ItemStack clicked, ItemStack cursor) {
|
||||
public InventoryPreClickEvent(Player player, Inventory inventory, int slot, ClickType clickType, ItemStack clicked, ItemStack cursor) {
|
||||
this.player = player;
|
||||
this.inventory = inventory;
|
||||
this.slot = slot;
|
||||
this.clickType = clickType;
|
||||
@ -22,6 +25,15 @@ public class InventoryPreClickEvent extends CancellableEvent {
|
||||
this.cursorItem = cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who is trying to click on the inventory
|
||||
*
|
||||
* @return the player who clicked
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be null if the clicked inventory is the player one
|
||||
*
|
||||
@ -31,26 +43,56 @@ public class InventoryPreClickEvent extends CancellableEvent {
|
||||
return inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the clicked slot number
|
||||
*
|
||||
* @return the clicked slot number
|
||||
*/
|
||||
public int getSlot() {
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the click type
|
||||
*
|
||||
* @return the click type
|
||||
*/
|
||||
public ClickType getClickType() {
|
||||
return clickType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item who have been clicked
|
||||
*
|
||||
* @return the clicked item
|
||||
*/
|
||||
public ItemStack getClickedItem() {
|
||||
return clickedItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the clicked item
|
||||
*
|
||||
* @param clickedItem the clicked item
|
||||
*/
|
||||
public void setClickedItem(ItemStack clickedItem) {
|
||||
this.clickedItem = ItemStackUtils.notNull(clickedItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item who was in the player cursor
|
||||
*
|
||||
* @return the cursor item
|
||||
*/
|
||||
public ItemStack getCursorItem() {
|
||||
return cursorItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the cursor item
|
||||
*
|
||||
* @param cursorItem the cursor item
|
||||
*/
|
||||
public void setCursorItem(ItemStack cursorItem) {
|
||||
this.cursorItem = ItemStackUtils.notNull(cursorItem);
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.CancellableEvent;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.utils.item.ItemStackUtils;
|
||||
|
||||
/**
|
||||
* Called as a result of {@link net.minestom.server.inventory.PlayerInventory#addItemStack(ItemStack)}
|
||||
*/
|
||||
public class PlayerAddItemStackEvent extends CancellableEvent {
|
||||
|
||||
private Player player;
|
||||
private ItemStack itemStack;
|
||||
|
||||
public PlayerAddItemStackEvent(Player player, ItemStack itemStack) {
|
||||
this.player = player;
|
||||
this.itemStack = itemStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who has an item stack added to his inventory
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item stack which will be added
|
||||
*
|
||||
* @return the item stack
|
||||
*/
|
||||
public ItemStack getItemStack() {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the item stack which will be added
|
||||
*
|
||||
* @param itemStack the new item stack
|
||||
*/
|
||||
public void setItemStack(ItemStack itemStack) {
|
||||
this.itemStack = ItemStackUtils.notNull(itemStack);
|
||||
}
|
||||
}
|
@ -1,42 +1,97 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.event.CancellableEvent;
|
||||
import net.minestom.server.instance.block.CustomBlock;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
|
||||
public class PlayerBlockBreakEvent extends CancellableEvent {
|
||||
|
||||
private BlockPosition blockPosition;
|
||||
|
||||
private short blockId;
|
||||
private CustomBlock customBlock;
|
||||
|
||||
private short resultBlockId;
|
||||
private short resultCustomBlockId;
|
||||
|
||||
public PlayerBlockBreakEvent(BlockPosition blockPosition, short resultBlockId, short resultCustomBlockId) {
|
||||
public PlayerBlockBreakEvent(BlockPosition blockPosition,
|
||||
short blockId, CustomBlock customBlock,
|
||||
short resultBlockId, short resultCustomBlockId) {
|
||||
this.blockPosition = blockPosition;
|
||||
|
||||
this.blockId = blockId;
|
||||
this.customBlock = customBlock;
|
||||
|
||||
this.resultBlockId = resultBlockId;
|
||||
this.resultCustomBlockId = resultCustomBlockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block position
|
||||
*
|
||||
* @return the block position
|
||||
*/
|
||||
public BlockPosition getBlockPosition() {
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the broken block visual id
|
||||
*
|
||||
* @return the block id
|
||||
*/
|
||||
public short getBlockId() {
|
||||
return blockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the broken custom block
|
||||
*
|
||||
* @return the custom block,
|
||||
* null if not any
|
||||
*/
|
||||
public CustomBlock getCustomBlock() {
|
||||
return customBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the visual block id result, which will be placed after the event
|
||||
*
|
||||
* @return the block id that will be set at {@link #getBlockPosition()}
|
||||
* set to 0 to remove
|
||||
*/
|
||||
public short getResultBlockId() {
|
||||
return resultBlockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the visual block id result
|
||||
*
|
||||
* @param resultBlockId the result block id
|
||||
*/
|
||||
public void setResultBlockId(short resultBlockId) {
|
||||
this.resultBlockId = resultBlockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the custom block id result, which will be placed after the event
|
||||
* <p>
|
||||
* Warning: the visual block will not be changed, be sure to call {@link #setResultBlockId(short)}
|
||||
* if you want the visual to be the same as {@link CustomBlock#getBlockId()}
|
||||
*
|
||||
* @return the custom block id that will be set at {@link #getBlockPosition()}
|
||||
* set to 0 to remove
|
||||
*/
|
||||
public short getResultCustomBlockId() {
|
||||
return resultCustomBlockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the custom block id result, which will be placed after the event
|
||||
*
|
||||
* @param resultCustomBlockId the custom block id result
|
||||
*/
|
||||
public void setResultCustomBlockId(short resultCustomBlockId) {
|
||||
this.resultCustomBlockId = resultCustomBlockId;
|
||||
}
|
||||
|
||||
public boolean isResultCustomBlock() {
|
||||
return resultCustomBlockId != 0;
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,19 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.CancellableEvent;
|
||||
import net.minestom.server.instance.block.BlockManager;
|
||||
import net.minestom.server.instance.block.CustomBlock;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
|
||||
/**
|
||||
* Called when a player tries placing a block
|
||||
*/
|
||||
public class PlayerBlockPlaceEvent extends CancellableEvent {
|
||||
|
||||
private static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
|
||||
|
||||
private final Player player;
|
||||
private short blockId;
|
||||
private short customBlockId;
|
||||
@ -23,38 +31,100 @@ public class PlayerBlockPlaceEvent extends CancellableEvent {
|
||||
this.consumeBlock = true;
|
||||
}
|
||||
|
||||
public void setCustomBlockId(short customBlockId) {
|
||||
this.customBlockId = customBlockId;
|
||||
/**
|
||||
* Set both the blockId and customBlockId
|
||||
*
|
||||
* @param customBlock the custom block to place
|
||||
*/
|
||||
public void setCustomBlock(CustomBlock customBlock) {
|
||||
setBlockId(customBlock.getBlockId());
|
||||
setCustomBlockId(customBlock.getCustomBlockId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set both the blockId and customBlockId
|
||||
*
|
||||
* @param customBlockId the custom block id to place
|
||||
*/
|
||||
public void setCustomBlock(short customBlockId) {
|
||||
CustomBlock customBlock = BLOCK_MANAGER.getCustomBlock(customBlockId);
|
||||
setCustomBlock(customBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set both the blockId and customBlockId
|
||||
*
|
||||
* @param customBlockId the custom block id to place
|
||||
*/
|
||||
public void setCustomBlock(String customBlockId) {
|
||||
CustomBlock customBlock = BLOCK_MANAGER.getCustomBlock(customBlockId);
|
||||
setCustomBlock(customBlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the custom block id to place
|
||||
*/
|
||||
public short getCustomBlockId() {
|
||||
return customBlockId;
|
||||
}
|
||||
|
||||
public void setBlockId(short blockId) {
|
||||
this.blockId = blockId;
|
||||
/**
|
||||
* Set the custom block id to place
|
||||
* <p>
|
||||
* WARNING: this does not change the visual block id, see {@link #setBlockId(short)}
|
||||
* or {@link #setCustomBlock(short)}
|
||||
*
|
||||
* @param customBlockId
|
||||
*/
|
||||
public void setCustomBlockId(short customBlockId) {
|
||||
this.customBlockId = customBlockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the visual block id to place
|
||||
*/
|
||||
public short getBlockId() {
|
||||
return blockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param blockId the visual block id to place
|
||||
*/
|
||||
public void setBlockId(short blockId) {
|
||||
this.blockId = blockId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the player who is placing the block
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the position of the block to place
|
||||
*/
|
||||
public BlockPosition getBlockPosition() {
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the hand with which the player is trying to place
|
||||
*/
|
||||
public Player.Hand getHand() {
|
||||
return hand;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param consumeBlock true if the block should be consumer (-1 amount), false otherwise
|
||||
*/
|
||||
public void consumeBlock(boolean consumeBlock) {
|
||||
this.consumeBlock = consumeBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the block will be consumed, false otherwise
|
||||
*/
|
||||
public boolean doesConsumeBlock() {
|
||||
return consumeBlock;
|
||||
}
|
||||
|
@ -8,6 +8,10 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Called every time a player write and send something in the chat.
|
||||
* The event can be cancelled to do not send anything, and the format can be changed
|
||||
*/
|
||||
public class PlayerChatEvent extends CancellableEvent {
|
||||
|
||||
private Player sender;
|
||||
@ -21,26 +25,52 @@ public class PlayerChatEvent extends CancellableEvent {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param chatFormat the custom chat format
|
||||
*/
|
||||
public void setChatFormat(Function<PlayerChatEvent, TextComponent> chatFormat) {
|
||||
this.chatFormat = chatFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the sender of the message
|
||||
*/
|
||||
public Player getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is all the players who will receive the message
|
||||
* It can be modified to add or remove recipient
|
||||
*
|
||||
* @return a modifiable list of message targets
|
||||
*/
|
||||
public Collection<Player> getRecipients() {
|
||||
return recipients;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the sender's message
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to change the message
|
||||
*
|
||||
* @param message the new message
|
||||
*/
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to retrieve the chat format for this message.
|
||||
* If null, the default format will be used
|
||||
*
|
||||
* @return the chat format which will be used
|
||||
*/
|
||||
public Function<PlayerChatEvent, TextComponent> getChatFormatFunction() {
|
||||
return chatFormat;
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ package net.minestom.server.event.player;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.Event;
|
||||
|
||||
/**
|
||||
* Called when a player receive a new chunk data
|
||||
*/
|
||||
public class PlayerChunkLoadEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
@ -14,14 +17,29 @@ public class PlayerChunkLoadEvent extends Event {
|
||||
this.chunkZ = chunkZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the chunk X
|
||||
*
|
||||
* @return the chunk X
|
||||
*/
|
||||
public int getChunkX() {
|
||||
return chunkX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the chunk Z
|
||||
*
|
||||
* @return the chunk Z
|
||||
*/
|
||||
public int getChunkZ() {
|
||||
return chunkZ;
|
||||
}
|
||||
|
@ -18,14 +18,29 @@ public class PlayerChunkUnloadEvent extends Event {
|
||||
this.chunkZ = chunkZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the chunk X
|
||||
*
|
||||
* @return the chunk X
|
||||
*/
|
||||
public int getChunkX() {
|
||||
return chunkX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the chunk Z
|
||||
*
|
||||
* @return the chunk Z
|
||||
*/
|
||||
public int getChunkZ() {
|
||||
return chunkZ;
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ package net.minestom.server.event.player;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.CancellableEvent;
|
||||
|
||||
/**
|
||||
* Called every time a player send a message starting by '/'
|
||||
*/
|
||||
public class PlayerCommandEvent extends CancellableEvent {
|
||||
|
||||
private Player player;
|
||||
@ -13,14 +16,25 @@ public class PlayerCommandEvent extends CancellableEvent {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the player who want to execute the command
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the command that the player wants to execute
|
||||
*/
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the command to execute
|
||||
*
|
||||
* @param command the new command
|
||||
*/
|
||||
public void setCommand(String command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
@ -1,6 +1,25 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.Event;
|
||||
|
||||
/**
|
||||
* Called when a player disconnect
|
||||
*/
|
||||
public class PlayerDisconnectEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
|
||||
public PlayerDisconnectEvent(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who is disconnecting
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,36 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.Event;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
|
||||
/**
|
||||
* Called when a player is finished eating
|
||||
*/
|
||||
public class PlayerEatEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
private ItemStack foodItem;
|
||||
|
||||
public PlayerEatEvent(ItemStack foodItem) {
|
||||
public PlayerEatEvent(Player player, ItemStack foodItem) {
|
||||
this.player = player;
|
||||
this.foodItem = foodItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who is finished eating
|
||||
*
|
||||
* @return the concerned player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the food item that has been eaten
|
||||
*
|
||||
* @return the food item
|
||||
*/
|
||||
public ItemStack getFoodItem() {
|
||||
return foodItem;
|
||||
}
|
||||
|
@ -4,20 +4,44 @@ import net.minestom.server.entity.Entity;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.Event;
|
||||
|
||||
/**
|
||||
* Called when a player interacts (right-click) with an entity
|
||||
*/
|
||||
public class PlayerInteractEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
private Entity entityTarget;
|
||||
private Player.Hand hand;
|
||||
|
||||
public PlayerInteractEvent(Entity entityTarget, Player.Hand hand) {
|
||||
public PlayerInteractEvent(Player player, Entity entityTarget, Player.Hand hand) {
|
||||
this.player = player;
|
||||
this.entityTarget = entityTarget;
|
||||
this.hand = hand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who is interacting
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the entity with who {@link #getPlayer()} is interacting
|
||||
*
|
||||
* @return the entity
|
||||
*/
|
||||
public Entity getTarget() {
|
||||
return entityTarget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get with which hand the player interacted with the entity
|
||||
*
|
||||
* @return the hand
|
||||
*/
|
||||
public Player.Hand getHand() {
|
||||
return hand;
|
||||
}
|
||||
|
@ -1,18 +1,49 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.Event;
|
||||
import net.minestom.server.instance.Instance;
|
||||
|
||||
/**
|
||||
* Called at player login, used to define his spawn instance
|
||||
* <p>
|
||||
* WARNING: defining the spawning instance is MANDATORY
|
||||
*/
|
||||
public class PlayerLoginEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
private Instance spawningInstance;
|
||||
|
||||
public PlayerLoginEvent(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who is logging
|
||||
*
|
||||
* @return the player who is logging
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the spawning instance of the player
|
||||
* <p>
|
||||
* WARNING: this must NOT be null, otherwise the player cannot spawn
|
||||
*
|
||||
* @return the spawning instance
|
||||
*/
|
||||
public Instance getSpawningInstance() {
|
||||
return spawningInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the spawning instance
|
||||
*
|
||||
* @param instance the new spawning instance
|
||||
*/
|
||||
public void setSpawningInstance(Instance instance) {
|
||||
this.spawningInstance = instance;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,16 +1,36 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.CancellableEvent;
|
||||
import net.minestom.server.utils.Position;
|
||||
|
||||
/**
|
||||
* Called when a player is modifying his position
|
||||
*/
|
||||
public class PlayerMoveEvent extends CancellableEvent {
|
||||
|
||||
private Player player;
|
||||
private Position newPosition;
|
||||
|
||||
public PlayerMoveEvent(float x, float y, float z, float yaw, float pitch) {
|
||||
this.newPosition = new Position(x, y, z, yaw, pitch);
|
||||
public PlayerMoveEvent(Player player, Position newPosition) {
|
||||
this.player = player;
|
||||
this.newPosition = newPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who is moving
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the target position
|
||||
*
|
||||
* @return the new position
|
||||
*/
|
||||
public Position getNewPosition() {
|
||||
return newPosition;
|
||||
}
|
||||
|
@ -1,25 +1,55 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.Event;
|
||||
|
||||
/**
|
||||
* Called when a player send {@link net.minestom.server.network.packet.client.play.ClientPluginMessagePacket}
|
||||
*/
|
||||
public class PlayerPluginMessageEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
private String identifier;
|
||||
private byte[] message;
|
||||
|
||||
public PlayerPluginMessageEvent(String identifier, byte[] message) {
|
||||
public PlayerPluginMessageEvent(Player player, String identifier, byte[] message) {
|
||||
this.player = player;
|
||||
this.identifier = identifier;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who sent the message
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message identifier
|
||||
*
|
||||
* @return the identifier
|
||||
*/
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message data as a byte array
|
||||
*
|
||||
* @return the message
|
||||
*/
|
||||
public byte[] getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message data as a String
|
||||
*
|
||||
* @return the message
|
||||
*/
|
||||
public String getMessageString() {
|
||||
return new String(message);
|
||||
}
|
||||
|
@ -21,18 +21,40 @@ public class PlayerPreEatEvent extends CancellableEvent {
|
||||
this.eatingTime = eatingTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* The player who is trying to eat
|
||||
*
|
||||
* @return the concerned player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* The food item which will be eaten
|
||||
*
|
||||
* @return the food item
|
||||
*/
|
||||
public ItemStack getFoodItem() {
|
||||
return foodItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the food eating time
|
||||
* <p>
|
||||
* This is by default {@link Player#getDefaultEatingTime()}
|
||||
*
|
||||
* @return the eating time
|
||||
*/
|
||||
public long getEatingTime() {
|
||||
return eatingTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the food eating time
|
||||
*
|
||||
* @param eatingTime the new eating time
|
||||
*/
|
||||
public void setEatingTime(long eatingTime) {
|
||||
this.eatingTime = eatingTime;
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.Event;
|
||||
import net.minestom.server.resourcepack.ResourcePackStatus;
|
||||
|
||||
/**
|
||||
* Called when a player warns the server of a resource pack status
|
||||
*/
|
||||
public class PlayerResourcePackStatusEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
private ResourcePackStatus status;
|
||||
|
||||
public PlayerResourcePackStatusEvent(Player player, ResourcePackStatus status) {
|
||||
this.player = player;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who send a resource pack status
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the resource pack status
|
||||
*
|
||||
* @return the resource pack status
|
||||
*/
|
||||
public ResourcePackStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
}
|
@ -1,20 +1,46 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.Event;
|
||||
import net.minestom.server.utils.Position;
|
||||
|
||||
/**
|
||||
* Called when {@link Player#respawn()} is executed (for custom respawn or as a result of
|
||||
* {@link net.minestom.server.network.packet.client.play.ClientStatusPacket}
|
||||
*/
|
||||
public class PlayerRespawnEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
private Position respawnPosition;
|
||||
|
||||
public PlayerRespawnEvent(Position respawnPosition) {
|
||||
public PlayerRespawnEvent(Player player, Position respawnPosition) {
|
||||
this.player = player;
|
||||
this.respawnPosition = respawnPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who is respawning
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the respawn position
|
||||
*
|
||||
* @return the respawn position
|
||||
*/
|
||||
public Position getRespawnPosition() {
|
||||
return respawnPosition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the respawn position
|
||||
*
|
||||
* @param respawnPosition the new respawn position
|
||||
*/
|
||||
public void setRespawnPosition(Position respawnPosition) {
|
||||
this.respawnPosition = respawnPosition;
|
||||
}
|
||||
|
@ -0,0 +1,69 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.CancellableEvent;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
import net.minestom.server.utils.item.ItemStackUtils;
|
||||
|
||||
/**
|
||||
* Called as a result of {@link net.minestom.server.inventory.PlayerInventory#setItemStack(int, ItemStack)}
|
||||
* and player click in his inventory
|
||||
*/
|
||||
public class PlayerSetItemStackEvent extends CancellableEvent {
|
||||
|
||||
private Player player;
|
||||
private int slot;
|
||||
private ItemStack itemStack;
|
||||
|
||||
public PlayerSetItemStackEvent(Player player, int slot, ItemStack itemStack) {
|
||||
this.player = player;
|
||||
this.slot = slot;
|
||||
this.itemStack = itemStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who has an item stack set to his inventory
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the slot where the item will be set
|
||||
*
|
||||
* @return the slot
|
||||
*/
|
||||
public int getSlot() {
|
||||
return slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the slot where the item will be set
|
||||
*
|
||||
* @param slot the new slot
|
||||
*/
|
||||
public void setSlot(int slot) {
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item stack which will be set
|
||||
*
|
||||
* @return the item stack
|
||||
*/
|
||||
public ItemStack getItemStack() {
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the item stack which will be set
|
||||
*
|
||||
* @param itemStack the new item stack
|
||||
*/
|
||||
public void setItemStack(ItemStack itemStack) {
|
||||
this.itemStack = ItemStackUtils.notNull(itemStack);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.entity.PlayerSkin;
|
||||
import net.minestom.server.event.Event;
|
||||
|
||||
/**
|
||||
* Called at the player connection to initialize his skin
|
||||
*/
|
||||
public class PlayerSkinInitEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
private PlayerSkin skin;
|
||||
|
||||
public PlayerSkinInitEvent(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player whose the skin is getting initialized
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the spawning skin of the player
|
||||
*
|
||||
* @return the player skin, or null if not any
|
||||
*/
|
||||
public PlayerSkin getSkin() {
|
||||
return skin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the spawning skin of the player
|
||||
*
|
||||
* @param skin the new player skin
|
||||
*/
|
||||
public void setSkin(PlayerSkin skin) {
|
||||
this.skin = skin;
|
||||
}
|
||||
}
|
@ -3,6 +3,9 @@ package net.minestom.server.event.player;
|
||||
import net.minestom.server.event.entity.EntitySpawnEvent;
|
||||
import net.minestom.server.instance.Instance;
|
||||
|
||||
/**
|
||||
* Called when a new instance is set for a player
|
||||
*/
|
||||
public class PlayerSpawnEvent extends EntitySpawnEvent {
|
||||
private final boolean firstSpawn;
|
||||
|
||||
@ -13,7 +16,8 @@ public class PlayerSpawnEvent extends EntitySpawnEvent {
|
||||
|
||||
/**
|
||||
* 'true' if the player is spawning for the first time. 'false' if this spawn event was triggered by a dimension teleport
|
||||
* @return
|
||||
*
|
||||
* @return true if this is the first spawn, false otherwise
|
||||
*/
|
||||
public boolean isFirstSpawn() {
|
||||
return firstSpawn;
|
||||
|
@ -1,24 +1,52 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.CancellableEvent;
|
||||
import net.minestom.server.instance.block.CustomBlock;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
|
||||
/**
|
||||
* Called when a player start digging a {@link CustomBlock},
|
||||
* can be used to forbid the player from mining a block
|
||||
* <p>
|
||||
* WARNING: this is not called for non-custom block
|
||||
*/
|
||||
public class PlayerStartDiggingEvent extends CancellableEvent {
|
||||
|
||||
private Player player;
|
||||
private BlockPosition blockPosition;
|
||||
private CustomBlock customBlock;
|
||||
|
||||
public PlayerStartDiggingEvent(BlockPosition blockPosition, CustomBlock customBlock) {
|
||||
public PlayerStartDiggingEvent(Player player, BlockPosition blockPosition, CustomBlock customBlock) {
|
||||
this.player = player;
|
||||
this.blockPosition = blockPosition;
|
||||
this.customBlock = customBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who started digging the block
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block position
|
||||
*
|
||||
* @return the block position
|
||||
*/
|
||||
public BlockPosition getBlockPosition() {
|
||||
return blockPosition;
|
||||
}
|
||||
|
||||
public CustomBlock getBlock() {
|
||||
/**
|
||||
* Get the custom block object that the player is trying to dig
|
||||
*
|
||||
* @return the custom block
|
||||
*/
|
||||
public CustomBlock getCustomBlock() {
|
||||
return customBlock;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ package net.minestom.server.event.player;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.Event;
|
||||
|
||||
/**
|
||||
* Called when a player start flying
|
||||
*/
|
||||
public class PlayerStartFlyingEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
@ -11,6 +14,11 @@ public class PlayerStartFlyingEvent extends Event {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who started flying
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ package net.minestom.server.event.player;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.Event;
|
||||
|
||||
/**
|
||||
* Called when a player stop flying
|
||||
*/
|
||||
public class PlayerStopFlyingEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
@ -11,6 +14,11 @@ public class PlayerStopFlyingEvent extends Event {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who stopped flying
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
@ -1,30 +1,65 @@
|
||||
package net.minestom.server.event.player;
|
||||
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.CancellableEvent;
|
||||
import net.minestom.server.item.ItemStack;
|
||||
|
||||
/**
|
||||
* Called when a player is trying to swap his main and off hand item
|
||||
*/
|
||||
public class PlayerSwapItemEvent extends CancellableEvent {
|
||||
|
||||
private Player player;
|
||||
private ItemStack mainHandItem;
|
||||
private ItemStack offHandItem;
|
||||
|
||||
public PlayerSwapItemEvent(ItemStack mainHandItem, ItemStack offHandItem) {
|
||||
public PlayerSwapItemEvent(Player player, ItemStack mainHandItem, ItemStack offHandItem) {
|
||||
this.player = player;
|
||||
this.mainHandItem = mainHandItem;
|
||||
this.offHandItem = offHandItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player who is trying to swap his hands item
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item which will be in player main hand after the event
|
||||
*
|
||||
* @return the item in main hand
|
||||
*/
|
||||
public ItemStack getMainHandItem() {
|
||||
return mainHandItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the item which will be in the player main hand
|
||||
*
|
||||
* @param mainHandItem the main hand item
|
||||
*/
|
||||
public void setMainHandItem(ItemStack mainHandItem) {
|
||||
this.mainHandItem = mainHandItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the item which will be in player off hand after the event
|
||||
*
|
||||
* @return the item in off hand
|
||||
*/
|
||||
public ItemStack getOffHandItem() {
|
||||
return offHandItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the item which will be in the player off hand
|
||||
*
|
||||
* @param offHandItem the off hand item
|
||||
*/
|
||||
public void setOffHandItem(ItemStack offHandItem) {
|
||||
this.offHandItem = offHandItem;
|
||||
}
|
||||
|
@ -3,6 +3,9 @@ package net.minestom.server.event.player;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.Event;
|
||||
|
||||
/**
|
||||
* Called at each player tick
|
||||
*/
|
||||
public class PlayerTickEvent extends Event {
|
||||
|
||||
private Player player;
|
||||
@ -11,6 +14,11 @@ public class PlayerTickEvent extends Event {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player
|
||||
*
|
||||
* @return the player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user