/** @param effect */
  public void addEffect(Effect effect) {
    Map<String, Effect> mapToUpdate = getMapForEffect(effect);

    Effect existingEffect = mapToUpdate.get(effect.getStack());
    if (existingEffect != null) {
      // Check stack level
      if (existingEffect.getSkillStackLvl() > effect.getSkillStackLvl()) return;

      // Check skill level (when stack level same)
      if (existingEffect.getSkillStackLvl() == effect.getSkillStackLvl()
          && existingEffect.getSkillLevel() > effect.getSkillLevel()) return;

      existingEffect.endEffect();
    }

    if (effect.isToggle() && mapToUpdate.size() >= 3) {
      Iterator<Effect> iter = mapToUpdate.values().iterator();
      Effect nextEffect = iter.next();
      nextEffect.endEffect();
      iter.remove();
    }

    mapToUpdate.put(effect.getStack(), effect);
    effect.startEffect(false);

    if (!effect.isPassive()) {
      broadCastEffects();
    }
  }
  @Override
  protected void writeImpl(AionConnection con, ByteBuffer buf) {
    PlayerCommonData pcd = member.getCommonData();
    WorldPosition wp = pcd.getPosition();

    /**
     * Required so that when member is disconnected, and his playerAllianceGroup slot is changed, he
     * will continue to appear as disconnected to the alliance.
     */
    if (!member.isOnline()) event = PlayerAllianceEvent.DISCONNECTED;

    writeD(buf, member.getAllianceId());
    writeD(buf, member.getObjectId());
    if (member.isOnline()) {
      PlayerLifeStats pls = member.getPlayer().getLifeStats();
      writeD(buf, pls.getMaxHp());
      writeD(buf, pls.getCurrentHp());
      writeD(buf, pls.getMaxMp());
      writeD(buf, pls.getCurrentMp());
      writeD(buf, pls.getMaxFp());
      writeD(buf, pls.getCurrentFp());
    } else {
      writeD(buf, 0);
      writeD(buf, 0);
      writeD(buf, 0);
      writeD(buf, 0);
      writeD(buf, 0);
      writeD(buf, 0);
    }
    writeD(buf, wp.getMapId());
    writeD(buf, wp.getMapId());
    writeF(buf, wp.getX());
    writeF(buf, wp.getY());
    writeF(buf, wp.getZ());
    writeC(buf, pcd.getPlayerClass().getClassId());
    writeC(buf, pcd.getGender().getGenderId());
    writeC(buf, pcd.getLevel());
    writeC(buf, this.event.getId());
    writeH(buf, 0x01); // channel 0x01?
    writeC(buf, 0x00); // wtf is this?
    switch (this.event) {
      case LEAVE:
      case LEAVE_TIMEOUT:
      case BANNED:
      case MOVEMENT:
      case DISCONNECTED:
        break;

      case ENTER:
      case UPDATE:
      case RECONNECT:
      case MEMBER_GROUP_CHANGE:

      case APPOINT_VICE_CAPTAIN: // Unused maybe...
      case DEMOTE_VICE_CAPTAIN:
      case APPOINT_CAPTAIN:
        writeS(buf, pcd.getName());
        writeD(buf, 0x00); // unk

        if (member.isOnline()) {
          List<Effect> abnormalEffects =
              member.getPlayer().getEffectController().getAbnormalEffects();
          writeH(buf, abnormalEffects.size());
          for (Effect effect : abnormalEffects) {
            writeD(buf, effect.getEffectorId());
            writeH(buf, effect.getSkillId());
            writeC(buf, effect.getSkillLevel());
            writeC(buf, effect.getTargetSlot());
            writeD(buf, effect.getElapsedTime());
          }
        } else {
          writeH(buf, 0);
        }
        break;
      default:
        break;
    }
  }