feat: allow FakePlayer to be attackted
This commit is contained in:
parent
d4c6af4633
commit
44ef00d397
7 changed files with 265 additions and 67 deletions
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
|
@ -4,15 +4,18 @@
|
|||
"java.jdt.ls.vmargs": "-Dfile.encoding=UTF-8",
|
||||
"java.configuration.updateBuildConfiguration": "automatic",
|
||||
"cSpell.words": [
|
||||
"Gamemode",
|
||||
"Gamerules",
|
||||
"Minecraft",
|
||||
"Mojang",
|
||||
"cliffbreak",
|
||||
"mkdir",
|
||||
"npcs",
|
||||
"teamcolors",
|
||||
"testremove",
|
||||
"unban",
|
||||
"uninject",
|
||||
"varo"
|
||||
],
|
||||
"java.format.settings.url": "eclipse-formatter.xml",
|
||||
"java.format.settings.url": "eclipse-formatter.xml"
|
||||
}
|
|
@ -17,7 +17,7 @@ import de.cliffbreak.varo.commands.VaroCommand;
|
|||
import de.cliffbreak.varo.listeners.BannedItemListener;
|
||||
import de.cliffbreak.varo.listeners.ChatListener;
|
||||
import de.cliffbreak.varo.listeners.CreatureSpawnListener;
|
||||
import de.cliffbreak.varo.listeners.EntityDamageByEntityListener;
|
||||
import de.cliffbreak.varo.listeners.PlayerInteractNPCListener;
|
||||
import de.cliffbreak.varo.listeners.EntityRegainHealthListener;
|
||||
import de.cliffbreak.varo.listeners.PlayerClientOptionsChangeListener;
|
||||
import de.cliffbreak.varo.listeners.PlayerDeathListener;
|
||||
|
@ -41,6 +41,7 @@ public class Varo extends JavaPlugin {
|
|||
this.playerCache = new PlayerCache(this);
|
||||
|
||||
// this.config.addDefault("Varo.Start", "TODO: StartDate");
|
||||
this.config.addDefault("Varo.Debug", false);
|
||||
this.config.addDefault("Varo.Bans", new ArrayList<String>());
|
||||
this.config.options().copyDefaults(true);
|
||||
this.saveConfiguration();
|
||||
|
@ -53,13 +54,16 @@ public class Varo extends JavaPlugin {
|
|||
getServer().getPluginManager().registerEvents(new PlayerDeathListener(this), this);
|
||||
getServer().getPluginManager().registerEvents(new BannedItemListener(), this);
|
||||
getServer().getPluginManager().registerEvents(new CreatureSpawnListener(this), this);
|
||||
getServer().getPluginManager().registerEvents(new PlayerInteractNPCListener(this), this);
|
||||
|
||||
getCommand("varo").setExecutor(new VaroCommand(this));
|
||||
|
||||
for (World world : getServer().getWorlds()) {
|
||||
if (world.getEnvironment() == Environment.NORMAL) {
|
||||
world.setDifficulty(Difficulty.HARD);
|
||||
// world.setDifficulty(Difficulty.HARD);
|
||||
world.setDifficulty(Difficulty.PEACEFUL); // TODO: REMOVE AFTER DEBUG!!
|
||||
world.setGameRule(GameRule.ANNOUNCE_ADVANCEMENTS, false);
|
||||
world.setGameRule(GameRule.REDUCED_DEBUG_INFO, true);
|
||||
}
|
||||
}
|
||||
getServer().removeRecipe(NamespacedKey.minecraft("fishing_rod"));
|
||||
|
@ -68,7 +72,6 @@ public class Varo extends JavaPlugin {
|
|||
@Override
|
||||
public void onDisable() {
|
||||
getLogger().info("Stopping CliffbreakVaro!");
|
||||
saveConfiguration();
|
||||
this.playerCache.shutdown();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package de.cliffbreak.varo.events;
|
||||
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
public class PlayerInteractNPCEvent extends Event {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Type type;
|
||||
private final int id;
|
||||
private final double damage;
|
||||
private final boolean isCritical;
|
||||
|
||||
public PlayerInteractNPCEvent(Type type, int id, double damage, boolean isCritical) {
|
||||
super(true);
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
this.damage = damage;
|
||||
this.isCritical = isCritical;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return InteractionType of the Event
|
||||
*/
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EntityId of the Event
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Damage from Player to Entity (only use if Type=ATTACK)
|
||||
*/
|
||||
public double getDamage() {
|
||||
return damage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Return if Player made a critical attack
|
||||
*/
|
||||
public boolean getIsCritical() {
|
||||
return isCritical;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
ATTACK, INTERACT,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package de.cliffbreak.varo.listeners;
|
||||
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
||||
import de.cliffbreak.varo.Varo;
|
||||
import de.cliffbreak.varo.events.PlayerInteractNPCEvent;
|
||||
import de.cliffbreak.varo.events.PlayerInteractNPCEvent.Type;
|
||||
|
||||
public class PlayerInteractNPCListener implements Listener {
|
||||
|
||||
private Varo plugin;
|
||||
|
||||
public PlayerInteractNPCListener(Varo plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEntityDamageByEntity(PlayerInteractNPCEvent e) {
|
||||
// plugin.getLogger().info(e.getType().toString() + " : " + e.getId() + " : " + e.getDamage());
|
||||
if (e.getType().equals(Type.ATTACK)) {
|
||||
plugin.npcManager.addDamage(e.getId(), e.getDamage(), e.getIsCritical());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package de.cliffbreak.varo.listeners;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Stack;
|
||||
|
||||
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
|
||||
|
@ -15,6 +14,7 @@ import org.bukkit.scheduler.BukkitRunnable;
|
|||
|
||||
import de.cliffbreak.varo.Varo;
|
||||
import de.cliffbreak.varo.uitls.MessageUtils;
|
||||
import de.cliffbreak.varo.uitls.PacketReader;
|
||||
|
||||
public class PlayerJoinQuitListener implements Listener {
|
||||
|
||||
|
@ -24,7 +24,7 @@ public class PlayerJoinQuitListener implements Listener {
|
|||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler()
|
||||
@EventHandler
|
||||
public void onPlayerQuit(final PlayerQuitEvent e) {
|
||||
e.setQuitMessage(null);
|
||||
plugin.npcManager.createClone(e.getPlayer(), true);
|
||||
|
@ -32,51 +32,62 @@ public class PlayerJoinQuitListener implements Listener {
|
|||
MessageUtils.getRichTextComponent(e.getPlayer().getName(), "§f hat den Server verlassen.", true));
|
||||
}
|
||||
|
||||
@EventHandler()
|
||||
@EventHandler
|
||||
public void onPlayerJoin(final PlayerJoinEvent e) {
|
||||
e.setJoinMessage(null);
|
||||
plugin.npcManager.removeClone(e.getPlayer());
|
||||
plugin.npcManager.syncClones(e.getPlayer());
|
||||
|
||||
// Inject PacketReader
|
||||
PacketReader packetReader = new PacketReader(plugin, e.getPlayer());
|
||||
packetReader.inject();
|
||||
|
||||
Bukkit.broadcast(
|
||||
MessageUtils.getRichTextComponent(e.getPlayer().getName(), "§f hat den Server betreten.", true));
|
||||
e.getPlayer().sendMessage("\n§7§l#### §9Cliffbreak.de - §lVaro §r§9Changelog §7§l####\n \n"
|
||||
+ " §cWarning: §r§c Plugin is running in DEBUG mode!\n ");
|
||||
|
||||
final Stack<String> changes = new Stack<String>();
|
||||
if (plugin.config.getBoolean("Varo.Debug")) {
|
||||
|
||||
changes.push(" §7• §r§lADD: §rAdd a FakePlayer if Player is logged out");
|
||||
changes.push(" §7• §r§lADD: §rAdd /varo test && /varo testremove");
|
||||
changes.push(" §7• §r§lFIX: §r/varo Command is only usable by Server Operators now");
|
||||
changes.push(" §7• §r§lADD: §rDisallow special Items (Enchanted Golden Apple, Fishing Rod, Totem of Undying)");
|
||||
changes.push(" §7• §r§lADD: §rUse Vanilla Hearts");
|
||||
changes.push(" §7• §r§lADD: §rDisable Fishing Rod Crafting Recipe");
|
||||
changes.push(" §7• §r§lFIX: §rCheck for Ban in AsyncPreLoginEvent");
|
||||
changes.push(" §7• §r§lFIX: §rOnly kick player after Entity isn't ticking anymore");
|
||||
changes.push(" §7• §r§lADD: §r/varo Command for Admins");
|
||||
changes.push(" §7• §r§lADD: §rBan Player on Death");
|
||||
changes.push(" §7• §r§lADD: §r1.8 Health Regeneration");
|
||||
changes.push(" §7• §r§lADD: §rCustom Dynamic ServerListEntry");
|
||||
changes.push(" §7• §r§lADD: §rControl Difficulty and Gamerules by the Plugin");
|
||||
changes.push(" §7• §r§lADD: §rHover over Playername for Details (Team)");
|
||||
changes.push(" §7• §r§lADD: §rRedesigned Chat with Timestamp");
|
||||
e.getPlayer().sendMessage("\n§7§l#### §9Cliffbreak.de - §lVaro §r§9Changelog §7§l####\n \n"
|
||||
+ " §cWarning: §r§c Plugin is running in DEBUG mode!\n ");
|
||||
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!e.getPlayer().isOnline()) {
|
||||
this.cancel();
|
||||
return;
|
||||
final Stack<String> changes = new Stack<String>();
|
||||
|
||||
changes.push(" §7• §r§lADD: §rFakePlayer is no attackable (can also be killed)");
|
||||
changes.push(" §7• §r§lADD: §rAdd a FakePlayer if Player is logged out");
|
||||
changes.push(" §7• §r§lADD: §rAdd /varo test && /varo testremove");
|
||||
changes.push(" §7• §r§lFIX: §r/varo Command is only usable by Server Operators now");
|
||||
changes.push(
|
||||
" §7• §r§lADD: §rDisallow special Items (Enchanted Golden Apple, Fishing Rod, Totem of Undying)");
|
||||
changes.push(" §7• §r§lADD: §rUse Vanilla Hearts");
|
||||
changes.push(" §7• §r§lADD: §rDisable Fishing Rod Crafting Recipe");
|
||||
changes.push(" §7• §r§lFIX: §rCheck for Ban in AsyncPreLoginEvent");
|
||||
changes.push(" §7• §r§lFIX: §rOnly kick player after Entity isn't ticking anymore");
|
||||
changes.push(" §7• §r§lADD: §r/varo Command for Admins");
|
||||
changes.push(" §7• §r§lADD: §rBan Player on Death");
|
||||
changes.push(" §7• §r§lADD: §r1.8 Health Regeneration");
|
||||
changes.push(" §7• §r§lADD: §rCustom Dynamic ServerListEntry");
|
||||
changes.push(" §7• §r§lADD: §rControl Difficulty and Gamerules by the Plugin");
|
||||
changes.push(" §7• §r§lADD: §rHover over Playername for Details (Team)");
|
||||
changes.push(" §7• §r§lADD: §rRedesigned Chat with Timestamp");
|
||||
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!e.getPlayer().isOnline()) {
|
||||
this.cancel();
|
||||
return;
|
||||
}
|
||||
if (changes.empty()) {
|
||||
this.cancel();
|
||||
return;
|
||||
}
|
||||
e.getPlayer().sendMessage(changes.pop());
|
||||
}
|
||||
if (changes.empty()) {
|
||||
this.cancel();
|
||||
return;
|
||||
}
|
||||
e.getPlayer().sendMessage(changes.pop());
|
||||
}
|
||||
}.runTaskTimer(plugin, 20, 20);
|
||||
}.runTaskTimer(plugin, 20, 20);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler()
|
||||
@EventHandler
|
||||
public void onServerListPing(final ServerListPingEvent event) {
|
||||
if (event instanceof PaperServerListPingEvent) {
|
||||
handlePaperServerListPing((PaperServerListPingEvent) event);
|
||||
|
|
|
@ -9,6 +9,8 @@ import com.mojang.authlib.properties.Property;
|
|||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
|
||||
|
@ -18,7 +20,6 @@ import org.bukkit.scoreboard.Scoreboard;
|
|||
import org.bukkit.scoreboard.Team;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
|
||||
import org.json.simple.JSONValue;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
|
@ -31,17 +32,18 @@ import net.minecraft.server.v1_15_R1.MinecraftServer;
|
|||
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityDestroy;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityHeadRotation;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityMetadata;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityStatus;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayOutNamedEntitySpawn;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayOutPlayerInfo;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayOutPlayerInfo.EnumPlayerInfoAction;
|
||||
import net.minecraft.server.v1_15_R1.PlayerConnection;
|
||||
import net.minecraft.server.v1_15_R1.PlayerInteractManager;
|
||||
import net.minecraft.server.v1_15_R1.WorldServer;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayOutPlayerInfo.EnumPlayerInfoAction;
|
||||
|
||||
public class NPCManager {
|
||||
|
||||
private final Varo plugin;
|
||||
private final ArrayList<EntityPlayer> players = new ArrayList<EntityPlayer>();
|
||||
private final ArrayList<EntityPlayer> npcs = new ArrayList<EntityPlayer>();
|
||||
private Scoreboard scoreboard;
|
||||
private Team afkTeam;
|
||||
|
||||
|
@ -74,16 +76,18 @@ public class NPCManager {
|
|||
} catch (IOException | ParseException e) {
|
||||
plugin.getLogger().info(e.getMessage());
|
||||
}
|
||||
final EntityPlayer npc = new EntityPlayer(nmsServer, nmsWorld, gameProfile,
|
||||
new PlayerInteractManager(nmsWorld));
|
||||
final PlayerInteractManager playerInteractManager = new PlayerInteractManager(nmsWorld);
|
||||
final EntityPlayer npc = new EntityPlayer(nmsServer, nmsWorld, gameProfile, playerInteractManager);
|
||||
|
||||
npc.setLocation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
|
||||
npc.setHealth((float) player.getHealth());
|
||||
|
||||
if (shouldHaveAFKPrefix) {
|
||||
this.afkTeam.addEntry(npc.getName());
|
||||
}
|
||||
|
||||
players.add(npc);
|
||||
npcs.add(npc);
|
||||
|
||||
for (Player connectionPlayer : Bukkit.getOnlinePlayers()) {
|
||||
final PlayerConnection connection = ((CraftPlayer) connectionPlayer).getHandle().playerConnection;
|
||||
|
@ -105,7 +109,7 @@ public class NPCManager {
|
|||
}
|
||||
|
||||
public void syncClones(Player player) {
|
||||
for (EntityPlayer npc : this.players) {
|
||||
for (EntityPlayer npc : this.npcs) {
|
||||
final PlayerConnection connection = ((CraftPlayer) player).getHandle().playerConnection;
|
||||
connection.sendPacket(new PacketPlayOutPlayerInfo(EnumPlayerInfoAction.ADD_PLAYER, npc));
|
||||
connection.sendPacket(new PacketPlayOutNamedEntitySpawn(npc));
|
||||
|
@ -118,10 +122,50 @@ public class NPCManager {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isNPC(int id) {
|
||||
for (EntityPlayer npc : this.npcs) {
|
||||
if (npc.getId() == id)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addDamage(int id, double damage, boolean isCritical) {
|
||||
for (EntityPlayer npc : this.npcs) {
|
||||
if (npc.getId() == id) {
|
||||
npc.setHealth((float) (npc.getHealth() - damage));
|
||||
|
||||
World world = npc.getWorld().getWorld();
|
||||
Location loc = new Location(world, npc.locX(), npc.locY(), npc.locZ());
|
||||
if (npc.getHealth() > 0.0F) {
|
||||
for (Player connectionPlayer : Bukkit.getOnlinePlayers()) {
|
||||
final PlayerConnection connection = ((CraftPlayer) connectionPlayer)
|
||||
.getHandle().playerConnection;
|
||||
connection.sendPacket(new PacketPlayOutEntityStatus(npc, (byte) 2)); // Send HURT (2) Animation
|
||||
}
|
||||
world.playSound(loc, Sound.ENTITY_PLAYER_HURT, 1.0F, 1.0F);
|
||||
world.playSound(loc, Sound.ENTITY_PLAYER_ATTACK_STRONG, 1.0F, 1.0F);
|
||||
if (isCritical)
|
||||
world.playSound(loc, Sound.ENTITY_PLAYER_ATTACK_CRIT, 1.0F, 1.0F);
|
||||
} else {
|
||||
for (Player connectionPlayer : Bukkit.getOnlinePlayers()) {
|
||||
final PlayerConnection connection = ((CraftPlayer) connectionPlayer)
|
||||
.getHandle().playerConnection;
|
||||
connection.sendPacket(new PacketPlayOutEntityMetadata(npc.getId(), npc.getDataWatcher(), true));
|
||||
}
|
||||
if (isCritical)
|
||||
world.playSound(loc, Sound.ENTITY_PLAYER_ATTACK_CRIT, 1.0F, 1.0F);
|
||||
world.playSound(loc, Sound.ENTITY_PLAYER_DEATH, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void removeClone(Player player) {
|
||||
this.afkTeam.removeEntry(player.getName());
|
||||
for (int i = 0; i < this.players.size(); i++) {
|
||||
EntityPlayer npc = this.players.get(i);
|
||||
for (int i = 0; i < this.npcs.size(); i++) {
|
||||
EntityPlayer npc = this.npcs.get(i);
|
||||
if (npc.getUniqueID().equals(player.getUniqueId())) {
|
||||
final WorldServer nmsWorld = ((CraftWorld) player.getWorld()).getHandle();
|
||||
nmsWorld.removeEntity(npc);
|
||||
|
@ -130,7 +174,7 @@ public class NPCManager {
|
|||
final PlayerConnection connection = ((CraftPlayer) connectionPlayer).getHandle().playerConnection;
|
||||
connection.sendPacket(new PacketPlayOutEntityDestroy(npc.getId()));
|
||||
}
|
||||
this.players.remove(npc);
|
||||
this.npcs.remove(npc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,23 +1,37 @@
|
|||
package de.cliffbreak.varo.uitls;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import net.minecraft.server.v1_15_R1.Packet;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import de.cliffbreak.varo.Varo;
|
||||
import de.cliffbreak.varo.events.PlayerInteractNPCEvent;
|
||||
import de.cliffbreak.varo.events.PlayerInteractNPCEvent.Type;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import net.minecraft.server.v1_15_R1.AttributeModifier;
|
||||
import net.minecraft.server.v1_15_R1.EnumItemSlot;
|
||||
import net.minecraft.server.v1_15_R1.GenericAttributes;
|
||||
import net.minecraft.server.v1_15_R1.ItemStack;
|
||||
import net.minecraft.server.v1_15_R1.Packet;
|
||||
|
||||
public class PacketReader {
|
||||
|
||||
Player player;
|
||||
Channel channel;
|
||||
private Varo plugin;
|
||||
private Player player;
|
||||
private Channel channel;
|
||||
|
||||
public PacketReader(final Player player) {
|
||||
public PacketReader(final Varo plugin, final Player player) {
|
||||
this.plugin = plugin;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
|
@ -40,21 +54,57 @@ public class PacketReader {
|
|||
}
|
||||
}
|
||||
|
||||
// https://wiki.vg/Protocol#Interact_Entity
|
||||
public void readPacket(final Packet<?> packet) {
|
||||
if (packet.getClass().getSimpleName().equalsIgnoreCase("PacketPlayInUseEntity")) {
|
||||
final int id = (Integer) getValue(packet, "a");
|
||||
|
||||
System.out.println(getValue(packet, "action").toString());
|
||||
System.out.println(getValue(packet, "a").toString());
|
||||
int id = (int) getValue(packet, "a");
|
||||
if (!plugin.npcManager.isNPC(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if (Main.npc.getEntityID() == id) {
|
||||
// if (getValue(packet, "action").toString().equalsIgnoreCase("ATTACK")) {
|
||||
// Main.npc.animation(1);
|
||||
// } else if (getValue(packet, "action").toString().equalsIgnoreCase("INTERACT")) {
|
||||
|
||||
// }
|
||||
// }
|
||||
try {
|
||||
Type type = Type.valueOf(getValue(packet, "action").toString());
|
||||
PlayerInteractNPCEvent event = new PlayerInteractNPCEvent(type, id, calculateDamage(this.player),
|
||||
isCriticalHit(this.player));
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
} catch (Exception e) {
|
||||
// noop()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private double calculateDamage(Player player) {
|
||||
double damage = 1.0; // Default 1.0 Damage (by hand)
|
||||
ItemStack nmsItemStack = CraftItemStack.asNMSCopy(player.getInventory().getItemInMainHand());
|
||||
Collection<AttributeModifier> attributes = nmsItemStack.getItem().a(EnumItemSlot.MAINHAND)
|
||||
.get(GenericAttributes.ATTACK_DAMAGE.getName());
|
||||
|
||||
for (AttributeModifier am : attributes) {
|
||||
damage += am.getAmount();
|
||||
}
|
||||
|
||||
if (isCriticalHit(player)) {
|
||||
damage = damage * 1.5;
|
||||
}
|
||||
|
||||
damage = damage * player.getAttackCooldown();
|
||||
|
||||
Map<Enchantment, Integer> enchantments = player.getInventory().getItemInMainHand().getEnchantments();
|
||||
|
||||
for (Map.Entry<Enchantment, Integer> enchantment : enchantments.entrySet()) {
|
||||
// TODO: Add more enchantments?
|
||||
if (enchantment.getKey().equals(Enchantment.DAMAGE_ALL))
|
||||
damage += 0.5 * (enchantment.getValue() + 1);
|
||||
}
|
||||
return damage;
|
||||
}
|
||||
|
||||
private boolean isCriticalHit(Player player) {
|
||||
return player.getFallDistance() > 0.0F && !player.isOnGround() && !player.getLocation().getBlock().isLiquid()
|
||||
&& player.getPotionEffect(PotionEffectType.BLINDNESS) == null && player.getVehicle() == null
|
||||
&& !player.isSprinting() && player.getAttackCooldown() > 0.848F;
|
||||
}
|
||||
|
||||
public void setValue(final Object obj, final String name, final Object value) {
|
||||
|
|
Loading…
Reference in a new issue