/**
   * Called when the player Left Clicks (attacks) an entity. Processed before damage is done, if
   * return value is true further processing is canceled and the entity is not attacked.
   * ■左クリックでEntityを殴ると呼ばれる。 (return : 相手にダメージを [true = 与えない : false = 与える])
   *
   * @param stack The Item being used
   * @param player The player that is attacking
   * @param entity The entity being attacked
   * @return True to cancel the rest of the interaction.
   */
  @Override
  public boolean onLeftClickEntity(ItemStack stackIn, EntityPlayer player, Entity entity) {
    // ■相手に傷をつける(DataWatcherに情報を刻む)
    if (entity instanceof EntityDragonPart) {
      // ■DragonPartからDragonを取得
      entity = (Entity) ((EntityDragonPart) entity).entityDragonObj;
    }
    DataWatcher dw = entity.getDataWatcher();

    int countHit = getHitCount(dw);

    // ■情報を刻む
    dw.updateObject(Hizume.getDWID(), ++countHit);

    // TODO
    if (!player.worldObj.isRemote) {
      // System.out.println("Entity = " + entity.getName() + " : Scars!");
    }

    return false;
  }
  private void spawnEntity(FMLMessage.EntitySpawnMessage spawnMsg) {
    ModContainer mc = Loader.instance().getIndexedModList().get(spawnMsg.modId);
    EntityRegistration er = EntityRegistry.instance().lookupModSpawn(mc, spawnMsg.modEntityTypeId);
    WorldClient wc = FMLClientHandler.instance().getWorldClient();
    Class<? extends Entity> cls = er.getEntityClass();
    try {
      Entity entity;
      if (er.hasCustomSpawning()) {
        entity = er.doCustomSpawning(spawnMsg);
      } else {
        entity = (Entity) (cls.getConstructor(World.class).newInstance(wc));

        int offset = spawnMsg.entityId - entity.getEntityId();
        entity.setEntityId(spawnMsg.entityId);
        entity.setLocationAndAngles(
            spawnMsg.scaledX,
            spawnMsg.scaledY,
            spawnMsg.scaledZ,
            spawnMsg.scaledYaw,
            spawnMsg.scaledPitch);
        if (entity instanceof EntityLiving) {
          ((EntityLiving) entity).rotationYawHead = spawnMsg.scaledHeadYaw;
        }

        Entity parts[] = entity.getParts();
        if (parts != null) {
          for (int j = 0; j < parts.length; j++) {
            parts[j].setEntityId(parts[j].getEntityId() + offset);
          }
        }
      }

      entity.serverPosX = spawnMsg.rawX;
      entity.serverPosY = spawnMsg.rawY;
      entity.serverPosZ = spawnMsg.rawZ;

      EntityClientPlayerMP clientPlayer = FMLClientHandler.instance().getClientPlayerEntity();
      if (entity instanceof IThrowableEntity) {
        Entity thrower =
            clientPlayer.getEntityId() == spawnMsg.throwerId
                ? clientPlayer
                : wc.getEntityByID(spawnMsg.throwerId);
        ((IThrowableEntity) entity).setThrower(thrower);
      }

      if (spawnMsg.dataWatcherList != null) {
        entity.getDataWatcher().updateWatchedObjectsFromList((List<?>) spawnMsg.dataWatcherList);
      }

      if (spawnMsg.throwerId > 0) {
        entity.setVelocity(spawnMsg.speedScaledX, spawnMsg.speedScaledY, spawnMsg.speedScaledZ);
      }

      if (entity instanceof IEntityAdditionalSpawnData) {
        ((IEntityAdditionalSpawnData) entity).readSpawnData(spawnMsg.dataStream);
      }
      wc.addEntityToWorld(spawnMsg.entityId, entity);
    } catch (Exception e) {
      FMLLog.log(Level.ERROR, e, "A severe problem occurred during the spawning of an entity");
      throw Throwables.propagate(e);
    }
  }
  /**
   * ■相手の傷を開く(クライアント側のみ)
   *
   * @param stackIn
   * @param playerIn
   */
  protected Entity doScars(ItemStack stackIn, EntityPlayer playerIn) {
    Entity target = null;

    boolean isSoundSE = false;

    // ■クライアント側で検出する
    List<MovingObjectPosition> mops = Hizume.proxy.getEntity(stackIn, playerIn);

    // ■モップにEntityが引っかかってる
    // if (mop != null && mop.typeOfHit == MovingObjectPosition.MovingObjectType.ENTITY)
    if (mops != null && !mops.isEmpty()) {
      for (MovingObjectPosition mop : mops) {
        // ■対象Entityを取得
        target = mop.entityHit;
        if (target == null) {
          continue;
        }

        // ■EntitySOWはこちら
        if (target instanceof EntitySOW) {
          // ■接触しているEntityをかき集める
          List<Entity> entities =
              playerIn.worldObj.getEntitiesWithinAABBExcludingEntity(
                  target, target.getEntityBoundingBox());
          if (entities == null || entities.isEmpty()) {
            continue;
          }

          for (Entity entity : entities) {
            // ■ドラゴン(概念)はスルー
            if (entity instanceof EntityDragon) {
              continue;
            }

            // ■生物系のみ
            if (!(entity instanceof EntityLivingBase) && !(entity instanceof EntityDragonPart)) {
              continue;
            }

            // ■爪痕をつけた本人
            if (entity.equals(playerIn)) {
              continue;
            }

            // ■1体でも接触していれば傷が開く
            // ▼サーバ側
            PacketHandler.INSTANCE.sendToServer(new MessageOpenSOW(target, false));

            // ▼クライアント側
            ((EntitySOW) target).changeScarsState();

            // ■効果音ならすよー
            isSoundSE = true;

            break;
          }
        }
        // ■EntityLivingBase等はこちら
        else {
          DataWatcher dw;
          if (target instanceof EntityDragonPart) {
            // target = ((Entity)((EntityDragonPart)target).entityDragonObj);
            // ■EnderDragonの傷は本体に蓄積してるので、そっちから取得
            dw = ((Entity) ((EntityDragonPart) target).entityDragonObj).getDataWatcher();
          } else {
            dw = target.getDataWatcher();
          }

          // ■対象Entityの傷を開く
          int nHit = this.getHitCount(dw);
          if (nHit > 0) {
            // ■総ダメージ
            float damage = attackDamage2 * (float) nHit;
            // ■サーバへメッセージ
            PacketHandler.INSTANCE.sendToServer(new MessageScars(target, damage));
            // ■傷は開いたのでリセット
            this.setHitCount(dw, 0);

            // ■効果音ならすよー
            isSoundSE = true;
          }

          // ■Entityに接触しているSOWを開く
          List<Entity> entities = playerIn.worldObj.weatherEffects;
          if (entities == null || entities.isEmpty()) {
            continue;
          }

          for (Entity entity : entities) {
            if (entity instanceof EntitySOW) {
              EntitySOW sow = (EntitySOW) entity;
              if (sow.getEntityBoundingBox().intersectsWith(target.getEntityBoundingBox())) {
                // ■重なってるので炸裂
                // ▼サーバ側
                PacketHandler.INSTANCE.sendToServer(new MessageOpenSOW(sow, false));

                // ▼クライアント側
                sow.changeScarsState();

                // ■効果音ならすよー
                isSoundSE = true;
              }
            }
          }
        }
      }
    }

    if (isSoundSE) {
      // playerIn.worldObj.playSoundAtEntity(playerIn, Hizume.MOD_ID + ":shan", 1.0f, 3.0f);
      PacketHandler.INSTANCE.sendToServer(new MessageOpenSOW(playerIn, true));
    }

    return target;
  }