actual freya branch
This commit is contained in:
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
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 com.l2jserver.Config;
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.model.L2AccessLevel;
|
||||
|
||||
/**
|
||||
* @author FBIagent<br>
|
||||
*/
|
||||
public class AccessLevels
|
||||
{
|
||||
/** The logger<br> */
|
||||
private static Logger _log = Logger.getLogger(AccessLevels.class.getName());
|
||||
/** Reserved master access level<br> */
|
||||
public static final int _masterAccessLevelNum = Config.MASTERACCESS_LEVEL;
|
||||
/** The master access level which can use everything<br> */
|
||||
public static L2AccessLevel _masterAccessLevel = new L2AccessLevel(_masterAccessLevelNum, "Master Access", Config.MASTERACCESS_NAME_COLOR, Config.MASTERACCESS_TITLE_COLOR, null, true, true, true, true, true, true, true, true);
|
||||
/** Reserved user access level<br> */
|
||||
public static final int _userAccessLevelNum = 0;
|
||||
/** The user access level which can do no administrative tasks<br> */
|
||||
public static L2AccessLevel _userAccessLevel = new L2AccessLevel(_userAccessLevelNum, "User", -1, -1, null, false, false, false, true, false, true, true, true);
|
||||
/** FastMap of access levels defined in database<br> */
|
||||
private TIntObjectHashMap<L2AccessLevel> _accessLevels;
|
||||
|
||||
/**
|
||||
* Returns the one and only instance of this class<br>
|
||||
* <br>
|
||||
* @return AccessLevels: the one and only instance of this class<br>
|
||||
*/
|
||||
public static AccessLevels getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private AccessLevels()
|
||||
{
|
||||
loadAccessLevels();
|
||||
_accessLevels.put(_userAccessLevelNum, _userAccessLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the access levels from database<br>
|
||||
*/
|
||||
private void loadAccessLevels()
|
||||
{
|
||||
_accessLevels = new TIntObjectHashMap<>();
|
||||
|
||||
Connection con = null;
|
||||
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
|
||||
PreparedStatement stmt = con.prepareStatement("SELECT * FROM `access_levels` ORDER BY `accessLevel` DESC");
|
||||
ResultSet rset = stmt.executeQuery();
|
||||
int accessLevel = 0;
|
||||
String name = null;
|
||||
int nameColor = 0;
|
||||
int titleColor = 0;
|
||||
String childs = null;
|
||||
boolean isGm = false;
|
||||
boolean allowPeaceAttack = false;
|
||||
boolean allowFixedRes = false;
|
||||
boolean allowTransaction = false;
|
||||
boolean allowAltG = false;
|
||||
boolean giveDamage = false;
|
||||
boolean takeAggro = false;
|
||||
boolean gainExp = false;
|
||||
|
||||
while (rset.next())
|
||||
{
|
||||
accessLevel = rset.getInt("accessLevel");
|
||||
name = rset.getString("name");
|
||||
|
||||
if (accessLevel == _userAccessLevelNum)
|
||||
{
|
||||
_log.warning("AccessLevels: Access level with name " + name + " is using reserved user access level " + _userAccessLevelNum + ". Ignoring it!");
|
||||
continue;
|
||||
}
|
||||
else if (accessLevel == _masterAccessLevelNum)
|
||||
{
|
||||
_log.warning("AccessLevels: Access level with name " + name + " is using reserved master access level " + _masterAccessLevelNum + ". Ignoring it!");
|
||||
continue;
|
||||
}
|
||||
else if (accessLevel < 0)
|
||||
{
|
||||
_log.warning("AccessLevels: Access level with name " + name + " is using banned access level state(below 0). Ignoring it!");
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
nameColor = Integer.decode("0x" + rset.getString("nameColor"));
|
||||
}
|
||||
catch (NumberFormatException nfe)
|
||||
{
|
||||
try
|
||||
{
|
||||
nameColor = Integer.decode("0xFFFFFF");
|
||||
}
|
||||
catch (NumberFormatException nfe2)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
titleColor = Integer.decode("0x" + rset.getString("titleColor"));
|
||||
|
||||
}
|
||||
catch (NumberFormatException nfe)
|
||||
{
|
||||
try
|
||||
{
|
||||
titleColor = Integer.decode("0xFFFF77");
|
||||
}
|
||||
catch (NumberFormatException nfe2)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
childs = rset.getString("childAccess");
|
||||
isGm = rset.getBoolean("isGm");
|
||||
allowPeaceAttack = rset.getBoolean("allowPeaceAttack");
|
||||
allowFixedRes = rset.getBoolean("allowFixedRes");
|
||||
allowTransaction = rset.getBoolean("allowTransaction");
|
||||
allowAltG = rset.getBoolean("allowAltg");
|
||||
giveDamage = rset.getBoolean("giveDamage");
|
||||
takeAggro = rset.getBoolean("takeAggro");
|
||||
gainExp = rset.getBoolean("gainExp");
|
||||
|
||||
_accessLevels.put(accessLevel, new L2AccessLevel(accessLevel, name, nameColor, titleColor, childs.isEmpty() ? null : childs, isGm, allowPeaceAttack, allowFixedRes, allowTransaction, allowAltG, giveDamage, takeAggro, gainExp));
|
||||
}
|
||||
|
||||
rset.close();
|
||||
stmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
_log.log(Level.WARNING, "AccessLevels: Error loading from database:" + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
_log.info("AccessLevels: Loaded " + _accessLevels.size() + " from database.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the access level by characterAccessLevel<br>
|
||||
* <br>
|
||||
* @param accessLevelNum as int<br>
|
||||
* <br>
|
||||
* @return AccessLevel: AccessLevel instance by char access level<br>
|
||||
*/
|
||||
public L2AccessLevel getAccessLevel(int accessLevelNum)
|
||||
{
|
||||
L2AccessLevel accessLevel = null;
|
||||
|
||||
synchronized (_accessLevels)
|
||||
{
|
||||
accessLevel = _accessLevels.get(accessLevelNum);
|
||||
}
|
||||
return accessLevel;
|
||||
}
|
||||
|
||||
public void addBanAccessLevel(int accessLevel)
|
||||
{
|
||||
synchronized (_accessLevels)
|
||||
{
|
||||
if (accessLevel > -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_accessLevels.put(accessLevel, new L2AccessLevel(accessLevel, "Banned", -1, -1, null, false, false, false, false, false, false, false, false));
|
||||
}
|
||||
}
|
||||
|
||||
public void reloadAccessLevels()
|
||||
{
|
||||
loadAccessLevels();
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final AccessLevels _instance = new AccessLevels();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.model.L2AccessLevel;
|
||||
import com.l2jserver.gameserver.model.L2AdminCommandAccessRight;
|
||||
|
||||
/**
|
||||
* @author FBIagent<br>
|
||||
*/
|
||||
public class AdminCommandAccessRights
|
||||
{
|
||||
/** The logger<br> */
|
||||
private static Logger _log = Logger.getLogger(AdminCommandAccessRights.class.getName());
|
||||
|
||||
private Map<String, L2AdminCommandAccessRight> _adminCommandAccessRights;
|
||||
|
||||
/**
|
||||
* Returns the one and only instance of this class<br>
|
||||
* <br>
|
||||
* @return AdminCommandAccessRights: the one and only instance of this class<br>
|
||||
*/
|
||||
public static AdminCommandAccessRights getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
/** The access rights<br> */
|
||||
private AdminCommandAccessRights()
|
||||
{
|
||||
loadAdminCommandAccessRights();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads admin command access rights from database<br>
|
||||
*/
|
||||
private void loadAdminCommandAccessRights()
|
||||
{
|
||||
_adminCommandAccessRights = new FastMap<>();
|
||||
|
||||
Connection con = null;
|
||||
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
|
||||
PreparedStatement stmt = con.prepareStatement("SELECT * FROM admin_command_access_rights");
|
||||
ResultSet rset = stmt.executeQuery();
|
||||
String adminCommand = null;
|
||||
String accessLevels = null;
|
||||
boolean confirm = false;
|
||||
|
||||
while (rset.next())
|
||||
{
|
||||
adminCommand = rset.getString("adminCommand");
|
||||
accessLevels = rset.getString("accessLevels");
|
||||
confirm = rset.getBoolean("confirmDlg");
|
||||
_adminCommandAccessRights.put(adminCommand, new L2AdminCommandAccessRight(adminCommand, accessLevels, confirm));
|
||||
}
|
||||
rset.close();
|
||||
stmt.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
_log.log(Level.WARNING, "AdminCommandAccessRights: Error loading from database:" + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
|
||||
_log.info("AdminCommandAccessRights: Loaded " + _adminCommandAccessRights.size() + " from database.");
|
||||
}
|
||||
|
||||
public boolean hasAccess(String adminCommand, L2AccessLevel accessLevel)
|
||||
{
|
||||
if (accessLevel.getLevel() == AccessLevels._masterAccessLevelNum)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
L2AdminCommandAccessRight acar = _adminCommandAccessRights.get(adminCommand);
|
||||
|
||||
if (acar == null)
|
||||
{
|
||||
_log.info("AdminCommandAccessRights: No rights defined for admin command " + adminCommand + ".");
|
||||
return false;
|
||||
}
|
||||
|
||||
return acar.hasAccess(accessLevel);
|
||||
}
|
||||
|
||||
public boolean requireConfirm(String command)
|
||||
{
|
||||
L2AdminCommandAccessRight acar = _adminCommandAccessRights.get(command);
|
||||
if (acar == null)
|
||||
{
|
||||
_log.info("AdminCommandAccessRights: No rights defined for admin command " + command + ".");
|
||||
return false;
|
||||
}
|
||||
return _adminCommandAccessRights.get(command).getRequireConfirm();
|
||||
}
|
||||
|
||||
public void reloadAdminCommandAccessRights()
|
||||
{
|
||||
loadAdminCommandAccessRights();
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final AdminCommandAccessRights _instance = new AdminCommandAccessRights();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author godson
|
||||
*/
|
||||
|
||||
package com.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.model.L2ArmorSet;
|
||||
|
||||
/**
|
||||
* @author Luno
|
||||
*/
|
||||
public class ArmorSetsTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(ArmorSetsTable.class.getName());
|
||||
|
||||
private final TIntObjectHashMap<L2ArmorSet> _armorSets;
|
||||
|
||||
public static ArmorSetsTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private ArmorSetsTable()
|
||||
{
|
||||
_armorSets = new TIntObjectHashMap<>();
|
||||
loadData();
|
||||
}
|
||||
|
||||
private void loadData()
|
||||
{
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT chest, legs, head, gloves, feet, skill, shield, shield_skill_id, enchant6skill, mw_legs, mw_head, mw_gloves, mw_feet, mw_shield FROM armorsets");
|
||||
ResultSet rset = statement.executeQuery();
|
||||
|
||||
while (rset.next())
|
||||
{
|
||||
int chest = rset.getInt("chest");
|
||||
int legs = rset.getInt("legs");
|
||||
int head = rset.getInt("head");
|
||||
int gloves = rset.getInt("gloves");
|
||||
int feet = rset.getInt("feet");
|
||||
String[] skills = rset.getString("skill").split(";");
|
||||
int shield = rset.getInt("shield");
|
||||
int shield_skill_id = rset.getInt("shield_skill_id");
|
||||
int enchant6skill = rset.getInt("enchant6skill");
|
||||
int mw_legs = rset.getInt("mw_legs");
|
||||
int mw_head = rset.getInt("mw_head");
|
||||
int mw_gloves = rset.getInt("mw_gloves");
|
||||
int mw_feet = rset.getInt("mw_feet");
|
||||
int mw_shield = rset.getInt("mw_shield");
|
||||
_armorSets.put(chest, new L2ArmorSet(chest, legs, head, gloves, feet, skills, shield, shield_skill_id, enchant6skill, mw_legs, mw_head, mw_gloves, mw_feet, mw_shield));
|
||||
}
|
||||
|
||||
rset.close();
|
||||
statement.close();
|
||||
_log.info("ArmorSetsTable: Loaded " + _armorSets.size() + " armor sets.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "ArmorSetsTable: Error reading ArmorSets table: " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
|
||||
if (Config.CUSTOM_ARMORSETS_TABLE)
|
||||
{
|
||||
try
|
||||
{
|
||||
int cSets = _armorSets.size();
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT chest, legs, head, gloves, feet, skill, shield, shield_skill_id, enchant6skill, mw_legs, mw_head, mw_gloves, mw_feet, mw_shield FROM custom_armorsets");
|
||||
ResultSet rset = statement.executeQuery();
|
||||
while (rset.next())
|
||||
{
|
||||
int chest = rset.getInt("chest");
|
||||
int legs = rset.getInt("legs");
|
||||
int head = rset.getInt("head");
|
||||
int gloves = rset.getInt("gloves");
|
||||
int feet = rset.getInt("feet");
|
||||
String[] skills = rset.getString("skill").split(";");
|
||||
int shield = rset.getInt("shield");
|
||||
int shield_skill_id = rset.getInt("shield_skill_id");
|
||||
int enchant6skill = rset.getInt("enchant6skill");
|
||||
int mw_legs = rset.getInt("mw_legs");
|
||||
int mw_head = rset.getInt("mw_head");
|
||||
int mw_gloves = rset.getInt("mw_gloves");
|
||||
int mw_feet = rset.getInt("mw_feet");
|
||||
int mw_shield = rset.getInt("mw_shield");
|
||||
_armorSets.put(chest, new L2ArmorSet(chest, legs, head, gloves, feet, skills, shield, shield_skill_id, enchant6skill, mw_legs, mw_head, mw_gloves, mw_feet, mw_shield));
|
||||
}
|
||||
|
||||
rset.close();
|
||||
statement.close();
|
||||
_log.info("ArmorSetsTable: Loaded " + (_armorSets.size() - cSets) + " Custom armor sets.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "ArmorSetsTable: Error reading Custom ArmorSets table: " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean setExists(int chestId)
|
||||
{
|
||||
return _armorSets.containsKey(chestId);
|
||||
}
|
||||
|
||||
public L2ArmorSet getSet(int chestId)
|
||||
{
|
||||
return _armorSets.get(chestId);
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final ArmorSetsTable _instance = new ArmorSetsTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,969 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.model.L2Augmentation;
|
||||
import com.l2jserver.gameserver.model.L2Skill;
|
||||
import com.l2jserver.gameserver.network.clientpackets.AbstractRefinePacket;
|
||||
import com.l2jserver.gameserver.skills.Stats;
|
||||
import com.l2jserver.gameserver.templates.item.L2Item;
|
||||
import com.l2jserver.util.Rnd;
|
||||
|
||||
/**
|
||||
* This class manages the augmentation data and can also create new augmentations.
|
||||
* @author durgus edited by Gigiikun
|
||||
*/
|
||||
public class AugmentationData
|
||||
{
|
||||
private static final Logger _log = Logger.getLogger(AugmentationData.class.getName());
|
||||
|
||||
public static final AugmentationData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Data Field
|
||||
|
||||
// stats
|
||||
private static final int STAT_START = 1;
|
||||
private static final int STAT_END = 14560;
|
||||
private static final int STAT_BLOCKSIZE = 3640;
|
||||
// private static final int STAT_NUMBEROF_BLOCKS = 4;
|
||||
private static final int STAT_SUBBLOCKSIZE = 91;
|
||||
// private static final int STAT_NUMBEROF_SUBBLOCKS = 40;
|
||||
private static final int STAT_NUM = 13;
|
||||
|
||||
private static final byte[] STATS1_MAP = new byte[STAT_SUBBLOCKSIZE];
|
||||
private static final byte[] STATS2_MAP = new byte[STAT_SUBBLOCKSIZE];
|
||||
|
||||
// skills
|
||||
private static final int BLUE_START = 14561;
|
||||
// private static final int PURPLE_START = 14578;
|
||||
// private static final int RED_START = 14685;
|
||||
private static final int SKILLS_BLOCKSIZE = 178;
|
||||
|
||||
// basestats
|
||||
private static final int BASESTAT_STR = 16341;
|
||||
private static final int BASESTAT_CON = 16342;
|
||||
private static final int BASESTAT_INT = 16343;
|
||||
private static final int BASESTAT_MEN = 16344;
|
||||
|
||||
// accessory
|
||||
private static final int ACC_START = 16669;
|
||||
private static final int ACC_BLOCKS_NUM = 10;
|
||||
private static final int ACC_STAT_SUBBLOCKSIZE = 21;
|
||||
private static final int ACC_STAT_NUM = 6;
|
||||
|
||||
private static final int ACC_RING_START = ACC_START;
|
||||
private static final int ACC_RING_SKILLS = 18;
|
||||
private static final int ACC_RING_BLOCKSIZE = ACC_RING_SKILLS + (4 * ACC_STAT_SUBBLOCKSIZE);
|
||||
private static final int ACC_RING_END = (ACC_RING_START + (ACC_BLOCKS_NUM * ACC_RING_BLOCKSIZE)) - 1;
|
||||
|
||||
private static final int ACC_EAR_START = ACC_RING_END + 1;
|
||||
private static final int ACC_EAR_SKILLS = 18;
|
||||
private static final int ACC_EAR_BLOCKSIZE = ACC_EAR_SKILLS + (4 * ACC_STAT_SUBBLOCKSIZE);
|
||||
private static final int ACC_EAR_END = (ACC_EAR_START + (ACC_BLOCKS_NUM * ACC_EAR_BLOCKSIZE)) - 1;
|
||||
|
||||
private static final int ACC_NECK_START = ACC_EAR_END + 1;
|
||||
private static final int ACC_NECK_SKILLS = 24;
|
||||
private static final int ACC_NECK_BLOCKSIZE = ACC_NECK_SKILLS + (4 * ACC_STAT_SUBBLOCKSIZE);
|
||||
|
||||
private static final int ACC_END = ACC_NECK_START + (ACC_BLOCKS_NUM * ACC_NECK_BLOCKSIZE);
|
||||
|
||||
private static final byte[] ACC_STATS1_MAP = new byte[ACC_STAT_SUBBLOCKSIZE];
|
||||
private static final byte[] ACC_STATS2_MAP = new byte[ACC_STAT_SUBBLOCKSIZE];
|
||||
|
||||
private final ArrayList<?>[] _augStats = new ArrayList[4];
|
||||
private final ArrayList<?>[] _augAccStats = new ArrayList[4];
|
||||
|
||||
private final ArrayList<?>[] _blueSkills = new ArrayList[10];
|
||||
private final ArrayList<?>[] _purpleSkills = new ArrayList[10];
|
||||
private final ArrayList<?>[] _redSkills = new ArrayList[10];
|
||||
private final ArrayList<?>[] _yellowSkills = new ArrayList[10];
|
||||
|
||||
private final TIntObjectHashMap<AugmentationSkill> _allSkills = new TIntObjectHashMap<>();
|
||||
|
||||
// =========================================================
|
||||
// Constructor
|
||||
private AugmentationData()
|
||||
{
|
||||
_log.info("Initializing AugmentationData.");
|
||||
|
||||
_augStats[0] = new ArrayList<AugmentationStat>();
|
||||
_augStats[1] = new ArrayList<AugmentationStat>();
|
||||
_augStats[2] = new ArrayList<AugmentationStat>();
|
||||
_augStats[3] = new ArrayList<AugmentationStat>();
|
||||
|
||||
_augAccStats[0] = new ArrayList<AugmentationStat>();
|
||||
_augAccStats[1] = new ArrayList<AugmentationStat>();
|
||||
_augAccStats[2] = new ArrayList<AugmentationStat>();
|
||||
_augAccStats[3] = new ArrayList<AugmentationStat>();
|
||||
|
||||
// Lookup tables structure: STAT1 represent first stat, STAT2 - second.
|
||||
// If both values are the same - use solo stat, if different - combined.
|
||||
byte idx;
|
||||
// weapon augmentation block: solo values first
|
||||
// 00-00, 01-01 ... 11-11,12-12
|
||||
for (idx = 0; idx < STAT_NUM; idx++)
|
||||
{
|
||||
// solo stats
|
||||
STATS1_MAP[idx] = idx;
|
||||
STATS2_MAP[idx] = idx;
|
||||
}
|
||||
// combined values next.
|
||||
// 00-01,00-02,00-03 ... 00-11,00-12;
|
||||
// 01-02,01-03 ... 01-11,01-12;
|
||||
// ...
|
||||
// 09-10,09-11,09-12;
|
||||
// 10-11,10-12;
|
||||
// 11-12
|
||||
for (int i = 0; i < STAT_NUM; i++)
|
||||
{
|
||||
for (int j = i + 1; j < STAT_NUM; idx++, j++)
|
||||
{
|
||||
// combined stats
|
||||
STATS1_MAP[idx] = (byte) i;
|
||||
STATS2_MAP[idx] = (byte) j;
|
||||
}
|
||||
}
|
||||
idx = 0;
|
||||
// accessory augmentation block, structure is different:
|
||||
// 00-00,00-01,00-02,00-03,00-04,00-05
|
||||
// 01-01,01-02,01-03,01-04,01-05
|
||||
// 02-02,02-03,02-04,02-05
|
||||
// 03-03,03-04,03-05
|
||||
// 04-04 \
|
||||
// 05-05 - order is changed here
|
||||
// 04-05 /
|
||||
// First values always solo, next are combined, except last 3 values
|
||||
for (int i = 0; i < (ACC_STAT_NUM - 2); i++)
|
||||
{
|
||||
for (int j = i; j < ACC_STAT_NUM; idx++, j++)
|
||||
{
|
||||
ACC_STATS1_MAP[idx] = (byte) i;
|
||||
ACC_STATS2_MAP[idx] = (byte) j;
|
||||
}
|
||||
}
|
||||
ACC_STATS1_MAP[idx] = 4;
|
||||
ACC_STATS2_MAP[idx++] = 4;
|
||||
ACC_STATS1_MAP[idx] = 5;
|
||||
ACC_STATS2_MAP[idx++] = 5;
|
||||
ACC_STATS1_MAP[idx] = 4;
|
||||
ACC_STATS2_MAP[idx] = 5;
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
_blueSkills[i] = new ArrayList<Integer>();
|
||||
_purpleSkills[i] = new ArrayList<Integer>();
|
||||
_redSkills[i] = new ArrayList<Integer>();
|
||||
_yellowSkills[i] = new ArrayList<Integer>();
|
||||
}
|
||||
|
||||
load();
|
||||
|
||||
// Use size*4: since theres 4 blocks of stat-data with equivalent size
|
||||
_log.info("AugmentationData: Loaded: " + (_augStats[0].size() * 4) + " augmentation stats.");
|
||||
_log.info("AugmentationData: Loaded: " + (_augAccStats[0].size() * 4) + " accessory augmentation stats.");
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
_log.info("AugmentationData: Loaded: " + _blueSkills[i].size() + " blue, " + _purpleSkills[i].size() + " purple and " + _redSkills[i].size() + " red skills for lifeStoneLevel " + i);
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Nested Class
|
||||
|
||||
public static class AugmentationSkill
|
||||
{
|
||||
private final int _skillId;
|
||||
private final int _skillLevel;
|
||||
|
||||
public AugmentationSkill(int skillId, int skillLevel)
|
||||
{
|
||||
_skillId = skillId;
|
||||
_skillLevel = skillLevel;
|
||||
}
|
||||
|
||||
public L2Skill getSkill()
|
||||
{
|
||||
return SkillTable.getInstance().getInfo(_skillId, _skillLevel);
|
||||
}
|
||||
}
|
||||
|
||||
public static class AugmentationStat
|
||||
{
|
||||
private final Stats _stat;
|
||||
private final int _singleSize;
|
||||
private final int _combinedSize;
|
||||
private final float _singleValues[];
|
||||
private final float _combinedValues[];
|
||||
|
||||
public AugmentationStat(Stats stat, float sValues[], float cValues[])
|
||||
{
|
||||
_stat = stat;
|
||||
_singleSize = sValues.length;
|
||||
_singleValues = sValues;
|
||||
_combinedSize = cValues.length;
|
||||
_combinedValues = cValues;
|
||||
}
|
||||
|
||||
public int getSingleStatSize()
|
||||
{
|
||||
return _singleSize;
|
||||
}
|
||||
|
||||
public int getCombinedStatSize()
|
||||
{
|
||||
return _combinedSize;
|
||||
}
|
||||
|
||||
public float getSingleStatValue(int i)
|
||||
{
|
||||
if ((i >= _singleSize) || (i < 0))
|
||||
{
|
||||
return _singleValues[_singleSize - 1];
|
||||
}
|
||||
return _singleValues[i];
|
||||
}
|
||||
|
||||
public float getCombinedStatValue(int i)
|
||||
{
|
||||
if ((i >= _combinedSize) || (i < 0))
|
||||
{
|
||||
return _combinedValues[_combinedSize - 1];
|
||||
}
|
||||
return _combinedValues[i];
|
||||
}
|
||||
|
||||
public Stats getStat()
|
||||
{
|
||||
return _stat;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private final void load()
|
||||
{
|
||||
// Load the skillmap
|
||||
// Note: the skillmap data is only used when generating new augmentations
|
||||
// the client expects a different id in order to display the skill in the
|
||||
// items description...
|
||||
try
|
||||
{
|
||||
int badAugmantData = 0;
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setIgnoringComments(true);
|
||||
|
||||
File file = new File(Config.DATAPACK_ROOT + "/data/stats/augmentation/augmentation_skillmap.xml");
|
||||
if (!file.exists())
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("The augmentation skillmap file is missing.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Document doc = factory.newDocumentBuilder().parse(file);
|
||||
|
||||
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 ("augmentation".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
NamedNodeMap attrs = d.getAttributes();
|
||||
int skillId = 0, augmentationId = Integer.parseInt(attrs.getNamedItem("id").getNodeValue());
|
||||
int skillLvL = 0;
|
||||
String type = "blue";
|
||||
|
||||
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
|
||||
{
|
||||
if ("skillId".equalsIgnoreCase(cd.getNodeName()))
|
||||
{
|
||||
attrs = cd.getAttributes();
|
||||
skillId = Integer.parseInt(attrs.getNamedItem("val").getNodeValue());
|
||||
}
|
||||
else if ("skillLevel".equalsIgnoreCase(cd.getNodeName()))
|
||||
{
|
||||
attrs = cd.getAttributes();
|
||||
skillLvL = Integer.parseInt(attrs.getNamedItem("val").getNodeValue());
|
||||
}
|
||||
else if ("type".equalsIgnoreCase(cd.getNodeName()))
|
||||
{
|
||||
attrs = cd.getAttributes();
|
||||
type = attrs.getNamedItem("val").getNodeValue();
|
||||
}
|
||||
}
|
||||
if (skillId == 0)
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Bad skillId in augmentation_skillmap.xml in the augmentationId:" + augmentationId);
|
||||
}
|
||||
badAugmantData++;
|
||||
continue;
|
||||
}
|
||||
else if (skillLvL == 0)
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Bad skillLevel in augmentation_skillmap.xml in the augmentationId:" + augmentationId);
|
||||
}
|
||||
badAugmantData++;
|
||||
continue;
|
||||
}
|
||||
int k = (augmentationId - BLUE_START) / SKILLS_BLOCKSIZE;
|
||||
|
||||
if (type.equalsIgnoreCase("blue"))
|
||||
{
|
||||
((ArrayList<Integer>) _blueSkills[k]).add(augmentationId);
|
||||
}
|
||||
else if (type.equalsIgnoreCase("purple"))
|
||||
{
|
||||
((ArrayList<Integer>) _purpleSkills[k]).add(augmentationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
((ArrayList<Integer>) _redSkills[k]).add(augmentationId);
|
||||
}
|
||||
|
||||
_allSkills.put(augmentationId, new AugmentationSkill(skillId, skillLvL));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (badAugmantData != 0)
|
||||
{
|
||||
_log.info("AugmentationData: " + badAugmantData + " bad skill(s) were skipped.");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error parsing augmentation_skillmap.xml.", e);
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the stats from xml
|
||||
for (int i = 1; i < 5; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setIgnoringComments(true);
|
||||
|
||||
File file = new File(Config.DATAPACK_ROOT + "/data/stats/augmentation/augmentation_stats" + i + ".xml");
|
||||
if (!file.exists())
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("The augmentation stat data file " + i + " is missing.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Document doc = factory.newDocumentBuilder().parse(file);
|
||||
|
||||
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 ("stat".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
NamedNodeMap attrs = d.getAttributes();
|
||||
String statName = attrs.getNamedItem("name").getNodeValue();
|
||||
float soloValues[] = null, combinedValues[] = null;
|
||||
|
||||
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
|
||||
{
|
||||
if ("table".equalsIgnoreCase(cd.getNodeName()))
|
||||
{
|
||||
attrs = cd.getAttributes();
|
||||
String tableName = attrs.getNamedItem("name").getNodeValue();
|
||||
|
||||
StringTokenizer data = new StringTokenizer(cd.getFirstChild().getNodeValue());
|
||||
FastList<Float> array = new FastList<>();
|
||||
while (data.hasMoreTokens())
|
||||
{
|
||||
array.add(Float.parseFloat(data.nextToken()));
|
||||
}
|
||||
|
||||
if (tableName.equalsIgnoreCase("#soloValues"))
|
||||
{
|
||||
soloValues = new float[array.size()];
|
||||
int x = 0;
|
||||
for (float value : array)
|
||||
{
|
||||
soloValues[x++] = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
combinedValues = new float[array.size()];
|
||||
int x = 0;
|
||||
for (float value : array)
|
||||
{
|
||||
combinedValues[x++] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// store this stat
|
||||
((ArrayList<AugmentationStat>) _augStats[(i - 1)]).add(new AugmentationStat(Stats.valueOfXml(statName), soloValues, combinedValues));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error parsing augmentation_stats" + i + ".xml.", e);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setIgnoringComments(true);
|
||||
|
||||
File file = new File(Config.DATAPACK_ROOT + "/data/stats/augmentation/augmentation_jewel_stats" + i + ".xml");
|
||||
|
||||
if (!file.exists())
|
||||
{
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("The jewel augmentation stat data file " + i + " is missing.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Document doc = factory.newDocumentBuilder().parse(file);
|
||||
|
||||
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 ("stat".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
NamedNodeMap attrs = d.getAttributes();
|
||||
String statName = attrs.getNamedItem("name").getNodeValue();
|
||||
float soloValues[] = null, combinedValues[] = null;
|
||||
|
||||
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
|
||||
{
|
||||
if ("table".equalsIgnoreCase(cd.getNodeName()))
|
||||
{
|
||||
attrs = cd.getAttributes();
|
||||
String tableName = attrs.getNamedItem("name").getNodeValue();
|
||||
|
||||
StringTokenizer data = new StringTokenizer(cd.getFirstChild().getNodeValue());
|
||||
FastList<Float> array = new FastList<>();
|
||||
while (data.hasMoreTokens())
|
||||
{
|
||||
array.add(Float.parseFloat(data.nextToken()));
|
||||
}
|
||||
|
||||
if (tableName.equalsIgnoreCase("#soloValues"))
|
||||
{
|
||||
soloValues = new float[array.size()];
|
||||
int x = 0;
|
||||
for (float value : array)
|
||||
{
|
||||
soloValues[x++] = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
combinedValues = new float[array.size()];
|
||||
int x = 0;
|
||||
for (float value : array)
|
||||
{
|
||||
combinedValues[x++] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// store this stat
|
||||
((ArrayList<AugmentationStat>) _augAccStats[(i - 1)]).add(new AugmentationStat(Stats.valueOfXml(statName), soloValues, combinedValues));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error parsing jewel augmentation_stats" + i + ".xml.", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new random augmentation
|
||||
* @param item
|
||||
* @param lifeStoneLevel
|
||||
* @param lifeSoneGrade
|
||||
* @param bodyPart
|
||||
* @return L2Augmentation
|
||||
*/
|
||||
public L2Augmentation generateRandomAugmentation(int lifeStoneLevel, int lifeStoneGrade, int bodyPart)
|
||||
{
|
||||
switch (bodyPart)
|
||||
{
|
||||
case L2Item.SLOT_LR_FINGER:
|
||||
case L2Item.SLOT_LR_EAR:
|
||||
case L2Item.SLOT_NECK:
|
||||
return generateRandomAccessoryAugmentation(lifeStoneLevel, bodyPart);
|
||||
default:
|
||||
return generateRandomWeaponAugmentation(lifeStoneLevel, lifeStoneGrade);
|
||||
}
|
||||
}
|
||||
|
||||
private L2Augmentation generateRandomWeaponAugmentation(int lifeStoneLevel, int lifeStoneGrade)
|
||||
{
|
||||
// Note that stat12 stands for stat 1 AND 2 (same for stat34 ;p )
|
||||
// this is because a value can contain up to 2 stat modifications
|
||||
// (there are two short values packed in one integer value, meaning 4 stat modifications at max)
|
||||
// for more info take a look at getAugStatsById(...)
|
||||
|
||||
// Note: lifeStoneGrade: (0 means low grade, 3 top grade)
|
||||
// First: determine whether we will add a skill/baseStatModifier or not
|
||||
// because this determine which color could be the result
|
||||
int stat12 = 0;
|
||||
int stat34 = 0;
|
||||
boolean generateSkill = false;
|
||||
boolean generateGlow = false;
|
||||
|
||||
// lifestonelevel is used for stat Id and skill level, but here the max level is 9
|
||||
lifeStoneLevel = Math.min(lifeStoneLevel, 9);
|
||||
|
||||
switch (lifeStoneGrade)
|
||||
{
|
||||
case AbstractRefinePacket.GRADE_NONE:
|
||||
if (Rnd.get(1, 100) <= Config.AUGMENTATION_NG_SKILL_CHANCE)
|
||||
{
|
||||
generateSkill = true;
|
||||
}
|
||||
if (Rnd.get(1, 100) <= Config.AUGMENTATION_NG_GLOW_CHANCE)
|
||||
{
|
||||
generateGlow = true;
|
||||
}
|
||||
break;
|
||||
case AbstractRefinePacket.GRADE_MID:
|
||||
if (Rnd.get(1, 100) <= Config.AUGMENTATION_MID_SKILL_CHANCE)
|
||||
{
|
||||
generateSkill = true;
|
||||
}
|
||||
if (Rnd.get(1, 100) <= Config.AUGMENTATION_MID_GLOW_CHANCE)
|
||||
{
|
||||
generateGlow = true;
|
||||
}
|
||||
break;
|
||||
case AbstractRefinePacket.GRADE_HIGH:
|
||||
if (Rnd.get(1, 100) <= Config.AUGMENTATION_HIGH_SKILL_CHANCE)
|
||||
{
|
||||
generateSkill = true;
|
||||
}
|
||||
if (Rnd.get(1, 100) <= Config.AUGMENTATION_HIGH_GLOW_CHANCE)
|
||||
{
|
||||
generateGlow = true;
|
||||
}
|
||||
break;
|
||||
case AbstractRefinePacket.GRADE_TOP:
|
||||
if (Rnd.get(1, 100) <= Config.AUGMENTATION_TOP_SKILL_CHANCE)
|
||||
{
|
||||
generateSkill = true;
|
||||
}
|
||||
if (Rnd.get(1, 100) <= Config.AUGMENTATION_TOP_GLOW_CHANCE)
|
||||
{
|
||||
generateGlow = true;
|
||||
}
|
||||
break;
|
||||
case AbstractRefinePacket.GRADE_ACC:
|
||||
if (Rnd.get(1, 100) <= Config.AUGMENTATION_ACC_SKILL_CHANCE)
|
||||
{
|
||||
generateSkill = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!generateSkill && (Rnd.get(1, 100) <= Config.AUGMENTATION_BASESTAT_CHANCE))
|
||||
{
|
||||
stat34 = Rnd.get(BASESTAT_STR, BASESTAT_MEN);
|
||||
}
|
||||
|
||||
// Second: decide which grade the augmentation result is going to have:
|
||||
// 0:yellow, 1:blue, 2:purple, 3:red
|
||||
// The chances used here are most likely custom,
|
||||
// whats known is: you cant have yellow with skill(or baseStatModifier)
|
||||
// noGrade stone can not have glow, mid only with skill, high has a chance(custom), top allways glow
|
||||
int resultColor = Rnd.get(0, 100);
|
||||
if ((stat34 == 0) && !generateSkill)
|
||||
{
|
||||
if (resultColor <= ((15 * lifeStoneGrade) + 40))
|
||||
{
|
||||
resultColor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultColor = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((resultColor <= ((10 * lifeStoneGrade) + 5)) || (stat34 != 0))
|
||||
{
|
||||
resultColor = 3;
|
||||
}
|
||||
else if (resultColor <= ((10 * lifeStoneGrade) + 10))
|
||||
{
|
||||
resultColor = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
resultColor = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// generate a skill if neccessary
|
||||
L2Skill skill = null;
|
||||
if (generateSkill)
|
||||
{
|
||||
switch (resultColor)
|
||||
{
|
||||
case 1: // blue skill
|
||||
stat34 = ((Integer) _blueSkills[lifeStoneLevel].get(Rnd.get(0, _blueSkills[lifeStoneLevel].size() - 1)));
|
||||
break;
|
||||
case 2: // purple skill
|
||||
stat34 = ((Integer) _purpleSkills[lifeStoneLevel].get(Rnd.get(0, _purpleSkills[lifeStoneLevel].size() - 1)));
|
||||
break;
|
||||
case 3: // red skill
|
||||
stat34 = ((Integer) _redSkills[lifeStoneLevel].get(Rnd.get(0, _redSkills[lifeStoneLevel].size() - 1)));
|
||||
break;
|
||||
}
|
||||
skill = _allSkills.get(stat34).getSkill();
|
||||
}
|
||||
|
||||
// Third: Calculate the subblock offset for the choosen color,
|
||||
// and the level of the lifeStone
|
||||
// from large number of retail augmentations:
|
||||
// no skill part
|
||||
// Id for stat12:
|
||||
// A:1-910 B:911-1820 C:1821-2730 D:2731-3640 E:3641-4550 F:4551-5460 G:5461-6370 H:6371-7280
|
||||
// Id for stat34(this defines the color):
|
||||
// I:7281-8190(yellow) K:8191-9100(blue) L:10921-11830(yellow) M:11831-12740(blue)
|
||||
// you can combine I-K with A-D and L-M with E-H
|
||||
// using C-D or G-H Id you will get a glow effect
|
||||
// there seems no correlation in which grade use which Id except for the glowing restriction
|
||||
// skill part
|
||||
// Id for stat12:
|
||||
// same for no skill part
|
||||
// A same as E, B same as F, C same as G, D same as H
|
||||
// A - no glow, no grade LS
|
||||
// B - weak glow, mid grade LS?
|
||||
// C - glow, high grade LS?
|
||||
// D - strong glow, top grade LS?
|
||||
|
||||
// is neither a skill nor basestat used for stat34? then generate a normal stat
|
||||
int offset;
|
||||
if (stat34 == 0)
|
||||
{
|
||||
int temp = Rnd.get(2, 3);
|
||||
int colorOffset = (resultColor * (10 * STAT_SUBBLOCKSIZE)) + (temp * STAT_BLOCKSIZE) + 1;
|
||||
offset = (lifeStoneLevel * STAT_SUBBLOCKSIZE) + colorOffset;
|
||||
|
||||
stat34 = Rnd.get(offset, (offset + STAT_SUBBLOCKSIZE) - 1);
|
||||
if (generateGlow && (lifeStoneGrade >= 2))
|
||||
{
|
||||
offset = (lifeStoneLevel * STAT_SUBBLOCKSIZE) + ((temp - 2) * STAT_BLOCKSIZE) + (lifeStoneGrade * (10 * STAT_SUBBLOCKSIZE)) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = (lifeStoneLevel * STAT_SUBBLOCKSIZE) + ((temp - 2) * STAT_BLOCKSIZE) + (Rnd.get(0, 1) * (10 * STAT_SUBBLOCKSIZE)) + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!generateGlow)
|
||||
{
|
||||
offset = (lifeStoneLevel * STAT_SUBBLOCKSIZE) + (Rnd.get(0, 1) * STAT_BLOCKSIZE) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = (lifeStoneLevel * STAT_SUBBLOCKSIZE) + (Rnd.get(0, 1) * STAT_BLOCKSIZE) + (((lifeStoneGrade + resultColor) / 2) * (10 * STAT_SUBBLOCKSIZE)) + 1;
|
||||
}
|
||||
}
|
||||
stat12 = Rnd.get(offset, (offset + STAT_SUBBLOCKSIZE) - 1);
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Augmentation success: stat12=" + stat12 + "; stat34=" + stat34 + "; resultColor=" + resultColor + "; level=" + lifeStoneLevel + "; grade=" + lifeStoneGrade);
|
||||
}
|
||||
return new L2Augmentation(((stat34 << 16) + stat12), skill);
|
||||
}
|
||||
|
||||
private L2Augmentation generateRandomAccessoryAugmentation(int lifeStoneLevel, int bodyPart)
|
||||
{
|
||||
int stat12 = 0;
|
||||
int stat34 = 0;
|
||||
int base = 0;
|
||||
int skillsLength = 0;
|
||||
|
||||
lifeStoneLevel = Math.min(lifeStoneLevel, 9);
|
||||
|
||||
switch (bodyPart)
|
||||
{
|
||||
case L2Item.SLOT_LR_FINGER:
|
||||
base = ACC_RING_START + (ACC_RING_BLOCKSIZE * lifeStoneLevel);
|
||||
skillsLength = ACC_RING_SKILLS;
|
||||
break;
|
||||
case L2Item.SLOT_LR_EAR:
|
||||
base = ACC_EAR_START + (ACC_EAR_BLOCKSIZE * lifeStoneLevel);
|
||||
skillsLength = ACC_EAR_SKILLS;
|
||||
break;
|
||||
case L2Item.SLOT_NECK:
|
||||
base = ACC_NECK_START + (ACC_NECK_BLOCKSIZE * lifeStoneLevel);
|
||||
skillsLength = ACC_NECK_SKILLS;
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
int resultColor = Rnd.get(0, 3);
|
||||
L2Skill skill = null;
|
||||
|
||||
// first augmentation (stats only)
|
||||
stat12 = Rnd.get(ACC_STAT_SUBBLOCKSIZE);
|
||||
|
||||
if (Rnd.get(1, 100) <= Config.AUGMENTATION_ACC_SKILL_CHANCE)
|
||||
{
|
||||
// second augmentation (skill)
|
||||
stat34 = base + Rnd.get(skillsLength);
|
||||
if (_allSkills.contains(stat34))
|
||||
{
|
||||
skill = _allSkills.get(stat34).getSkill();
|
||||
}
|
||||
}
|
||||
|
||||
if (skill == null)
|
||||
{
|
||||
// second augmentation (stats)
|
||||
// calculating any different from stat12 value inside sub-block
|
||||
// starting from next and wrapping over using remainder
|
||||
stat34 = (stat12 + 1 + Rnd.get(ACC_STAT_SUBBLOCKSIZE - 1)) % ACC_STAT_SUBBLOCKSIZE;
|
||||
// this is a stats - skipping skills
|
||||
stat34 = base + skillsLength + (ACC_STAT_SUBBLOCKSIZE * resultColor) + stat34;
|
||||
}
|
||||
|
||||
// stat12 has stats only
|
||||
stat12 = base + skillsLength + (ACC_STAT_SUBBLOCKSIZE * resultColor) + stat12;
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("Accessory augmentation success: stat12=" + stat12 + "; stat34=" + stat34 + "; level=" + lifeStoneLevel);
|
||||
}
|
||||
return new L2Augmentation(((stat34 << 16) + stat12), skill);
|
||||
}
|
||||
|
||||
public static class AugStat
|
||||
{
|
||||
private final Stats _stat;
|
||||
private final float _value;
|
||||
|
||||
public AugStat(Stats stat, float value)
|
||||
{
|
||||
_stat = stat;
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public Stats getStat()
|
||||
{
|
||||
return _stat;
|
||||
}
|
||||
|
||||
public float getValue()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stat and basestat boni for a given augmentation id
|
||||
* @param augmentationId
|
||||
* @return
|
||||
*/
|
||||
public FastList<AugStat> getAugStatsById(int augmentationId)
|
||||
{
|
||||
FastList<AugStat> temp = new FastList<>();
|
||||
// An augmentation id contains 2 short vaues so we gotta seperate them here
|
||||
// both values contain a number from 1-16380, the first 14560 values are stats
|
||||
// the 14560 stats are divided into 4 blocks each holding 3640 values
|
||||
// each block contains 40 subblocks holding 91 stat values
|
||||
// the first 13 values are so called Solo-stats and they have the highest stat increase possible
|
||||
// after the 13 Solo-stats come 78 combined stats (thats every possible combination of the 13 solo stats)
|
||||
// the first 12 combined stats (14-26) is the stat 1 combined with stat 2-13
|
||||
// the next 11 combined stats then are stat 2 combined with stat 3-13 and so on...
|
||||
// to get the idea have a look @ optiondata_client-e.dat - thats where the data came from :)
|
||||
int stats[] = new int[2];
|
||||
stats[0] = 0x0000FFFF & augmentationId;
|
||||
stats[1] = (augmentationId >> 16);
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
// weapon augmentation - stats
|
||||
if ((stats[i] >= STAT_START) && (stats[i] <= STAT_END))
|
||||
{
|
||||
int base = stats[i] - STAT_START;
|
||||
int color = base / STAT_BLOCKSIZE; // 4 color blocks
|
||||
int subblock = base % STAT_BLOCKSIZE; // offset in color block
|
||||
int level = subblock / STAT_SUBBLOCKSIZE; // stat level (sub-block number)
|
||||
int stat = subblock % STAT_SUBBLOCKSIZE; // offset in sub-block - stat
|
||||
|
||||
byte stat1 = STATS1_MAP[stat];
|
||||
byte stat2 = STATS2_MAP[stat];
|
||||
if (stat1 == stat2) // solo stat
|
||||
{
|
||||
AugmentationStat as = ((AugmentationStat) _augStats[color].get(stat1));
|
||||
temp.add(new AugStat(as.getStat(), as.getSingleStatValue(level)));
|
||||
}
|
||||
else
|
||||
// combined stat
|
||||
{
|
||||
AugmentationStat as = ((AugmentationStat) _augStats[color].get(stat1));
|
||||
temp.add(new AugStat(as.getStat(), as.getCombinedStatValue(level)));
|
||||
as = ((AugmentationStat) _augStats[color].get(stat2));
|
||||
temp.add(new AugStat(as.getStat(), as.getCombinedStatValue(level)));
|
||||
}
|
||||
}
|
||||
// its a base stat
|
||||
else if ((stats[i] >= BASESTAT_STR) && (stats[i] <= BASESTAT_MEN))
|
||||
{
|
||||
switch (stats[i])
|
||||
{
|
||||
case BASESTAT_STR:
|
||||
temp.add(new AugStat(Stats.STAT_STR, 1.0f));
|
||||
break;
|
||||
case BASESTAT_CON:
|
||||
temp.add(new AugStat(Stats.STAT_CON, 1.0f));
|
||||
break;
|
||||
case BASESTAT_INT:
|
||||
temp.add(new AugStat(Stats.STAT_INT, 1.0f));
|
||||
break;
|
||||
case BASESTAT_MEN:
|
||||
temp.add(new AugStat(Stats.STAT_MEN, 1.0f));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// accessory augmentation
|
||||
// 3 areas for rings, earrings and necklaces
|
||||
// each area consist of 10 blocks (level)
|
||||
// each block has skills first (18 or 24 for necklaces)
|
||||
// and sub-block for stats next
|
||||
else if ((stats[i] >= ACC_START) && (stats[i] <= ACC_END))
|
||||
{
|
||||
int base, level, subblock;
|
||||
|
||||
if (stats[i] <= ACC_RING_END) // rings area
|
||||
{
|
||||
base = stats[i] - ACC_RING_START; // calculate base offset
|
||||
level = base / ACC_RING_BLOCKSIZE; // stat level (block number)
|
||||
subblock = (base % ACC_RING_BLOCKSIZE) - ACC_RING_SKILLS; // skills first
|
||||
}
|
||||
else if (stats[i] <= ACC_EAR_END) // earrings area
|
||||
{
|
||||
base = stats[i] - ACC_EAR_START;
|
||||
level = base / ACC_EAR_BLOCKSIZE;
|
||||
subblock = (base % ACC_EAR_BLOCKSIZE) - ACC_EAR_SKILLS;
|
||||
}
|
||||
else
|
||||
// necklaces
|
||||
{
|
||||
base = stats[i] - ACC_NECK_START;
|
||||
level = base / ACC_NECK_BLOCKSIZE;
|
||||
subblock = (base % ACC_NECK_BLOCKSIZE) - ACC_NECK_SKILLS;
|
||||
}
|
||||
|
||||
if (subblock >= 0) // stat, not skill
|
||||
{
|
||||
int color = subblock / ACC_STAT_SUBBLOCKSIZE;
|
||||
int stat = subblock % ACC_STAT_SUBBLOCKSIZE;
|
||||
byte stat1 = ACC_STATS1_MAP[stat];
|
||||
byte stat2 = ACC_STATS2_MAP[stat];
|
||||
if (stat1 == stat2) // solo
|
||||
{
|
||||
AugmentationStat as = ((AugmentationStat) _augAccStats[color].get(stat1));
|
||||
temp.add(new AugStat(as.getStat(), as.getSingleStatValue(level)));
|
||||
}
|
||||
else
|
||||
// combined
|
||||
{
|
||||
AugmentationStat as = ((AugmentationStat) _augAccStats[color].get(stat1));
|
||||
temp.add(new AugStat(as.getStat(), as.getCombinedStatValue(level)));
|
||||
as = ((AugmentationStat) _augAccStats[color].get(stat2));
|
||||
temp.add(new AugStat(as.getStat(), as.getCombinedStatValue(level)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns skill by augmentation Id or null if not valid or not found
|
||||
*/
|
||||
public L2Skill getAugSkillById(int augmentationId)
|
||||
{
|
||||
final AugmentationSkill temp = _allSkills.get(augmentationId);
|
||||
if (temp == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return temp.getSkill();
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final AugmentationData _instance = new AugmentationData();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision: 1.3.2.2.2.1 $ $Date: 2005/03/27 15:29:18 $
|
||||
*/
|
||||
public class CharNameTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(CharNameTable.class.getName());
|
||||
|
||||
private final Map<Integer, String> _chars;
|
||||
private final Map<Integer, Integer> _accessLevels;
|
||||
|
||||
private CharNameTable()
|
||||
{
|
||||
_chars = new FastMap<>();
|
||||
_accessLevels = new FastMap<>();
|
||||
if (Config.CACHE_CHAR_NAMES)
|
||||
{
|
||||
loadAll();
|
||||
}
|
||||
}
|
||||
|
||||
public static CharNameTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
public final void addName(L2PcInstance player)
|
||||
{
|
||||
if (player != null)
|
||||
{
|
||||
addName(player.getObjectId(), player.getName());
|
||||
_accessLevels.put(player.getObjectId(), player.getAccessLevel().getLevel());
|
||||
}
|
||||
}
|
||||
|
||||
private final void addName(int objectId, String name)
|
||||
{
|
||||
if (name != null)
|
||||
{
|
||||
if (!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;
|
||||
}
|
||||
|
||||
Iterator<Entry<Integer, String>> it = _chars.entrySet().iterator();
|
||||
|
||||
Map.Entry<Integer, String> pair;
|
||||
while (it.hasNext())
|
||||
{
|
||||
pair = it.next();
|
||||
if (pair.getValue().equalsIgnoreCase(name))
|
||||
{
|
||||
return pair.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.CACHE_CHAR_NAMES)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int id = -1;
|
||||
int accessLevel = 0;
|
||||
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT charId,accesslevel FROM characters WHERE char_name=?");
|
||||
statement.setString(1, name);
|
||||
ResultSet rset = statement.executeQuery();
|
||||
while (rset.next())
|
||||
{
|
||||
id = rset.getInt(1);
|
||||
accessLevel = rset.getInt(2);
|
||||
}
|
||||
rset.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Could not check existing char name: " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
|
||||
if (id > 0)
|
||||
{
|
||||
_chars.put(id, name);
|
||||
_accessLevels.put(id, accessLevel);
|
||||
return id;
|
||||
}
|
||||
|
||||
return -1; // not found
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int accessLevel = 0;
|
||||
Connection con = null;
|
||||
PreparedStatement statement = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
statement = con.prepareStatement("SELECT char_name,accesslevel FROM characters WHERE charId=?");
|
||||
statement.setInt(1, id);
|
||||
ResultSet rset = statement.executeQuery();
|
||||
while (rset.next())
|
||||
{
|
||||
name = rset.getString(1);
|
||||
accessLevel = rset.getInt(2);
|
||||
}
|
||||
rset.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Could not check existing char id: " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
if ((name != null) && !name.isEmpty())
|
||||
{
|
||||
_chars.put(id, name);
|
||||
_accessLevels.put(id, accessLevel);
|
||||
return name;
|
||||
}
|
||||
|
||||
return null; // not found
|
||||
}
|
||||
|
||||
public final int getAccessLevelById(int objectId)
|
||||
{
|
||||
if (getNameById(objectId) != null)
|
||||
{
|
||||
return _accessLevels.get(objectId);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public synchronized boolean doesCharNameExist(String name)
|
||||
{
|
||||
boolean result = true;
|
||||
Connection con = null;
|
||||
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT account_name FROM characters WHERE char_name=?");
|
||||
statement.setString(1, name);
|
||||
ResultSet rset = statement.executeQuery();
|
||||
result = rset.next();
|
||||
rset.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Could not check existing charname: " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int accountCharNumber(String account)
|
||||
{
|
||||
Connection con = null;
|
||||
int number = 0;
|
||||
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT COUNT(char_name) FROM characters WHERE account_name=?");
|
||||
statement.setString(1, account);
|
||||
ResultSet rset = statement.executeQuery();
|
||||
while (rset.next())
|
||||
{
|
||||
number = rset.getInt(1);
|
||||
}
|
||||
rset.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Could not check existing char number: " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
private void loadAll()
|
||||
{
|
||||
String name;
|
||||
int id = -1;
|
||||
int accessLevel = 0;
|
||||
PreparedStatement statement = null;
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
statement = con.prepareStatement("SELECT charId,char_name,accesslevel FROM characters");
|
||||
ResultSet rset = statement.executeQuery();
|
||||
while (rset.next())
|
||||
{
|
||||
id = rset.getInt(1);
|
||||
name = rset.getString(2);
|
||||
accessLevel = rset.getInt(3);
|
||||
_chars.put(id, name);
|
||||
_accessLevels.put(id, accessLevel);
|
||||
}
|
||||
rset.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Could not load char name: " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
_log.info(getClass().getSimpleName() + ": Loaded " + _chars.size() + " char names.");
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final CharNameTable _instance = new CharNameTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
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 com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
import com.l2jserver.gameserver.templates.StatsSet;
|
||||
import com.l2jserver.gameserver.templates.chars.L2PcTemplate;
|
||||
|
||||
/**
|
||||
* @author Unknown, Forsaiken
|
||||
*/
|
||||
public final class CharTemplateTable
|
||||
{
|
||||
private static final Logger _log = Logger.getLogger(CharTemplateTable.class.getName());
|
||||
|
||||
public static final CharTemplateTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private final L2PcTemplate[] _templates;
|
||||
|
||||
private CharTemplateTable()
|
||||
{
|
||||
_templates = new L2PcTemplate[ClassId.values().length];
|
||||
|
||||
Connection con = null;
|
||||
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT * FROM class_list, char_templates, lvlupgain" + " WHERE class_list.id = char_templates.classId" + " AND class_list.id = lvlupgain.classId" + " ORDER BY class_list.id");
|
||||
ResultSet rset = statement.executeQuery();
|
||||
|
||||
int count = 0;
|
||||
while (rset.next())
|
||||
{
|
||||
StatsSet set = new StatsSet();
|
||||
set.set("classId", rset.getInt("id"));
|
||||
set.set("className", rset.getString("className"));
|
||||
set.set("raceId", rset.getInt("raceId"));
|
||||
set.set("baseSTR", rset.getInt("STR"));
|
||||
set.set("baseCON", rset.getInt("CON"));
|
||||
set.set("baseDEX", rset.getInt("DEX"));
|
||||
set.set("baseINT", rset.getInt("_INT"));
|
||||
set.set("baseWIT", rset.getInt("WIT"));
|
||||
set.set("baseMEN", rset.getInt("MEN"));
|
||||
set.set("baseHpMax", rset.getFloat("defaultHpBase"));
|
||||
set.set("lvlHpAdd", rset.getFloat("defaultHpAdd"));
|
||||
set.set("lvlHpMod", rset.getFloat("defaultHpMod"));
|
||||
set.set("baseMpMax", rset.getFloat("defaultMpBase"));
|
||||
set.set("baseCpMax", rset.getFloat("defaultCpBase"));
|
||||
set.set("lvlCpAdd", rset.getFloat("defaultCpAdd"));
|
||||
set.set("lvlCpMod", rset.getFloat("defaultCpMod"));
|
||||
set.set("lvlMpAdd", rset.getFloat("defaultMpAdd"));
|
||||
set.set("lvlMpMod", rset.getFloat("defaultMpMod"));
|
||||
set.set("baseHpReg", 1.5);
|
||||
set.set("baseMpReg", 0.9);
|
||||
set.set("basePAtk", rset.getInt("p_atk"));
|
||||
set.set("basePDef", /* classId.isMage()? 77 : 129 */rset.getInt("p_def"));
|
||||
set.set("baseMAtk", rset.getInt("m_atk"));
|
||||
set.set("baseMDef", rset.getInt("char_templates.m_def"));
|
||||
set.set("classBaseLevel", rset.getInt("class_lvl"));
|
||||
set.set("basePAtkSpd", rset.getInt("p_spd"));
|
||||
set.set("baseMAtkSpd", /* classId.isMage()? 166 : 333 */rset.getInt("char_templates.m_spd"));
|
||||
set.set("baseCritRate", rset.getInt("char_templates.critical") / 10);
|
||||
set.set("baseRunSpd", rset.getInt("move_spd"));
|
||||
set.set("baseWalkSpd", 0);
|
||||
set.set("baseShldDef", 0);
|
||||
set.set("baseShldRate", 0);
|
||||
set.set("baseAtkRange", 40);
|
||||
|
||||
set.set("spawnX", rset.getInt("x"));
|
||||
set.set("spawnY", rset.getInt("y"));
|
||||
set.set("spawnZ", rset.getInt("z"));
|
||||
|
||||
L2PcTemplate ct;
|
||||
|
||||
set.set("collision_radius", rset.getDouble("m_col_r"));
|
||||
set.set("collision_height", rset.getDouble("m_col_h"));
|
||||
set.set("collision_radius_female", rset.getDouble("f_col_r"));
|
||||
set.set("collision_height_female", rset.getDouble("f_col_h"));
|
||||
ct = new L2PcTemplate(set);
|
||||
|
||||
_templates[ct.classId.getId()] = ct;
|
||||
++count;
|
||||
}
|
||||
|
||||
rset.close();
|
||||
statement.close();
|
||||
|
||||
_log.info("CharTemplateTable: Loaded " + count + " Character Templates.");
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Failed loading char templates", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT classId, itemId, amount, equipped FROM char_creation_items");
|
||||
ResultSet rset = statement.executeQuery();
|
||||
|
||||
int classId, itemId, amount;
|
||||
boolean equipped;
|
||||
while (rset.next())
|
||||
{
|
||||
classId = rset.getInt("classId");
|
||||
itemId = rset.getInt("itemId");
|
||||
amount = rset.getInt("amount");
|
||||
equipped = rset.getString("equipped").equals("true");
|
||||
|
||||
if (ItemTable.getInstance().getTemplate(itemId) != null)
|
||||
{
|
||||
if (classId == -1)
|
||||
{
|
||||
for (L2PcTemplate pct : _templates)
|
||||
{
|
||||
if (pct != null)
|
||||
{
|
||||
pct.addItem(itemId, amount, equipped);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
L2PcTemplate pct = _templates[classId];
|
||||
if (pct != null)
|
||||
{
|
||||
pct.addItem(itemId, amount, equipped);
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("char_creation_items: Entry for undefined class, classId: " + classId);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("char_creation_items: No data for itemId: " + itemId + " defined for classId " + classId);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Failed loading char creation items.", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
|
||||
public L2PcTemplate getTemplate(ClassId classId)
|
||||
{
|
||||
return this.getTemplate(classId.getId());
|
||||
}
|
||||
|
||||
public L2PcTemplate getTemplate(int classId)
|
||||
{
|
||||
return _templates[classId];
|
||||
}
|
||||
|
||||
public final String getClassNameById(int classId)
|
||||
{
|
||||
L2PcTemplate pcTemplate = getTemplate(classId);
|
||||
if (pcTemplate == null)
|
||||
{
|
||||
throw new IllegalArgumentException("No template for classId: " + classId);
|
||||
}
|
||||
return pcTemplate.className;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final CharTemplateTable _instance = new CharTemplateTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,538 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.communitybbs.Manager.ForumsBBSManager;
|
||||
import com.l2jserver.gameserver.idfactory.IdFactory;
|
||||
import com.l2jserver.gameserver.instancemanager.FortManager;
|
||||
import com.l2jserver.gameserver.instancemanager.FortSiegeManager;
|
||||
import com.l2jserver.gameserver.instancemanager.SiegeManager;
|
||||
import com.l2jserver.gameserver.model.L2Clan;
|
||||
import com.l2jserver.gameserver.model.L2ClanMember;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.entity.Fort;
|
||||
import com.l2jserver.gameserver.model.entity.FortSiege;
|
||||
import com.l2jserver.gameserver.model.entity.Siege;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.communityserver.CommunityServerThread;
|
||||
import com.l2jserver.gameserver.network.communityserver.writepackets.WorldInfo;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExBrExtraUserInfo;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PledgeShowInfoUpdate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PledgeShowMemberListAll;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PledgeShowMemberListUpdate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jserver.gameserver.network.serverpackets.UserInfo;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision: 1.11.2.5.2.5 $ $Date: 2005/03/27 15:29:18 $
|
||||
*/
|
||||
public class ClanTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(ClanTable.class.getName());
|
||||
|
||||
private final Map<Integer, L2Clan> _clans;
|
||||
|
||||
public static ClanTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
public L2Clan[] getClans()
|
||||
{
|
||||
return _clans.values().toArray(new L2Clan[_clans.size()]);
|
||||
}
|
||||
|
||||
private ClanTable()
|
||||
{
|
||||
// forums has to be loaded before clan data, because of last forum id used should have also memo included
|
||||
if (Config.COMMUNITY_TYPE > 0)
|
||||
{
|
||||
ForumsBBSManager.getInstance().initRoot();
|
||||
}
|
||||
|
||||
_clans = new FastMap<>();
|
||||
L2Clan clan;
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT clan_id FROM clan_data");
|
||||
ResultSet result = statement.executeQuery();
|
||||
|
||||
// Count the clans
|
||||
int clanCount = 0;
|
||||
|
||||
while (result.next())
|
||||
{
|
||||
int clanId = result.getInt("clan_id");
|
||||
_clans.put(clanId, new L2Clan(clanId));
|
||||
clan = getClan(clanId);
|
||||
if (clan.getDissolvingExpiryTime() != 0)
|
||||
{
|
||||
scheduleRemoveClan(clan.getClanId());
|
||||
}
|
||||
clanCount++;
|
||||
}
|
||||
result.close();
|
||||
statement.close();
|
||||
|
||||
_log.info("Restored " + clanCount + " clans from the database.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error restoring ClanTable.", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
|
||||
allianceCheck();
|
||||
restorewars();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clanId
|
||||
* @return
|
||||
*/
|
||||
public L2Clan getClan(int clanId)
|
||||
{
|
||||
L2Clan clan = _clans.get(Integer.valueOf(clanId));
|
||||
|
||||
return clan;
|
||||
}
|
||||
|
||||
public L2Clan getClanByName(String clanName)
|
||||
{
|
||||
for (L2Clan clan : getClans())
|
||||
{
|
||||
if (clan.getName().equalsIgnoreCase(clanName))
|
||||
{
|
||||
return clan;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new clan and store clan info to database
|
||||
* @param player
|
||||
* @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.fine(player.getObjectId() + "(" + player.getName() + ") requested a clan creation.");
|
||||
}
|
||||
|
||||
if (10 > player.getLevel())
|
||||
{
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_DO_NOT_MEET_CRITERIA_IN_ORDER_TO_CREATE_A_CLAN));
|
||||
return null;
|
||||
}
|
||||
if (0 != player.getClanId())
|
||||
{
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.FAILED_TO_CREATE_CLAN));
|
||||
return null;
|
||||
}
|
||||
if (System.currentTimeMillis() < player.getClanCreateExpiryTime())
|
||||
{
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_MUST_WAIT_XX_DAYS_BEFORE_CREATING_A_NEW_CLAN));
|
||||
return null;
|
||||
}
|
||||
if (!Util.isAlphaNumeric(clanName) || (2 > clanName.length()))
|
||||
{
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CLAN_NAME_INCORRECT));
|
||||
return null;
|
||||
}
|
||||
if (16 < clanName.length())
|
||||
{
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CLAN_NAME_TOO_LONG));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (null != getClanByName(clanName))
|
||||
{
|
||||
// clan name is already taken
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.S1_ALREADY_EXISTS);
|
||||
sm.addString(clanName);
|
||||
player.sendPacket(sm);
|
||||
sm = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
L2Clan clan = new L2Clan(IdFactory.getInstance().getNextId(), clanName);
|
||||
L2ClanMember leader = new L2ClanMember(clan, player.getName(), player.getLevel(), player.getClassId().getId(), player.getObjectId(), player.getPledgeType(), player.getPowerGrade(), player.getTitle(), player.getAppearance().getSex(), player.getRace().ordinal());
|
||||
clan.setLeader(leader);
|
||||
leader.setPlayerInstance(player);
|
||||
clan.store();
|
||||
player.setClan(clan);
|
||||
player.setPledgeClass(leader.calculatePledgeClass(player));
|
||||
player.setClanPrivileges(L2Clan.CP_ALL);
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.fine("New clan created: " + clan.getClanId() + " " + clan.getName());
|
||||
}
|
||||
|
||||
_clans.put(Integer.valueOf(clan.getClanId()), clan);
|
||||
|
||||
// should be update packet only
|
||||
player.sendPacket(new PledgeShowInfoUpdate(clan));
|
||||
player.sendPacket(new PledgeShowMemberListAll(clan, player));
|
||||
player.sendPacket(new UserInfo(player));
|
||||
player.sendPacket(new ExBrExtraUserInfo(player));
|
||||
player.sendPacket(new PledgeShowMemberListUpdate(player));
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CLAN_CREATED));
|
||||
// notify CB server that a new Clan is created
|
||||
CommunityServerThread.getInstance().sendPacket(new WorldInfo(null, clan, WorldInfo.TYPE_UPDATE_CLAN_DATA));
|
||||
return clan;
|
||||
}
|
||||
|
||||
public synchronized void destroyClan(int clanId)
|
||||
{
|
||||
L2Clan clan = getClan(clanId);
|
||||
if (clan == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
clan.broadcastToOnlineMembers(SystemMessage.getSystemMessage(SystemMessageId.CLAN_HAS_DISPERSED));
|
||||
int castleId = clan.getHasCastle();
|
||||
if (castleId == 0)
|
||||
{
|
||||
for (Siege siege : SiegeManager.getInstance().getSieges())
|
||||
{
|
||||
siege.removeSiegeClan(clan);
|
||||
}
|
||||
}
|
||||
int fortId = clan.getHasFort();
|
||||
if (fortId == 0)
|
||||
{
|
||||
for (FortSiege siege : FortSiegeManager.getInstance().getSieges())
|
||||
{
|
||||
siege.removeSiegeClan(clan);
|
||||
}
|
||||
}
|
||||
L2ClanMember leaderMember = clan.getLeader();
|
||||
if (leaderMember == null)
|
||||
{
|
||||
clan.getWarehouse().destroyAllItems("ClanRemove", null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
clan.getWarehouse().destroyAllItems("ClanRemove", clan.getLeader().getPlayerInstance(), null);
|
||||
}
|
||||
|
||||
for (L2ClanMember member : clan.getMembers())
|
||||
{
|
||||
clan.removeClanMember(member.getObjectId(), 0);
|
||||
}
|
||||
|
||||
_clans.remove(clanId);
|
||||
IdFactory.getInstance().releaseId(clanId);
|
||||
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("DELETE FROM clan_data WHERE clan_id=?");
|
||||
statement.setInt(1, clanId);
|
||||
statement.execute();
|
||||
statement.close();
|
||||
|
||||
statement = con.prepareStatement("DELETE FROM clan_privs WHERE clan_id=?");
|
||||
statement.setInt(1, clanId);
|
||||
statement.execute();
|
||||
statement.close();
|
||||
|
||||
statement = con.prepareStatement("DELETE FROM clan_skills WHERE clan_id=?");
|
||||
statement.setInt(1, clanId);
|
||||
statement.execute();
|
||||
statement.close();
|
||||
|
||||
statement = con.prepareStatement("DELETE FROM clan_subpledges WHERE clan_id=?");
|
||||
statement.setInt(1, clanId);
|
||||
statement.execute();
|
||||
statement.close();
|
||||
|
||||
statement = con.prepareStatement("DELETE FROM clan_wars WHERE clan1=? OR clan2=?");
|
||||
statement.setInt(1, clanId);
|
||||
statement.setInt(2, clanId);
|
||||
statement.execute();
|
||||
statement.close();
|
||||
|
||||
statement = con.prepareStatement("DELETE FROM clan_notices WHERE clan_id=?");
|
||||
statement.setInt(1, clanId);
|
||||
statement.execute();
|
||||
statement.close();
|
||||
|
||||
if (castleId != 0)
|
||||
{
|
||||
statement = con.prepareStatement("UPDATE castle SET taxPercent = 0 WHERE id = ?");
|
||||
statement.setInt(1, castleId);
|
||||
statement.execute();
|
||||
statement.close();
|
||||
}
|
||||
if (fortId != 0)
|
||||
{
|
||||
Fort fort = FortManager.getInstance().getFortById(fortId);
|
||||
if (fort != null)
|
||||
{
|
||||
L2Clan owner = fort.getOwnerClan();
|
||||
if (clan == owner)
|
||||
{
|
||||
fort.removeOwner(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.fine("clan removed in db: " + clanId);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error removing clan from DB.", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
|
||||
public void scheduleRemoveClan(final 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)
|
||||
{
|
||||
L2Clan clan1 = ClanTable.getInstance().getClan(clanId1);
|
||||
L2Clan clan2 = ClanTable.getInstance().getClan(clanId2);
|
||||
clan1.setEnemyClan(clan2);
|
||||
clan2.setAttackerClan(clan1);
|
||||
clan1.broadcastClanStatus();
|
||||
clan2.broadcastClanStatus();
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("REPLACE INTO clan_wars (clan1, clan2, wantspeace1, wantspeace2) VALUES(?,?,?,?)");
|
||||
statement.setInt(1, clanId1);
|
||||
statement.setInt(2, clanId2);
|
||||
statement.setInt(3, 0);
|
||||
statement.setInt(4, 0);
|
||||
statement.execute();
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error storing clan wars data.", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
// SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.WAR_WITH_THE_S1_CLAN_HAS_BEGUN);
|
||||
//
|
||||
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.CLAN_WAR_DECLARED_AGAINST_S1_IF_KILLED_LOSE_LOW_EXP);
|
||||
msg.addString(clan2.getName());
|
||||
clan1.broadcastToOnlineMembers(msg);
|
||||
// msg = SystemMessage.getSystemMessage(SystemMessageId.WAR_WITH_THE_S1_CLAN_HAS_BEGUN);
|
||||
// msg.addString(clan1.getName());
|
||||
// clan2.broadcastToOnlineMembers(msg);
|
||||
// clan1 declared clan war.
|
||||
msg = SystemMessage.getSystemMessage(SystemMessageId.CLAN_S1_DECLARED_WAR);
|
||||
msg.addString(clan1.getName());
|
||||
clan2.broadcastToOnlineMembers(msg);
|
||||
}
|
||||
|
||||
public void deleteclanswars(int clanId1, int clanId2)
|
||||
{
|
||||
L2Clan clan1 = ClanTable.getInstance().getClan(clanId1);
|
||||
L2Clan clan2 = ClanTable.getInstance().getClan(clanId2);
|
||||
clan1.deleteEnemyClan(clan2);
|
||||
clan2.deleteAttackerClan(clan1);
|
||||
clan1.broadcastClanStatus();
|
||||
clan2.broadcastClanStatus();
|
||||
// for(L2ClanMember player: clan1.getMembers())
|
||||
// {
|
||||
// if(player.getPlayerInstance()!=null)
|
||||
// player.getPlayerInstance().setWantsPeace(0);
|
||||
// }
|
||||
// for(L2ClanMember player: clan2.getMembers())
|
||||
// {
|
||||
// if(player.getPlayerInstance()!=null)
|
||||
// player.getPlayerInstance().setWantsPeace(0);
|
||||
// }
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("DELETE FROM clan_wars WHERE clan1=? AND clan2=?");
|
||||
statement.setInt(1, clanId1);
|
||||
statement.setInt(2, clanId2);
|
||||
statement.execute();
|
||||
// statement = con.prepareStatement("DELETE FROM clan_wars WHERE clan1=? AND clan2=?");
|
||||
// statement.setInt(1,clanId2);
|
||||
// statement.setInt(2,clanId1);
|
||||
// statement.execute();
|
||||
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error removing clan wars data.", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
// SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.WAR_WITH_THE_S1_CLAN_HAS_ENDED);
|
||||
SystemMessage msg = SystemMessage.getSystemMessage(SystemMessageId.WAR_AGAINST_S1_HAS_STOPPED);
|
||||
msg.addString(clan2.getName());
|
||||
clan1.broadcastToOnlineMembers(msg);
|
||||
msg = SystemMessage.getSystemMessage(SystemMessageId.CLAN_S1_HAS_DECIDED_TO_STOP);
|
||||
msg.addString(clan1.getName());
|
||||
clan2.broadcastToOnlineMembers(msg);
|
||||
// msg = SystemMessage.getSystemMessage(SystemMessageId.WAR_WITH_THE_S1_CLAN_HAS_ENDED);
|
||||
// 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().length - 1))
|
||||
{
|
||||
clan1.deleteEnemyClan(clan2);
|
||||
clan2.deleteEnemyClan(clan1);
|
||||
deleteclanswars(clan1.getClanId(), clan2.getClanId());
|
||||
}
|
||||
}
|
||||
|
||||
private void restorewars()
|
||||
{
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT clan1, clan2, wantspeace1, wantspeace2 FROM clan_wars");
|
||||
ResultSet rset = statement.executeQuery();
|
||||
while (rset.next())
|
||||
{
|
||||
getClan(rset.getInt("clan1")).setEnemyClan(rset.getInt("clan2"));
|
||||
getClan(rset.getInt("clan2")).setAttackerClan(rset.getInt("clan1"));
|
||||
}
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error restoring clan wars data.", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for nonexistent alliances
|
||||
*/
|
||||
private void allianceCheck()
|
||||
{
|
||||
for (L2Clan clan : _clans.values())
|
||||
{
|
||||
int allyId = clan.getAllyId();
|
||||
if ((allyId != 0) && (clan.getClanId() != allyId))
|
||||
{
|
||||
if (!_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 void storeClanScore()
|
||||
{
|
||||
for (L2Clan clan : _clans.values())
|
||||
{
|
||||
clan.updateClanScoreInDB();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final ClanTable _instance = new ClanTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.LineNumberReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.idfactory.IdFactory;
|
||||
import com.l2jserver.gameserver.instancemanager.ClanHallManager;
|
||||
import com.l2jserver.gameserver.instancemanager.InstanceManager;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
|
||||
import com.l2jserver.gameserver.model.entity.ClanHall;
|
||||
import com.l2jserver.gameserver.pathfinding.AbstractNodeLoc;
|
||||
import com.l2jserver.gameserver.templates.StatsSet;
|
||||
import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
|
||||
|
||||
public class DoorTable
|
||||
{
|
||||
private static final Logger _log = Logger.getLogger(DoorTable.class.getName());
|
||||
|
||||
private final TIntObjectHashMap<L2DoorInstance> _staticItems;
|
||||
private final TIntObjectHashMap<ArrayList<L2DoorInstance>> _regions;
|
||||
|
||||
public static DoorTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private DoorTable()
|
||||
{
|
||||
_staticItems = new TIntObjectHashMap<>();
|
||||
_regions = new TIntObjectHashMap<>();
|
||||
parseData();
|
||||
onStart();
|
||||
}
|
||||
|
||||
public void reloadAll()
|
||||
{
|
||||
respawn();
|
||||
}
|
||||
|
||||
public void respawn()
|
||||
{
|
||||
_staticItems.clear();
|
||||
_regions.clear();
|
||||
parseData();
|
||||
}
|
||||
|
||||
public void parseData()
|
||||
{
|
||||
File doorData = new File(Config.DATAPACK_ROOT, "data/door.csv");
|
||||
try (LineNumberReader lnr = new LineNumberReader(new BufferedReader(new FileReader(doorData))))
|
||||
{
|
||||
String line = null;
|
||||
_log.info("Searching clan halls doors:");
|
||||
|
||||
while ((line = lnr.readLine()) != null)
|
||||
{
|
||||
if ((line.trim().length() == 0) || line.startsWith("#"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
L2DoorInstance door = parseList(line, false);
|
||||
putDoor(door);
|
||||
door.spawnMe(door.getX(), door.getY(), door.getZ());
|
||||
ClanHall clanhall = ClanHallManager.getInstance().getNearbyClanHall(door.getX(), door.getY(), 500);
|
||||
if (clanhall != null)
|
||||
{
|
||||
clanhall.getDoors().add(door);
|
||||
door.setClanHall(clanhall);
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.info("door " + door.getDoorName() + " attached to ch " + clanhall.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_log.info("DoorTable: Loaded " + _staticItems.size() + " Door Templates for " + _regions.size() + " regions.");
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
_log.warning("door.csv is missing in data folder");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Error while creating door table " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses door list.
|
||||
* @param line string
|
||||
* @param commanderDoor whether the door is commander door (fortress)
|
||||
* @return created door instance
|
||||
*/
|
||||
public static L2DoorInstance parseList(final String line, final boolean commanderDoor)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(line, ";");
|
||||
L2DoorInstance door = null;
|
||||
try
|
||||
{
|
||||
String name = st.nextToken();
|
||||
int id = Integer.parseInt(st.nextToken());
|
||||
int x = Integer.parseInt(st.nextToken());
|
||||
int y = Integer.parseInt(st.nextToken());
|
||||
int z = Integer.parseInt(st.nextToken());
|
||||
int rangeXMin = Integer.parseInt(st.nextToken());
|
||||
int rangeYMin = Integer.parseInt(st.nextToken());
|
||||
int rangeZMin = Integer.parseInt(st.nextToken());
|
||||
int rangeXMax = Integer.parseInt(st.nextToken());
|
||||
int rangeYMax = Integer.parseInt(st.nextToken());
|
||||
int rangeZMax = Integer.parseInt(st.nextToken());
|
||||
int hp = Integer.parseInt(st.nextToken());
|
||||
int pdef = Integer.parseInt(st.nextToken());
|
||||
int mdef = Integer.parseInt(st.nextToken());
|
||||
int emitter = Integer.parseInt(st.nextToken());
|
||||
boolean unlockable = false;
|
||||
if (st.hasMoreTokens())
|
||||
{
|
||||
unlockable = Boolean.parseBoolean(st.nextToken());
|
||||
}
|
||||
boolean startOpen = false;
|
||||
if (st.hasMoreTokens())
|
||||
{
|
||||
startOpen = Boolean.parseBoolean(st.nextToken());
|
||||
}
|
||||
boolean targetable = true;
|
||||
if (st.hasMoreTokens())
|
||||
{
|
||||
targetable = Boolean.parseBoolean(st.nextToken());
|
||||
}
|
||||
|
||||
if (rangeXMin > rangeXMax)
|
||||
{
|
||||
_log.severe("Error in door data, XMin > XMax, ID:" + id);
|
||||
}
|
||||
if (rangeYMin > rangeYMax)
|
||||
{
|
||||
_log.severe("Error in door data, YMin > YMax, ID:" + id);
|
||||
}
|
||||
if (rangeZMin > rangeZMax)
|
||||
{
|
||||
_log.severe("Error in door data, ZMin > ZMax, ID:" + id);
|
||||
}
|
||||
int collisionRadius; // (max) radius for movement checks
|
||||
if ((rangeXMax - rangeXMin) > (rangeYMax - rangeYMin))
|
||||
{
|
||||
collisionRadius = rangeYMax - rangeYMin;
|
||||
}
|
||||
else
|
||||
{
|
||||
collisionRadius = rangeXMax - rangeXMin;
|
||||
}
|
||||
|
||||
StatsSet npcDat = new StatsSet();
|
||||
npcDat.set("npcId", id);
|
||||
npcDat.set("level", 0);
|
||||
npcDat.set("jClass", "door");
|
||||
|
||||
npcDat.set("baseSTR", 0);
|
||||
npcDat.set("baseCON", 0);
|
||||
npcDat.set("baseDEX", 0);
|
||||
npcDat.set("baseINT", 0);
|
||||
npcDat.set("baseWIT", 0);
|
||||
npcDat.set("baseMEN", 0);
|
||||
|
||||
npcDat.set("baseShldDef", 0);
|
||||
npcDat.set("baseShldRate", 0);
|
||||
npcDat.set("baseAccCombat", 38);
|
||||
npcDat.set("baseEvasRate", 38);
|
||||
npcDat.set("baseCritRate", 38);
|
||||
|
||||
// npcDat.set("name", "");
|
||||
npcDat.set("collision_radius", collisionRadius);
|
||||
npcDat.set("collision_height", rangeZMax - rangeZMin);
|
||||
npcDat.set("sex", "male");
|
||||
npcDat.set("type", "");
|
||||
npcDat.set("baseAtkRange", 0);
|
||||
npcDat.set("baseMpMax", 0);
|
||||
npcDat.set("baseCpMax", 0);
|
||||
npcDat.set("rewardExp", 0);
|
||||
npcDat.set("rewardSp", 0);
|
||||
npcDat.set("basePAtk", 0);
|
||||
npcDat.set("baseMAtk", 0);
|
||||
npcDat.set("basePAtkSpd", 0);
|
||||
npcDat.set("aggroRange", 0);
|
||||
npcDat.set("baseMAtkSpd", 0);
|
||||
npcDat.set("rhand", 0);
|
||||
npcDat.set("lhand", 0);
|
||||
npcDat.set("armor", 0);
|
||||
npcDat.set("baseWalkSpd", 0);
|
||||
npcDat.set("baseRunSpd", 0);
|
||||
npcDat.set("name", name);
|
||||
npcDat.set("baseHpMax", hp);
|
||||
npcDat.set("baseHpReg", 3.e-3f);
|
||||
npcDat.set("baseMpReg", 3.e-3f);
|
||||
npcDat.set("basePDef", pdef);
|
||||
npcDat.set("baseMDef", mdef);
|
||||
|
||||
L2CharTemplate template = new L2CharTemplate(npcDat);
|
||||
door = new L2DoorInstance(IdFactory.getInstance().getNextId(), template, id, name, unlockable);
|
||||
door.setRange(rangeXMin, rangeYMin, rangeZMin, rangeXMax, rangeYMax, rangeZMax);
|
||||
door.setCurrentHpMp(door.getMaxHp(), door.getMaxMp());
|
||||
door.setXYZInvisible(x, y, z);
|
||||
door.setMapRegion(MapRegionTable.getInstance().getMapRegion(x, y));
|
||||
door.setEmitter(emitter);
|
||||
door.setTargetable(targetable);
|
||||
|
||||
if (commanderDoor)
|
||||
{
|
||||
door.setIsCommanderDoor(startOpen);
|
||||
}
|
||||
else
|
||||
{
|
||||
door.setOpen(startOpen);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.severe("Error in door data at line: " + line);
|
||||
}
|
||||
return door;
|
||||
}
|
||||
|
||||
public L2DoorInstance getDoor(Integer id)
|
||||
{
|
||||
return _staticItems.get(id);
|
||||
}
|
||||
|
||||
public void putDoor(L2DoorInstance door)
|
||||
{
|
||||
_staticItems.put(door.getDoorId(), door);
|
||||
|
||||
if (_regions.contains(door.getMapRegion()))
|
||||
{
|
||||
_regions.get(door.getMapRegion()).add(door);
|
||||
}
|
||||
else
|
||||
{
|
||||
final ArrayList<L2DoorInstance> region = new ArrayList<>();
|
||||
region.add(door);
|
||||
_regions.put(door.getMapRegion(), region);
|
||||
}
|
||||
}
|
||||
|
||||
public L2DoorInstance[] getDoors()
|
||||
{
|
||||
L2DoorInstance[] _allTemplates = _staticItems.getValues(new L2DoorInstance[_staticItems.size()]);
|
||||
return _allTemplates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a check and sets up a scheduled task for those doors that require auto opening/closing.
|
||||
*/
|
||||
public void checkAutoOpen()
|
||||
{
|
||||
for (L2DoorInstance doorInst : getDoors())
|
||||
{
|
||||
// Garden of Eva (every 7 minutes)
|
||||
if (doorInst.getDoorName().startsWith("goe"))
|
||||
{
|
||||
doorInst.setAutoActionDelay(420000);
|
||||
}
|
||||
else if (doorInst.getDoorName().startsWith("aden_tower"))
|
||||
{
|
||||
doorInst.setAutoActionDelay(300000);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: check which are automatic // devils (every 5 minutes) else if (doorInst.getDoorName().startsWith("pirate_isle")) doorInst.setAutoActionDelay(300000); // Cruma Tower (every 20 minutes) else if (doorInst.getDoorName().startsWith("cruma")) doorInst.setAutoActionDelay(1200000);
|
||||
*/
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
ArrayList<L2DoorInstance> allDoors;
|
||||
if ((instanceId > 0) && (InstanceManager.getInstance().getInstance(instanceId) != null))
|
||||
{
|
||||
allDoors = InstanceManager.getInstance().getInstance(instanceId).getDoors();
|
||||
}
|
||||
else
|
||||
{
|
||||
allDoors = _regions.get(MapRegionTable.getInstance().getMapRegion(x, y));
|
||||
}
|
||||
|
||||
if (allDoors == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (L2DoorInstance doorInst : allDoors)
|
||||
{
|
||||
if (doorInst.getXMax() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// line segment goes through box
|
||||
// first basic checks to stop most calculations short
|
||||
// phase 1, x
|
||||
if (((x <= doorInst.getXMax()) && (tx >= doorInst.getXMin())) || ((tx <= doorInst.getXMax()) && (x >= doorInst.getXMin())))
|
||||
{
|
||||
// phase 2, y
|
||||
if (((y <= doorInst.getYMax()) && (ty >= doorInst.getYMin())) || ((ty <= doorInst.getYMax()) && (y >= doorInst.getYMin())))
|
||||
{
|
||||
// phase 3, basically only z remains but now we calculate it with another formula (by rage)
|
||||
// in some cases the direct line check (only) in the beginning isn't sufficient,
|
||||
// when char z changes a lot along the path
|
||||
if ((doorInst.getCurrentHp() > 0) && !doorInst.getOpen())
|
||||
{
|
||||
int px1 = doorInst.getXMin();
|
||||
int py1 = doorInst.getYMin();
|
||||
int pz1 = doorInst.getZMin();
|
||||
int px2 = doorInst.getXMax();
|
||||
int py2 = doorInst.getYMax();
|
||||
int pz2 = doorInst.getZMax();
|
||||
|
||||
int l = tx - x;
|
||||
int m = ty - y;
|
||||
int n = tz - z;
|
||||
|
||||
int dk;
|
||||
|
||||
if ((dk = ((doorInst.getA() * l) + (doorInst.getB() * m) + (doorInst.getC() * n))) == 0)
|
||||
{
|
||||
continue; // Parallel
|
||||
}
|
||||
|
||||
float p = (float) ((doorInst.getA() * x) + (doorInst.getB() * y) + (doorInst.getC() * z) + doorInst.getD()) / (float) dk;
|
||||
|
||||
int fx = (int) (x - (l * p));
|
||||
int fy = (int) (y - (m * p));
|
||||
int fz = (int) (z - (n * p));
|
||||
|
||||
if (((Math.min(x, tx) <= fx) && (fx <= Math.max(x, tx))) && ((Math.min(y, ty) <= fy) && (fy <= Math.max(y, ty))) && ((Math.min(z, tz) <= fz) && (fz <= Math.max(z, tz))))
|
||||
{
|
||||
if ((((fx >= px1) && (fx <= px2)) || ((fx >= px2) && (fx <= px1))) && (((fy >= py1) && (fy <= py2)) || ((fy >= py2) && (fy <= py1))) && (((fz >= pz1) && (fz <= pz2)) || ((fz >= pz2) && (fz <= pz1))))
|
||||
{
|
||||
return true; // Door between
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void onStart()
|
||||
{
|
||||
try
|
||||
{
|
||||
checkAutoOpen();
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
{
|
||||
_log.log(Level.WARNING, "There are errors in your Door.csv file. Update door.csv", e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final DoorTable _instance = new DoorTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.model.L2EnchantSkillGroup;
|
||||
import com.l2jserver.gameserver.model.L2EnchantSkillGroup.EnchantSkillDetail;
|
||||
import com.l2jserver.gameserver.model.L2EnchantSkillLearn;
|
||||
import com.l2jserver.gameserver.model.L2Skill;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision: 1.13.2.2.2.8 $ $Date: 2005/04/06 16:13:25 $
|
||||
*/
|
||||
public class EnchantGroupsTable
|
||||
{
|
||||
public static final int NORMAL_ENCHANT_COST_MULTIPLIER = 1;
|
||||
public static final int SAFE_ENCHANT_COST_MULTIPLIER = 5;
|
||||
|
||||
public static final int NORMAL_ENCHANT_BOOK = 6622;
|
||||
public static final int SAFE_ENCHANT_BOOK = 9627;
|
||||
public static final int CHANGE_ENCHANT_BOOK = 9626;
|
||||
public static final int UNTRAIN_ENCHANT_BOOK = 9625;
|
||||
|
||||
private static Logger _log = Logger.getLogger(EnchantGroupsTable.class.getName());
|
||||
|
||||
private TIntObjectHashMap<L2EnchantSkillGroup> _enchantSkillGroups; // enchant skill group
|
||||
private TIntObjectHashMap<L2EnchantSkillLearn> _enchantSkillTrees; // enchant skill list
|
||||
|
||||
public static EnchantGroupsTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private EnchantGroupsTable()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
private void load()
|
||||
{
|
||||
int count = 0;
|
||||
Connection con = null;
|
||||
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
|
||||
try
|
||||
{
|
||||
_enchantSkillGroups = new TIntObjectHashMap<>();
|
||||
_enchantSkillTrees = new TIntObjectHashMap<>();
|
||||
|
||||
PreparedStatement statement = con.prepareStatement("SELECT group_id, level, adena, exp, sp, success_rate76, success_rate77, success_rate78, success_rate79, success_rate80, success_rate81, success_rate82, success_rate83, success_rate84, success_rate85 FROM enchant_skill_groups ORDER BY group_id, level");
|
||||
ResultSet enchantGroups = statement.executeQuery();
|
||||
|
||||
int prevGroupId = -1;
|
||||
|
||||
while (enchantGroups.next())
|
||||
{
|
||||
int id = enchantGroups.getInt("group_id");
|
||||
int lvl = enchantGroups.getInt("level");
|
||||
int adena = enchantGroups.getInt("adena");
|
||||
int exp = enchantGroups.getInt("exp");
|
||||
int sp = enchantGroups.getInt("sp");
|
||||
byte rate76 = enchantGroups.getByte("success_rate76");
|
||||
byte rate77 = enchantGroups.getByte("success_rate77");
|
||||
byte rate78 = enchantGroups.getByte("success_rate78");
|
||||
byte rate79 = enchantGroups.getByte("success_rate79");
|
||||
byte rate80 = enchantGroups.getByte("success_rate80");
|
||||
byte rate81 = enchantGroups.getByte("success_rate81");
|
||||
byte rate82 = enchantGroups.getByte("success_rate82");
|
||||
byte rate83 = enchantGroups.getByte("success_rate83");
|
||||
byte rate84 = enchantGroups.getByte("success_rate84");
|
||||
byte rate85 = enchantGroups.getByte("success_rate85");
|
||||
|
||||
if (prevGroupId != id)
|
||||
{
|
||||
prevGroupId = id;
|
||||
}
|
||||
|
||||
L2EnchantSkillGroup group = _enchantSkillGroups.get(id);
|
||||
if (group == null)
|
||||
{
|
||||
group = new L2EnchantSkillGroup(id);
|
||||
_enchantSkillGroups.put(id, group);
|
||||
count++;
|
||||
}
|
||||
EnchantSkillDetail esd = new EnchantSkillDetail(lvl, adena, exp, sp, rate76, rate77, rate78, rate79, rate80, rate81, rate82, rate83, rate84, rate85);
|
||||
group.addEnchantDetail(esd);
|
||||
}
|
||||
|
||||
enchantGroups.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error while loading enchant skill groups ", e);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error while loading enchant skill groups ", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
|
||||
_log.info("EnchantGroupsTable: Loaded " + count + " groups.");
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
_log.log(Level.SEVERE, "Error while loading generating enchant skill id: " + skillId + "; route: " + route + "; missing group: " + group);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public L2EnchantSkillLearn getSkillEnchantmentForSkill(L2Skill skill)
|
||||
{
|
||||
L2EnchantSkillLearn esl = getSkillEnchantmentBySkillId(skill.getId());
|
||||
// there is enchantment for this skill and we have the required level of it
|
||||
if ((esl != null) && (skill.getLevel() >= esl.getBaseLevel()))
|
||||
{
|
||||
return esl;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public L2EnchantSkillLearn getSkillEnchantmentBySkillId(int skillId)
|
||||
{
|
||||
return _enchantSkillTrees.get(skillId);
|
||||
}
|
||||
|
||||
public int getEnchantSkillSpCost(L2Skill skill)
|
||||
{
|
||||
L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
|
||||
if (enchantSkillLearn != null)
|
||||
{
|
||||
|
||||
EnchantSkillDetail esd = enchantSkillLearn.getEnchantSkillDetail(skill.getLevel());
|
||||
if (esd != null)
|
||||
{
|
||||
return esd.getSpCost();
|
||||
}
|
||||
}
|
||||
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public int getEnchantSkillAdenaCost(L2Skill skill)
|
||||
{
|
||||
L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
|
||||
if (enchantSkillLearn != null)
|
||||
{
|
||||
EnchantSkillDetail esd = enchantSkillLearn.getEnchantSkillDetail(skill.getLevel());
|
||||
if (esd != null)
|
||||
{
|
||||
return esd.getAdenaCost();
|
||||
}
|
||||
}
|
||||
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public byte getEnchantSkillRate(L2PcInstance player, L2Skill skill)
|
||||
{
|
||||
L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
|
||||
if (enchantSkillLearn != null)
|
||||
{
|
||||
EnchantSkillDetail esd = enchantSkillLearn.getEnchantSkillDetail(skill.getLevel());
|
||||
if (esd != null)
|
||||
{
|
||||
return esd.getRate(player);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final EnchantGroupsTable _instance = new EnchantGroupsTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return L2EnchantSkillGroup
|
||||
*/
|
||||
public L2EnchantSkillGroup getEnchantSkillGroupById(int id)
|
||||
{
|
||||
return _enchantSkillGroups.get(id);
|
||||
}
|
||||
|
||||
public void reload()
|
||||
{
|
||||
load();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.model.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.skills.Stats;
|
||||
import com.l2jserver.gameserver.skills.funcs.FuncTemplate;
|
||||
import com.l2jserver.gameserver.skills.funcs.LambdaConst;
|
||||
import com.l2jserver.gameserver.templates.item.L2Item;
|
||||
|
||||
/**
|
||||
* @author MrPoke
|
||||
*/
|
||||
public class EnchantHPBonusData
|
||||
{
|
||||
protected static final Logger _log = Logger.getLogger(EnchantHPBonusData.class.getName());
|
||||
|
||||
private final TIntObjectHashMap<Integer[]> _armorHPBonus = new TIntObjectHashMap<>();
|
||||
private static final float fullArmorModifier = 1.5f;
|
||||
|
||||
public static final EnchantHPBonusData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private EnchantHPBonusData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
public void reload()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
private void load()
|
||||
{
|
||||
_armorHPBonus.clear();
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setIgnoringComments(true);
|
||||
File file = new File(Config.DATAPACK_ROOT, "data/enchantHPBonus.xml");
|
||||
Document doc = null;
|
||||
|
||||
if (file.exists())
|
||||
{
|
||||
try
|
||||
{
|
||||
doc = factory.newDocumentBuilder().parse(file);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Could not parse enchantHPBonus.xml file: " + e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
|
||||
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()))
|
||||
{
|
||||
NamedNodeMap attrs = d.getAttributes();
|
||||
Node att;
|
||||
Integer grade;
|
||||
|
||||
att = attrs.getNamedItem("grade");
|
||||
if (att == null)
|
||||
{
|
||||
_log.severe("[EnchantHPBonusData] Missing grade, skipping");
|
||||
continue;
|
||||
}
|
||||
grade = Integer.parseInt(att.getNodeValue());
|
||||
|
||||
att = attrs.getNamedItem("values");
|
||||
if (att == null)
|
||||
{
|
||||
_log.severe("[EnchantHPBonusData] Missing bonus id: " + grade + ", skipping");
|
||||
continue;
|
||||
}
|
||||
StringTokenizer st = new StringTokenizer(att.getNodeValue(), ",");
|
||||
int tokenCount = st.countTokens();
|
||||
Integer[] bonus = new Integer[tokenCount];
|
||||
for (int i = 0; i < tokenCount; i++)
|
||||
{
|
||||
Integer value = Integer.decode(st.nextToken().trim());
|
||||
if (value == null)
|
||||
{
|
||||
_log.severe("[EnchantHPBonusData] Bad Hp value!! grade: " + grade + " token: " + i);
|
||||
value = 0;
|
||||
}
|
||||
bonus[i] = value;
|
||||
}
|
||||
_armorHPBonus.put(grade, bonus);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_armorHPBonus.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<Integer> itemIds = ItemTable.getInstance().getAllArmorsId();
|
||||
int count = 0;
|
||||
|
||||
for (Integer itemId : itemIds)
|
||||
{
|
||||
L2Item item = ItemTable.getInstance().getTemplate(itemId);
|
||||
if ((item != null) && (item.getCrystalType() != L2Item.CRYSTAL_NONE))
|
||||
{
|
||||
switch (item.getBodyPart())
|
||||
{
|
||||
case L2Item.SLOT_CHEST:
|
||||
case L2Item.SLOT_FEET:
|
||||
case L2Item.SLOT_GLOVES:
|
||||
case L2Item.SLOT_HEAD:
|
||||
case L2Item.SLOT_LEGS:
|
||||
case L2Item.SLOT_BACK:
|
||||
case L2Item.SLOT_FULL_ARMOR:
|
||||
case L2Item.SLOT_UNDERWEAR:
|
||||
case L2Item.SLOT_L_HAND:
|
||||
count++;
|
||||
FuncTemplate ft = new FuncTemplate(null, null, "EnchantHp", Stats.MAX_HP, 0x60, new LambdaConst(0));
|
||||
item.attach(ft);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// shields in the weapons table
|
||||
itemIds = ItemTable.getInstance().getAllWeaponsId();
|
||||
for (Integer itemId : itemIds)
|
||||
{
|
||||
L2Item item = ItemTable.getInstance().getTemplate(itemId);
|
||||
if ((item != null) && (item.getCrystalType() != L2Item.CRYSTAL_NONE))
|
||||
{
|
||||
switch (item.getBodyPart())
|
||||
{
|
||||
case L2Item.SLOT_L_HAND:
|
||||
count++;
|
||||
FuncTemplate ft = new FuncTemplate(null, null, "EnchantHp", Stats.MAX_HP, 0x60, new LambdaConst(0));
|
||||
item.attach(ft);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_log.info("Enchant HP Bonus registered for " + count + " items!");
|
||||
}
|
||||
}
|
||||
|
||||
public final int getHPBonus(L2ItemInstance item)
|
||||
{
|
||||
final Integer[] values = _armorHPBonus.get(item.getItem().getItemGradeSPlus());
|
||||
|
||||
if ((values == null) || (values.length == 0))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (item.getItem().getBodyPart() == L2Item.SLOT_FULL_ARMOR)
|
||||
{
|
||||
return (int) (values[Math.min(item.getEnchantLevel(), values.length) - 1] * fullArmorModifier);
|
||||
}
|
||||
return values[Math.min(item.getEnchantLevel(), values.length) - 1];
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final EnchantHPBonusData _instance = new EnchantHPBonusData();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
import com.l2jserver.gameserver.script.DateRange;
|
||||
|
||||
/**
|
||||
* This class manage drop of Special Events created by GM for a defined period. During a Special Event all L2Attackable can drop extra Items. Those extra Items are defined in the table <B>allNpcDateDrops</B>. Each Special Event has a start and end date to stop to drop extra Items automaticaly.<BR>
|
||||
* <BR>
|
||||
*/
|
||||
|
||||
public class EventDroplist
|
||||
{
|
||||
|
||||
// private static Logger _log = Logger.getLogger(EventDroplist.class.getName());
|
||||
|
||||
/** The table containing all DataDrop object */
|
||||
private final List<DateDrop> _allNpcDateDrops;
|
||||
|
||||
public static EventDroplist getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
public static class DateDrop
|
||||
{
|
||||
/** Start and end date of the Event */
|
||||
public DateRange dateRange;
|
||||
|
||||
/** The table containing Item identifier that can be dropped as extra Items during the Event */
|
||||
public int[] items;
|
||||
|
||||
/** The min number of Item dropped in one time during this Event */
|
||||
public int min;
|
||||
|
||||
/** The max number of Item dropped in one time during this Event */
|
||||
public int max;
|
||||
|
||||
/** The rate of drop for this Event */
|
||||
public int chance;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor of EventDroplist.<BR>
|
||||
* <BR>
|
||||
*/
|
||||
private EventDroplist()
|
||||
{
|
||||
_allNpcDateDrops = new FastList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and Init a new DateDrop then add it to the allNpcDateDrops of EventDroplist .<BR>
|
||||
* <BR>
|
||||
* @param items The table containing all item identifier of this DateDrop
|
||||
* @param count The table containing min and max value of this DateDrop
|
||||
* @param chance The chance to obtain this drop
|
||||
* @param range The DateRange object to add to this DateDrop
|
||||
*/
|
||||
public void addGlobalDrop(int[] items, int[] count, int chance, DateRange range)
|
||||
{
|
||||
|
||||
DateDrop date = new DateDrop();
|
||||
|
||||
date.dateRange = range;
|
||||
date.items = items;
|
||||
date.min = count[0];
|
||||
date.max = count[1];
|
||||
date.chance = chance;
|
||||
|
||||
_allNpcDateDrops.add(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all DateDrop of EventDroplist allNpcDateDrops within the date range.<BR>
|
||||
* <BR>
|
||||
*/
|
||||
public List<DateDrop> getAllDrops()
|
||||
{
|
||||
List<DateDrop> list = new FastList<>();
|
||||
|
||||
for (DateDrop drop : _allNpcDateDrops)
|
||||
{
|
||||
Date currentDate = new Date();
|
||||
// _log.info("From: "+drop.from+" To: "+drop.to+" Now: "+ currentDate);
|
||||
if (drop.dateRange.isWithinRange(currentDate))
|
||||
{
|
||||
list.add(drop);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final EventDroplist _instance = new EventDroplist();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.model.FishData;
|
||||
|
||||
/**
|
||||
* @author -Nemesiss-
|
||||
*/
|
||||
public class FishTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(FishTable.class.getName());
|
||||
|
||||
private static List<FishData> _fishsNormal;
|
||||
private static List<FishData> _fishsEasy;
|
||||
private static List<FishData> _fishsHard;
|
||||
|
||||
public static FishTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private FishTable()
|
||||
{
|
||||
// Create table that contains all fish datas
|
||||
int count = 0;
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
_fishsEasy = new FastList<>();
|
||||
_fishsNormal = new FastList<>();
|
||||
_fishsHard = new FastList<>();
|
||||
FishData fish;
|
||||
PreparedStatement statement = con.prepareStatement("SELECT id, level, name, hp, hpregen, fish_type, fish_group, fish_guts, guts_check_time, wait_time, combat_time FROM fish ORDER BY id");
|
||||
ResultSet fishes = statement.executeQuery();
|
||||
|
||||
while (fishes.next())
|
||||
{
|
||||
int id = fishes.getInt("id");
|
||||
int lvl = fishes.getInt("level");
|
||||
String name = fishes.getString("name");
|
||||
int hp = fishes.getInt("hp");
|
||||
int hpreg = fishes.getInt("hpregen");
|
||||
int type = fishes.getInt("fish_type");
|
||||
int group = fishes.getInt("fish_group");
|
||||
int fish_guts = fishes.getInt("fish_guts");
|
||||
int guts_check_time = fishes.getInt("guts_check_time");
|
||||
int wait_time = fishes.getInt("wait_time");
|
||||
int combat_time = fishes.getInt("combat_time");
|
||||
fish = new FishData(id, lvl, name, hp, hpreg, type, group, fish_guts, guts_check_time, wait_time, combat_time);
|
||||
switch (fish.getGroup())
|
||||
{
|
||||
case 0:
|
||||
_fishsEasy.add(fish);
|
||||
break;
|
||||
case 1:
|
||||
_fishsNormal.add(fish);
|
||||
break;
|
||||
case 2:
|
||||
_fishsHard.add(fish);
|
||||
}
|
||||
}
|
||||
fishes.close();
|
||||
statement.close();
|
||||
count = _fishsEasy.size() + _fishsNormal.size() + _fishsHard.size();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error while creating fish table" + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
_log.info("FishTable: Loaded " + count + " Fishes.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Fish - lvl
|
||||
* @param Fish - type
|
||||
* @param Fish - group
|
||||
* @return List of Fish that can be fished
|
||||
*/
|
||||
public List<FishData> getfish(int lvl, int type, int group)
|
||||
{
|
||||
List<FishData> result = new FastList<>();
|
||||
List<FishData> _Fishs = null;
|
||||
switch (group)
|
||||
{
|
||||
case 0:
|
||||
_Fishs = _fishsEasy;
|
||||
break;
|
||||
case 1:
|
||||
_Fishs = _fishsNormal;
|
||||
break;
|
||||
case 2:
|
||||
_Fishs = _fishsHard;
|
||||
}
|
||||
if (_Fishs == null)
|
||||
{
|
||||
// the fish list is empty
|
||||
_log.warning("Fish are not defined !");
|
||||
return null;
|
||||
}
|
||||
for (FishData f : _Fishs)
|
||||
{
|
||||
if (f.getLevel() != lvl)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (f.getType() != type)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result.add(f);
|
||||
}
|
||||
if (result.isEmpty())
|
||||
{
|
||||
_log.warning("Cant Find Any Fish!? - Lvl: " + lvl + " Type: " + type);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final FishTable _instance = new FishTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Skill;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* @author Gnacik
|
||||
*/
|
||||
public class GMSkillTable
|
||||
{
|
||||
private static final L2Skill[] _gmSkills = new L2Skill[34];
|
||||
private static final int[] _gmSkillsId =
|
||||
{
|
||||
7029,
|
||||
7041,
|
||||
7042,
|
||||
7043,
|
||||
7044,
|
||||
7045,
|
||||
7046,
|
||||
7047,
|
||||
7048,
|
||||
7049,
|
||||
7050,
|
||||
7051,
|
||||
7052,
|
||||
7053,
|
||||
7054,
|
||||
7055,
|
||||
7056,
|
||||
7057,
|
||||
7058,
|
||||
7059,
|
||||
7060,
|
||||
7061,
|
||||
7062,
|
||||
7063,
|
||||
7064,
|
||||
7088,
|
||||
7089,
|
||||
7090,
|
||||
7091,
|
||||
7092,
|
||||
7093,
|
||||
7094,
|
||||
7095,
|
||||
7096
|
||||
};
|
||||
|
||||
private GMSkillTable()
|
||||
{
|
||||
for (int i = 0; i < _gmSkillsId.length; i++)
|
||||
{
|
||||
_gmSkills[i] = SkillTable.getInstance().getInfo(_gmSkillsId[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static GMSkillTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
public static L2Skill[] getGMSkills()
|
||||
{
|
||||
return _gmSkills;
|
||||
}
|
||||
|
||||
public static boolean isGMSkill(int skillid)
|
||||
{
|
||||
for (int id : _gmSkillsId)
|
||||
{
|
||||
if (id == skillid)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addSkills(L2PcInstance gmchar)
|
||||
{
|
||||
for (L2Skill s : getGMSkills())
|
||||
{
|
||||
gmchar.addSkill(s, false); // Don't Save GM skills to database
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final GMSkillTable _instance = new GMSkillTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.templates.L2HelperBuff;
|
||||
import com.l2jserver.gameserver.templates.StatsSet;
|
||||
|
||||
/**
|
||||
* This class represents the Newbie Helper Buff list Author: Ayor
|
||||
*/
|
||||
|
||||
public class HelperBuffTable
|
||||
{
|
||||
|
||||
private static Logger _log = Logger.getLogger(HennaTable.class.getName());
|
||||
|
||||
/** The table containing all Buff of the Newbie Helper */
|
||||
private final List<L2HelperBuff> _helperBuff;
|
||||
|
||||
/**
|
||||
* The player level since Newbie Helper can give the fisrt buff <BR>
|
||||
* Used to generate message : "Come back here when you have reached level ...")
|
||||
*/
|
||||
private int _magicClassLowestLevel = 100;
|
||||
private int _physicClassLowestLevel = 100;
|
||||
|
||||
/**
|
||||
* The player level above which Newbie Helper won't give any buff <BR>
|
||||
* Used to generate message : "Only novice character of level ... or less can receive my support magic.")
|
||||
*/
|
||||
private int _magicClassHighestLevel = 1;
|
||||
private int _physicClassHighestLevel = 1;
|
||||
|
||||
private int _servitorLowestLevel = 100;
|
||||
|
||||
private int _servitorHighestLevel = 1;
|
||||
|
||||
public static HelperBuffTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and Load the Newbie Helper Buff list from SQL Table helper_buff_list
|
||||
*/
|
||||
private HelperBuffTable()
|
||||
{
|
||||
_helperBuff = new FastList<>();
|
||||
restoreHelperBuffData();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and Load the Newbie Helper Buff list from SQL Table helper_buff_list
|
||||
*/
|
||||
private void restoreHelperBuffData()
|
||||
{
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT * FROM helper_buff_list");
|
||||
ResultSet helperbuffdata = statement.executeQuery();
|
||||
|
||||
fillHelperBuffTable(helperbuffdata);
|
||||
helperbuffdata.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Table helper_buff_list not found : Update your DataPack! Error : " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the Newbie Helper Buff list from SQL Table helper_buff_list
|
||||
*/
|
||||
private void fillHelperBuffTable(ResultSet HelperBuffData) throws Exception
|
||||
{
|
||||
|
||||
while (HelperBuffData.next())
|
||||
{
|
||||
StatsSet helperBuffDat = new StatsSet();
|
||||
int id = HelperBuffData.getInt("id");
|
||||
|
||||
helperBuffDat.set("id", id);
|
||||
helperBuffDat.set("skillID", HelperBuffData.getInt("skill_id"));
|
||||
helperBuffDat.set("skillLevel", HelperBuffData.getInt("skill_level"));
|
||||
helperBuffDat.set("lowerLevel", HelperBuffData.getInt("lower_level"));
|
||||
helperBuffDat.set("upperLevel", HelperBuffData.getInt("upper_level"));
|
||||
helperBuffDat.set("isMagicClass", HelperBuffData.getString("is_magic_class"));
|
||||
helperBuffDat.set("forSummon", HelperBuffData.getString("forSummon"));
|
||||
|
||||
// Calulate the range level in wich player must be to obtain buff from Newbie Helper
|
||||
if ("false".equals(HelperBuffData.getString("is_magic_class")))
|
||||
{
|
||||
if (HelperBuffData.getInt("lower_level") < _physicClassLowestLevel)
|
||||
{
|
||||
_physicClassLowestLevel = HelperBuffData.getInt("lower_level");
|
||||
}
|
||||
|
||||
if (HelperBuffData.getInt("upper_level") > _physicClassHighestLevel)
|
||||
{
|
||||
_physicClassHighestLevel = HelperBuffData.getInt("upper_level");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (HelperBuffData.getInt("lower_level") < _magicClassLowestLevel)
|
||||
{
|
||||
_magicClassLowestLevel = HelperBuffData.getInt("lower_level");
|
||||
}
|
||||
|
||||
if (HelperBuffData.getInt("upper_level") > _magicClassHighestLevel)
|
||||
{
|
||||
_magicClassHighestLevel = HelperBuffData.getInt("upper_level");
|
||||
}
|
||||
}
|
||||
if ("true".equals(HelperBuffData.getString("forSummon")))
|
||||
{
|
||||
if (HelperBuffData.getInt("lower_level") < _servitorLowestLevel)
|
||||
{
|
||||
_servitorLowestLevel = HelperBuffData.getInt("lower_level");
|
||||
}
|
||||
|
||||
if (HelperBuffData.getInt("upper_level") > _servitorHighestLevel)
|
||||
{
|
||||
_servitorHighestLevel = HelperBuffData.getInt("upper_level");
|
||||
}
|
||||
}
|
||||
// Add this Helper Buff to the Helper Buff List
|
||||
L2HelperBuff template = new L2HelperBuff(helperBuffDat);
|
||||
_helperBuff.add(template);
|
||||
}
|
||||
|
||||
_log.info("Helper Buff Table: Loaded " + _helperBuff.size() + " Templates.");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Helper Buff List
|
||||
*/
|
||||
public List<L2HelperBuff> getHelperBuffTable()
|
||||
{
|
||||
return _helperBuff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the magicClassHighestLevel.
|
||||
*/
|
||||
public int getMagicClassHighestLevel()
|
||||
{
|
||||
return _magicClassHighestLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the magicClassLowestLevel.
|
||||
*/
|
||||
public int getMagicClassLowestLevel()
|
||||
{
|
||||
return _magicClassLowestLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the physicClassHighestLevel.
|
||||
*/
|
||||
public int getPhysicClassHighestLevel()
|
||||
{
|
||||
return _physicClassHighestLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the physicClassLowestLevel.
|
||||
*/
|
||||
public int getPhysicClassLowestLevel()
|
||||
{
|
||||
return _physicClassLowestLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the servitorLowestLevel.
|
||||
*/
|
||||
public int getServitorLowestLevel()
|
||||
{
|
||||
return _servitorLowestLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the servitorHighestLevel.
|
||||
*/
|
||||
public int getServitorHighestLevel()
|
||||
{
|
||||
return _servitorHighestLevel;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final HelperBuffTable _instance = new HelperBuffTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.templates.StatsSet;
|
||||
import com.l2jserver.gameserver.templates.item.L2Henna;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public class HennaTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(HennaTable.class.getName());
|
||||
|
||||
private final TIntObjectHashMap<L2Henna> _henna;
|
||||
|
||||
public static HennaTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private HennaTable()
|
||||
{
|
||||
_henna = new TIntObjectHashMap<>();
|
||||
restoreHennaData();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void restoreHennaData()
|
||||
{
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT symbol_id, symbol_name, dye_id, dye_amount, price, stat_INT, stat_STR, stat_CON, stat_MEM, stat_DEX, stat_WIT FROM henna");
|
||||
ResultSet hennadata = statement.executeQuery();
|
||||
|
||||
fillHennaTable(hennadata);
|
||||
hennadata.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error while creating henna table " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
|
||||
private void fillHennaTable(ResultSet HennaData) throws Exception
|
||||
{
|
||||
while (HennaData.next())
|
||||
{
|
||||
StatsSet hennaDat = new StatsSet();
|
||||
int id = HennaData.getInt("symbol_id");
|
||||
|
||||
hennaDat.set("symbol_id", id);
|
||||
hennaDat.set("dye", HennaData.getInt("dye_id"));
|
||||
hennaDat.set("price", HennaData.getInt("price"));
|
||||
// amount of dye required
|
||||
hennaDat.set("amount", HennaData.getInt("dye_amount"));
|
||||
hennaDat.set("stat_INT", HennaData.getInt("stat_INT"));
|
||||
hennaDat.set("stat_STR", HennaData.getInt("stat_STR"));
|
||||
hennaDat.set("stat_CON", HennaData.getInt("stat_CON"));
|
||||
hennaDat.set("stat_MEM", HennaData.getInt("stat_MEM"));
|
||||
hennaDat.set("stat_DEX", HennaData.getInt("stat_DEX"));
|
||||
hennaDat.set("stat_WIT", HennaData.getInt("stat_WIT"));
|
||||
|
||||
L2Henna template = new L2Henna(hennaDat);
|
||||
_henna.put(id, template);
|
||||
}
|
||||
_log.info("HennaTable: Loaded " + _henna.size() + " Templates.");
|
||||
}
|
||||
|
||||
public L2Henna getTemplate(int id)
|
||||
{
|
||||
return _henna.get(id);
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final HennaTable _instance = new HennaTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javolution.util.FastList;
|
||||
import javolution.util.FastMap;
|
||||
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.model.L2HennaInstance;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
import com.l2jserver.gameserver.templates.item.L2Henna;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public class HennaTreeTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(HennaTreeTable.class.getName());
|
||||
private Map<ClassId, List<L2HennaInstance>> _hennaTrees;
|
||||
private final boolean _initialized = true;
|
||||
|
||||
public static HennaTreeTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private HennaTreeTable()
|
||||
{
|
||||
_hennaTrees = new FastMap<>();
|
||||
int classId = 0;
|
||||
int count = 0;
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT class_name, id, parent_id FROM class_list ORDER BY id");
|
||||
ResultSet classlist = statement.executeQuery();
|
||||
List<L2HennaInstance> list;
|
||||
// int parentClassId;
|
||||
// L2Henna henna;
|
||||
PreparedStatement statement2 = con.prepareStatement("SELECT class_id, symbol_id FROM henna_trees where class_id=? ORDER BY symbol_id");
|
||||
while (classlist.next())
|
||||
{
|
||||
list = new FastList<>();
|
||||
classId = classlist.getInt("id");
|
||||
|
||||
statement2.setInt(1, classId);
|
||||
ResultSet hennatree = statement2.executeQuery();
|
||||
statement2.clearParameters();
|
||||
while (hennatree.next())
|
||||
{
|
||||
int id = hennatree.getInt("symbol_id");
|
||||
// String name = hennatree.getString("name");
|
||||
L2Henna template = HennaTable.getInstance().getTemplate(id);
|
||||
if (template == null)
|
||||
{
|
||||
hennatree.close();
|
||||
statement2.close();
|
||||
classlist.close();
|
||||
statement.close();
|
||||
return;
|
||||
}
|
||||
L2HennaInstance temp = new L2HennaInstance(template);
|
||||
temp.setSymbolId(id);
|
||||
temp.setItemIdDye(template.getDyeId());
|
||||
temp.setAmountDyeRequire(template.getAmountDyeRequire());
|
||||
temp.setPrice(template.getPrice());
|
||||
temp.setStatINT(template.getStatINT());
|
||||
temp.setStatSTR(template.getStatSTR());
|
||||
temp.setStatCON(template.getStatCON());
|
||||
temp.setStatMEM(template.getStatMEM());
|
||||
temp.setStatDEX(template.getStatDEX());
|
||||
temp.setStatWIT(template.getStatWIT());
|
||||
|
||||
list.add(temp);
|
||||
}
|
||||
_hennaTrees.put(ClassId.values()[classId], list);
|
||||
hennatree.close();
|
||||
count += list.size();
|
||||
_log.fine("Henna Tree for Class: " + classId + " has " + list.size() + " Henna Templates.");
|
||||
}
|
||||
|
||||
classlist.close();
|
||||
statement.close();
|
||||
statement2.close();
|
||||
|
||||
_log.info("HennaTreeTable: Loaded " + count + " Henna Tree Templates.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error loading Henna Tree Table.", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
|
||||
public L2HennaInstance[] getAvailableHenna(ClassId classId)
|
||||
{
|
||||
List<L2HennaInstance> result = new FastList<>();
|
||||
List<L2HennaInstance> henna = _hennaTrees.get(classId);
|
||||
if (henna == null)
|
||||
{
|
||||
// the hennatree for this class is undefined, so we give an empty list
|
||||
_log.warning("Hennatree for class " + classId + " is not defined !");
|
||||
return new L2HennaInstance[0];
|
||||
}
|
||||
|
||||
for (L2HennaInstance temp : henna)
|
||||
{
|
||||
result.add(temp);
|
||||
}
|
||||
|
||||
return result.toArray(new L2HennaInstance[result.size()]);
|
||||
}
|
||||
|
||||
public boolean isInitialized()
|
||||
{
|
||||
return _initialized;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final HennaTreeTable _instance = new HennaTreeTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.model.L2DropCategory;
|
||||
import com.l2jserver.gameserver.model.L2DropData;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision$ $Date$
|
||||
*/
|
||||
public class HerbDropTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(HerbDropTable.class.getName());
|
||||
|
||||
private final TIntObjectHashMap<FastList<L2DropCategory>> _herbGroups;
|
||||
|
||||
public static HerbDropTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private HerbDropTable()
|
||||
{
|
||||
_herbGroups = new TIntObjectHashMap<>();
|
||||
restoreData();
|
||||
}
|
||||
|
||||
private void restoreData()
|
||||
{
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT " + L2DatabaseFactory.getInstance().safetyString(new String[]
|
||||
{
|
||||
"groupId",
|
||||
"itemId",
|
||||
"min",
|
||||
"max",
|
||||
"category",
|
||||
"chance"
|
||||
}) + " FROM herb_droplist_groups ORDER BY groupId, chance DESC");
|
||||
ResultSet dropData = statement.executeQuery();
|
||||
L2DropData dropDat = null;
|
||||
|
||||
while (dropData.next())
|
||||
{
|
||||
int groupId = dropData.getInt("groupId");
|
||||
FastList<L2DropCategory> category;
|
||||
if (_herbGroups.contains(groupId))
|
||||
{
|
||||
category = _herbGroups.get(groupId);
|
||||
}
|
||||
else
|
||||
{
|
||||
category = new FastList<>();
|
||||
_herbGroups.put(groupId, category);
|
||||
}
|
||||
|
||||
dropDat = new L2DropData();
|
||||
|
||||
dropDat.setItemId(dropData.getInt("itemId"));
|
||||
dropDat.setMinDrop(dropData.getInt("min"));
|
||||
dropDat.setMaxDrop(dropData.getInt("max"));
|
||||
dropDat.setChance(dropData.getInt("chance"));
|
||||
|
||||
int categoryType = dropData.getInt("category");
|
||||
|
||||
if (ItemTable.getInstance().getTemplate(dropDat.getItemId()) == null)
|
||||
{
|
||||
_log.warning("Herb Drop data for undefined item template! GroupId: " + groupId + " itemId: " + dropDat.getItemId());
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean catExists = false;
|
||||
for (L2DropCategory cat : category)
|
||||
{
|
||||
// if the category exists, add the drop to this category.
|
||||
if (cat.getCategoryType() == categoryType)
|
||||
{
|
||||
cat.addDropData(dropDat, false);
|
||||
catExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if the category doesn't exit, create it and add the drop
|
||||
if (!catExists)
|
||||
{
|
||||
L2DropCategory cat = new L2DropCategory(categoryType);
|
||||
cat.addDropData(dropDat, false);
|
||||
category.add(cat);
|
||||
}
|
||||
}
|
||||
|
||||
dropData.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "HerbDroplistGroupsTable: Error reading Herb dropdata. ", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
|
||||
public FastList<L2DropCategory> getHerbDroplist(int groupId)
|
||||
{
|
||||
return _herbGroups.get(groupId);
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final HerbDropTable _instance = new HerbDropTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Skill;
|
||||
|
||||
/**
|
||||
* @author BiTi
|
||||
*/
|
||||
public class HeroSkillTable
|
||||
{
|
||||
private static final L2Skill[] _heroSkills = new L2Skill[5];
|
||||
private static final int[] _heroSkillsId =
|
||||
{
|
||||
395,
|
||||
396,
|
||||
1374,
|
||||
1375,
|
||||
1376
|
||||
};
|
||||
|
||||
private HeroSkillTable()
|
||||
{
|
||||
for (int i = 0; i < _heroSkillsId.length; i++)
|
||||
{
|
||||
_heroSkills[i] = SkillTable.getInstance().getInfo(_heroSkillsId[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static HeroSkillTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
public static L2Skill[] getHeroSkills()
|
||||
{
|
||||
return _heroSkills;
|
||||
}
|
||||
|
||||
public static boolean isHeroSkill(int skillid)
|
||||
{
|
||||
/*
|
||||
* Do not perform checks directly on L2Skill array, it will cause errors due to SkillTable not initialized
|
||||
*/
|
||||
for (int id : _heroSkillsId)
|
||||
{
|
||||
if (id == skillid)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final HeroSkillTable _instance = new HeroSkillTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,511 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import static com.l2jserver.gameserver.model.itemcontainer.PcInventory.ADENA_ID;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.Item;
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.idfactory.IdFactory;
|
||||
import com.l2jserver.gameserver.model.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.model.L2ItemInstance.ItemLocation;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.L2World;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2EventMonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.skills.SkillsEngine;
|
||||
import com.l2jserver.gameserver.templates.item.L2Armor;
|
||||
import com.l2jserver.gameserver.templates.item.L2ArmorType;
|
||||
import com.l2jserver.gameserver.templates.item.L2EtcItem;
|
||||
import com.l2jserver.gameserver.templates.item.L2Item;
|
||||
import com.l2jserver.gameserver.templates.item.L2Weapon;
|
||||
import com.l2jserver.gameserver.templates.item.L2WeaponType;
|
||||
import com.l2jserver.gameserver.util.GMAudit;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision: 1.9.2.6.2.9 $ $Date: 2005/04/02 15:57:34 $
|
||||
*/
|
||||
public class ItemTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(ItemTable.class.getName());
|
||||
private static Logger _logItems = Logger.getLogger("item");
|
||||
|
||||
public static final Map<String, Integer> _materials = new FastMap<>();
|
||||
public static final Map<String, Integer> _crystalTypes = new FastMap<>();
|
||||
public static final Map<String, Integer> _slots = new FastMap<>();
|
||||
public static final Map<String, L2WeaponType> _weaponTypes = new FastMap<>();
|
||||
public static final Map<String, L2ArmorType> _armorTypes = new FastMap<>();
|
||||
|
||||
private L2Item[] _allTemplates;
|
||||
private final Map<Integer, L2EtcItem> _etcItems;
|
||||
private final Map<Integer, L2Armor> _armors;
|
||||
private final Map<Integer, L2Weapon> _weapons;
|
||||
|
||||
static
|
||||
{
|
||||
_materials.put("adamantaite", L2Item.MATERIAL_ADAMANTAITE);
|
||||
_materials.put("blood_steel", L2Item.MATERIAL_BLOOD_STEEL);
|
||||
_materials.put("bone", L2Item.MATERIAL_BONE);
|
||||
_materials.put("bronze", L2Item.MATERIAL_BRONZE);
|
||||
_materials.put("cloth", L2Item.MATERIAL_CLOTH);
|
||||
_materials.put("chrysolite", L2Item.MATERIAL_CHRYSOLITE);
|
||||
_materials.put("cobweb", L2Item.MATERIAL_COBWEB);
|
||||
_materials.put("cotton", L2Item.MATERIAL_FINE_STEEL);
|
||||
_materials.put("crystal", L2Item.MATERIAL_CRYSTAL);
|
||||
_materials.put("damascus", L2Item.MATERIAL_DAMASCUS);
|
||||
_materials.put("dyestuff", L2Item.MATERIAL_DYESTUFF);
|
||||
_materials.put("fine_steel", L2Item.MATERIAL_FINE_STEEL);
|
||||
_materials.put("fish", L2Item.MATERIAL_FISH);
|
||||
_materials.put("gold", L2Item.MATERIAL_GOLD);
|
||||
_materials.put("horn", L2Item.MATERIAL_HORN);
|
||||
_materials.put("leather", L2Item.MATERIAL_LEATHER);
|
||||
_materials.put("liquid", L2Item.MATERIAL_LIQUID);
|
||||
_materials.put("mithril", L2Item.MATERIAL_MITHRIL);
|
||||
_materials.put("oriharukon", L2Item.MATERIAL_ORIHARUKON);
|
||||
_materials.put("paper", L2Item.MATERIAL_PAPER);
|
||||
_materials.put("rune_xp", L2Item.MATERIAL_RUNE_XP);
|
||||
_materials.put("rune_sp", L2Item.MATERIAL_RUNE_SP);
|
||||
_materials.put("rune_remove_penalty", L2Item.MATERIAL_RUNE_PENALTY);
|
||||
_materials.put("scale_of_dragon", L2Item.MATERIAL_SCALE_OF_DRAGON);
|
||||
_materials.put("seed", L2Item.MATERIAL_SEED);
|
||||
_materials.put("silver", L2Item.MATERIAL_SILVER);
|
||||
_materials.put("steel", L2Item.MATERIAL_STEEL);
|
||||
_materials.put("wood", L2Item.MATERIAL_WOOD);
|
||||
|
||||
_crystalTypes.put("s84", L2Item.CRYSTAL_S84);
|
||||
_crystalTypes.put("s80", L2Item.CRYSTAL_S80);
|
||||
_crystalTypes.put("s", L2Item.CRYSTAL_S);
|
||||
_crystalTypes.put("a", L2Item.CRYSTAL_A);
|
||||
_crystalTypes.put("b", L2Item.CRYSTAL_B);
|
||||
_crystalTypes.put("c", L2Item.CRYSTAL_C);
|
||||
_crystalTypes.put("d", L2Item.CRYSTAL_D);
|
||||
_crystalTypes.put("none", L2Item.CRYSTAL_NONE);
|
||||
|
||||
// weapon types
|
||||
for (L2WeaponType type : L2WeaponType.values())
|
||||
{
|
||||
_weaponTypes.put(type.toString(), type);
|
||||
}
|
||||
|
||||
// armor types
|
||||
for (L2ArmorType type : L2ArmorType.values())
|
||||
{
|
||||
_armorTypes.put(type.toString(), type);
|
||||
}
|
||||
|
||||
_slots.put("shirt", L2Item.SLOT_UNDERWEAR);
|
||||
_slots.put("lbracelet", L2Item.SLOT_L_BRACELET);
|
||||
_slots.put("rbracelet", L2Item.SLOT_R_BRACELET);
|
||||
_slots.put("talisman", L2Item.SLOT_DECO);
|
||||
_slots.put("chest", L2Item.SLOT_CHEST);
|
||||
_slots.put("fullarmor", L2Item.SLOT_FULL_ARMOR);
|
||||
_slots.put("head", L2Item.SLOT_HEAD);
|
||||
_slots.put("hair", L2Item.SLOT_HAIR);
|
||||
_slots.put("hairall", L2Item.SLOT_HAIRALL);
|
||||
_slots.put("underwear", L2Item.SLOT_UNDERWEAR);
|
||||
_slots.put("back", L2Item.SLOT_BACK);
|
||||
_slots.put("neck", L2Item.SLOT_NECK);
|
||||
_slots.put("legs", L2Item.SLOT_LEGS);
|
||||
_slots.put("feet", L2Item.SLOT_FEET);
|
||||
_slots.put("gloves", L2Item.SLOT_GLOVES);
|
||||
_slots.put("chest,legs", L2Item.SLOT_CHEST | L2Item.SLOT_LEGS);
|
||||
_slots.put("belt", L2Item.SLOT_BELT);
|
||||
_slots.put("rhand", L2Item.SLOT_R_HAND);
|
||||
_slots.put("lhand", L2Item.SLOT_L_HAND);
|
||||
_slots.put("lrhand", L2Item.SLOT_LR_HAND);
|
||||
_slots.put("rear;lear", L2Item.SLOT_R_EAR | L2Item.SLOT_L_EAR);
|
||||
_slots.put("rfinger;lfinger", L2Item.SLOT_R_FINGER | L2Item.SLOT_L_FINGER);
|
||||
_slots.put("wolf", L2Item.SLOT_WOLF);
|
||||
_slots.put("greatwolf", L2Item.SLOT_GREATWOLF);
|
||||
_slots.put("hatchling", L2Item.SLOT_HATCHLING);
|
||||
_slots.put("strider", L2Item.SLOT_STRIDER);
|
||||
_slots.put("babypet", L2Item.SLOT_BABYPET);
|
||||
_slots.put("none", L2Item.SLOT_NONE);
|
||||
|
||||
// retail compatibility
|
||||
_slots.put("onepiece", L2Item.SLOT_FULL_ARMOR);
|
||||
_slots.put("hair2", L2Item.SLOT_HAIR2);
|
||||
_slots.put("dhair", L2Item.SLOT_HAIRALL);
|
||||
_slots.put("alldress", L2Item.SLOT_ALLDRESS);
|
||||
_slots.put("deco1", L2Item.SLOT_DECO);
|
||||
_slots.put("waist", L2Item.SLOT_BELT);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns instance of ItemTable
|
||||
* @return ItemTable
|
||||
*/
|
||||
public static ItemTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new object Item
|
||||
* @return
|
||||
*/
|
||||
public Item newItem()
|
||||
{
|
||||
return new Item();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
private ItemTable()
|
||||
{
|
||||
_etcItems = new FastMap<>();
|
||||
_armors = new FastMap<>();
|
||||
_weapons = new FastMap<>();
|
||||
load();
|
||||
}
|
||||
|
||||
private void load()
|
||||
{
|
||||
int highest = 0;
|
||||
_armors.clear();
|
||||
_etcItems.clear();
|
||||
_weapons.clear();
|
||||
for (L2Item item : SkillsEngine.getInstance().loadItems())
|
||||
{
|
||||
if (highest < item.getItemId())
|
||||
{
|
||||
highest = item.getItemId();
|
||||
}
|
||||
if (item instanceof L2EtcItem)
|
||||
{
|
||||
_etcItems.put(item.getItemId(), (L2EtcItem) item);
|
||||
}
|
||||
else if (item instanceof L2Armor)
|
||||
{
|
||||
_armors.put(item.getItemId(), (L2Armor) item);
|
||||
}
|
||||
else
|
||||
{
|
||||
_weapons.put(item.getItemId(), (L2Weapon) item);
|
||||
}
|
||||
}
|
||||
buildFastLookupTable(highest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a variable in which all items are putting in in function of their ID.
|
||||
*/
|
||||
private void buildFastLookupTable(int size)
|
||||
{
|
||||
// Create a FastLookUp Table called _allTemplates of size : value of the highest item ID
|
||||
_log.info("Highest item id used:" + size);
|
||||
_allTemplates = new L2Item[size + 1];
|
||||
|
||||
// Insert armor item in Fast Look Up Table
|
||||
for (L2Armor item : _armors.values())
|
||||
{
|
||||
_allTemplates[item.getItemId()] = item;
|
||||
}
|
||||
|
||||
// Insert weapon item in Fast Look Up Table
|
||||
for (L2Weapon item : _weapons.values())
|
||||
{
|
||||
_allTemplates[item.getItemId()] = item;
|
||||
}
|
||||
|
||||
// Insert etcItem item in Fast Look Up Table
|
||||
for (L2EtcItem item : _etcItems.values())
|
||||
{
|
||||
_allTemplates[item.getItemId()] = item;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the item corresponding to the item ID
|
||||
* @param id : int designating the item
|
||||
* @return L2Item
|
||||
*/
|
||||
public L2Item getTemplate(int id)
|
||||
{
|
||||
if (id >= _allTemplates.length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return _allTemplates[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the L2ItemInstance corresponding to the Item Identifier and quantitiy add logs the activity.<BR>
|
||||
* <BR>
|
||||
* <B><U> Actions</U> :</B><BR>
|
||||
* <BR>
|
||||
* <li>Create and Init the L2ItemInstance corresponding to the Item Identifier and quantity</li> <li>Add the L2ItemInstance object to _allObjects of L2world</li> <li>Logs Item creation according to log settings</li><BR>
|
||||
* <BR>
|
||||
* @param process : String Identifier of process triggering this action
|
||||
* @param itemId : int Item Identifier of the item to be created
|
||||
* @param count : int Quantity of items to be created for stackable items
|
||||
* @param actor : L2PcInstance Player requesting the item creation
|
||||
* @param reference : Object Object referencing current action like NPC selling item or previous item in transformation
|
||||
* @return L2ItemInstance corresponding to the new item
|
||||
*/
|
||||
public L2ItemInstance createItem(String process, int itemId, long count, L2PcInstance actor, Object reference)
|
||||
{
|
||||
// Create and Init the L2ItemInstance corresponding to the Item Identifier
|
||||
L2ItemInstance item = new L2ItemInstance(IdFactory.getInstance().getNextId(), itemId);
|
||||
|
||||
if (process.equalsIgnoreCase("loot"))
|
||||
{
|
||||
ScheduledFuture<?> itemLootShedule;
|
||||
if ((reference instanceof L2Attackable) && ((L2Attackable) reference).isRaid()) // loot privilege for raids
|
||||
{
|
||||
L2Attackable raid = (L2Attackable) reference;
|
||||
// if in CommandChannel and was killing a World/RaidBoss
|
||||
if ((raid.getFirstCommandChannelAttacked() != null) && !Config.AUTO_LOOT_RAIDS)
|
||||
{
|
||||
item.setOwnerId(raid.getFirstCommandChannelAttacked().getChannelLeader().getObjectId());
|
||||
itemLootShedule = ThreadPoolManager.getInstance().scheduleGeneral(new ResetOwner(item), Config.LOOT_RAIDS_PRIVILEGE_INTERVAL);
|
||||
item.setItemLootShedule(itemLootShedule);
|
||||
}
|
||||
}
|
||||
else if (!Config.AUTO_LOOT || ((reference instanceof L2EventMonsterInstance) && ((L2EventMonsterInstance) reference).eventDropOnGround()))
|
||||
{
|
||||
item.setOwnerId(actor.getObjectId());
|
||||
itemLootShedule = ThreadPoolManager.getInstance().scheduleGeneral(new ResetOwner(item), 15000);
|
||||
item.setItemLootShedule(itemLootShedule);
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.fine("ItemTable: Item created oid:" + item.getObjectId() + " itemid:" + itemId);
|
||||
}
|
||||
|
||||
// Add the L2ItemInstance object to _allObjects of L2world
|
||||
L2World.getInstance().storeObject(item);
|
||||
|
||||
// Set Item parameters
|
||||
if (item.isStackable() && (count > 1))
|
||||
{
|
||||
item.setCount(count);
|
||||
}
|
||||
|
||||
if (Config.LOG_ITEMS && !process.equals("Reset"))
|
||||
{
|
||||
if (!Config.LOG_ITEMS_SMALL_LOG || (Config.LOG_ITEMS_SMALL_LOG && (item.isEquipable() || (item.getItemId() == ADENA_ID))))
|
||||
{
|
||||
LogRecord record = new LogRecord(Level.INFO, "CREATE:" + process);
|
||||
record.setLoggerName("item");
|
||||
record.setParameters(new Object[]
|
||||
{
|
||||
item,
|
||||
actor,
|
||||
reference
|
||||
});
|
||||
_logItems.log(record);
|
||||
}
|
||||
}
|
||||
|
||||
if (actor != null)
|
||||
{
|
||||
if (actor.isGM())
|
||||
{
|
||||
String referenceName = "no-reference";
|
||||
if (reference instanceof L2Object)
|
||||
{
|
||||
referenceName = (((L2Object) reference).getName() != null ? ((L2Object) reference).getName() : "no-name");
|
||||
}
|
||||
else if (reference instanceof String)
|
||||
{
|
||||
referenceName = (String) reference;
|
||||
}
|
||||
String targetName = (actor.getTarget() != null ? actor.getTarget().getName() : "no-target");
|
||||
if (Config.GMAUDIT)
|
||||
{
|
||||
GMAudit.auditGMAction(actor.getName() + " [" + actor.getObjectId() + "]", process + "(id: " + itemId + " count: " + count + " name: " + item.getItemName() + " objId: " + item.getObjectId() + ")", targetName, "L2Object referencing this action is: " + referenceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public L2ItemInstance createItem(String process, int itemId, int count, L2PcInstance actor)
|
||||
{
|
||||
return createItem(process, itemId, count, actor, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a dummy (fr = factice) item.<BR>
|
||||
* <BR>
|
||||
* <U><I>Concept :</I></U><BR>
|
||||
* Dummy item is created by setting the ID of the object in the world at null value
|
||||
* @param itemId : int designating the item
|
||||
* @return L2ItemInstance designating the dummy item created
|
||||
*/
|
||||
public L2ItemInstance createDummyItem(int itemId)
|
||||
{
|
||||
L2Item item = getTemplate(itemId);
|
||||
if (item == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
L2ItemInstance temp = new L2ItemInstance(0, item);
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the L2ItemInstance.<BR>
|
||||
* <BR>
|
||||
* <B><U> Actions</U> :</B><BR>
|
||||
* <BR>
|
||||
* <li>Sets L2ItemInstance parameters to be unusable</li> <li>Removes the L2ItemInstance object to _allObjects of L2world</li> <li>Logs Item delettion according to log settings</li><BR>
|
||||
* <BR>
|
||||
* @param process : String Identifier of process triggering this action
|
||||
* @param itemId : int Item Identifier of the item to be created
|
||||
* @param actor : L2PcInstance Player requesting the item destroy
|
||||
* @param reference : Object Object referencing current action like NPC selling item or previous item in transformation
|
||||
*/
|
||||
public void destroyItem(String process, L2ItemInstance item, L2PcInstance actor, Object reference)
|
||||
{
|
||||
synchronized (item)
|
||||
{
|
||||
long old = item.getCount();
|
||||
item.setCount(0);
|
||||
item.setOwnerId(0);
|
||||
item.setLocation(ItemLocation.VOID);
|
||||
item.setLastChange(L2ItemInstance.REMOVED);
|
||||
|
||||
L2World.getInstance().removeObject(item);
|
||||
IdFactory.getInstance().releaseId(item.getObjectId());
|
||||
|
||||
if (Config.LOG_ITEMS)
|
||||
{
|
||||
if (!Config.LOG_ITEMS_SMALL_LOG || (Config.LOG_ITEMS_SMALL_LOG && (item.isEquipable() || (item.getItemId() == ADENA_ID))))
|
||||
{
|
||||
LogRecord record = new LogRecord(Level.INFO, "DELETE:" + process);
|
||||
record.setLoggerName("item");
|
||||
record.setParameters(new Object[]
|
||||
{
|
||||
item,
|
||||
"PrevCount(" + old + ")",
|
||||
actor,
|
||||
reference
|
||||
});
|
||||
_logItems.log(record);
|
||||
}
|
||||
}
|
||||
|
||||
if (actor != null)
|
||||
{
|
||||
if (actor.isGM())
|
||||
{
|
||||
String referenceName = "no-reference";
|
||||
if (reference instanceof L2Object)
|
||||
{
|
||||
referenceName = (((L2Object) reference).getName() != null ? ((L2Object) reference).getName() : "no-name");
|
||||
}
|
||||
else if (reference instanceof String)
|
||||
{
|
||||
referenceName = (String) reference;
|
||||
}
|
||||
String targetName = (actor.getTarget() != null ? actor.getTarget().getName() : "no-target");
|
||||
if (Config.GMAUDIT)
|
||||
{
|
||||
GMAudit.auditGMAction(actor.getName() + " [" + actor.getObjectId() + "]", process + "(id: " + item.getItemId() + " count: " + item.getCount() + " itemObjId: " + item.getObjectId() + ")", targetName, "L2Object referencing this action is: " + referenceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if it's a pet control item, delete the pet as well
|
||||
if (PetDataTable.isPetItem(item.getItemId()))
|
||||
{
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
// Delete the pet in db
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("DELETE FROM pets WHERE item_obj_id=?");
|
||||
statement.setInt(1, item.getObjectId());
|
||||
statement.execute();
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "could not delete pet objectid:", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void reload()
|
||||
{
|
||||
load();
|
||||
EnchantHPBonusData.getInstance().reload();
|
||||
}
|
||||
|
||||
protected static class ResetOwner implements Runnable
|
||||
{
|
||||
L2ItemInstance _item;
|
||||
|
||||
public ResetOwner(L2ItemInstance item)
|
||||
{
|
||||
_item = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
_item.setOwnerId(0);
|
||||
_item.setItemLootShedule(null);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<Integer> getAllArmorsId()
|
||||
{
|
||||
return _armors.keySet();
|
||||
}
|
||||
|
||||
public Set<Integer> getAllWeaponsId()
|
||||
{
|
||||
return _weapons.keySet();
|
||||
}
|
||||
|
||||
public int getArraySize()
|
||||
{
|
||||
return _allTemplates.length;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final ItemTable _instance = new ItemTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.model.L2LvlupData;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @author NightMarez
|
||||
* @version $Revision: 1.3.2.4.2.3 $ $Date: 2005/03/27 15:29:18 $
|
||||
*/
|
||||
public class LevelUpData
|
||||
{
|
||||
private static final String SELECT_ALL = "SELECT classid, defaulthpbase, defaulthpadd, defaulthpmod, defaultcpbase, defaultcpadd, defaultcpmod, defaultmpbase, defaultmpadd, defaultmpmod, class_lvl FROM lvlupgain";
|
||||
private static final String CLASS_LVL = "class_lvl";
|
||||
private static final String MP_MOD = "defaultmpmod";
|
||||
private static final String MP_ADD = "defaultmpadd";
|
||||
private static final String MP_BASE = "defaultmpbase";
|
||||
private static final String HP_MOD = "defaulthpmod";
|
||||
private static final String HP_ADD = "defaulthpadd";
|
||||
private static final String HP_BASE = "defaulthpbase";
|
||||
private static final String CP_MOD = "defaultcpmod";
|
||||
private static final String CP_ADD = "defaultcpadd";
|
||||
private static final String CP_BASE = "defaultcpbase";
|
||||
private static final String CLASS_ID = "classid";
|
||||
|
||||
private static Logger _log = Logger.getLogger(LevelUpData.class.getName());
|
||||
|
||||
private final TIntObjectHashMap<L2LvlupData> _lvlTable;
|
||||
|
||||
public static LevelUpData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private LevelUpData()
|
||||
{
|
||||
_lvlTable = new TIntObjectHashMap<>();
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement(SELECT_ALL);
|
||||
ResultSet rset = statement.executeQuery();
|
||||
L2LvlupData lvlDat;
|
||||
|
||||
while (rset.next())
|
||||
{
|
||||
lvlDat = new L2LvlupData();
|
||||
lvlDat.setClassid(rset.getInt(CLASS_ID));
|
||||
lvlDat.setClassLvl(rset.getInt(CLASS_LVL));
|
||||
lvlDat.setClassHpBase(rset.getFloat(HP_BASE));
|
||||
lvlDat.setClassHpAdd(rset.getFloat(HP_ADD));
|
||||
lvlDat.setClassHpModifier(rset.getFloat(HP_MOD));
|
||||
lvlDat.setClassCpBase(rset.getFloat(CP_BASE));
|
||||
lvlDat.setClassCpAdd(rset.getFloat(CP_ADD));
|
||||
lvlDat.setClassCpModifier(rset.getFloat(CP_MOD));
|
||||
lvlDat.setClassMpBase(rset.getFloat(MP_BASE));
|
||||
lvlDat.setClassMpAdd(rset.getFloat(MP_ADD));
|
||||
lvlDat.setClassMpModifier(rset.getFloat(MP_MOD));
|
||||
|
||||
_lvlTable.put(lvlDat.getClassid(), lvlDat);
|
||||
}
|
||||
|
||||
rset.close();
|
||||
statement.close();
|
||||
|
||||
_log.info("LevelUpData: Loaded " + _lvlTable.size() + " Character Level Up Templates.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error loading Level Up data.", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param template id
|
||||
* @return
|
||||
*/
|
||||
public L2LvlupData getTemplate(int classId)
|
||||
{
|
||||
return _lvlTable.get(classId);
|
||||
}
|
||||
|
||||
public L2LvlupData getTemplate(ClassId classId)
|
||||
{
|
||||
return _lvlTable.get(classId.getId());
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final LevelUpData _instance = new LevelUpData();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,543 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.SevenSigns;
|
||||
import com.l2jserver.gameserver.instancemanager.CastleManager;
|
||||
import com.l2jserver.gameserver.instancemanager.ClanHallManager;
|
||||
import com.l2jserver.gameserver.instancemanager.FortManager;
|
||||
import com.l2jserver.gameserver.instancemanager.InstanceManager;
|
||||
import com.l2jserver.gameserver.instancemanager.TerritoryWarManager;
|
||||
import com.l2jserver.gameserver.instancemanager.TownManager;
|
||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2SiegeFlagInstance;
|
||||
import com.l2jserver.gameserver.model.entity.Castle;
|
||||
import com.l2jserver.gameserver.model.entity.ClanHall;
|
||||
import com.l2jserver.gameserver.model.entity.Fort;
|
||||
import com.l2jserver.gameserver.model.entity.Instance;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2ArenaZone;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2ClanHallZone;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
*/
|
||||
public class MapRegionTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(MapRegionTable.class.getName());
|
||||
|
||||
private final int[][] _regions = new int[16][18];
|
||||
|
||||
public static enum TeleportWhereType
|
||||
{
|
||||
Castle,
|
||||
ClanHall,
|
||||
SiegeFlag,
|
||||
Town,
|
||||
Fortress
|
||||
}
|
||||
|
||||
public static MapRegionTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private MapRegionTable()
|
||||
{
|
||||
int count2 = 0;
|
||||
|
||||
// LineNumberReader lnr = null;
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT region, sec0, sec1, sec2, sec3, sec4, sec5, sec6, sec7, sec8, sec9, sec10,sec11,sec12,sec13,sec14,sec15 FROM mapregion");
|
||||
ResultSet rset = statement.executeQuery();
|
||||
int region;
|
||||
while (rset.next())
|
||||
{
|
||||
region = rset.getInt(1);
|
||||
|
||||
for (int j = 0; j < 16; j++)
|
||||
{
|
||||
_regions[j][region] = rset.getInt(j + 2);
|
||||
count2++;
|
||||
// _log.fine(j+","+region+" -> "+rset.getInt(j+2));
|
||||
}
|
||||
}
|
||||
|
||||
rset.close();
|
||||
statement.close();
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.fine(count2 + " mapregion loaded");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error loading Map Region Table.", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
|
||||
public final int getMapRegion(int posX, int posY)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _regions[getMapRegionX(posX)][getMapRegionY(posY)];
|
||||
}
|
||||
catch (ArrayIndexOutOfBoundsException e)
|
||||
{
|
||||
// Position sent is outside MapRegionTable area.
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.log(Level.WARNING, "MapRegionTable: Player outside map regions at X,Y=" + posX + "," + posY, e);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public final int getMapRegionX(int posX)
|
||||
{
|
||||
return (posX >> 15) + 9;// + centerTileX;
|
||||
}
|
||||
|
||||
public final int getMapRegionY(int posY)
|
||||
{
|
||||
return (posY >> 15) + 10;// + centerTileX;
|
||||
}
|
||||
|
||||
public int getAreaCastle(L2Character activeChar)
|
||||
{
|
||||
int area = getClosestTownNumber(activeChar);
|
||||
int castle;
|
||||
switch (area)
|
||||
{
|
||||
case 0:
|
||||
castle = 1;
|
||||
break;// Talking Island Village
|
||||
case 1:
|
||||
castle = 4;
|
||||
break; // Elven Village
|
||||
case 2:
|
||||
castle = 4;
|
||||
break; // Dark Elven Village
|
||||
case 3:
|
||||
castle = 9;
|
||||
break; // Orc Village
|
||||
case 4:
|
||||
castle = 9;
|
||||
break; // Dwarven Village
|
||||
case 5:
|
||||
castle = 1;
|
||||
break; // Town of Gludio
|
||||
case 6:
|
||||
castle = 1;
|
||||
break; // Gludin Village
|
||||
case 7:
|
||||
castle = 2;
|
||||
break; // Town of Dion
|
||||
case 8:
|
||||
castle = 3;
|
||||
break; // Town of Giran
|
||||
case 9:
|
||||
castle = 4;
|
||||
break; // Town of Oren
|
||||
case 10:
|
||||
castle = 5;
|
||||
break; // Town of Aden
|
||||
case 11:
|
||||
castle = 5;
|
||||
break; // Hunters Village
|
||||
case 12:
|
||||
castle = 3;
|
||||
break; // Giran Harbor
|
||||
case 13:
|
||||
castle = 6;
|
||||
break; // Heine
|
||||
case 14:
|
||||
castle = 8;
|
||||
break; // Rune Township
|
||||
case 15:
|
||||
castle = 7;
|
||||
break; // Town of Goddard
|
||||
case 16:
|
||||
castle = 9;
|
||||
break; // Town of Shuttgart
|
||||
case 17:
|
||||
castle = 2;
|
||||
break; // Floran Village
|
||||
case 18:
|
||||
castle = 8;
|
||||
break; // Primeval Isle Wharf
|
||||
case 19:
|
||||
castle = 5;
|
||||
break; // Kamael Village
|
||||
case 20:
|
||||
castle = 6;
|
||||
break; // South of Wastelands Camp
|
||||
case 21:
|
||||
castle = 8;
|
||||
break; // Fantasy Island
|
||||
default:
|
||||
castle = 5;
|
||||
break; // Town of Aden
|
||||
}
|
||||
return castle;
|
||||
}
|
||||
|
||||
public int getClosestTownNumber(L2Character activeChar)
|
||||
{
|
||||
return getMapRegion(activeChar.getX(), activeChar.getY());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get town name by character position
|
||||
* @param activeChar
|
||||
* @return String
|
||||
*/
|
||||
public String getClosestTownName(L2Character activeChar)
|
||||
{
|
||||
return getClosestTownName(getMapRegion(activeChar.getX(), activeChar.getY()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get town name by town id
|
||||
* @param townId
|
||||
* @return String
|
||||
*/
|
||||
public String getClosestTownName(int townId)
|
||||
{
|
||||
String nearestTown = null;
|
||||
switch (townId)
|
||||
{
|
||||
case 0:
|
||||
nearestTown = "Talking Island Village";
|
||||
break;
|
||||
case 1:
|
||||
nearestTown = "Elven Village";
|
||||
break;
|
||||
case 2:
|
||||
nearestTown = "Dark Elven Village";
|
||||
break;
|
||||
case 3:
|
||||
nearestTown = "Orc Village";
|
||||
break;
|
||||
case 4:
|
||||
nearestTown = "Dwarven Village";
|
||||
break;
|
||||
case 5:
|
||||
nearestTown = "Town of Gludio";
|
||||
break;
|
||||
case 6:
|
||||
nearestTown = "Gludin Village";
|
||||
break;
|
||||
case 7:
|
||||
nearestTown = "Town of Dion";
|
||||
break;
|
||||
case 8:
|
||||
nearestTown = "Town of Giran";
|
||||
break;
|
||||
case 9:
|
||||
nearestTown = "Town of Oren";
|
||||
break;
|
||||
case 10:
|
||||
nearestTown = "Town of Aden";
|
||||
break;
|
||||
case 11:
|
||||
nearestTown = "Hunters Village";
|
||||
break;
|
||||
case 12:
|
||||
nearestTown = "Giran Harbor";
|
||||
break;
|
||||
case 13:
|
||||
nearestTown = "Heine";
|
||||
break;
|
||||
case 14:
|
||||
nearestTown = "Rune Township";
|
||||
break;
|
||||
case 15:
|
||||
nearestTown = "Town of Goddard";
|
||||
break;
|
||||
case 16:
|
||||
nearestTown = "Town of Schuttgart";
|
||||
break;
|
||||
case 18:
|
||||
nearestTown = "Primeval Isle";
|
||||
break;
|
||||
case 19:
|
||||
nearestTown = "Kamael Village";
|
||||
break;
|
||||
case 20:
|
||||
nearestTown = "South of Wastelands Camp";
|
||||
break;
|
||||
case 21:
|
||||
nearestTown = "Fantasy Island";
|
||||
break;
|
||||
case 22:
|
||||
nearestTown = "Neutral Zone";
|
||||
break;
|
||||
case 23:
|
||||
nearestTown = "Coliseum";
|
||||
break;
|
||||
case 24:
|
||||
nearestTown = "GM Consultation service";
|
||||
break;
|
||||
case 25:
|
||||
nearestTown = "Dimensional Gap";
|
||||
break;
|
||||
case 26:
|
||||
nearestTown = "Cemetary of the Empire";
|
||||
break;
|
||||
case 27:
|
||||
nearestTown = "Inside the Steel Citadel";
|
||||
break;
|
||||
case 28:
|
||||
nearestTown = "Steel Citadel Resistance";
|
||||
break;
|
||||
case 29:
|
||||
nearestTown = "Inside Kamaloka";
|
||||
break;
|
||||
case 30:
|
||||
nearestTown = "Inside Nia Kamaloka";
|
||||
break;
|
||||
case 31:
|
||||
nearestTown = "Inside Rim Kamaloka";
|
||||
break;
|
||||
case 32:
|
||||
nearestTown = "Keucereus clan association";
|
||||
break;
|
||||
case 33:
|
||||
nearestTown = "Inside the Seed of Infinity";
|
||||
break;
|
||||
case 34:
|
||||
nearestTown = "Outside the Seed of Infinity";
|
||||
break;
|
||||
case 35:
|
||||
nearestTown = "Aerial Cleft";
|
||||
break;
|
||||
default:
|
||||
nearestTown = "Town of Aden";
|
||||
break;
|
||||
}
|
||||
|
||||
return nearestTown;
|
||||
}
|
||||
|
||||
public Location getTeleToLocation(L2Character activeChar, TeleportWhereType teleportWhere)
|
||||
{
|
||||
int[] coord;
|
||||
|
||||
if (activeChar instanceof L2PcInstance)
|
||||
{
|
||||
L2PcInstance player = ((L2PcInstance) activeChar);
|
||||
|
||||
// If in Monster Derby Track
|
||||
if (player.isInsideZone(L2Character.ZONE_MONSTERTRACK))
|
||||
{
|
||||
return new Location(12661, 181687, -3560);
|
||||
}
|
||||
|
||||
Castle castle = null;
|
||||
Fort fort = null;
|
||||
ClanHall clanhall = null;
|
||||
|
||||
if ((player.getClan() != null) && !player.isFlyingMounted() && !player.isFlying()) // flying players in gracia cant use teleports to aden continent
|
||||
{
|
||||
// If teleport to clan hall
|
||||
if (teleportWhere == TeleportWhereType.ClanHall)
|
||||
{
|
||||
|
||||
clanhall = ClanHallManager.getInstance().getClanHallByOwner(player.getClan());
|
||||
if (clanhall != null)
|
||||
{
|
||||
L2ClanHallZone zone = clanhall.getZone();
|
||||
if ((zone != null) && !player.isFlyingMounted())
|
||||
{
|
||||
return zone.getSpawnLoc();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If teleport to castle
|
||||
if (teleportWhere == TeleportWhereType.Castle)
|
||||
{
|
||||
castle = CastleManager.getInstance().getCastleByOwner(player.getClan());
|
||||
// Otherwise check if player is on castle or fortress ground
|
||||
// and player's clan is defender
|
||||
if (castle == null)
|
||||
{
|
||||
castle = CastleManager.getInstance().getCastle(player);
|
||||
if (!((castle != null) && castle.getSiege().getIsInProgress() && (castle.getSiege().getDefenderClan(player.getClan()) != null)))
|
||||
{
|
||||
castle = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ((castle != null) && (castle.getCastleId() > 0))
|
||||
{
|
||||
return castle.getCastleZone().getSpawnLoc();
|
||||
}
|
||||
}
|
||||
|
||||
// If teleport to fortress
|
||||
if (teleportWhere == TeleportWhereType.Fortress)
|
||||
{
|
||||
fort = FortManager.getInstance().getFortByOwner(player.getClan());
|
||||
// Otherwise check if player is on castle or fortress ground
|
||||
// and player's clan is defender
|
||||
if (fort == null)
|
||||
{
|
||||
fort = FortManager.getInstance().getFort(player);
|
||||
if (!((fort != null) && fort.getSiege().getIsInProgress() && (fort.getOwnerClan() == player.getClan())))
|
||||
{
|
||||
fort = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ((fort != null) && (fort.getFortId() > 0))
|
||||
{
|
||||
return fort.getFortZone().getSpawnLoc();
|
||||
}
|
||||
}
|
||||
|
||||
// If teleport to SiegeHQ
|
||||
if (teleportWhere == TeleportWhereType.SiegeFlag)
|
||||
{
|
||||
castle = CastleManager.getInstance().getCastle(player);
|
||||
fort = FortManager.getInstance().getFort(player);
|
||||
L2SiegeFlagInstance tw_flag = TerritoryWarManager.getInstance().getFlagForClan(player.getClan());
|
||||
if (tw_flag != null)
|
||||
{
|
||||
return new Location(tw_flag.getX(), tw_flag.getY(), tw_flag.getZ());
|
||||
}
|
||||
else if (castle != null)
|
||||
{
|
||||
if (castle.getSiege().getIsInProgress())
|
||||
{
|
||||
// Check if player's clan is attacker
|
||||
List<L2Npc> flags = castle.getSiege().getFlag(player.getClan());
|
||||
if ((flags != null) && !flags.isEmpty())
|
||||
{
|
||||
// Spawn to flag - Need more work to get player to the nearest flag
|
||||
L2Npc flag = flags.get(0);
|
||||
return new Location(flag.getX(), flag.getY(), flag.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (fort != null)
|
||||
{
|
||||
if (fort.getSiege().getIsInProgress())
|
||||
{
|
||||
// Check if player's clan is attacker
|
||||
List<L2Npc> flags = fort.getSiege().getFlag(player.getClan());
|
||||
if ((flags != null) && !flags.isEmpty())
|
||||
{
|
||||
// Spawn to flag - Need more work to get player to the nearest flag
|
||||
L2Npc flag = flags.get(0);
|
||||
return new Location(flag.getX(), flag.getY(), flag.getZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Karma player land out of city
|
||||
if (player.getKarma() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
return TownManager.getClosestTown(activeChar).getChaoticSpawnLoc();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (player.isFlyingMounted())
|
||||
{
|
||||
return new Location(-186330, 242944, 2544);
|
||||
}
|
||||
return new Location(17817, 170079, -3530);
|
||||
}
|
||||
}
|
||||
|
||||
// Checking if in arena
|
||||
L2ArenaZone arena = ZoneManager.getInstance().getArena(player);
|
||||
if (arena != null)
|
||||
{
|
||||
return arena.getSpawnLoc();
|
||||
}
|
||||
|
||||
// Checking if needed to be respawned in "far" town from the castle;
|
||||
castle = CastleManager.getInstance().getCastle(player);
|
||||
if (castle != null)
|
||||
{
|
||||
if (castle.getSiege().getIsInProgress())
|
||||
{
|
||||
// Check if player's clan is participating
|
||||
if ((castle.getSiege().checkIsDefender(player.getClan()) || castle.getSiege().checkIsAttacker(player.getClan())) && (SevenSigns.getInstance().getSealOwner(SevenSigns.SEAL_STRIFE) == SevenSigns.CABAL_DAWN))
|
||||
{
|
||||
return TownManager.getSecondClosestTown(activeChar).getSpawnLoc();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Checking if in an instance
|
||||
if (player.getInstanceId() > 0)
|
||||
{
|
||||
Instance inst = InstanceManager.getInstance().getInstance(player.getInstanceId());
|
||||
if (inst != null)
|
||||
{
|
||||
coord = inst.getSpawnLoc();
|
||||
if ((coord[0] != 0) && (coord[1] != 0) && (coord[2] != 0))
|
||||
{
|
||||
return new Location(coord[0], coord[1], coord[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get the nearest town
|
||||
try
|
||||
{
|
||||
return TownManager.getClosestTown(activeChar).getSpawnLoc();
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
{
|
||||
// port to the Talking Island if no closest town found
|
||||
return new Location(-84176, 243382, -3126);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final MapRegionTable _instance = new MapRegionTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.InstanceListManager;
|
||||
import com.l2jserver.gameserver.instancemanager.CastleManager;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MerchantInstance;
|
||||
import com.l2jserver.gameserver.model.entity.Castle;
|
||||
|
||||
/**
|
||||
* @author KenM
|
||||
*/
|
||||
public class MerchantPriceConfigTable implements InstanceListManager
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(MerchantPriceConfigTable.class.getName());
|
||||
|
||||
public static MerchantPriceConfigTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static final String MPCS_FILE = "MerchantPriceConfig.xml";
|
||||
|
||||
private final Map<Integer, MerchantPriceConfig> _mpcs = new FastMap<>();
|
||||
private MerchantPriceConfig _defaultMpc;
|
||||
|
||||
private MerchantPriceConfigTable()
|
||||
{
|
||||
}
|
||||
|
||||
public MerchantPriceConfig getMerchantPriceConfig(L2MerchantInstance npc)
|
||||
{
|
||||
for (MerchantPriceConfig mpc : _mpcs.values())
|
||||
{
|
||||
if (npc.getWorldRegion().containsZone(mpc.getZoneId()))
|
||||
{
|
||||
return mpc;
|
||||
}
|
||||
}
|
||||
return _defaultMpc;
|
||||
}
|
||||
|
||||
public MerchantPriceConfig getMerchantPriceConfig(int id)
|
||||
{
|
||||
return _mpcs.get(id);
|
||||
}
|
||||
|
||||
public void loadXML() throws SAXException, IOException, ParserConfigurationException
|
||||
{
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setIgnoringComments(true);
|
||||
File file = new File(Config.DATAPACK_ROOT + "/data/" + MPCS_FILE);
|
||||
if (file.exists())
|
||||
{
|
||||
int defaultPriceConfigId;
|
||||
Document doc = factory.newDocumentBuilder().parse(file);
|
||||
|
||||
Node n = doc.getDocumentElement();
|
||||
Node dpcNode = n.getAttributes().getNamedItem("defaultPriceConfig");
|
||||
if (dpcNode == null)
|
||||
{
|
||||
throw new IllegalStateException("merchantPriceConfig must define an 'defaultPriceConfig'");
|
||||
}
|
||||
defaultPriceConfigId = Integer.parseInt(dpcNode.getNodeValue());
|
||||
MerchantPriceConfig mpc;
|
||||
for (n = n.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
mpc = parseMerchantPriceConfig(n);
|
||||
if (mpc != null)
|
||||
{
|
||||
_mpcs.put(mpc.getId(), mpc);
|
||||
}
|
||||
}
|
||||
|
||||
MerchantPriceConfig defaultMpc = this.getMerchantPriceConfig(defaultPriceConfigId);
|
||||
if (defaultMpc == null)
|
||||
{
|
||||
throw new IllegalStateException("'defaultPriceConfig' points to an non-loaded priceConfig");
|
||||
}
|
||||
_defaultMpc = defaultMpc;
|
||||
}
|
||||
}
|
||||
|
||||
private MerchantPriceConfig parseMerchantPriceConfig(Node n)
|
||||
{
|
||||
if (n.getNodeName().equals("priceConfig"))
|
||||
{
|
||||
final int id;
|
||||
final int baseTax;
|
||||
int castleId = -1;
|
||||
int zoneId = -1;
|
||||
final String name;
|
||||
|
||||
Node node = n.getAttributes().getNamedItem("id");
|
||||
if (node == null)
|
||||
{
|
||||
throw new IllegalStateException("Must define the priceConfig 'id'");
|
||||
}
|
||||
id = Integer.parseInt(node.getNodeValue());
|
||||
|
||||
node = n.getAttributes().getNamedItem("name");
|
||||
if (node == null)
|
||||
{
|
||||
throw new IllegalStateException("Must define the priceConfig 'name'");
|
||||
}
|
||||
name = node.getNodeValue();
|
||||
|
||||
node = n.getAttributes().getNamedItem("baseTax");
|
||||
if (node == null)
|
||||
{
|
||||
throw new IllegalStateException("Must define the priceConfig 'baseTax'");
|
||||
}
|
||||
baseTax = Integer.parseInt(node.getNodeValue());
|
||||
|
||||
node = n.getAttributes().getNamedItem("castleId");
|
||||
if (node != null)
|
||||
{
|
||||
castleId = Integer.parseInt(node.getNodeValue());
|
||||
}
|
||||
|
||||
node = n.getAttributes().getNamedItem("zoneId");
|
||||
if (node != null)
|
||||
{
|
||||
zoneId = Integer.parseInt(node.getNodeValue());
|
||||
}
|
||||
|
||||
return new MerchantPriceConfig(id, name, baseTax, castleId, zoneId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadInstances()
|
||||
{
|
||||
try
|
||||
{
|
||||
loadXML();
|
||||
_log.info("MerchantPriceConfigTable: Loaded " + _mpcs.size() + " merchant price configs.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Failed loading MerchantPriceConfigTable. Reason: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateReferences()
|
||||
{
|
||||
for (final MerchantPriceConfig mpc : _mpcs.values())
|
||||
{
|
||||
mpc.updateReferences();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activateInstances()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @author KenM
|
||||
*/
|
||||
public static final class MerchantPriceConfig
|
||||
{
|
||||
private final int _id;
|
||||
private final String _name;
|
||||
private final int _baseTax;
|
||||
private final int _castleId;
|
||||
private Castle _castle;
|
||||
private final int _zoneId;
|
||||
|
||||
public MerchantPriceConfig(final int id, final String name, final int baseTax, final int castleId, final int zoneId)
|
||||
{
|
||||
_id = id;
|
||||
_name = name;
|
||||
_baseTax = baseTax;
|
||||
_castleId = castleId;
|
||||
_zoneId = zoneId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the id.
|
||||
*/
|
||||
public int getId()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the name.
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the baseTax.
|
||||
*/
|
||||
public int getBaseTax()
|
||||
{
|
||||
return _baseTax;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the baseTax / 100.0.
|
||||
*/
|
||||
public double getBaseTaxRate()
|
||||
{
|
||||
return _baseTax / 100.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the castle.
|
||||
*/
|
||||
public Castle getCastle()
|
||||
{
|
||||
return _castle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the zoneId.
|
||||
*/
|
||||
public int getZoneId()
|
||||
{
|
||||
return _zoneId;
|
||||
}
|
||||
|
||||
public boolean hasCastle()
|
||||
{
|
||||
return getCastle() != null;
|
||||
}
|
||||
|
||||
public double getCastleTaxRate()
|
||||
{
|
||||
return hasCastle() ? getCastle().getTaxRate() : 0.0;
|
||||
}
|
||||
|
||||
public int getTotalTax()
|
||||
{
|
||||
return hasCastle() ? (getCastle().getTaxPercent() + getBaseTax()) : getBaseTax();
|
||||
}
|
||||
|
||||
public double getTotalTaxRate()
|
||||
{
|
||||
return getTotalTax() / 100.0;
|
||||
}
|
||||
|
||||
public void updateReferences()
|
||||
{
|
||||
_castle = CastleManager.getInstance().getCastleById(_castleId);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final MerchantPriceConfigTable _instance = new MerchantPriceConfigTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import gnu.trove.TIntObjectIterator;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import javolution.util.FastList;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.multisell.Entry;
|
||||
import com.l2jserver.gameserver.model.multisell.Ingredient;
|
||||
import com.l2jserver.gameserver.model.multisell.ListContainer;
|
||||
import com.l2jserver.gameserver.model.multisell.PreparedListContainer;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExBrExtraUserInfo;
|
||||
import com.l2jserver.gameserver.network.serverpackets.MultiSellList;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jserver.gameserver.network.serverpackets.UserInfo;
|
||||
|
||||
public class MultiSell
|
||||
{
|
||||
public static final int PAGE_SIZE = 40;
|
||||
|
||||
public static final int PC_BANG_POINTS = -100;
|
||||
public static final int CLAN_REPUTATION = -200;
|
||||
public static final int FAME = -300;
|
||||
|
||||
private static final Logger _log = Logger.getLogger(MultiSell.class.getName());
|
||||
|
||||
private final TIntObjectHashMap<ListContainer> _entries;
|
||||
|
||||
public static MultiSell getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private MultiSell()
|
||||
{
|
||||
_entries = new TIntObjectHashMap<>();
|
||||
load();
|
||||
}
|
||||
|
||||
public final void reload()
|
||||
{
|
||||
_entries.clear();
|
||||
load();
|
||||
}
|
||||
|
||||
/**
|
||||
* This will generate the multisell list for the items. There exist various parameters in multisells that affect the way they will appear: 1) inventory only: * 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. * if false, show the entire list. 2) maintain enchantment: presumably, only lists with "inventory only" set to true should sometimes have this as true. This makes no sense otherwise... * If true, then the product will match the enchantment level of the
|
||||
* ingredient. 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. 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. * If false, then any level ingredient will be considered equal and product will always be at +0 3) apply taxes: Uses the "taxIngredient" entry
|
||||
* in order to add a certain amount of adena to the ingredients
|
||||
*/
|
||||
public final void separateAndSend(int listId, L2PcInstance player, L2Npc npc, boolean inventoryOnly)
|
||||
{
|
||||
ListContainer template = _entries.get(listId);
|
||||
if (template == null)
|
||||
{
|
||||
_log.warning("[MultiSell] can't find list id: " + listId + " requested by player: " + player.getName() + ", npcId:" + (npc != null ? npc.getNpcId() : 0));
|
||||
return;
|
||||
}
|
||||
|
||||
final PreparedListContainer list = new PreparedListContainer(template, inventoryOnly, player, npc);
|
||||
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 static final boolean checkSpecialIngredient(int id, long amount, L2PcInstance player)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case CLAN_REPUTATION:
|
||||
if (player.getClan() == null)
|
||||
{
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_ARE_NOT_A_CLAN_MEMBER));
|
||||
break;
|
||||
}
|
||||
if (!player.isClanLeader())
|
||||
{
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.ONLY_THE_CLAN_LEADER_IS_ENABLED));
|
||||
break;
|
||||
}
|
||||
if (player.getClan().getReputationScore() < amount)
|
||||
{
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.THE_CLAN_REPUTATION_SCORE_IS_TOO_LOW));
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
case FAME:
|
||||
if (player.getFame() < amount)
|
||||
{
|
||||
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.NOT_ENOUGH_FAME_POINTS));
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static final boolean getSpecialIngredient(int id, long amount, L2PcInstance player)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case CLAN_REPUTATION:
|
||||
player.getClan().takeReputationScore((int) amount, true);
|
||||
SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.S1_DEDUCTED_FROM_CLAN_REP);
|
||||
smsg.addItemNumber(amount);
|
||||
player.sendPacket(smsg);
|
||||
return true;
|
||||
case FAME:
|
||||
player.setFame(player.getFame() - (int) amount);
|
||||
player.sendPacket(new UserInfo(player));
|
||||
player.sendPacket(new ExBrExtraUserInfo(player));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static final void addSpecialProduct(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));
|
||||
player.sendPacket(new ExBrExtraUserInfo(player));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private final void load()
|
||||
{
|
||||
Document doc = null;
|
||||
int id = 0;
|
||||
List<File> files = new FastList<>();
|
||||
hashFiles("multisell", files);
|
||||
|
||||
for (File f : files)
|
||||
{
|
||||
try
|
||||
{
|
||||
id = Integer.parseInt(f.getName().replaceAll(".xml", ""));
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setIgnoringComments(true);
|
||||
doc = factory.newDocumentBuilder().parse(f);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error loading file " + f, e);
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ListContainer list = parseDocument(doc);
|
||||
list.setListId(id);
|
||||
_entries.put(id, list);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error in file " + f, e);
|
||||
}
|
||||
}
|
||||
verify();
|
||||
_log.log(Level.INFO, "MultiSell: Loaded " + _entries.size() + " lists.");
|
||||
}
|
||||
|
||||
private final ListContainer parseDocument(Document doc)
|
||||
{
|
||||
int entryId = 1;
|
||||
Node attribute;
|
||||
ListContainer list = new ListContainer();
|
||||
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
attribute = n.getAttributes().getNamedItem("applyTaxes");
|
||||
if (attribute == null)
|
||||
{
|
||||
list.setApplyTaxes(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
list.setApplyTaxes(Boolean.parseBoolean(attribute.getNodeValue()));
|
||||
}
|
||||
|
||||
attribute = n.getAttributes().getNamedItem("maintainEnchantment");
|
||||
if (attribute == null)
|
||||
{
|
||||
list.setMaintainEnchantment(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
list.setMaintainEnchantment(Boolean.parseBoolean(attribute.getNodeValue()));
|
||||
}
|
||||
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("item".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
Entry e = parseEntry(d, entryId++);
|
||||
list.getEntries().add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ("item".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
Entry e = parseEntry(n, entryId++);
|
||||
list.getEntries().add(e);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private final Entry parseEntry(Node n, int entryId)
|
||||
{
|
||||
Node attribute;
|
||||
Node first = n.getFirstChild();
|
||||
final Entry entry = new Entry(entryId);
|
||||
|
||||
for (n = first; n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("ingredient".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
int id = Integer.parseInt(n.getAttributes().getNamedItem("id").getNodeValue());
|
||||
long count = Long.parseLong(n.getAttributes().getNamedItem("count").getNodeValue());
|
||||
boolean isTaxIngredient, mantainIngredient;
|
||||
|
||||
attribute = n.getAttributes().getNamedItem("isTaxIngredient");
|
||||
if (attribute != null)
|
||||
{
|
||||
isTaxIngredient = Boolean.parseBoolean(attribute.getNodeValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
isTaxIngredient = false;
|
||||
}
|
||||
|
||||
attribute = n.getAttributes().getNamedItem("maintainIngredient");
|
||||
if (attribute != null)
|
||||
{
|
||||
mantainIngredient = Boolean.parseBoolean(attribute.getNodeValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
mantainIngredient = false;
|
||||
}
|
||||
|
||||
entry.addIngredient(new Ingredient(id, count, isTaxIngredient, mantainIngredient));
|
||||
}
|
||||
else if ("production".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
int id = Integer.parseInt(n.getAttributes().getNamedItem("id").getNodeValue());
|
||||
long count = Long.parseLong(n.getAttributes().getNamedItem("count").getNodeValue());
|
||||
|
||||
entry.addProduct(new Ingredient(id, count, false, false));
|
||||
}
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
private final void hashFiles(String dirname, List<File> hash)
|
||||
{
|
||||
File dir = new File(Config.DATAPACK_ROOT, "data/" + dirname);
|
||||
if (!dir.exists())
|
||||
{
|
||||
_log.log(Level.WARNING, "Dir " + dir.getAbsolutePath() + " not exists");
|
||||
return;
|
||||
}
|
||||
|
||||
File[] files = dir.listFiles();
|
||||
for (File f : files)
|
||||
{
|
||||
if (f.getName().endsWith(".xml"))
|
||||
{
|
||||
hash.add(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void verify()
|
||||
{
|
||||
ListContainer list;
|
||||
final TIntObjectIterator<ListContainer> iter = _entries.iterator();
|
||||
while (iter.hasNext())
|
||||
{
|
||||
iter.advance();
|
||||
list = iter.value();
|
||||
|
||||
for (Entry ent : list.getEntries())
|
||||
{
|
||||
for (Ingredient ing : ent.getIngredients())
|
||||
{
|
||||
if (!verifyIngredient(ing))
|
||||
{
|
||||
_log.warning("[MultiSell] can't find ingredient with itemId: " + ing.getItemId() + " in list: " + list.getListId());
|
||||
}
|
||||
}
|
||||
for (Ingredient ing : ent.getProducts())
|
||||
{
|
||||
if (!verifyIngredient(ing))
|
||||
{
|
||||
_log.warning("[MultiSell] can't find product with itemId: " + ing.getItemId() + " in list: " + list.getListId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final boolean verifyIngredient(Ingredient ing)
|
||||
{
|
||||
switch (ing.getItemId())
|
||||
{
|
||||
case CLAN_REPUTATION:
|
||||
case FAME:
|
||||
return true;
|
||||
default:
|
||||
if (ing.getTemplate() != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final MultiSell _instance = new MultiSell();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Skill;
|
||||
|
||||
/**
|
||||
* @author -Nemesiss-
|
||||
*/
|
||||
public class NobleSkillTable
|
||||
{
|
||||
private static final L2Skill[] _nobleSkills = new L2Skill[8];
|
||||
|
||||
private NobleSkillTable()
|
||||
{
|
||||
_nobleSkills[0] = SkillTable.getInstance().getInfo(1323, 1);
|
||||
_nobleSkills[1] = SkillTable.getInstance().getInfo(325, 1);
|
||||
_nobleSkills[2] = SkillTable.getInstance().getInfo(326, 1);
|
||||
_nobleSkills[3] = SkillTable.getInstance().getInfo(327, 1);
|
||||
_nobleSkills[4] = SkillTable.getInstance().getInfo(1324, 1);
|
||||
_nobleSkills[5] = SkillTable.getInstance().getInfo(1325, 1);
|
||||
_nobleSkills[6] = SkillTable.getInstance().getInfo(1326, 1);
|
||||
_nobleSkills[7] = SkillTable.getInstance().getInfo(1327, 1);
|
||||
}
|
||||
|
||||
public static NobleSkillTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
public L2Skill[] getNobleSkills()
|
||||
{
|
||||
return _nobleSkills;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final NobleSkillTable _instance = new NobleSkillTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntIntHashMap;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
|
||||
public class NpcBufferTable
|
||||
{
|
||||
protected static Logger _log = Logger.getLogger(NpcBufferTable.class.getName());
|
||||
|
||||
private final TIntObjectHashMap<NpcBufferSkills> _buffers = new TIntObjectHashMap<>();
|
||||
|
||||
private static class NpcBufferSkills
|
||||
{
|
||||
private final TIntIntHashMap _skillId = new TIntIntHashMap();
|
||||
private final TIntIntHashMap _skillLevels = new TIntIntHashMap();
|
||||
private final TIntIntHashMap _skillFeeIds = new TIntIntHashMap();
|
||||
private final TIntIntHashMap _skillFeeAmounts = new TIntIntHashMap();
|
||||
|
||||
public NpcBufferSkills(int npcId)
|
||||
{
|
||||
}
|
||||
|
||||
public void addSkill(int skillId, int skillLevel, int skillFeeId, int skillFeeAmount, int buffGroup)
|
||||
{
|
||||
_skillId.put(buffGroup, skillId);
|
||||
_skillLevels.put(buffGroup, skillLevel);
|
||||
_skillFeeIds.put(buffGroup, skillFeeId);
|
||||
_skillFeeAmounts.put(buffGroup, skillFeeAmount);
|
||||
}
|
||||
|
||||
public int[] getSkillGroupInfo(int buffGroup)
|
||||
{
|
||||
Integer skillId = _skillId.get(buffGroup);
|
||||
Integer skillLevel = _skillLevels.get(buffGroup);
|
||||
Integer skillFeeId = _skillFeeIds.get(buffGroup);
|
||||
Integer skillFeeAmount = _skillFeeAmounts.get(buffGroup);
|
||||
|
||||
if ((skillId == null) || (skillLevel == null) || (skillFeeId == null) || (skillFeeAmount == null))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new int[]
|
||||
{
|
||||
skillId,
|
||||
skillLevel,
|
||||
skillFeeId,
|
||||
skillFeeAmount
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private NpcBufferTable()
|
||||
{
|
||||
Connection con = null;
|
||||
int skillCount = 0;
|
||||
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
|
||||
PreparedStatement statement = con.prepareStatement("SELECT `npc_id`,`skill_id`,`skill_level`,`skill_fee_id`,`skill_fee_amount`,`buff_group` FROM `npc_buffer` ORDER BY `npc_id` ASC");
|
||||
ResultSet rset = statement.executeQuery();
|
||||
|
||||
int lastNpcId = 0;
|
||||
NpcBufferSkills skills = null;
|
||||
|
||||
while (rset.next())
|
||||
{
|
||||
int npcId = rset.getInt("npc_id");
|
||||
int skillId = rset.getInt("skill_id");
|
||||
int skillLevel = rset.getInt("skill_level");
|
||||
int skillFeeId = rset.getInt("skill_fee_id");
|
||||
int skillFeeAmount = rset.getInt("skill_fee_amount");
|
||||
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
|
||||
{
|
||||
skills.addSkill(skillId, skillLevel, skillFeeId, skillFeeAmount, buffGroup);
|
||||
}
|
||||
|
||||
lastNpcId = npcId;
|
||||
skillCount++;
|
||||
}
|
||||
|
||||
if (lastNpcId != 0)
|
||||
{
|
||||
_buffers.put(lastNpcId, skills);
|
||||
}
|
||||
rset.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "NpcBufferTable: Error reading npc_buffer table: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
if (Config.CUSTOM_NPCBUFFER_TABLES)
|
||||
{
|
||||
try
|
||||
{
|
||||
PreparedStatement statement = con.prepareStatement("SELECT `npc_id`,`skill_id`,`skill_level`,`skill_fee_id`,`skill_fee_amount`,`buff_group` FROM `custom_npc_buffer` ORDER BY `npc_id` ASC");
|
||||
ResultSet rset = statement.executeQuery();
|
||||
|
||||
int lastNpcId = 0;
|
||||
NpcBufferSkills skills = null;
|
||||
|
||||
while (rset.next())
|
||||
{
|
||||
int npcId = rset.getInt("npc_id");
|
||||
int skillId = rset.getInt("skill_id");
|
||||
int skillLevel = rset.getInt("skill_level");
|
||||
int skillFeeId = rset.getInt("skill_fee_id");
|
||||
int skillFeeAmount = rset.getInt("skill_fee_amount");
|
||||
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
|
||||
{
|
||||
skills.addSkill(skillId, skillLevel, skillFeeId, skillFeeAmount, buffGroup);
|
||||
}
|
||||
|
||||
lastNpcId = npcId;
|
||||
skillCount++;
|
||||
}
|
||||
|
||||
if (lastNpcId != 0)
|
||||
{
|
||||
_buffers.put(lastNpcId, skills);
|
||||
}
|
||||
rset.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "NpcBufferTable: Error reading custom_npc_buffer table: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
|
||||
_log.info("NpcBufferSkillIdsTable: Loaded " + _buffers.size() + " buffers and " + skillCount + " skills.");
|
||||
}
|
||||
|
||||
public static NpcBufferTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
public int[] getSkillInfo(int npcId, int buffGroup)
|
||||
{
|
||||
NpcBufferSkills skills = _buffers.get(npcId);
|
||||
|
||||
if (skills == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return skills.getSkillGroupInfo(buffGroup);
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final NpcBufferTable _instance = new NpcBufferTable();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.model.L2NpcWalkerNode;
|
||||
|
||||
/**
|
||||
* Main Table to Load Npc Walkers Routes and Chat SQL Table.<br>
|
||||
* @author Rayan RPG for L2Emu Project, JIV
|
||||
* @since 927
|
||||
*/
|
||||
public class NpcWalkerRoutesTable
|
||||
{
|
||||
private final static Logger _log = Logger.getLogger(SpawnTable.class.getName());
|
||||
|
||||
private final TIntObjectHashMap<List<L2NpcWalkerNode>> _routes = new TIntObjectHashMap<>();
|
||||
|
||||
public static NpcWalkerRoutesTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private NpcWalkerRoutesTable()
|
||||
{
|
||||
if (Config.ALLOW_NPC_WALKERS)
|
||||
{
|
||||
_log.info("Initializing Walkers Routes Table.");
|
||||
load();
|
||||
}
|
||||
}
|
||||
|
||||
public void load()
|
||||
{
|
||||
_routes.clear();
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setIgnoringComments(true);
|
||||
File file = new File(Config.DATAPACK_ROOT, "data/WalkerRoutes.xml");
|
||||
Document doc = null;
|
||||
if (file.exists())
|
||||
{
|
||||
try
|
||||
{
|
||||
doc = factory.newDocumentBuilder().parse(file);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Could not parse WalkerRoutes.xml file: " + e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
|
||||
Node n = doc.getFirstChild();
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if (d.getNodeName().equals("walker"))
|
||||
{
|
||||
List<L2NpcWalkerNode> list = new ArrayList<>();
|
||||
int npcId = Integer.parseInt(d.getAttributes().getNamedItem("npcId").getNodeValue());
|
||||
for (Node r = d.getFirstChild(); r != null; r = r.getNextSibling())
|
||||
{
|
||||
if (r.getNodeName().equals("route"))
|
||||
{
|
||||
NamedNodeMap attrs = r.getAttributes();
|
||||
int id = Integer.parseInt(attrs.getNamedItem("id").getNodeValue());
|
||||
int x = Integer.parseInt(attrs.getNamedItem("X").getNodeValue());
|
||||
int y = Integer.parseInt(attrs.getNamedItem("Y").getNodeValue());
|
||||
int z = Integer.parseInt(attrs.getNamedItem("Z").getNodeValue());
|
||||
int delay = Integer.parseInt(attrs.getNamedItem("delay").getNodeValue());
|
||||
String chat = attrs.getNamedItem("string").getNodeValue();
|
||||
boolean running = Boolean.parseBoolean(attrs.getNamedItem("run").getNodeValue());
|
||||
list.add(new L2NpcWalkerNode(id, chat, x, y, z, delay, running));
|
||||
}
|
||||
}
|
||||
_routes.put(npcId, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Object list : _routes.getValues())
|
||||
{
|
||||
((ArrayList<?>) list).trimToSize();
|
||||
}
|
||||
|
||||
_log.info("WalkerRoutesTable: Loaded " + _routes.size() + " Npc Walker Routes.");
|
||||
}
|
||||
|
||||
public List<L2NpcWalkerNode> getRouteForNpc(int id)
|
||||
{
|
||||
return _routes.get(id);
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final NpcWalkerRoutesTable _instance = new NpcWalkerRoutesTable();
|
||||
}
|
||||
|
||||
public static void main(String... arg)
|
||||
{
|
||||
getInstance().load();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Calendar;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.LoginServerThread;
|
||||
import com.l2jserver.gameserver.model.L2ManufactureItem;
|
||||
import com.l2jserver.gameserver.model.L2ManufactureList;
|
||||
import com.l2jserver.gameserver.model.L2World;
|
||||
import com.l2jserver.gameserver.model.TradeList.TradeItem;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.L2GameClient;
|
||||
import com.l2jserver.gameserver.network.L2GameClient.GameClientState;
|
||||
|
||||
public class OfflineTradersTable
|
||||
{
|
||||
private static Logger _log = 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_ITEMS = "DELETE FROM character_offline_trade_items";
|
||||
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 static void storeOffliners()
|
||||
{
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement stm = con.prepareStatement(CLEAR_OFFLINE_TABLE);
|
||||
stm.execute();
|
||||
stm.close();
|
||||
stm = con.prepareStatement(CLEAR_OFFLINE_TABLE_ITEMS);
|
||||
stm.execute();
|
||||
stm.close();
|
||||
|
||||
con.setAutoCommit(false); // avoid halfway done
|
||||
stm = con.prepareStatement(SAVE_OFFLINE_STATUS);
|
||||
PreparedStatement stm_items = con.prepareStatement(SAVE_ITEMS);
|
||||
|
||||
// TextBuilder items = TextBuilder.newInstance();
|
||||
for (L2PcInstance pc : L2World.getInstance().getAllPlayers().values())
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((pc.getPrivateStoreType() != L2PcInstance.STORE_PRIVATE_NONE) && ((pc.getClient() == null) || pc.getClient().isDetached()))
|
||||
{
|
||||
stm.setInt(1, pc.getObjectId()); // Char Id
|
||||
stm.setLong(2, pc.getOfflineStartTime());
|
||||
stm.setInt(3, pc.getPrivateStoreType()); // store type
|
||||
String title = null;
|
||||
|
||||
switch (pc.getPrivateStoreType())
|
||||
{
|
||||
case L2PcInstance.STORE_PRIVATE_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().getItemId());
|
||||
stm_items.setLong(3, i.getCount());
|
||||
stm_items.setLong(4, i.getPrice());
|
||||
stm_items.executeUpdate();
|
||||
stm_items.clearParameters();
|
||||
}
|
||||
break;
|
||||
case L2PcInstance.STORE_PRIVATE_SELL:
|
||||
case L2PcInstance.STORE_PRIVATE_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 L2PcInstance.STORE_PRIVATE_MANUFACTURE:
|
||||
if (!Config.OFFLINE_CRAFT_ENABLE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
title = pc.getCreateList().getStoreName();
|
||||
for (L2ManufactureItem i : pc.getCreateList().getList())
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
stm.setString(4, title);
|
||||
stm.executeUpdate();
|
||||
stm.clearParameters();
|
||||
con.commit(); // flush
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "OfflineTradersTable[storeTradeItems()]: Error while saving offline trader: " + pc.getObjectId() + " " + e, e);
|
||||
}
|
||||
}
|
||||
stm.close();
|
||||
stm_items.close();
|
||||
_log.info("Offline traders stored.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "OfflineTradersTable[storeTradeItems()]: Error while saving offline traders: " + e, e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
|
||||
public static void restoreOfflineTraders()
|
||||
{
|
||||
_log.info("Loading offline traders...");
|
||||
Connection con = null;
|
||||
int nTraders = 0;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement stm = con.prepareStatement(LOAD_OFFLINE_STATUS);
|
||||
ResultSet rs = stm.executeQuery();
|
||||
while (rs.next())
|
||||
{
|
||||
long time = rs.getLong("time");
|
||||
if (Config.OFFLINE_MAX_DAYS > 0)
|
||||
{
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTimeInMillis(time);
|
||||
cal.add(Calendar.DAY_OF_YEAR, Config.OFFLINE_MAX_DAYS);
|
||||
if (cal.getTimeInMillis() <= System.currentTimeMillis())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int type = rs.getInt("type");
|
||||
if (type == L2PcInstance.STORE_PRIVATE_NONE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
L2PcInstance player = null;
|
||||
|
||||
try
|
||||
{
|
||||
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());
|
||||
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);
|
||||
PreparedStatement stm_items = con.prepareStatement(LOAD_OFFLINE_ITEMS);
|
||||
stm_items.setInt(1, player.getObjectId());
|
||||
ResultSet items = stm_items.executeQuery();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case L2PcInstance.STORE_PRIVATE_BUY:
|
||||
while (items.next())
|
||||
{
|
||||
if (player.getBuyList().addItemByItemId(items.getInt(2), items.getLong(3), items.getLong(4)) == null)
|
||||
{
|
||||
throw new NullPointerException();
|
||||
}
|
||||
}
|
||||
player.getBuyList().setTitle(rs.getString("title"));
|
||||
break;
|
||||
case L2PcInstance.STORE_PRIVATE_SELL:
|
||||
case L2PcInstance.STORE_PRIVATE_PACKAGE_SELL:
|
||||
while (items.next())
|
||||
{
|
||||
if (player.getSellList().addItem(items.getInt(2), items.getLong(3), items.getLong(4)) == null)
|
||||
{
|
||||
throw new NullPointerException();
|
||||
}
|
||||
}
|
||||
player.getSellList().setTitle(rs.getString("title"));
|
||||
player.getSellList().setPackaged(type == L2PcInstance.STORE_PRIVATE_PACKAGE_SELL);
|
||||
break;
|
||||
case L2PcInstance.STORE_PRIVATE_MANUFACTURE:
|
||||
L2ManufactureList createList = new L2ManufactureList();
|
||||
while (items.next())
|
||||
{
|
||||
createList.add(new L2ManufactureItem(items.getInt(2), items.getLong(4)));
|
||||
}
|
||||
player.setCreateList(createList);
|
||||
player.getCreateList().setStoreName(rs.getString("title"));
|
||||
break;
|
||||
}
|
||||
items.close();
|
||||
stm_items.close();
|
||||
|
||||
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)
|
||||
{
|
||||
_log.log(Level.WARNING, "OfflineTradersTable[loadOffliners()]: Error loading trader: " + player, e);
|
||||
if (player != null)
|
||||
{
|
||||
player.deleteMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
rs.close();
|
||||
stm.close();
|
||||
_log.info("Loaded: " + nTraders + " offline trader(s)");
|
||||
stm = con.prepareStatement(CLEAR_OFFLINE_TABLE);
|
||||
stm.execute();
|
||||
stm.close();
|
||||
stm = con.prepareStatement(CLEAR_OFFLINE_TABLE_ITEMS);
|
||||
stm.execute();
|
||||
stm.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "OfflineTradersTable[loadOffliners()]: Error while loading offline traders: ", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,516 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.model.L2PetData;
|
||||
import com.l2jserver.gameserver.model.L2PetLevelData;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PetInstance;
|
||||
import com.l2jserver.gameserver.templates.item.L2EtcItemType;
|
||||
import com.l2jserver.gameserver.templates.item.L2Item;
|
||||
|
||||
public class PetDataTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(L2PetInstance.class.getName());
|
||||
|
||||
private static TIntObjectHashMap<L2PetData> _petTable;
|
||||
|
||||
public static PetDataTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private PetDataTable()
|
||||
{
|
||||
_petTable = new TIntObjectHashMap<>();
|
||||
load();
|
||||
}
|
||||
|
||||
public void load()
|
||||
{
|
||||
_petTable.clear();
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
factory.setIgnoringComments(true);
|
||||
File file = new File(Config.DATAPACK_ROOT, "data/stats/npc/PetData.xml");
|
||||
Document doc = null;
|
||||
if (file.exists())
|
||||
{
|
||||
try
|
||||
{
|
||||
doc = factory.newDocumentBuilder().parse(file);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Could not parse PetData.xml file: " + e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
|
||||
Node n = doc.getFirstChild();
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if (d.getNodeName().equals("pet"))
|
||||
{
|
||||
int npcId = Integer.parseInt(d.getAttributes().getNamedItem("id").getNodeValue());
|
||||
// index ignored for now
|
||||
L2PetData data = new L2PetData();
|
||||
for (Node p = d.getFirstChild(); p != null; p = p.getNextSibling())
|
||||
{
|
||||
if (p.getNodeName().equals("set"))
|
||||
{
|
||||
NamedNodeMap attrs = p.getAttributes();
|
||||
String type = attrs.getNamedItem("name").getNodeValue();
|
||||
if ("food".equals(type))
|
||||
{
|
||||
String[] values = attrs.getNamedItem("val").getNodeValue().split(";");
|
||||
int[] food = new int[values.length];
|
||||
for (int i = 0; i < values.length; i++)
|
||||
{
|
||||
food[i] = Integer.parseInt(values[i]);
|
||||
}
|
||||
data.set_food(food);
|
||||
}
|
||||
else if ("load".equals(type))
|
||||
{
|
||||
data.set_load(Integer.parseInt(attrs.getNamedItem("val").getNodeValue()));
|
||||
}
|
||||
else if ("hungry_limit".equals(type))
|
||||
{
|
||||
data.set_hungry_limit(Integer.parseInt(attrs.getNamedItem("val").getNodeValue()));
|
||||
}
|
||||
// sync_level and evolve ignored
|
||||
}
|
||||
else if (p.getNodeName().equals("skills"))
|
||||
{
|
||||
for (Node s = p.getFirstChild(); s != null; s = s.getNextSibling())
|
||||
{
|
||||
if (s.getNodeName().equals("skill"))
|
||||
{
|
||||
NamedNodeMap attrs = s.getAttributes();
|
||||
int skillId = Integer.parseInt(attrs.getNamedItem("skillId").getNodeValue());
|
||||
int skillLvl = Integer.parseInt(attrs.getNamedItem("skillLvl").getNodeValue());
|
||||
int minLvl = Integer.parseInt(attrs.getNamedItem("minLvl").getNodeValue());
|
||||
data.addNewSkill(skillId, skillLvl, minLvl);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (p.getNodeName().equals("stats"))
|
||||
{
|
||||
for (Node s = p.getFirstChild(); s != null; s = s.getNextSibling())
|
||||
{
|
||||
if (s.getNodeName().equals("stat"))
|
||||
{
|
||||
int level = Integer.parseInt(s.getAttributes().getNamedItem("level").getNodeValue());
|
||||
L2PetLevelData stat = new L2PetLevelData();
|
||||
for (Node bean = s.getFirstChild(); bean != null; bean = bean.getNextSibling())
|
||||
{
|
||||
if (bean.getNodeName().equals("set"))
|
||||
{
|
||||
NamedNodeMap attrs = bean.getAttributes();
|
||||
String type = attrs.getNamedItem("name").getNodeValue();
|
||||
String value = attrs.getNamedItem("val").getNodeValue();
|
||||
if ("max_meal".equals(type))
|
||||
{
|
||||
stat.setPetMaxFeed(Integer.parseInt(value));
|
||||
}
|
||||
else if ("exp".equals(type))
|
||||
{
|
||||
stat.setPetMaxExp(Long.parseLong(value));
|
||||
}
|
||||
else if ("get_exp_type".equals(type))
|
||||
{
|
||||
stat.setOwnerExpTaken(Integer.parseInt(value));
|
||||
}
|
||||
else if ("consume_meal_in_battle".equals(type))
|
||||
{
|
||||
stat.setPetFeedBattle(Integer.parseInt(value));
|
||||
}
|
||||
else if ("consume_meal_in_normal".equals(type))
|
||||
{
|
||||
stat.setPetFeedNormal(Integer.parseInt(value));
|
||||
}
|
||||
else if ("org_pattack".equals(type))
|
||||
{
|
||||
stat.setPetPAtk(Float.parseFloat(value));
|
||||
}
|
||||
else if ("org_pdefend".equals(type))
|
||||
{
|
||||
stat.setPetPDef(Float.parseFloat(value));
|
||||
}
|
||||
else if ("org_mattack".equals(type))
|
||||
{
|
||||
stat.setPetMAtk(Float.parseFloat(value));
|
||||
}
|
||||
else if ("org_mdefend".equals(type))
|
||||
{
|
||||
stat.setPetMDef(Float.parseFloat(value));
|
||||
}
|
||||
else if ("org_hp".equals(type))
|
||||
{
|
||||
stat.setPetMaxHP(Float.parseFloat(value));
|
||||
}
|
||||
else if ("org_mp".equals(type))
|
||||
{
|
||||
stat.setPetMaxMP(Float.parseFloat(value));
|
||||
}
|
||||
else if ("org_hp_regen".equals(type))
|
||||
{
|
||||
stat.setPetRegenHP(Float.parseFloat(value));
|
||||
}
|
||||
else if ("org_mp_regen".equals(type))
|
||||
{
|
||||
stat.setPetRegenMP(Float.parseFloat(value));
|
||||
}
|
||||
else if ("soulshot_count".equals(type))
|
||||
{
|
||||
stat.setPetSoulShot((short) Integer.parseInt(value));
|
||||
}
|
||||
else if ("spiritshot_count".equals(type))
|
||||
{
|
||||
stat.setPetSpiritShot((short) Integer.parseInt(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
data.addNewStat(stat, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_petTable.put(npcId, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("Not found PetData.xml");
|
||||
}
|
||||
|
||||
_log.info(getClass().getSimpleName() + ": Loaded " + _petTable.size() + " Pets.");
|
||||
|
||||
}
|
||||
|
||||
public L2PetLevelData getPetLevelData(int petID, int petLevel)
|
||||
{
|
||||
return _petTable.get(petID).getPetLevelData(petLevel);
|
||||
}
|
||||
|
||||
public L2PetData getPetData(int petID)
|
||||
{
|
||||
if (!_petTable.contains(petID))
|
||||
{
|
||||
_log.info("Missing pet data for npcid: " + petID);
|
||||
}
|
||||
return _petTable.get(petID);
|
||||
}
|
||||
|
||||
public int getPetMinLevel(int petID)
|
||||
{
|
||||
return _petTable.get(petID).getMinLevel();
|
||||
}
|
||||
|
||||
/*
|
||||
* Pets stuffs
|
||||
*/
|
||||
public static boolean isWolf(int npcId)
|
||||
{
|
||||
return npcId == 12077;
|
||||
}
|
||||
|
||||
public static boolean isEvolvedWolf(int npcId)
|
||||
{
|
||||
return (npcId == 16030) || (npcId == 16037) || (npcId == 16025) || (npcId == 16041) || (npcId == 16042);
|
||||
}
|
||||
|
||||
public static boolean isSinEater(int npcId)
|
||||
{
|
||||
return npcId == 12564;
|
||||
}
|
||||
|
||||
public static boolean isHatchling(int npcId)
|
||||
{
|
||||
return (npcId > 12310) && (npcId < 12314);
|
||||
}
|
||||
|
||||
public static boolean isStrider(int npcId)
|
||||
{
|
||||
return ((npcId > 12525) && (npcId < 12529)) || ((npcId > 16037) && (npcId < 16041)) || (npcId == 16068);
|
||||
}
|
||||
|
||||
public static boolean isWyvern(int npcId)
|
||||
{
|
||||
return npcId == 12621;
|
||||
}
|
||||
|
||||
public static boolean isBaby(int npcId)
|
||||
{
|
||||
return (npcId > 12779) && (npcId < 12783);
|
||||
}
|
||||
|
||||
public static boolean isImprovedBaby(int npcId)
|
||||
{
|
||||
return (npcId > 16033) && (npcId < 16037);
|
||||
}
|
||||
|
||||
public static boolean isPetFood(int itemId)
|
||||
{
|
||||
switch (itemId)
|
||||
{
|
||||
case 2515:
|
||||
case 4038:
|
||||
case 5168:
|
||||
case 5169:
|
||||
case 6316:
|
||||
case 7582:
|
||||
case 9668:
|
||||
case 10425:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see L2PetData#getFood()
|
||||
*/
|
||||
@Deprecated
|
||||
public static int[] getFoodItemId(int npcId)
|
||||
{
|
||||
switch (npcId)
|
||||
{
|
||||
case 12077:// Wolf
|
||||
case 12564:// Sin Eater
|
||||
return new int[]
|
||||
{
|
||||
2515
|
||||
};
|
||||
|
||||
case 16030:// Great Wolf
|
||||
case 16025:// Black Wolf
|
||||
case 16037:// White Great Wolf
|
||||
case 16041:// Fenrir
|
||||
case 16042:// White Fenrir
|
||||
return new int[]
|
||||
{
|
||||
9668
|
||||
};
|
||||
|
||||
case 12311:// hatchling of wind
|
||||
case 12312:// hatchling of star
|
||||
case 12313:// hatchling of twilight
|
||||
return new int[]
|
||||
{
|
||||
4038
|
||||
};
|
||||
|
||||
case 12526:// wind strider
|
||||
case 12527:// Star strider
|
||||
case 12528:// Twilight strider
|
||||
case 16038:// red wind strider
|
||||
case 16039:// red Star strider
|
||||
case 16040:// red Twilight strider
|
||||
case 16068:// Guardian Strider
|
||||
return new int[]
|
||||
{
|
||||
5168,
|
||||
5169
|
||||
};
|
||||
|
||||
case 12621: // wyvern
|
||||
return new int[]
|
||||
{
|
||||
6316
|
||||
};
|
||||
|
||||
case 12780:// Baby Buffalo
|
||||
case 12782:// Baby Cougar
|
||||
case 12781:// Baby Kookaburra
|
||||
return new int[]
|
||||
{
|
||||
7582
|
||||
};
|
||||
|
||||
case 16034:// Improved Baby Buffalo
|
||||
case 16036:// Improved Baby Cougar
|
||||
case 16035:// Improved Baby Kookaburra
|
||||
return new int[]
|
||||
{
|
||||
10425
|
||||
};
|
||||
|
||||
default:
|
||||
return new int[]
|
||||
{
|
||||
0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isPetItem(int itemId)
|
||||
{
|
||||
L2Item item = ItemTable.getInstance().getTemplate(itemId);
|
||||
if ((item != null) && (item.getItemType() == L2EtcItemType.PET_COLLAR))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
/*
|
||||
* switch (itemId) { case 2375: // Wolf case 3500: // hatchling of wind case 3501: // hatchling of star case 3502: // hatchling of twilight case 4422: // strider of wind case 4423: // strider of star case 4424: // strider of dusk case 4425: // Sin Eater case 6648: // baby buffalo case 6649:
|
||||
* // baby cougar case 6650: // baby kookaburra case 8663: // Wyvern case 9882: // Great Wolf case 10163: // Black Wolf case 10307: // Great Snow Wolf case 10308: // red strider of wind case 10309: // red strider of star case 10310: // red strider of dusk case 10311: // improved buffalo case
|
||||
* 10312: // improved cougar case 10313: // improved kookaburra case 10426: // Fenrir case 10611: // White Fenrir case 14819: // Guardian Strider return true; default: return false; }
|
||||
*/
|
||||
}
|
||||
|
||||
public static int[] getPetItemsByNpc(int npcId)
|
||||
{
|
||||
switch (npcId)
|
||||
{
|
||||
case 12077:// Wolf
|
||||
return new int[]
|
||||
{
|
||||
2375
|
||||
};
|
||||
case 16025:// Great Wolf
|
||||
return new int[]
|
||||
{
|
||||
9882
|
||||
};
|
||||
case 16030:// Black Wolf
|
||||
return new int[]
|
||||
{
|
||||
10163
|
||||
};
|
||||
case 16037:// White Great Wolf
|
||||
return new int[]
|
||||
{
|
||||
10307
|
||||
};
|
||||
case 16041:// Fenrir
|
||||
return new int[]
|
||||
{
|
||||
10426
|
||||
};
|
||||
case 16042:// White Fenrir
|
||||
return new int[]
|
||||
{
|
||||
10611
|
||||
};
|
||||
case 12564:// Sin Eater
|
||||
return new int[]
|
||||
{
|
||||
4425
|
||||
};
|
||||
|
||||
case 12311:// hatchling of wind
|
||||
case 12312:// hatchling of star
|
||||
case 12313:// hatchling of twilight
|
||||
return new int[]
|
||||
{
|
||||
3500,
|
||||
3501,
|
||||
3502
|
||||
};
|
||||
|
||||
case 12526:// wind strider
|
||||
case 12527:// Star strider
|
||||
case 12528:// Twilight strider
|
||||
case 16038: // red strider of wind
|
||||
case 16039: // red strider of star
|
||||
case 16040: // red strider of dusk
|
||||
case 16068: // Guardian Strider
|
||||
return new int[]
|
||||
{
|
||||
4422,
|
||||
4423,
|
||||
4424,
|
||||
10308,
|
||||
10309,
|
||||
10310,
|
||||
14819
|
||||
};
|
||||
|
||||
case 12621:// Wyvern
|
||||
return new int[]
|
||||
{
|
||||
8663
|
||||
};
|
||||
|
||||
case 12780:// Baby Buffalo
|
||||
case 12782:// Baby Cougar
|
||||
case 12781:// Baby Kookaburra
|
||||
return new int[]
|
||||
{
|
||||
6648,
|
||||
6649,
|
||||
6650
|
||||
};
|
||||
|
||||
case 16034:// Improved Baby Buffalo
|
||||
case 16036:// Improved Baby Cougar
|
||||
case 16035:// Improved Baby Kookaburra
|
||||
return new int[]
|
||||
{
|
||||
10311,
|
||||
10312,
|
||||
10313
|
||||
};
|
||||
|
||||
// unknown item id.. should never happen
|
||||
default:
|
||||
return new int[]
|
||||
{
|
||||
0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isMountable(int npcId)
|
||||
{
|
||||
return (npcId == 12526 // wind strider
|
||||
) || (npcId == 12527 // star strider
|
||||
) || (npcId == 12528 // twilight strider
|
||||
) || (npcId == 12621 // wyvern
|
||||
) || (npcId == 16037 // Great Snow Wolf
|
||||
) || (npcId == 16041 // Fenrir Wolf
|
||||
) || (npcId == 16042 // White Fenrir Wolf
|
||||
) || (npcId == 16038 // Red Wind Strider
|
||||
) || (npcId == 16039 // Red Star Strider
|
||||
) || (npcId == 16040 // Red Twilight Strider
|
||||
) || (npcId == 16068); // Guardian Strider
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final PetDataTable _instance = new PetDataTable();
|
||||
}
|
||||
|
||||
public static void main(String... s)
|
||||
{
|
||||
getInstance();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
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.l2jserver.Config;
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
|
||||
public class PetNameTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(PetNameTable.class.getName());
|
||||
|
||||
private PetNameTable()
|
||||
{
|
||||
}
|
||||
|
||||
public static PetNameTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
public boolean doesPetNameExist(String name, int petNpcId)
|
||||
{
|
||||
boolean result = true;
|
||||
Connection con = null;
|
||||
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT name FROM pets p, items i WHERE p.item_obj_id = i.object_id AND name=? AND i.item_id IN (?)");
|
||||
statement.setString(1, name);
|
||||
|
||||
String cond = "";
|
||||
for (int it : PetDataTable.getPetItemsByNpc(petNpcId))
|
||||
{
|
||||
if (!cond.isEmpty())
|
||||
{
|
||||
cond += ", ";
|
||||
}
|
||||
cond += it;
|
||||
}
|
||||
statement.setString(2, cond);
|
||||
ResultSet rset = statement.executeQuery();
|
||||
result = rset.next();
|
||||
rset.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (SQLException e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Could not check existing petname:" + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
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
|
||||
{
|
||||
_log.warning("ERROR : Pet name pattern of config is wrong!");
|
||||
pattern = Pattern.compile(".*");
|
||||
}
|
||||
Matcher regexp = pattern.matcher(name);
|
||||
if (!regexp.matches())
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isAlphaNumeric(String text)
|
||||
{
|
||||
boolean result = true;
|
||||
char[] chars = text.toCharArray();
|
||||
for (int i = 0; i < chars.length; i++)
|
||||
{
|
||||
if (!Character.isLetterOrDigit(chars[i]))
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final PetNameTable _instance = new PetNameTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TIntIntHashMap;
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Skill;
|
||||
import com.l2jserver.gameserver.skills.SkillsEngine;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class SkillTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(SkillTable.class.getName());
|
||||
|
||||
private final TIntObjectHashMap<L2Skill> _skills;
|
||||
private final TIntIntHashMap _skillMaxLevel;
|
||||
private final TIntArrayList _enchantable;
|
||||
|
||||
public static SkillTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private SkillTable()
|
||||
{
|
||||
_skills = new TIntObjectHashMap<>();
|
||||
_skillMaxLevel = new TIntIntHashMap();
|
||||
_enchantable = new TIntArrayList();
|
||||
load();
|
||||
}
|
||||
|
||||
public void reload()
|
||||
{
|
||||
load();
|
||||
// Reload Skill Tree as well.
|
||||
SkillTreesData.getInstance().load();
|
||||
}
|
||||
|
||||
private void load()
|
||||
{
|
||||
_skills.clear();
|
||||
SkillsEngine.getInstance().loadAllSkills(_skills);
|
||||
|
||||
_skillMaxLevel.clear();
|
||||
for (final L2Skill skill : _skills.getValues(new L2Skill[_skills.size()]))
|
||||
{
|
||||
final int skillId = skill.getId();
|
||||
final int skillLvl = skill.getLevel();
|
||||
if (skillLvl > 99)
|
||||
{
|
||||
if (!_enchantable.contains(skillId))
|
||||
{
|
||||
_enchantable.add(skillId);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// only non-enchanted skills
|
||||
final int maxLvl = _skillMaxLevel.get(skillId);
|
||||
if (skillLvl > maxLvl)
|
||||
{
|
||||
_skillMaxLevel.put(skillId, skillLvl);
|
||||
}
|
||||
}
|
||||
|
||||
// Sorting for binarySearch
|
||||
_enchantable.sort();
|
||||
|
||||
// Reloading as well FrequentSkill enumeration values
|
||||
for (FrequentSkill sk : FrequentSkill.values())
|
||||
{
|
||||
sk._skill = getInfo(sk._id, sk._level);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the skill hash
|
||||
* @param skill The L2Skill to be hashed
|
||||
* @return getSkillHashCode(skill.getId(), skill.getLevel())
|
||||
*/
|
||||
public static int getSkillHashCode(L2Skill skill)
|
||||
{
|
||||
return getSkillHashCode(skill.getId(), skill.getLevel());
|
||||
}
|
||||
|
||||
/**
|
||||
* Centralized method for easier change of the hashing sys
|
||||
* @param skillId The Skill Id
|
||||
* @param skillLevel The Skill Level
|
||||
* @return The Skill hash number
|
||||
*/
|
||||
public static int getSkillHashCode(int skillId, int skillLevel)
|
||||
{
|
||||
return (skillId * 1021) + skillLevel;
|
||||
}
|
||||
|
||||
public final L2Skill getInfo(final int skillId, final int level)
|
||||
{
|
||||
final L2Skill result = _skills.get(getSkillHashCode(skillId, level));
|
||||
if (result != null)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// skill/level not found, fix for transformation scripts
|
||||
final int maxLvl = _skillMaxLevel.get(skillId);
|
||||
// requested level too high
|
||||
if ((maxLvl > 0) && (level > maxLvl))
|
||||
{
|
||||
return _skills.get(getSkillHashCode(skillId, maxLvl));
|
||||
}
|
||||
|
||||
_log.warning("No skill info found for skill id " + skillId + " and skill level " + level + ".");
|
||||
return null;
|
||||
}
|
||||
|
||||
public final int getMaxLevel(final int skillId)
|
||||
{
|
||||
return _skillMaxLevel.get(skillId);
|
||||
}
|
||||
|
||||
public final boolean isEnchantable(final int skillId)
|
||||
{
|
||||
return _enchantable.binarySearch(skillId) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with siege skills. If addNoble == true, will add also Advanced headquarters.
|
||||
*/
|
||||
public L2Skill[] getSiegeSkills(boolean addNoble, boolean hasCastle)
|
||||
{
|
||||
L2Skill[] temp = new L2Skill[2 + (addNoble ? 1 : 0) + (hasCastle ? 2 : 0)];
|
||||
int i = 0;
|
||||
temp[i++] = _skills.get(SkillTable.getSkillHashCode(246, 1));
|
||||
temp[i++] = _skills.get(SkillTable.getSkillHashCode(247, 1));
|
||||
|
||||
if (addNoble)
|
||||
{
|
||||
temp[i++] = _skills.get(SkillTable.getSkillHashCode(326, 1));
|
||||
}
|
||||
if (hasCastle)
|
||||
{
|
||||
temp[i++] = _skills.get(SkillTable.getSkillHashCode(844, 1));
|
||||
temp[i++] = _skills.get(SkillTable.getSkillHashCode(845, 1));
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final SkillTable _instance = new SkillTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum to hold some important references to frequently used (hardcoded) skills in core
|
||||
* @author DrHouse
|
||||
*/
|
||||
public static enum FrequentSkill
|
||||
{
|
||||
RAID_CURSE(4215, 1),
|
||||
RAID_CURSE2(4515, 1),
|
||||
SEAL_OF_RULER(246, 1),
|
||||
BUILD_HEADQUARTERS(247, 1),
|
||||
WYVERN_BREATH(4289, 1),
|
||||
STRIDER_SIEGE_ASSAULT(325, 1),
|
||||
FAKE_PETRIFICATION(4616, 1),
|
||||
FIREWORK(5965, 1),
|
||||
LARGE_FIREWORK(2025, 1),
|
||||
BLESSING_OF_PROTECTION(5182, 1),
|
||||
ARENA_CP_RECOVERY(4380, 1),
|
||||
VOID_BURST(3630, 1),
|
||||
VOID_FLOW(3631, 1),
|
||||
THE_VICTOR_OF_WAR(5074, 1),
|
||||
THE_VANQUISHED_OF_WAR(5075, 1),
|
||||
SPECIAL_TREE_RECOVERY_BONUS(2139, 1);
|
||||
|
||||
protected final int _id;
|
||||
protected final int _level;
|
||||
protected L2Skill _skill = null;
|
||||
|
||||
private FrequentSkill(int id, int level)
|
||||
{
|
||||
_id = id;
|
||||
_level = level;
|
||||
}
|
||||
|
||||
public L2Skill getSkill()
|
||||
{
|
||||
return _skill;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,372 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javolution.util.FastSet;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.instancemanager.DayNightSpawnManager;
|
||||
import com.l2jserver.gameserver.model.L2Spawn;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @author Nightmare
|
||||
* @version $Revision: 1.5.2.6.2.7 $ $Date: 2005/03/27 15:29:18 $
|
||||
*/
|
||||
public class SpawnTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(SpawnTable.class.getName());
|
||||
|
||||
private final FastSet<L2Spawn> _spawntable = new FastSet<L2Spawn>().shared();
|
||||
private int _npcSpawnCount;
|
||||
private int _customSpawnCount;
|
||||
|
||||
public static SpawnTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private SpawnTable()
|
||||
{
|
||||
if (!Config.ALT_DEV_NO_SPAWNS)
|
||||
{
|
||||
fillSpawnTable();
|
||||
}
|
||||
}
|
||||
|
||||
public FastSet<L2Spawn> getSpawnTable()
|
||||
{
|
||||
return _spawntable;
|
||||
}
|
||||
|
||||
private void fillSpawnTable()
|
||||
{
|
||||
Connection con = null;
|
||||
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT count, npc_templateid, locx, locy, locz, heading, respawn_delay, loc_id, periodOfDay FROM spawnlist");
|
||||
ResultSet rset = statement.executeQuery();
|
||||
|
||||
L2Spawn spawnDat;
|
||||
L2NpcTemplate template1;
|
||||
|
||||
while (rset.next())
|
||||
{
|
||||
template1 = NpcTable.getInstance().getTemplate(rset.getInt("npc_templateid"));
|
||||
if (template1 != null)
|
||||
{
|
||||
if (template1.type.equalsIgnoreCase("L2SiegeGuard"))
|
||||
{
|
||||
// Don't spawn
|
||||
}
|
||||
else if (template1.type.equalsIgnoreCase("L2RaidBoss"))
|
||||
{
|
||||
// Don't spawn raidboss
|
||||
}
|
||||
else if (!Config.ALLOW_CLASS_MASTERS && template1.type.equals("L2ClassMaster"))
|
||||
{
|
||||
// Dont' spawn class masters
|
||||
}
|
||||
else
|
||||
{
|
||||
spawnDat = new L2Spawn(template1);
|
||||
spawnDat.setAmount(rset.getInt("count"));
|
||||
spawnDat.setLocx(rset.getInt("locx"));
|
||||
spawnDat.setLocy(rset.getInt("locy"));
|
||||
spawnDat.setLocz(rset.getInt("locz"));
|
||||
spawnDat.setHeading(rset.getInt("heading"));
|
||||
spawnDat.setRespawnDelay(rset.getInt("respawn_delay"));
|
||||
int loc_id = rset.getInt("loc_id");
|
||||
spawnDat.setLocation(loc_id);
|
||||
|
||||
switch (rset.getInt("periodOfDay"))
|
||||
{
|
||||
case 0: // default
|
||||
_npcSpawnCount += spawnDat.init();
|
||||
break;
|
||||
case 1: // Day
|
||||
DayNightSpawnManager.getInstance().addDayCreature(spawnDat);
|
||||
_npcSpawnCount++;
|
||||
break;
|
||||
case 2: // Night
|
||||
DayNightSpawnManager.getInstance().addNightCreature(spawnDat);
|
||||
_npcSpawnCount++;
|
||||
break;
|
||||
}
|
||||
|
||||
_spawntable.add(spawnDat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("SpawnTable: Data missing in NPC table for ID: " + rset.getInt("npc_templateid") + ".");
|
||||
}
|
||||
}
|
||||
rset.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// problem with initializing spawn, go to next one
|
||||
_log.log(Level.WARNING, "SpawnTable: Spawn could not be initialized: " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
|
||||
_log.info("SpawnTable: Loaded " + _spawntable.size() + " Npc Spawn Locations.");
|
||||
|
||||
if (Config.CUSTOM_SPAWNLIST_TABLE)
|
||||
{
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT count, npc_templateid, locx, locy, locz, heading, respawn_delay, loc_id, periodOfDay FROM custom_spawnlist");
|
||||
ResultSet rset = statement.executeQuery();
|
||||
|
||||
L2Spawn spawnDat;
|
||||
L2NpcTemplate template1;
|
||||
|
||||
while (rset.next())
|
||||
{
|
||||
template1 = NpcTable.getInstance().getTemplate(rset.getInt("npc_templateid"));
|
||||
if (template1 != null)
|
||||
{
|
||||
if (template1.type.equalsIgnoreCase("L2SiegeGuard"))
|
||||
{
|
||||
// Don't spawn
|
||||
}
|
||||
else if (template1.type.equalsIgnoreCase("L2RaidBoss"))
|
||||
{
|
||||
// Don't spawn raidboss
|
||||
}
|
||||
else if (!Config.ALLOW_CLASS_MASTERS && template1.type.equals("L2ClassMaster"))
|
||||
{
|
||||
// Dont' spawn class masters
|
||||
}
|
||||
else
|
||||
{
|
||||
spawnDat = new L2Spawn(template1);
|
||||
spawnDat.setAmount(rset.getInt("count"));
|
||||
spawnDat.setLocx(rset.getInt("locx"));
|
||||
spawnDat.setLocy(rset.getInt("locy"));
|
||||
spawnDat.setLocz(rset.getInt("locz"));
|
||||
spawnDat.setHeading(rset.getInt("heading"));
|
||||
spawnDat.setRespawnDelay(rset.getInt("respawn_delay"));
|
||||
spawnDat.setCustom(true);
|
||||
int loc_id = rset.getInt("loc_id");
|
||||
spawnDat.setLocation(loc_id);
|
||||
|
||||
switch (rset.getInt("periodOfDay"))
|
||||
{
|
||||
case 0: // default
|
||||
_customSpawnCount += spawnDat.init();
|
||||
break;
|
||||
case 1: // Day
|
||||
DayNightSpawnManager.getInstance().addDayCreature(spawnDat);
|
||||
_customSpawnCount++;
|
||||
break;
|
||||
case 2: // Night
|
||||
DayNightSpawnManager.getInstance().addNightCreature(spawnDat);
|
||||
_customSpawnCount++;
|
||||
break;
|
||||
}
|
||||
|
||||
_spawntable.add(spawnDat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.warning("CustomSpawnTable: Data missing in NPC table for ID: " + rset.getInt("npc_templateid") + ".");
|
||||
}
|
||||
}
|
||||
rset.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// problem with initializing spawn, go to next one
|
||||
_log.log(Level.WARNING, "CustomSpawnTable: Spawn could not be initialized: " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
_log.info("CustomSpawnTable: Loaded " + _customSpawnCount + " Npc Spawn Locations.");
|
||||
|
||||
}
|
||||
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
_log.fine("SpawnTable: Spawning completed, total number of NPCs in the world: " + (_npcSpawnCount + _customSpawnCount));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void addNewSpawn(L2Spawn spawn, boolean storeInDb)
|
||||
{
|
||||
_spawntable.add(spawn);
|
||||
|
||||
if (storeInDb)
|
||||
{
|
||||
String spawnTable;
|
||||
if (spawn.isCustom() && Config.CUSTOM_SPAWNLIST_TABLE)
|
||||
{
|
||||
spawnTable = "custom_spawnlist";
|
||||
}
|
||||
else
|
||||
{
|
||||
spawnTable = "spawnlist";
|
||||
}
|
||||
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("INSERT INTO " + spawnTable + "(count,npc_templateid,locx,locy,locz,heading,respawn_delay,loc_id) values(?,?,?,?,?,?,?,?)");
|
||||
statement.setInt(1, spawn.getAmount());
|
||||
statement.setInt(2, spawn.getNpcid());
|
||||
statement.setInt(3, spawn.getLocx());
|
||||
statement.setInt(4, spawn.getLocy());
|
||||
statement.setInt(5, spawn.getLocz());
|
||||
statement.setInt(6, spawn.getHeading());
|
||||
statement.setInt(7, spawn.getRespawnDelay() / 1000);
|
||||
statement.setInt(8, spawn.getLocation());
|
||||
statement.execute();
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// problem with storing spawn
|
||||
_log.log(Level.WARNING, "SpawnTable: Could not store spawn in the DB:" + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteSpawn(L2Spawn spawn, boolean updateDb)
|
||||
{
|
||||
|
||||
if (!_spawntable.remove(spawn))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (updateDb)
|
||||
{
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("DELETE FROM " + (spawn.isCustom() ? "custom_spawnlist" : "spawnlist") + " WHERE locx=? AND locy=? AND locz=? AND npc_templateid=? AND heading=?");
|
||||
statement.setInt(1, spawn.getLocx());
|
||||
statement.setInt(2, spawn.getLocy());
|
||||
statement.setInt(3, spawn.getLocz());
|
||||
statement.setInt(4, spawn.getNpcid());
|
||||
statement.setInt(5, spawn.getHeading());
|
||||
statement.execute();
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// problem with deleting spawn
|
||||
_log.log(Level.WARNING, "SpawnTable: Spawn " + spawn + " could not be removed from DB: " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// just wrapper
|
||||
public void reloadAll()
|
||||
{
|
||||
fillSpawnTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the spawn of a NPC<BR>
|
||||
* <BR>
|
||||
* @param npcId : ID of the NPC to find.
|
||||
* @return
|
||||
*/
|
||||
public void findNPCInstances(L2PcInstance activeChar, int npcId, int teleportIndex, boolean showposition)
|
||||
{
|
||||
int index = 0;
|
||||
for (L2Spawn spawn : _spawntable)
|
||||
{
|
||||
|
||||
if (npcId == spawn.getNpcid())
|
||||
{
|
||||
index++;
|
||||
L2Npc _npc = spawn.getLastSpawn();
|
||||
if (teleportIndex > -1)
|
||||
{
|
||||
if (teleportIndex == index)
|
||||
{
|
||||
if (showposition && (_npc != null))
|
||||
{
|
||||
activeChar.teleToLocation(_npc.getX(), _npc.getY(), _npc.getZ(), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
activeChar.teleToLocation(spawn.getLocx(), spawn.getLocy(), spawn.getLocz(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (showposition && (_npc != null))
|
||||
{
|
||||
activeChar.sendMessage(index + " - " + spawn.getTemplate().name + " (" + spawn + "): " + _npc.getX() + " " + _npc.getY() + " " + _npc.getZ());
|
||||
}
|
||||
else
|
||||
{
|
||||
activeChar.sendMessage(index + " - " + spawn.getTemplate().name + " (" + spawn + "): " + spawn.getLocx() + " " + spawn.getLocy() + " " + spawn.getLocz());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (index == 0)
|
||||
{
|
||||
activeChar.sendMessage("No current spawns found.");
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final SpawnTable _instance = new SpawnTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.idfactory.IdFactory;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2StaticObjectInstance;
|
||||
import com.l2jserver.gameserver.templates.StatsSet;
|
||||
import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
|
||||
|
||||
public class StaticObjects
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(StaticObjects.class.getName());
|
||||
|
||||
private final TIntObjectHashMap<L2StaticObjectInstance> _staticObjects;
|
||||
|
||||
public static StaticObjects getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private StaticObjects()
|
||||
{
|
||||
_staticObjects = new TIntObjectHashMap<>();
|
||||
parseData();
|
||||
_log.info("StaticObject: Loaded " + _staticObjects.size() + " StaticObject Templates.");
|
||||
}
|
||||
|
||||
private void parseData()
|
||||
{
|
||||
File doorData = new File(Config.DATAPACK_ROOT, "data/staticobjects.csv");
|
||||
try (LineNumberReader lnr = new LineNumberReader(new BufferedReader(new FileReader(doorData))))
|
||||
{
|
||||
String line = null;
|
||||
while ((line = lnr.readLine()) != null)
|
||||
{
|
||||
if ((line.trim().length() == 0) || line.startsWith("#"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
L2StaticObjectInstance obj = parse(line);
|
||||
_staticObjects.put(obj.getStaticObjectId(), obj);
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
_log.warning("staticobjects.csv is missing in data folder");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Error while creating StaticObjects table " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public static L2StaticObjectInstance parse(String line)
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(line, ";");
|
||||
|
||||
st.nextToken(); // Pass over static object name (not used in server)
|
||||
|
||||
int id = Integer.parseInt(st.nextToken());
|
||||
int x = Integer.parseInt(st.nextToken());
|
||||
int y = Integer.parseInt(st.nextToken());
|
||||
int z = Integer.parseInt(st.nextToken());
|
||||
int type = Integer.parseInt(st.nextToken());
|
||||
String texture = st.nextToken();
|
||||
int map_x = Integer.parseInt(st.nextToken());
|
||||
int map_y = Integer.parseInt(st.nextToken());
|
||||
|
||||
StatsSet npcDat = new StatsSet();
|
||||
npcDat.set("npcId", id);
|
||||
npcDat.set("level", 0);
|
||||
npcDat.set("jClass", "staticobject");
|
||||
|
||||
npcDat.set("baseSTR", 0);
|
||||
npcDat.set("baseCON", 0);
|
||||
npcDat.set("baseDEX", 0);
|
||||
npcDat.set("baseINT", 0);
|
||||
npcDat.set("baseWIT", 0);
|
||||
npcDat.set("baseMEN", 0);
|
||||
|
||||
npcDat.set("baseShldDef", 0);
|
||||
npcDat.set("baseShldRate", 0);
|
||||
npcDat.set("baseAccCombat", 38);
|
||||
npcDat.set("baseEvasRate", 38);
|
||||
npcDat.set("baseCritRate", 38);
|
||||
|
||||
// npcDat.set("name", "");
|
||||
npcDat.set("collision_radius", 10);
|
||||
npcDat.set("collision_height", 10);
|
||||
npcDat.set("sex", "male");
|
||||
npcDat.set("type", "");
|
||||
npcDat.set("baseAtkRange", 0);
|
||||
npcDat.set("baseMpMax", 0);
|
||||
npcDat.set("baseCpMax", 0);
|
||||
npcDat.set("rewardExp", 0);
|
||||
npcDat.set("rewardSp", 0);
|
||||
npcDat.set("basePAtk", 0);
|
||||
npcDat.set("baseMAtk", 0);
|
||||
npcDat.set("basePAtkSpd", 0);
|
||||
npcDat.set("aggroRange", 0);
|
||||
npcDat.set("baseMAtkSpd", 0);
|
||||
npcDat.set("rhand", 0);
|
||||
npcDat.set("lhand", 0);
|
||||
npcDat.set("armor", 0);
|
||||
npcDat.set("baseWalkSpd", 0);
|
||||
npcDat.set("baseRunSpd", 0);
|
||||
npcDat.set("name", "");
|
||||
npcDat.set("baseHpMax", 1);
|
||||
npcDat.set("baseHpReg", 3.e-3f);
|
||||
npcDat.set("baseMpReg", 3.e-3f);
|
||||
npcDat.set("basePDef", 1);
|
||||
npcDat.set("baseMDef", 1);
|
||||
|
||||
L2CharTemplate template = new L2CharTemplate(npcDat);
|
||||
L2StaticObjectInstance obj = new L2StaticObjectInstance(IdFactory.getInstance().getNextId(), template, id);
|
||||
obj.setType(type);
|
||||
obj.setXYZ(x, y, z);
|
||||
obj.setMap(texture, map_x, map_y);
|
||||
obj.spawnMe();
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public void putObject(L2StaticObjectInstance obj)
|
||||
{
|
||||
_staticObjects.put(obj.getStaticObjectId(), obj);
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final StaticObjects _instance = new StaticObjects();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @author FBIagent
|
||||
*
|
||||
*/
|
||||
|
||||
package com.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Scanner;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.model.L2SummonItem;
|
||||
|
||||
public class SummonItemsData
|
||||
{
|
||||
protected static final Logger _log = Logger.getLogger(SummonItemsData.class.getName());
|
||||
private TIntObjectHashMap<L2SummonItem> _summonitems;
|
||||
|
||||
public static SummonItemsData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private SummonItemsData()
|
||||
{
|
||||
_summonitems = new TIntObjectHashMap<>();
|
||||
|
||||
Scanner s;
|
||||
|
||||
try
|
||||
{
|
||||
s = new Scanner(new File(Config.DATAPACK_ROOT + "/data/summon_items.csv"));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.warning("Summon items data: Can not find '" + Config.DATAPACK_ROOT + "/data/summon_items.csv'");
|
||||
return;
|
||||
}
|
||||
|
||||
int lineCount = 0;
|
||||
|
||||
while (s.hasNextLine())
|
||||
{
|
||||
lineCount++;
|
||||
|
||||
String line = s.nextLine();
|
||||
|
||||
if (line.startsWith("#"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (line.isEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] lineSplit = line.split(";");
|
||||
boolean ok = true;
|
||||
int itemID = 0, npcID = 0;
|
||||
byte summonType = 0;
|
||||
int despawn = -1;
|
||||
|
||||
try
|
||||
{
|
||||
itemID = Integer.parseInt(lineSplit[0]);
|
||||
npcID = Integer.parseInt(lineSplit[1]);
|
||||
summonType = Byte.parseByte(lineSplit[2]);
|
||||
if (summonType == 0)
|
||||
{
|
||||
despawn = Integer.parseInt(lineSplit[3]);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.warning("Summon items data: Error in line " + lineCount + " -> incomplete/invalid data or wrong seperator!");
|
||||
_log.warning(" " + line);
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
L2SummonItem summonitem = new L2SummonItem(itemID, npcID, summonType, despawn);
|
||||
_summonitems.put(itemID, summonitem);
|
||||
}
|
||||
|
||||
_log.info("Summon items data: Loaded " + _summonitems.size() + " summon items.");
|
||||
}
|
||||
|
||||
public L2SummonItem getSummonItem(int itemId)
|
||||
{
|
||||
return _summonitems.get(itemId);
|
||||
}
|
||||
|
||||
public int[] itemIDs()
|
||||
{
|
||||
int size = _summonitems.size();
|
||||
int[] result = new int[size];
|
||||
int i = 0;
|
||||
for (Object si : _summonitems.getValues())
|
||||
{
|
||||
result[i++] = ((L2SummonItem) si).getItemId();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final SummonItemsData _instance = new SummonItemsData();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javolution.util.FastList;
|
||||
import javolution.util.FastMap;
|
||||
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
||||
|
||||
public class SummonSkillsTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(SummonSkillsTable.class.getName());
|
||||
private final FastMap<Integer, Map<Integer, L2PetSkillLearn>> _skillTrees;
|
||||
|
||||
public static SummonSkillsTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
public void reload()
|
||||
{
|
||||
_skillTrees.clear();
|
||||
load();
|
||||
}
|
||||
|
||||
private SummonSkillsTable()
|
||||
{
|
||||
_skillTrees = new FastMap<>();
|
||||
load();
|
||||
}
|
||||
|
||||
private void load()
|
||||
{
|
||||
int npcId = 0;
|
||||
int count = 0;
|
||||
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
try
|
||||
{
|
||||
PreparedStatement statement = con.prepareStatement("SELECT id FROM npc WHERE type IN ('L2Pet','L2BabyPet','L2SiegeSummon') ORDER BY id");
|
||||
ResultSet petlist = statement.executeQuery();
|
||||
Map<Integer, L2PetSkillLearn> map;
|
||||
L2PetSkillLearn skillLearn;
|
||||
|
||||
PreparedStatement statement2 = con.prepareStatement("SELECT minLvl, skillId, skillLvl FROM pets_skills where templateId=? ORDER BY skillId, skillLvl");
|
||||
while (petlist.next())
|
||||
{
|
||||
map = new FastMap<>();
|
||||
npcId = petlist.getInt("id");
|
||||
statement2.setInt(1, npcId);
|
||||
ResultSet skilltree = statement2.executeQuery();
|
||||
statement2.clearParameters();
|
||||
|
||||
while (skilltree.next())
|
||||
{
|
||||
int id = skilltree.getInt("skillId");
|
||||
int lvl = skilltree.getInt("skillLvl");
|
||||
int minLvl = skilltree.getInt("minLvl");
|
||||
|
||||
skillLearn = new L2PetSkillLearn(id, lvl, minLvl);
|
||||
map.put(SkillTable.getSkillHashCode(id, lvl + 1), skillLearn);
|
||||
}
|
||||
_skillTrees.put(npcId, map);
|
||||
skilltree.close();
|
||||
|
||||
count += map.size();
|
||||
_log.fine("PetSkillsTable: skill tree for pet " + npcId + " has " + map.size() + " skills");
|
||||
}
|
||||
statement2.close();
|
||||
petlist.close();
|
||||
statement.close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error while creating pet skill tree (Pet ID " + npcId + "): " + e.getMessage(), e);
|
||||
}
|
||||
_log.info("PetSkillsTable: Loaded " + count + " skills.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error while loading pet skills tables: " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
|
||||
public int getAvailableLevel(L2Summon cha, int skillId)
|
||||
{
|
||||
int lvl = 0;
|
||||
if (!_skillTrees.containsKey(cha.getNpcId()))
|
||||
{
|
||||
_log.warning("Pet id " + cha.getNpcId() + " does not have any skills assigned.");
|
||||
return lvl;
|
||||
}
|
||||
Collection<L2PetSkillLearn> skills = _skillTrees.get(cha.getNpcId()).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
|
||||
int maxLvl = SkillTable.getInstance().getMaxLevel(temp.getId());
|
||||
if (lvl > maxLvl)
|
||||
{
|
||||
lvl = maxLvl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (temp.getMinLevel() <= cha.getLevel())
|
||||
{
|
||||
if (temp.getLevel() > lvl)
|
||||
{
|
||||
lvl = temp.getLevel();
|
||||
}
|
||||
}
|
||||
}
|
||||
return lvl;
|
||||
}
|
||||
|
||||
public FastList<Integer> getAvailableSkills(L2Summon cha)
|
||||
{
|
||||
FastList<Integer> skillIds = new FastList<>();
|
||||
if (!_skillTrees.containsKey(cha.getNpcId()))
|
||||
{
|
||||
_log.warning("Pet id " + cha.getNpcId() + " does not have any skills assigned.");
|
||||
return skillIds;
|
||||
}
|
||||
Collection<L2PetSkillLearn> skills = _skillTrees.get(cha.getNpcId()).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;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final SummonSkillsTable _instance = new SummonSkillsTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.model.L2TeleportLocation;
|
||||
|
||||
/**
|
||||
* This class ...
|
||||
* @version $Revision: 1.3.2.2.2.3 $ $Date: 2005/03/27 15:29:18 $
|
||||
*/
|
||||
public class TeleportLocationTable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(TeleportLocationTable.class.getName());
|
||||
|
||||
private TIntObjectHashMap<L2TeleportLocation> _teleports;
|
||||
|
||||
public static TeleportLocationTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private TeleportLocationTable()
|
||||
{
|
||||
reloadAll();
|
||||
}
|
||||
|
||||
public void reloadAll()
|
||||
{
|
||||
_teleports = new TIntObjectHashMap<>();
|
||||
|
||||
Connection con = null;
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT id, loc_x, loc_y, loc_z, price, fornoble, itemId FROM teleport");
|
||||
ResultSet rset = statement.executeQuery();
|
||||
L2TeleportLocation teleport;
|
||||
|
||||
while (rset.next())
|
||||
{
|
||||
teleport = new L2TeleportLocation();
|
||||
|
||||
teleport.setTeleId(rset.getInt("id"));
|
||||
teleport.setLocX(rset.getInt("loc_x"));
|
||||
teleport.setLocY(rset.getInt("loc_y"));
|
||||
teleport.setLocZ(rset.getInt("loc_z"));
|
||||
teleport.setPrice(rset.getInt("price"));
|
||||
teleport.setIsForNoble(rset.getInt("fornoble") == 1);
|
||||
teleport.setItemId(rset.getInt("itemId"));
|
||||
|
||||
_teleports.put(teleport.getTeleId(), teleport);
|
||||
}
|
||||
|
||||
rset.close();
|
||||
statement.close();
|
||||
|
||||
_log.info("TeleportLocationTable: Loaded " + _teleports.size() + " Teleport Location Templates.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.SEVERE, "Error loading Teleport Table.", e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
|
||||
if (Config.CUSTOM_TELEPORT_TABLE)
|
||||
{
|
||||
try
|
||||
{
|
||||
con = L2DatabaseFactory.getInstance().getConnection();
|
||||
PreparedStatement statement = con.prepareStatement("SELECT id, loc_x, loc_y, loc_z, price, fornoble, itemId FROM custom_teleport");
|
||||
ResultSet rset = statement.executeQuery();
|
||||
L2TeleportLocation teleport;
|
||||
int _cTeleCount = _teleports.size();
|
||||
while (rset.next())
|
||||
{
|
||||
teleport = new L2TeleportLocation();
|
||||
teleport.setTeleId(rset.getInt("id"));
|
||||
teleport.setLocX(rset.getInt("loc_x"));
|
||||
teleport.setLocY(rset.getInt("loc_y"));
|
||||
teleport.setLocZ(rset.getInt("loc_z"));
|
||||
teleport.setPrice(rset.getInt("price"));
|
||||
teleport.setIsForNoble(rset.getInt("fornoble") == 1);
|
||||
teleport.setItemId(rset.getInt("itemId"));
|
||||
|
||||
_teleports.put(teleport.getTeleId(), teleport);
|
||||
}
|
||||
rset.close();
|
||||
statement.close();
|
||||
_cTeleCount = _teleports.size() - _cTeleCount;
|
||||
if (_cTeleCount > 0)
|
||||
{
|
||||
_log.info("TeleportLocationTable: Loaded " + _cTeleCount + " Custom Teleport Location Templates.");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Error while creating custom teleport table " + e.getMessage(), e);
|
||||
}
|
||||
finally
|
||||
{
|
||||
L2DatabaseFactory.close(con);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param template id
|
||||
* @return
|
||||
*/
|
||||
public L2TeleportLocation getTemplate(int id)
|
||||
{
|
||||
return _teleports.get(id);
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final TeleportLocationTable _instance = new TeleportLocationTable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* 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.l2jserver.gameserver.datatables;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javolution.util.FastList;
|
||||
import javolution.util.FastMap;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.model.entity.ActionKey;
|
||||
|
||||
/**
|
||||
* @author mrTJO
|
||||
*/
|
||||
public class UITable
|
||||
{
|
||||
private static Logger _log = Logger.getLogger(UITable.class.getName());
|
||||
|
||||
private final Map<Integer, List<ActionKey>> _storedKeys;
|
||||
private final Map<Integer, List<Integer>> _storedCategories;
|
||||
|
||||
public static UITable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private UITable()
|
||||
{
|
||||
_storedKeys = new FastMap<>();
|
||||
_storedCategories = new FastMap<>();
|
||||
|
||||
parseCatData();
|
||||
parseKeyData();
|
||||
_log.info("UITable: Loaded " + _storedCategories.size() + " Categories.");
|
||||
_log.info("UITable: Loaded " + _storedKeys.size() + " Keys.");
|
||||
}
|
||||
|
||||
private void parseCatData()
|
||||
{
|
||||
File uiData = new File(Config.DATAPACK_ROOT, "data/uicats_en.csv");
|
||||
try (LineNumberReader lnr = new LineNumberReader(new BufferedReader(new FileReader(uiData))))
|
||||
{
|
||||
String line = null;
|
||||
while ((line = lnr.readLine()) != null)
|
||||
{
|
||||
if ((line.trim().length() == 0) || line.startsWith("#"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
StringTokenizer st = new StringTokenizer(line, ";");
|
||||
|
||||
int cat = Integer.parseInt(st.nextToken());
|
||||
int cmd = Integer.parseInt(st.nextToken());
|
||||
|
||||
insertCategory(cat, cmd);
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
_log.warning("uicats_en.csv is missing in data folder");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Error while creating UI Default Categories table " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseKeyData()
|
||||
{
|
||||
File uiData = new File(Config.DATAPACK_ROOT, "data/uikeys_en.csv");
|
||||
try (LineNumberReader lnr = new LineNumberReader(new BufferedReader(new FileReader(uiData))))
|
||||
{
|
||||
String line = null;
|
||||
while ((line = lnr.readLine()) != null)
|
||||
{
|
||||
if ((line.trim().length() == 0) || line.startsWith("#"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
StringTokenizer st = new StringTokenizer(line, ";");
|
||||
|
||||
int cat = Integer.parseInt(st.nextToken());
|
||||
int cmd = Integer.parseInt(st.nextToken());
|
||||
int key = Integer.parseInt(st.nextToken());
|
||||
int tk1 = Integer.parseInt(st.nextToken());
|
||||
int tk2 = Integer.parseInt(st.nextToken());
|
||||
int shw = Integer.parseInt(st.nextToken());
|
||||
|
||||
insertKey(cat, cmd, key, tk1, tk2, shw);
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
_log.warning("uikeys_en.csv is missing in data folder");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.log(Level.WARNING, "Error while creating UI Default Keys table " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void insertCategory(int cat, int cmd)
|
||||
{
|
||||
if (_storedCategories.containsKey(cat))
|
||||
{
|
||||
_storedCategories.get(cat).add(cmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Integer> tmp = new FastList<>();
|
||||
tmp.add(cmd);
|
||||
_storedCategories.put(cat, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
private void insertKey(int cat, int cmdId, int key, int tgKey1, int tgKey2, int show)
|
||||
{
|
||||
ActionKey tmk = new ActionKey(cat, cmdId, key, tgKey1, tgKey2, show);
|
||||
if (_storedKeys.containsKey(cat))
|
||||
{
|
||||
_storedKeys.get(cat).add(tmk);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<ActionKey> tmp = new FastList<>();
|
||||
tmp.add(tmk);
|
||||
_storedKeys.put(cat, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, List<Integer>> getCategories()
|
||||
{
|
||||
return _storedCategories;
|
||||
}
|
||||
|
||||
public Map<Integer, List<ActionKey>> getKeys()
|
||||
{
|
||||
return _storedKeys;
|
||||
}
|
||||
|
||||
@SuppressWarnings("synthetic-access")
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final UITable _instance = new UITable();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user