@Override public boolean onLeftClickEntity(ItemStack stack, EntityPlayer player, Entity target) { if (target instanceof EntityLivingBase) { WorldUtils.playSoundAtEntity(player, Sounds.HAMMER, 0.4F, 0.5F); TargetUtils.knockTargetBack((EntityLivingBase) target, player); } return true; }
private boolean lootTarget(EntityPlayer player, EntityLivingBase target) { if (target.getEntityData().getBoolean("LootableEntityFlag")) { return false; } IEntityLootable lootable = (target instanceof IEntityLootable ? (IEntityLootable) target : null); float lootChance = (lootable != null ? lootable.getLootableChance(player, getType()) : LootableEntityRegistry.getEntityLootChance(target.getClass())); lootChance *= Config.getWhipLootMultiplier(); boolean wasItemStolen = false; if (rand.nextFloat() < lootChance) { ItemStack loot = (lootable != null ? lootable.getEntityLoot(player, getType()) : LootableEntityRegistry.getEntityLoot(target.getClass())); // TODO remove the following if Skulltulas are added: if (target instanceof EntitySpider && rand.nextInt(25) == 0) { loot = new ItemStack(ZSSItems.skulltulaToken); } if (loot != null) { EntityItem item = new EntityItem(worldObj, posX, posY + 1, posZ, loot); double dx = player.posX - posX; double dy = player.posY - posY; double dz = player.posZ - posZ; TargetUtils.setEntityHeading(item, dx, dy, dz, 1.0F, 1.0F, true); if (!worldObj.isRemote) { worldObj.spawnEntityInWorld(item); } player.triggerAchievement(ZSSAchievements.orcaThief); wasItemStolen = true; } } if (lootable == null || lootable.onLootStolen(player, wasItemStolen)) { if (!worldObj.isRemote) { target.getEntityData().setBoolean("LootableEntityFlag", true); } } return wasItemStolen; }
/** * Called when the shield blocks an attack when held in the normal fashion (i.e. non-BG2) used by * Deku Shield to damage / destroy the stack and by Mirror Shield to reflect projectiles * * @return Return the amount of damage remaining, if any; 0 cancels the hurt event */ public float onBlock(EntityPlayer player, ItemStack shield, DamageSource source, float damage) { ZSSPlayerInfo.get(player).onAttackBlocked(shield, damage); WorldUtils.playSoundAtEntity(player, Sounds.HAMMER, 0.4F, 0.5F); float damageBlocked = damage; if (toolMaterial == ToolMaterial.WOOD) { if (source.isProjectile() && !source.isExplosion() && source.getSourceOfDamage() instanceof IProjectile) { if (ZSSMain.isBG2Enabled && player.getHeldItem() == shield && shield.getItem() instanceof IArrowCatcher) { if (((IArrowCatcher) shield.getItem()) .catchArrow(shield, player, (IProjectile) source.getSourceOfDamage())) { ((InventoryPlayerBattle) player.inventory).hasChanged = true; } } } else if (source instanceof IDamageAoE && ((IDamageAoE) source).isAoEDamage()) { damageBlocked *= magicReduction; } int dmg = Math.round(source.isFireDamage() ? damage + 10.0F : damage - 2.0F); if (dmg > 0) { shield.damageItem(dmg, player); if (shield.stackSize <= 0) { ForgeEventFactory.onPlayerDestroyItem(player, shield); if (ZSSMain.isBG2Enabled && BattlegearUtils.isPlayerInBattlemode(player)) { BattlegearUtils.setPlayerOffhandItem(player, null); } else { player.destroyCurrentEquippedItem(); } } } } else if (toolMaterial == ToolMaterial.EMERALD) { if (source.isProjectile() && !source.isExplosion() && source.getSourceOfDamage() != null) { float chance = (source.isMagicDamage() ? (1F / 3F) : 1.0F); if (source.getSourceOfDamage() instanceof IReflectable) { ((IReflectable) source.getSourceOfDamage()) .getReflectChance(shield, player, source.getEntity()); } if (player.worldObj.rand.nextFloat() < chance) { Entity projectile = null; try { projectile = source .getSourceOfDamage() .getClass() .getConstructor(World.class) .newInstance(player.worldObj); } catch (Exception e) {; } if (projectile != null) { NBTTagCompound data = new NBTTagCompound(); source.getSourceOfDamage().writeToNBT(data); projectile.readFromNBT(data); projectile.getEntityData().setBoolean("isReflected", true); projectile.posX -= projectile.motionX; projectile.posY -= projectile.motionY; projectile.posZ -= projectile.motionZ; double motionX = (double) (-MathHelper.sin(player.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(player.rotationPitch / 180.0F * (float) Math.PI)); double motionZ = (double) (MathHelper.cos(player.rotationYaw / 180.0F * (float) Math.PI) * MathHelper.cos(player.rotationPitch / 180.0F * (float) Math.PI)); double motionY = (double) (-MathHelper.sin(player.rotationPitch / 180.0F * (float) Math.PI)); TargetUtils.setEntityHeading( projectile, motionX, motionY, motionZ, 1.0F, 2.0F + (20.0F * player.worldObj.rand.nextFloat()), false); if (projectile instanceof IReflectable) { ((IReflectable) projectile) .onReflected(shield, player, source.getEntity(), source.getSourceOfDamage()); } player.worldObj.spawnEntityInWorld(projectile); } } else if (source.isUnblockable() || (source instanceof IDamageAoE && ((IDamageAoE) source).isAoEDamage())) { // failed to reflect projectile damageBlocked *= magicReduction; } } } else if (source.isUnblockable() || (source instanceof IDamageAoE && ((IDamageAoE) source).isAoEDamage())) { damageBlocked *= magicReduction; // default shield behavior blocks half damage from AoE magic attacks } return (damage - damageBlocked); }
protected void swingThrower() { EntityLivingBase thrower = getThrower(); if (thrower != null && !thrower.onGround && isInGround()) { if (thrower.worldObj.isRemote) { // Determine the swing variables on first swing tick: float x = dataWatcher.getWatchableObjectFloat(HIT_POS_X); float y = dataWatcher.getWatchableObjectFloat(HIT_POS_Y); float z = dataWatcher.getWatchableObjectFloat(HIT_POS_Z); if (swingTicks == 0 && swingVec == null && thrower.motionY < 0) { swingVec = Vec3.createVectorHelper( (x - thrower.posX), y - (thrower.posY + thrower.getEyeHeight()), (z - thrower.posZ)) .normalize(); dy = (thrower.getDistance(x, y, z) / 7.0D); // lower divisor gives bigger change in y // calculate horizontal distance to find initial swing tick position // as distance approaches zero, swing ticks should approach ticks required / 2 // as distance approaches maxDistance, swing ticks should approach zero // this makes sure player's arc is even around pivot point double d = Math.min(thrower.getDistance(x, thrower.posY, z), getMaxDistance()); swingTicks = MathHelper.floor_double(((getMaxDistance() - d) / getMaxDistance()) * 8); } if (swingVec != null) { double sin = Math.sin(10.0D * swingTicks * Math.PI / 180.0D); double f = 0.8D; // arbitrary horizontal motion factor thrower.motionX = (sin * swingVec.xCoord * f); thrower.motionZ = (sin * swingVec.zCoord * f); // y motion needs to oscillate twice as quickly, so it goes up on the other side of the // swing thrower.motionY = dy * -Math.sin(20.0D * swingTicks * Math.PI / 180.0D); // check for horizontal collisions that should stop swinging motion MovingObjectPosition mop = TargetUtils.checkForImpact(worldObj, thrower, this, -(thrower.width / 4.0F), false); if (mop != null && mop.typeOfHit != MovingObjectType.MISS) { thrower.motionX = -thrower.motionX * 0.15D; thrower.motionY = -thrower.motionY * 0.15D; thrower.motionZ = -thrower.motionZ * 0.15D; swingVec = null; } ++swingTicks; // increment at end if (thrower.fallDistance > 0 && thrower.motionY < 0) { // 0.466885F seems to be roughly the amount added each tick while swinging; round for a // little extra server-side padding PacketDispatcher.sendToServer(new FallDistancePacket(thrower, -0.467F)); thrower.fallDistance -= 0.467F; } } else if (swingTicks > 0) { // still let player hang there after colliding, but move towards center if (thrower.getDistanceSq(x, thrower.posY, z) > 1.0D) { double dx = x - thrower.posX; double dz = z - thrower.posZ; thrower.motionX = 0.15D * dx; thrower.motionZ = 0.15D * dz; } if (thrower.posY < (y - (getMaxDistance() / 2.0D))) { thrower.motionY = 0; } ++swingTicks; // increment at end PacketDispatcher.sendToServer(new FallDistancePacket(thrower, 0.0F)); thrower.fallDistance = 0.0F; } } } }