This commit is contained in:
MobiusDev
2016-10-20 23:40:28 +00:00
parent 7772f93f80
commit 93c43d7067
18458 changed files with 3262754 additions and 0 deletions

View File

@@ -0,0 +1,172 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.sql.impl;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.gameserver.enums.ChatType;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.announce.Announcement;
import com.l2jmobius.gameserver.model.announce.AnnouncementType;
import com.l2jmobius.gameserver.model.announce.AutoAnnouncement;
import com.l2jmobius.gameserver.model.announce.IAnnouncement;
import com.l2jmobius.gameserver.network.serverpackets.CreatureSay;
/**
* Loads announcements from database.
* @author UnAfraid
*/
public final class AnnouncementsTable
{
private static Logger LOGGER = Logger.getLogger(AnnouncementsTable.class.getName());
private final Map<Integer, IAnnouncement> _announcements = new ConcurrentSkipListMap<>();
protected AnnouncementsTable()
{
load();
}
private void load()
{
_announcements.clear();
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement st = con.createStatement();
ResultSet rset = st.executeQuery("SELECT * FROM announcements"))
{
while (rset.next())
{
final AnnouncementType type = AnnouncementType.findById(rset.getInt("type"));
final Announcement announce;
switch (type)
{
case NORMAL:
case CRITICAL:
{
announce = new Announcement(rset);
break;
}
case AUTO_NORMAL:
case AUTO_CRITICAL:
{
announce = new AutoAnnouncement(rset);
break;
}
default:
{
continue;
}
}
_announcements.put(announce.getId(), announce);
}
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Failed loading announcements:", e);
}
}
/**
* Sending all announcements to the player
* @param player
*/
public void showAnnouncements(L2PcInstance player)
{
sendAnnouncements(player, AnnouncementType.NORMAL);
sendAnnouncements(player, AnnouncementType.CRITICAL);
sendAnnouncements(player, AnnouncementType.EVENT);
}
/**
* Sends all announcements to the player by the specified type
* @param player
* @param type
*/
public void sendAnnouncements(L2PcInstance player, AnnouncementType type)
{
for (IAnnouncement announce : _announcements.values())
{
if (announce.isValid() && (announce.getType() == type))
{
player.sendPacket(new CreatureSay(0, //
type == AnnouncementType.CRITICAL ? ChatType.CRITICAL_ANNOUNCE : ChatType.ANNOUNCEMENT, //
player.getName(), announce.getContent()));
}
}
}
/**
* Adds announcement
* @param announce
*/
public void addAnnouncement(IAnnouncement announce)
{
if (announce.storeMe())
{
_announcements.put(announce.getId(), announce);
}
}
/**
* Removes announcement by id
* @param id
* @return {@code true} if announcement exists and was deleted successfully, {@code false} otherwise.
*/
public boolean deleteAnnouncement(int id)
{
final IAnnouncement announce = _announcements.remove(id);
return (announce != null) && announce.deleteMe();
}
/**
* @param id
* @return {@link IAnnouncement} by id
*/
public IAnnouncement getAnnounce(int id)
{
return _announcements.get(id);
}
/**
* @return {@link Collection} containing all announcements
*/
public Collection<IAnnouncement> getAllAnnouncements()
{
return _announcements.values();
}
/**
* @return Single instance of {@link AnnouncementsTable}
*/
public static AnnouncementsTable getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final AnnouncementsTable _instance = new AnnouncementsTable();
}
}

View File

@@ -0,0 +1,285 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.sql.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
/**
* Loads name and access level for all players.
* @version 2005/03/27
*/
public class CharNameTable
{
private static Logger _log = Logger.getLogger(CharNameTable.class.getName());
private final Map<Integer, String> _chars = new ConcurrentHashMap<>();
private final Map<Integer, Integer> _accessLevels = new ConcurrentHashMap<>();
protected CharNameTable()
{
if (Config.CACHE_CHAR_NAMES)
{
loadAll();
}
}
public final void addName(L2PcInstance player)
{
if (player == null)
{
return;
}
addName(player.getObjectId(), player.getName());
_accessLevels.put(player.getObjectId(), player.getAccessLevel().getLevel());
}
private final void addName(int objectId, String name)
{
if ((name != null) && !name.equals(_chars.get(objectId)))
{
_chars.put(objectId, name);
}
}
public final void removeName(int objId)
{
_chars.remove(objId);
_accessLevels.remove(objId);
}
public final int getIdByName(String name)
{
if ((name == null) || name.isEmpty())
{
return -1;
}
for (Entry<Integer, String> entry : _chars.entrySet())
{
if (entry.getValue().equalsIgnoreCase(name))
{
return entry.getKey();
}
}
if (Config.CACHE_CHAR_NAMES)
{
return -1;
}
int id = -1;
int accessLevel = 0;
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT charId,accesslevel FROM characters WHERE char_name=?"))
{
ps.setString(1, name);
try (ResultSet rs = ps.executeQuery())
{
while (rs.next())
{
id = rs.getInt(1);
accessLevel = rs.getInt(2);
}
}
}
catch (SQLException e)
{
_log.log(Level.WARNING, getClass().getSimpleName() + ": Could not check existing char name: " + e.getMessage(), e);
}
if (id <= 0)
{
return -1; // not found
}
_chars.put(id, name);
_accessLevels.put(id, accessLevel);
return id;
}
public final String getNameById(int id)
{
if (id <= 0)
{
return null;
}
String name = _chars.get(id);
if (name != null)
{
return name;
}
if (Config.CACHE_CHAR_NAMES)
{
return null;
}
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT char_name,accesslevel FROM characters WHERE charId=?"))
{
ps.setInt(1, id);
try (ResultSet rset = ps.executeQuery())
{
if (rset.next())
{
name = rset.getString(1);
_chars.put(id, name);
_accessLevels.put(id, rset.getInt(2));
return name;
}
}
}
catch (SQLException e)
{
_log.log(Level.WARNING, getClass().getSimpleName() + ": Could not check existing char id: " + e.getMessage(), e);
}
return null; // not found
}
public final int getAccessLevelById(int objectId)
{
return getNameById(objectId) != null ? _accessLevels.get(objectId) : 0;
}
public synchronized boolean doesCharNameExist(String name)
{
boolean result = true;
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT account_name FROM characters WHERE char_name=?"))
{
ps.setString(1, name);
try (ResultSet rs = ps.executeQuery())
{
result = rs.next();
}
}
catch (SQLException e)
{
_log.log(Level.WARNING, getClass().getSimpleName() + ": Could not check existing charname: " + e.getMessage(), e);
}
return result;
}
public int getAccountCharacterCount(String account)
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT COUNT(char_name) FROM characters WHERE account_name=?"))
{
ps.setString(1, account);
try (ResultSet rset = ps.executeQuery())
{
while (rset.next())
{
return rset.getInt(1);
}
}
}
catch (SQLException e)
{
_log.log(Level.WARNING, getClass().getSimpleName() + ": Could not check existing char count: " + e.getMessage(), e);
}
return 0;
}
public int getLevelById(int objectId)
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT level FROM characters WHERE charId = ?"))
{
ps.setInt(1, objectId);
try (ResultSet rset = ps.executeQuery())
{
while (rset.next())
{
return rset.getInt(1);
}
}
}
catch (SQLException e)
{
_log.log(Level.WARNING, getClass().getSimpleName() + ": Could not check existing char count: " + e.getMessage(), e);
}
return 0;
}
public int getClassIdById(int objectId)
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT classid FROM characters WHERE charId = ?"))
{
ps.setInt(1, objectId);
try (ResultSet rset = ps.executeQuery())
{
while (rset.next())
{
return rset.getInt(1);
}
}
}
catch (SQLException e)
{
_log.log(Level.WARNING, getClass().getSimpleName() + ": Could not check existing char count: " + e.getMessage(), e);
}
return 0;
}
private void loadAll()
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement s = con.createStatement();
ResultSet rs = s.executeQuery("SELECT charId, char_name, accesslevel FROM characters"))
{
while (rs.next())
{
final int id = rs.getInt(1);
_chars.put(id, rs.getString(2));
_accessLevels.put(id, rs.getInt(3));
}
}
catch (SQLException e)
{
_log.log(Level.WARNING, getClass().getSimpleName() + ": Could not load char name: " + e.getMessage(), e);
}
_log.info(getClass().getSimpleName() + ": Loaded " + _chars.size() + " char names.");
}
public static CharNameTable getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final CharNameTable _instance = new CharNameTable();
}
}

View File

@@ -0,0 +1,256 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.sql.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.gameserver.data.xml.impl.NpcData;
import com.l2jmobius.gameserver.data.xml.impl.PetDataTable;
import com.l2jmobius.gameserver.datatables.SkillData;
import com.l2jmobius.gameserver.model.L2PetData;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2ServitorInstance;
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.network.serverpackets.PetItemList;
/**
* @author Nyaran
*/
public class CharSummonTable
{
private static final Logger LOGGER = Logger.getLogger(CharSummonTable.class.getName());
private static final Map<Integer, Integer> _pets = new ConcurrentHashMap<>();
private static final Map<Integer, Set<Integer>> _servitors = new ConcurrentHashMap<>();
// SQL
private static final String INIT_PET = "SELECT ownerId, item_obj_id FROM pets WHERE restore = 'true'";
private static final String INIT_SUMMONS = "SELECT ownerId, summonId FROM character_summons";
private static final String LOAD_SUMMON = "SELECT summonSkillId, summonId, curHp, curMp, time FROM character_summons WHERE ownerId = ?";
private static final String REMOVE_SUMMON = "DELETE FROM character_summons WHERE ownerId = ? and summonId = ?";
private static final String SAVE_SUMMON = "REPLACE INTO character_summons (ownerId,summonId,summonSkillId,curHp,curMp,time) VALUES (?,?,?,?,?,?)";
public Map<Integer, Integer> getPets()
{
return _pets;
}
public Map<Integer, Set<Integer>> getServitors()
{
return _servitors;
}
public void init()
{
if (Config.RESTORE_SERVITOR_ON_RECONNECT)
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement s = con.createStatement();
ResultSet rs = s.executeQuery(INIT_SUMMONS))
{
while (rs.next())
{
_servitors.computeIfAbsent(rs.getInt("ownerId"), k -> ConcurrentHashMap.newKeySet()).add(rs.getInt("summonId"));
}
}
catch (Exception e)
{
LOGGER.warning(getClass().getSimpleName() + ": Error while loading saved servitor: " + e);
}
}
if (Config.RESTORE_PET_ON_RECONNECT)
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement s = con.createStatement();
ResultSet rs = s.executeQuery(INIT_PET))
{
while (rs.next())
{
_pets.put(rs.getInt("ownerId"), rs.getInt("item_obj_id"));
}
}
catch (Exception e)
{
LOGGER.warning(getClass().getSimpleName() + ": Error while loading saved pet: " + e);
}
}
}
public void removeServitor(L2PcInstance activeChar, int summonObjectId)
{
_servitors.computeIfPresent(activeChar.getObjectId(), (k, v) ->
{
v.remove(summonObjectId);
return !v.isEmpty() ? v : null;
});
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement(REMOVE_SUMMON))
{
ps.setInt(1, activeChar.getObjectId());
ps.setInt(2, summonObjectId);
ps.execute();
}
catch (SQLException e)
{
LOGGER.warning(getClass().getSimpleName() + ": Summon cannot be removed: " + e);
}
}
public void restorePet(L2PcInstance activeChar)
{
final L2ItemInstance item = activeChar.getInventory().getItemByObjectId(_pets.get(activeChar.getObjectId()));
if (item == null)
{
LOGGER.warning(getClass().getSimpleName() + ": Null pet summoning item for: " + activeChar);
return;
}
final L2PetData petData = PetDataTable.getInstance().getPetDataByItemId(item.getId());
if (petData == null)
{
LOGGER.warning(getClass().getSimpleName() + ": Null pet data for: " + activeChar + " and summoning item: " + item);
return;
}
final L2NpcTemplate npcTemplate = NpcData.getInstance().getTemplate(petData.getNpcId());
if (npcTemplate == null)
{
LOGGER.warning(getClass().getSimpleName() + ": Null pet NPC template for: " + activeChar + " and pet Id:" + petData.getNpcId());
return;
}
final L2PetInstance pet = L2PetInstance.spawnPet(npcTemplate, activeChar, item);
if (pet == null)
{
LOGGER.warning(getClass().getSimpleName() + ": Null pet instance for: " + activeChar + " and pet NPC template:" + npcTemplate);
return;
}
pet.setShowSummonAnimation(true);
pet.setTitle(activeChar.getName());
if (!pet.isRespawned())
{
pet.setCurrentHp(pet.getMaxHp());
pet.setCurrentMp(pet.getMaxMp());
pet.getStat().setExp(pet.getExpForThisLevel());
pet.setCurrentFed(pet.getMaxFed());
}
pet.setRunning();
if (!pet.isRespawned())
{
pet.storeMe();
}
item.setEnchantLevel(pet.getLevel());
activeChar.setPet(pet);
pet.spawnMe(activeChar.getX() + 50, activeChar.getY() + 100, activeChar.getZ());
pet.startFeed();
pet.setFollowStatus(true);
pet.getOwner().sendPacket(new PetItemList(pet.getInventory().getItems()));
pet.broadcastStatusUpdate();
}
public void restoreServitor(L2PcInstance activeChar)
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement(LOAD_SUMMON))
{
ps.setInt(1, activeChar.getObjectId());
try (ResultSet rs = ps.executeQuery())
{
Skill skill;
while (rs.next())
{
final int summonObjId = rs.getInt("summonId");
final int skillId = rs.getInt("summonSkillId");
final int curHp = rs.getInt("curHp");
final int curMp = rs.getInt("curMp");
final int time = rs.getInt("time");
skill = SkillData.getInstance().getSkill(skillId, activeChar.getSkillLevel(skillId));
if ((skill == null) || !activeChar.hasServitor(summonObjId))
{
removeServitor(activeChar, summonObjId);
return;
}
skill.applyEffects(activeChar, activeChar);
final L2ServitorInstance summon = (L2ServitorInstance) activeChar.getServitor(summonObjId);
summon.setCurrentHp(curHp);
summon.setCurrentMp(curMp);
summon.setLifeTimeRemaining(time);
}
}
}
catch (SQLException e)
{
LOGGER.warning(getClass().getSimpleName() + ": Servitor cannot be restored: " + e);
}
}
public void saveSummon(L2ServitorInstance summon)
{
if ((summon == null) || (summon.getLifeTimeRemaining() <= 0))
{
return;
}
_servitors.computeIfAbsent(summon.getOwner().getObjectId(), k -> ConcurrentHashMap.newKeySet()).add(summon.getObjectId());
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement(SAVE_SUMMON))
{
ps.setInt(1, summon.getOwner().getObjectId());
ps.setInt(2, summon.getObjectId());
ps.setInt(3, summon.getReferenceSkill());
ps.setInt(4, (int) Math.round(summon.getCurrentHp()));
ps.setInt(5, (int) Math.round(summon.getCurrentMp()));
ps.setInt(6, summon.getLifeTimeRemaining());
ps.execute();
}
catch (Exception e)
{
LOGGER.warning(getClass().getSimpleName() + ": Failed to store summon: " + summon + " from " + summon.getOwner() + ", error: " + e);
}
}
public static CharSummonTable getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final CharSummonTable _instance = new CharSummonTable();
}
}

View File

@@ -0,0 +1,543 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.sql.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.gameserver.ThreadPoolManager;
import com.l2jmobius.gameserver.communitybbs.Manager.ForumsBBSManager;
import com.l2jmobius.gameserver.enums.UserInfoType;
import com.l2jmobius.gameserver.idfactory.IdFactory;
import com.l2jmobius.gameserver.instancemanager.CHSiegeManager;
import com.l2jmobius.gameserver.instancemanager.ClanHallAuctionManager;
import com.l2jmobius.gameserver.instancemanager.FortManager;
import com.l2jmobius.gameserver.instancemanager.FortSiegeManager;
import com.l2jmobius.gameserver.instancemanager.SiegeManager;
import com.l2jmobius.gameserver.model.ClanPrivilege;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.L2ClanMember;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.entity.Auction;
import com.l2jmobius.gameserver.model.entity.Fort;
import com.l2jmobius.gameserver.model.entity.FortSiege;
import com.l2jmobius.gameserver.model.entity.Siege;
import com.l2jmobius.gameserver.model.entity.clanhall.SiegableHall;
import com.l2jmobius.gameserver.model.events.EventDispatcher;
import com.l2jmobius.gameserver.model.events.impl.character.player.clan.OnPlayerClanCreate;
import com.l2jmobius.gameserver.model.events.impl.character.player.clan.OnPlayerClanDestroy;
import com.l2jmobius.gameserver.model.events.impl.clan.OnClanWarFinish;
import com.l2jmobius.gameserver.model.events.impl.clan.OnClanWarStart;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.PledgeShowInfoUpdate;
import com.l2jmobius.gameserver.network.serverpackets.PledgeShowMemberListAll;
import com.l2jmobius.gameserver.network.serverpackets.PledgeShowMemberListUpdate;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.util.Util;
import com.l2jmobius.util.EnumIntBitmask;
/**
* This class loads the clan related data.
*/
public class ClanTable
{
private static final Logger _log = Logger.getLogger(ClanTable.class.getName());
private final Map<Integer, L2Clan> _clans = new ConcurrentHashMap<>();
protected ClanTable()
{
// forums has to be loaded before clan data, because of last forum id used should have also memo included
if (Config.ENABLE_COMMUNITY_BOARD)
{
ForumsBBSManager.getInstance().initRoot();
}
L2Clan clan;
// Count the clans
int clanCount = 0;
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement s = con.createStatement();
ResultSet rs = s.executeQuery("SELECT clan_id FROM clan_data"))
{
while (rs.next())
{
final int clanId = rs.getInt("clan_id");
_clans.put(clanId, new L2Clan(clanId));
clan = getClan(clanId);
if (clan.getDissolvingExpiryTime() != 0)
{
scheduleRemoveClan(clan.getId());
}
clanCount++;
}
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Error restoring ClanTable.", e);
}
_log.info(getClass().getSimpleName() + ": Restored " + clanCount + " clans from the database.");
allianceCheck();
restorewars();
}
/**
* Gets the clans.
* @return the clans
*/
public Collection<L2Clan> getClans()
{
return _clans.values();
}
/**
* Gets the clan count.
* @return the clan count
*/
public int getClanCount()
{
return _clans.size();
}
/**
* @param clanId
* @return
*/
public L2Clan getClan(int clanId)
{
return _clans.get(clanId);
}
public L2Clan getClanByName(String clanName)
{
return getClans().stream().filter(c -> c.getName().equalsIgnoreCase(clanName)).findFirst().orElse(null);
}
/**
* Creates a new clan and store clan info to database
* @param player
* @param clanName
* @return NULL if clan with same name already exists
*/
public L2Clan createClan(L2PcInstance player, String clanName)
{
if (null == player)
{
return null;
}
if (Config.DEBUG)
{
_log.info(getClass().getSimpleName() + ": " + player.getObjectId() + "(" + player.getName() + ") requested a clan creation.");
}
if (10 > player.getLevel())
{
player.sendPacket(SystemMessageId.YOU_DO_NOT_MEET_THE_CRITERIA_IN_ORDER_TO_CREATE_A_CLAN);
return null;
}
if (0 != player.getClanId())
{
player.sendPacket(SystemMessageId.YOU_HAVE_FAILED_TO_CREATE_A_CLAN);
return null;
}
if (System.currentTimeMillis() < player.getClanCreateExpiryTime())
{
player.sendPacket(SystemMessageId.YOU_MUST_WAIT_10_DAYS_BEFORE_CREATING_A_NEW_CLAN);
return null;
}
if (!Util.isAlphaNumeric(clanName) || (2 > clanName.length()))
{
player.sendPacket(SystemMessageId.CLAN_NAME_IS_INVALID);
return null;
}
if (16 < clanName.length())
{
player.sendPacket(SystemMessageId.CLAN_NAME_S_LENGTH_IS_INCORRECT);
return null;
}
if (null != getClanByName(clanName))
{
// clan name is already taken
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_ALREADY_EXISTS);
sm.addString(clanName);
player.sendPacket(sm);
return null;
}
final L2Clan clan = new L2Clan(IdFactory.getInstance().getNextId(), clanName);
final L2ClanMember leader = new L2ClanMember(clan, player);
clan.setLeader(leader);
leader.setPlayerInstance(player);
clan.store();
player.setClan(clan);
player.setPledgeClass(L2ClanMember.calculatePledgeClass(player));
player.setClanPrivileges(new EnumIntBitmask<>(ClanPrivilege.class, true));
_clans.put(Integer.valueOf(clan.getId()), clan);
// should be update packet only
player.sendPacket(new PledgeShowInfoUpdate(clan));
player.sendPacket(new PledgeShowMemberListAll(clan));
player.sendPacket(new PledgeShowMemberListUpdate(player));
player.sendPacket(SystemMessageId.YOUR_CLAN_HAS_BEEN_CREATED);
player.broadcastUserInfo(UserInfoType.RELATION, UserInfoType.CLAN);
// Notify to scripts
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerClanCreate(player, clan));
return clan;
}
public synchronized void destroyClan(int clanId)
{
final L2Clan clan = getClan(clanId);
if (clan == null)
{
return;
}
clan.broadcastToOnlineMembers(SystemMessage.getSystemMessage(SystemMessageId.CLAN_HAS_DISPERSED));
final int castleId = clan.getCastleId();
if (castleId == 0)
{
for (Siege siege : SiegeManager.getInstance().getSieges())
{
siege.removeSiegeClan(clan);
}
}
final int fortId = clan.getFortId();
if (fortId == 0)
{
for (FortSiege siege : FortSiegeManager.getInstance().getSieges())
{
siege.removeAttacker(clan);
}
}
final int hallId = clan.getHideoutId();
if (hallId == 0)
{
for (SiegableHall hall : CHSiegeManager.getInstance().getConquerableHalls().values())
{
hall.removeAttacker(clan);
}
}
final Auction auction = ClanHallAuctionManager.getInstance().getAuction(clan.getAuctionBiddedAt());
if (auction != null)
{
auction.cancelBid(clan.getId());
}
final L2ClanMember leaderMember = clan.getLeader();
clan.getWarehouse().destroyAllItems("ClanRemove", leaderMember == null ? null : clan.getLeader().getPlayerInstance(), null);
for (L2ClanMember member : clan.getMembers())
{
clan.removeClanMember(member.getObjectId(), 0);
}
_clans.remove(clanId);
IdFactory.getInstance().releaseId(clanId);
try (Connection con = DatabaseFactory.getInstance().getConnection())
{
try (PreparedStatement ps = con.prepareStatement("DELETE FROM clan_data WHERE clan_id=?"))
{
ps.setInt(1, clanId);
ps.execute();
}
try (PreparedStatement ps = con.prepareStatement("DELETE FROM clan_privs WHERE clan_id=?"))
{
ps.setInt(1, clanId);
ps.execute();
}
try (PreparedStatement ps = con.prepareStatement("DELETE FROM clan_skills WHERE clan_id=?"))
{
ps.setInt(1, clanId);
ps.execute();
}
try (PreparedStatement ps = con.prepareStatement("DELETE FROM clan_subpledges WHERE clan_id=?"))
{
ps.setInt(1, clanId);
ps.execute();
}
try (PreparedStatement ps = con.prepareStatement("DELETE FROM clan_wars WHERE clan1=? OR clan2=?"))
{
ps.setInt(1, clanId);
ps.setInt(2, clanId);
ps.execute();
}
try (PreparedStatement ps = con.prepareStatement("DELETE FROM clan_notices WHERE clan_id=?"))
{
ps.setInt(1, clanId);
ps.execute();
}
if (castleId != 0)
{
try (PreparedStatement ps = con.prepareStatement("UPDATE castle SET taxPercent = 0 WHERE id = ?"))
{
ps.setInt(1, castleId);
ps.execute();
}
}
if (fortId != 0)
{
final Fort fort = FortManager.getInstance().getFortById(fortId);
if ((fort != null) && (clan == fort.getOwnerClan()))
{
fort.removeOwner(true);
}
}
if (hallId != 0)
{
final SiegableHall hall = CHSiegeManager.getInstance().getSiegableHall(hallId);
if ((hall != null) && (hall.getOwnerId() == clanId))
{
hall.free();
}
}
}
catch (Exception e)
{
_log.log(Level.SEVERE, getClass().getSimpleName() + ": Error removing clan from DB.", e);
}
// Notify to scripts
EventDispatcher.getInstance().notifyEventAsync(new OnPlayerClanDestroy(leaderMember, clan));
}
public void scheduleRemoveClan(int clanId)
{
ThreadPoolManager.getInstance().scheduleGeneral(() ->
{
if (getClan(clanId) == null)
{
return;
}
if (getClan(clanId).getDissolvingExpiryTime() != 0)
{
destroyClan(clanId);
}
}, Math.max(getClan(clanId).getDissolvingExpiryTime() - System.currentTimeMillis(), 300000));
}
public boolean isAllyExists(String allyName)
{
for (L2Clan clan : getClans())
{
if ((clan.getAllyName() != null) && clan.getAllyName().equalsIgnoreCase(allyName))
{
return true;
}
}
return false;
}
public void storeclanswars(int clanId1, int clanId2)
{
final L2Clan clan1 = getClan(clanId1);
final L2Clan clan2 = getClan(clanId2);
EventDispatcher.getInstance().notifyEventAsync(new OnClanWarStart(clan1, clan2));
clan1.setEnemyClan(clan2);
clan2.setAttackerClan(clan1);
clan1.broadcastClanStatus();
clan2.broadcastClanStatus();
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("REPLACE INTO clan_wars (clan1, clan2, wantspeace1, wantspeace2) VALUES(?,?,?,?)"))
{
ps.setInt(1, clanId1);
ps.setInt(2, clanId2);
ps.setInt(3, 0);
ps.setInt(4, 0);
ps.execute();
}
catch (Exception e)
{
_log.log(Level.SEVERE, getClass().getSimpleName() + ": Error storing clan wars data.", e);
}
// SystemMessage msg =
// SystemMessage.getSystemMessage(SystemMessageId.A_CLAN_WAR_WITH_CLAN_S1_HAS_STARTED_THE_CLAN_THAT_CANCELS_THE_WAR_FIRST_WILL_LOSE_5_000_CLAN_REPUTATION_ANY_CLAN_THAT_CANCELS_THE_WAR_WILL_BE_UNABLE_TO_DECLARE_A_WAR_FOR_1_WEEK_IF_YOUR_CLAN_MEMBER_GETS_KILLED_BY_THE_OTHER_CLAN_XP_DECREASES_BY_1_4_OF_THE_AMOUNT_THAT_DECREASES_IN_THE_HUNTING_GROUND);
//
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.YOU_HAVE_DECLARED_A_CLAN_WAR_WITH_S1);
msg.addString(clan2.getName());
clan1.broadcastToOnlineMembers(msg);
// msg =
// SystemMessage.getSystemMessage(SystemMessageId.A_CLAN_WAR_WITH_CLAN_S1_HAS_STARTED_THE_CLAN_THAT_CANCELS_THE_WAR_FIRST_WILL_LOSE_5_000_CLAN_REPUTATION_ANY_CLAN_THAT_CANCELS_THE_WAR_WILL_BE_UNABLE_TO_DECLARE_A_WAR_FOR_1_WEEK_IF_YOUR_CLAN_MEMBER_GETS_KILLED_BY_THE_OTHER_CLAN_XP_DECREASES_BY_1_4_OF_THE_AMOUNT_THAT_DECREASES_IN_THE_HUNTING_GROUND);
// msg.addString(clan1.getName());
// clan2.broadcastToOnlineMembers(msg);
// clan1 declared clan war.
msg = SystemMessage.getSystemMessage(SystemMessageId.S1_HAS_DECLARED_A_CLAN_WAR_THE_WAR_WILL_AUTOMATICALLY_START_IF_YOU_KILL_S1_CLAN_MEMBERS_5_TIMES_WITHIN_A_WEEK);
msg.addString(clan1.getName());
clan2.broadcastToOnlineMembers(msg);
}
public void deleteclanswars(int clanId1, int clanId2)
{
final L2Clan clan1 = getClan(clanId1);
final L2Clan clan2 = getClan(clanId2);
EventDispatcher.getInstance().notifyEventAsync(new OnClanWarFinish(clan1, clan2));
clan1.deleteEnemyClan(clan2);
clan2.deleteAttackerClan(clan1);
clan1.broadcastClanStatus();
clan2.broadcastClanStatus();
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("DELETE FROM clan_wars WHERE clan1=? AND clan2=?"))
{
ps.setInt(1, clanId1);
ps.setInt(2, clanId2);
ps.execute();
}
catch (Exception e)
{
_log.log(Level.SEVERE, getClass().getSimpleName() + ": Error removing clan wars data.", e);
}
// SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.WAR_WITH_THE_S1_CLAN_HAS_ENDED);
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.THE_WAR_AGAINST_S1_CLAN_HAS_BEEN_STOPPED);
msg.addString(clan2.getName());
clan1.broadcastToOnlineMembers(msg);
msg = SystemMessage.getSystemMessage(SystemMessageId.THE_CLAN_S1_HAS_DECIDED_TO_STOP_THE_WAR);
msg.addString(clan1.getName());
clan2.broadcastToOnlineMembers(msg);
}
public void checkSurrender(L2Clan clan1, L2Clan clan2)
{
int count = 0;
for (L2ClanMember player : clan1.getMembers())
{
if ((player != null) && (player.getPlayerInstance().getWantsPeace() == 1))
{
count++;
}
}
if (count == (clan1.getMembers().size() - 1))
{
clan1.deleteEnemyClan(clan2);
clan2.deleteEnemyClan(clan1);
deleteclanswars(clan1.getId(), clan2.getId());
}
}
private void restorewars()
{
L2Clan clan1, clan2;
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement statement = con.createStatement();
ResultSet rset = statement.executeQuery("SELECT clan1, clan2 FROM clan_wars"))
{
while (rset.next())
{
clan1 = getClan(rset.getInt("clan1"));
clan2 = getClan(rset.getInt("clan2"));
if ((clan1 != null) && (clan2 != null))
{
clan1.setEnemyClan(rset.getInt("clan2"));
clan2.setAttackerClan(rset.getInt("clan1"));
}
else
{
_log.log(Level.WARNING, getClass().getSimpleName() + ": restorewars one of clans is null clan1:" + clan1 + " clan2:" + clan2);
}
}
}
catch (Exception e)
{
_log.log(Level.SEVERE, getClass().getSimpleName() + ": Error restoring clan wars data.", e);
}
}
/**
* Check for nonexistent alliances
*/
private void allianceCheck()
{
for (L2Clan clan : _clans.values())
{
final int allyId = clan.getAllyId();
if ((allyId != 0) && (clan.getId() != allyId) && !_clans.containsKey(allyId))
{
clan.setAllyId(0);
clan.setAllyName(null);
clan.changeAllyCrest(0, true);
clan.updateClanInDB();
_log.info(getClass().getSimpleName() + ": Removed alliance from clan: " + clan);
}
}
}
public List<L2Clan> getClanAllies(int allianceId)
{
final List<L2Clan> clanAllies = new ArrayList<>();
if (allianceId != 0)
{
for (L2Clan clan : _clans.values())
{
if ((clan != null) && (clan.getAllyId() == allianceId))
{
clanAllies.add(clan);
}
}
}
return clanAllies;
}
public void storeClanScore()
{
for (L2Clan clan : _clans.values())
{
clan.updateClanScoreInDB();
}
}
public static ClanTable getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final ClanTable _instance = new ClanTable();
}
}

