Working block breaker

This commit is contained in:
fullwall 2013-02-17 21:47:20 +08:00
parent 968d325a15
commit 121bdbd9c4
2 changed files with 88 additions and 61 deletions

View File

@ -217,8 +217,9 @@ public class EventListen implements Listener {
@EventHandler @EventHandler
public void onPlayerInteractEntity(PlayerInteractEntityEvent event) { public void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
NPC npc = npcRegistry.getNPC(event.getRightClicked()); NPC npc = npcRegistry.getNPC(event.getRightClicked());
if (npc == null) if (npc == null) {
return; return;
}
Player player = event.getPlayer(); Player player = event.getPlayer();

View File

@ -1,92 +1,118 @@
package net.citizensnpcs.npc.ai; 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.Block;
import net.minecraft.server.v1_4_R1.Enchantment; import net.minecraft.server.v1_4_R1.Enchantment;
import net.minecraft.server.v1_4_R1.EnchantmentManager; 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.EntityLiving;
import net.minecraft.server.v1_4_R1.EntityPlayer;
import net.minecraft.server.v1_4_R1.ItemStack; import net.minecraft.server.v1_4_R1.ItemStack;
import net.minecraft.server.v1_4_R1.Material; import net.minecraft.server.v1_4_R1.Material;
import net.minecraft.server.v1_4_R1.MobEffectList; import net.minecraft.server.v1_4_R1.MobEffectList;
public class BlockBreaker { import org.bukkit.craftbukkit.v1_4_R1.entity.CraftLivingEntity;
private EntityLiving entity; import org.bukkit.craftbukkit.v1_4_R1.inventory.CraftItemStack;
private ItemStack in; import org.bukkit.entity.LivingEntity;
private int lastDigTick, currentTick; 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()) { if (block.material.isAlwaysDestroyable()) {
return true; return true;
} else { } 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) { @Override
if (true) { public void run() {
entity.world.douseFire(null, i, j, k, l); if (!isDigging) {
lastDigTick = currentTick; cancel();
float f = 1.0F; return;
int i1 = entity.world.getTypeId(i, j, k); }
if (i1 > 0) { if (entity instanceof EntityPlayer)
Block.byId[i1].attack(entity.world, i, j, k, null); PlayerAnimation.ARM_SWING.play((Player) entity.getBukkitEntity());
// Allow fire punching to be blocked currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit
entity.world.douseFire((EntityHuman) null, i, j, k, l); 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) { int modifiedDamage = (int) (damage * 10.0F);
f = getStr(Block.byId[i1]); 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 { } else {
// this.d = true; strength += levelSquared;
// 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;
} }
} }
}
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)) { 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)) { 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)) { if (entity.a(Material.WATER) && !EnchantmentManager.hasWaterWorkerEnchantment(entity)) {
f /= 5.0F; strength /= 5.0F;
} }
if (!entity.onGround) { if (!entity.onGround) {
f /= 5.0F; strength /= 5.0F;
} }
return strength;
return f;
} }
} }