/** * 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); }
@Override public void updateWeather() { super.updateWeather(); if (!this.worldObj.isRemote) { if (this.dataNotLoaded) { this.savefile = OrbitSpinSaveData.initWorldData(this.worldObj); this.readFromNBT(this.savefile.datacompound); if (ConfigManagerCore.enableDebug) System.out.println( "Loading data from save: " + this.savefile.datacompound.getFloat("omegaSky")); this.dataNotLoaded = false; } if (this.doSpinning) { boolean updateNeeded = true; if (this.angularVelocityTarget < this.angularVelocityRadians) { float newAngle = this.angularVelocityRadians - this.angularVelocityAccel; if (newAngle < this.angularVelocityTarget) { newAngle = this.angularVelocityTarget; } this.setSpinRate(newAngle); this.thrustersFiring = true; } else if (this.angularVelocityTarget > this.angularVelocityRadians) { float newAngle = this.angularVelocityRadians + this.angularVelocityAccel; if (newAngle > this.angularVelocityTarget) { newAngle = this.angularVelocityTarget; } this.setSpinRate(newAngle); this.thrustersFiring = true; } else if (this.thrustersFiring) { this.thrustersFiring = false; } else { updateNeeded = false; } if (updateNeeded) { this.writeToNBT(this.savefile.datacompound); this.savefile.markDirty(); List<Object> objList = new ArrayList<Object>(); objList.add(Float.valueOf(this.angularVelocityRadians)); objList.add(Boolean.valueOf(this.thrustersFiring)); GalacticraftCore.packetPipeline.sendToDimension( new PacketSimple(EnumSimplePacket.C_UPDATE_STATION_SPIN, objList), this.spaceStationDimensionID); } // Update entity positions if in freefall this.loadedEntities.clear(); this.loadedEntities.addAll(this.worldObj.loadedEntityList); for (Entity e : this.loadedEntities) { if ((e instanceof EntityItem || e instanceof EntityLivingBase && !(e instanceof EntityPlayer) || e instanceof EntityTNTPrimed || e instanceof EntityFallingBlock) && !e.onGround) { boolean freefall = true; if (e.boundingBox.maxX >= this.ssBoundsMinX && e.boundingBox.minX <= this.ssBoundsMaxX && e.boundingBox.maxY >= this.ssBoundsMinY && e.boundingBox.minY <= this.ssBoundsMaxY && e.boundingBox.maxZ >= this.ssBoundsMinZ && e.boundingBox.minZ <= this.ssBoundsMaxZ) { // Entity is somewhere within the space station boundaries // Check if the entity's bounding box is in the same block coordinates as any // non-vacuum block (including torches etc) // If so, it's assumed the entity has something close enough to catch onto, so is not // in freefall // Note: breatheable air here means the entity is definitely not in freefall int xmx = MathHelper.floor_double(e.boundingBox.maxX + 0.2D); int ym = MathHelper.floor_double(e.boundingBox.minY - 0.1D); int yy = MathHelper.floor_double(e.boundingBox.maxY + 0.1D); int zm = MathHelper.floor_double(e.boundingBox.minZ - 0.2D); int zz = MathHelper.floor_double(e.boundingBox.maxZ + 0.2D); BLOCKCHECK: for (int x = MathHelper.floor_double(e.boundingBox.minX - 0.2D); x <= xmx; x++) { for (int y = ym; y <= yy; y++) { for (int z = zm; z <= zz; z++) { if (this.worldObj.blockExists(x, y, z) && this.worldObj.getBlock(x, y, z) != Blocks.air) { freefall = false; break BLOCKCHECK; } } } } } if (freefall) { // Do the rotation if (this.angularVelocityRadians != 0F) { float angle; final double xx = e.posX - this.spinCentreX; final double zz = e.posZ - this.spinCentreZ; double arc = Math.sqrt(xx * xx + zz * zz); if (xx == 0D) { angle = zz > 0 ? 3.141592536F / 2 : -3.141592536F / 2; } else { angle = (float) Math.atan(zz / xx); } if (xx < 0D) { angle += 3.141592536F; } angle += this.angularVelocityRadians / 3F; arc = arc * this.angularVelocityRadians; final double offsetX = -arc * MathHelper.sin(angle); final double offsetZ = arc * MathHelper.cos(angle); e.posX += offsetX; e.posZ += offsetZ; e.lastTickPosX += offsetX; e.lastTickPosZ += offsetZ; // Rotated into an unloaded chunk (probably also drifted out to there): byebye if (!this.worldObj.blockExists( MathHelper.floor_double(e.posX), 64, MathHelper.floor_double(e.posZ))) { e.setDead(); } e.boundingBox.offset(offsetX, 0.0D, offsetZ); // TODO check for block collisions here - if so move the entity appropriately and // apply fall damage // Moving the entity = slide along / down e.rotationYaw += this.skyAngularVelocity; while (e.rotationYaw > 360F) { e.rotationYaw -= 360F; } } // Undo deceleration if (e instanceof EntityLivingBase) { e.motionX /= 0.91F; e.motionZ /= 0.91F; if (e instanceof EntityFlying) { e.motionY /= 0.91F; } else if (e instanceof EntityFallingBlock) { e.motionY /= 0.9800000190734863D; // e.motionY += 0.03999999910593033D; // e.posY += 0.03999999910593033D; // e.lastTickPosY += 0.03999999910593033D; } else { e.motionY /= 0.9800000190734863D; } } else { e.motionX /= 0.9800000190734863D; e.motionY /= 0.9800000190734863D; e.motionZ /= 0.9800000190734863D; } } } } } } }