View File

@@ -0,0 +1,219 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.sql.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.gameserver.model.L2Clan;
import com.l2jmobius.gameserver.model.L2Crest;
import com.l2jmobius.gameserver.model.L2Crest.CrestType;
/**
* Loads and saves crests from database.
* @author NosBit
*/
public final class CrestTable
{
private static final Logger LOGGER = Logger.getLogger(CrestTable.class.getName());
private final Map<Integer, L2Crest> _crests = new ConcurrentHashMap<>();
private final AtomicInteger _nextId = new AtomicInteger(1);
protected CrestTable()
{
load();
}
public synchronized void load()
{
_crests.clear();
final Set<Integer> crestsInUse = new HashSet<>();
for (L2Clan clan : ClanTable.getInstance().getClans())
{
if (clan.getCrestId() != 0)
{
crestsInUse.add(clan.getCrestId());
}
if (clan.getCrestLargeId() != 0)
{
crestsInUse.add(clan.getCrestLargeId());
}
if (clan.getAllyCrestId() != 0)
{
crestsInUse.add(clan.getAllyCrestId());
}
}
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement statement = con.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = statement.executeQuery("SELECT `crest_id`, `data`, `type` FROM `crests` ORDER BY `crest_id` DESC"))
{
while (rs.next())
{
final int id = rs.getInt("crest_id");
if (_nextId.get() <= id)
{
_nextId.set(id + 1);
}
// delete all unused crests except the last one we dont want to reuse
// a crest id because client will display wrong crest if its reused
if (!crestsInUse.contains(id) && (id != (_nextId.get() - 1)))
{
rs.deleteRow();
continue;
}
final byte[] data = rs.getBytes("data");
final CrestType crestType = CrestType.getById(rs.getInt("type"));
if (crestType != null)
{
_crests.put(id, new L2Crest(id, data, crestType));
}
else
{
LOGGER.warning("Unknown crest type found in database. Type:" + rs.getInt("type"));
}
}
}
catch (SQLException e)
{
LOGGER.log(Level.WARNING, "There was an error while loading crests from database:", e);
}
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _crests.size() + " Crests.");
for (L2Clan clan : ClanTable.getInstance().getClans())
{
if ((clan.getCrestId() != 0) && (getCrest(clan.getCrestId()) == null))
{
LOGGER.info("Removing non-existent crest for clan " + clan.getName() + " [" + clan.getId() + "], crestId:" + clan.getCrestId());
clan.setCrestId(0);
clan.changeClanCrest(0);
}
if ((clan.getCrestLargeId() != 0) && (getCrest(clan.getCrestLargeId()) == null))
{
LOGGER.info("Removing non-existent large crest for clan " + clan.getName() + " [" + clan.getId() + "], crestLargeId:" + clan.getCrestLargeId());
clan.setCrestLargeId(0);
clan.changeLargeCrest(0);
}
if ((clan.getAllyCrestId() != 0) && (getCrest(clan.getAllyCrestId()) == null))
{
LOGGER.info("Removing non-existent ally crest for clan " + clan.getName() + " [" + clan.getId() + "], allyCrestId:" + clan.getAllyCrestId());
clan.setAllyCrestId(0);
clan.changeAllyCrest(0, true);
}
}
}
/**
* @param crestId The crest id
* @return {@code L2Crest} if crest is found, {@code null} if crest was not found.
*/
public L2Crest getCrest(int crestId)
{
return _crests.get(crestId);
}
/**
* Creates a {@code L2Crest} object and inserts it in database and cache.
* @param data
* @param crestType
* @return {@code L2Crest} on success, {@code null} on failure.
*/
public L2Crest createCrest(byte[] data, CrestType crestType)
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("INSERT INTO `crests`(`crest_id`, `data`, `type`) VALUES(?, ?, ?)"))
{
final L2Crest crest = new L2Crest(getNextId(), data, crestType);
statement.setInt(1, crest.getId());
statement.setBytes(2, crest.getData());
statement.setInt(3, crest.getType().getId());
statement.executeUpdate();
_crests.put(crest.getId(), crest);
return crest;
}
catch (SQLException e)
{
LOGGER.log(Level.WARNING, "There was an error while saving crest in database:", e);
}
return null;
}
/**
* Removes crest from database and cache.
* @param crestId the id of crest to be removed.
*/
public void removeCrest(int crestId)
{
_crests.remove(crestId);
// avoid removing last crest id we dont want to lose index...
// because client will display wrong crest if its reused
if (crestId == (_nextId.get() - 1))
{
return;
}
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("DELETE FROM `crests` WHERE `crest_id` = ?"))
{
statement.setInt(1, crestId);
statement.executeUpdate();
}
catch (SQLException e)
{
LOGGER.log(Level.WARNING, "There was an error while deleting crest from database:", e);
}
}
/**
* @return The next crest id.
*/
public int getNextId()
{
return _nextId.getAndIncrement();
}
public static CrestTable getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final CrestTable _instance = new CrestTable();
}
}

View File

@@ -0,0 +1,199 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.sql.impl;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
public class NpcBufferTable
{
private static final Logger LOGGER = Logger.getLogger(NpcBufferTable.class.getName());
private final Map<Integer, NpcBufferSkills> _buffers = new HashMap<>();
public static class NpcBufferData
{
private final SkillHolder _skill;
private final ItemHolder _fee;
protected NpcBufferData(int skillId, int skillLevel, int feeId, int feeAmount)
{
_skill = new SkillHolder(skillId, skillLevel);
_fee = new ItemHolder(feeId, feeAmount);
}
public SkillHolder getSkill()
{
return _skill;
}
public ItemHolder getFee()
{
return _fee;
}
}
private static class NpcBufferSkills
{
private final int _npcId;
private final Map<Integer, NpcBufferData> _skills = new HashMap<>();
protected NpcBufferSkills(int npcId)
{
_npcId = npcId;
}
public void addSkill(int skillId, int skillLevel, int skillFeeId, int skillFeeAmount, int buffGroup)
{
_skills.put(buffGroup, new NpcBufferData(skillId, skillLevel, skillFeeId, skillFeeAmount));
}
public NpcBufferData getSkillGroupInfo(int buffGroup)
{
return _skills.get(buffGroup);
}
@SuppressWarnings("unused")
public int getNpcId()
{
return _npcId;
}
}
protected NpcBufferTable()
{
int skillCount = 0;
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement s = con.createStatement();
ResultSet rset = s.executeQuery("SELECT `npc_id`,`skill_id`,`skill_level`,`skill_fee_id`,`skill_fee_amount`,`buff_group` FROM `npc_buffer` ORDER BY `npc_id` ASC"))
{
int lastNpcId = 0;
NpcBufferSkills skills = null;
while (rset.next())
{
final int npcId = rset.getInt("npc_id");
final int skillId = rset.getInt("skill_id");
final int skillLevel = rset.getInt("skill_level");
final int skillFeeId = rset.getInt("skill_fee_id");
final int skillFeeAmount = rset.getInt("skill_fee_amount");
final int buffGroup = rset.getInt("buff_group");
if (npcId != lastNpcId)
{
if (lastNpcId != 0)
{
_buffers.put(lastNpcId, skills);
}
skills = new NpcBufferSkills(npcId);
skills.addSkill(skillId, skillLevel, skillFeeId, skillFeeAmount, buffGroup);
}
else if (skills != null)
{
skills.addSkill(skillId, skillLevel, skillFeeId, skillFeeAmount, buffGroup);
}
lastNpcId = npcId;
skillCount++;
}
if (lastNpcId != 0)
{
_buffers.put(lastNpcId, skills);
}
}
catch (SQLException e)
{
LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Error reading npc_buffer table: " + e.getMessage(), e);
}
if (Config.CUSTOM_NPCBUFFER_TABLES)
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement s = con.createStatement();
ResultSet rset = s.executeQuery("SELECT `npc_id`,`skill_id`,`skill_level`,`skill_fee_id`,`skill_fee_amount`,`buff_group` FROM `custom_npc_buffer` ORDER BY `npc_id` ASC"))
{
int lastNpcId = 0;
NpcBufferSkills skills = null;
while (rset.next())
{
final int npcId = rset.getInt("npc_id");
final int skillId = rset.getInt("skill_id");
final int skillLevel = rset.getInt("skill_level");
final int skillFeeId = rset.getInt("skill_fee_id");
final int skillFeeAmount = rset.getInt("skill_fee_amount");
final int buffGroup = rset.getInt("buff_group");
if (npcId != lastNpcId)
{
if (lastNpcId != 0)
{
_buffers.put(lastNpcId, skills);
}
skills = new NpcBufferSkills(npcId);
skills.addSkill(skillId, skillLevel, skillFeeId, skillFeeAmount, buffGroup);
}
else if (skills != null)
{
skills.addSkill(skillId, skillLevel, skillFeeId, skillFeeAmount, buffGroup);
}
lastNpcId = npcId;
skillCount++;
}
if (lastNpcId != 0)
{
_buffers.put(lastNpcId, skills);
}
}
catch (SQLException e)
{
LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Error reading custom_npc_buffer table: " + e.getMessage(), e);
}
}
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _buffers.size() + " buffers and " + skillCount + " skills.");
}
public NpcBufferData getSkillInfo(int npcId, int buffGroup)
{
final NpcBufferSkills skills = _buffers.get(npcId);
return skills != null ? skills.getSkillGroupInfo(buffGroup) : null;
}
public static NpcBufferTable getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final NpcBufferTable _instance = new NpcBufferTable();
}
}

View File

@@ -0,0 +1,415 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.sql.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.gameserver.LoginServerThread;
import com.l2jmobius.gameserver.enums.PrivateStoreType;
import com.l2jmobius.gameserver.model.L2ManufactureItem;
import com.l2jmobius.gameserver.model.L2World;
import com.l2jmobius.gameserver.model.TradeItem;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.L2GameClient;
import com.l2jmobius.gameserver.network.L2GameClient.GameClientState;
public class OfflineTradersTable
{
private static Logger LOGGER = Logger.getLogger(OfflineTradersTable.class.getName());
// SQL DEFINITIONS
private static final String SAVE_OFFLINE_STATUS = "INSERT INTO character_offline_trade (`charId`,`time`,`type`,`title`) VALUES (?,?,?,?)";
private static final String SAVE_ITEMS = "INSERT INTO character_offline_trade_items (`charId`,`item`,`count`,`price`) VALUES (?,?,?,?)";
private static final String CLEAR_OFFLINE_TABLE = "DELETE FROM character_offline_trade";
private static final String CLEAR_OFFLINE_TABLE_PLAYER = "DELETE FROM character_offline_trade WHERE `charId`=?";
private static final String CLEAR_OFFLINE_TABLE_ITEMS = "DELETE FROM character_offline_trade_items";
private static final String CLEAR_OFFLINE_TABLE_ITEMS_PLAYER = "DELETE FROM character_offline_trade_items WHERE `charId`=?";
private static final String LOAD_OFFLINE_STATUS = "SELECT * FROM character_offline_trade";
private static final String LOAD_OFFLINE_ITEMS = "SELECT * FROM character_offline_trade_items WHERE `charId`=?";
public void storeOffliners()
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement stm1 = con.prepareStatement(CLEAR_OFFLINE_TABLE);
PreparedStatement stm2 = con.prepareStatement(CLEAR_OFFLINE_TABLE_ITEMS);
PreparedStatement stm3 = con.prepareStatement(SAVE_OFFLINE_STATUS);
PreparedStatement stm_items = con.prepareStatement(SAVE_ITEMS))
{
stm1.execute();
stm2.execute();
con.setAutoCommit(false); // avoid halfway done
for (L2PcInstance pc : L2World.getInstance().getPlayers())
{
try
{
if ((pc.getPrivateStoreType() != PrivateStoreType.NONE) && pc.isInOfflineMode())
{
stm3.setInt(1, pc.getObjectId()); // Char Id
stm3.setLong(2, pc.getOfflineStartTime());
stm3.setInt(3, pc.getPrivateStoreType().getId()); // store type
String title = null;
switch (pc.getPrivateStoreType())
{
case BUY:
{
if (!Config.OFFLINE_TRADE_ENABLE)
{
continue;
}
title = pc.getBuyList().getTitle();
for (TradeItem i : pc.getBuyList().getItems())
{
stm_items.setInt(1, pc.getObjectId());
stm_items.setInt(2, i.getItem().getId());
stm_items.setLong(3, i.getCount());
stm_items.setLong(4, i.getPrice());
stm_items.executeUpdate();
stm_items.clearParameters();
}
break;
}
case SELL:
case PACKAGE_SELL:
{
if (!Config.OFFLINE_TRADE_ENABLE)
{
continue;
}
title = pc.getSellList().getTitle();
for (TradeItem i : pc.getSellList().getItems())
{
stm_items.setInt(1, pc.getObjectId());
stm_items.setInt(2, i.getObjectId());
stm_items.setLong(3, i.getCount());
stm_items.setLong(4, i.getPrice());
stm_items.executeUpdate();
stm_items.clearParameters();
}
break;
}
case MANUFACTURE:
{
if (!Config.OFFLINE_CRAFT_ENABLE)
{
continue;
}
title = pc.getStoreName();
for (L2ManufactureItem i : pc.getManufactureItems().values())
{
stm_items.setInt(1, pc.getObjectId());
stm_items.setInt(2, i.getRecipeId());
stm_items.setLong(3, 0);
stm_items.setLong(4, i.getCost());
stm_items.executeUpdate();
stm_items.clearParameters();
}
break;
}
}
stm3.setString(4, title);
stm3.executeUpdate();
stm3.clearParameters();
con.commit(); // flush
}
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while saving offline trader: " + pc.getObjectId() + " " + e, e);
}
}
LOGGER.info(getClass().getSimpleName() + ": Offline traders stored.");
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while saving offline traders: " + e, e);
}
}
public void restoreOfflineTraders()
{
LOGGER.info(getClass().getSimpleName() + ": Loading offline traders...");
int nTraders = 0;
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement stm = con.createStatement();
ResultSet rs = stm.executeQuery(LOAD_OFFLINE_STATUS))
{
while (rs.next())
{
final long time = rs.getLong("time");
if (Config.OFFLINE_MAX_DAYS > 0)
{
final Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(time);
cal.add(Calendar.DAY_OF_YEAR, Config.OFFLINE_MAX_DAYS);
if (cal.getTimeInMillis() <= System.currentTimeMillis())
{
continue;
}
}
final PrivateStoreType type = PrivateStoreType.findById(rs.getInt("type"));
if (type == null)
{
LOGGER.warning(getClass().getSimpleName() + ": PrivateStoreType with id " + rs.getInt("type") + " could not be found.");
continue;
}
if (type == PrivateStoreType.NONE)
{
continue;
}
L2PcInstance player = null;
try
{
final L2GameClient client = new L2GameClient(null);
client.setDetached(true);
player = L2PcInstance.load(rs.getInt("charId"));
client.setActiveChar(player);
player.setOnlineStatus(true, false);
client.setAccountName(player.getAccountNamePlayer());
L2World.getInstance().addPlayerToWorld(player);
client.setState(GameClientState.IN_GAME);
player.setClient(client);
player.setOfflineStartTime(time);
player.spawnMe(player.getX(), player.getY(), player.getZ());
LoginServerThread.getInstance().addGameServerLogin(player.getAccountName(), client);
try (PreparedStatement stm_items = con.prepareStatement(LOAD_OFFLINE_ITEMS))
{
stm_items.setInt(1, player.getObjectId());
try (ResultSet items = stm_items.executeQuery())
{
switch (type)
{
case BUY:
{
while (items.next())
{
if (player.getBuyList().addItemByItemId(items.getInt(2), items.getLong(3), items.getLong(4), 0, 0, 0, new int[]
{
0,
0,
0,
0,
0,
0
}, 0) == null)
{
continue;
// throw new NullPointerException();
}
}
player.getBuyList().setTitle(rs.getString("title"));
break;
}
case SELL:
case PACKAGE_SELL:
{
while (items.next())
{
if (player.getSellList().addItem(items.getInt(2), items.getLong(3), items.getLong(4)) == null)
{
continue;
// throw new NullPointerException();
}
}
player.getSellList().setTitle(rs.getString("title"));
player.getSellList().setPackaged(type == PrivateStoreType.PACKAGE_SELL);
break;
}
case MANUFACTURE:
{
while (items.next())
{
player.getManufactureItems().put(items.getInt(2), new L2ManufactureItem(items.getInt(2), items.getLong(4)));
}
player.setStoreName(rs.getString("title"));
break;
}
}
}
}
player.sitDown();
if (Config.OFFLINE_SET_NAME_COLOR)
{
player.getAppearance().setNameColor(Config.OFFLINE_NAME_COLOR);
}
player.setPrivateStoreType(type);
player.setOnlineStatus(true, true);
player.restoreEffects();
player.broadcastUserInfo();
nTraders++;
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error loading trader: " + player, e);
if (player != null)
{
player.deleteMe();
}
}
}
LOGGER.info(getClass().getSimpleName() + ": Loaded: " + nTraders + " offline trader(s)");
if (!Config.STORE_OFFLINE_TRADE_IN_REALTIME)
{
try (Statement stm1 = con.createStatement())
{
stm1.execute(CLEAR_OFFLINE_TABLE);
stm1.execute(CLEAR_OFFLINE_TABLE_ITEMS);
}
}
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while loading offline traders: ", e);
}
}
public static synchronized void onTransaction(L2PcInstance trader, boolean finished, boolean firstCall)
{
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement stm1 = con.prepareStatement(CLEAR_OFFLINE_TABLE_ITEMS_PLAYER);
PreparedStatement stm2 = con.prepareStatement(CLEAR_OFFLINE_TABLE_PLAYER);
PreparedStatement stm3 = con.prepareStatement(SAVE_ITEMS);
PreparedStatement stm4 = con.prepareStatement(SAVE_OFFLINE_STATUS))
{
String title = null;
stm1.setInt(1, trader.getObjectId()); // Char Id
stm1.execute();
stm1.close();
// Trade is done - clear info
if (finished)
{
stm2.setInt(1, trader.getObjectId()); // Char Id
stm2.execute();
stm2.close();
}
else
{
try
{
if ((trader.getClient() == null) || trader.getClient().isDetached())
{
switch (trader.getPrivateStoreType())
{
case BUY:
{
if (firstCall)
{
title = trader.getBuyList().getTitle();
}
for (TradeItem i : trader.getBuyList().getItems())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getItem().getId());
stm3.setLong(3, i.getCount());
stm3.setLong(4, i.getPrice());
stm3.executeUpdate();
stm3.clearParameters();
}
break;
}
case SELL:
case PACKAGE_SELL:
{
if (firstCall)
{
title = trader.getSellList().getTitle();
}
for (TradeItem i : trader.getSellList().getItems())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getObjectId());
stm3.setLong(3, i.getCount());
stm3.setLong(4, i.getPrice());
stm3.executeUpdate();
stm3.clearParameters();
}
break;
}
case MANUFACTURE:
{
if (firstCall)
{
title = trader.getStoreName();
}
for (L2ManufactureItem i : trader.getManufactureItems().values())
{
stm3.setInt(1, trader.getObjectId());
stm3.setInt(2, i.getRecipeId());
stm3.setLong(3, 0);
stm3.setLong(4, i.getCost());
stm3.executeUpdate();
stm3.clearParameters();
}
break;
}
}
stm3.close();
if (firstCall)
{
stm4.setInt(1, trader.getObjectId()); // Char Id
stm4.setLong(2, trader.getOfflineStartTime());
stm4.setInt(3, trader.getPrivateStoreType().getId()); // store type
stm4.setString(4, title);
stm4.executeUpdate();
stm4.clearParameters();
stm4.close();
}
}
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, "OfflineTradersTable[storeTradeItems()]: Error while saving offline trader: " + trader.getObjectId() + " " + e, e);
}
}
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, "OfflineTradersTable[storeTradeItems()]: Error while saving offline traders: " + e, e);
}
}
/**
* Gets the single instance of OfflineTradersTable.
* @return single instance of OfflineTradersTable
*/
public static OfflineTradersTable getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final OfflineTradersTable _instance = new OfflineTradersTable();
}
}

View File

@@ -0,0 +1,115 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.sql.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import com.l2jmobius.Config;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.gameserver.data.xml.impl.PetDataTable;
public class PetNameTable
{
private static Logger LOGGER = Logger.getLogger(PetNameTable.class.getName());
public static PetNameTable getInstance()
{
return SingletonHolder._instance;
}
public boolean doesPetNameExist(String name, int petNpcId)
{
boolean result = true;
try (Connection con = DatabaseFactory.getInstance().getConnection();
PreparedStatement ps = con.prepareStatement("SELECT name FROM pets p, items i WHERE p.item_obj_id = i.object_id AND name=? AND i.item_id IN (?)"))
{
ps.setString(1, name);
final StringBuilder cond = new StringBuilder();
if (!cond.toString().isEmpty())
{
cond.append(", ");
}
cond.append(PetDataTable.getInstance().getPetItemsByNpc(petNpcId));
ps.setString(2, cond.toString());
try (ResultSet rs = ps.executeQuery())
{
result = rs.next();
}
}
catch (SQLException e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Could not check existing petname:" + e.getMessage(), e);
}
return result;
}
public boolean isValidPetName(String name)
{
boolean result = true;
if (!isAlphaNumeric(name))
{
return result;
}
Pattern pattern;
try
{
pattern = Pattern.compile(Config.PET_NAME_TEMPLATE);
}
catch (PatternSyntaxException e) // case of illegal pattern
{
LOGGER.warning(getClass().getSimpleName() + ": Pet name pattern of config is wrong!");
pattern = Pattern.compile(".*");
}
final Matcher regexp = pattern.matcher(name);
if (!regexp.matches())
{
result = false;
}
return result;
}
private boolean isAlphaNumeric(String text)
{
boolean result = true;
final char[] chars = text.toCharArray();
for (int i = 0; i < chars.length; i++)
{
if (!Character.isLetterOrDigit(chars[i]))
{
result = false;
break;
}
}
return result;
}
private static class SingletonHolder
{
protected static final PetNameTable _instance = new PetNameTable();
}
}

View File

@@ -0,0 +1,175 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.sql.impl;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.l2jmobius.gameserver.model.actor.L2Summon;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2PetInstance;
import com.l2jmobius.gameserver.model.actor.instance.L2ServitorInstance;
import com.l2jmobius.gameserver.model.skills.Skill;
/**
* @author Nyaran
*/
public class SummonEffectsTable
{
/** Servitors **/
// Map tree
// -> key: charObjectId, value: classIndex Map
// --> key: classIndex, value: servitors Map
// ---> key: servitorSkillId, value: Effects list
private final Map<Integer, Map<Integer, Map<Integer, Map<Integer, SummonEffect>>>> _servitorEffects = new HashMap<>();
/** Pets **/
// key: petItemObjectId, value: Effects list
private final Map<Integer, Map<Integer, SummonEffect>> _petEffects = new HashMap<>();
private Map<Integer, Map<Integer, SummonEffect>> getServitorEffects(L2PcInstance owner)
{
final Map<Integer, Map<Integer, Map<Integer, SummonEffect>>> servitorMap = _servitorEffects.get(owner.getObjectId());
return servitorMap == null ? null : servitorMap.get(owner.getClassIndex());
}
private Map<Integer, SummonEffect> getServitorEffects(L2PcInstance owner, int referenceSkill)
{
return containsOwner(owner) ? getServitorEffects(owner).get(referenceSkill) : null;
}
private boolean containsOwner(L2PcInstance owner)
{
return _servitorEffects.getOrDefault(owner.getObjectId(), Collections.emptyMap()).containsKey(owner.getClassIndex());
}
private void removeEffects(Map<Integer, SummonEffect> map, int skillId)
{
if (map != null)
{
map.remove(skillId);
}
}
private void applyEffects(L2Summon summon, Map<Integer, SummonEffect> map)
{
if (map == null)
{
return;
}
for (SummonEffect se : map.values())
{
if (se != null)
{
se.getSkill().applyEffects(summon, summon, false, se.getEffectCurTime());
}
}
}
public boolean containsSkill(L2PcInstance owner, int referenceSkill)
{
return containsOwner(owner) && getServitorEffects(owner).containsKey(referenceSkill);
}
public void clearServitorEffects(L2PcInstance owner, int referenceSkill)
{
if (containsOwner(owner))
{
getServitorEffects(owner).getOrDefault(referenceSkill, Collections.emptyMap()).clear();
}
}
public void addServitorEffect(L2PcInstance owner, int referenceSkill, Skill skill, int effectCurTime)
{
_servitorEffects.putIfAbsent(owner.getObjectId(), new HashMap<Integer, Map<Integer, Map<Integer, SummonEffect>>>());
_servitorEffects.get(owner.getObjectId()).putIfAbsent(owner.getClassIndex(), new HashMap<Integer, Map<Integer, SummonEffect>>());
getServitorEffects(owner).putIfAbsent(referenceSkill, new ConcurrentHashMap<Integer, SummonEffect>());
getServitorEffects(owner).get(referenceSkill).put(skill.getId(), new SummonEffect(skill, effectCurTime));
}
public void removeServitorEffects(L2PcInstance owner, int referenceSkill, int skillId)
{
removeEffects(getServitorEffects(owner, referenceSkill), skillId);
}
public void applyServitorEffects(L2ServitorInstance servitor, L2PcInstance owner, int referenceSkill)
{
applyEffects(servitor, getServitorEffects(owner, referenceSkill));
}
public void addPetEffect(int controlObjectId, Skill skill, int effectCurTime)
{
_petEffects.computeIfAbsent(controlObjectId, k -> new ConcurrentHashMap<>()).put(skill.getId(), new SummonEffect(skill, effectCurTime));
}
public boolean containsPetId(int controlObjectId)
{
return _petEffects.containsKey(controlObjectId);
}
public void applyPetEffects(L2PetInstance l2PetInstance, int controlObjectId)
{
applyEffects(l2PetInstance, _petEffects.get(controlObjectId));
}
public void clearPetEffects(int controlObjectId)
{
final Map<Integer, SummonEffect> effects = _petEffects.get(controlObjectId);
if (effects != null)
{
effects.clear();
}
}
public void removePetEffects(int controlObjectId, int skillId)
{
removeEffects(_petEffects.get(controlObjectId), skillId);
}
private class SummonEffect
{
Skill _skill;
int _effectCurTime;
public SummonEffect(Skill skill, int effectCurTime)
{
_skill = skill;
_effectCurTime = effectCurTime;
}
public Skill getSkill()
{
return _skill;
}
public int getEffectCurTime()
{
return _effectCurTime;
}
}
public static SummonEffectsTable getInstance()
{
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder
{
protected static final SummonEffectsTable INSTANCE = new SummonEffectsTable();
}
}

View File

@@ -0,0 +1,179 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.sql.impl;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.gameserver.datatables.SkillData;
import com.l2jmobius.gameserver.model.actor.L2Summon;
public class SummonSkillsTable
{
private static Logger LOGGER = Logger.getLogger(SummonSkillsTable.class.getName());
private final Map<Integer, Map<Integer, L2PetSkillLearn>> _skillTrees = new HashMap<>();
protected SummonSkillsTable()
{
load();
}
public void load()
{
_skillTrees.clear();
int count = 0;
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement s = con.createStatement();
ResultSet rs = s.executeQuery("SELECT templateId, minLvl, skillId, skillLvl FROM pets_skills"))
{
while (rs.next())
{
final int npcId = rs.getInt("templateId");
Map<Integer, L2PetSkillLearn> skillTree = _skillTrees.get(npcId);
if (skillTree == null)
{
skillTree = new HashMap<>();
_skillTrees.put(npcId, skillTree);
}
final int id = rs.getInt("skillId");
final int lvl = rs.getInt("skillLvl");
skillTree.put(SkillData.getSkillHashCode(id, lvl + 1), new L2PetSkillLearn(id, lvl, rs.getInt("minLvl")));
count++;
}
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Error while loading pet skill tree:", e);
}
LOGGER.info(getClass().getSimpleName() + ": Loaded " + count + " skills.");
}
public int getAvailableLevel(L2Summon cha, int skillId)
{
int lvl = 0;
if (!_skillTrees.containsKey(cha.getId()))
{
LOGGER.warning(getClass().getSimpleName() + ": Pet id " + cha.getId() + " does not have any skills assigned.");
return lvl;
}
final Collection<L2PetSkillLearn> skills = _skillTrees.get(cha.getId()).values();
for (L2PetSkillLearn temp : skills)
{
if (temp.getId() != skillId)
{
continue;
}
if (temp.getLevel() == 0)
{
if (cha.getLevel() < 70)
{
lvl = cha.getLevel() / 10;
if (lvl <= 0)
{
lvl = 1;
}
}
else
{
lvl = 7 + ((cha.getLevel() - 70) / 5);
}
// formula usable for skill that have 10 or more skill levels
final int maxLvl = SkillData.getInstance().getMaxLevel(temp.getId());
if (lvl > maxLvl)
{
lvl = maxLvl;
}
break;
}
if ((temp.getMinLevel() <= cha.getLevel()) && (temp.getLevel() > lvl))
{
lvl = temp.getLevel();
}
}
return lvl;
}
public List<Integer> getAvailableSkills(L2Summon cha)
{
final List<Integer> skillIds = new ArrayList<>();
if (!_skillTrees.containsKey(cha.getId()))
{
LOGGER.warning(getClass().getSimpleName() + ": Pet id " + cha.getId() + " does not have any skills assigned.");
return skillIds;
}
final Collection<L2PetSkillLearn> skills = _skillTrees.get(cha.getId()).values();
for (L2PetSkillLearn temp : skills)
{
if (skillIds.contains(temp.getId()))
{
continue;
}
skillIds.add(temp.getId());
}
return skillIds;
}
public static final class L2PetSkillLearn
{
private final int _id;
private final int _level;
private final int _minLevel;
public L2PetSkillLearn(int id, int lvl, int minLvl)
{
_id = id;
_level = lvl;
_minLevel = minLvl;
}
public int getId()
{
return _id;
}
public int getLevel()
{
return _level;
}
public int getMinLevel()
{
return _minLevel;
}
}
public static SummonSkillsTable getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final SummonSkillsTable _instance = new SummonSkillsTable();
}
}

