private boolean canBreakAt(World world, int x, int y, int z) {
   if (y < 0) return false;
   if (y > 255) return false;
   if (y == 0 && !ConfigRegistry.VOIDHOLE.getState()) return false;
   return world.isRemote
       || ReikaPlayerAPI.playerCanBreakAt((WorldServer) world, x, y, z, this.getServerPlacer());
 }
 public boolean givePlayerRecipe(EntityPlayer ep, CastingRecipe cr) {
   if (!this.playerHasUsedRecipe(ep, cr)) {
     this.getNBTRecipes(ep).appendTag(new NBTTagInt(cr.getIDCode()));
     if (ep instanceof EntityPlayerMP) ReikaPlayerAPI.syncCustomData((EntityPlayerMP) ep);
     return true;
   }
   return false;
 }
 public boolean setPlayerResearchLevel(EntityPlayer ep, ResearchLevel r, boolean notify) {
   if (r.movePlayerTo(ep)) {
     if (ep instanceof EntityPlayerMP) ReikaPlayerAPI.syncCustomData((EntityPlayerMP) ep);
     if (notify) this.notifyPlayerOfProgression(ep, r);
     ProgressionCacher.instance.updateProgressCache(ep);
     return true;
   }
   return false;
 }
 public void maxPlayerResearch(EntityPlayer ep, boolean notify) {
   this.setPlayerResearchLevel(
       ep, ResearchLevel.levelList[ResearchLevel.levelList.length - 1], notify);
   for (ChromaResearch r : ChromaResearch.getAllObtainableFragments()) {
     this.givePlayerFragment(ep, r, notify);
   }
   for (CastingRecipe r : RecipesCastingTable.instance.getAllRecipes()) {
     this.givePlayerRecipe(ep, r);
   }
   if (ep instanceof EntityPlayerMP) ReikaPlayerAPI.syncCustomData((EntityPlayerMP) ep);
 }
 public boolean givePlayerFragment(EntityPlayer ep, ChromaResearch r, boolean notify) {
   if (!this.playerHasFragment(ep, r)) {
     this.getNBTFragments(ep).appendTag(new NBTTagString(r.name()));
     this.checkForUpgrade(ep);
     if (ep instanceof EntityPlayerMP) ReikaPlayerAPI.syncCustomData((EntityPlayerMP) ep);
     if (notify) this.notifyPlayerOfProgression(ep, r);
     ProgressionCacher.instance.updateProgressCache(ep);
     MinecraftForge.EVENT_BUS.post(new ProgressionEvent(ep, r.name(), ResearchType.FRAGMENT));
     return true;
   }
   return false;
 }
 public boolean removePlayerFragment(EntityPlayer ep, ChromaResearch r, boolean notify) {
   if (this.playerHasFragment(ep, r)) {
     NBTTagList li = this.getNBTFragments(ep);
     Iterator<NBTTagString> it = li.tagList.iterator();
     while (it.hasNext()) {
       NBTTagString s = it.next();
       if (s.func_150285_a_().equals(r.name())) it.remove();
     }
     if (ep instanceof EntityPlayerMP) ReikaPlayerAPI.syncCustomData((EntityPlayerMP) ep);
     ProgressionCacher.instance.updateProgressCache(ep);
     return true;
   }
   return false;
 }
 @Override
 public boolean attackEntityFrom(DamageSource src, float dmg) {
   Entity e = src.getEntity();
   if (e instanceof EntityPlayer) {
     if (!ReikaPlayerAPI.isFake((EntityPlayer) e)) {
       boolean flag = super.attackEntityFrom(src, dmg);
       if (flag && this.getHealth() <= 0) {
         this.die();
       }
       return flag;
     }
   }
   return false;
 }
  @Override
  public ItemStack onItemRightClick(ItemStack is, World world, EntityPlayer ep) {
    if (!world.isRemote && this.getWater(is) < CAPACITY) {
      MovingObjectPosition mov = ReikaPlayerAPI.getLookedAtBlock(ep, 5, true);
      if (mov != null) {
        int x = mov.blockX;
        int y = mov.blockY;
        int z = mov.blockZ;
        Block id = world.getBlock(x, y, z);
        if (id == Blocks.water && ReikaWorldHelper.isLiquidSourceBlock(world, x, y, z)) {
          this.addWater(is, 1000);
          world.setBlock(x, y, z, Blocks.air);
          return is;
        }
      }
    }

    ep.setItemInUse(is, this.getMaxItemUseDuration(is));

    return is;
  }
  @Override
  public void onDeath(DamageSource src) {
    ChromaSounds.DISCHARGE.playSound(this, 1F, 2F);
    if (!worldObj.isRemote) {
      Entity e = src.getEntity();
      if (e instanceof EntityPlayer) {
        EntityPlayer ep = (EntityPlayer) e;
        if (doDrops && !ReikaPlayerAPI.isFakeOrNotInteractable(ep, posX, posY, posZ, 8)) {
          int looting = EnchantmentHelper.getLootingModifier((EntityPlayer) src.getEntity());
          ReikaItemHelper.dropItem(
              this,
              ReikaItemHelper.getSizedItemStack(
                  ChromaStacks.beaconDust, rand.nextInt(1 + looting * 2)));
          if (looting > 1) {
            if (color.isPrimary()) ReikaItemHelper.dropItem(this, ChromaStacks.purityDust);
            else ReikaItemHelper.dropItem(this, ChromaStacks.auraDust);
          }
        }
        ProgressStage.BALLLIGHTNING.stepPlayerTo(ep);
      }

      this.sendDeathParticles();
    }
  }
 private NBTTagCompound getNBT(EntityPlayer ep) {
   NBTTagCompound nbt = ReikaPlayerAPI.getDeathPersistentNBT(ep);
   if (!nbt.hasKey(NBT_TAG)) nbt.setTag(NBT_TAG, new NBTTagCompound());
   NBTTagCompound li = nbt.getCompoundTag(NBT_TAG);
   return li;
 }
 public void resetPlayerResearch(EntityPlayer ep, boolean notify) {
   ReikaPlayerAPI.getDeathPersistentNBT(ep).removeTag(NBT_TAG);
   if (ep instanceof EntityPlayerMP) ReikaPlayerAPI.syncCustomData((EntityPlayerMP) ep);
 }
  @Override
  public ItemStack onItemRightClick(ItemStack is, World world, EntityPlayer ep) {
    if (is.getItemDamage() <= 0) {
      this.noCharge();
      return is;
    }
    this.warnCharge(is);
    if (!ReikaPlayerAPI.playerHasOrIsCreative(ep, Block.gravel.blockID, -1)) {
      if (!world.isRemote) world.playAuxSFX(1001, (int) ep.posX, (int) ep.posY, (int) ep.posZ, 1);
      return is;
    }
    for (float i = 1; i <= 128; i += 0.5) {
      Vec3 look = ep.getLookVec();
      double[] looks = ReikaVectorHelper.getPlayerLookCoords(ep, i);
      AxisAlignedBB fov =
          AxisAlignedBB.getBoundingBox(
              looks[0] - 0.5,
              looks[1] - 0.5,
              looks[2] - 0.5,
              looks[0] + 0.5,
              looks[1] + 0.5,
              looks[2] + 0.5);
      List infov = world.getEntitiesWithinAABB(EntityLivingBase.class, fov);
      for (int k = 0; k < infov.size(); k++) {
        EntityLivingBase ent = (EntityLivingBase) infov.get(k);
        if (!ep.equals(ent)
            && this.isEntityAttackable(ent)
            && ReikaWorldHelper.lineOfSight(world, ep, ent)) {
          double dist =
              ReikaMathLibrary.py3d(ep.posX - ent.posX, ep.posY - ent.posY, ep.posZ - ent.posZ);
          double x = ep.posX + look.xCoord;
          double y = ep.posY + ep.getEyeHeight() + look.yCoord;
          double z = ep.posZ + look.zCoord;
          double dx = ent.posX - ep.posX;
          double dy = ent.posY - ep.posY;
          double dz = ent.posZ - ep.posZ;
          if (!world.isRemote) {
            ItemStack fl = new ItemStack(Item.flint);
            EntityItem ei =
                new EntityItem(
                    world,
                    look.xCoord / look.lengthVector() + ep.posX,
                    look.yCoord / look.lengthVector() + ep.posY,
                    look.zCoord / look.lengthVector() + ep.posZ,
                    fl);
            ei.delayBeforeCanPickup = 100;
            ei.motionX = dx;
            ei.motionY = dy + 1;
            ei.motionZ = dz;
            // ReikaChatHelper.writeCoords(world, ei.posX, ei.posY, ei.posZ);
            ei.velocityChanged = true;
            world.playSoundAtEntity(ep, "dig.gravel", 1.5F, 2F);
            ei.lifespan = 5;
            world.spawnEntityInWorld(ei);

            if (is.getItemDamage() > 4096) { // approx the 1-hit kill of a 10-heart mob
              // ReikaPacketHelper.sendUpdatePacket(RotaryCraft.packetChannel,
              // PacketRegistry.GRAVELGUN.getMinValue(), world, (int)ent.posX, (int)ent.posY,
              // (int)ent.posZ);
              // world.playSoundAtEntity(ep, "random.explode", 0.25F, 1F);
            }
            if (ent instanceof EntityDragon) {
              EntityDragon ed = (EntityDragon) ent;
              ed.attackEntityFromPart(
                  ed.dragonPartBody, DamageSource.causePlayerDamage(ep), this.getAttackDamage(is));
            } else {
              int dmg = this.getAttackDamage(is);
              if (ent instanceof EntityPlayer) {
                for (int n = 1; n < 5; n++) {
                  ItemRegistry ir = ItemRegistry.getEntry(ent.getCurrentItemOrArmor(n));
                  if (ir != null) {
                    if (ir.isBedrockArmor()) dmg *= 0.75;
                  }
                }
              }
              ent.attackEntityFrom(DamageSource.causePlayerDamage(ep), dmg);
              if (dmg >= 500) RotaryAchievements.MASSIVEHIT.triggerAchievement(ep);
            }
            if (ent instanceof EntityMob
                && (ent.isDead || ent.getHealth() <= 0)
                && ReikaMathLibrary.py3d(ep.posX - ent.posX, ep.posY - ent.posY, ep.posZ - ent.posZ)
                    >= 80) RotaryAchievements.GRAVELGUN.triggerAchievement(ep);
          }
          // ReikaWorldHelper.spawnParticleLine(world, x, y, z, ent.posX, ent.posY+ent.height/2,
          // ent.posZ, "crit", 0, 0, 0, 60);
          for (float t = 0; t < 2; t += 0.05F)
            world.spawnParticle("crit", x, y, z, dx / dist * t, dy / dist * t, dz / dist * t);
        }
      }
      if (infov.size() > 0 && !(infov.size() == 1 && infov.get(0) instanceof EntityPlayer)) {
        if (!ep.capabilities.isCreativeMode)
          ReikaInventoryHelper.findAndDecrStack(
              Block.gravel.blockID, -1, ep.inventory.mainInventory);
        return new ItemStack(is.itemID, is.stackSize, is.getItemDamage() - 1);
      }
    }
    return is;
  }
 private static boolean hasPlayer(PlayerTracker pt, EntityPlayer ep) {
   String tag = BASE_TAG + pt.getID();
   return ReikaPlayerAPI.getDeathPersistentNBT(ep).getBoolean(tag);
 }
 private static void addPlayer(PlayerTracker pt, EntityPlayer ep) {
   String tag = BASE_TAG + pt.getID();
   ReikaPlayerAPI.getDeathPersistentNBT(ep).setBoolean(tag, true);
 }