From 121bdbd9c4ac7ef355b05139a91e8b2d80c70c36 Mon Sep 17 00:00:00 2001 From: fullwall Date: Sun, 17 Feb 2013 21:47:20 +0800 Subject: [PATCH] Working block breaker --- .../java/net/citizensnpcs/EventListen.java | 3 +- .../net/citizensnpcs/npc/ai/BlockBreaker.java | 146 +++++++++++------- 2 files changed, 88 insertions(+), 61 deletions(-) diff --git a/src/main/java/net/citizensnpcs/EventListen.java b/src/main/java/net/citizensnpcs/EventListen.java index 74d73ab96..028391045 100644 --- a/src/main/java/net/citizensnpcs/EventListen.java +++ b/src/main/java/net/citizensnpcs/EventListen.java @@ -217,8 +217,9 @@ public class EventListen implements Listener { @EventHandler public void onPlayerInteractEntity(PlayerInteractEntityEvent event) { NPC npc = npcRegistry.getNPC(event.getRightClicked()); - if (npc == null) + if (npc == null) { return; + } Player player = event.getPlayer(); diff --git a/src/main/java/net/citizensnpcs/npc/ai/BlockBreaker.java b/src/main/java/net/citizensnpcs/npc/ai/BlockBreaker.java index cb010c114..702039481 100644 --- a/src/main/java/net/citizensnpcs/npc/ai/BlockBreaker.java +++ b/src/main/java/net/citizensnpcs/npc/ai/BlockBreaker.java @@ -1,92 +1,118 @@ package net.citizensnpcs.npc.ai; +import net.citizensnpcs.util.PlayerAnimation; import net.minecraft.server.v1_4_R1.Block; import net.minecraft.server.v1_4_R1.Enchantment; import net.minecraft.server.v1_4_R1.EnchantmentManager; -import net.minecraft.server.v1_4_R1.EntityHuman; import net.minecraft.server.v1_4_R1.EntityLiving; +import net.minecraft.server.v1_4_R1.EntityPlayer; import net.minecraft.server.v1_4_R1.ItemStack; import net.minecraft.server.v1_4_R1.Material; import net.minecraft.server.v1_4_R1.MobEffectList; -public class BlockBreaker { - private EntityLiving entity; - private ItemStack in; - private int lastDigTick, currentTick; +import org.bukkit.craftbukkit.v1_4_R1.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.v1_4_R1.inventory.CraftItemStack; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; - public boolean destroyable(Block block) { +public class BlockBreaker implements Runnable { + private int currentDamage; + private int currentTick; + private final EntityLiving entity; + private boolean isDigging; + private final int startDigTick; + private final int x, y, z; + + public BlockBreaker(LivingEntity entity, org.bukkit.block.Block target) { + this.entity = ((CraftLivingEntity) entity).getHandle(); + this.x = target.getX(); + this.y = target.getY(); + this.z = target.getZ(); + this.startDigTick = (int) (System.currentTimeMillis() / 50); + } + + public void cancel() { + isDigging = false; + currentDamage = -1; + entity.world.g(entity.id, x, y, z, -1); + } + + private net.minecraft.server.v1_4_R1.ItemStack getCurrentItem() { + return entity.getEquipment(0); + } + + private float getStrength(Block block) { + float base = block.m(null, 0, 0, 0); + return base < 0.0F ? 0.0F : (!isDestroyable(block) ? 1.0F / base / 100.0F : strengthMod(block) / base / 30.0F); + } + + private boolean isDestroyable(Block block) { if (block.material.isAlwaysDestroyable()) { return true; } else { - return in != null ? in.b(block) : false; + ItemStack current = getCurrentItem(); + return current != null ? current.b(block) : false; } } - public void dig(int i, int j, int k, int l) { - if (true) { - entity.world.douseFire(null, i, j, k, l); - lastDigTick = currentTick; - float f = 1.0F; - int i1 = entity.world.getTypeId(i, j, k); - if (i1 > 0) { - Block.byId[i1].attack(entity.world, i, j, k, null); - // Allow fire punching to be blocked - entity.world.douseFire((EntityHuman) null, i, j, k, l); + @Override + public void run() { + if (!isDigging) { + cancel(); + return; + } + if (entity instanceof EntityPlayer) + PlayerAnimation.ARM_SWING.play((Player) entity.getBukkitEntity()); + currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit + Block block = Block.byId[entity.world.getTypeId(x, y, z)]; + if (block == null) { + cancel(); + } else { + int tickDifference = currentTick - startDigTick; + float damage = getStrength(block) * (tickDifference + 1); + if (damage >= 1F) { + entity.world.getWorld().getBlockAt(x, y, z) + .breakNaturally(CraftItemStack.asCraftMirror(getCurrentItem())); + cancel(); } - if (i1 > 0) { - f = getStr(Block.byId[i1]); + int modifiedDamage = (int) (damage * 10.0F); + if (modifiedDamage != currentDamage) { + setBlockDamage(modifiedDamage); + currentDamage = modifiedDamage; } - EntityHuman m; - if (i1 > 0 && f >= 1.0F) { - // this.breakBlock(i, j, k); + } + } + + private void setBlockDamage(int modifiedDamage) { + entity.world.g(entity.id, x, y, z, modifiedDamage); + } + + private float strengthMod(Block block) { + ItemStack itemstack = getCurrentItem(); + float strength = itemstack != null ? itemstack.a(block) : 1; + int ench = EnchantmentManager.getEnchantmentLevel(Enchantment.DURABILITY.id, getCurrentItem()); + + if (ench > 0 && itemstack != null) { + float levelSquared = ench * ench + 1; + + if (!itemstack.b(block) && strength <= 1.0F) { + strength += levelSquared * 0.08F; } else { - // this.d = true; - // this.f = i; - // this.g = j; - // this.h = k; - int j1 = (int) (f * 10.0F); - entity.world.g(entity.id, i, j, k, j1); - // entity.o = j1; + strength += levelSquared; } } - } - - public float getStr(Block block) { - float base = block.m(null, 0, 0, 0); - return base < 0.0F ? 0.0F : (!destroyable(block) ? 1.0F / base / 100.0F : strengthMod(block) / base / 30.0F); - } - - public float strengthMod(Block block) { - float f = in.a(block); - int i = EnchantmentManager.getEnchantmentLevel(Enchantment.DURABILITY.id, in); - ItemStack itemstack = in; - - if (i > 0 && itemstack != null) { - float f1 = i * i + 1; - - if (!itemstack.b(block) && f <= 1.0F) { - f += f1 * 0.08F; - } else { - f += f1; - } - } - if (entity.hasEffect(MobEffectList.FASTER_DIG)) { - f *= 1.0F + (entity.getEffect(MobEffectList.FASTER_DIG).getAmplifier() + 1) * 0.2F; + strength *= 1.0F + (entity.getEffect(MobEffectList.FASTER_DIG).getAmplifier() + 1) * 0.2F; } - if (entity.hasEffect(MobEffectList.SLOWER_DIG)) { - f *= 1.0F - (entity.getEffect(MobEffectList.SLOWER_DIG).getAmplifier() + 1) * 0.2F; + strength *= 1.0F - (entity.getEffect(MobEffectList.SLOWER_DIG).getAmplifier() + 1) * 0.2F; } - if (entity.a(Material.WATER) && !EnchantmentManager.hasWaterWorkerEnchantment(entity)) { - f /= 5.0F; + strength /= 5.0F; } - if (!entity.onGround) { - f /= 5.0F; + strength /= 5.0F; } - - return f; + return strength; } } \ No newline at end of file