View File

@@ -0,0 +1,125 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.sql.impl;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.Config;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.gameserver.model.L2TeleportLocation;
public class TeleportLocationTable
{
private static Logger LOGGER = Logger.getLogger(TeleportLocationTable.class.getName());
private final Map<Integer, L2TeleportLocation> _teleports = new HashMap<>();
protected TeleportLocationTable()
{
reloadAll();
}
public void reloadAll()
{
_teleports.clear();
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement s = con.createStatement();
ResultSet rs = s.executeQuery("SELECT id, loc_x, loc_y, loc_z, price, fornoble, itemId FROM teleport"))
{
L2TeleportLocation teleport;
while (rs.next())
{
teleport = new L2TeleportLocation();
teleport.setTeleId(rs.getInt("id"));
teleport.setLocX(rs.getInt("loc_x"));
teleport.setLocY(rs.getInt("loc_y"));
teleport.setLocZ(rs.getInt("loc_z"));
teleport.setPrice(rs.getInt("price"));
teleport.setIsForNoble(rs.getInt("fornoble") == 1);
teleport.setItemId(rs.getInt("itemId"));
_teleports.put(teleport.getTeleId(), teleport);
}
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _teleports.size() + " Teleport Location Templates.");
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Error loading Teleport Table.", e);
}
if (!Config.CUSTOM_TELEPORT_TABLE)
{
return;
}
int _cTeleCount = _teleports.size();
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement s = con.createStatement();
ResultSet rs = s.executeQuery("SELECT id, loc_x, loc_y, loc_z, price, fornoble, itemId FROM custom_teleport"))
{
L2TeleportLocation teleport;
while (rs.next())
{
teleport = new L2TeleportLocation();
teleport.setTeleId(rs.getInt("id"));
teleport.setLocX(rs.getInt("loc_x"));
teleport.setLocY(rs.getInt("loc_y"));
teleport.setLocZ(rs.getInt("loc_z"));
teleport.setPrice(rs.getInt("price"));
teleport.setIsForNoble(rs.getInt("fornoble") == 1);
teleport.setItemId(rs.getInt("itemId"));
_teleports.put(teleport.getTeleId(), teleport);
}
_cTeleCount = _teleports.size() - _cTeleCount;
if (_cTeleCount > 0)
{
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _cTeleCount + " Custom Teleport Location Templates.");
}
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Error while creating custom teleport table " + e.getMessage(), e);
}
}
/**
* @param id
* @return
*/
public L2TeleportLocation getTemplate(int id)
{
return _teleports.get(id);
}
public static TeleportLocationTable getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final TeleportLocationTable _instance = new TeleportLocationTable();
}
}

View File

@@ -0,0 +1,111 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.sql.impl;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.gameserver.model.L2Territory;
import com.l2jmobius.gameserver.model.Location;
/**
* @author Balancer, Mr
*/
public class TerritoryTable
{
private static final Logger LOGGER = Logger.getLogger(TerritoryTable.class.getName());
private static final Map<Integer, L2Territory> _territory = new HashMap<>();
/**
* Instantiates a new territory.
*/
protected TerritoryTable()
{
load();
}
/**
* Gets the random point.
* @param terr the territory Id?
* @return the random point
*/
public Location getRandomPoint(int terr)
{
return _territory.get(terr).getRandomPoint();
}
/**
* Gets the proc max.
* @param terr the territory Id?
* @return the proc max
*/
public int getProcMax(int terr)
{
return _territory.get(terr).getProcMax();
}
/**
* Load the data from database.
*/
public void load()
{
_territory.clear();
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement stmt = con.createStatement();
ResultSet rset = stmt.executeQuery("SELECT * FROM locations WHERE loc_id>0"))
{
while (rset.next())
{
final int terrId = rset.getInt("loc_id");
L2Territory terr = _territory.get(terrId);
if (terr == null)
{
terr = new L2Territory(terrId);
_territory.put(terrId, terr);
}
terr.add(rset.getInt("loc_x"), rset.getInt("loc_y"), rset.getInt("loc_zmin"), rset.getInt("loc_zmax"), rset.getInt("proc"));
}
LOGGER.info("TerritoryTable: Loaded " + _territory.size() + " territories from database.");
}
catch (SQLException e)
{
LOGGER.log(Level.SEVERE, "TerritoryTable: Failed to load territories from database!", e);
}
}
/**
* Gets the single instance of Territory.
* @return single instance of Territory
*/
public static TerritoryTable getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final TerritoryTable _instance = new TerritoryTable();
}
}

View File

@@ -0,0 +1,103 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.holders.RangeAbilityPointsHolder;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* @author UnAfraid
*/
public final class AbilityPointsData implements IXmlReader
{
private final List<RangeAbilityPointsHolder> _points = new ArrayList<>();
protected AbilityPointsData()
{
load();
}
@Override
public synchronized void load()
{
_points.clear();
parseFile(new File("config/AbilityPoints.xml"));
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _points.size() + " range fees.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("points".equalsIgnoreCase(d.getNodeName()))
{
final NamedNodeMap attrs = d.getAttributes();
_points.add(new RangeAbilityPointsHolder(parseInteger(attrs, "from"), parseInteger(attrs, "to"), parseInteger(attrs, "costs")));
}
}
}
}
}
public RangeAbilityPointsHolder getHolder(int points)
{
for (RangeAbilityPointsHolder holder : _points)
{
if ((holder.getMin() <= points) && (holder.getMax() >= points))
{
return holder;
}
}
return null;
}
public long getPrice(int points)
{
points++; // for next point
final RangeAbilityPointsHolder holder = getHolder(points);
if (holder != null)
{
return holder.getSP();
}
final RangeAbilityPointsHolder prevHolder = getHolder(points - 1);
return prevHolder != null ? prevHolder.getSP() : points >= 13 ? 1_000_000_000 : points >= 9 ? 750_000_000 : points >= 5 ? 500_000_000 : 250_000_000;
}
public static AbilityPointsData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final AbilityPointsData _instance = new AbilityPointsData();
}
}

View File

@@ -0,0 +1,352 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.L2AccessLevel;
import com.l2jmobius.gameserver.model.L2AdminCommandAccessRight;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.L2GameServerPacket;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* Loads administrator access levels and commands.
* @author UnAfraid
*/
public final class AdminData implements IXmlReader
{
private final Map<Integer, L2AccessLevel> _accessLevels = new HashMap<>();
private final Map<String, L2AdminCommandAccessRight> _adminCommandAccessRights = new HashMap<>();
private final Map<L2PcInstance, Boolean> _gmList = new ConcurrentHashMap<>();
private int _highestLevel = 0;
protected AdminData()
{
load();
}
@Override
public synchronized void load()
{
_accessLevels.clear();
_adminCommandAccessRights.clear();
parseDatapackFile("../config/AccessLevels.xml");
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _accessLevels.size() + " Access Levels.");
parseDatapackFile("../config/AdminCommands.xml");
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _adminCommandAccessRights.size() + " Access Commands.");
}
@Override
public void parseDocument(Document doc)
{
NamedNodeMap attrs;
Node attr;
StatsSet set;
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("access".equalsIgnoreCase(d.getNodeName()))
{
set = new StatsSet();
attrs = d.getAttributes();
for (int i = 0; i < attrs.getLength(); i++)
{
attr = attrs.item(i);
set.set(attr.getNodeName(), attr.getNodeValue());
}
final L2AccessLevel level = new L2AccessLevel(set);
if (level.getLevel() > _highestLevel)
{
_highestLevel = level.getLevel();
}
_accessLevels.put(level.getLevel(), level);
}
else if ("admin".equalsIgnoreCase(d.getNodeName()))
{
set = new StatsSet();
attrs = d.getAttributes();
for (int i = 0; i < attrs.getLength(); i++)
{
attr = attrs.item(i);
set.set(attr.getNodeName(), attr.getNodeValue());
}
final L2AdminCommandAccessRight command = new L2AdminCommandAccessRight(set);
_adminCommandAccessRights.put(command.getAdminCommand(), command);
}
}
}
}
}
/**
* Returns the access level by characterAccessLevel.
* @param accessLevelNum as int
* @return the access level instance by char access level
*/
public L2AccessLevel getAccessLevel(int accessLevelNum)
{
if (accessLevelNum < 0)
{
return _accessLevels.get(-1);
}
if (!_accessLevels.containsKey(accessLevelNum))
{
_accessLevels.put(accessLevelNum, new L2AccessLevel());
}
return _accessLevels.get(accessLevelNum);
}
/**
* Gets the master access level.
* @return the master access level
*/
public L2AccessLevel getMasterAccessLevel()
{
return _accessLevels.get(_highestLevel);
}
/**
* Checks for access level.
* @param id the id
* @return {@code true}, if successful, {@code false} otherwise
*/
public boolean hasAccessLevel(int id)
{
return _accessLevels.containsKey(id);
}
/**
* Checks for access.
* @param adminCommand the admin command
* @param accessLevel the access level
* @return {@code true}, if successful, {@code false} otherwise
*/
public boolean hasAccess(String adminCommand, L2AccessLevel accessLevel)
{
L2AdminCommandAccessRight acar = _adminCommandAccessRights.get(adminCommand);
if (acar == null)
{
// Trying to avoid the spam for next time when the gm would try to use the same command
if ((accessLevel.getLevel() > 0) && (accessLevel.getLevel() == _highestLevel))
{
acar = new L2AdminCommandAccessRight(adminCommand, true, accessLevel.getLevel());
_adminCommandAccessRights.put(adminCommand, acar);
LOGGER.info(getClass().getSimpleName() + ": No rights defined for admin command " + adminCommand + " auto setting accesslevel: " + accessLevel.getLevel() + " !");
}
else
{
LOGGER.info(getClass().getSimpleName() + ": No rights defined for admin command " + adminCommand + " !");
return false;
}
}
return acar.hasAccess(accessLevel);
}
/**
* Require confirm.
* @param command the command
* @return {@code true}, if the command require confirmation, {@code false} otherwise
*/
public boolean requireConfirm(String command)
{
final L2AdminCommandAccessRight acar = _adminCommandAccessRights.get(command);
if (acar == null)
{
LOGGER.info(getClass().getSimpleName() + ": No rights defined for admin command " + command + ".");
return false;
}
return acar.getRequireConfirm();
}
/**
* Gets the all GMs.
* @param includeHidden the include hidden
* @return the all GMs
*/
public List<L2PcInstance> getAllGms(boolean includeHidden)
{
final List<L2PcInstance> tmpGmList = new ArrayList<>();
for (Entry<L2PcInstance, Boolean> entry : _gmList.entrySet())
{
if (includeHidden || !entry.getValue())
{
tmpGmList.add(entry.getKey());
}
}
return tmpGmList;
}
/**
* Gets the all GM names.
* @param includeHidden the include hidden
* @return the all GM names
*/
public List<String> getAllGmNames(boolean includeHidden)
{
final List<String> tmpGmList = new ArrayList<>();
for (Entry<L2PcInstance, Boolean> entry : _gmList.entrySet())
{
if (!entry.getValue())
{
tmpGmList.add(entry.getKey().getName());
}
else if (includeHidden)
{
tmpGmList.add(entry.getKey().getName() + " (invis)");
}
}
return tmpGmList;
}
/**
* Add a L2PcInstance player to the Set _gmList.
* @param player the player
* @param hidden the hidden
*/
public void addGm(L2PcInstance player, boolean hidden)
{
_gmList.put(player, hidden);
}
/**
* Delete a GM.
* @param player the player
*/
public void deleteGm(L2PcInstance player)
{
_gmList.remove(player);
}
/**
* GM will be displayed on clients GM list.
* @param player the player
*/
public void showGm(L2PcInstance player)
{
if (_gmList.containsKey(player))
{
_gmList.put(player, false);
}
}
/**
* GM will no longer be displayed on clients GM list.
* @param player the player
*/
public void hideGm(L2PcInstance player)
{
if (_gmList.containsKey(player))
{
_gmList.put(player, true);
}
}
/**
* Checks if is GM online.
* @param includeHidden the include hidden
* @return true, if is GM online
*/
public boolean isGmOnline(boolean includeHidden)
{
for (Entry<L2PcInstance, Boolean> entry : _gmList.entrySet())
{
if (includeHidden || !entry.getValue())
{
return true;
}
}
return false;
}
/**
* Send list to player.
* @param player the player
*/
public void sendListToPlayer(L2PcInstance player)
{
if (isGmOnline(player.isGM()))
{
player.sendPacket(SystemMessageId.GM_LIST);
for (String name : getAllGmNames(player.isGM()))
{
final SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.GM_C1);
sm.addString(name);
player.sendPacket(sm);
}
}
else
{
player.sendPacket(SystemMessageId.THERE_ARE_NO_GMS_CURRENTLY_VISIBLE_IN_THE_PUBLIC_LIST_AS_THEY_MAY_BE_PERFORMING_OTHER_FUNCTIONS_AT_THE_MOMENT);
}
}
/**
* Broadcast to GMs.
* @param packet the packet
*/
public void broadcastToGMs(L2GameServerPacket packet)
{
for (L2PcInstance gm : getAllGms(true))
{
gm.sendPacket(packet);
}
}
/**
* Broadcast message to GMs.
* @param message the message
*/
public void broadcastMessageToGMs(String message)
{
for (L2PcInstance gm : getAllGms(true))
{
gm.sendMessage(message);
}
}
/**
* Gets the single instance of AdminTable.
* @return AccessLevels: the one and only instance of this class<br>
*/
public static AdminData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final AdminData _instance = new AdminData();
}
}

View File

@@ -0,0 +1,153 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.enums.Race;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.items.appearance.AppearanceStone;
import com.l2jmobius.gameserver.model.items.appearance.AppearanceTargetType;
import com.l2jmobius.gameserver.model.items.type.CrystalType;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* @author UnAfraid
*/
public class AppearanceItemData implements IXmlReader
{
private final Map<Integer, AppearanceStone> _stones = new HashMap<>();
protected AppearanceItemData()
{
load();
}
@Override
public void load()
{
parseDatapackFile("AppearanceStones.xml");
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _stones.size() + " Stones");
//@formatter:off
/*
for (L2Item item : ItemTable.getInstance().getAllItems())
{
if ((item == null) || !item.getName().contains("Appearance Stone"))
{
continue;
}
if (item.getName().contains("Pack") || _stones.containsKey(item.getId()))
{
continue;
}
System.out.println("Unhandled appearance stone: " + item);
}
*/
//@formatter:on
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("appearance_stone".equalsIgnoreCase(d.getNodeName()))
{
final NamedNodeMap attrs = d.getAttributes();
final StatsSet set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
final Node att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
final AppearanceStone stone = new AppearanceStone(set);
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
{
switch (c.getNodeName())
{
case "grade":
{
final CrystalType type = CrystalType.valueOf(c.getTextContent());
stone.addCrystalType(type);
break;
}
case "targetType":
{
final AppearanceTargetType type = AppearanceTargetType.valueOf(c.getTextContent());
stone.addTargetType(type);
break;
}
case "bodyPart":
{
final int part = ItemTable.SLOTS.get(c.getTextContent());
stone.addBodyPart(part);
break;
}
case "race":
{
final Race race = Race.valueOf(c.getTextContent());
stone.addRace(race);
break;
}
case "raceNot":
{
final Race raceNot = Race.valueOf(c.getTextContent());
stone.addRaceNot(raceNot);
break;
}
}
}
_stones.put(stone.getId(), stone);
}
}
}
}
}
public AppearanceStone getStone(int stone)
{
return _stones.get(stone);
}
/**
* Gets the single instance of AppearanceItemData.
* @return single instance of AppearanceItemData
*/
public static AppearanceItemData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final AppearanceItemData _instance = new AppearanceItemData();
}
}

View File

@@ -0,0 +1,220 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.L2ArmorSet;
import com.l2jmobius.gameserver.model.holders.ArmorsetSkillHolder;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* Loads armor set bonuses.
* @author godson, Luno, UnAfraid
*/
public final class ArmorSetsData implements IXmlReader
{
private final Map<Integer, L2ArmorSet> _armorSets = new HashMap<>();
/**
* Instantiates a new armor sets data.
*/
protected ArmorSetsData()
{
load();
}
@Override
public void load()
{
_armorSets.clear();
parseDatapackDirectory("stats/armorsets", false);
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _armorSets.size() + " Armor sets.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("set".equalsIgnoreCase(d.getNodeName()))
{
final L2ArmorSet set = new L2ArmorSet();
set.setIsVisual(parseBoolean(d.getAttributes(), "visual", false));
set.setMinimumPieces(parseInteger(d.getAttributes(), "minimumPieces"));
for (Node a = d.getFirstChild(); a != null; a = a.getNextSibling())
{
final NamedNodeMap attrs = a.getAttributes();
switch (a.getNodeName())
{
case "chest":
{
set.addChest(parseInteger(attrs, "id"));
break;
}
case "feet":
{
set.addFeet(parseInteger(attrs, "id"));
break;
}
case "gloves":
{
set.addGloves(parseInteger(attrs, "id"));
break;
}
case "head":
{
set.addHead(parseInteger(attrs, "id"));
break;
}
case "legs":
{
set.addLegs(parseInteger(attrs, "id"));
break;
}
case "shield":
{
set.addShield(parseInteger(attrs, "id"));
break;
}
case "skill":
{
final int skillId = parseInteger(attrs, "id");
final int skillLevel = parseInteger(attrs, "level");
final int minimumPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minimumPieces));
break;
}
case "shield_skill":
{
final int skillId = parseInteger(attrs, "id");
final int skillLevel = parseInteger(attrs, "level");
set.addShieldSkill(new SkillHolder(skillId, skillLevel));
break;
}
case "enchant6skill":
{
final int skillId = parseInteger(attrs, "id");
final int skillLevel = parseInteger(attrs, "level");
final int minimumEnchant = parseInteger(attrs, "minimumEnchant", 6);
set.addEnchantSkill(new ArmorsetSkillHolder(skillId, skillLevel, minimumEnchant));
break;
}
case "enchant7skill":
{
final int skillId = parseInteger(attrs, "id");
final int skillLevel = parseInteger(attrs, "level");
final int minimumEnchant = parseInteger(attrs, "minimumEnchant", 7);
set.addEnchantSkill(new ArmorsetSkillHolder(skillId, skillLevel, minimumEnchant));
break;
}
case "enchant8skill":
{
final int skillId = parseInteger(attrs, "id");
final int skillLevel = parseInteger(attrs, "level");
final int minimumEnchant = parseInteger(attrs, "minimumEnchant", 8);
set.addEnchantSkill(new ArmorsetSkillHolder(skillId, skillLevel, minimumEnchant));
break;
}
case "con":
{
set.addCon(parseInteger(attrs, "val"));
break;
}
case "dex":
{
set.addDex(parseInteger(attrs, "val"));
break;
}
case "str":
{
set.addStr(parseInteger(attrs, "val"));
break;
}
case "men":
{
set.addMen(parseInteger(attrs, "val"));
break;
}
case "wit":
{
set.addWit(parseInteger(attrs, "val"));
break;
}
case "int":
{
set.addInt(parseInteger(attrs, "val"));
break;
}
}
}
for (int chestId : set.getChests())
{
_armorSets.put(chestId, set);
}
}
}
}
}
}
/**
* Checks if is armor set.
* @param chestId the chest Id to verify.
* @return {@code true} if the chest Id belongs to a registered armor set, {@code false} otherwise.
*/
public boolean isArmorSet(int chestId)
{
return _armorSets.containsKey(chestId);
}
/**
* Gets the sets the.
* @param chestId the chest Id identifying the armor set.
* @return the armor set associated to the give chest Id.
*/
public L2ArmorSet getSet(int chestId)
{
return _armorSets.get(chestId);
}
/**
* Gets the single instance of ArmorSetsData.
* @return single instance of ArmorSetsData
*/
public static ArmorSetsData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final ArmorSetsData _instance = new ArmorSetsData();
}
}

View File

@@ -0,0 +1,160 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.enums.Race;
import com.l2jmobius.gameserver.enums.Sex;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.beautyshop.BeautyData;
import com.l2jmobius.gameserver.model.beautyshop.BeautyItem;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* @author Sdw
*/
public final class BeautyShopData implements IXmlReader
{
private final Map<Race, Map<Sex, BeautyData>> _beautyList = new HashMap<>();
private final Map<Sex, BeautyData> _beautyData = new HashMap<>();
protected BeautyShopData()
{
load();
}
@Override
public synchronized void load()
{
_beautyList.clear();
_beautyData.clear();
parseDatapackFile("BeautyShop.xml");
}
@Override
public void parseDocument(Document doc)
{
NamedNodeMap attrs;
StatsSet set;
Node att;
Race race = null;
Sex sex = null;
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("race".equalsIgnoreCase(d.getNodeName()))
{
att = d.getAttributes().getNamedItem("type");
if (att != null)
{
race = parseEnum(att, Race.class);
}
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("sex".equalsIgnoreCase(b.getNodeName()))
{
att = b.getAttributes().getNamedItem("type");
if (att != null)
{
sex = parseEnum(att, Sex.class);
}
final BeautyData beautyData = new BeautyData();
for (Node a = b.getFirstChild(); a != null; a = a.getNextSibling())
{
if ("hair".equalsIgnoreCase(a.getNodeName()))
{
attrs = a.getAttributes();
set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
final BeautyItem hair = new BeautyItem(set);
for (Node g = a.getFirstChild(); g != null; g = g.getNextSibling())
{
if ("color".equalsIgnoreCase(g.getNodeName()))
{
attrs = g.getAttributes();
set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
hair.addColor(set);
}
}
beautyData.addHair(hair);
}
else if ("face".equalsIgnoreCase(a.getNodeName()))
{
attrs = a.getAttributes();
set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
beautyData.addFace(new BeautyItem(set));
}
}
_beautyData.put(sex, beautyData);
}
}
_beautyList.put(race, _beautyData);
}
}
}
}
}
public boolean hasBeautyData(Race race, Sex sex)
{
return _beautyList.containsKey(race) && _beautyList.get(race).containsKey(sex);
}
public BeautyData getBeautyData(Race race, Sex sex)
{
return _beautyList.containsKey(race) ? _beautyList.get(race).get(sex) : null;
}
public static BeautyShopData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final BeautyShopData _instance = new BeautyShopData();
}
}

View File

@@ -0,0 +1,191 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.io.File;
import java.io.FileFilter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.Config;
import com.l2jmobius.commons.database.DatabaseFactory;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.buylist.L2BuyList;
import com.l2jmobius.gameserver.model.buylist.Product;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.util.data.xml.IXmlReader;
import com.l2jmobius.util.file.filter.NumericNameFilter;
/**
* Loads buy lists for NPCs.
* @author NosBit
*/
public final class BuyListData implements IXmlReader
{
private final Map<Integer, L2BuyList> _buyLists = new HashMap<>();
private static final FileFilter NUMERIC_FILTER = new NumericNameFilter();
protected BuyListData()
{
load();
}
@Override
public synchronized void load()
{
_buyLists.clear();
parseDatapackDirectory("buylists", false);
if (Config.CUSTOM_BUYLIST_LOAD)
{
parseDatapackDirectory("buylists/custom", false);
}
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _buyLists.size() + " BuyLists.");
try (Connection con = DatabaseFactory.getInstance().getConnection();
Statement statement = con.createStatement();
ResultSet rs = statement.executeQuery("SELECT * FROM `buylists`"))
{
while (rs.next())
{
final int buyListId = rs.getInt("buylist_id");
final int itemId = rs.getInt("item_id");
final long count = rs.getLong("count");
final long nextRestockTime = rs.getLong("next_restock_time");
final L2BuyList buyList = getBuyList(buyListId);
if (buyList == null)
{
LOGGER.warning("BuyList found in database but not loaded from xml! BuyListId: " + buyListId);
continue;
}
final Product product = buyList.getProductByItemId(itemId);
if (product == null)
{
LOGGER.warning("ItemId found in database but not loaded from xml! BuyListId: " + buyListId + " ItemId: " + itemId);
continue;
}
if (count < product.getMaxCount())
{
product.setCount(count);
product.restartRestockTask(nextRestockTime);
}
}
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, "Failed to load buyList data from database.", e);
}
}
@Override
public void parseDocument(Document doc, File f)
{
try
{
final int buyListId = Integer.parseInt(f.getName().replaceAll(".xml", ""));
for (Node node = doc.getFirstChild(); node != null; node = node.getNextSibling())
{
if ("list".equalsIgnoreCase(node.getNodeName()))
{
final L2BuyList buyList = new L2BuyList(buyListId);
for (Node list_node = node.getFirstChild(); list_node != null; list_node = list_node.getNextSibling())
{
if ("item".equalsIgnoreCase(list_node.getNodeName()))
{
int itemId = -1;
long price = -1;
long restockDelay = -1;
long count = -1;
final NamedNodeMap attrs = list_node.getAttributes();
Node attr = attrs.getNamedItem("id");
itemId = Integer.parseInt(attr.getNodeValue());
attr = attrs.getNamedItem("price");
if (attr != null)
{
price = Long.parseLong(attr.getNodeValue());
}
attr = attrs.getNamedItem("restock_delay");
if (attr != null)
{
restockDelay = Long.parseLong(attr.getNodeValue());
}
attr = attrs.getNamedItem("count");
if (attr != null)
{
count = Long.parseLong(attr.getNodeValue());
}
final L2Item item = ItemTable.getInstance().getTemplate(itemId);
if (item != null)
{
buyList.addProduct(new Product(buyList.getListId(), item, price, restockDelay, count));
}
else
{
LOGGER.warning("Item not found. BuyList:" + buyList.getListId() + " ItemID:" + itemId + " File:" + f.getName());
}
}
else if ("npcs".equalsIgnoreCase(list_node.getNodeName()))
{
for (Node npcs_node = list_node.getFirstChild(); npcs_node != null; npcs_node = npcs_node.getNextSibling())
{
if ("npc".equalsIgnoreCase(npcs_node.getNodeName()))
{
buyList.addAllowedNpc(Integer.parseInt(npcs_node.getTextContent()));
}
}
}
}
_buyLists.put(buyList.getListId(), buyList);
}
}
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, "Failed to load buyList data from xml File:" + f.getName(), e);
}
}
@Override
public FileFilter getCurrentFileFilter()
{
return NUMERIC_FILTER;
}
public L2BuyList getBuyList(int listId)
{
return _buyLists.get(listId);
}
public static BuyListData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final BuyListData _instance = new BuyListData();
}
}

View File

@@ -0,0 +1,107 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.enums.CastleSide;
import com.l2jmobius.gameserver.model.holders.CastleSpawnHolder;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* @author St3eT
*/
public final class CastleData implements IXmlReader
{
private final Map<Integer, List<CastleSpawnHolder>> _castles = new HashMap<>();
protected CastleData()
{
load();
}
@Override
public void load()
{
_castles.clear();
parseDatapackDirectory("/castles", true);
}
@Override
public void parseDocument(Document doc)
{
for (Node listNode = doc.getFirstChild(); listNode != null; listNode = listNode.getNextSibling())
{
if ("list".equals(listNode.getNodeName()))
{
for (Node castleNode = listNode.getFirstChild(); castleNode != null; castleNode = castleNode.getNextSibling())
{
if ("castle".equals(castleNode.getNodeName()))
{
final int castleId = parseInteger(castleNode.getAttributes(), "id");
final List<CastleSpawnHolder> spawns = new ArrayList<>();
for (Node tpNode = castleNode.getFirstChild(); tpNode != null; tpNode = tpNode.getNextSibling())
{
if ("spawn".equals(tpNode.getNodeName()))
{
final CastleSide side = parseEnum(tpNode.getAttributes(), CastleSide.class, "castleSide", CastleSide.NEUTRAL);
for (Node npcNode = tpNode.getFirstChild(); npcNode != null; npcNode = npcNode.getNextSibling())
{
if ("npc".equals(npcNode.getNodeName()))
{
final NamedNodeMap np = npcNode.getAttributes();
spawns.add(new CastleSpawnHolder(parseInteger(np, "id"), side, parseInteger(np, "x"), parseInteger(np, "y"), parseInteger(np, "z"), parseInteger(np, "heading")));
}
}
}
}
_castles.put(castleId, spawns);
}
}
}
}
}
public final List<CastleSpawnHolder> getSpawnsForSide(int castleId, CastleSide side)
{
return _castles.getOrDefault(castleId, Collections.emptyList()).stream().filter(s -> s.getSide() == side).collect(Collectors.toList());
}
/**
* Gets the single instance of TeleportersData.
* @return single instance of TeleportersData
*/
public static CastleData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final CastleData _instance = new CastleData();
}
}

View File

