/**
   * This method is used for creating new players
   *
   * @param playerCommonData
   * @param playerAppearance
   * @return Player
   */
  public static Player newPlayer(
      PlayerCommonData playerCommonData, PlayerAppearance playerAppearance) {
    PlayerInitialData playerInitialData = DataManager.PLAYER_INITIAL_DATA;
    LocationData ld = playerInitialData.getSpawnLocation(playerCommonData.getRace());

    WorldPosition position =
        World.getInstance()
            .createPosition(ld.getMapId(), ld.getX(), ld.getY(), ld.getZ(), ld.getHeading());
    playerCommonData.setPosition(position);

    Player newPlayer = new Player(new PlayerController(), playerCommonData, playerAppearance);

    // Starting skills
    SkillLearnService.addNewSkills(newPlayer, true);

    // Starting items
    PlayerCreationData playerCreationData =
        playerInitialData.getPlayerCreationData(playerCommonData.getPlayerClass());

    List<ItemType> items = playerCreationData.getItems();

    Storage playerInventory = new Storage(StorageType.CUBE);
    Storage regularWarehouse = new Storage(StorageType.REGULAR_WAREHOUSE);
    Storage accountWarehouse = new Storage(StorageType.ACCOUNT_WAREHOUSE);

    Equipment equipment = new Equipment(newPlayer);
    newPlayer.setStorage(playerInventory, StorageType.CUBE);
    newPlayer.setStorage(regularWarehouse, StorageType.REGULAR_WAREHOUSE);
    newPlayer.setStorage(accountWarehouse, StorageType.ACCOUNT_WAREHOUSE);
    newPlayer.setEquipment(equipment);
    newPlayer.setMailbox(new Mailbox());

    for (ItemType itemType : items) {
      int itemId = itemType.getTemplate().getTemplateId();
      Item item = ItemService.newItem(itemId, itemType.getCount());
      if (item == null) continue;

      // When creating new player - all equipment that has slot values will be equipped
      // Make sure you will not put into xml file more items than possible to equip.
      ItemTemplate itemTemplate = item.getItemTemplate();
      item.setOwnerId(newPlayer.getObjectId());
      if (itemTemplate.isArmor() || itemTemplate.isWeapon()) {
        item.setEquipped(true);
        List<ItemSlot> itemSlots = ItemSlot.getSlotsFor(itemTemplate.getItemSlot());
        item.setEquipmentSlot(itemSlots.get(0).getSlotIdMask());
        equipment.onLoadHandler(item);
      } else ItemService.onLoadHandler(newPlayer, newPlayer.getInventory(), item);
    }
    equipment.onLoadApplyEquipmentStats();
    /** Mark inventory and equipment as UPDATE_REQUIRED to be saved during character creation */
    playerInventory.setPersistentState(PersistentState.UPDATE_REQUIRED);
    equipment.setPersistentState(PersistentState.UPDATE_REQUIRED);
    return newPlayer;
  }
  /**
   * Returns the player with given objId (if such player exists)
   *
   * @param playerObjId
   * @param account
   * @return Player
   */
  public static Player getPlayer(int playerObjId, Account account) {
    Player player = playerCache.get(playerObjId);
    if (player != null) return player;

    /** Player common data and appearance should be already loaded in account */
    PlayerAccountData playerAccountData = account.getPlayerAccountData(playerObjId);
    PlayerCommonData pcd = playerAccountData.getPlayerCommonData();
    PlayerAppearance appearance = playerAccountData.getAppereance();

    player = new Player(new PlayerController(), pcd, appearance);

    LegionMember legionMember = LegionService.getInstance().getLegionMember(player.getObjectId());
    if (legionMember != null) player.setLegionMember(legionMember);

    if (GroupService.getInstance().isGroupMember(playerObjId))
      GroupService.getInstance().setGroup(player);

    if (AllianceService.getInstance().isAllianceMember(playerObjId))
      AllianceService.getInstance().setAlliance(player);

    MacroList macroses = DAOManager.getDAO(PlayerMacrossesDAO.class).restoreMacrosses(playerObjId);
    player.setMacroList(macroses);

    player.setSkillList(DAOManager.getDAO(PlayerSkillListDAO.class).loadSkillList(playerObjId));
    player.setKnownlist(new KnownList(player));
    player.setFriendList(DAOManager.getDAO(FriendListDAO.class).load(player));
    player.setBlockList(DAOManager.getDAO(BlockListDAO.class).load(player));
    player.setTitleList(DAOManager.getDAO(PlayerTitleListDAO.class).loadTitleList(playerObjId));

    DAOManager.getDAO(PlayerSettingsDAO.class).loadSettings(player);
    DAOManager.getDAO(AbyssRankDAO.class).loadAbyssRank(player);
    PlayerStatsData playerStatsData = DataManager.PLAYER_STATS_DATA;
    player.setPlayerStatsTemplate(playerStatsData.getTemplate(player));

    player.setGameStats(new PlayerGameStats(playerStatsData, player));

    Equipment equipment = DAOManager.getDAO(InventoryDAO.class).loadEquipment(player);
    ItemService.loadItemStones(equipment.getEquippedItemsWithoutStigma());
    equipment.setOwner(player);
    player.setEquipment(equipment);

    player.setLifeStats(new PlayerLifeStats(player));
    player.setEffectController(new PlayerEffectController(player));
    player.setFlyController(new FlyController(player));
    player.setReviveController(new ReviveController(player));

    player.setQuestStateList(DAOManager.getDAO(PlayerQuestListDAO.class).load(player));
    player.setRecipeList(DAOManager.getDAO(PlayerRecipesDAO.class).load(player.getObjectId()));

    /** Account warehouse should be already loaded in account */
    Storage accWarehouse = account.getAccountWarehouse();

    player.setStorage(accWarehouse, StorageType.ACCOUNT_WAREHOUSE);

    Storage inventory =
        DAOManager.getDAO(InventoryDAO.class)
            .loadStorage(player, player.getObjectId(), StorageType.CUBE);
    ItemService.loadItemStones(inventory.getStorageItems());

    player.setStorage(inventory, StorageType.CUBE);

    Storage warehouse =
        DAOManager.getDAO(InventoryDAO.class)
            .loadStorage(player, player.getObjectId(), StorageType.REGULAR_WAREHOUSE);
    ItemService.loadItemStones(warehouse.getStorageItems());

    player.setStorage(warehouse, StorageType.REGULAR_WAREHOUSE);

    /** Apply equipment stats (items and manastones were loaded in account) */
    player.getEquipment().onLoadApplyEquipmentStats();

    DAOManager.getDAO(PlayerPunishmentsDAO.class).loadPlayerPunishments(player);

    ItemService.restoreKinah(player);

    // update passive stats after effect controller, stats and equipment are initialized
    player.getController().updatePassiveStats();
    // load saved effects
    DAOManager.getDAO(PlayerEffectsDAO.class).loadPlayerEffects(player);
    // load item cooldowns
    DAOManager.getDAO(ItemCooldownsDAO.class).loadItemCooldowns(player);

    if (player.getCommonData().getTitleId() > 0) {
      TitleChangeListener.onTitleChange(
          player.getGameStats(), player.getCommonData().getTitleId(), true);
    }
    player.getGameStats().recomputeStats();

    DAOManager.getDAO(PlayerLifeStatsDAO.class).loadPlayerLifeStat(player);
    // analyze current instance
    InstanceService.onPlayerLogin(player);

    if (CacheConfig.CACHE_PLAYERS) playerCache.put(playerObjId, player);

    return player;
  }