@@ -0,0 +1,126 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.enums.CategoryType;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* Loads the category data with Class or NPC IDs.
* @author NosBit, xban1x
*/
public final class CategoryData implements IXmlReader
{
private static final Logger LOGGER = Logger.getLogger(CategoryData.class.getName());
private final Map<CategoryType, Set<Integer>> _categories = new HashMap<>();
protected CategoryData()
{
load();
}
@Override
public void load()
{
_categories.clear();
parseDatapackFile("CategoryData.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _categories.size() + " Categories.");
}
@Override
public void parseDocument(Document doc)
{
for (Node node = doc.getFirstChild(); node != null; node = node.getNextSibling())
{
if ("list".equalsIgnoreCase(node.getNodeName()))
{
for (Node list_node = node.getFirstChild(); list_node != null; list_node = list_node.getNextSibling())
{
if ("category".equalsIgnoreCase(list_node.getNodeName()))
{
final NamedNodeMap attrs = list_node.getAttributes();
final CategoryType categoryType = CategoryType.findByName(attrs.getNamedItem("name").getNodeValue());
if (categoryType == null)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Can't find category by name :" + attrs.getNamedItem("name").getNodeValue());
continue;
}
final Set<Integer> ids = new HashSet<>();
for (Node category_node = list_node.getFirstChild(); category_node != null; category_node = category_node.getNextSibling())
{
if ("id".equalsIgnoreCase(category_node.getNodeName()))
{
ids.add(Integer.parseInt(category_node.getTextContent()));
}
}
_categories.put(categoryType, ids);
}
}
}
}
}
/**
* Checks if ID is in category.
* @param type The category type
* @param id The id to be checked
* @return {@code true} if id is in category, {@code false} if id is not in category or category was not found
*/
public boolean isInCategory(CategoryType type, int id)
{
final Set<Integer> category = getCategoryByType(type);
if (category == null)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Can't find category type :" + type);
return false;
}
return category.contains(id);
}
/**
* Gets the category by category type.
* @param type The category type
* @return A {@code Set} containing all the IDs in category if category is found, {@code null} if category was not found
*/
public Set<Integer> getCategoryByType(CategoryType type)
{
return _categories.get(type);
}
public static CategoryData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final CategoryData _instance = new CategoryData();
}
}

View File

@@ -0,0 +1,121 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.base.ClassId;
import com.l2jmobius.gameserver.model.base.ClassInfo;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* Loads the the list of classes and it's info.
* @author Zoey76
*/
public final class ClassListData implements IXmlReader
{
private final Map<ClassId, ClassInfo> _classData = new HashMap<>();
/**
* Instantiates a new class list data.
*/
protected ClassListData()
{
load();
}
@Override
public void load()
{
_classData.clear();
parseDatapackFile("stats/chars/classList.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _classData.size() + " Class data.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equals(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
final NamedNodeMap attrs = d.getAttributes();
if ("class".equals(d.getNodeName()))
{
Node attr = attrs.getNamedItem("classId");
final ClassId classId = ClassId.getClassId(parseInteger(attr));
attr = attrs.getNamedItem("name");
final String className = attr.getNodeValue();
attr = attrs.getNamedItem("parentClassId");
_classData.put(classId, new ClassInfo(classId, className, ((attr != null) ? ClassId.getClassId(parseInteger(attr)) : null)));
}
}
}
}
}
/**
* Gets the class list.
* @return the complete class list
*/
public Map<ClassId, ClassInfo> getClassList()
{
return _classData;
}
/**
* Gets the class info.
* @param classId the class ID
* @return the class info related to the given {@code classId}
*/
public ClassInfo getClass(ClassId classId)
{
return _classData.get(classId);
}
/**
* Gets the class info.
* @param classId the class Id as integer
* @return the class info related to the given {@code classId}
*/
public ClassInfo getClass(int classId)
{
final ClassId id = ClassId.getClassId(classId);
return (id != null) ? _classData.get(id) : null;
}
/**
* Gets the single instance of ClassListData.
* @return single instance of ClassListData
*/
public static ClassListData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final ClassListData _instance = new ClassListData();
}
}

View File

@@ -0,0 +1,262 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.base.ClassId;
import com.l2jmobius.gameserver.model.holders.DailyMissionHolder;
import com.l2jmobius.gameserver.network.serverpackets.dailymission.ExOneDayReceiveRewardList;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* The Class DailyMissionData.
* @author Mobius
*/
public class DailyMissionData implements IXmlReader
{
private final List<DailyMissionHolder> _dailyMissions = new ArrayList<>();
private final List<DailyMissionHolder> _dailyLevelUpMissions = new ArrayList<>();
/**
* Instantiates new daily mission data.
*/
protected DailyMissionData()
{
load();
}
@Override
public void load()
{
_dailyMissions.clear();
_dailyLevelUpMissions.clear();
parseDatapackFile("DailyMissions.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _dailyMissions.size() + " daily missions.");
}
@Override
public void parseDocument(Document doc)
{
int id;
int clientId;
String type;
int level;
List<Integer> classesList;
Map<Integer, Integer> rewards;
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("mission".equalsIgnoreCase(d.getNodeName()))
{
final NamedNodeMap attrs = d.getAttributes();
Node att;
id = -1;
clientId = 0;
type = "";
level = 1;
classesList = new ArrayList<>();
rewards = new HashMap<>();
att = attrs.getNamedItem("id");
if (att == null)
{
LOGGER.severe(getClass().getSimpleName() + ": Missing id for daily mission, skipping");
continue;
}
id = Integer.parseInt(att.getNodeValue());
att = attrs.getNamedItem("clientId");
if (att == null)
{
LOGGER.severe(getClass().getSimpleName() + ": Missing clientId for daily mission id: " + id + ", skipping");
continue;
}
clientId = Integer.parseInt(att.getNodeValue());
att = attrs.getNamedItem("type");
if (att == null)
{
LOGGER.severe(getClass().getSimpleName() + ": Missing type for daily mission id: " + id + ", skipping");
continue;
}
type = att.getNodeValue();
att = attrs.getNamedItem("level");
if (att == null)
{
LOGGER.severe(getClass().getSimpleName() + ": Missing level for daily mission id: " + id + ", skipping");
continue;
}
level = Integer.parseInt(att.getNodeValue());
att = attrs.getNamedItem("classes");
if (att == null)
{
LOGGER.severe(getClass().getSimpleName() + ": Missing classes for daily mission id: " + id + ", skipping");
continue;
}
if (att.getNodeValue().equalsIgnoreCase("ALL"))
{
for (ClassId cid : ClassId.values())
{
classesList.add(cid.getId());
}
}
else
{
for (String element : att.getNodeValue().split(","))
{
classesList.add(Integer.parseInt(element));
}
}
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
{
if ("reward".equalsIgnoreCase(c.getNodeName()))
{
rewards.put(Integer.parseInt(c.getAttributes().getNamedItem("item").getNodeValue()), Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue()));
}
}
if (type.equalsIgnoreCase("LEVEL"))
{
_dailyLevelUpMissions.add(new DailyMissionHolder(id, clientId, type, level, classesList, rewards));
}
_dailyMissions.add(new DailyMissionHolder(id, clientId, type, level, classesList, rewards));
}
}
}
}
}
/**
* @param id int
* @param player L2PcInstance
* @return int
*/
public int RewardStatus(int id, L2PcInstance player)
{
if (player.getLevel() < _dailyMissions.get(id - 1).getLevel())
{
return 2; // Not Available
}
if (player.getVariables().getString("DailyMission" + id, null) != null)
{
return 3; // Complete
}
return 1; // Available
}
/**
* @param rewardId1 int
* @param player L2PcInstance
*/
public void rewardPlayer(int rewardId1, L2PcInstance player)
{
for (DailyMissionHolder mission : _dailyMissions)
{
if ((mission.getClientId() == rewardId1) && (RewardStatus(mission.getId(), player) == 1))
{
for (int classId : mission.getAvailableClasses())
{
if (player.getClassId().getId() == classId)
{
for (int itemId : mission.getRewards().keySet())
{
player.addItem("DailyMission", itemId, mission.getRewards().get(itemId), player, true);
}
for (DailyMissionHolder m : _dailyMissions)
{
if (mission.getClientId() == m.getClientId())
{
player.getVariables().set("DailyMission" + m.getId(), System.currentTimeMillis());
}
}
player.sendPacket(new ExOneDayReceiveRewardList(player));
break;
}
}
}
}
}
/**
* Gets the daily missions.
* @param classId int
* @return the daily missions
*/
public List<DailyMissionHolder> getDailyMissions(int classId)
{
final List<DailyMissionHolder> missions = new ArrayList<>();
for (DailyMissionHolder mission : _dailyMissions)
{
if (mission.getAvailableClasses().contains(classId))
{
missions.add(mission);
}
}
return missions;
}
/**
* Gets the daily level up missions.
* @param classId int
* @return the daily level up missions
*/
public List<DailyMissionHolder> getDailyLevelUpMissions(int classId)
{
final List<DailyMissionHolder> missions = new ArrayList<>();
for (DailyMissionHolder mission : _dailyLevelUpMissions)
{
if (mission.getAvailableClasses().contains(classId))
{
missions.add(mission);
}
}
return missions;
}
/**
* Gets the single instance of DailyMissionData.
* @return single instance of DailyMissionData
*/
public static DailyMissionData getInstance()
{
return SingletonHolder._instance;
}
/**
* The Class SingletonHolder.
*/
private static class SingletonHolder
{
protected static final DailyMissionData _instance = new DailyMissionData();
}
}

View File

@@ -0,0 +1,256 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.instancemanager.InstanceManager;
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.instance.L2DoorInstance;
import com.l2jmobius.gameserver.model.actor.templates.L2DoorTemplate;
import com.l2jmobius.gameserver.pathfinding.AbstractNodeLoc;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* Loads doors.
* @author JIV, GodKratos, UnAfraid
*/
public class DoorData implements IXmlReader
{
private static final Map<String, Set<Integer>> _groups = new HashMap<>();
private final Map<Integer, L2DoorInstance> _doors = new HashMap<>();
private final Map<Integer, StatsSet> _templates = new HashMap<>();
private final Map<Integer, List<L2DoorInstance>> _regions = new HashMap<>();
protected DoorData()
{
load();
}
@Override
public void load()
{
_doors.clear();
_groups.clear();
_regions.clear();
parseDatapackFile("Doors.xml");
}
@Override
public void parseDocument(Document doc)
{
for (Node a = doc.getFirstChild(); a != null; a = a.getNextSibling())
{
if ("list".equalsIgnoreCase(a.getNodeName()))
{
for (Node b = a.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("door".equalsIgnoreCase(b.getNodeName()))
{
final NamedNodeMap attrs = b.getAttributes();
final StatsSet set = new StatsSet();
set.set("baseHpMax", 1); // Avoid doors without HP value created dead due to default value 0 in L2CharTemplate
for (int i = 0; i < attrs.getLength(); i++)
{
final Node att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
makeDoor(set);
_templates.put(set.getInt("id"), set);
}
}
}
}
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _doors.size() + " Door Templates for " + _regions.size() + " regions.");
}
public void insertCollisionData(StatsSet set)
{
int posX, posY, nodeX, nodeY, height;
height = set.getInt("height");
String[] pos = set.getString("node1").split(",");
nodeX = Integer.parseInt(pos[0]);
nodeY = Integer.parseInt(pos[1]);
pos = set.getString("node2").split(",");
posX = Integer.parseInt(pos[0]);
posY = Integer.parseInt(pos[1]);
int collisionRadius = Math.min(Math.abs(nodeX - posX), Math.abs(nodeY - posY)); // (max) radius for movement checks
if (collisionRadius < 20)
{
collisionRadius = 20;
}
set.set("collisionRadius", collisionRadius);
set.set("collisionHeight", height);
}
/**
* @param set
*/
private void makeDoor(StatsSet set)
{
insertCollisionData(set);
final L2DoorTemplate template = new L2DoorTemplate(set);
final L2DoorInstance door = new L2DoorInstance(template);
door.setCurrentHp(door.getMaxHp());
door.spawnMe(template.getX(), template.getY(), template.getZ());
putDoor(door, MapRegionManager.getInstance().getMapRegionLocId(door));
}
public StatsSet getDoorTemplate(int doorId)
{
return _templates.get(doorId);
}
public L2DoorInstance getDoor(int doorId)
{
return _doors.get(doorId);
}
public void putDoor(L2DoorInstance door, int region)
{
_doors.put(door.getId(), door);
if (!_regions.containsKey(region))
{
_regions.put(region, new ArrayList<L2DoorInstance>());
}
_regions.get(region).add(door);
}
public static void addDoorGroup(String groupName, int doorId)
{
Set<Integer> set = _groups.get(groupName);
if (set == null)
{
set = new HashSet<>();
_groups.put(groupName, set);
}
set.add(doorId);
}
public static Set<Integer> getDoorsByGroup(String groupName)
{
return _groups.get(groupName);
}
public Collection<L2DoorInstance> getDoors()
{
return _doors.values();
}
public boolean checkIfDoorsBetween(AbstractNodeLoc start, AbstractNodeLoc end, int instanceId)
{
return checkIfDoorsBetween(start.getX(), start.getY(), start.getZ(), end.getX(), end.getY(), end.getZ(), instanceId);
}
public boolean checkIfDoorsBetween(int x, int y, int z, int tx, int ty, int tz, int instanceId)
{
return checkIfDoorsBetween(x, y, z, tx, ty, tz, instanceId, false);
}
/**
* GodKratos: TODO: remove GeoData checks from door table and convert door nodes to Geo zones
* @param x
* @param y
* @param z
* @param tx
* @param ty
* @param tz
* @param instanceId
* @param doubleFaceCheck
* @return {@code boolean}
*/
public boolean checkIfDoorsBetween(int x, int y, int z, int tx, int ty, int tz, int instanceId, boolean doubleFaceCheck)
{
Collection<L2DoorInstance> allDoors;
if ((instanceId > 0) && (InstanceManager.getInstance().getInstance(instanceId) != null))
{
allDoors = InstanceManager.getInstance().getInstance(instanceId).getDoors();
}
else
{
allDoors = _regions.get(MapRegionManager.getInstance().getMapRegionLocId(x, y));
}
if (allDoors == null)
{
return false;
}
for (L2DoorInstance doorInst : allDoors)
{
// check dead and open
if (doorInst.isDead() || doorInst.getOpen() || !doorInst.checkCollision() || (doorInst.getX(0) == 0))
{
continue;
}
boolean intersectFace = false;
for (int i = 0; i < 4; i++)
{
final int j = (i + 1) < 4 ? i + 1 : 0;
// lower part of the multiplier fraction, if it is 0 we avoid an error and also know that the lines are parallel
final int denominator = ((ty - y) * (doorInst.getX(i) - doorInst.getX(j))) - ((tx - x) * (doorInst.getY(i) - doorInst.getY(j)));
if (denominator == 0)
{
continue;
}
// multipliers to the equations of the lines. If they are lower than 0 or bigger than 1, we know that segments don't intersect
final float multiplier1 = (float) (((doorInst.getX(j) - doorInst.getX(i)) * (y - doorInst.getY(i))) - ((doorInst.getY(j) - doorInst.getY(i)) * (x - doorInst.getX(i)))) / denominator;
final float multiplier2 = (float) (((tx - x) * (y - doorInst.getY(i))) - ((ty - y) * (x - doorInst.getX(i)))) / denominator;
if ((multiplier1 >= 0) && (multiplier1 <= 1) && (multiplier2 >= 0) && (multiplier2 <= 1))
{
final int intersectZ = Math.round(z + (multiplier1 * (tz - z)));
// now checking if the resulting point is between door's min and max z
if ((intersectZ > doorInst.getZMin()) && (intersectZ < doorInst.getZMax()))
{
if (!doubleFaceCheck || intersectFace)
{
return true;
}
intersectFace = true;
}
}
}
}
return false;
}
public static DoorData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final DoorData _instance = new DoorData();
}
}

View File

@@ -0,0 +1,202 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.enums.StatFunction;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.items.type.CrystalType;
import com.l2jmobius.gameserver.model.stats.Stats;
import com.l2jmobius.gameserver.model.stats.functions.FuncTemplate;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* This class holds the Enchant HP Bonus Data.
* @author MrPoke, Zoey76
*/
public class EnchantItemBonusData implements IXmlReader
{
private final Map<CrystalType, List<Integer>> _armorHPBonuses = new EnumMap<>(CrystalType.class);
private static final float FULL_ARMOR_MODIFIER = 1.5f; // TODO: Move it to config!
/**
* Instantiates a new enchant hp bonus data.
*/
protected EnchantItemBonusData()
{
load();
}
@Override
public void load()
{
_armorHPBonuses.clear();
parseDatapackFile("stats/enchantHPBonus.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _armorHPBonuses.size() + " Enchant HP Bonuses.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("enchantHP".equalsIgnoreCase(d.getNodeName()))
{
final List<Integer> bonuses = new ArrayList<>(12);
for (Node e = d.getFirstChild(); e != null; e = e.getNextSibling())
{
if ("bonus".equalsIgnoreCase(e.getNodeName()))
{
bonuses.add(Integer.parseInt(e.getTextContent()));
}
}
_armorHPBonuses.put(parseEnum(d.getAttributes(), CrystalType.class, "grade"), bonuses);
}
}
}
}
if (_armorHPBonuses.isEmpty())
{
return;
}
final ItemTable it = ItemTable.getInstance();
for (Integer itemId : it.getAllArmorsId())
{
final L2Item item = it.getTemplate(itemId);
if ((item != null) && (item.getCrystalType() != CrystalType.NONE))
{
switch (item.getBodyPart())
{
case L2Item.SLOT_CHEST:
{
if (item.getCrystalTypePlus() == CrystalType.R)
{
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTPATK.getName(), -1, Stats.POWER_ATTACK, 0));
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTMATK.getName(), -1, Stats.MAGIC_ATTACK, 0));
break;
}
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTHP.getName(), -1, Stats.MAX_HP, 0));
break;
}
case L2Item.SLOT_FEET:
{
if (item.getCrystalTypePlus() == CrystalType.R)
{
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTRUNSPD.getName(), -1, Stats.MOVE_SPEED, 0));
break;
}
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTHP.getName(), -1, Stats.MAX_HP, 0));
break;
}
case L2Item.SLOT_GLOVES:
{
if (item.getCrystalTypePlus() == CrystalType.R)
{
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTACCEVAS.getName(), -1, Stats.ACCURACY_COMBAT, 0));
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTACCEVAS.getName(), -1, Stats.ACCURACY_MAGIC, 0));
break;
}
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTHP.getName(), -1, Stats.MAX_HP, 0));
break;
}
case L2Item.SLOT_HEAD:
{
if (item.getCrystalTypePlus() == CrystalType.R)
{
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTACCEVAS.getName(), -1, Stats.EVASION_RATE, 0));
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTACCEVAS.getName(), -1, Stats.MAGIC_EVASION_RATE, 0));
break;
}
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTHP.getName(), -1, Stats.MAX_HP, 0));
break;
}
case L2Item.SLOT_LEGS:
{
if (item.getCrystalTypePlus() == CrystalType.R)
{
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTPMCRITRATE.getName(), -1, Stats.CRITICAL_RATE, 0));
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTPMCRITRATE.getName(), -1, Stats.MCRITICAL_RATE, 0));
break;
}
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTHP.getName(), -1, Stats.MAX_HP, 0));
break;
}
case L2Item.SLOT_BACK:
case L2Item.SLOT_FULL_ARMOR:
case L2Item.SLOT_UNDERWEAR:
case L2Item.SLOT_L_HAND:
case L2Item.SLOT_BELT:
{
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTHP.getName(), -1, Stats.MAX_HP, 0));
break;
}
default:
{
break;
}
}
}
}
}
/**
* Gets the HP bonus.
* @param item the item
* @return the HP bonus
*/
public final int getHPBonus(L2ItemInstance item)
{
final List<Integer> values = _armorHPBonuses.get(item.getItem().getCrystalTypePlus());
if ((values == null) || values.isEmpty() || (item.getOlyEnchantLevel() <= 0))
{
return 0;
}
final double blessedArmorBonus = item.isBlessedItem() ? 1.5 : 1;
final int bonus = values.get(Math.min(item.getOlyEnchantLevel(), values.size()) - 1);
return item.getItem().getBodyPart() == L2Item.SLOT_FULL_ARMOR ? (int) (bonus * FULL_ARMOR_MODIFIER * blessedArmorBonus) : bonus;
}
/**
* Gets the single instance of EnchantBonusData.
* @return single instance of EnchantBonusData
*/
public static EnchantItemBonusData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final EnchantItemBonusData _instance = new EnchantItemBonusData();
}
}

View File

@@ -0,0 +1,165 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.items.enchant.EnchantScroll;
import com.l2jmobius.gameserver.model.items.enchant.EnchantSupportItem;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* Loads item enchant data.
* @author UnAfraid
*/
public class EnchantItemData implements IXmlReader
{
private final Map<Integer, EnchantScroll> _scrolls = new HashMap<>();
private final Map<Integer, EnchantSupportItem> _supports = new HashMap<>();
/**
* Instantiates a new enchant item data.
*/
public EnchantItemData()
{
load();
}
@Override
public synchronized void load()
{
_scrolls.clear();
_supports.clear();
parseDatapackFile("EnchantItemData.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _scrolls.size() + " Enchant Scrolls.");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _supports.size() + " Support Items.");
}
@Override
public void parseDocument(Document doc)
{
StatsSet set;
Node att;
NamedNodeMap attrs;
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("enchant".equalsIgnoreCase(d.getNodeName()))
{
attrs = d.getAttributes();
set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
try
{
final EnchantScroll item = new EnchantScroll(set);
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
{
if ("item".equalsIgnoreCase(cd.getNodeName()))
{
item.addItem(parseInteger(cd.getAttributes(), "id"));
}
}
_scrolls.put(item.getId(), item);
}
catch (NullPointerException e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Unexistent enchant scroll: " + set.getString("id") + " defined in enchant data!");
}
catch (IllegalAccessError e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Wrong enchant scroll item type: " + set.getString("id") + " defined in enchant data!");
}
}
else if ("support".equalsIgnoreCase(d.getNodeName()))
{
attrs = d.getAttributes();
set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
try
{
final EnchantSupportItem item = new EnchantSupportItem(set);
_supports.put(item.getId(), item);
}
catch (NullPointerException e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Unexistent enchant support item: " + set.getString("id") + " defined in enchant data!");
}
catch (IllegalAccessError e)
{
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Wrong enchant support item type: " + set.getString("id") + " defined in enchant data!");
}
}
}
}
}
}
/**
* Gets the enchant scroll.
* @param scroll the scroll
* @return enchant template for scroll
*/
public final EnchantScroll getEnchantScroll(L2ItemInstance scroll)
{
return _scrolls.get(scroll.getId());
}
/**
* Gets the support item.
* @param item the item
* @return enchant template for support item
*/
public final EnchantSupportItem getSupportItem(L2ItemInstance item)
{
return _supports.get(item.getId());
}
/**
* Gets the single instance of EnchantItemData.
* @return single instance of EnchantItemData
*/
public static EnchantItemData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final EnchantItemData _instance = new EnchantItemData();
}
}

View File

@@ -0,0 +1,166 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.holders.RangeChanceHolder;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.items.enchant.EnchantItemGroup;
import com.l2jmobius.gameserver.model.items.enchant.EnchantRateItem;
import com.l2jmobius.gameserver.model.items.enchant.EnchantScrollGroup;
import com.l2jmobius.gameserver.util.Util;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* @author UnAfraid
*/
public final class EnchantItemGroupsData implements IXmlReader
{
private final Map<String, EnchantItemGroup> _itemGroups = new HashMap<>();
private final Map<Integer, EnchantScrollGroup> _scrollGroups = new HashMap<>();
protected EnchantItemGroupsData()
{
load();
}
@Override
public synchronized void load()
{
_itemGroups.clear();
_scrollGroups.clear();
parseDatapackFile("EnchantItemGroups.xml");
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _itemGroups.size() + " item group templates.");
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _scrollGroups.size() + " scroll group templates.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("enchantRateGroup".equalsIgnoreCase(d.getNodeName()))
{
final String name = parseString(d.getAttributes(), "name");
final EnchantItemGroup group = new EnchantItemGroup(name);
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
{
if ("current".equalsIgnoreCase(cd.getNodeName()))
{
final String range = parseString(cd.getAttributes(), "enchant");
final double chance = parseDouble(cd.getAttributes(), "chance");
int min = -1;
int max = 0;
if (range.contains("-"))
{
final String[] split = range.split("-");
if ((split.length == 2) && Util.isDigit(split[0]) && Util.isDigit(split[1]))
{
min = Integer.parseInt(split[0]);
max = Integer.parseInt(split[1]);
}
}
else if (Util.isDigit(range))
{
min = Integer.parseInt(range);
max = min;
}
if ((min > -1) && (max > 0))
{
group.addChance(new RangeChanceHolder(min, max, chance));
}
}
}
_itemGroups.put(name, group);
}
else if ("enchantScrollGroup".equals(d.getNodeName()))
{
final int id = parseInteger(d.getAttributes(), "id");
final EnchantScrollGroup group = new EnchantScrollGroup(id);
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
{
if ("enchantRate".equalsIgnoreCase(cd.getNodeName()))
{
final EnchantRateItem rateGroup = new EnchantRateItem(parseString(cd.getAttributes(), "group"));
for (Node z = cd.getFirstChild(); z != null; z = z.getNextSibling())
{
if ("item".equals(z.getNodeName()))
{
final NamedNodeMap attrs = z.getAttributes();
if (attrs.getNamedItem("slot") != null)
{
rateGroup.addSlot(ItemTable.SLOTS.get(parseString(attrs, "slot")));
}
if (attrs.getNamedItem("magicWeapon") != null)
{
rateGroup.setMagicWeapon(parseBoolean(attrs, "magicWeapon"));
}
if (attrs.getNamedItem("id") != null)
{
rateGroup.setItemId(parseInteger(attrs, "id"));
}
}
}
group.addRateGroup(rateGroup);
}
}
_scrollGroups.put(id, group);
}
}
}
}
}
public EnchantItemGroup getItemGroup(L2Item item, int scrollGroup)
{
final EnchantScrollGroup group = _scrollGroups.get(scrollGroup);
final EnchantRateItem rateGroup = group.getRateGroup(item);
return rateGroup != null ? _itemGroups.get(rateGroup.getName()) : null;
}
public EnchantItemGroup getItemGroup(String name)
{
return _itemGroups.get(name);
}
public EnchantScrollGroup getScrollGroup(int id)
{
return _scrollGroups.get(id);
}
public static EnchantItemGroupsData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final EnchantItemGroupsData _instance = new EnchantItemGroupsData();
}
}

View File

@@ -0,0 +1,124 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.model.options.EnchantOptions;
import com.l2jmobius.gameserver.util.Util;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* @author UnAfraid
*/
public class EnchantItemOptionsData implements IXmlReader
{
private final Map<Integer, Map<Integer, EnchantOptions>> _data = new HashMap<>();
protected EnchantItemOptionsData()
{
load();
}
@Override
public synchronized void load()
{
_data.clear();
parseDatapackFile("EnchantItemOptions.xml");
}
@Override
public void parseDocument(Document doc)
{
int counter = 0;
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("item".equalsIgnoreCase(d.getNodeName()))
{
final int itemId = parseInteger(d.getAttributes(), "id");
if (!_data.containsKey(itemId))
{
_data.put(itemId, new HashMap<Integer, EnchantOptions>());
}
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
{
if ("options".equalsIgnoreCase(cd.getNodeName()))
{
final EnchantOptions op = new EnchantOptions(parseInteger(cd.getAttributes(), "level"));
_data.get(itemId).put(op.getLevel(), op);
for (byte i = 0; i < 3; i++)
{
final Node att = cd.getAttributes().getNamedItem("option" + (i + 1));
if ((att != null) && Util.isDigit(att.getNodeValue()))
{
op.setOption(i, parseInteger(att));
}
}
counter++;
}
}
}
}
}
}
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _data.size() + " Items and " + counter + " Options.");
}
/**
* @param itemId
* @param enchantLevel
* @return enchant effects information.
*/
public EnchantOptions getOptions(int itemId, int enchantLevel)
{
return !_data.containsKey(itemId) || !_data.get(itemId).containsKey(enchantLevel) ? null : _data.get(itemId).get(enchantLevel);
}
/**
* @param item
* @return enchant effects information.
*/
public EnchantOptions getOptions(L2ItemInstance item)
{
return item != null ? getOptions(item.getId(), item.getEnchantLevel()) : null;
}
/**
* Gets the single instance of EnchantOptionsData.
* @return single instance of EnchantOptionsData
*/
public static EnchantItemOptionsData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final EnchantItemOptionsData _instance = new EnchantItemOptionsData();
}
}

View File

@@ -0,0 +1,258 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.L2EnchantSkillGroup;
import com.l2jmobius.gameserver.model.L2EnchantSkillGroup.EnchantSkillHolder;
import com.l2jmobius.gameserver.model.L2EnchantSkillLearn;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* This class holds the Enchant Groups information.
* @author Micr0
*/
public class EnchantSkillGroupsData implements IXmlReader
{
public static final int NORMAL_ENCHANT_COST_MULTIPLIER = Config.NORMAL_ENCHANT_COST_MULTIPLIER;
public static final int SAFE_ENCHANT_COST_MULTIPLIER = Config.SAFE_ENCHANT_COST_MULTIPLIER;
public static final int NORMAL_ENCHANT_BOOK_OLD = 6622;
public static final int SAFE_ENCHANT_BOOK_OLD = 9627;
public static final int CHANGE_ENCHANT_BOOK_OLD = 9626;
public static final int UNTRAIN_ENCHANT_BOOK_OLD = 9625;
public static final int NORMAL_ENCHANT_BOOK = 30297;
public static final int SAFE_ENCHANT_BOOK = 30298;
public static final int CHANGE_ENCHANT_BOOK = 30299;
public static final int UNTRAIN_ENCHANT_BOOK = 30300;
public static final int IMMORTAL_SCROLL = 37044;
public static final int NORMAL_ENCHANT_BOOK_V2 = 46150;
public static final int SAFE_ENCHANT_BOOK_V2 = 46151;
public static final int CHANGE_ENCHANT_BOOK_V2 = 46152;
public static final int IMMORTAL_SCROLL_V2 = 46153;
public static final int NORMAL_ENCHANT_BOOK_V3 = 46154;
public static final int SAFE_ENCHANT_BOOK_V3 = 46155;
public static final int CHANGE_ENCHANT_BOOK_V3 = 46156;
public static final int IMMORTAL_SCROLL_V3 = 46157;
private final Map<Integer, L2EnchantSkillGroup> _enchantSkillGroups = new HashMap<>();
private final Map<Integer, L2EnchantSkillLearn> _enchantSkillTrees = new HashMap<>();
/**
* Instantiates a new enchant groups table.
*/
protected EnchantSkillGroupsData()
{
load();
}
@Override
public void load()
{
_enchantSkillGroups.clear();
_enchantSkillTrees.clear();
parseDatapackFile("EnchantSkillGroups.xml");
int routes = 0;
for (L2EnchantSkillGroup group : _enchantSkillGroups.values())
{
routes += group.getEnchantGroupDetails().size();
}
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _enchantSkillGroups.size() + " groups and " + routes + " routes.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("group".equalsIgnoreCase(d.getNodeName()))
{
NamedNodeMap attrs = d.getAttributes();
final int id = parseInteger(attrs, "id");
L2EnchantSkillGroup group = _enchantSkillGroups.get(id);
if (group == null)
{
group = new L2EnchantSkillGroup(id);
_enchantSkillGroups.put(id, group);
}
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("enchant".equalsIgnoreCase(b.getNodeName()))
{
attrs = b.getAttributes();
final StatsSet set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
final Node att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
group.addEnchantDetail(new EnchantSkillHolder(set));
}
}
}
}
}
}
}
/**
* Adds the new route for skill.
* @param skillId the skill id
* @param maxLvL the max lvl
* @param route the route
* @param group the group
* @return the int
*/
public int addNewRouteForSkill(int skillId, int maxLvL, int route, int group)
{
L2EnchantSkillLearn enchantableSkill = _enchantSkillTrees.get(skillId);
if (enchantableSkill == null)
{
enchantableSkill = new L2EnchantSkillLearn(skillId, maxLvL);
_enchantSkillTrees.put(skillId, enchantableSkill);
}
if (_enchantSkillGroups.containsKey(group))
{
enchantableSkill.addNewEnchantRoute(route, group);
return _enchantSkillGroups.get(group).getEnchantGroupDetails().size();
}
LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Error while loading generating enchant skill id: " + skillId + "; route: " + route + "; missing group: " + group);
return 0;
}
/**
* Gets the skill enchantment for skill.
* @param skill the skill
* @return the skill enchantment for skill
*/
public L2EnchantSkillLearn getSkillEnchantmentForSkill(Skill skill)
{
// there is enchantment for this skill and we have the required level of it
final L2EnchantSkillLearn esl = getSkillEnchantmentBySkillId(skill.getId());
return (esl != null) && (skill.getLevel() >= esl.getBaseLevel()) ? esl : null;
}
/**
* Gets the skill enchantment by skill id.
* @param skillId the skill id
* @return the skill enchantment by skill id
*/
public L2EnchantSkillLearn getSkillEnchantmentBySkillId(int skillId)
{
return _enchantSkillTrees.get(skillId);
}
/**
* Gets the enchant skill group by id.
* @param id the id
* @return the enchant skill group by id
*/
public L2EnchantSkillGroup getEnchantSkillGroupById(int id)
{
return _enchantSkillGroups.get(id);
}
/**
* Gets the enchant skill sp cost.
* @param skill the skill
* @return the enchant skill sp cost
*/
public int getEnchantSkillSpCost(Skill skill)
{
final L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
if (enchantSkillLearn != null)
{
final EnchantSkillHolder esh = enchantSkillLearn.getEnchantSkillHolder(skill.getLevel());
if (esh != null)
{
return esh.getSpCost();
}
}
return Integer.MAX_VALUE;
}
/**
* Gets the enchant skill Adena cost.
* @param skill the skill
* @return the enchant skill Adena cost
*/
public int getEnchantSkillAdenaCost(Skill skill)
{
final L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
if (enchantSkillLearn != null)
{
final EnchantSkillHolder esh = enchantSkillLearn.getEnchantSkillHolder(skill.getLevel());
if (esh != null)
{
return esh.getAdenaCost();
}
}
return Integer.MAX_VALUE;
}
/**
* Gets the enchant skill rate.
* @param player the player
* @param skill the skill
* @return the enchant skill rate
*/
public byte getEnchantSkillRate(L2PcInstance player, Skill skill)
{
final L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
if (enchantSkillLearn != null)
{
final EnchantSkillHolder esh = enchantSkillLearn.getEnchantSkillHolder(skill.getLevel());
if (esh != null)
{
return esh.getRate(player);
}
}
return 0;
}
/**
* Gets the single instance of EnchantGroupsData.
* @return single instance of EnchantGroupsData
*/
public static EnchantSkillGroupsData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final EnchantSkillGroupsData _instance = new EnchantSkillGroupsData();
}
}

View File

@@ -0,0 +1,137 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.Config;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* This class holds the Experience points for each level for players and pets.
* @author mrTJO
*/
public final class ExperienceData implements IXmlReader
{
private final Map<Integer, Long> _expTable = new HashMap<>();
private byte MAX_LEVEL;
private byte MAX_PET_LEVEL;
/**
* Instantiates a new experience table.
*/
protected ExperienceData()
{
load();
}
@Override
public void load()
{
_expTable.clear();
parseDatapackFile("stats/experience.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + (_expTable.size() - 1) + " levels.");
LOGGER.info(getClass().getSimpleName() + ": Max Player Level is: " + (MAX_LEVEL - 1));
LOGGER.info(getClass().getSimpleName() + ": Max Pet Level is: " + (MAX_PET_LEVEL - 1));
}
@Override
public void parseDocument(Document doc)
{
final Node table = doc.getFirstChild();
final NamedNodeMap tableAttr = table.getAttributes();
MAX_LEVEL = (byte) (Byte.parseByte(tableAttr.getNamedItem("maxLevel").getNodeValue()) + 1);
MAX_PET_LEVEL = (byte) (Byte.parseByte(tableAttr.getNamedItem("maxPetLevel").getNodeValue()) + 1);
if (MAX_LEVEL > Config.PLAYER_MAXIMUM_LEVEL)
{
MAX_LEVEL = Config.PLAYER_MAXIMUM_LEVEL;
}
if (MAX_PET_LEVEL > MAX_LEVEL)
{
MAX_PET_LEVEL = MAX_LEVEL; // Pet level should not exceed owner level.
}
int maxLevel = 0;
for (Node n = table.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("experience".equals(n.getNodeName()))
{
final NamedNodeMap attrs = n.getAttributes();
maxLevel = parseInteger(attrs, "level");
if (maxLevel > Config.PLAYER_MAXIMUM_LEVEL)
{
break;
}
_expTable.put(maxLevel, parseLong(attrs, "tolevel"));
}
}
}
/**
* Gets the exp for level.
* @param level the level required.
* @return the experience points required to reach the given level.
*/
public long getExpForLevel(int level)
{
if (level > Config.PLAYER_MAXIMUM_LEVEL)
{
level = Config.PLAYER_MAXIMUM_LEVEL;
}
return _expTable.get(level);
}
/**
* Gets the max level.
* @return the maximum level acquirable by a player.
*/
public byte getMaxLevel()
{
return MAX_LEVEL;
}
/**
* Gets the max pet level.
* @return the maximum level acquirable by a pet.
*/
public byte getMaxPetLevel()
{
return MAX_PET_LEVEL;
}
/**
* Gets the single instance of ExperienceTable.
* @return single instance of ExperienceTable
*/
public static ExperienceData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final ExperienceData _instance = new ExperienceData();
}
}

View File

@@ -0,0 +1,169 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.fishing.L2Fish;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* This class holds the Fish information.
* @author nonom
*/
public final class FishData implements IXmlReader
{
private final Map<Integer, L2Fish> _fishNormal = new HashMap<>();
private final Map<Integer, L2Fish> _fishEasy = new HashMap<>();
private final Map<Integer, L2Fish> _fishHard = new HashMap<>();
/**
* Instantiates a new fish data.
*/
protected FishData()
{
load();
}
@Override
public void load()
{
_fishEasy.clear();
_fishNormal.clear();
_fishHard.clear();
parseDatapackFile("stats/fishing/fishes.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + (_fishEasy.size() + _fishNormal.size() + _fishHard.size()) + " Fishes.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("fish".equalsIgnoreCase(d.getNodeName()))
{
final NamedNodeMap attrs = d.getAttributes();
final StatsSet set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
final Node att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
final L2Fish fish = new L2Fish(set);
switch (fish.getFishGrade())
{
case 0:
{
_fishEasy.put(fish.getFishId(), fish);
break;
}
case 1:
{
_fishNormal.put(fish.getFishId(), fish);
break;
}
case 2:
{
_fishHard.put(fish.getFishId(), fish);
break;
}
}
}
}
}
}
}
/**
* Gets the fish.
* @param level the fish Level
* @param group the fish Group
* @param grade the fish Grade
* @return List of Fish that can be fished
*/
public List<L2Fish> getFish(int level, int group, int grade)
{
final ArrayList<L2Fish> result = new ArrayList<>();
Map<Integer, L2Fish> fish = null;
switch (grade)
{
case 0:
{
fish = _fishEasy;
break;
}
case 1:
{
fish = _fishNormal;
break;
}
case 2:
{
fish = _fishHard;
break;
}
default:
{
LOGGER.warning(getClass().getSimpleName() + ": Unmanaged fish grade!");
return result;
}
}
for (L2Fish f : fish.values())
{
if ((f.getFishLevel() != level) || (f.getFishGroup() != group))
{
continue;
}
result.add(f);
}
if (result.isEmpty())
{
LOGGER.warning(getClass().getSimpleName() + ": Cannot find any fish for level: " + level + " group: " + group + " and grade: " + grade + "!");
}
return result;
}
/**
* Gets the single instance of FishData.
* @return single instance of FishData
*/
public static FishData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final FishData _instance = new FishData();
}
}

View File

@@ -0,0 +1,121 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.fishing.L2FishingMonster;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* This class holds the Fishing Monsters information.
* @author nonom
*/
public final class FishingMonstersData implements IXmlReader
{
private final Map<Integer, L2FishingMonster> _fishingMonstersData = new HashMap<>();
/**
* Instantiates a new fishing monsters data.
*/
protected FishingMonstersData()
{
load();
}
@Override
public void load()
{
_fishingMonstersData.clear();
parseDatapackFile("stats/fishing/fishingMonsters.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _fishingMonstersData.size() + " Fishing Monsters.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("fishingMonster".equalsIgnoreCase(d.getNodeName()))
{
final NamedNodeMap attrs = d.getAttributes();
final StatsSet set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
final Node att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
final L2FishingMonster fishingMonster = new L2FishingMonster(set);
_fishingMonstersData.put(fishingMonster.getFishingMonsterId(), fishingMonster);
}
}
}
}
}
/**
* Gets the fishing monster.
* @param lvl the fisherman level
* @return a fishing monster given the fisherman level
*/
public L2FishingMonster getFishingMonster(int lvl)
{
for (L2FishingMonster fishingMonster : _fishingMonstersData.values())
{
if ((lvl >= fishingMonster.getUserMinLevel()) && (lvl <= fishingMonster.getUserMaxLevel()))
{
return fishingMonster;
}
}
return null;
}
/**
* Gets the fishing monster by Id.
* @param id the fishing monster Id
* @return the fishing monster by Id
*/
public L2FishingMonster getFishingMonsterById(int id)
{
return _fishingMonstersData.containsKey(id) ? _fishingMonstersData.get(id) : null;
}
/**
* Gets the single instance of FishingMonsterData.
* @return single instance of FishingMonsterData
*/
public static FishingMonstersData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final FishingMonstersData _instance = new FishingMonstersData();
}
}

View File

@@ -0,0 +1,104 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.fishing.L2FishingRod;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* This class holds the Fishing Rods information.
* @author nonom
*/
public final class FishingRodsData implements IXmlReader
{
private final Map<Integer, L2FishingRod> _fishingRods = new HashMap<>();
/**
* Instantiates a new fishing rods data.
*/
protected FishingRodsData()
{
load();
}
@Override
public void load()
{
_fishingRods.clear();
parseDatapackFile("stats/fishing/fishingRods.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _fishingRods.size() + " Fishing Rods.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("fishingRod".equalsIgnoreCase(d.getNodeName()))
{
final NamedNodeMap attrs = d.getAttributes();
final StatsSet set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
final Node att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
final L2FishingRod fishingRod = new L2FishingRod(set);
_fishingRods.put(fishingRod.getFishingRodItemId(), fishingRod);
}
}
}
}
}
/**
* Gets the fishing rod.
* @param itemId the item id
* @return A fishing Rod by Item Id
*/
public L2FishingRod getFishingRod(int itemId)
{
return _fishingRods.get(itemId);
}
/**
* Gets the single instance of FishingRodsData.
* @return single instance of FishingRodsData
*/
public static FishingRodsData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final FishingRodsData _instance = new FishingRodsData();
}
}

View File

@@ -0,0 +1,192 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.base.ClassId;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
import com.l2jmobius.gameserver.model.items.L2Henna;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* This class holds the henna related information.<br>
* Cost and required amount to add the henna to the player.<br>
* Cost and retrieved amount for removing the henna from the player.<br>
* Allowed classes to wear each henna.
* @author Zoey76
*/
public final class HennaData implements IXmlReader
{
private final Map<Integer, L2Henna> _hennaList = new HashMap<>();
/**
* Instantiates a new henna data.
*/
protected HennaData()
{
load();
}
@Override
public void load()
{
_hennaList.clear();
parseDatapackFile("stats/hennaList.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _hennaList.size() + " Henna data.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equals(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("henna".equals(d.getNodeName()))
{
parseHenna(d);
}
}
}
}
}
/**
* Parses the henna.
* @param d the d
*/
private void parseHenna(Node d)
{
final StatsSet set = new StatsSet();
final List<ClassId> wearClassIds = new ArrayList<>();
final List<SkillHolder> skills = new ArrayList<>();
NamedNodeMap attrs = d.getAttributes();
Node attr;
for (int i = 0; i < attrs.getLength(); i++)
{
attr = attrs.item(i);
set.set(attr.getNodeName(), attr.getNodeValue());
}
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
{
final String name = c.getNodeName();
attrs = c.getAttributes();
switch (name)
{
case "stats":
{
for (int i = 0; i < attrs.getLength(); i++)
{
attr = attrs.item(i);
set.set(attr.getNodeName(), attr.getNodeValue());
}
break;
}
case "wear":
{
attr = attrs.getNamedItem("count");
set.set("wear_count", attr.getNodeValue());
attr = attrs.getNamedItem("fee");
set.set("wear_fee", attr.getNodeValue());
break;
}
case "cancel":
{
attr = attrs.getNamedItem("count");
set.set("cancel_count", attr.getNodeValue());
attr = attrs.getNamedItem("fee");
set.set("cancel_fee", attr.getNodeValue());
break;
}
case "skills":
{
for (Node i = c.getFirstChild(); i != null; i = i.getNextSibling())
{
if ("skill".equals(i.getNodeName()))
{
skills.add(new SkillHolder(Integer.parseInt(i.getAttributes().getNamedItem("id").getNodeValue()), Integer.parseInt(i.getAttributes().getNamedItem("level").getNodeValue())));
}
}
break;
}
case "classId":
{
wearClassIds.add(ClassId.getClassId(Integer.parseInt(c.getTextContent())));
break;
}
}
}
final L2Henna henna = new L2Henna(set);
henna.setWearClassIds(wearClassIds);
henna.setSkills(skills);
_hennaList.put(henna.getDyeId(), henna);
}
/**
* Gets the henna.
* @param id of the dye.
* @return the dye with that id.
*/
public L2Henna getHenna(int id)
{
return _hennaList.get(id);
}
/**
* Gets the henna list.
* @param classId the player's class Id.
* @return the list with all the allowed dyes.
*/
public List<L2Henna> getHennaList(ClassId classId)
{
final List<L2Henna> list = new ArrayList<>();
for (L2Henna henna : _hennaList.values())
{
if (henna.isAllowedClass(classId))
{
list.add(henna);
}
}
return list;
}
/**
* Gets the single instance of HennaData.
* @return single instance of HennaData
*/
public static HennaData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final HennaData _instance = new HennaData();
}
}

View File

@@ -0,0 +1,172 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.GameTimeController;
import com.l2jmobius.gameserver.model.actor.L2Character;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* This class load, holds and calculates the hit condition bonuses.
* @author Nik
*/
public final class HitConditionBonusData implements IXmlReader
{
private int frontBonus = 0;
private int sideBonus = 0;
private int backBonus = 0;
private int highBonus = 0;
private int lowBonus = 0;
private int darkBonus = 0;
private int rainBonus = 0;
/**
* Instantiates a new hit condition bonus.
*/
protected HitConditionBonusData()
{
load();
}
@Override
public void load()
{
parseDatapackFile("stats/hitConditionBonus.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded Hit Condition bonuses.");
if (Config.DEBUG)
{
LOGGER.info(getClass().getSimpleName() + ": Front bonus: " + frontBonus);
LOGGER.info(getClass().getSimpleName() + ": Side bonus: " + sideBonus);
LOGGER.info(getClass().getSimpleName() + ": Back bonus: " + backBonus);
LOGGER.info(getClass().getSimpleName() + ": High bonus: " + highBonus);
LOGGER.info(getClass().getSimpleName() + ": Low bonus: " + lowBonus);
LOGGER.info(getClass().getSimpleName() + ": Dark bonus: " + darkBonus);
LOGGER.info(getClass().getSimpleName() + ": Rain bonus: " + rainBonus);
}
}
@Override
public void parseDocument(Document doc)
{
for (Node d = doc.getFirstChild().getFirstChild(); d != null; d = d.getNextSibling())
{
final NamedNodeMap attrs = d.getAttributes();
switch (d.getNodeName())
{
case "front":
{
frontBonus = parseInteger(attrs, "val");
break;
}
case "side":
{
sideBonus = parseInteger(attrs, "val");
break;
}
case "back":
{
backBonus = parseInteger(attrs, "val");
break;
}
case "high":
{
highBonus = parseInteger(attrs, "val");
break;
}
case "low":
{
lowBonus = parseInteger(attrs, "val");
break;
}
case "dark":
{
darkBonus = parseInteger(attrs, "val");
break;
}
case "rain":
{
rainBonus = parseInteger(attrs, "val");
break;
}
}
}
}
/**
* Gets the condition bonus.
* @param attacker the attacking character.
* @param target the attacked character.
* @return the bonus of the attacker against the target.
*/
public double getConditionBonus(L2Character attacker, L2Character target)
{
double mod = 100;
// Get high or low bonus
if ((attacker.getZ() - target.getZ()) > 50)
{
mod += highBonus;
}
else if ((attacker.getZ() - target.getZ()) < -50)
{
mod += lowBonus;
}
// Get weather bonus
if (GameTimeController.getInstance().isNight())
{
mod += darkBonus;
// else if () No rain support yet.
// chance += hitConditionBonus.rainBonus;
}
// Get side bonus
if (attacker.isBehindTarget())
{
mod += backBonus;
}
else if (attacker.isInFrontOfTarget())
{
mod += frontBonus;
}
else
{
mod += sideBonus;
}
// If (mod / 100) is less than 0, return 0, because we can't lower more than 100%.
return Math.max(mod / 100, 0);
}
/**
* Gets the single instance of HitConditionBonus.
* @return single instance of HitConditionBonus
*/
public static HitConditionBonusData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final HitConditionBonusData _instance = new HitConditionBonusData();
}
}

View File

@@ -0,0 +1,138 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.base.ClassId;
import com.l2jmobius.gameserver.model.items.PcItemTemplate;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* This class holds the Initial Equipment information.<br>
* What items get each newly created character and if this item is equipped upon creation (<b>Requires the item to be equippable</b>).
* @author Zoey76
*/
public final class InitialEquipmentData implements IXmlReader
{
private final Map<ClassId, List<PcItemTemplate>> _initialEquipmentList = new HashMap<>();
private static final String NORMAL = "stats/initialEquipment.xml";
private static final String EVENT = "stats/initialEquipmentEvent.xml";
/**
* Instantiates a new initial equipment data.
*/
protected InitialEquipmentData()
{
load();
}
@Override
public void load()
{
_initialEquipmentList.clear();
parseDatapackFile(Config.INITIAL_EQUIPMENT_EVENT ? EVENT : NORMAL);
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _initialEquipmentList.size() + " Initial Equipment data.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("equipment".equalsIgnoreCase(d.getNodeName()))
{
parseEquipment(d);
}
}
}
}
}
/**
* Parses the equipment.
* @param d parse an initial equipment and add it to {@link #_initialEquipmentList}
*/
private void parseEquipment(Node d)
{
NamedNodeMap attrs = d.getAttributes();
final ClassId classId = ClassId.getClassId(Integer.parseInt(attrs.getNamedItem("classId").getNodeValue()));
final List<PcItemTemplate> equipList = new ArrayList<>();
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
{
if ("item".equalsIgnoreCase(c.getNodeName()))
{
final StatsSet set = new StatsSet();
attrs = c.getAttributes();
for (int i = 0; i < attrs.getLength(); i++)
{
final Node attr = attrs.item(i);
set.set(attr.getNodeName(), attr.getNodeValue());
}
equipList.add(new PcItemTemplate(set));
}
}
_initialEquipmentList.put(classId, equipList);
}
/**
* Gets the equipment list.
* @param cId the class Id for the required initial equipment.
* @return the initial equipment for the given class Id.
*/
public List<PcItemTemplate> getEquipmentList(ClassId cId)
{
return _initialEquipmentList.get(cId);
}
/**
* Gets the equipment list.
* @param cId the class Id for the required initial equipment.
* @return the initial equipment for the given class Id.
*/
public List<PcItemTemplate> getEquipmentList(int cId)
{
return _initialEquipmentList.get(ClassId.getClassId(cId));
}
/**
* Gets the single instance of InitialEquipmentData.
* @return single instance of InitialEquipmentData
*/
public static InitialEquipmentData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final InitialEquipmentData _instance = new InitialEquipmentData();
}
}

View File

@@ -0,0 +1,362 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.enums.MacroType;
import com.l2jmobius.gameserver.enums.ShortcutType;
import com.l2jmobius.gameserver.model.Macro;
import com.l2jmobius.gameserver.model.MacroCmd;
import com.l2jmobius.gameserver.model.Shortcut;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.base.ClassId;
import com.l2jmobius.gameserver.model.items.instance.L2ItemInstance;
import com.l2jmobius.gameserver.network.serverpackets.ShortCutRegister;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* This class holds the Initial Shortcuts information.<br>
* What shortcuts get each newly created character.
* @author Zoey76
*/
public final class InitialShortcutData implements IXmlReader
{
private final Map<ClassId, List<Shortcut>> _initialShortcutData = new HashMap<>();
private final List<Shortcut> _initialGlobalShortcutList = new ArrayList<>();
private final Map<Integer, Macro> _macroPresets = new HashMap<>();
/**
* Instantiates a new initial shortcuts data.
*/
protected InitialShortcutData()
{
load();
}
@Override
public void load()
{
_initialShortcutData.clear();
_initialGlobalShortcutList.clear();
parseDatapackFile("stats/initialShortcuts.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _initialGlobalShortcutList.size() + " Initial Global Shortcuts data.");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _initialShortcutData.size() + " Initial Shortcuts data.");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _macroPresets.size() + " Macros presets.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equals(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
switch (d.getNodeName())
{
case "shortcuts":
{
parseShortcuts(d);
break;
}
case "macros":
{
parseMacros(d);
break;
}
}
}
}
}
}
/**
* Parses a shortcut.
* @param d the node
*/
private void parseShortcuts(Node d)
{
NamedNodeMap attrs = d.getAttributes();
final Node classIdNode = attrs.getNamedItem("classId");
final List<Shortcut> list = new ArrayList<>();
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
{
if ("page".equals(c.getNodeName()))
{
attrs = c.getAttributes();
final int pageId = parseInteger(attrs, "pageId");
for (Node b = c.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("slot".equals(b.getNodeName()))
{
list.add(createShortcut(pageId, b));
}
}
}
}
if (classIdNode != null)
{
_initialShortcutData.put(ClassId.getClassId(Integer.parseInt(classIdNode.getNodeValue())), list);
}
else
{
_initialGlobalShortcutList.addAll(list);
}
}
/**
* Parses a macro.
* @param d the node
*/
private void parseMacros(Node d)
{
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
{
if ("macro".equals(c.getNodeName()))
{
NamedNodeMap attrs = c.getAttributes();
if (!parseBoolean(attrs, "enabled", true))
{
continue;
}
final int macroId = parseInteger(attrs, "macroId");
final int icon = parseInteger(attrs, "icon");
final String name = parseString(attrs, "name");
final String description = parseString(attrs, "description");
final String acronym = parseString(attrs, "acronym");
final List<MacroCmd> commands = new ArrayList<>(1);
int entry = 0;
for (Node b = c.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("command".equals(b.getNodeName()))
{
attrs = b.getAttributes();
final MacroType type = parseEnum(attrs, MacroType.class, "type");
int d1 = 0;
int d2 = 0;
final String cmd = b.getTextContent();
switch (type)
{
case SKILL:
{
d1 = parseInteger(attrs, "skillId"); // Skill ID
d2 = parseInteger(attrs, "skillLvl", 0); // Skill level
break;
}
case ACTION:
{
// Not handled by client.
d1 = parseInteger(attrs, "actionId");
break;
}
case TEXT:
{
// Doesn't have numeric parameters.
break;
}
case SHORTCUT:
{
d1 = parseInteger(attrs, "page"); // Page
d2 = parseInteger(attrs, "slot", 0); // Slot
break;
}
case ITEM:
{
// Not handled by client.
d1 = parseInteger(attrs, "itemId");
break;
}
case DELAY:
{
d1 = parseInteger(attrs, "delay"); // Delay in seconds
break;
}
}
commands.add(new MacroCmd(entry++, type, d1, d2, cmd));
}
}
_macroPresets.put(macroId, new Macro(macroId, icon, name, description, acronym, commands));
}
}
}
/**
* Parses a node an create a shortcut from it.
* @param pageId the page ID
* @param b the node to parse
* @return the new shortcut
*/
private Shortcut createShortcut(int pageId, Node b)
{
final NamedNodeMap attrs = b.getAttributes();
return new Shortcut(parseInteger(attrs, "slotId"), pageId, parseEnum(attrs, ShortcutType.class, "shortcutType"), parseInteger(attrs, "shortcutId"), parseInteger(attrs, "shortcutLevel", 0), parseInteger(attrs, "characterType", 0));
}
/**
* Gets the shortcut list.
* @param cId the class ID for the shortcut list
* @return the shortcut list for the give class ID
*/
public List<Shortcut> getShortcutList(ClassId cId)
{
return _initialShortcutData.get(cId);
}
/**
* Gets the shortcut list.
* @param cId the class ID for the shortcut list
* @return the shortcut list for the give class ID
*/
public List<Shortcut> getShortcutList(int cId)
{
return _initialShortcutData.get(ClassId.getClassId(cId));
}
/**
* Gets the global shortcut list.
* @return the global shortcut list
*/
public List<Shortcut> getGlobalMacroList()
{
return _initialGlobalShortcutList;
}
/**
* Register all the available shortcuts for the given player.
* @param player the player
*/
public void registerAllShortcuts(L2PcInstance player)
{
if (player == null)
{
return;
}
// Register global shortcuts.
for (Shortcut shortcut : _initialGlobalShortcutList)
{
int shortcutId = shortcut.getId();
switch (shortcut.getType())
{
case ITEM:
{
final L2ItemInstance item = player.getInventory().getItemByItemId(shortcutId);
if (item == null)
{
continue;
}
shortcutId = item.getObjectId();
break;
}
case SKILL:
{
if (!player.getSkills().containsKey(shortcutId))
{
continue;
}
break;
}
case MACRO:
{
final Macro macro = _macroPresets.get(shortcutId);
if (macro == null)
{
continue;
}
player.registerMacro(macro);
break;
}
}
// Register shortcut
final Shortcut newShortcut = new Shortcut(shortcut.getSlot(), shortcut.getPage(), shortcut.getType(), shortcutId, shortcut.getLevel(), shortcut.getCharacterType());
player.sendPacket(new ShortCutRegister(newShortcut));
player.registerShortCut(newShortcut);
}
// Register class specific shortcuts.
if (_initialShortcutData.containsKey(player.getClassId()))
{
for (Shortcut shortcut : _initialShortcutData.get(player.getClassId()))
{
int shortcutId = shortcut.getId();
switch (shortcut.getType())
{
case ITEM:
{
final L2ItemInstance item = player.getInventory().getItemByItemId(shortcutId);
if (item == null)
{
continue;
}
shortcutId = item.getObjectId();
break;
}
case SKILL:
{
if (!player.getSkills().containsKey(shortcut.getId()))
{
continue;
}
break;
}
case MACRO:
{
final Macro macro = _macroPresets.get(shortcutId);
if (macro == null)
{
continue;
}
player.registerMacro(macro);
break;
}
}
// Register shortcut
final Shortcut newShortcut = new Shortcut(shortcut.getSlot(), shortcut.getPage(), shortcut.getType(), shortcutId, shortcut.getLevel(), shortcut.getCharacterType());
player.sendPacket(new ShortCutRegister(newShortcut));
player.registerShortCut(newShortcut);
}
}
}
/**
* Gets the single instance of InitialEquipmentData.
* @return single instance of InitialEquipmentData
*/
public static InitialShortcutData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final InitialShortcutData _instance = new InitialShortcutData();
}
}

View File

@@ -0,0 +1,96 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.CrystalizationData;
import com.l2jmobius.gameserver.model.holders.ItemChanceHolder;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* @author UnAfraid
*/
public final class ItemCrystalizationData implements IXmlReader
{
private final Map<Integer, CrystalizationData> _items = new HashMap<>();
protected ItemCrystalizationData()
{
load();
}
@Override
public void load()
{
parseDatapackFile("CrystalizableItems.xml");
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _items.size() + " Items");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("crystalizable_item".equalsIgnoreCase(d.getNodeName()))
{
final int id = parseInteger(d.getAttributes(), "id");
final CrystalizationData data = new CrystalizationData(id);
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
{
if ("item".equalsIgnoreCase(c.getNodeName()))
{
final NamedNodeMap attrs = c.getAttributes();
data.addItem(new ItemChanceHolder(parseInteger(attrs, "id"), parseDouble(attrs, "chance"), parseLong(attrs, "count")));
}
}
_items.put(id, data);
}
}
}
}
}
public CrystalizationData getCrystalization(int itemId)
{
return _items.get(itemId);
}
/**
* Gets the single instance of ItemCrystalizationData.
* @return single instance of ItemCrystalizationData
*/
public static ItemCrystalizationData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final ItemCrystalizationData _instance = new ItemCrystalizationData();
}
}

View File

@@ -0,0 +1,97 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.Config;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* Karma data.
* @author UnAfraid
*/
public class KarmaData implements IXmlReader
{
private final Map<Integer, Double> _karmaTable = new HashMap<>();
public KarmaData()
{
load();
}
@Override
public synchronized void load()
{
_karmaTable.clear();
parseDatapackFile("stats/chars/pcKarmaIncrease.xml");
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded " + _karmaTable.size() + " karma modifiers.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("pcKarmaIncrease".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("increase".equalsIgnoreCase(d.getNodeName()))
{
final NamedNodeMap attrs = d.getAttributes();
final int level = parseInteger(attrs, "lvl");
if (level >= Config.PLAYER_MAXIMUM_LEVEL)
{
break;
}
_karmaTable.put(level, parseDouble(attrs, "val"));
}
}
}
}
}
/**
* @param level
* @return {@code double} modifier used to calculate karma lost upon death.
*/
public double getMultiplier(int level)
{
return _karmaTable.get(level);
}
/**
* Gets the single instance of KarmaData.
* @return single instance of KarmaData
*/
public static KarmaData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final KarmaData _instance = new KarmaData();
}
}

View File

@@ -0,0 +1,164 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.holders.ItemHolder;
import com.l2jmobius.util.Rnd;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* @author Mathael
*/
public class LuckyGameData implements IXmlReader
{
private static final List<ItemHolder> _fortuneReadingTicketRewards = new ArrayList<>();
private static final List<ItemHolder> _luxuryFortuneReadingTicketRewards = new ArrayList<>();
private static final List<ItemHolder> _rareLuxuryFortuneReadingTicketRewards = new ArrayList<>();
protected LuckyGameData()
{
load();
}
@Override
public void load()
{
_fortuneReadingTicketRewards.clear();
_luxuryFortuneReadingTicketRewards.clear();
_rareLuxuryFortuneReadingTicketRewards.clear();
parseDatapackFile("LuckyGameData.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _fortuneReadingTicketRewards.size() + " Normal item rewards.");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _luxuryFortuneReadingTicketRewards.size() + " Luxury item rewards.");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _rareLuxuryFortuneReadingTicketRewards.size() + " Rare item rewards.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
final NamedNodeMap at = n.getAttributes();
final Node attribute = at.getNamedItem("enabled");
if ((attribute != null) && Boolean.parseBoolean(attribute.getNodeValue())) // <list enabled="true"
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("fortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName()))
{
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("item".equalsIgnoreCase(b.getNodeName()))
{
final NamedNodeMap attrs = b.getAttributes();
final int itemId = parseInteger(attrs, "id");
final int count = parseInteger(attrs, "count");
if ((itemId == 0) || (count == 0))
{
LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero.");
return;
}
_fortuneReadingTicketRewards.add(new ItemHolder(itemId, count));
}
}
}
else if ("luxuryFortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName()))
{
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("item".equalsIgnoreCase(b.getNodeName()))
{
final NamedNodeMap attrs = b.getAttributes();
final int itemId = parseInteger(attrs, "id");
final int count = parseInteger(attrs, "count");
if ((itemId == 0) || (count == 0))
{
LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero.");
return;
}
_luxuryFortuneReadingTicketRewards.add(new ItemHolder(itemId, count));
}
}
}
else if ("rareLuxuryFortuneReadingTicketRewards".equalsIgnoreCase(d.getNodeName()))
{
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("item".equalsIgnoreCase(b.getNodeName()))
{
final NamedNodeMap attrs = b.getAttributes();
final int itemId = parseInteger(attrs, "id");
final int count = parseInteger(attrs, "count");
if ((itemId == 0) || (count == 0))
{
LOGGER.severe(getClass().getSimpleName() + ": itemId: [" + itemId + "] count: [" + count + "] cannot be zero.");
return;
}
_rareLuxuryFortuneReadingTicketRewards.add(new ItemHolder(itemId, count));
}
}
}
}
}
}
}
}
public static ItemHolder getRandomNormalReward()
{
return _fortuneReadingTicketRewards.get(Rnd.get(_fortuneReadingTicketRewards.size()));
}
public static ItemHolder getRandomLuxuryReward()
{
return _luxuryFortuneReadingTicketRewards.get(Rnd.get(_luxuryFortuneReadingTicketRewards.size()));
}
public static ItemHolder getRandomRareReward()
{
return _rareLuxuryFortuneReadingTicketRewards.get(Rnd.get(_rareLuxuryFortuneReadingTicketRewards.size()));
}
public static LuckyGameData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final LuckyGameData _instance = new LuckyGameData();
}
}

View File

@@ -0,0 +1,439 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.io.File;
import java.io.FileFilter;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.L2Npc;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.multisell.Entry;
import com.l2jmobius.gameserver.model.multisell.Ingredient;
import com.l2jmobius.gameserver.model.multisell.ListContainer;
import com.l2jmobius.gameserver.model.multisell.PreparedListContainer;
import com.l2jmobius.gameserver.network.SystemMessageId;
import com.l2jmobius.gameserver.network.serverpackets.ExPCCafePointInfo;
import com.l2jmobius.gameserver.network.serverpackets.MultiSellList;
import com.l2jmobius.gameserver.network.serverpackets.SystemMessage;
import com.l2jmobius.gameserver.network.serverpackets.UserInfo;
import com.l2jmobius.gameserver.util.Util;
import com.l2jmobius.util.data.xml.IXmlReader;
import com.l2jmobius.util.file.filter.NumericNameFilter;
public final class MultisellData implements IXmlReader
{
private final Map<Integer, ListContainer> _entries = new HashMap<>();
public static final int PAGE_SIZE = 40;
// Special IDs.
public static final int PC_BANG_POINTS = -100;
public static final int CLAN_REPUTATION = -200;
public static final int FAME = -300;
public static final int RAID_POINTS = -500;
// Misc
private static final FileFilter NUMERIC_FILTER = new NumericNameFilter();
protected MultisellData()
{
load();
}
@Override
public void load()
{
_entries.clear();
parseDatapackDirectory("multisell", false);
if (Config.CUSTOM_MULTISELL_LOAD)
{
parseDatapackDirectory("multisell/custom", false);
}
verify();
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded " + _entries.size() + " multisell lists.");
}
@Override
public void parseDocument(Document doc, File f)
{
try
{
final int id = Integer.parseInt(f.getName().replaceAll(".xml", ""));
int entryId = 1;
Node att;
final ListContainer list = new ListContainer(id);
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
list.setApplyTaxes(parseBoolean(n.getAttributes(), "applyTaxes", false));
list.setNewMultisell(parseBoolean(n.getAttributes(), "isNewMultisell", false));
list.setMaintainEnchantment(parseBoolean(n.getAttributes(), "maintainEnchantment", false));
att = n.getAttributes().getNamedItem("useRate");
if (att != null)
{
try
{
list.setUseRate(Double.valueOf(att.getNodeValue()));
if (list.getUseRate() <= 1e-6)
{
throw new NumberFormatException("The value cannot be 0"); // threat 0 as invalid value
}
}
catch (NumberFormatException e)
{
try
{
list.setUseRate(Config.class.getField(att.getNodeValue()).getDouble(Config.class));
}
catch (Exception e1)
{
LOGGER.warning(e1.getMessage() + doc.getLocalName());
list.setUseRate(1.0);
}
}
catch (DOMException e)
{
LOGGER.warning(e.getMessage() + doc.getLocalName());
}
}
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("item".equalsIgnoreCase(d.getNodeName()))
{
list.getEntries().add(parseEntry(d, entryId++, list));
}
else if ("npcs".equalsIgnoreCase(d.getNodeName()))
{
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("npc".equalsIgnoreCase(b.getNodeName()) && Util.isDigit(b.getTextContent()))
{
list.allowNpc(Integer.parseInt(b.getTextContent()));
}
}
}
}
}
}
_entries.put(id, list);
}
catch (Exception e)
{
LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Error in file " + f, e);
}
}
@Override
public FileFilter getCurrentFileFilter()
{
return NUMERIC_FILTER;
}
private final Entry parseEntry(Node n, int entryId, ListContainer list)
{
final Node first = n.getFirstChild();
final Entry entry = new Entry(entryId);
NamedNodeMap attrs;
Node att;
StatsSet set;
for (n = first; n != null; n = n.getNextSibling())
{
if ("ingredient".equalsIgnoreCase(n.getNodeName()))
{
attrs = n.getAttributes();
set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
entry.addIngredient(new Ingredient(set));
}
else if ("production".equalsIgnoreCase(n.getNodeName()))
{
attrs = n.getAttributes();
set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
entry.addProduct(new Ingredient(set));
}
}
return entry;
}
/**
* This will generate the multisell list for the items.<br>
* There exist various parameters in multisells that affect the way they will appear:
* <ol>
* <li>Inventory only:
* <ul>
* <li>If true, only show items of the multisell for which the "primary" ingredients are already in the player's inventory. By "primary" ingredients we mean weapon and armor.</li>
* <li>If false, show the entire list.</li>
* </ul>
* </li>
* <li>Maintain enchantment: presumably, only lists with "inventory only" set to true should sometimes have this as true. This makes no sense otherwise...
* <ul>
* <li>If true, then the product will match the enchantment level of the ingredient.<br>
* If the player has multiple items that match the ingredient list but the enchantment levels differ, then the entries need to be duplicated to show the products and ingredients for each enchantment level.<br>
* For example: If the player has a crystal staff +1 and a crystal staff +3 and goes to exchange it at the mammon, the list should have all exchange possibilities for the +1 staff, followed by all possibilities for the +3 staff.</li>
* <li>If false, then any level ingredient will be considered equal and product will always be at +0</li>
* </ul>
* </li>
* <li>Apply taxes: Uses the "taxIngredient" entry in order to add a certain amount of adena to the ingredients.
* <li>
* <li>Additional product and ingredient multipliers.</li>
* </ol>
* @param listId
* @param player
* @param npc
* @param inventoryOnly
* @param productMultiplier
* @param ingredientMultiplier
*/
public final void separateAndSend(int listId, L2PcInstance player, L2Npc npc, boolean inventoryOnly, double productMultiplier, double ingredientMultiplier)
{
final ListContainer template = _entries.get(listId);
if (template == null)
{
LOGGER.warning(getClass().getSimpleName() + ": Cannot find list ID: " + listId + " requested by player: " + player.getName() + ", NPC ID:" + (npc != null ? npc.getId() : 0));
return;
}
if (!template.isNpcAllowed(-1) && (((npc != null) && !template.isNpcAllowed(npc.getId())) || ((npc == null) && template.isNpcOnly())))
{
LOGGER.warning(getClass().getSimpleName() + ": Player " + player + " attempted to open multisell " + listId + " from npc " + npc + " which is not allowed!");
return;
}
final PreparedListContainer list = new PreparedListContainer(template, inventoryOnly, player, npc);
// Pass through this only when multipliers are different from 1
if ((productMultiplier != 1) || (ingredientMultiplier != 1))
{
list.getEntries().forEach(entry ->
{
// Math.max used here to avoid dropping count to 0
entry.getProducts().forEach(product -> product.setItemCount((long) Math.max(product.getItemCount() * productMultiplier, 1)));
// Math.max used here to avoid dropping count to 0
entry.getIngredients().forEach(ingredient -> ingredient.setItemCount((long) Math.max(ingredient.getItemCount() * ingredientMultiplier, 1)));
});
}
int index = 0;
do
{
// send list at least once even if size = 0
player.sendPacket(new MultiSellList(list, index));
index += PAGE_SIZE;
}
while (index < list.getEntries().size());
player.setMultiSell(list);
}
public final void separateAndSend(int listId, L2PcInstance player, L2Npc npc, boolean inventoryOnly)
{
separateAndSend(listId, player, npc, inventoryOnly, 1, 1);
}
public static boolean hasSpecialIngredient(int id, long amount, L2PcInstance player)
{
switch (id)
{
case PC_BANG_POINTS:
{
if (player.getPcBangPoints() >= amount)
{
return true;
}
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_ARE_SHORT_OF_PC_POINTS));
break;
}
case CLAN_REPUTATION:
{
if (player.getClan() == null)
{
player.sendPacket(SystemMessageId.YOU_ARE_NOT_A_CLAN_MEMBER_AND_CANNOT_PERFORM_THIS_ACTION);
break;
}
if (!player.isClanLeader())
{
player.sendPacket(SystemMessageId.ONLY_THE_CLAN_LEADER_IS_ENABLED);
break;
}
if (player.getClan().getReputationScore() >= amount)
{
return true;
}
player.sendPacket(SystemMessageId.THE_CLAN_REPUTATION_IS_TOO_LOW);
break;
}
case FAME:
{
if (player.getFame() < amount)
{
player.sendPacket(SystemMessageId.YOU_DON_T_HAVE_ENOUGH_FAME_TO_DO_THAT);
break;
}
}
case RAID_POINTS:
{
if (player.getRaidPoints() >= amount)
{
return true;
}
player.sendPacket(SystemMessageId.NOT_ENOUGH_RAID_POINTS);
break;
}
}
return false;
}
public static boolean takeSpecialIngredient(int id, long amount, L2PcInstance player)
{
switch (id)
{
case PC_BANG_POINTS: // PcBang points
{
final int cost = player.getPcBangPoints() - (int) amount;
player.setPcBangPoints(cost);
final SystemMessage smsgpc = SystemMessage.getSystemMessage(SystemMessageId.YOU_ARE_USING_S1_POINT);
smsgpc.addLong((int) amount);
player.sendPacket(smsgpc);
player.sendPacket(new ExPCCafePointInfo(player.getPcBangPoints(), (int) amount, 1));
return true;
}
case CLAN_REPUTATION:
{
player.getClan().takeReputationScore((int) amount, true);
final SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.S1_POINT_S_HAVE_BEEN_DEDUCTED_FROM_THE_CLAN_S_REPUTATION);
smsg.addLong(amount);
player.sendPacket(smsg);
return true;
}
case FAME:
{
player.setFame(player.getFame() - (int) amount);
player.sendPacket(new UserInfo(player));
return true;
}
case RAID_POINTS:
{
player.setRaidPoints(player.getRaidPoints() - (int) amount);
player.sendPacket(new UserInfo(player));
return true;
}
}
return false;
}
public static void giveSpecialProduct(int id, long amount, L2PcInstance player)
{
switch (id)
{
case CLAN_REPUTATION:
{
player.getClan().addReputationScore((int) amount, true);
break;
}
case FAME:
{
player.setFame((int) (player.getFame() + amount));
player.sendPacket(new UserInfo(player));
break;
}
case RAID_POINTS:
{
player.setRaidPoints((int) (player.getRaidPoints() + amount));
player.sendPacket(new UserInfo(player));
break;
}
}
}
private final void verify()
{
for (ListContainer list : _entries.values())
{
for (Entry ent : list.getEntries())
{
for (Ingredient ing : ent.getIngredients())
{
if (!verifyIngredient(ing))
{
LOGGER.warning(getClass().getSimpleName() + ": Cannot find ingredient with item ID: " + ing.getItemId() + " in list: " + list.getListId());
}
}
for (Ingredient ing : ent.getProducts())
{
if (!verifyIngredient(ing))
{
LOGGER.warning(getClass().getSimpleName() + ": Cannot find product with item ID: " + ing.getItemId() + " in list: " + list.getListId());
}
}
}
}
}
private final boolean verifyIngredient(Ingredient ing)
{
switch (ing.getItemId())
{
case PC_BANG_POINTS:
case CLAN_REPUTATION:
case FAME:
case RAID_POINTS:
{
return true;
}
default:
{
return ing.getTemplate() != null;
}
}
}
public static MultisellData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final MultisellData _instance = new MultisellData();
}
}

View File

@@ -0,0 +1,876 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.datatables.SkillData;
import com.l2jmobius.gameserver.enums.AISkillScope;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.templates.L2NpcTemplate;
import com.l2jmobius.gameserver.model.base.ClassId;
import com.l2jmobius.gameserver.model.drops.DropListScope;
import com.l2jmobius.gameserver.model.drops.GeneralDropItem;
import com.l2jmobius.gameserver.model.drops.GroupedGeneralDropItem;
import com.l2jmobius.gameserver.model.drops.IDropItem;
import com.l2jmobius.gameserver.model.effects.L2EffectType;
import com.l2jmobius.gameserver.model.holders.MinionHolder;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
import com.l2jmobius.gameserver.model.skills.Skill;
import com.l2jmobius.gameserver.util.Util;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* NPC data parser.
* @author NosBit
*/
public class NpcData implements IXmlReader
{
private final Map<Integer, L2NpcTemplate> _npcs = new ConcurrentHashMap<>();
private final Map<String, Integer> _clans = new ConcurrentHashMap<>();
private MinionData _minionData;
protected NpcData()
{
load();
}
@Override
public synchronized void load()
{
_minionData = new MinionData();
parseDatapackDirectory("stats/npcs", false);
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _npcs.size() + " NPCs.");
if (Config.CUSTOM_NPC_DATA)
{
final int npcCount = _npcs.size();
parseDatapackDirectory("stats/npcs/custom", true);
LOGGER.info(getClass().getSimpleName() + ": Loaded " + (_npcs.size() - npcCount) + " Custom NPCs.");
}
_minionData = null;
loadNpcsSkillLearn();
}
@Override
public void parseDocument(Document doc, File f)
{
for (Node node = doc.getFirstChild(); node != null; node = node.getNextSibling())
{
if ("list".equalsIgnoreCase(node.getNodeName()))
{
for (Node listNode = node.getFirstChild(); listNode != null; listNode = listNode.getNextSibling())
{
if ("npc".equalsIgnoreCase(listNode.getNodeName()))
{
NamedNodeMap attrs = listNode.getAttributes();
final StatsSet set = new StatsSet();
final int npcId = parseInteger(attrs, "id");
Map<String, Object> parameters = null;
Map<Integer, Skill> skills = null;
Set<Integer> clans = null;
Set<Integer> ignoreClanNpcIds = null;
Map<DropListScope, List<IDropItem>> dropLists = null;
set.set("id", npcId);
set.set("displayId", parseInteger(attrs, "displayId"));
set.set("level", parseByte(attrs, "level"));
set.set("type", parseString(attrs, "type"));
set.set("name", parseString(attrs, "name"));
set.set("usingServerSideName", parseBoolean(attrs, "usingServerSideName"));
set.set("title", parseString(attrs, "title"));
set.set("usingServerSideTitle", parseBoolean(attrs, "usingServerSideTitle"));
for (Node npcNode = listNode.getFirstChild(); npcNode != null; npcNode = npcNode.getNextSibling())
{
attrs = npcNode.getAttributes();
switch (npcNode.getNodeName().toLowerCase())
{
case "parameters":
{
if (parameters == null)
{
parameters = new HashMap<>();
}
for (Node parametersNode = npcNode.getFirstChild(); parametersNode != null; parametersNode = parametersNode.getNextSibling())
{
attrs = parametersNode.getAttributes();
switch (parametersNode.getNodeName().toLowerCase())
{
case "param":
{
parameters.put(parseString(attrs, "name"), parseString(attrs, "value"));
break;
}
case "skill":
{
parameters.put(parseString(attrs, "name"), new SkillHolder(parseInteger(attrs, "id"), parseInteger(attrs, "level")));
break;
}
case "minions":
{
final List<MinionHolder> minions = new ArrayList<>(1);
for (Node minionsNode = parametersNode.getFirstChild(); minionsNode != null; minionsNode = minionsNode.getNextSibling())
{
if (minionsNode.getNodeName().equalsIgnoreCase("npc"))
{
attrs = minionsNode.getAttributes();
minions.add(new MinionHolder(parseInteger(attrs, "id"), parseInteger(attrs, "count"), parseInteger(attrs, "respawnTime"), parseInteger(attrs, "weightPoint")));
}
}
if (!minions.isEmpty())
{
parameters.put(parseString(parametersNode.getAttributes(), "name"), minions);
}
break;
}
}
}
break;
}
case "race":
case "sex":
{
set.set(npcNode.getNodeName(), npcNode.getTextContent().toUpperCase());
break;
}
case "equipment":
{
set.set("chestId", parseInteger(attrs, "chest"));
set.set("rhandId", parseInteger(attrs, "rhand"));
set.set("lhandId", parseInteger(attrs, "lhand"));
set.set("weaponEnchant", parseInteger(attrs, "weaponEnchant"));
break;
}
case "acquire":
{
set.set("exp", parseDouble(attrs, "exp"));
set.set("sp", parseDouble(attrs, "sp"));
set.set("raidPoints", parseDouble(attrs, "raidPoints"));
break;
}
case "stats":
{
for (Node statsNode = npcNode.getFirstChild(); statsNode != null; statsNode = statsNode.getNextSibling())
{
attrs = statsNode.getAttributes();
switch (statsNode.getNodeName().toLowerCase())
{
case "vitals":
{
set.set("baseHpMax", parseDouble(attrs, "hp"));
set.set("baseHpReg", parseDouble(attrs, "hpRegen"));
set.set("baseMpMax", parseDouble(attrs, "mp"));
set.set("baseMpReg", parseDouble(attrs, "mpRegen"));
break;
}
case "attack":
{
set.set("basePAtk", parseDouble(attrs, "physical"));
set.set("baseMAtk", parseDouble(attrs, "magical"));
set.set("baseRndDam", parseInteger(attrs, "random"));
set.set("baseCritRate", parseInteger(attrs, "critical"));
set.set("accuracy", parseDouble(attrs, "accuracy")); // TODO: Implement me
set.set("basePAtkSpd", parseInteger(attrs, "attackSpeed"));
set.set("reuseDelay", parseInteger(attrs, "reuseDelay")); // TODO: Implement me
set.set("baseAtkType", parseString(attrs, "type"));
set.set("baseAtkRange", parseInteger(attrs, "range"));
set.set("distance", parseInteger(attrs, "distance")); // TODO: Implement me
set.set("width", parseInteger(attrs, "width")); // TODO: Implement me
break;
}
case "defence":
{
set.set("basePDef", parseDouble(attrs, "physical"));
set.set("baseMDef", parseDouble(attrs, "magical"));
set.set("evasion", parseInteger(attrs, "evasion")); // TODO: Implement me
set.set("baseShldDef", parseInteger(attrs, "shield"));
set.set("baseShldRate", parseInteger(attrs, "shieldRate"));
break;
}
case "attribute":
{
for (Node attributeNode = statsNode.getFirstChild(); attributeNode != null; attributeNode = attributeNode.getNextSibling())
{
attrs = attributeNode.getAttributes();
switch (attributeNode.getNodeName().toLowerCase())
{
case "attack":
{
final String attackAttributeType = parseString(attrs, "type");
switch (attackAttributeType.toUpperCase())
{
case "FIRE":
{
set.set("baseFire", parseInteger(attrs, "value"));
break;
}
case "WATER":
{
set.set("baseWater", parseInteger(attrs, "value"));
break;
}
case "WIND":
{
set.set("baseWind", parseInteger(attrs, "value"));
break;
}
case "EARTH":
{
set.set("baseEarth", parseInteger(attrs, "value"));
break;
}
case "DARK":
{
set.set("baseDark", parseInteger(attrs, "value"));
break;
}
case "HOLY":
{
set.set("baseHoly", parseInteger(attrs, "value"));
break;
}
}
break;
}
case "defence":
{
set.set("baseFireRes", parseInteger(attrs, "fire"));
set.set("baseWaterRes", parseInteger(attrs, "water"));
set.set("baseWindRes", parseInteger(attrs, "wind"));
set.set("baseEarthRes", parseInteger(attrs, "earth"));
set.set("baseHolyRes", parseInteger(attrs, "holy"));
set.set("baseDarkRes", parseInteger(attrs, "dark"));
set.set("baseElementRes", parseInteger(attrs, "default"));
break;
}
}
}
break;
}
case "speed":
{
{
for (Node speedNode = statsNode.getFirstChild(); speedNode != null; speedNode = speedNode.getNextSibling())
{
attrs = speedNode.getAttributes();
switch (speedNode.getNodeName().toLowerCase())
{
case "walk":
{
set.set("baseWalkSpd", parseDouble(attrs, "ground"));
set.set("baseSwimWalkSpd", parseDouble(attrs, "swim"));
set.set("baseFlyWalkSpd", parseDouble(attrs, "fly"));
break;
}
case "run":
{
set.set("baseRunSpd", parseDouble(attrs, "ground"));
set.set("baseSwimRunSpd", parseDouble(attrs, "swim"));
set.set("baseFlyRunSpd", parseDouble(attrs, "fly"));
break;
}
}
}
break;
}
}
case "hitTime":
{
set.set("hitTime", npcNode.getTextContent()); // TODO: Implement me default 600 (value in ms)
break;
}
}
}
break;
}
case "status":
{
set.set("unique", parseBoolean(attrs, "unique"));
set.set("attackable", parseBoolean(attrs, "attackable"));
set.set("targetable", parseBoolean(attrs, "targetable"));
set.set("talkable", parseBoolean(attrs, "talkable"));
set.set("undying", parseBoolean(attrs, "undying"));
set.set("showName", parseBoolean(attrs, "showName"));
set.set("flying", parseBoolean(attrs, "flying"));
set.set("canMove", parseBoolean(attrs, "canMove"));
set.set("noSleepMode", parseBoolean(attrs, "noSleepMode"));
set.set("passableDoor", parseBoolean(attrs, "passableDoor"));
set.set("hasSummoner", parseBoolean(attrs, "hasSummoner"));
set.set("canBeSown", parseBoolean(attrs, "canBeSown"));
break;
}
case "skilllist":
{
skills = new HashMap<>();
for (Node skillListNode = npcNode.getFirstChild(); skillListNode != null; skillListNode = skillListNode.getNextSibling())
{
if ("skill".equalsIgnoreCase(skillListNode.getNodeName()))
{
attrs = skillListNode.getAttributes();
final int skillId = parseInteger(attrs, "id");
final int skillLevel = parseInteger(attrs, "level");
final Skill skill = SkillData.getInstance().getSkill(skillId, skillLevel);
if (skill != null)
{
skills.put(skill.getId(), skill);
}
else
{
LOGGER.warning("[" + f.getName() + "] skill not found. NPC ID: " + npcId + " Skill ID:" + skillId + " Skill Level: " + skillLevel);
}
}
}
break;
}
case "shots":
{
set.set("soulShot", parseInteger(attrs, "soul"));
set.set("spiritShot", parseInteger(attrs, "spirit"));
set.set("shotShotChance", parseInteger(attrs, "shotChance"));
set.set("spiritShotChance", parseInteger(attrs, "spiritChance"));
break;
}
case "corpsetime":
{
set.set("corpseTime", npcNode.getTextContent());
break;
}
case "excrteffect":
{
set.set("exCrtEffect", npcNode.getTextContent()); // TODO: Implement me default ? type boolean
break;
}
case "snpcprophprate":
{
set.set("sNpcPropHpRate", npcNode.getTextContent()); // TODO: Implement me default 1 type double
break;
}
case "ai":
{
set.set("aiType", parseString(attrs, "type"));
set.set("aggroRange", parseInteger(attrs, "aggroRange"));
set.set("clanHelpRange", parseInteger(attrs, "clanHelpRange"));
set.set("dodge", parseInteger(attrs, "dodge"));
set.set("isChaos", parseBoolean(attrs, "isChaos"));
set.set("isAggressive", parseBoolean(attrs, "isAggressive"));
for (Node aiNode = npcNode.getFirstChild(); aiNode != null; aiNode = aiNode.getNextSibling())
{
attrs = aiNode.getAttributes();
switch (aiNode.getNodeName().toLowerCase())
{
case "skill":
{
set.set("minSkillChance", parseInteger(attrs, "minChance"));
set.set("maxSkillChance", parseInteger(attrs, "maxChance"));
set.set("primarySkillId", parseInteger(attrs, "primaryId"));
set.set("shortRangeSkillId", parseInteger(attrs, "shortRangeId"));
set.set("shortRangeSkillChance", parseInteger(attrs, "shortRangeChance"));
set.set("longRangeSkillId", parseInteger(attrs, "longRangeId"));
set.set("longRangeSkillChance", parseInteger(attrs, "longRangeChance"));
break;
}
case "clanList":
{
for (Node clanListNode = aiNode.getFirstChild(); clanListNode != null; clanListNode = clanListNode.getNextSibling())
{
attrs = clanListNode.getAttributes();
switch (clanListNode.getNodeName().toLowerCase())
{
case "clan":
{
if (clans == null)
{
clans = new HashSet<>(1);
}
clans.add(getOrCreateClanId(clanListNode.getTextContent()));
break;
}
case "ignoreNpcId":
{
if (ignoreClanNpcIds == null)
{
ignoreClanNpcIds = new HashSet<>(1);
}
ignoreClanNpcIds.add(Integer.parseInt(clanListNode.getTextContent()));
break;
}
}
}
break;
}
}
}
break;
}
case "droplists":
{
for (Node dropListsNode = npcNode.getFirstChild(); dropListsNode != null; dropListsNode = dropListsNode.getNextSibling())
{
DropListScope dropListScope = null;
try
{
dropListScope = Enum.valueOf(DropListScope.class, dropListsNode.getNodeName().toUpperCase());
}
catch (Exception e)
{
}
if (dropListScope != null)
{
if (dropLists == null)
{
dropLists = new EnumMap<>(DropListScope.class);
}
final List<IDropItem> dropList = new ArrayList<>();
parseDropList(f, dropListsNode, dropListScope, dropList);
dropLists.put(dropListScope, Collections.unmodifiableList(dropList));
}
}
break;
}
case "collision":
{
for (Node collisionNode = npcNode.getFirstChild(); collisionNode != null; collisionNode = collisionNode.getNextSibling())
{
attrs = collisionNode.getAttributes();
switch (collisionNode.getNodeName().toLowerCase())
{
case "radius":
{
set.set("collisionRadius", parseDouble(attrs, "normal"));
set.set("collisionRadiusGrown", parseDouble(attrs, "grown"));
break;
}
case "height":
{
set.set("collisionHeight", parseDouble(attrs, "normal"));
set.set("collisionHeightGrown", parseDouble(attrs, "grown"));
break;
}
}
}
break;
}
}
}
L2NpcTemplate template = _npcs.get(npcId);
if (template == null)
{
template = new L2NpcTemplate(set);
_npcs.put(template.getId(), template);
}
else
{
template.set(set);
}
if (_minionData._tempMinions.containsKey(npcId))
{
if (parameters == null)
{
parameters = new HashMap<>();
}
parameters.putIfAbsent("Privates", _minionData._tempMinions.get(npcId));
}
template.setParameters(parameters != null ? new StatsSet(Collections.unmodifiableMap(parameters)) : StatsSet.EMPTY_STATSET);
if (skills != null)
{
Map<AISkillScope, List<Skill>> aiSkillLists = null;
for (Skill skill : skills.values())
{
if (skill.isPassive())
{
continue;
}
if (aiSkillLists == null)
{
aiSkillLists = new EnumMap<>(AISkillScope.class);
}
final List<AISkillScope> aiSkillScopes = new ArrayList<>();
final AISkillScope shortOrLongRangeScope = skill.getCastRange() <= 150 ? AISkillScope.SHORT_RANGE : AISkillScope.LONG_RANGE;
if (skill.isSuicideAttack())
{
aiSkillScopes.add(AISkillScope.SUICIDE);
}
else
{
aiSkillScopes.add(AISkillScope.GENERAL);
if (skill.isContinuous())
{
if (!skill.isDebuff())
{
aiSkillScopes.add(AISkillScope.BUFF);
}
else
{
aiSkillScopes.add(AISkillScope.DEBUFF);
aiSkillScopes.add(AISkillScope.COT);
aiSkillScopes.add(shortOrLongRangeScope);
}
}
else if (skill.hasEffectType(L2EffectType.DISPEL, L2EffectType.DISPEL_BY_SLOT))
{
aiSkillScopes.add(AISkillScope.NEGATIVE);
aiSkillScopes.add(shortOrLongRangeScope);
}
else if (skill.hasEffectType(L2EffectType.HEAL))
{
aiSkillScopes.add(AISkillScope.HEAL);
}
else if (skill.hasEffectType(L2EffectType.PHYSICAL_ATTACK, L2EffectType.PHYSICAL_ATTACK_HP_LINK, L2EffectType.MAGICAL_ATTACK, L2EffectType.DEATH_LINK, L2EffectType.HP_DRAIN))
{
aiSkillScopes.add(AISkillScope.ATTACK);
aiSkillScopes.add(AISkillScope.UNIVERSAL);
aiSkillScopes.add(shortOrLongRangeScope);
}
else if (skill.hasEffectType(L2EffectType.SLEEP))
{
aiSkillScopes.add(AISkillScope.IMMOBILIZE);
}
else if (skill.hasEffectType(L2EffectType.STUN, L2EffectType.ROOT))
{
aiSkillScopes.add(AISkillScope.IMMOBILIZE);
aiSkillScopes.add(shortOrLongRangeScope);
}
else if (skill.hasEffectType(L2EffectType.MUTE, L2EffectType.FEAR))
{
aiSkillScopes.add(AISkillScope.COT);
aiSkillScopes.add(shortOrLongRangeScope);
}
else if (skill.hasEffectType(L2EffectType.PARALYZE))
{
aiSkillScopes.add(AISkillScope.IMMOBILIZE);
aiSkillScopes.add(shortOrLongRangeScope);
}
else if (skill.hasEffectType(L2EffectType.DMG_OVER_TIME, L2EffectType.DMG_OVER_TIME_PERCENT))
{
aiSkillScopes.add(shortOrLongRangeScope);
}
else if (skill.hasEffectType(L2EffectType.RESURRECTION))
{
aiSkillScopes.add(AISkillScope.RES);
}
else
{
aiSkillScopes.add(AISkillScope.UNIVERSAL);
}
}
for (AISkillScope aiSkillScope : aiSkillScopes)
{
List<Skill> aiSkills = aiSkillLists.get(aiSkillScope);
if (aiSkills == null)
{
aiSkills = new ArrayList<>();
aiSkillLists.put(aiSkillScope, aiSkills);
}
aiSkills.add(skill);
}
}
template.setSkills(skills);
template.setAISkillLists(aiSkillLists);
}
else
{
template.setSkills(null);
template.setAISkillLists(null);
}
template.setClans(clans);
template.setIgnoreClanNpcIds(ignoreClanNpcIds);
template.setDropLists(dropLists);
}
}
}
}
}
private void parseDropList(File f, Node dropListNode, DropListScope dropListScope, List<IDropItem> drops)
{
for (Node dropNode = dropListNode.getFirstChild(); dropNode != null; dropNode = dropNode.getNextSibling())
{
switch (dropNode.getNodeName().toLowerCase())
{
case "group":
{
final GroupedGeneralDropItem dropItem = dropListScope.newGroupedDropItem(parseDouble(dropNode.getAttributes(), "chance"));
final List<IDropItem> groupedDropList = new ArrayList<>(2);
for (Node groupNode = dropNode.getFirstChild(); groupNode != null; groupNode = groupNode.getNextSibling())
{
parseDropListItem(groupNode, dropListScope, groupedDropList);
}
final List<GeneralDropItem> items = new ArrayList<>(groupedDropList.size());
for (IDropItem item : groupedDropList)
{
if (item instanceof GeneralDropItem)
{
items.add((GeneralDropItem) item);
}
else
{
LOGGER.warning("[" + f + "] grouped general drop item supports only general drop item.");
}
}
dropItem.setItems(items);
drops.add(dropItem);
break;
}
default:
{
parseDropListItem(dropNode, dropListScope, drops);
break;
}
}
}
}
private void parseDropListItem(Node dropListItem, DropListScope dropListScope, List<IDropItem> drops)
{
final NamedNodeMap attrs = dropListItem.getAttributes();
switch (dropListItem.getNodeName().toLowerCase())
{
case "item":
{
final IDropItem dropItem = dropListScope.newDropItem(parseInteger(attrs, "id"), parseLong(attrs, "min"), parseLong(attrs, "max"), parseDouble(attrs, "chance"));
if (dropItem != null)
{
drops.add(dropItem);
}
break;
}
}
}
/**
* Gets or creates a clan id if it doesnt exists.
* @param clanName the clan name to get or create its id
* @return the clan id for the given clan name
*/
private int getOrCreateClanId(String clanName)
{
Integer id = _clans.get(clanName.toUpperCase());
if (id == null)
{
id = _clans.size();
_clans.put(clanName.toUpperCase(), id);
}
return id;
}
/**
* Gets the clan id
* @param clanName the clan name to get its id
* @return the clan id for the given clan name if it exists, -1 otherwise
*/
public int getClanId(String clanName)
{
final Integer id = _clans.get(clanName.toUpperCase());
return id != null ? id : -1;
}
/**
* Gets the template.
* @param id the template Id to get.
* @return the template for the given id.
*/
public L2NpcTemplate getTemplate(int id)
{
return _npcs.get(id);
}
/**
* Gets the template by name.
* @param name of the template to get.
* @return the template for the given name.
*/
public L2NpcTemplate getTemplateByName(String name)
{
for (L2NpcTemplate npcTemplate : _npcs.values())
{
if (npcTemplate.getName().equalsIgnoreCase(name))
{
return npcTemplate;
}
}
return null;
}
/**
* Gets all templates matching the filter.
* @param filter
* @return the template list for the given filter
*/
public List<L2NpcTemplate> getTemplates(Predicate<L2NpcTemplate> filter)
{
//@formatter:off
return _npcs.values().stream()
.filter(filter)
.collect(Collectors.toList());
//@formatter:on
}
/**
* Gets the all of level.
* @param lvls of all the templates to get.
* @return the template list for the given level.
*/
public List<L2NpcTemplate> getAllOfLevel(int... lvls)
{
return getTemplates(template -> Util.contains(lvls, template.getLevel()));
}
/**
* Gets the all monsters of level.
* @param lvls of all the monster templates to get.
* @return the template list for the given level.
*/
public List<L2NpcTemplate> getAllMonstersOfLevel(int... lvls)
{
return getTemplates(template -> Util.contains(lvls, template.getLevel()) && template.isType("L2Monster"));
}
/**
* Gets the all npc starting with.
* @param text of all the NPC templates which its name start with.
* @return the template list for the given letter.
*/
public List<L2NpcTemplate> getAllNpcStartingWith(String text)
{
return getTemplates(template -> template.isType("L2Npc") && template.getName().startsWith(text));
}
/**
* Gets the all npc of class type.
* @param classTypes of all the templates to get.
* @return the template list for the given class type.
*/
public List<L2NpcTemplate> getAllNpcOfClassType(String... classTypes)
{
return getTemplates(template -> Util.contains(classTypes, template.getType(), true));
}
public void loadNpcsSkillLearn()
{
_npcs.values().forEach(template ->
{
final List<ClassId> teachInfo = SkillLearnData.getInstance().getSkillLearnData(template.getId());
if (teachInfo != null)
{
template.addTeachInfo(teachInfo);
}
});
}
/**
* This class handles minions from Spawn System<br>
* Once Spawn System gets reworked delete this class<br>
* @author Zealar
*/
private final class MinionData implements IXmlReader
{
public final Map<Integer, List<MinionHolder>> _tempMinions = new HashMap<>();
protected MinionData()
{
load();
}
@Override
public void load()
{
_tempMinions.clear();
parseDatapackFile("MinionData.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _tempMinions.size() + " minions data.");
}
@Override
public void parseDocument(Document doc)
{
for (Node node = doc.getFirstChild(); node != null; node = node.getNextSibling())
{
if ("list".equals(node.getNodeName()))
{
for (Node listNode = node.getFirstChild(); listNode != null; listNode = listNode.getNextSibling())
{
if ("npc".equals(listNode.getNodeName()))
{
final List<MinionHolder> minions = new ArrayList<>(1);
NamedNodeMap attrs = listNode.getAttributes();
final int id = parseInteger(attrs, "id");
for (Node npcNode = listNode.getFirstChild(); npcNode != null; npcNode = npcNode.getNextSibling())
{
if ("minion".equals(npcNode.getNodeName()))
{
attrs = npcNode.getAttributes();
minions.add(new MinionHolder(parseInteger(attrs, "id"), parseInteger(attrs, "count"), parseInteger(attrs, "respawnTime"), 0));
}
}
_tempMinions.put(id, minions);
}
}
}
}
}
}
/**
* Gets the single instance of NpcData.
* @return single instance of NpcData
*/
public static NpcData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final NpcData _instance = new NpcData();
}
}

View File

@@ -0,0 +1,161 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
import com.l2jmobius.gameserver.model.options.Options;
import com.l2jmobius.gameserver.model.options.OptionsSkillHolder;
import com.l2jmobius.gameserver.model.options.OptionsSkillType;
import com.l2jmobius.gameserver.model.stats.Stats;
import com.l2jmobius.gameserver.model.stats.functions.FuncTemplate;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* Item Option data.
* @author UnAfraid
*/
public class OptionData implements IXmlReader
{
private final Map<Integer, Options> _optionData = new HashMap<>();
protected OptionData()
{
load();
}
@Override
public synchronized void load()
{
_optionData.clear();
parseDatapackDirectory("stats/options", false);
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _optionData.size() + " Options.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("option".equalsIgnoreCase(d.getNodeName()))
{
final int id = parseInteger(d.getAttributes(), "id");
final Options op = new Options(id);
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
{
switch (cd.getNodeName())
{
case "for":
{
for (Node fd = cd.getFirstChild(); fd != null; fd = fd.getNextSibling())
{
switch (fd.getNodeName())
{
case "add":
case "sub":
case "mul":
case "div":
case "set":
case "share":
case "enchant":
case "enchanthp":
{
parseFuncs(fd.getAttributes(), fd.getNodeName(), op);
}
}
}
break;
}
case "active_skill":
{
op.addActiveSkill(new SkillHolder(parseInteger(cd.getAttributes(), "id"), parseInteger(cd.getAttributes(), "level")));
break;
}
case "passive_skill":
{
op.addPassiveSkill(new SkillHolder(parseInteger(cd.getAttributes(), "id"), parseInteger(cd.getAttributes(), "level")));
break;
}
case "attack_skill":
{
op.addActivationSkill(new OptionsSkillHolder(parseInteger(cd.getAttributes(), "id"), parseInteger(cd.getAttributes(), "level"), parseDouble(cd.getAttributes(), "chance"), OptionsSkillType.ATTACK));
break;
}
case "magic_skill":
{
op.addActivationSkill(new OptionsSkillHolder(parseInteger(cd.getAttributes(), "id"), parseInteger(cd.getAttributes(), "level"), parseDouble(cd.getAttributes(), "chance"), OptionsSkillType.MAGIC));
break;
}
case "critical_skill":
{
op.addActivationSkill(new OptionsSkillHolder(parseInteger(cd.getAttributes(), "id"), parseInteger(cd.getAttributes(), "level"), parseDouble(cd.getAttributes(), "chance"), OptionsSkillType.CRITICAL));
break;
}
}
}
_optionData.put(op.getId(), op);
}
}
}
}
}
private void parseFuncs(NamedNodeMap attrs, String functionName, Options op)
{
final Stats stat = Stats.valueOfXml(parseString(attrs, "stat"));
final double val = parseDouble(attrs, "val");
int order = -1;
final Node orderNode = attrs.getNamedItem("order");
if (orderNode != null)
{
order = Integer.parseInt(orderNode.getNodeValue());
}
op.addFunc(new FuncTemplate(null, null, functionName, order, stat, val));
}
public Options getOptions(int id)
{
return _optionData.get(id);
}
/**
* Gets the single instance of OptionsData.
* @return single instance of OptionsData
*/
public static OptionData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final OptionData _instance = new OptionData();
}
}

View File

@@ -0,0 +1,236 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.enums.MountType;
import com.l2jmobius.gameserver.model.L2PetData;
import com.l2jmobius.gameserver.model.L2PetLevelData;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* This class parse and hold all pet parameters.<br>
* TODO: load and use all pet parameters.
* @author Zoey76 (rework)
*/
public final class PetDataTable implements IXmlReader
{
private final Map<Integer, L2PetData> _pets = new HashMap<>();
/**
* Instantiates a new pet data table.
*/
protected PetDataTable()
{
load();
}
@Override
public void load()
{
_pets.clear();
parseDatapackDirectory("stats/pets", false);
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _pets.size() + " Pets.");
}
@Override
public void parseDocument(Document doc)
{
NamedNodeMap attrs;
for (Node d = doc.getFirstChild().getFirstChild(); d != null; d = d.getNextSibling())
{
if (d.getNodeName().equals("pet"))
{
final int npcId = parseInteger(d.getAttributes(), "id");
final int itemId = parseInteger(d.getAttributes(), "itemId");
// index ignored for now
final L2PetData data = new L2PetData(npcId, itemId);
for (Node p = d.getFirstChild(); p != null; p = p.getNextSibling())
{
if (p.getNodeName().equals("set"))
{
attrs = p.getAttributes();
final String type = attrs.getNamedItem("name").getNodeValue();
if ("food".equals(type))
{
for (String foodId : attrs.getNamedItem("val").getNodeValue().split(";"))
{
data.addFood(Integer.valueOf(foodId));
}
}
else if ("load".equals(type))
{
data.setLoad(parseInteger(attrs, "val"));
}
else if ("hungry_limit".equals(type))
{
data.setHungryLimit(parseInteger(attrs, "val"));
}
else if ("sync_level".equals(type))
{
data.setSyncLevel(parseInteger(attrs, "val") == 1);
}
// evolve ignored
}
else if (p.getNodeName().equals("skills"))
{
for (Node s = p.getFirstChild(); s != null; s = s.getNextSibling())
{
if (s.getNodeName().equals("skill"))
{
attrs = s.getAttributes();
data.addNewSkill(parseInteger(attrs, "skillId"), parseInteger(attrs, "skillLvl"), parseInteger(attrs, "minLvl"));
}
}
}
else if (p.getNodeName().equals("stats"))
{
for (Node s = p.getFirstChild(); s != null; s = s.getNextSibling())
{
if (s.getNodeName().equals("stat"))
{
final int level = Integer.parseInt(s.getAttributes().getNamedItem("level").getNodeValue());
final StatsSet set = new StatsSet();
for (Node bean = s.getFirstChild(); bean != null; bean = bean.getNextSibling())
{
if (bean.getNodeName().equals("set"))
{
attrs = bean.getAttributes();
if (attrs.getNamedItem("name").getNodeValue().equals("speed_on_ride"))
{
set.set("walkSpeedOnRide", attrs.getNamedItem("walk").getNodeValue());
set.set("runSpeedOnRide", attrs.getNamedItem("run").getNodeValue());
set.set("slowSwimSpeedOnRide", attrs.getNamedItem("slowSwim").getNodeValue());
set.set("fastSwimSpeedOnRide", attrs.getNamedItem("fastSwim").getNodeValue());
if (attrs.getNamedItem("slowFly") != null)
{
set.set("slowFlySpeedOnRide", attrs.getNamedItem("slowFly").getNodeValue());
}
if (attrs.getNamedItem("fastFly") != null)
{
set.set("fastFlySpeedOnRide", attrs.getNamedItem("fastFly").getNodeValue());
}
}
else
{
set.set(attrs.getNamedItem("name").getNodeValue(), attrs.getNamedItem("val").getNodeValue());
}
}
}
data.addNewStat(level, new L2PetLevelData(set));
}
}
}
}
_pets.put(npcId, data);
}
}
}
/**
* @param itemId
* @return
*/
public L2PetData getPetDataByItemId(int itemId)
{
for (L2PetData data : _pets.values())
{
if (data.getItemId() == itemId)
{
return data;
}
}
return null;
}
/**
* Gets the pet level data.
* @param petId the pet Id.
* @param petLevel the pet level.
* @return the pet's parameters for the given Id and level.
*/
public L2PetLevelData getPetLevelData(int petId, int petLevel)
{
final L2PetData pd = getPetData(petId);
return pd != null ? pd.getPetLevelData(petLevel) : null;
}
/**
* Gets the pet data.
* @param petId the pet Id.
* @return the pet data
*/
public L2PetData getPetData(int petId)
{
if (!_pets.containsKey(petId))
{
LOGGER.info(getClass().getSimpleName() + ": Missing pet data for npcid: " + petId);
}
return _pets.get(petId);
}
/**
* Gets the pet min level.
* @param petId the pet Id.
* @return the pet min level
*/
public int getPetMinLevel(int petId)
{
return _pets.get(petId).getMinLevel();
}
/**
* Gets the pet items by npc.
* @param npcId the NPC ID to get its summoning item
* @return summoning item for the given NPC ID
*/
public int getPetItemsByNpc(int npcId)
{
return _pets.get(npcId).getItemId();
}
/**
* Checks if is mountable.
* @param npcId the NPC Id to verify.
* @return {@code true} if the given Id is from a mountable pet, {@code false} otherwise.
*/
public static boolean isMountable(int npcId)
{
return MountType.findByNpcId(npcId) != MountType.NONE;
}
/**
* Gets the single instance of PetDataTable.
* @return this class unique instance.
*/
public static PetDataTable getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final PetDataTable _instance = new PetDataTable();
}
}

View File

@@ -0,0 +1,192 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.templates.L2PcTemplate;
import com.l2jmobius.gameserver.model.base.ClassId;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* Loads player's base stats.
* @author Forsaiken, Zoey76, GKR
*/
public final class PlayerTemplateData implements IXmlReader
{
private static final Logger LOGGER = Logger.getLogger(PlayerTemplateData.class.getName());
private final Map<ClassId, L2PcTemplate> _playerTemplates = new HashMap<>();
private int _dataCount = 0;
protected PlayerTemplateData()
{
load();
}
@Override
public void load()
{
_playerTemplates.clear();
parseDatapackDirectory("stats/chars/baseStats", false);
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _playerTemplates.size() + " character templates.");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _dataCount + " level up gain records.");
}
@Override
public void parseDocument(Document doc)
{
NamedNodeMap attrs;
int classId = 0;
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("classId".equalsIgnoreCase(d.getNodeName()))
{
classId = Integer.parseInt(d.getTextContent());
}
else if ("staticData".equalsIgnoreCase(d.getNodeName()))
{
final StatsSet set = new StatsSet();
set.set("classId", classId);
final List<Location> creationPoints = new ArrayList<>();
for (Node nd = d.getFirstChild(); nd != null; nd = nd.getNextSibling())
{
// Skip odd nodes
if (nd.getNodeName().equals("#text"))
{
continue;
}
if (nd.getChildNodes().getLength() > 1)
{
for (Node cnd = nd.getFirstChild(); cnd != null; cnd = cnd.getNextSibling())
{
// use L2CharTemplate(superclass) fields for male collision height and collision radius
if (nd.getNodeName().equalsIgnoreCase("collisionMale"))
{
if (cnd.getNodeName().equalsIgnoreCase("radius"))
{
set.set("collisionRadius", cnd.getTextContent());
}
else if (cnd.getNodeName().equalsIgnoreCase("height"))
{
set.set("collisionHeight", cnd.getTextContent());
}
}
if ("node".equalsIgnoreCase(cnd.getNodeName()))
{
attrs = cnd.getAttributes();
creationPoints.add(new Location(parseInteger(attrs, "x"), parseInteger(attrs, "y"), parseInteger(attrs, "z")));
}
else if ("walk".equalsIgnoreCase(cnd.getNodeName()))
{
set.set("baseWalkSpd", cnd.getTextContent());
}
else if ("run".equalsIgnoreCase(cnd.getNodeName()))
{
set.set("baseRunSpd", cnd.getTextContent());
}
else if ("slowSwim".equals(cnd.getNodeName()))
{
set.set("baseSwimWalkSpd", cnd.getTextContent());
}
else if ("fastSwim".equals(cnd.getNodeName()))
{
set.set("baseSwimRunSpd", cnd.getTextContent());
}
else if (!cnd.getNodeName().equals("#text"))
{
set.set(nd.getNodeName() + cnd.getNodeName(), cnd.getTextContent());
}
}
}
else
{
set.set(nd.getNodeName(), nd.getTextContent());
}
}
// calculate total pdef and mdef from parts
set.set("basePDef", set.getInt("basePDefchest", 0) + set.getInt("basePDeflegs", 0) + set.getInt("basePDefhead", 0) + set.getInt("basePDeffeet", 0) + set.getInt("basePDefgloves", 0) + set.getInt("basePDefunderwear", 0) + set.getInt("basePDefcloak", 0));
set.set("baseMDef", set.getInt("baseMDefrear", 0) + set.getInt("baseMDeflear", 0) + set.getInt("baseMDefrfinger", 0) + set.getInt("baseMDefrfinger", 0) + set.getInt("baseMDefneck", 0));
_playerTemplates.put(ClassId.getClassId(classId), new L2PcTemplate(set, creationPoints));
}
else if ("lvlUpgainData".equalsIgnoreCase(d.getNodeName()))
{
for (Node lvlNode = d.getFirstChild(); lvlNode != null; lvlNode = lvlNode.getNextSibling())
{
if ("level".equalsIgnoreCase(lvlNode.getNodeName()))
{
attrs = lvlNode.getAttributes();
final int level = parseInteger(attrs, "val");
for (Node valNode = lvlNode.getFirstChild(); valNode != null; valNode = valNode.getNextSibling())
{
final String nodeName = valNode.getNodeName();
if ((level < Config.PLAYER_MAXIMUM_LEVEL) && (nodeName.startsWith("hp") || nodeName.startsWith("mp") || nodeName.startsWith("cp")) && _playerTemplates.containsKey(ClassId.getClassId(classId)))
{
_playerTemplates.get(ClassId.getClassId(classId)).setUpgainValue(nodeName, level, Double.parseDouble(valNode.getTextContent()));
_dataCount++;
}
}
}
}
// TODO: Generate stats automatically.
}
}
}
}
}
public L2PcTemplate getTemplate(ClassId classId)
{
return _playerTemplates.get(classId);
}
public L2PcTemplate getTemplate(int classId)
{
return _playerTemplates.get(ClassId.getClassId(classId));
}
public static PlayerTemplateData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final PlayerTemplateData _instance = new PlayerTemplateData();
}
}

View File

@@ -0,0 +1,95 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.Arrays;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* This class holds the Player Xp Percent Lost Data for each level for players.
* @author Zealar
*/
public final class PlayerXpPercentLostData implements IXmlReader
{
private final int _maxlevel = ExperienceData.getInstance().getMaxLevel();
private final double[] _playerXpPercentLost = new double[_maxlevel + 1];
protected PlayerXpPercentLostData()
{
Arrays.fill(_playerXpPercentLost, 1.);
load();
}
@Override
public void load()
{
parseDatapackFile("stats/chars/playerXpPercentLost.xml");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("xpLost".equalsIgnoreCase(d.getNodeName()))
{
final NamedNodeMap attrs = d.getAttributes();
final Integer level = parseInteger(attrs, "level");
if (level > _maxlevel)
{
break;
}
_playerXpPercentLost[level] = parseDouble(attrs, "val");
}
}
}
}
}
public double getXpPercent(int level)
{
if (level <= _maxlevel)
{
return _playerXpPercentLost[level];
}
LOGGER.warning("Require to high level inside PlayerXpPercentLostData (" + level + ")");
return _playerXpPercentLost[_maxlevel];
}
/**
* Gets the single instance of PlayerXpPercentLostData.
* @return single instance of PlayerXpPercentLostData.
*/
public static PlayerXpPercentLostData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final PlayerXpPercentLostData _instance = new PlayerXpPercentLostData();
}
}

View File

@@ -0,0 +1,141 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.datatables.ItemTable;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.items.L2Item;
import com.l2jmobius.gameserver.model.primeshop.PrimeShopGroup;
import com.l2jmobius.gameserver.model.primeshop.PrimeShopItem;
import com.l2jmobius.gameserver.network.serverpackets.primeshop.ExBRProductInfo;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* @author Gnacik, UnAfraid
*/
public class PrimeShopData implements IXmlReader
{
private final Map<Integer, PrimeShopGroup> _primeItems = new LinkedHashMap<>();
protected PrimeShopData()
{
load();
}
@Override
public void load()
{
_primeItems.clear();
parseDatapackFile("PrimeShop.xml");
LOGGER.info(_primeItems.size() > 0 ? getClass().getSimpleName() + ": Loaded " + _primeItems.size() + " items" : getClass().getSimpleName() + ": System is disabled.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
final NamedNodeMap at = n.getAttributes();
final Node attribute = at.getNamedItem("enabled");
if ((attribute != null) && Boolean.parseBoolean(attribute.getNodeValue()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("item".equalsIgnoreCase(d.getNodeName()))
{
NamedNodeMap attrs = d.getAttributes();
Node att;
final StatsSet set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
final List<PrimeShopItem> items = new ArrayList<>();
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("item".equalsIgnoreCase(b.getNodeName()))
{
attrs = b.getAttributes();
final int itemId = parseInteger(attrs, "itemId");
final int count = parseInteger(attrs, "count");
final L2Item item = ItemTable.getInstance().getTemplate(itemId);
if (item == null)
{
LOGGER.severe(getClass().getSimpleName() + ": Item template null for itemId: " + itemId + " brId: " + set.getInt("id"));
return;
}
items.add(new PrimeShopItem(itemId, count, item.getWeight(), item.isTradeable() ? 1 : 0));
}
}
_primeItems.put(set.getInt("id"), new PrimeShopGroup(set, items));
}
}
}
}
}
}
public void showProductInfo(L2PcInstance player, int brId)
{
final PrimeShopGroup item = _primeItems.get(brId);
if ((player == null) || (item == null))
{
return;
}
player.sendPacket(new ExBRProductInfo(item));
}
public PrimeShopGroup getItem(int brId)
{
return _primeItems.get(brId);
}
public Map<Integer, PrimeShopGroup> getPrimeItems()
{
return _primeItems;
}
public static PrimeShopData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final PrimeShopData _instance = new PrimeShopData();
}
}

View File

@@ -0,0 +1,277 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.L2RecipeInstance;
import com.l2jmobius.gameserver.model.L2RecipeList;
import com.l2jmobius.gameserver.model.L2RecipeStatInstance;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* The Class RecipeData.
* @author Zoey76
*/
public class RecipeData implements IXmlReader
{
private final Map<Integer, L2RecipeList> _recipes = new HashMap<>();
/**
* Instantiates a new recipe data.
*/
protected RecipeData()
{
load();
}
@Override
public void load()
{
_recipes.clear();
parseDatapackFile("Recipes.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _recipes.size() + " recipes.");
}
@Override
public void parseDocument(Document doc)
{
// TODO: Cleanup checks enforced by XSD.
final List<L2RecipeInstance> recipePartList = new ArrayList<>();
final List<L2RecipeStatInstance> recipeStatUseList = new ArrayList<>();
final List<L2RecipeStatInstance> recipeAltStatChangeList = new ArrayList<>();
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
RECIPES_FILE: for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("item".equalsIgnoreCase(d.getNodeName()))
{
recipePartList.clear();
recipeStatUseList.clear();
recipeAltStatChangeList.clear();
final NamedNodeMap attrs = d.getAttributes();
Node att;
int id = -1;
boolean haveRare = false;
final StatsSet set = new StatsSet();
att = attrs.getNamedItem("id");
if (att == null)
{
LOGGER.severe(getClass().getSimpleName() + ": Missing id for recipe item, skipping");
continue;
}
id = Integer.parseInt(att.getNodeValue());
set.set("id", id);
att = attrs.getNamedItem("recipeId");
if (att == null)
{
LOGGER.severe(getClass().getSimpleName() + ": Missing recipeId for recipe item id: " + id + ", skipping");
continue;
}
set.set("recipeId", Integer.parseInt(att.getNodeValue()));
att = attrs.getNamedItem("name");
if (att == null)
{
LOGGER.severe(getClass().getSimpleName() + ": Missing name for recipe item id: " + id + ", skipping");
continue;
}
set.set("recipeName", att.getNodeValue());
att = attrs.getNamedItem("craftLevel");
if (att == null)
{
LOGGER.severe(getClass().getSimpleName() + ": Missing level for recipe item id: " + id + ", skipping");
continue;
}
set.set("craftLevel", Integer.parseInt(att.getNodeValue()));
att = attrs.getNamedItem("type");
if (att == null)
{
LOGGER.severe(getClass().getSimpleName() + ": Missing type for recipe item id: " + id + ", skipping");
continue;
}
set.set("isDwarvenRecipe", att.getNodeValue().equalsIgnoreCase("dwarven"));
att = attrs.getNamedItem("successRate");
if (att == null)
{
LOGGER.severe(getClass().getSimpleName() + ": Missing successRate for recipe item id: " + id + ", skipping");
continue;
}
set.set("successRate", Integer.parseInt(att.getNodeValue()));
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
{
if ("statUse".equalsIgnoreCase(c.getNodeName()))
{
final String statName = c.getAttributes().getNamedItem("name").getNodeValue();
final int value = Integer.parseInt(c.getAttributes().getNamedItem("value").getNodeValue());
try
{
recipeStatUseList.add(new L2RecipeStatInstance(statName, value));
}
catch (Exception e)
{
LOGGER.severe(getClass().getSimpleName() + ": Error in StatUse parameter for recipe item id: " + id + ", skipping");
continue RECIPES_FILE;
}
}
else if ("altStatChange".equalsIgnoreCase(c.getNodeName()))
{
final String statName = c.getAttributes().getNamedItem("name").getNodeValue();
final int value = Integer.parseInt(c.getAttributes().getNamedItem("value").getNodeValue());
try
{
recipeAltStatChangeList.add(new L2RecipeStatInstance(statName, value));
}
catch (Exception e)
{
LOGGER.severe(getClass().getSimpleName() + ": Error in AltStatChange parameter for recipe item id: " + id + ", skipping");
continue RECIPES_FILE;
}
}
else if ("ingredient".equalsIgnoreCase(c.getNodeName()))
{
recipePartList.add(new L2RecipeInstance(Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue()), Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue())));
}
else if ("production".equalsIgnoreCase(c.getNodeName()))
{
set.set("itemId", Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue()));
set.set("count", Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue()));
}
else if ("productionRare".equalsIgnoreCase(c.getNodeName()))
{
set.set("rareItemId", Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue()));
set.set("rareCount", Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue()));
set.set("rarity", Integer.parseInt(c.getAttributes().getNamedItem("rarity").getNodeValue()));
haveRare = true;
}
}
final L2RecipeList recipeList = new L2RecipeList(set, haveRare);
for (L2RecipeInstance recipePart : recipePartList)
{
recipeList.addRecipe(recipePart);
}
for (L2RecipeStatInstance recipeStatUse : recipeStatUseList)
{
recipeList.addStatUse(recipeStatUse);
}
for (L2RecipeStatInstance recipeAltStatChange : recipeAltStatChangeList)
{
recipeList.addAltStatChange(recipeAltStatChange);
}
_recipes.put(id, recipeList);
}
}
}
}
}
/**
* Gets the recipe list.
* @param listId the list id
* @return the recipe list
*/
public L2RecipeList getRecipeList(int listId)
{
return _recipes.get(listId);
}
/**
* Gets the recipe by item id.
* @param itemId the item id
* @return the recipe by item id
*/
public L2RecipeList getRecipeByItemId(int itemId)
{
for (L2RecipeList find : _recipes.values())
{
if (find.getRecipeId() == itemId)
{
return find;
}
}
return null;
}
/**
* Gets the all item ids.
* @return the all item ids
*/
public int[] getAllItemIds()
{
final int[] idList = new int[_recipes.size()];
int i = 0;
for (L2RecipeList rec : _recipes.values())
{
idList[i++] = rec.getRecipeId();
}
return idList;
}
/**
* Gets the valid recipe list.
* @param player the player
* @param id the recipe list id
* @return the valid recipe list
*/
public L2RecipeList getValidRecipeList(L2PcInstance player, int id)
{
final L2RecipeList recipeList = _recipes.get(id);
if ((recipeList == null) || (recipeList.getRecipes().length == 0))
{
player.sendMessage(getClass().getSimpleName() + ": No recipe for: " + id);
player.isInCraftMode(false);
return null;
}
return recipeList;
}
/**
* Gets the single instance of RecipeData.
* @return single instance of RecipeData
*/
public static RecipeData getInstance()
{
return SingletonHolder._instance;
}
/**
* The Class SingletonHolder.
*/
private static class SingletonHolder
{
protected static final RecipeData _instance = new RecipeData();
}
}

View File

@@ -0,0 +1,140 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* Secondary Auth data.
* @author NosBit
*/
public class SecondaryAuthData implements IXmlReader
{
private final Set<String> _forbiddenPasswords = new HashSet<>();
private boolean _enabled = false;
private int _maxAttempts = 5;
private int _banTime = 480;
private String _recoveryLink = "";
protected SecondaryAuthData()
{
load();
}
@Override
public synchronized void load()
{
_forbiddenPasswords.clear();
parseFile(new File("config/SecondaryAuth.xml"));
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _forbiddenPasswords.size() + " forbidden passwords.");
}
@Override
public void parseDocument(Document doc)
{
try
{
for (Node node = doc.getFirstChild(); node != null; node = node.getNextSibling())
{
if ("list".equalsIgnoreCase(node.getNodeName()))
{
for (Node list_node = node.getFirstChild(); list_node != null; list_node = list_node.getNextSibling())
{
if ("enabled".equalsIgnoreCase(list_node.getNodeName()))
{
_enabled = Boolean.parseBoolean(list_node.getTextContent());
}
else if ("maxAttempts".equalsIgnoreCase(list_node.getNodeName()))
{
_maxAttempts = Integer.parseInt(list_node.getTextContent());
}
else if ("banTime".equalsIgnoreCase(list_node.getNodeName()))
{
_banTime = Integer.parseInt(list_node.getTextContent());
}
else if ("recoveryLink".equalsIgnoreCase(list_node.getNodeName()))
{
_recoveryLink = list_node.getTextContent();
}
else if ("forbiddenPasswords".equalsIgnoreCase(list_node.getNodeName()))
{
for (Node forbiddenPasswords_node = list_node.getFirstChild(); forbiddenPasswords_node != null; forbiddenPasswords_node = forbiddenPasswords_node.getNextSibling())
{
if ("password".equalsIgnoreCase(forbiddenPasswords_node.getNodeName()))
{
_forbiddenPasswords.add(forbiddenPasswords_node.getTextContent());
}
}
}
}
}
}
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, "Failed to load secondary auth data from xml.", e);
}
}
public boolean isEnabled()
{
return _enabled;
}
public int getMaxAttempts()
{
return _maxAttempts;
}
public int getBanTime()
{
return _banTime;
}
public String getRecoveryLink()
{
return _recoveryLink;
}
public Set<String> getForbiddenPasswords()
{
return _forbiddenPasswords;
}
public boolean isForbiddenPassword(String password)
{
return _forbiddenPasswords.contains(password);
}
public static SecondaryAuthData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final SecondaryAuthData _instance = new SecondaryAuthData();
}
}

View File

@@ -0,0 +1,199 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.Location;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.VehiclePathPoint;
import com.l2jmobius.gameserver.model.actor.instance.L2ShuttleInstance;
import com.l2jmobius.gameserver.model.actor.templates.L2CharTemplate;
import com.l2jmobius.gameserver.model.shuttle.L2ShuttleData;
import com.l2jmobius.gameserver.model.shuttle.L2ShuttleEngine;
import com.l2jmobius.gameserver.model.shuttle.L2ShuttleStop;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* @author UnAfraid
*/
public final class ShuttleData implements IXmlReader
{
private final Map<Integer, L2ShuttleData> _shuttles = new HashMap<>();
private final Map<Integer, L2ShuttleInstance> _shuttleInstances = new HashMap<>();
protected ShuttleData()
{
load();
}
@Override
public synchronized void load()
{
if (!_shuttleInstances.isEmpty())
{
for (L2ShuttleInstance shuttle : _shuttleInstances.values())
{
shuttle.deleteMe();
}
_shuttleInstances.clear();
}
parseDatapackFile("ShuttleData.xml");
init();
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _shuttles.size() + " Shuttles.");
}
@Override
public void parseDocument(Document doc)
{
NamedNodeMap attrs;
StatsSet set;
Node att;
L2ShuttleData data;
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("shuttle".equalsIgnoreCase(d.getNodeName()))
{
attrs = d.getAttributes();
set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
data = new L2ShuttleData(set);
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("doors".equalsIgnoreCase(b.getNodeName()))
{
for (Node a = b.getFirstChild(); a != null; a = a.getNextSibling())
{
if ("door".equalsIgnoreCase(a.getNodeName()))
{
attrs = a.getAttributes();
data.addDoor(parseInteger(attrs, "id"));
}
}
}
else if ("stops".equalsIgnoreCase(b.getNodeName()))
{
for (Node a = b.getFirstChild(); a != null; a = a.getNextSibling())
{
if ("stop".equalsIgnoreCase(a.getNodeName()))
{
attrs = a.getAttributes();
final L2ShuttleStop stop = new L2ShuttleStop(parseInteger(attrs, "id"));
for (Node z = a.getFirstChild(); z != null; z = z.getNextSibling())
{
if ("dimension".equalsIgnoreCase(z.getNodeName()))
{
attrs = z.getAttributes();
stop.addDimension(new Location(parseInteger(attrs, "x"), parseInteger(attrs, "y"), parseInteger(attrs, "z")));
}
}
data.addStop(stop);
}
}
}
else if ("routes".equalsIgnoreCase(b.getNodeName()))
{
for (Node a = b.getFirstChild(); a != null; a = a.getNextSibling())
{
if ("route".equalsIgnoreCase(a.getNodeName()))
{
attrs = a.getAttributes();
final List<Location> locs = new ArrayList<>();
for (Node z = a.getFirstChild(); z != null; z = z.getNextSibling())
{
if ("loc".equalsIgnoreCase(z.getNodeName()))
{
attrs = z.getAttributes();
locs.add(new Location(parseInteger(attrs, "x"), parseInteger(attrs, "y"), parseInteger(attrs, "z")));
}
}
final VehiclePathPoint[] route = new VehiclePathPoint[locs.size()];
int i = 0;
for (Location loc : locs)
{
route[i++] = new VehiclePathPoint(loc);
}
data.addRoute(route);
}
}
}
}
_shuttles.put(data.getId(), data);
}
}
}
}
}
private void init()
{
for (L2ShuttleData data : _shuttles.values())
{
final L2ShuttleInstance shuttle = new L2ShuttleInstance(new L2CharTemplate(new StatsSet()));
shuttle.setData(data);
shuttle.setHeading(data.getLocation().getHeading());
shuttle.setLocationInvisible(data.getLocation());
shuttle.spawnMe();
shuttle.getStat().setMoveSpeed(300);
shuttle.getStat().setRotationSpeed(0);
shuttle.registerEngine(new L2ShuttleEngine(data, shuttle));
shuttle.runEngine(1000);
_shuttleInstances.put(shuttle.getObjectId(), shuttle);
}
}
public L2ShuttleInstance getShuttle(int id)
{
for (L2ShuttleInstance shuttle : _shuttleInstances.values())
{
if ((shuttle.getObjectId() == id) || (shuttle.getId() == id))
{
return shuttle;
}
}
return null;
}
public static ShuttleData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final ShuttleData _instance = new ShuttleData();
}
}

View File

@@ -0,0 +1,122 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.SiegeScheduleDate;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.util.Util;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* Siege Schedule data.
* @author UnAfraid
*/
public class SiegeScheduleData implements IXmlReader
{
private final List<SiegeScheduleDate> _scheduleData = new ArrayList<>();
protected SiegeScheduleData()
{
load();
}
@Override
public synchronized void load()
{
_scheduleData.clear();
parseDatapackFile("../config/SiegeSchedule.xml");
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _scheduleData.size() + " siege schedulers.");
if (!_scheduleData.isEmpty())
{
return;
}
_scheduleData.add(new SiegeScheduleDate(new StatsSet()));
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Emergency Loaded: " + _scheduleData.size() + " default siege schedulers.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node cd = n.getFirstChild(); cd != null; cd = cd.getNextSibling())
{
switch (cd.getNodeName())
{
case "schedule":
{
final StatsSet set = new StatsSet();
final NamedNodeMap attrs = cd.getAttributes();
for (int i = 0; i < attrs.getLength(); i++)
{
final Node node = attrs.item(i);
final String key = node.getNodeName();
String val = node.getNodeValue();
if ("day".equals(key) && !Util.isDigit(val))
{
val = Integer.toString(getValueForField(val));
}
set.set(key, val);
}
_scheduleData.add(new SiegeScheduleDate(set));
break;
}
}
}
}
}
}
private int getValueForField(String field)
{
try
{
return Calendar.class.getField(field).getInt(Calendar.class);
}
catch (Exception e)
{
LOGGER.log(Level.WARNING, "", e);
return -1;
}
}
public List<SiegeScheduleDate> getScheduleDates()
{
return _scheduleData;
}
public static SiegeScheduleData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final SiegeScheduleData _instance = new SiegeScheduleData();
}
}

View File

@@ -0,0 +1,99 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.base.ClassId;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* Holds all skill learn data for all NPCs.
* @author xban1x
*/
public final class SkillLearnData implements IXmlReader
{
private final Map<Integer, List<ClassId>> _skillLearn = new HashMap<>();
protected SkillLearnData()
{
load();
}
@Override
public synchronized void load()
{
_skillLearn.clear();
parseDatapackFile("SkillLearn.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _skillLearn.size() + " Skill Learn data.");
}
@Override
public void parseDocument(Document doc)
{
for (Node node = doc.getFirstChild(); node != null; node = node.getNextSibling())
{
if ("list".equalsIgnoreCase(node.getNodeName()))
{
for (Node list_node = node.getFirstChild(); list_node != null; list_node = list_node.getNextSibling())
{
if ("npc".equalsIgnoreCase(list_node.getNodeName()))
{
final List<ClassId> classIds = new ArrayList<>();
for (Node c = list_node.getFirstChild(); c != null; c = c.getNextSibling())
{
if ("classId".equalsIgnoreCase(c.getNodeName()))
{
classIds.add(ClassId.getClassId(Integer.parseInt(c.getTextContent())));
}
}
_skillLearn.put(parseInteger(list_node.getAttributes(), "id"), classIds);
}
}
}
}
}
/**
* @param npcId
* @return {@link List} of {@link ClassId}'s that this npcId can teach.
*/
public List<ClassId> getSkillLearnData(int npcId)
{
return _skillLearn.get(npcId);
}
/**
* Gets the single instance of SkillLearnData.
* @return single instance of SkillLearnData
*/
public static SkillLearnData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final SkillLearnData _instance = new SkillLearnData();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,105 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
import com.l2jmobius.gameserver.network.clientpackets.ensoul.SoulCrystalOption;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* @author Mathael
*/
public class SoulCrystalOptionsData implements IXmlReader
{
private static final HashMap<Integer, SoulCrystalOption> _soulCrystalOptions = new HashMap<>();
protected SoulCrystalOptionsData()
{
load();
}
@Override
public void load()
{
_soulCrystalOptions.clear();
parseDatapackFile("SoulCrystalOptions.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _soulCrystalOptions.size() + " Soul Crystal Options.");
}
@Override
public void parseDocument(Document doc)
{
int skillId;
int level;
int effectId;
int type;
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("SoulCrystalOptions".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("option".equalsIgnoreCase(d.getNodeName()))
{
final NamedNodeMap attrs = d.getAttributes();
skillId = parseInteger(attrs, "skillId", 0);
level = parseInteger(attrs, "level", 0);
effectId = parseInteger(attrs, "effectId", 0); // unique
type = parseInteger(attrs, "type", 1);
if (effectId == 0)
{
LOGGER.severe(getClass().getSimpleName() + ": Bad Soul Crystal Option [" + effectId + "] !");
return;
}
// Somes options need to be confirmed.
if (skillId != 0)
{
_soulCrystalOptions.put(effectId, new SoulCrystalOption(effectId, type == 2, new SkillHolder(skillId, level)));
}
}
}
}
}
}
public SoulCrystalOption getByEffectId(int effectId)
{
return _soulCrystalOptions.get(effectId);
}
public static SoulCrystalOptionsData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final SoulCrystalOptionsData _instance = new SoulCrystalOptionsData();
}
}

View File

@@ -0,0 +1,117 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.instance.L2StaticObjectInstance;
import com.l2jmobius.gameserver.model.actor.templates.L2CharTemplate;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* This class loads and holds all static object data.
* @author UnAfraid
*/
public final class StaticObjectData implements IXmlReader
{
private final Map<Integer, L2StaticObjectInstance> _staticObjects = new HashMap<>();
/**
* Instantiates a new static objects.
*/
protected StaticObjectData()
{
load();
}
@Override
public void load()
{
_staticObjects.clear();
parseDatapackFile("StaticObjects.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _staticObjects.size() + " static object templates.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("object".equalsIgnoreCase(d.getNodeName()))
{
final NamedNodeMap attrs = d.getAttributes();
final StatsSet set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
final Node att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
addObject(set);
}
}
}
}
}
/**
* Initialize an static object based on the stats set and add it to the map.
* @param set the stats set to add.
*/
private void addObject(StatsSet set)
{
final L2StaticObjectInstance obj = new L2StaticObjectInstance(new L2CharTemplate(new StatsSet()), set.getInt("id"));
obj.setType(set.getInt("type", 0));
obj.setName(set.getString("name"));
obj.setMap(set.getString("texture", "none"), set.getInt("map_x", 0), set.getInt("map_y", 0));
obj.spawnMe(set.getInt("x"), set.getInt("y"), set.getInt("z"));
_staticObjects.put(obj.getObjectId(), obj);
}
/**
* Gets the static objects.
* @return a collection of static objects.
*/
public Collection<L2StaticObjectInstance> getStaticObjects()
{
return _staticObjects.values();
}
/**
* Gets the single instance of StaticObjects.
* @return single instance of StaticObjects
*/
public static StaticObjectData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final StaticObjectData _instance = new StaticObjectData();
}
}

View File

@@ -0,0 +1,113 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.teleporter.TeleportHolder;
import com.l2jmobius.gameserver.model.teleporter.TeleportLocation;
import com.l2jmobius.gameserver.model.teleporter.TeleportType;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* @author UnAfraid
*/
public class TeleportersData implements IXmlReader
{
private final Map<Integer, TeleportHolder> _teleporters = new HashMap<>();
protected TeleportersData()
{
load();
}
@Override
public void load()
{
_teleporters.clear();
parseDatapackDirectory("teleporters", true);
LOGGER.log(Level.INFO, "Loaded: " + _teleporters.size() + " npc teleporters.");
}
@Override
public void parseDocument(Document doc)
{
for (Node listNode = doc.getFirstChild(); listNode != null; listNode = listNode.getNextSibling())
{
if ("list".equals(listNode.getNodeName()))
{
for (Node npcNode = listNode.getFirstChild(); npcNode != null; npcNode = npcNode.getNextSibling())
{
if ("npc".equals(npcNode.getNodeName()))
{
final int id = parseInteger(npcNode.getAttributes(), "id");
final TeleportHolder holder = new TeleportHolder(id);
for (Node tpNode = npcNode.getFirstChild(); tpNode != null; tpNode = tpNode.getNextSibling())
{
if ("teleport".equals(tpNode.getNodeName()))
{
final TeleportType type = parseEnum(tpNode.getAttributes(), TeleportType.class, "type", TeleportType.NORMAL);
for (Node locNode = tpNode.getFirstChild(); locNode != null; locNode = locNode.getNextSibling())
{
if ("location".equals(locNode.getNodeName()))
{
final NamedNodeMap attrs = locNode.getAttributes();
final int nextId = holder.getLocations(type).size() + 1;
final StatsSet set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
final Node locationNode = attrs.item(i);
set.set(locationNode.getNodeName(), locationNode.getNodeValue());
}
holder.addLocation(type, new TeleportLocation(nextId, set));
}
}
}
}
_teleporters.put(id, holder);
}
}
}
}
}
public TeleportHolder getHolder(int npcId)
{
return _teleporters.get(npcId);
}
/**
* Gets the single instance of TeleportersData.
* @return single instance of TeleportersData
*/
public static TeleportersData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final TeleportersData _instance = new TeleportersData();
}
}

View File

@@ -0,0 +1,237 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.StatsSet;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.actor.transform.Transform;
import com.l2jmobius.gameserver.model.actor.transform.TransformLevelData;
import com.l2jmobius.gameserver.model.actor.transform.TransformTemplate;
import com.l2jmobius.gameserver.model.holders.AdditionalItemHolder;
import com.l2jmobius.gameserver.model.holders.AdditionalSkillHolder;
import com.l2jmobius.gameserver.model.holders.SkillHolder;
import com.l2jmobius.gameserver.network.serverpackets.ExBasicActionList;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* Transformation data.
* @author UnAfraid
*/
public final class TransformData implements IXmlReader
{
private final Map<Integer, Transform> _transformData = new HashMap<>();
protected TransformData()
{
load();
}
@Override
public synchronized void load()
{
_transformData.clear();
parseDatapackDirectory("stats/transformations", false);
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _transformData.size() + " transform templates.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("transform".equalsIgnoreCase(d.getNodeName()))
{
NamedNodeMap attrs = d.getAttributes();
final StatsSet set = new StatsSet();
for (int i = 0; i < attrs.getLength(); i++)
{
final Node att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
final Transform transform = new Transform(set);
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
{
final boolean isMale = "Male".equalsIgnoreCase(cd.getNodeName());
if ("Male".equalsIgnoreCase(cd.getNodeName()) || "Female".equalsIgnoreCase(cd.getNodeName()))
{
TransformTemplate templateData = null;
for (Node z = cd.getFirstChild(); z != null; z = z.getNextSibling())
{
switch (z.getNodeName())
{
case "common":
{
for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
{
switch (s.getNodeName())
{
case "base":
case "stats":
case "defense":
case "magicDefense":
case "collision":
case "moving":
{
attrs = s.getAttributes();
for (int i = 0; i < attrs.getLength(); i++)
{
final Node att = attrs.item(i);
set.set(att.getNodeName(), att.getNodeValue());
}
break;
}
}
}
templateData = new TransformTemplate(set);
transform.setTemplate(isMale, templateData);
break;
}
case "skills":
{
if (templateData == null)
{
templateData = new TransformTemplate(set);
transform.setTemplate(isMale, templateData);
}
for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
{
if ("skill".equals(s.getNodeName()))
{
attrs = s.getAttributes();
templateData.addSkill(new SkillHolder(parseInteger(attrs, "id"), parseInteger(attrs, "level")));
}
}
break;
}
case "actions":
{
if (templateData == null)
{
templateData = new TransformTemplate(set);
transform.setTemplate(isMale, templateData);
}
set.set("actions", z.getTextContent());
final int[] actions = set.getIntArray("actions", " ");
templateData.setBasicActionList(new ExBasicActionList(actions));
break;
}
case "additionalSkills":
{
if (templateData == null)
{
templateData = new TransformTemplate(set);
transform.setTemplate(isMale, templateData);
}
for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
{
if ("skill".equals(s.getNodeName()))
{
attrs = s.getAttributes();
templateData.addAdditionalSkill(new AdditionalSkillHolder(parseInteger(attrs, "id"), parseInteger(attrs, "level"), parseInteger(attrs, "minLevel")));
}
}
break;
}
case "items":
{
if (templateData == null)
{
templateData = new TransformTemplate(set);
transform.setTemplate(isMale, templateData);
}
for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
{
if ("item".equals(s.getNodeName()))
{
attrs = s.getAttributes();
templateData.addAdditionalItem(new AdditionalItemHolder(parseInteger(attrs, "id"), parseBoolean(attrs, "allowed")));
}
}
break;
}
case "levels":
{
if (templateData == null)
{
templateData = new TransformTemplate(set);
transform.setTemplate(isMale, templateData);
}
final StatsSet levelsSet = new StatsSet();
for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
{
if ("level".equals(s.getNodeName()))
{
attrs = s.getAttributes();
for (int i = 0; i < attrs.getLength(); i++)
{
final Node att = attrs.item(i);
levelsSet.set(att.getNodeName(), att.getNodeValue());
}
}
}
templateData.addLevelData(new TransformLevelData(levelsSet));
break;
}
}
}
}
}
_transformData.put(transform.getId(), transform);
}
}
}
}
}
public Transform getTransform(int id)
{
return _transformData.get(id);
}
public boolean transformPlayer(int id, L2PcInstance player)
{
final Transform transform = getTransform(id);
if (transform != null)
{
player.transform(transform);
}
return transform != null;
}
public static TransformData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final TransformData _instance = new TransformData();
}
}

View File

@@ -0,0 +1,193 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import com.l2jmobius.gameserver.model.ActionKey;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* UI Data parser.
* @author Zoey76
*/
public class UIData implements IXmlReader
{
private static final Logger LOGGER = Logger.getLogger(UIData.class.getName());
private final Map<Integer, List<ActionKey>> _storedKeys = new HashMap<>();
private final Map<Integer, List<Integer>> _storedCategories = new HashMap<>();
protected UIData()
{
load();
}
@Override
public void load()
{
_storedKeys.clear();
_storedCategories.clear();
parseDatapackFile("ui/ui_en.xml");
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _storedKeys.size() + " keys " + _storedCategories.size() + " categories.");
}
@Override
public void parseDocument(Document doc)
{
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
{
if ("list".equalsIgnoreCase(n.getNodeName()))
{
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("category".equalsIgnoreCase(d.getNodeName()))
{
parseCategory(d);
}
}
}
}
}
private void parseCategory(Node n)
{
final int cat = parseInteger(n.getAttributes(), "id");
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
{
if ("commands".equalsIgnoreCase(d.getNodeName()))
{
parseCommands(cat, d);
}
else if ("keys".equalsIgnoreCase(d.getNodeName()))
{
parseKeys(cat, d);
}
}
}
private void parseCommands(int cat, Node d)
{
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
{
if ("cmd".equalsIgnoreCase(c.getNodeName()))
{
addCategory(_storedCategories, cat, Integer.parseInt(c.getTextContent()));
}
}
}
private void parseKeys(int cat, Node d)
{
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
{
if ("key".equalsIgnoreCase(c.getNodeName()))
{
final ActionKey akey = new ActionKey(cat);
for (int i = 0; i < c.getAttributes().getLength(); i++)
{
final Node att = c.getAttributes().item(i);
final int val = Integer.parseInt(att.getNodeValue());
switch (att.getNodeName())
{
case "cmd":
{
akey.setCommandId(val);
break;
}
case "key":
{
akey.setKeyId(val);
break;
}
case "toggleKey1":
{
akey.setToogleKey1(val);
break;
}
case "toggleKey2":
{
akey.setToogleKey2(val);
break;
}
case "showType":
{
akey.setShowStatus(val);
break;
}
}
}
addKey(_storedKeys, cat, akey);
}
}
}
/**
* Add a category to the stored categories.
* @param map the map to store the category
* @param cat the category
* @param cmd the command
*/
public static void addCategory(Map<Integer, List<Integer>> map, int cat, int cmd)
{
map.computeIfAbsent(cat, k -> new ArrayList<>()).add(cmd);
}
/**
* Create and insert an Action Key into the stored keys.
* @param map the map to store the key
* @param cat the category
* @param akey the action key
*/
public static void addKey(Map<Integer, List<ActionKey>> map, int cat, ActionKey akey)
{
map.computeIfAbsent(cat, k -> new ArrayList<>()).add(akey);
}
/**
* @return the categories
*/
public Map<Integer, List<Integer>> getCategories()
{
return _storedCategories;
}
/**
* @return the keys
*/
public Map<Integer, List<ActionKey>> getKeys()
{
return _storedKeys;
}
public static UIData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final UIData _instance = new UIData();
}
}

View File

@@ -0,0 +1,157 @@
/*
* This file is part of the L2J Mobius project.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jmobius.gameserver.data.xml.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import com.l2jmobius.Config;
import com.l2jmobius.gameserver.instancemanager.MapRegionManager;
import com.l2jmobius.gameserver.model.holders.WallHolder;
import com.l2jmobius.util.data.xml.IXmlReader;
/**
* Loads Wall Data.
* @author Mobius
*/
public class WallData implements IXmlReader
{
private final Map<Integer, List<WallHolder>> _walls = new HashMap<>();
protected WallData()
{
load();
}
@Override
public void load()
{
if (!Config.ENABLE_WALL_DATA)
{
return;
}
_walls.clear();
parseDatapackDirectory("walls", false);
}
@Override
public void parseDocument(Document doc)
{
int point1X;
int point1Y;
int point2X;
int point2Y;
int minZ;
int maxZ;
int region;
int counter = 0;
for (Node a = doc.getFirstChild(); a != null; a = a.getNextSibling())
{
if ("list".equalsIgnoreCase(a.getNodeName()))
{
for (Node b = a.getFirstChild(); b != null; b = b.getNextSibling())
{
if ("wall".equalsIgnoreCase(b.getNodeName()))
{
final NamedNodeMap attrs = b.getAttributes();
point1X = parseInteger(attrs, "point1X");
point1Y = parseInteger(attrs, "point1Y");
point2X = parseInteger(attrs, "point2X");
point2Y = parseInteger(attrs, "point2Y");
minZ = parseInteger(attrs, "minZ");
maxZ = parseInteger(attrs, "maxZ");
region = MapRegionManager.getInstance().getMapRegionLocId(point1X, point1Y);
if (!_walls.containsKey(region))
{
_walls.put(region, new ArrayList<WallHolder>());
}
_walls.get(region).add(new WallHolder(point1X, point1Y, point2X, point2Y, minZ, maxZ));
counter++;
}
}
}
}
LOGGER.info(getClass().getSimpleName() + ": Loaded " + counter + " wall data.");
}
/**
* @param x
* @param y
* @param z
* @param tx
* @param ty
* @param tz
* @return {@code boolean}
*/
public boolean checkIfWallsBetween(int x, int y, int z, int tx, int ty, int tz)
{
if (!Config.ENABLE_WALL_DATA)
{
return false;
}
final Collection<WallHolder> allWalls = _walls.get(MapRegionManager.getInstance().getMapRegionLocId(x, y));
if (allWalls != null)
{
for (WallHolder wall : allWalls)
{
// lower part of the multiplier fraction, if it is 0 we avoid an error and also know that the lines are parallel
final int denominator = ((ty - y) * (wall.getPoint1X() - wall.getPoint2X())) - ((tx - x) * (wall.getPoint1Y() - wall.getPoint2Y()));
if (denominator == 0)
{
continue;
}
// multipliers to the equations of the lines. If they are lower than 0 or bigger than 1, we know that segments don't intersect
final float multiplier1 = (float) (((wall.getPoint2X() - wall.getPoint1X()) * (y - wall.getPoint1Y())) - ((wall.getPoint2Y() - wall.getPoint1Y()) * (x - wall.getPoint1X()))) / denominator;
final float multiplier2 = (float) (((tx - x) * (y - wall.getPoint1Y())) - ((ty - y) * (x - wall.getPoint1X()))) / denominator;
if ((multiplier1 >= 0) && (multiplier1 <= 1) && (multiplier2 >= 0) && (multiplier2 <= 1))
{
final int intersectZ = Math.round(z + (multiplier1 * (tz - z)));
// now checking if the resulting point is between the wall min and max z
if ((intersectZ > wall.getZMin()) && (intersectZ < wall.getZMax()))
{
return true;
}
}
}
}
return false;
}
public List<WallHolder> getRegionWalls(int x, int y)
{
return _walls.get(MapRegionManager.getInstance().getMapRegionLocId(x, y));
}
public static WallData getInstance()
{
return SingletonHolder._instance;
}
private static class SingletonHolder
{
protected static final WallData _instance = new WallData();
}
}