Sync with L2JServer Jan 24th 2015.
This commit is contained in:
644
trunk/java/com/l2jserver/gameserver/data/xml/IXmlReader.java
Normal file
644
trunk/java/com/l2jserver/gameserver/data/xml/IXmlReader.java
Normal file
@ -0,0 +1,644 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.util.file.filter.XMLFilter;
|
||||
|
||||
/**
|
||||
* Abstract class for XML parsers.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public interface IXmlReader
|
||||
{
|
||||
static final Logger LOGGER = Logger.getLogger(IXmlReader.class.getName());
|
||||
|
||||
static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
|
||||
static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
|
||||
/** The default file filter, ".xml" files only. */
|
||||
static final XMLFilter XML_FILTER = new XMLFilter();
|
||||
|
||||
/**
|
||||
* This method can be used to load/reload the data.<br>
|
||||
* It's highly recommended to clear the data storage, either the list or map.
|
||||
*/
|
||||
public void load();
|
||||
|
||||
/**
|
||||
* Wrapper for {@link #parseFile(File)} method.
|
||||
* @param path the relative path to the datapack root of the XML file to parse.
|
||||
*/
|
||||
default void parseDatapackFile(String path)
|
||||
{
|
||||
parseFile(new File(Config.DATAPACK_ROOT, path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a single XML file.<br>
|
||||
* If the file was successfully parsed, call {@link #parseDocument(Document, File)} for the parsed document.<br>
|
||||
* <b>Validation is enforced.</b>
|
||||
* @param f the XML file to parse.
|
||||
*/
|
||||
default void parseFile(File f)
|
||||
{
|
||||
if (!getCurrentFileFilter().accept(f))
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Could not parse " + f.getName() + " is not a file or it doesn't exist!");
|
||||
return;
|
||||
}
|
||||
|
||||
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
dbf.setNamespaceAware(true);
|
||||
dbf.setValidating(true);
|
||||
dbf.setIgnoringComments(true);
|
||||
try
|
||||
{
|
||||
dbf.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
|
||||
final DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
db.setErrorHandler(new XMLErrorHandler());
|
||||
parseDocument(db.parse(f), f);
|
||||
}
|
||||
catch (SAXParseException e)
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Could not parse file " + f.getName() + " at line " + e.getLineNumber() + ", column " + e.getColumnNumber() + ": " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Could not parse file " + f.getName() + ": " + e.getMessage());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for {@link #parseDirectory(File, boolean)}.
|
||||
* @param file the path to the directory where the XML files are.
|
||||
* @return {@code false} if it fails to find the directory, {@code true} otherwise.
|
||||
*/
|
||||
default boolean parseDirectory(File file)
|
||||
{
|
||||
return parseDirectory(file, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all XML files from {@code path} and calls {@link #parseFile(File)} for each one of them.
|
||||
* @param dir the directory object to scan.
|
||||
* @param recursive parses all sub folders if there is.
|
||||
* @return {@code false} if it fails to find the directory, {@code true} otherwise.
|
||||
*/
|
||||
default boolean parseDirectory(File dir, boolean recursive)
|
||||
{
|
||||
if (!dir.exists())
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Folder " + dir.getAbsolutePath() + " doesn't exist!");
|
||||
return false;
|
||||
}
|
||||
|
||||
final File[] listOfFiles = dir.listFiles();
|
||||
for (File f : listOfFiles)
|
||||
{
|
||||
if (recursive && f.isDirectory())
|
||||
{
|
||||
parseDirectory(f, recursive);
|
||||
}
|
||||
else if (getCurrentFileFilter().accept(f))
|
||||
{
|
||||
parseFile(f);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for {@link #parseDirectory(File, boolean)}.
|
||||
* @param path the path to the directory where the XML files are
|
||||
* @param recursive parses all sub folders if there is
|
||||
* @return {@code false} if it fails to find the directory, {@code true} otherwise
|
||||
*/
|
||||
default boolean parseDatapackDirectory(String path, boolean recursive)
|
||||
{
|
||||
return parseDirectory(new File(Config.DATAPACK_ROOT, path), recursive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method that when implemented will parse the current document.<br>
|
||||
* Is expected to be call from {@link #parseFile(File)}.
|
||||
* @param doc the current document to parse
|
||||
* @param f the current file
|
||||
*/
|
||||
default void parseDocument(Document doc, File f)
|
||||
{
|
||||
parseDocument(doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method that when implemented will parse the current document.<br>
|
||||
* Is expected to be call from {@link #parseFile(File)}.
|
||||
* @param doc the current document to parse
|
||||
*/
|
||||
default void parseDocument(Document doc)
|
||||
{
|
||||
LOGGER.severe("Parser not implemented!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a boolean value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Boolean parseBoolean(Node node, Boolean defaultValue)
|
||||
{
|
||||
return node != null ? Boolean.valueOf(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a boolean value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Boolean parseBoolean(Node node)
|
||||
{
|
||||
return parseBoolean(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a boolean value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Boolean parseBoolean(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseBoolean(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a boolean value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Boolean parseBoolean(NamedNodeMap attrs, String name, Boolean defaultValue)
|
||||
{
|
||||
return parseBoolean(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a byte value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Byte parseByte(Node node, Byte defaultValue)
|
||||
{
|
||||
return node != null ? Byte.valueOf(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a byte value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Byte parseByte(Node node)
|
||||
{
|
||||
return parseByte(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a byte value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Byte parseByte(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseByte(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a byte value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Byte parseByte(NamedNodeMap attrs, String name, Byte defaultValue)
|
||||
{
|
||||
return parseByte(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a short value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Short parseShort(Node node, Short defaultValue)
|
||||
{
|
||||
return node != null ? Short.valueOf(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a short value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Short parseShort(Node node)
|
||||
{
|
||||
return parseShort(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a short value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Short parseShort(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseShort(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a short value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Short parseShort(NamedNodeMap attrs, String name, Short defaultValue)
|
||||
{
|
||||
return parseShort(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an int value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default int parseInt(Node node, Integer defaultValue)
|
||||
{
|
||||
return node != null ? Integer.parseInt(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an int value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default int parseInt(Node node)
|
||||
{
|
||||
return parseInt(node, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an integer value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Integer parseInteger(Node node, Integer defaultValue)
|
||||
{
|
||||
return node != null ? Integer.valueOf(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an integer value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Integer parseInteger(Node node)
|
||||
{
|
||||
return parseInteger(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an integer value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Integer parseInteger(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseInteger(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an integer value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Integer parseInteger(NamedNodeMap attrs, String name, Integer defaultValue)
|
||||
{
|
||||
return parseInteger(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a long value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Long parseLong(Node node, Long defaultValue)
|
||||
{
|
||||
return node != null ? Long.valueOf(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a long value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Long parseLong(Node node)
|
||||
{
|
||||
return parseLong(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a long value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Long parseLong(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseLong(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a long value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Long parseLong(NamedNodeMap attrs, String name, Long defaultValue)
|
||||
{
|
||||
return parseLong(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a float value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Float parseFloat(Node node, Float defaultValue)
|
||||
{
|
||||
return node != null ? Float.valueOf(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a float value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Float parseFloat(Node node)
|
||||
{
|
||||
return parseFloat(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a float value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Float parseFloat(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseFloat(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a float value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Float parseFloat(NamedNodeMap attrs, String name, Float defaultValue)
|
||||
{
|
||||
return parseFloat(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a double value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Double parseDouble(Node node, Double defaultValue)
|
||||
{
|
||||
return node != null ? Double.valueOf(node.getNodeValue()) : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a double value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Double parseDouble(Node node)
|
||||
{
|
||||
return parseDouble(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a double value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default Double parseDouble(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseDouble(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a double value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default Double parseDouble(NamedNodeMap attrs, String name, Double defaultValue)
|
||||
{
|
||||
return parseDouble(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string value.
|
||||
* @param node the node to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default String parseString(Node node, String defaultValue)
|
||||
{
|
||||
return node != null ? node.getNodeValue() : defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string value.
|
||||
* @param node the node to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default String parseString(Node node)
|
||||
{
|
||||
return parseString(node, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null, the value of the parsed node, otherwise null
|
||||
*/
|
||||
default String parseString(NamedNodeMap attrs, String name)
|
||||
{
|
||||
return parseString(attrs.getNamedItem(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a string value.
|
||||
* @param attrs the attributes
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null, the value of the parsed node, otherwise the default value
|
||||
*/
|
||||
default String parseString(NamedNodeMap attrs, String name, String defaultValue)
|
||||
{
|
||||
return parseString(attrs.getNamedItem(name), defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an enumerated value.
|
||||
* @param <T> the enumerated type
|
||||
* @param node the node to parse
|
||||
* @param clazz the class of the enumerated
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null and the node value is valid the parsed value, otherwise the default value
|
||||
*/
|
||||
default <T extends Enum<T>> T parseEnum(Node node, Class<T> clazz, T defaultValue)
|
||||
{
|
||||
if (node == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return Enum.valueOf(clazz, node.getNodeValue());
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
LOGGER.warning("Invalid value specified for node: " + node.getNodeName() + " specified value: " + node.getNodeValue() + " should be enum value of \"" + clazz.getSimpleName() + "\" using default value: " + defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an enumerated value.
|
||||
* @param <T> the enumerated type
|
||||
* @param node the node to parse
|
||||
* @param clazz the class of the enumerated
|
||||
* @return if the node is not null and the node value is valid the parsed value, otherwise null
|
||||
*/
|
||||
default <T extends Enum<T>> T parseEnum(Node node, Class<T> clazz)
|
||||
{
|
||||
return parseEnum(node, clazz, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an enumerated value.
|
||||
* @param <T> the enumerated type
|
||||
* @param attrs the attributes
|
||||
* @param clazz the class of the enumerated
|
||||
* @param name the name of the attribute to parse
|
||||
* @return if the node is not null and the node value is valid the parsed value, otherwise null
|
||||
*/
|
||||
default <T extends Enum<T>> T parseEnum(NamedNodeMap attrs, Class<T> clazz, String name)
|
||||
{
|
||||
return parseEnum(attrs.getNamedItem(name), clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an enumerated value.
|
||||
* @param <T> the enumerated type
|
||||
* @param attrs the attributes
|
||||
* @param clazz the class of the enumerated
|
||||
* @param name the name of the attribute to parse
|
||||
* @param defaultValue the default value
|
||||
* @return if the node is not null and the node value is valid the parsed value, otherwise the default value
|
||||
*/
|
||||
default <T extends Enum<T>> T parseEnum(NamedNodeMap attrs, Class<T> clazz, String name, T defaultValue)
|
||||
{
|
||||
return parseEnum(attrs.getNamedItem(name), clazz, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current file filter.
|
||||
* @return the current file filter
|
||||
*/
|
||||
default FileFilter getCurrentFileFilter()
|
||||
{
|
||||
return XML_FILTER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple XML error handler.
|
||||
* @author Zoey76
|
||||
*/
|
||||
class XMLErrorHandler implements ErrorHandler
|
||||
{
|
||||
@Override
|
||||
public void warning(SAXParseException e) throws SAXParseException
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(SAXParseException e) throws SAXParseException
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fatalError(SAXParseException e) throws SAXParseException
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.holders.RangeAbilityPointsHolder;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public final class AbilityPointsData implements IXmlReader
|
||||
{
|
||||
private final List<RangeAbilityPointsHolder> _points = new ArrayList<>();
|
||||
|
||||
protected AbilityPointsData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
_points.clear();
|
||||
parseFile(new File("config/AbilityPoints.xml"));
|
||||
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _points.size() + " range fees.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("points".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
final NamedNodeMap attrs = d.getAttributes();
|
||||
final int from = parseInteger(attrs, "from");
|
||||
final int to = parseInteger(attrs, "to");
|
||||
final int costs = parseInteger(attrs, "costs");
|
||||
_points.add(new RangeAbilityPointsHolder(from, to, costs));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RangeAbilityPointsHolder getHolder(int points)
|
||||
{
|
||||
for (RangeAbilityPointsHolder holder : _points)
|
||||
{
|
||||
if ((holder.getMin() <= points) && (holder.getMax() >= points))
|
||||
{
|
||||
return holder;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public long getPrice(int points)
|
||||
{
|
||||
points++; // for next point
|
||||
final RangeAbilityPointsHolder holder = getHolder(points);
|
||||
if (holder == null)
|
||||
{
|
||||
final RangeAbilityPointsHolder prevHolder = getHolder(points - 1);
|
||||
if (prevHolder != null)
|
||||
{
|
||||
return prevHolder.getSP();
|
||||
}
|
||||
|
||||
// No data found
|
||||
return points >= 13 ? 1_000_000_000 : points >= 9 ? 750_000_000 : points >= 5 ? 500_000_000 : 250_000_000;
|
||||
}
|
||||
return holder.getSP();
|
||||
}
|
||||
|
||||
public static final AbilityPointsData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final AbilityPointsData _instance = new AbilityPointsData();
|
||||
}
|
||||
}
|
357
trunk/java/com/l2jserver/gameserver/data/xml/impl/AdminData.java
Normal file
357
trunk/java/com/l2jserver/gameserver/data/xml/impl/AdminData.java
Normal file
@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.L2AccessLevel;
|
||||
import com.l2jserver.gameserver.model.L2AdminCommandAccessRight;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.L2GameServerPacket;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
|
||||
/**
|
||||
* Loads administrator access levels and commands.
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public final class AdminData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, L2AccessLevel> _accessLevels = new HashMap<>();
|
||||
private final Map<String, L2AdminCommandAccessRight> _adminCommandAccessRights = new HashMap<>();
|
||||
private final Map<L2PcInstance, Boolean> _gmList = new FastMap<L2PcInstance, Boolean>().shared();
|
||||
private int _highestLevel = 0;
|
||||
|
||||
protected AdminData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
_accessLevels.clear();
|
||||
_adminCommandAccessRights.clear();
|
||||
parseDatapackFile("config/accessLevels.xml");
|
||||
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _accessLevels.size() + " Access Levels.");
|
||||
parseDatapackFile("config/adminCommands.xml");
|
||||
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _adminCommandAccessRights.size() + " Access Commands.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
Node attr;
|
||||
StatsSet set;
|
||||
L2AccessLevel level;
|
||||
L2AdminCommandAccessRight command;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("access".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
set = new StatsSet();
|
||||
attrs = d.getAttributes();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
attr = attrs.item(i);
|
||||
set.set(attr.getNodeName(), attr.getNodeValue());
|
||||
}
|
||||
level = new L2AccessLevel(set);
|
||||
if (level.getLevel() > _highestLevel)
|
||||
{
|
||||
_highestLevel = level.getLevel();
|
||||
}
|
||||
_accessLevels.put(level.getLevel(), level);
|
||||
}
|
||||
else if ("admin".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
set = new StatsSet();
|
||||
attrs = d.getAttributes();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
attr = attrs.item(i);
|
||||
set.set(attr.getNodeName(), attr.getNodeValue());
|
||||
}
|
||||
command = new L2AdminCommandAccessRight(set);
|
||||
_adminCommandAccessRights.put(command.getAdminCommand(), command);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the access level by characterAccessLevel.
|
||||
* @param accessLevelNum as int
|
||||
* @return the access level instance by char access level
|
||||
*/
|
||||
public L2AccessLevel getAccessLevel(int accessLevelNum)
|
||||
{
|
||||
if (accessLevelNum < 0)
|
||||
{
|
||||
return _accessLevels.get(-1);
|
||||
}
|
||||
else if (!_accessLevels.containsKey(accessLevelNum))
|
||||
{
|
||||
_accessLevels.put(accessLevelNum, new L2AccessLevel());
|
||||
}
|
||||
return _accessLevels.get(accessLevelNum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the master access level.
|
||||
* @return the master access level
|
||||
*/
|
||||
public L2AccessLevel getMasterAccessLevel()
|
||||
{
|
||||
return _accessLevels.get(_highestLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for access level.
|
||||
* @param id the id
|
||||
* @return {@code true}, if successful, {@code false} otherwise
|
||||
*/
|
||||
public boolean hasAccessLevel(int id)
|
||||
{
|
||||
return _accessLevels.containsKey(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for access.
|
||||
* @param adminCommand the admin command
|
||||
* @param accessLevel the access level
|
||||
* @return {@code true}, if successful, {@code false} otherwise
|
||||
*/
|
||||
public boolean hasAccess(String adminCommand, L2AccessLevel accessLevel)
|
||||
{
|
||||
L2AdminCommandAccessRight acar = _adminCommandAccessRights.get(adminCommand);
|
||||
if (acar == null)
|
||||
{
|
||||
// Trying to avoid the spam for next time when the gm would try to use the same command
|
||||
if ((accessLevel.getLevel() > 0) && (accessLevel.getLevel() == _highestLevel))
|
||||
{
|
||||
acar = new L2AdminCommandAccessRight(adminCommand, true, accessLevel.getLevel());
|
||||
_adminCommandAccessRights.put(adminCommand, acar);
|
||||
LOGGER.info(getClass().getSimpleName() + ": No rights defined for admin command " + adminCommand + " auto setting accesslevel: " + accessLevel.getLevel() + " !");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.info(getClass().getSimpleName() + ": No rights defined for admin command " + adminCommand + " !");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return acar.hasAccess(accessLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Require confirm.
|
||||
* @param command the command
|
||||
* @return {@code true}, if the command require confirmation, {@code false} otherwise
|
||||
*/
|
||||
public boolean requireConfirm(String command)
|
||||
{
|
||||
final L2AdminCommandAccessRight acar = _adminCommandAccessRights.get(command);
|
||||
if (acar == null)
|
||||
{
|
||||
LOGGER.info(getClass().getSimpleName() + ": No rights defined for admin command " + command + ".");
|
||||
return false;
|
||||
}
|
||||
return acar.getRequireConfirm();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the all GMs.
|
||||
* @param includeHidden the include hidden
|
||||
* @return the all GMs
|
||||
*/
|
||||
public List<L2PcInstance> getAllGms(boolean includeHidden)
|
||||
{
|
||||
final List<L2PcInstance> tmpGmList = new ArrayList<>();
|
||||
for (Entry<L2PcInstance, Boolean> entry : _gmList.entrySet())
|
||||
{
|
||||
if (includeHidden || !entry.getValue())
|
||||
{
|
||||
tmpGmList.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
return tmpGmList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the all GM names.
|
||||
* @param includeHidden the include hidden
|
||||
* @return the all GM names
|
||||
*/
|
||||
public List<String> getAllGmNames(boolean includeHidden)
|
||||
{
|
||||
final List<String> tmpGmList = new ArrayList<>();
|
||||
for (Entry<L2PcInstance, Boolean> entry : _gmList.entrySet())
|
||||
{
|
||||
if (!entry.getValue())
|
||||
{
|
||||
tmpGmList.add(entry.getKey().getName());
|
||||
}
|
||||
else if (includeHidden)
|
||||
{
|
||||
tmpGmList.add(entry.getKey().getName() + " (invis)");
|
||||
}
|
||||
}
|
||||
return tmpGmList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a L2PcInstance player to the Set _gmList.
|
||||
* @param player the player
|
||||
* @param hidden the hidden
|
||||
*/
|
||||
public void addGm(L2PcInstance player, boolean hidden)
|
||||
{
|
||||
_gmList.put(player, hidden);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a GM.
|
||||
* @param player the player
|
||||
*/
|
||||
public void deleteGm(L2PcInstance player)
|
||||
{
|
||||
_gmList.remove(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* GM will be displayed on clients GM list.
|
||||
* @param player the player
|
||||
*/
|
||||
public void showGm(L2PcInstance player)
|
||||
{
|
||||
if (_gmList.containsKey(player))
|
||||
{
|
||||
_gmList.put(player, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GM will no longer be displayed on clients GM list.
|
||||
* @param player the player
|
||||
*/
|
||||
public void hideGm(L2PcInstance player)
|
||||
{
|
||||
if (_gmList.containsKey(player))
|
||||
{
|
||||
_gmList.put(player, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is GM online.
|
||||
* @param includeHidden the include hidden
|
||||
* @return true, if is GM online
|
||||
*/
|
||||
public boolean isGmOnline(boolean includeHidden)
|
||||
{
|
||||
for (Entry<L2PcInstance, Boolean> entry : _gmList.entrySet())
|
||||
{
|
||||
if (includeHidden || !entry.getValue())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send list to player.
|
||||
* @param player the player
|
||||
*/
|
||||
public void sendListToPlayer(L2PcInstance player)
|
||||
{
|
||||
if (isGmOnline(player.isGM()))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.GM_LIST);
|
||||
|
||||
for (String name : getAllGmNames(player.isGM()))
|
||||
{
|
||||
SystemMessage sm = SystemMessage.getSystemMessage(SystemMessageId.GM_C1);
|
||||
sm.addString(name);
|
||||
player.sendPacket(sm);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THERE_ARE_NO_GMS_CURRENTLY_VISIBLE_IN_THE_PUBLIC_LIST_AS_THEY_MAY_BE_PERFORMING_OTHER_FUNCTIONS_AT_THE_MOMENT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast to GMs.
|
||||
* @param packet the packet
|
||||
*/
|
||||
public void broadcastToGMs(L2GameServerPacket packet)
|
||||
{
|
||||
for (L2PcInstance gm : getAllGms(true))
|
||||
{
|
||||
gm.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast message to GMs.
|
||||
* @param message the message
|
||||
*/
|
||||
public void broadcastMessageToGMs(String message)
|
||||
{
|
||||
for (L2PcInstance gm : getAllGms(true))
|
||||
{
|
||||
gm.sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of AdminTable.
|
||||
* @return AccessLevels: the one and only instance of this class<br>
|
||||
*/
|
||||
public static AdminData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final AdminData _instance = new AdminData();
|
||||
}
|
||||
}
|
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.L2ArmorSet;
|
||||
import com.l2jserver.gameserver.model.holders.ArmorsetSkillHolder;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
|
||||
/**
|
||||
* Loads armor set bonuses.
|
||||
* @author godson, Luno, UnAfraid
|
||||
*/
|
||||
public final class ArmorSetsData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, L2ArmorSet> _armorSets = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new armor sets data.
|
||||
*/
|
||||
protected ArmorSetsData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_armorSets.clear();
|
||||
parseDatapackDirectory("data/stats/armorsets", false);
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _armorSets.size() + " Armor sets.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
L2ArmorSet set;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("set".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
set = new L2ArmorSet();
|
||||
set.setMinimumPieces(parseInteger(d.getAttributes(), "minimumPieces"));
|
||||
|
||||
for (Node a = d.getFirstChild(); a != null; a = a.getNextSibling())
|
||||
{
|
||||
attrs = a.getAttributes();
|
||||
switch (a.getNodeName())
|
||||
{
|
||||
case "chest":
|
||||
{
|
||||
set.addChest(parseInteger(attrs, "id"));
|
||||
break;
|
||||
}
|
||||
case "feet":
|
||||
{
|
||||
set.addFeet(parseInteger(attrs, "id"));
|
||||
break;
|
||||
}
|
||||
case "gloves":
|
||||
{
|
||||
set.addGloves(parseInteger(attrs, "id"));
|
||||
break;
|
||||
}
|
||||
case "head":
|
||||
{
|
||||
set.addHead(parseInteger(attrs, "id"));
|
||||
break;
|
||||
}
|
||||
case "legs":
|
||||
{
|
||||
set.addLegs(parseInteger(attrs, "id"));
|
||||
break;
|
||||
}
|
||||
case "shield":
|
||||
{
|
||||
set.addShield(parseInteger(attrs, "id"));
|
||||
break;
|
||||
}
|
||||
case "skill":
|
||||
{
|
||||
final int skillId = parseInteger(attrs, "id");
|
||||
final int skillLevel = parseInteger(attrs, "level");
|
||||
final int minimumPieces = parseInteger(attrs, "minimumPieces", set.getMinimumPieces());
|
||||
set.addSkill(new ArmorsetSkillHolder(skillId, skillLevel, minimumPieces));
|
||||
break;
|
||||
}
|
||||
case "shield_skill":
|
||||
{
|
||||
int skillId = parseInteger(attrs, "id");
|
||||
int skillLevel = parseInteger(attrs, "level");
|
||||
set.addShieldSkill(new SkillHolder(skillId, skillLevel));
|
||||
break;
|
||||
}
|
||||
case "enchant6skill":
|
||||
{
|
||||
final int skillId = parseInteger(attrs, "id");
|
||||
final int skillLevel = parseInteger(attrs, "level");
|
||||
final int minimumEnchant = parseInteger(attrs, "minimumEnchant", 6);
|
||||
set.addEnchantSkill(new ArmorsetSkillHolder(skillId, skillLevel, minimumEnchant));
|
||||
break;
|
||||
}
|
||||
case "con":
|
||||
{
|
||||
set.addCon(parseInteger(attrs, "val"));
|
||||
break;
|
||||
}
|
||||
case "dex":
|
||||
{
|
||||
set.addDex(parseInteger(attrs, "val"));
|
||||
break;
|
||||
}
|
||||
case "str":
|
||||
{
|
||||
set.addStr(parseInteger(attrs, "val"));
|
||||
break;
|
||||
}
|
||||
case "men":
|
||||
{
|
||||
set.addMen(parseInteger(attrs, "val"));
|
||||
break;
|
||||
}
|
||||
case "wit":
|
||||
{
|
||||
set.addWit(parseInteger(attrs, "val"));
|
||||
break;
|
||||
}
|
||||
case "int":
|
||||
{
|
||||
set.addInt(parseInteger(attrs, "val"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int chestId : set.getChests())
|
||||
{
|
||||
_armorSets.put(chestId, set);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is armor set.
|
||||
* @param chestId the chest Id to verify.
|
||||
* @return {@code true} if the chest Id belongs to a registered armor set, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isArmorSet(int chestId)
|
||||
{
|
||||
return _armorSets.containsKey(chestId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sets the.
|
||||
* @param chestId the chest Id identifying the armor set.
|
||||
* @return the armor set associated to the give chest Id.
|
||||
*/
|
||||
public L2ArmorSet getSet(int chestId)
|
||||
{
|
||||
return _armorSets.get(chestId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of ArmorSetsData.
|
||||
* @return single instance of ArmorSetsData
|
||||
*/
|
||||
public static ArmorSetsData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final ArmorSetsData _instance = new ArmorSetsData();
|
||||
}
|
||||
}
|
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.enums.Race;
|
||||
import com.l2jserver.gameserver.enums.Sex;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.beautyshop.BeautyData;
|
||||
import com.l2jserver.gameserver.model.beautyshop.BeautyItem;
|
||||
|
||||
/**
|
||||
* @author Sdw
|
||||
*/
|
||||
public final class BeautyShopData implements IXmlReader
|
||||
{
|
||||
private final Map<Race, Map<Sex, BeautyData>> _beautyList = new HashMap<>();
|
||||
private final Map<Sex, BeautyData> _beautyData = new HashMap<>();
|
||||
|
||||
protected BeautyShopData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
_beautyList.clear();
|
||||
_beautyData.clear();
|
||||
parseDatapackFile("data/BeautyShop.xml");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
StatsSet set;
|
||||
Node att;
|
||||
Race race = null;
|
||||
Sex sex = null;
|
||||
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("race".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
att = d.getAttributes().getNamedItem("type");
|
||||
if (att != null)
|
||||
{
|
||||
race = parseEnum(att, Race.class);
|
||||
}
|
||||
|
||||
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
|
||||
{
|
||||
if ("sex".equalsIgnoreCase(b.getNodeName()))
|
||||
{
|
||||
att = b.getAttributes().getNamedItem("type");
|
||||
if (att != null)
|
||||
{
|
||||
sex = parseEnum(att, Sex.class);
|
||||
}
|
||||
|
||||
BeautyData beautyData = new BeautyData();
|
||||
|
||||
for (Node a = b.getFirstChild(); a != null; a = a.getNextSibling())
|
||||
{
|
||||
if ("hair".equalsIgnoreCase(a.getNodeName()))
|
||||
{
|
||||
attrs = a.getAttributes();
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
BeautyItem hair = new BeautyItem(set);
|
||||
|
||||
for (Node g = a.getFirstChild(); g != null; g = g.getNextSibling())
|
||||
{
|
||||
if ("color".equalsIgnoreCase(g.getNodeName()))
|
||||
{
|
||||
attrs = g.getAttributes();
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
hair.addColor(set);
|
||||
}
|
||||
}
|
||||
beautyData.addHair(hair);
|
||||
}
|
||||
else if ("face".equalsIgnoreCase(a.getNodeName()))
|
||||
{
|
||||
attrs = a.getAttributes();
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
BeautyItem face = new BeautyItem(set);
|
||||
beautyData.addFace(face);
|
||||
}
|
||||
}
|
||||
|
||||
_beautyData.put(sex, beautyData);
|
||||
}
|
||||
}
|
||||
_beautyList.put(race, _beautyData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasBeautyData(Race race, Sex sex)
|
||||
{
|
||||
return _beautyList.containsKey(race) && _beautyList.get(race).containsKey(sex);
|
||||
}
|
||||
|
||||
public BeautyData getBeautyData(Race race, Sex sex)
|
||||
{
|
||||
if (_beautyList.containsKey(race))
|
||||
{
|
||||
return _beautyList.get(race).get(sex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static BeautyShopData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final BeautyShopData _instance = new BeautyShopData();
|
||||
}
|
||||
}
|
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.L2DatabaseFactory;
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.datatables.ItemTable;
|
||||
import com.l2jserver.gameserver.model.buylist.L2BuyList;
|
||||
import com.l2jserver.gameserver.model.buylist.Product;
|
||||
import com.l2jserver.gameserver.model.items.L2Item;
|
||||
import com.l2jserver.util.file.filter.NumericNameFilter;
|
||||
|
||||
/**
|
||||
* Loads buy lists for NPCs.
|
||||
* @author NosBit
|
||||
*/
|
||||
public final class BuyListData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, L2BuyList> _buyLists = new HashMap<>();
|
||||
private static final FileFilter NUMERIC_FILTER = new NumericNameFilter();
|
||||
|
||||
protected BuyListData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
_buyLists.clear();
|
||||
parseDatapackDirectory("data/buylists", false);
|
||||
if (Config.CUSTOM_BUYLIST_LOAD)
|
||||
{
|
||||
parseDatapackDirectory("data/buylists/custom", false);
|
||||
}
|
||||
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _buyLists.size() + " BuyLists.");
|
||||
|
||||
try (Connection con = L2DatabaseFactory.getInstance().getConnection();
|
||||
Statement statement = con.createStatement();
|
||||
ResultSet rs = statement.executeQuery("SELECT * FROM `buylists`"))
|
||||
{
|
||||
while (rs.next())
|
||||
{
|
||||
int buyListId = rs.getInt("buylist_id");
|
||||
int itemId = rs.getInt("item_id");
|
||||
long count = rs.getLong("count");
|
||||
long nextRestockTime = rs.getLong("next_restock_time");
|
||||
final L2BuyList buyList = getBuyList(buyListId);
|
||||
if (buyList == null)
|
||||
{
|
||||
LOGGER.warning("BuyList found in database but not loaded from xml! BuyListId: " + buyListId);
|
||||
continue;
|
||||
}
|
||||
final Product product = buyList.getProductByItemId(itemId);
|
||||
if (product == null)
|
||||
{
|
||||
LOGGER.warning("ItemId found in database but not loaded from xml! BuyListId: " + buyListId + " ItemId: " + itemId);
|
||||
continue;
|
||||
}
|
||||
if (count < product.getMaxCount())
|
||||
{
|
||||
product.setCount(count);
|
||||
product.restartRestockTask(nextRestockTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Failed to load buyList data from database.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc, File f)
|
||||
{
|
||||
try
|
||||
{
|
||||
final int buyListId = Integer.parseInt(f.getName().replaceAll(".xml", ""));
|
||||
|
||||
for (Node node = doc.getFirstChild(); node != null; node = node.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(node.getNodeName()))
|
||||
{
|
||||
final L2BuyList buyList = new L2BuyList(buyListId);
|
||||
for (Node list_node = node.getFirstChild(); list_node != null; list_node = list_node.getNextSibling())
|
||||
{
|
||||
if ("item".equalsIgnoreCase(list_node.getNodeName()))
|
||||
{
|
||||
int itemId = -1;
|
||||
long price = -1;
|
||||
long restockDelay = -1;
|
||||
long count = -1;
|
||||
NamedNodeMap attrs = list_node.getAttributes();
|
||||
Node attr = attrs.getNamedItem("id");
|
||||
itemId = Integer.parseInt(attr.getNodeValue());
|
||||
attr = attrs.getNamedItem("price");
|
||||
if (attr != null)
|
||||
{
|
||||
price = Long.parseLong(attr.getNodeValue());
|
||||
}
|
||||
attr = attrs.getNamedItem("restock_delay");
|
||||
if (attr != null)
|
||||
{
|
||||
restockDelay = Long.parseLong(attr.getNodeValue());
|
||||
}
|
||||
attr = attrs.getNamedItem("count");
|
||||
if (attr != null)
|
||||
{
|
||||
count = Long.parseLong(attr.getNodeValue());
|
||||
}
|
||||
final L2Item item = ItemTable.getInstance().getTemplate(itemId);
|
||||
if (item != null)
|
||||
{
|
||||
buyList.addProduct(new Product(buyList.getListId(), item, price, restockDelay, count));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warning("Item not found. BuyList:" + buyList.getListId() + " ItemID:" + itemId + " File:" + f.getName());
|
||||
}
|
||||
}
|
||||
else if ("npcs".equalsIgnoreCase(list_node.getNodeName()))
|
||||
{
|
||||
for (Node npcs_node = list_node.getFirstChild(); npcs_node != null; npcs_node = npcs_node.getNextSibling())
|
||||
{
|
||||
if ("npc".equalsIgnoreCase(npcs_node.getNodeName()))
|
||||
{
|
||||
int npcId = Integer.parseInt(npcs_node.getTextContent());
|
||||
buyList.addAllowedNpc(npcId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_buyLists.put(buyList.getListId(), buyList);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Failed to load buyList data from xml File:" + f.getName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileFilter getCurrentFileFilter()
|
||||
{
|
||||
return NUMERIC_FILTER;
|
||||
}
|
||||
|
||||
public L2BuyList getBuyList(int listId)
|
||||
{
|
||||
return _buyLists.get(listId);
|
||||
}
|
||||
|
||||
public static BuyListData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final BuyListData _instance = new BuyListData();
|
||||
}
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.enums.CastleSide;
|
||||
import com.l2jserver.gameserver.model.holders.CastleSpawnHolder;
|
||||
|
||||
/**
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class CastleData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, List<CastleSpawnHolder>> _castles = new HashMap<>();
|
||||
|
||||
protected CastleData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_castles.clear();
|
||||
parseDatapackDirectory("data/castles", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node listNode = doc.getFirstChild(); listNode != null; listNode = listNode.getNextSibling())
|
||||
{
|
||||
if ("list".equals(listNode.getNodeName()))
|
||||
{
|
||||
for (Node castleNode = listNode.getFirstChild(); castleNode != null; castleNode = castleNode.getNextSibling())
|
||||
{
|
||||
if ("castle".equals(castleNode.getNodeName()))
|
||||
{
|
||||
final int castleId = parseInteger(castleNode.getAttributes(), "id");
|
||||
final List<CastleSpawnHolder> spawns = new ArrayList<>();
|
||||
|
||||
for (Node tpNode = castleNode.getFirstChild(); tpNode != null; tpNode = tpNode.getNextSibling())
|
||||
{
|
||||
if ("spawn".equals(tpNode.getNodeName()))
|
||||
{
|
||||
final CastleSide side = parseEnum(tpNode.getAttributes(), CastleSide.class, "castleSide", CastleSide.NEUTRAL);
|
||||
for (Node npcNode = tpNode.getFirstChild(); npcNode != null; npcNode = npcNode.getNextSibling())
|
||||
{
|
||||
if ("npc".equals(npcNode.getNodeName()))
|
||||
{
|
||||
final NamedNodeMap np = npcNode.getAttributes();
|
||||
final int npcId = parseInteger(np, "id");
|
||||
final int x = parseInteger(np, "x");
|
||||
final int y = parseInteger(np, "y");
|
||||
final int z = parseInteger(np, "z");
|
||||
final int heading = parseInteger(np, "heading");
|
||||
|
||||
spawns.add(new CastleSpawnHolder(npcId, side, x, y, z, heading));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_castles.put(castleId, spawns);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final List<CastleSpawnHolder> getSpawnsForSide(int castleId, CastleSide side)
|
||||
{
|
||||
return _castles.getOrDefault(castleId, Collections.emptyList()).stream().filter(s -> s.getSide() == side).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of TeleportersData.
|
||||
* @return single instance of TeleportersData
|
||||
*/
|
||||
public static CastleData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final CastleData _instance = new CastleData();
|
||||
}
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.enums.CategoryType;
|
||||
|
||||
/**
|
||||
* Loads the category data with Class or NPC IDs.
|
||||
* @author NosBit, xban1x
|
||||
*/
|
||||
public final class CategoryData implements IXmlReader
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(CategoryData.class.getName());
|
||||
|
||||
private final Map<CategoryType, Set<Integer>> _categories = new HashMap<>();
|
||||
|
||||
protected CategoryData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_categories.clear();
|
||||
parseDatapackFile("data/categoryData.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _categories.size() + " Categories.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node node = doc.getFirstChild(); node != null; node = node.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(node.getNodeName()))
|
||||
{
|
||||
for (Node list_node = node.getFirstChild(); list_node != null; list_node = list_node.getNextSibling())
|
||||
{
|
||||
if ("category".equalsIgnoreCase(list_node.getNodeName()))
|
||||
{
|
||||
final NamedNodeMap attrs = list_node.getAttributes();
|
||||
final CategoryType categoryType = CategoryType.findByName(attrs.getNamedItem("name").getNodeValue());
|
||||
if (categoryType == null)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Can't find category by name :" + attrs.getNamedItem("name").getNodeValue());
|
||||
continue;
|
||||
}
|
||||
|
||||
final Set<Integer> ids = new HashSet<>();
|
||||
for (Node category_node = list_node.getFirstChild(); category_node != null; category_node = category_node.getNextSibling())
|
||||
{
|
||||
if ("id".equalsIgnoreCase(category_node.getNodeName()))
|
||||
{
|
||||
ids.add(Integer.parseInt(category_node.getTextContent()));
|
||||
}
|
||||
}
|
||||
_categories.put(categoryType, ids);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if ID is in category.
|
||||
* @param type The category type
|
||||
* @param id The id to be checked
|
||||
* @return {@code true} if id is in category, {@code false} if id is not in category or category was not found
|
||||
*/
|
||||
public boolean isInCategory(CategoryType type, int id)
|
||||
{
|
||||
final Set<Integer> category = getCategoryByType(type);
|
||||
if (category == null)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Can't find category type :" + type);
|
||||
return false;
|
||||
}
|
||||
return category.contains(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the category by category type.
|
||||
* @param type The category type
|
||||
* @return A {@code Set} containing all the IDs in category if category is found, {@code null} if category was not found
|
||||
*/
|
||||
public Set<Integer> getCategoryByType(CategoryType type)
|
||||
{
|
||||
return _categories.get(type);
|
||||
}
|
||||
|
||||
public static CategoryData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final CategoryData _instance = new CategoryData();
|
||||
}
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
import com.l2jserver.gameserver.model.base.ClassInfo;
|
||||
|
||||
/**
|
||||
* Loads the the list of classes and it's info.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public final class ClassListData implements IXmlReader
|
||||
{
|
||||
private final Map<ClassId, ClassInfo> _classData = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new class list data.
|
||||
*/
|
||||
protected ClassListData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_classData.clear();
|
||||
parseDatapackFile("data/stats/chars/classList.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _classData.size() + " Class data.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
Node attr;
|
||||
ClassId classId;
|
||||
String className;
|
||||
ClassId parentClassId;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equals(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
attrs = d.getAttributes();
|
||||
if ("class".equals(d.getNodeName()))
|
||||
{
|
||||
attr = attrs.getNamedItem("classId");
|
||||
classId = ClassId.getClassId(parseInteger(attr));
|
||||
attr = attrs.getNamedItem("name");
|
||||
className = attr.getNodeValue();
|
||||
attr = attrs.getNamedItem("parentClassId");
|
||||
parentClassId = (attr != null) ? ClassId.getClassId(parseInteger(attr)) : null;
|
||||
_classData.put(classId, new ClassInfo(classId, className, parentClassId));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the class list.
|
||||
* @return the complete class list.
|
||||
*/
|
||||
public Map<ClassId, ClassInfo> getClassList()
|
||||
{
|
||||
return _classData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the class info.
|
||||
* @param classId the class Id.
|
||||
* @return the class info related to the given {@code classId}.
|
||||
*/
|
||||
public ClassInfo getClass(ClassId classId)
|
||||
{
|
||||
return _classData.get(classId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the class info.
|
||||
* @param classId the class Id as integer.
|
||||
* @return the class info related to the given {@code classId}.
|
||||
*/
|
||||
public ClassInfo getClass(int classId)
|
||||
{
|
||||
final ClassId id = ClassId.getClassId(classId);
|
||||
return (id != null) ? _classData.get(id) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of ClassListData.
|
||||
* @return single instance of ClassListData
|
||||
*/
|
||||
public static ClassListData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final ClassListData _instance = new ClassListData();
|
||||
}
|
||||
}
|
263
trunk/java/com/l2jserver/gameserver/data/xml/impl/DoorData.java
Normal file
263
trunk/java/com/l2jserver/gameserver/data/xml/impl/DoorData.java
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.idfactory.IdFactory;
|
||||
import com.l2jserver.gameserver.instancemanager.InstanceManager;
|
||||
import com.l2jserver.gameserver.instancemanager.MapRegionManager;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2DoorTemplate;
|
||||
import com.l2jserver.gameserver.pathfinding.AbstractNodeLoc;
|
||||
|
||||
/**
|
||||
* Loads doors.
|
||||
* @author JIV, GodKratos, UnAfraid
|
||||
*/
|
||||
public class DoorData implements IXmlReader
|
||||
{
|
||||
private static final Map<String, Set<Integer>> _groups = new HashMap<>();
|
||||
private final Map<Integer, L2DoorInstance> _doors = new HashMap<>();
|
||||
private final Map<Integer, StatsSet> _templates = new HashMap<>();
|
||||
private final Map<Integer, List<L2DoorInstance>> _regions = new HashMap<>();
|
||||
|
||||
protected DoorData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_doors.clear();
|
||||
_groups.clear();
|
||||
_regions.clear();
|
||||
parseDatapackFile("data/doors.xml");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
Node att;
|
||||
StatsSet set;
|
||||
for (Node a = doc.getFirstChild(); a != null; a = a.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(a.getNodeName()))
|
||||
{
|
||||
for (Node b = a.getFirstChild(); b != null; b = b.getNextSibling())
|
||||
{
|
||||
if ("door".equalsIgnoreCase(b.getNodeName()))
|
||||
{
|
||||
attrs = b.getAttributes();
|
||||
set = new StatsSet();
|
||||
set.set("baseHpMax", 1); // Avoid doors without HP value created dead due to default value 0 in L2CharTemplate
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
makeDoor(set);
|
||||
_templates.put(set.getInt("id"), set);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _doors.size() + " Door Templates for " + _regions.size() + " regions.");
|
||||
}
|
||||
|
||||
public void insertCollisionData(StatsSet set)
|
||||
{
|
||||
int posX, posY, nodeX, nodeY, height;
|
||||
height = set.getInt("height");
|
||||
String[] pos = set.getString("node1").split(",");
|
||||
nodeX = Integer.parseInt(pos[0]);
|
||||
nodeY = Integer.parseInt(pos[1]);
|
||||
pos = set.getString("node2").split(",");
|
||||
posX = Integer.parseInt(pos[0]);
|
||||
posY = Integer.parseInt(pos[1]);
|
||||
int collisionRadius; // (max) radius for movement checks
|
||||
collisionRadius = Math.min(Math.abs(nodeX - posX), Math.abs(nodeY - posY));
|
||||
if (collisionRadius < 20)
|
||||
{
|
||||
collisionRadius = 20;
|
||||
}
|
||||
|
||||
set.set("collision_radius", collisionRadius);
|
||||
set.set("collision_height", height);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param set
|
||||
*/
|
||||
private void makeDoor(StatsSet set)
|
||||
{
|
||||
insertCollisionData(set);
|
||||
L2DoorTemplate template = new L2DoorTemplate(set);
|
||||
L2DoorInstance door = new L2DoorInstance(IdFactory.getInstance().getNextId(), template);
|
||||
door.setCurrentHp(door.getMaxHp());
|
||||
door.spawnMe(template.getX(), template.getY(), template.getZ());
|
||||
putDoor(door, MapRegionManager.getInstance().getMapRegionLocId(door));
|
||||
}
|
||||
|
||||
public StatsSet getDoorTemplate(int doorId)
|
||||
{
|
||||
return _templates.get(doorId);
|
||||
}
|
||||
|
||||
public L2DoorInstance getDoor(int doorId)
|
||||
{
|
||||
return _doors.get(doorId);
|
||||
}
|
||||
|
||||
public void putDoor(L2DoorInstance door, int region)
|
||||
{
|
||||
_doors.put(door.getId(), door);
|
||||
|
||||
if (!_regions.containsKey(region))
|
||||
{
|
||||
_regions.put(region, new ArrayList<L2DoorInstance>());
|
||||
}
|
||||
_regions.get(region).add(door);
|
||||
}
|
||||
|
||||
public static void addDoorGroup(String groupName, int doorId)
|
||||
{
|
||||
Set<Integer> set = _groups.get(groupName);
|
||||
if (set == null)
|
||||
{
|
||||
set = new HashSet<>();
|
||||
_groups.put(groupName, set);
|
||||
}
|
||||
set.add(doorId);
|
||||
}
|
||||
|
||||
public static Set<Integer> getDoorsByGroup(String groupName)
|
||||
{
|
||||
return _groups.get(groupName);
|
||||
}
|
||||
|
||||
public Collection<L2DoorInstance> getDoors()
|
||||
{
|
||||
return _doors.values();
|
||||
}
|
||||
|
||||
public boolean checkIfDoorsBetween(AbstractNodeLoc start, AbstractNodeLoc end, int instanceId)
|
||||
{
|
||||
return checkIfDoorsBetween(start.getX(), start.getY(), start.getZ(), end.getX(), end.getY(), end.getZ(), instanceId);
|
||||
}
|
||||
|
||||
public boolean checkIfDoorsBetween(int x, int y, int z, int tx, int ty, int tz, int instanceId)
|
||||
{
|
||||
return checkIfDoorsBetween(x, y, z, tx, ty, tz, instanceId, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* GodKratos: TODO: remove GeoData checks from door table and convert door nodes to Geo zones
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param tx
|
||||
* @param ty
|
||||
* @param tz
|
||||
* @param instanceId
|
||||
* @param doubleFaceCheck
|
||||
* @return {@code boolean}
|
||||
*/
|
||||
public boolean checkIfDoorsBetween(int x, int y, int z, int tx, int ty, int tz, int instanceId, boolean doubleFaceCheck)
|
||||
{
|
||||
Collection<L2DoorInstance> allDoors;
|
||||
if ((instanceId > 0) && (InstanceManager.getInstance().getInstance(instanceId) != null))
|
||||
{
|
||||
allDoors = InstanceManager.getInstance().getInstance(instanceId).getDoors();
|
||||
}
|
||||
else
|
||||
{
|
||||
allDoors = _regions.get(MapRegionManager.getInstance().getMapRegionLocId(x, y));
|
||||
}
|
||||
|
||||
if (allDoors == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (L2DoorInstance doorInst : allDoors)
|
||||
{
|
||||
// check dead and open
|
||||
if (doorInst.isDead() || doorInst.getOpen() || !doorInst.checkCollision() || (doorInst.getX(0) == 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean intersectFace = false;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int j = (i + 1) < 4 ? i + 1 : 0;
|
||||
// lower part of the multiplier fraction, if it is 0 we avoid an error and also know that the lines are parallel
|
||||
int denominator = ((ty - y) * (doorInst.getX(i) - doorInst.getX(j))) - ((tx - x) * (doorInst.getY(i) - doorInst.getY(j)));
|
||||
if (denominator == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// multipliers to the equations of the lines. If they are lower than 0 or bigger than 1, we know that segments don't intersect
|
||||
float multiplier1 = (float) (((doorInst.getX(j) - doorInst.getX(i)) * (y - doorInst.getY(i))) - ((doorInst.getY(j) - doorInst.getY(i)) * (x - doorInst.getX(i)))) / denominator;
|
||||
float multiplier2 = (float) (((tx - x) * (y - doorInst.getY(i))) - ((ty - y) * (x - doorInst.getX(i)))) / denominator;
|
||||
if ((multiplier1 >= 0) && (multiplier1 <= 1) && (multiplier2 >= 0) && (multiplier2 <= 1))
|
||||
{
|
||||
int intersectZ = Math.round(z + (multiplier1 * (tz - z)));
|
||||
// now checking if the resulting point is between door's min and max z
|
||||
if ((intersectZ > doorInst.getZMin()) && (intersectZ < doorInst.getZMax()))
|
||||
{
|
||||
if (!doubleFaceCheck || intersectFace)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
intersectFace = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static DoorData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final DoorData _instance = new DoorData();
|
||||
}
|
||||
}
|
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.items.enchant.EnchantScroll;
|
||||
import com.l2jserver.gameserver.model.items.enchant.EnchantSupportItem;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
|
||||
/**
|
||||
* Loads item enchant data.
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public class EnchantItemData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, EnchantScroll> _scrolls = new HashMap<>();
|
||||
private final Map<Integer, EnchantSupportItem> _supports = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new enchant item data.
|
||||
*/
|
||||
public EnchantItemData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
_scrolls.clear();
|
||||
_supports.clear();
|
||||
parseDatapackFile("data/enchantItemData.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _scrolls.size() + " Enchant Scrolls.");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _supports.size() + " Support Items.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
StatsSet set;
|
||||
Node att;
|
||||
NamedNodeMap attrs;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("enchant".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
attrs = d.getAttributes();
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final EnchantScroll item = new EnchantScroll(set);
|
||||
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
|
||||
{
|
||||
if ("item".equalsIgnoreCase(cd.getNodeName()))
|
||||
{
|
||||
item.addItem(parseInteger(cd.getAttributes(), "id"));
|
||||
}
|
||||
}
|
||||
_scrolls.put(item.getId(), item);
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Unexistent enchant scroll: " + set.getString("id") + " defined in enchant data!");
|
||||
}
|
||||
catch (IllegalAccessError e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Wrong enchant scroll item type: " + set.getString("id") + " defined in enchant data!");
|
||||
}
|
||||
}
|
||||
else if ("support".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
attrs = d.getAttributes();
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
final EnchantSupportItem item = new EnchantSupportItem(set);
|
||||
_supports.put(item.getId(), item);
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Unexistent enchant support item: " + set.getString("id") + " defined in enchant data!");
|
||||
}
|
||||
catch (IllegalAccessError e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, getClass().getSimpleName() + ": Wrong enchant support item type: " + set.getString("id") + " defined in enchant data!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enchant scroll.
|
||||
* @param scroll the scroll
|
||||
* @return enchant template for scroll
|
||||
*/
|
||||
public final EnchantScroll getEnchantScroll(L2ItemInstance scroll)
|
||||
{
|
||||
return _scrolls.get(scroll.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the support item.
|
||||
* @param item the item
|
||||
* @return enchant template for support item
|
||||
*/
|
||||
public final EnchantSupportItem getSupportItem(L2ItemInstance item)
|
||||
{
|
||||
return _supports.get(item.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of EnchantItemData.
|
||||
* @return single instance of EnchantItemData
|
||||
*/
|
||||
public static final EnchantItemData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final EnchantItemData _instance = new EnchantItemData();
|
||||
}
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.datatables.ItemTable;
|
||||
import com.l2jserver.gameserver.model.holders.RangeChanceHolder;
|
||||
import com.l2jserver.gameserver.model.items.L2Item;
|
||||
import com.l2jserver.gameserver.model.items.enchant.EnchantItemGroup;
|
||||
import com.l2jserver.gameserver.model.items.enchant.EnchantRateItem;
|
||||
import com.l2jserver.gameserver.model.items.enchant.EnchantScrollGroup;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public final class EnchantItemGroupsData implements IXmlReader
|
||||
{
|
||||
private final Map<String, EnchantItemGroup> _itemGroups = new HashMap<>();
|
||||
private final Map<Integer, EnchantScrollGroup> _scrollGroups = new HashMap<>();
|
||||
|
||||
protected EnchantItemGroupsData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
_itemGroups.clear();
|
||||
_scrollGroups.clear();
|
||||
parseDatapackFile("data/enchantItemGroups.xml");
|
||||
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _itemGroups.size() + " item group templates.");
|
||||
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _scrollGroups.size() + " scroll group templates.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("enchantRateGroup".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
String name = parseString(d.getAttributes(), "name");
|
||||
final EnchantItemGroup group = new EnchantItemGroup(name);
|
||||
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
|
||||
{
|
||||
if ("current".equalsIgnoreCase(cd.getNodeName()))
|
||||
{
|
||||
String range = parseString(cd.getAttributes(), "enchant");
|
||||
double chance = parseDouble(cd.getAttributes(), "chance");
|
||||
int min = -1;
|
||||
int max = 0;
|
||||
if (range.contains("-"))
|
||||
{
|
||||
String[] split = range.split("-");
|
||||
if ((split.length == 2) && Util.isDigit(split[0]) && Util.isDigit(split[1]))
|
||||
{
|
||||
min = Integer.parseInt(split[0]);
|
||||
max = Integer.parseInt(split[1]);
|
||||
}
|
||||
}
|
||||
else if (Util.isDigit(range))
|
||||
{
|
||||
min = Integer.parseInt(range);
|
||||
max = min;
|
||||
}
|
||||
if ((min > -1) && (max > 0))
|
||||
{
|
||||
group.addChance(new RangeChanceHolder(min, max, chance));
|
||||
}
|
||||
}
|
||||
}
|
||||
_itemGroups.put(name, group);
|
||||
}
|
||||
else if ("enchantScrollGroup".equals(d.getNodeName()))
|
||||
{
|
||||
int id = parseInteger(d.getAttributes(), "id");
|
||||
final EnchantScrollGroup group = new EnchantScrollGroup(id);
|
||||
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
|
||||
{
|
||||
if ("enchantRate".equalsIgnoreCase(cd.getNodeName()))
|
||||
{
|
||||
final EnchantRateItem rateGroup = new EnchantRateItem(parseString(cd.getAttributes(), "group"));
|
||||
for (Node z = cd.getFirstChild(); z != null; z = z.getNextSibling())
|
||||
{
|
||||
if ("item".equals(z.getNodeName()))
|
||||
{
|
||||
final NamedNodeMap attrs = z.getAttributes();
|
||||
if (attrs.getNamedItem("slot") != null)
|
||||
{
|
||||
rateGroup.addSlot(ItemTable._slots.get(parseString(attrs, "slot")));
|
||||
}
|
||||
if (attrs.getNamedItem("magicWeapon") != null)
|
||||
{
|
||||
rateGroup.setMagicWeapon(parseBoolean(attrs, "magicWeapon"));
|
||||
}
|
||||
if (attrs.getNamedItem("id") != null)
|
||||
{
|
||||
rateGroup.setItemId(parseInteger(attrs, "id"));
|
||||
}
|
||||
}
|
||||
}
|
||||
group.addRateGroup(rateGroup);
|
||||
}
|
||||
}
|
||||
_scrollGroups.put(id, group);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public EnchantItemGroup getItemGroup(L2Item item, int scrollGroup)
|
||||
{
|
||||
final EnchantScrollGroup group = _scrollGroups.get(scrollGroup);
|
||||
final EnchantRateItem rateGroup = group.getRateGroup(item);
|
||||
return rateGroup != null ? _itemGroups.get(rateGroup.getName()) : null;
|
||||
}
|
||||
|
||||
public EnchantItemGroup getItemGroup(String name)
|
||||
{
|
||||
return _itemGroups.get(name);
|
||||
}
|
||||
|
||||
public EnchantScrollGroup getScrollGroup(int id)
|
||||
{
|
||||
return _scrollGroups.get(id);
|
||||
}
|
||||
|
||||
public static EnchantItemGroupsData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final EnchantItemGroupsData _instance = new EnchantItemGroupsData();
|
||||
}
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.datatables.ItemTable;
|
||||
import com.l2jserver.gameserver.enums.StatFunction;
|
||||
import com.l2jserver.gameserver.model.items.L2Item;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.model.items.type.CrystalType;
|
||||
import com.l2jserver.gameserver.model.stats.Stats;
|
||||
import com.l2jserver.gameserver.model.stats.functions.FuncTemplate;
|
||||
|
||||
/**
|
||||
* This class holds the Enchant HP Bonus Data.
|
||||
* @author MrPoke, Zoey76
|
||||
*/
|
||||
public class EnchantItemHPBonusData implements IXmlReader
|
||||
{
|
||||
private final Map<CrystalType, List<Integer>> _armorHPBonuses = new EnumMap<>(CrystalType.class);
|
||||
|
||||
private static final float FULL_ARMOR_MODIFIER = 1.5f; // TODO: Move it to config!
|
||||
|
||||
/**
|
||||
* Instantiates a new enchant hp bonus data.
|
||||
*/
|
||||
protected EnchantItemHPBonusData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("enchantHP".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
List<Integer> bonuses = new ArrayList<>();
|
||||
for (Node e = d.getFirstChild(); e != null; e = e.getNextSibling())
|
||||
{
|
||||
if ("bonus".equalsIgnoreCase(e.getNodeName()))
|
||||
{
|
||||
bonuses.add(Integer.valueOf(e.getTextContent()));
|
||||
}
|
||||
}
|
||||
_armorHPBonuses.put(parseEnum(d.getAttributes(), CrystalType.class, "grade"), bonuses);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_armorHPBonuses.isEmpty())
|
||||
{
|
||||
final ItemTable it = ItemTable.getInstance();
|
||||
L2Item item;
|
||||
// Armors
|
||||
final Collection<Integer> armorIds = it.getAllArmorsId();
|
||||
for (Integer itemId : armorIds)
|
||||
{
|
||||
item = it.getTemplate(itemId);
|
||||
if ((item != null) && (item.getCrystalType() != CrystalType.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:
|
||||
case L2Item.SLOT_BELT:
|
||||
item.attach(new FuncTemplate(null, null, StatFunction.ENCHANTHP.getName(), -1, Stats.MAX_HP, 0));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_armorHPBonuses.clear();
|
||||
parseDatapackFile("data/stats/enchantHPBonus.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _armorHPBonuses.size() + " Enchant HP Bonuses.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the HP bonus.
|
||||
* @param item the item
|
||||
* @return the HP bonus
|
||||
*/
|
||||
public final int getHPBonus(L2ItemInstance item)
|
||||
{
|
||||
final List<Integer> values = _armorHPBonuses.get(item.getItem().getItemGradeSPlus());
|
||||
if ((values == null) || values.isEmpty() || (item.getOlyEnchantLevel() <= 0))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
final int bonus = values.get(Math.min(item.getOlyEnchantLevel(), values.size()) - 1);
|
||||
if (item.getItem().getBodyPart() == L2Item.SLOT_FULL_ARMOR)
|
||||
{
|
||||
return (int) (bonus * FULL_ARMOR_MODIFIER);
|
||||
}
|
||||
return bonus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of EnchantHPBonusData.
|
||||
* @return single instance of EnchantHPBonusData
|
||||
*/
|
||||
public static final EnchantItemHPBonusData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final EnchantItemHPBonusData _instance = new EnchantItemHPBonusData();
|
||||
}
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.model.options.EnchantOptions;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public class EnchantItemOptionsData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, Map<Integer, EnchantOptions>> _data = new HashMap<>();
|
||||
|
||||
protected EnchantItemOptionsData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
_data.clear();
|
||||
parseDatapackFile("data/enchantItemOptions.xml");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
Node att = null;
|
||||
int counter = 0;
|
||||
EnchantOptions op = null;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("item".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
int itemId = parseInteger(d.getAttributes(), "id");
|
||||
if (!_data.containsKey(itemId))
|
||||
{
|
||||
_data.put(itemId, new HashMap<Integer, EnchantOptions>());
|
||||
}
|
||||
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
|
||||
{
|
||||
if ("options".equalsIgnoreCase(cd.getNodeName()))
|
||||
{
|
||||
op = new EnchantOptions(parseInteger(cd.getAttributes(), "level"));
|
||||
_data.get(itemId).put(op.getLevel(), op);
|
||||
|
||||
for (byte i = 0; i < 3; i++)
|
||||
{
|
||||
att = cd.getAttributes().getNamedItem("option" + (i + 1));
|
||||
if ((att != null) && Util.isDigit(att.getNodeValue()))
|
||||
{
|
||||
op.setOption(i, parseInteger(att));
|
||||
}
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _data.size() + " Items and " + counter + " Options.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param itemId
|
||||
* @param enchantLevel
|
||||
* @return enchant effects information.
|
||||
*/
|
||||
public EnchantOptions getOptions(int itemId, int enchantLevel)
|
||||
{
|
||||
if (!_data.containsKey(itemId) || !_data.get(itemId).containsKey(enchantLevel))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return _data.get(itemId).get(enchantLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param item
|
||||
* @return enchant effects information.
|
||||
*/
|
||||
public EnchantOptions getOptions(L2ItemInstance item)
|
||||
{
|
||||
return item != null ? getOptions(item.getId(), item.getEnchantLevel()) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of EnchantOptionsData.
|
||||
* @return single instance of EnchantOptionsData
|
||||
*/
|
||||
public static final EnchantItemOptionsData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final EnchantItemOptionsData _instance = new EnchantItemOptionsData();
|
||||
}
|
||||
}
|
@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.L2EnchantSkillGroup;
|
||||
import com.l2jserver.gameserver.model.L2EnchantSkillGroup.EnchantSkillHolder;
|
||||
import com.l2jserver.gameserver.model.L2EnchantSkillLearn;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* This class holds the Enchant Groups information.
|
||||
* @author Micr0
|
||||
*/
|
||||
public class EnchantSkillGroupsData implements IXmlReader
|
||||
{
|
||||
public static final int NORMAL_ENCHANT_COST_MULTIPLIER = Config.NORMAL_ENCHANT_COST_MULTIPLIER;
|
||||
public static final int SAFE_ENCHANT_COST_MULTIPLIER = Config.SAFE_ENCHANT_COST_MULTIPLIER;
|
||||
|
||||
public static final int NORMAL_ENCHANT_BOOK = 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 final Map<Integer, L2EnchantSkillGroup> _enchantSkillGroups = new HashMap<>();
|
||||
private final Map<Integer, L2EnchantSkillLearn> _enchantSkillTrees = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new enchant groups table.
|
||||
*/
|
||||
protected EnchantSkillGroupsData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_enchantSkillGroups.clear();
|
||||
_enchantSkillTrees.clear();
|
||||
parseDatapackFile("data/enchantSkillGroups.xml");
|
||||
int routes = 0;
|
||||
for (L2EnchantSkillGroup group : _enchantSkillGroups.values())
|
||||
{
|
||||
routes += group.getEnchantGroupDetails().size();
|
||||
}
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _enchantSkillGroups.size() + " groups and " + routes + " routes.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
StatsSet set;
|
||||
Node att;
|
||||
int id = 0;
|
||||
L2EnchantSkillGroup group;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("group".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
attrs = d.getAttributes();
|
||||
id = parseInteger(attrs, "id");
|
||||
|
||||
group = _enchantSkillGroups.get(id);
|
||||
if (group == null)
|
||||
{
|
||||
group = new L2EnchantSkillGroup(id);
|
||||
_enchantSkillGroups.put(id, group);
|
||||
}
|
||||
|
||||
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
|
||||
{
|
||||
if ("enchant".equalsIgnoreCase(b.getNodeName()))
|
||||
{
|
||||
attrs = b.getAttributes();
|
||||
set = new StatsSet();
|
||||
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
group.addEnchantDetail(new EnchantSkillHolder(set));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the new route for skill.
|
||||
* @param skillId the skill id
|
||||
* @param maxLvL the max lvl
|
||||
* @param route the route
|
||||
* @param group the group
|
||||
* @return the int
|
||||
*/
|
||||
public int addNewRouteForSkill(int skillId, int maxLvL, int route, int group)
|
||||
{
|
||||
L2EnchantSkillLearn enchantableSkill = _enchantSkillTrees.get(skillId);
|
||||
if (enchantableSkill == null)
|
||||
{
|
||||
enchantableSkill = new L2EnchantSkillLearn(skillId, maxLvL);
|
||||
_enchantSkillTrees.put(skillId, enchantableSkill);
|
||||
}
|
||||
if (_enchantSkillGroups.containsKey(group))
|
||||
{
|
||||
enchantableSkill.addNewEnchantRoute(route, group);
|
||||
|
||||
return _enchantSkillGroups.get(group).getEnchantGroupDetails().size();
|
||||
}
|
||||
LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Error while loading generating enchant skill id: " + skillId + "; route: " + route + "; missing group: " + group);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the skill enchantment for skill.
|
||||
* @param skill the skill
|
||||
* @return the skill enchantment for skill
|
||||
*/
|
||||
public L2EnchantSkillLearn getSkillEnchantmentForSkill(Skill skill)
|
||||
{
|
||||
// there is enchantment for this skill and we have the required level of it
|
||||
final L2EnchantSkillLearn esl = getSkillEnchantmentBySkillId(skill.getId());
|
||||
if ((esl != null) && (skill.getLevel() >= esl.getBaseLevel()))
|
||||
{
|
||||
return esl;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the skill enchantment by skill id.
|
||||
* @param skillId the skill id
|
||||
* @return the skill enchantment by skill id
|
||||
*/
|
||||
public L2EnchantSkillLearn getSkillEnchantmentBySkillId(int skillId)
|
||||
{
|
||||
return _enchantSkillTrees.get(skillId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enchant skill group by id.
|
||||
* @param id the id
|
||||
* @return the enchant skill group by id
|
||||
*/
|
||||
public L2EnchantSkillGroup getEnchantSkillGroupById(int id)
|
||||
{
|
||||
return _enchantSkillGroups.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enchant skill sp cost.
|
||||
* @param skill the skill
|
||||
* @return the enchant skill sp cost
|
||||
*/
|
||||
public int getEnchantSkillSpCost(Skill skill)
|
||||
{
|
||||
final L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
|
||||
if (enchantSkillLearn != null)
|
||||
{
|
||||
final EnchantSkillHolder esh = enchantSkillLearn.getEnchantSkillHolder(skill.getLevel());
|
||||
if (esh != null)
|
||||
{
|
||||
return esh.getSpCost();
|
||||
}
|
||||
}
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enchant skill Adena cost.
|
||||
* @param skill the skill
|
||||
* @return the enchant skill Adena cost
|
||||
*/
|
||||
public int getEnchantSkillAdenaCost(Skill skill)
|
||||
{
|
||||
final L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
|
||||
if (enchantSkillLearn != null)
|
||||
{
|
||||
final EnchantSkillHolder esh = enchantSkillLearn.getEnchantSkillHolder(skill.getLevel());
|
||||
if (esh != null)
|
||||
{
|
||||
return esh.getAdenaCost();
|
||||
}
|
||||
}
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the enchant skill rate.
|
||||
* @param player the player
|
||||
* @param skill the skill
|
||||
* @return the enchant skill rate
|
||||
*/
|
||||
public byte getEnchantSkillRate(L2PcInstance player, Skill skill)
|
||||
{
|
||||
final L2EnchantSkillLearn enchantSkillLearn = _enchantSkillTrees.get(skill.getId());
|
||||
if (enchantSkillLearn != null)
|
||||
{
|
||||
final EnchantSkillHolder esh = enchantSkillLearn.getEnchantSkillHolder(skill.getLevel());
|
||||
if (esh != null)
|
||||
{
|
||||
return esh.getRate(player);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of EnchantGroupsData.
|
||||
* @return single instance of EnchantGroupsData
|
||||
*/
|
||||
public static EnchantSkillGroupsData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final EnchantSkillGroupsData _instance = new EnchantSkillGroupsData();
|
||||
}
|
||||
}
|
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
|
||||
/**
|
||||
* This class holds the Experience points for each level for players and pets.
|
||||
* @author mrTJO
|
||||
*/
|
||||
public final class ExperienceData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, Long> _expTable = new HashMap<>();
|
||||
|
||||
private byte MAX_LEVEL;
|
||||
private byte MAX_PET_LEVEL;
|
||||
|
||||
/**
|
||||
* Instantiates a new experience table.
|
||||
*/
|
||||
protected ExperienceData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_expTable.clear();
|
||||
parseDatapackFile("data/stats/experience.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _expTable.size() + " levels.");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Max Player Level is: " + (MAX_LEVEL - 1));
|
||||
LOGGER.info(getClass().getSimpleName() + ": Max Pet Level is: " + (MAX_PET_LEVEL - 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
final Node table = doc.getFirstChild();
|
||||
final NamedNodeMap tableAttr = table.getAttributes();
|
||||
|
||||
MAX_LEVEL = (byte) (Byte.parseByte(tableAttr.getNamedItem("maxLevel").getNodeValue()) + 1);
|
||||
MAX_PET_LEVEL = (byte) (Byte.parseByte(tableAttr.getNamedItem("maxPetLevel").getNodeValue()) + 1);
|
||||
|
||||
NamedNodeMap attrs;
|
||||
for (Node n = table.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("experience".equals(n.getNodeName()))
|
||||
{
|
||||
attrs = n.getAttributes();
|
||||
_expTable.put(parseInteger(attrs, "level"), parseLong(attrs, "tolevel"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the exp for level.
|
||||
* @param level the level required.
|
||||
* @return the experience points required to reach the given level.
|
||||
*/
|
||||
public long getExpForLevel(int level)
|
||||
{
|
||||
return _expTable.get(level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the max level.
|
||||
* @return the maximum level acquirable by a player.
|
||||
*/
|
||||
public byte getMaxLevel()
|
||||
{
|
||||
return MAX_LEVEL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the max pet level.
|
||||
* @return the maximum level acquirable by a pet.
|
||||
*/
|
||||
public byte getMaxPetLevel()
|
||||
{
|
||||
return MAX_PET_LEVEL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of ExperienceTable.
|
||||
* @return single instance of ExperienceTable
|
||||
*/
|
||||
public static ExperienceData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final ExperienceData _instance = new ExperienceData();
|
||||
}
|
||||
}
|
174
trunk/java/com/l2jserver/gameserver/data/xml/impl/FishData.java
Normal file
174
trunk/java/com/l2jserver/gameserver/data/xml/impl/FishData.java
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.fishing.L2Fish;
|
||||
|
||||
/**
|
||||
* This class holds the Fish information.
|
||||
* @author nonom
|
||||
*/
|
||||
public final class FishData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, L2Fish> _fishNormal = new HashMap<>();
|
||||
private final Map<Integer, L2Fish> _fishEasy = new HashMap<>();
|
||||
private final Map<Integer, L2Fish> _fishHard = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new fish data.
|
||||
*/
|
||||
protected FishData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_fishEasy.clear();
|
||||
_fishNormal.clear();
|
||||
_fishHard.clear();
|
||||
parseDatapackFile("data/stats/fishing/fishes.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + (_fishEasy.size() + _fishNormal.size() + _fishHard.size()) + " Fishes.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
Node att;
|
||||
L2Fish fish;
|
||||
StatsSet set;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("fish".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
attrs = d.getAttributes();
|
||||
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
fish = new L2Fish(set);
|
||||
switch (fish.getFishGrade())
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
_fishEasy.put(fish.getFishId(), fish);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
_fishNormal.put(fish.getFishId(), fish);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
_fishHard.put(fish.getFishId(), fish);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fish.
|
||||
* @param level the fish Level
|
||||
* @param group the fish Group
|
||||
* @param grade the fish Grade
|
||||
* @return List of Fish that can be fished
|
||||
*/
|
||||
public List<L2Fish> getFish(int level, int group, int grade)
|
||||
{
|
||||
final ArrayList<L2Fish> result = new ArrayList<>();
|
||||
Map<Integer, L2Fish> fish = null;
|
||||
switch (grade)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
fish = _fishEasy;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
fish = _fishNormal;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
fish = _fishHard;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Unmanaged fish grade!");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
for (L2Fish f : fish.values())
|
||||
{
|
||||
if ((f.getFishLevel() != level) || (f.getFishGroup() != group))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
result.add(f);
|
||||
}
|
||||
|
||||
if (result.isEmpty())
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": Cannot find any fish for level: " + level + " group: " + group + " and grade: " + grade + "!");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of FishData.
|
||||
* @return single instance of FishData
|
||||
*/
|
||||
public static FishData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final FishData _instance = new FishData();
|
||||
}
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.fishing.L2FishingMonster;
|
||||
|
||||
/**
|
||||
* This class holds the Fishing Monsters information.
|
||||
* @author nonom
|
||||
*/
|
||||
public final class FishingMonstersData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, L2FishingMonster> _fishingMonstersData = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new fishing monsters data.
|
||||
*/
|
||||
protected FishingMonstersData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_fishingMonstersData.clear();
|
||||
parseDatapackFile("data/stats/fishing/fishingMonsters.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _fishingMonstersData.size() + " Fishing Monsters.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
Node att;
|
||||
L2FishingMonster fishingMonster;
|
||||
StatsSet set;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("fishingMonster".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
|
||||
attrs = d.getAttributes();
|
||||
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
fishingMonster = new L2FishingMonster(set);
|
||||
_fishingMonstersData.put(fishingMonster.getFishingMonsterId(), fishingMonster);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fishing monster.
|
||||
* @param lvl the fisherman level
|
||||
* @return a fishing monster given the fisherman level
|
||||
*/
|
||||
public L2FishingMonster getFishingMonster(int lvl)
|
||||
{
|
||||
for (L2FishingMonster fishingMonster : _fishingMonstersData.values())
|
||||
{
|
||||
if ((lvl >= fishingMonster.getUserMinLevel()) && (lvl <= fishingMonster.getUserMaxLevel()))
|
||||
{
|
||||
return fishingMonster;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fishing monster by Id.
|
||||
* @param id the fishing monster Id
|
||||
* @return the fishing monster by Id
|
||||
*/
|
||||
public L2FishingMonster getFishingMonsterById(int id)
|
||||
{
|
||||
if (_fishingMonstersData.containsKey(id))
|
||||
{
|
||||
return _fishingMonstersData.get(id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of FishingMonsterData.
|
||||
* @return single instance of FishingMonsterData
|
||||
*/
|
||||
public static FishingMonstersData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final FishingMonstersData _instance = new FishingMonstersData();
|
||||
}
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.fishing.L2FishingRod;
|
||||
|
||||
/**
|
||||
* This class holds the Fishing Rods information.
|
||||
* @author nonom
|
||||
*/
|
||||
public final class FishingRodsData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, L2FishingRod> _fishingRods = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new fishing rods data.
|
||||
*/
|
||||
protected FishingRodsData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_fishingRods.clear();
|
||||
parseDatapackFile("data/stats/fishing/fishingRods.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _fishingRods.size() + " Fishing Rods.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
Node att;
|
||||
L2FishingRod fishingRod;
|
||||
StatsSet set;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("fishingRod".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
|
||||
attrs = d.getAttributes();
|
||||
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
fishingRod = new L2FishingRod(set);
|
||||
_fishingRods.put(fishingRod.getFishingRodItemId(), fishingRod);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fishing rod.
|
||||
* @param itemId the item id
|
||||
* @return A fishing Rod by Item Id
|
||||
*/
|
||||
public L2FishingRod getFishingRod(int itemId)
|
||||
{
|
||||
return _fishingRods.get(itemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of FishingRodsData.
|
||||
* @return single instance of FishingRodsData
|
||||
*/
|
||||
public static FishingRodsData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final FishingRodsData _instance = new FishingRodsData();
|
||||
}
|
||||
}
|
181
trunk/java/com/l2jserver/gameserver/data/xml/impl/HennaData.java
Normal file
181
trunk/java/com/l2jserver/gameserver/data/xml/impl/HennaData.java
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
import com.l2jserver.gameserver.model.items.L2Henna;
|
||||
|
||||
/**
|
||||
* This class holds the henna related information.<br>
|
||||
* Cost and required amount to add the henna to the player.<br>
|
||||
* Cost and retrieved amount for removing the henna from the player.<br>
|
||||
* Allowed classes to wear each henna.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public final class HennaData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, L2Henna> _hennaList = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new henna data.
|
||||
*/
|
||||
protected HennaData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_hennaList.clear();
|
||||
parseDatapackFile("data/stats/hennaList.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _hennaList.size() + " Henna data.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equals(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("henna".equals(d.getNodeName()))
|
||||
{
|
||||
parseHenna(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the henna.
|
||||
* @param d the d
|
||||
*/
|
||||
private void parseHenna(Node d)
|
||||
{
|
||||
final StatsSet set = new StatsSet();
|
||||
final List<ClassId> wearClassIds = new ArrayList<>();
|
||||
NamedNodeMap attrs = d.getAttributes();
|
||||
Node attr;
|
||||
String name;
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
attr = attrs.item(i);
|
||||
set.set(attr.getNodeName(), attr.getNodeValue());
|
||||
}
|
||||
|
||||
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
|
||||
{
|
||||
name = c.getNodeName();
|
||||
attrs = c.getAttributes();
|
||||
switch (name)
|
||||
{
|
||||
case "stats":
|
||||
{
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
attr = attrs.item(i);
|
||||
set.set(attr.getNodeName(), attr.getNodeValue());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "wear":
|
||||
{
|
||||
attr = attrs.getNamedItem("count");
|
||||
set.set("wear_count", attr.getNodeValue());
|
||||
attr = attrs.getNamedItem("fee");
|
||||
set.set("wear_fee", attr.getNodeValue());
|
||||
break;
|
||||
}
|
||||
case "cancel":
|
||||
{
|
||||
attr = attrs.getNamedItem("count");
|
||||
set.set("cancel_count", attr.getNodeValue());
|
||||
attr = attrs.getNamedItem("fee");
|
||||
set.set("cancel_fee", attr.getNodeValue());
|
||||
break;
|
||||
}
|
||||
case "classId":
|
||||
{
|
||||
wearClassIds.add(ClassId.getClassId(Integer.parseInt(c.getTextContent())));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
final L2Henna henna = new L2Henna(set);
|
||||
henna.setWearClassIds(wearClassIds);
|
||||
_hennaList.put(henna.getDyeId(), henna);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the henna.
|
||||
* @param id of the dye.
|
||||
* @return the dye with that id.
|
||||
*/
|
||||
public L2Henna getHenna(int id)
|
||||
{
|
||||
return _hennaList.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the henna list.
|
||||
* @param classId the player's class Id.
|
||||
* @return the list with all the allowed dyes.
|
||||
*/
|
||||
public List<L2Henna> getHennaList(ClassId classId)
|
||||
{
|
||||
final List<L2Henna> list = new ArrayList<>();
|
||||
for (L2Henna henna : _hennaList.values())
|
||||
{
|
||||
if (henna.isAllowedClass(classId))
|
||||
{
|
||||
list.add(henna);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of HennaData.
|
||||
* @return single instance of HennaData
|
||||
*/
|
||||
public static HennaData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final HennaData _instance = new HennaData();
|
||||
}
|
||||
}
|
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.GameTimeController;
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
|
||||
/**
|
||||
* This class load, holds and calculates the hit condition bonuses.
|
||||
* @author Nik
|
||||
*/
|
||||
public final class HitConditionBonusData implements IXmlReader
|
||||
{
|
||||
private int frontBonus = 0;
|
||||
private int sideBonus = 0;
|
||||
private int backBonus = 0;
|
||||
private int highBonus = 0;
|
||||
private int lowBonus = 0;
|
||||
private int darkBonus = 0;
|
||||
private int rainBonus = 0;
|
||||
|
||||
/**
|
||||
* Instantiates a new hit condition bonus.
|
||||
*/
|
||||
protected HitConditionBonusData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
parseDatapackFile("data/stats/hitConditionBonus.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded Hit Condition bonuses.");
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
LOGGER.info(getClass().getSimpleName() + ": Front bonus: " + frontBonus);
|
||||
LOGGER.info(getClass().getSimpleName() + ": Side bonus: " + sideBonus);
|
||||
LOGGER.info(getClass().getSimpleName() + ": Back bonus: " + backBonus);
|
||||
LOGGER.info(getClass().getSimpleName() + ": High bonus: " + highBonus);
|
||||
LOGGER.info(getClass().getSimpleName() + ": Low bonus: " + lowBonus);
|
||||
LOGGER.info(getClass().getSimpleName() + ": Dark bonus: " + darkBonus);
|
||||
LOGGER.info(getClass().getSimpleName() + ": Rain bonus: " + rainBonus);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node d = doc.getFirstChild().getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
NamedNodeMap attrs = d.getAttributes();
|
||||
switch (d.getNodeName())
|
||||
{
|
||||
case "front":
|
||||
{
|
||||
frontBonus = parseInteger(attrs, "val");
|
||||
break;
|
||||
}
|
||||
case "side":
|
||||
{
|
||||
sideBonus = parseInteger(attrs, "val");
|
||||
break;
|
||||
}
|
||||
case "back":
|
||||
{
|
||||
backBonus = parseInteger(attrs, "val");
|
||||
break;
|
||||
}
|
||||
case "high":
|
||||
{
|
||||
highBonus = parseInteger(attrs, "val");
|
||||
break;
|
||||
}
|
||||
case "low":
|
||||
{
|
||||
lowBonus = parseInteger(attrs, "val");
|
||||
break;
|
||||
}
|
||||
case "dark":
|
||||
{
|
||||
darkBonus = parseInteger(attrs, "val");
|
||||
break;
|
||||
}
|
||||
case "rain":
|
||||
{
|
||||
rainBonus = parseInteger(attrs, "val");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the condition bonus.
|
||||
* @param attacker the attacking character.
|
||||
* @param target the attacked character.
|
||||
* @return the bonus of the attacker against the target.
|
||||
*/
|
||||
public double getConditionBonus(L2Character attacker, L2Character target)
|
||||
{
|
||||
double mod = 100;
|
||||
// Get high or low bonus
|
||||
if ((attacker.getZ() - target.getZ()) > 50)
|
||||
{
|
||||
mod += highBonus;
|
||||
}
|
||||
else if ((attacker.getZ() - target.getZ()) < -50)
|
||||
{
|
||||
mod += lowBonus;
|
||||
}
|
||||
|
||||
// Get weather bonus
|
||||
if (GameTimeController.getInstance().isNight())
|
||||
{
|
||||
mod += darkBonus;
|
||||
// else if () No rain support yet.
|
||||
// chance += hitConditionBonus.rainBonus;
|
||||
}
|
||||
|
||||
// Get side bonus
|
||||
if (attacker.isBehindTarget())
|
||||
{
|
||||
mod += backBonus;
|
||||
}
|
||||
else if (attacker.isInFrontOfTarget())
|
||||
{
|
||||
mod += frontBonus;
|
||||
}
|
||||
else
|
||||
{
|
||||
mod += sideBonus;
|
||||
}
|
||||
|
||||
// If (mod / 100) is less than 0, return 0, because we can't lower more than 100%.
|
||||
return Math.max(mod / 100, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of HitConditionBonus.
|
||||
* @return single instance of HitConditionBonus
|
||||
*/
|
||||
public static HitConditionBonusData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final HitConditionBonusData _instance = new HitConditionBonusData();
|
||||
}
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
import com.l2jserver.gameserver.model.items.PcItemTemplate;
|
||||
|
||||
/**
|
||||
* This class holds the Initial Equipment information.<br>
|
||||
* What items get each newly created character and if this item is equipped upon creation (<b>Requires the item to be equippable</b>).
|
||||
* @author Zoey76
|
||||
*/
|
||||
public final class InitialEquipmentData implements IXmlReader
|
||||
{
|
||||
private final Map<ClassId, List<PcItemTemplate>> _initialEquipmentList = new HashMap<>();
|
||||
private static final String NORMAL = "data/stats/initialEquipment.xml";
|
||||
private static final String EVENT = "data/stats/initialEquipmentEvent.xml";
|
||||
|
||||
/**
|
||||
* Instantiates a new initial equipment data.
|
||||
*/
|
||||
protected InitialEquipmentData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_initialEquipmentList.clear();
|
||||
parseDatapackFile(Config.INITIAL_EQUIPMENT_EVENT ? EVENT : NORMAL);
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _initialEquipmentList.size() + " Initial Equipment data.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("equipment".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
parseEquipment(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the equipment.
|
||||
* @param d parse an initial equipment and add it to {@link #_initialEquipmentList}
|
||||
*/
|
||||
private void parseEquipment(Node d)
|
||||
{
|
||||
NamedNodeMap attrs = d.getAttributes();
|
||||
final ClassId classId = ClassId.getClassId(Integer.parseInt(attrs.getNamedItem("classId").getNodeValue()));
|
||||
final List<PcItemTemplate> equipList = new ArrayList<>();
|
||||
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
|
||||
{
|
||||
if ("item".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
final StatsSet set = new StatsSet();
|
||||
attrs = c.getAttributes();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
Node attr = attrs.item(i);
|
||||
set.set(attr.getNodeName(), attr.getNodeValue());
|
||||
}
|
||||
equipList.add(new PcItemTemplate(set));
|
||||
}
|
||||
}
|
||||
_initialEquipmentList.put(classId, equipList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the equipment list.
|
||||
* @param cId the class Id for the required initial equipment.
|
||||
* @return the initial equipment for the given class Id.
|
||||
*/
|
||||
public List<PcItemTemplate> getEquipmentList(ClassId cId)
|
||||
{
|
||||
return _initialEquipmentList.get(cId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the equipment list.
|
||||
* @param cId the class Id for the required initial equipment.
|
||||
* @return the initial equipment for the given class Id.
|
||||
*/
|
||||
public List<PcItemTemplate> getEquipmentList(int cId)
|
||||
{
|
||||
return _initialEquipmentList.get(ClassId.getClassId(cId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of InitialEquipmentData.
|
||||
* @return single instance of InitialEquipmentData
|
||||
*/
|
||||
public static InitialEquipmentData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final InitialEquipmentData _instance = new InitialEquipmentData();
|
||||
}
|
||||
}
|
@ -0,0 +1,369 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.enums.MacroType;
|
||||
import com.l2jserver.gameserver.enums.ShortcutType;
|
||||
import com.l2jserver.gameserver.model.Macro;
|
||||
import com.l2jserver.gameserver.model.MacroCmd;
|
||||
import com.l2jserver.gameserver.model.Shortcut;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ShortCutRegister;
|
||||
|
||||
/**
|
||||
* This class holds the Initial Shortcuts information.<br>
|
||||
* What shortcuts get each newly created character.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public final class InitialShortcutData implements IXmlReader
|
||||
{
|
||||
private final Map<ClassId, List<Shortcut>> _initialShortcutData = new HashMap<>();
|
||||
private final List<Shortcut> _initialGlobalShortcutList = new ArrayList<>();
|
||||
private final Map<Integer, Macro> _macroPresets = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new initial shortcuts data.
|
||||
*/
|
||||
protected InitialShortcutData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_initialShortcutData.clear();
|
||||
_initialGlobalShortcutList.clear();
|
||||
|
||||
parseDatapackFile("data/stats/initialShortcuts.xml");
|
||||
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _initialGlobalShortcutList.size() + " Initial Global Shortcuts data.");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _initialShortcutData.size() + " Initial Shortcuts data.");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _macroPresets.size() + " Macros presets.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equals(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
switch (d.getNodeName())
|
||||
{
|
||||
case "shortcuts":
|
||||
{
|
||||
parseShortcuts(d);
|
||||
break;
|
||||
}
|
||||
case "macros":
|
||||
{
|
||||
parseMacros(d);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a shortcut.
|
||||
* @param d the node
|
||||
*/
|
||||
private void parseShortcuts(Node d)
|
||||
{
|
||||
NamedNodeMap attrs = d.getAttributes();
|
||||
final Node classIdNode = attrs.getNamedItem("classId");
|
||||
final List<Shortcut> list = new ArrayList<>();
|
||||
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
|
||||
{
|
||||
if ("page".equals(c.getNodeName()))
|
||||
{
|
||||
attrs = c.getAttributes();
|
||||
final int pageId = parseInteger(attrs, "pageId");
|
||||
for (Node b = c.getFirstChild(); b != null; b = b.getNextSibling())
|
||||
{
|
||||
if ("slot".equals(b.getNodeName()))
|
||||
{
|
||||
list.add(createShortcut(pageId, b));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (classIdNode != null)
|
||||
{
|
||||
_initialShortcutData.put(ClassId.getClassId(Integer.parseInt(classIdNode.getNodeValue())), list);
|
||||
}
|
||||
else
|
||||
{
|
||||
_initialGlobalShortcutList.addAll(list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a macro.
|
||||
* @param d the node
|
||||
*/
|
||||
private void parseMacros(Node d)
|
||||
{
|
||||
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
|
||||
{
|
||||
if ("macro".equals(c.getNodeName()))
|
||||
{
|
||||
NamedNodeMap attrs = c.getAttributes();
|
||||
if (!parseBoolean(attrs, "enabled", true))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
final int macroId = parseInteger(attrs, "macroId");
|
||||
final int icon = parseInteger(attrs, "icon");
|
||||
final String name = parseString(attrs, "name");
|
||||
final String description = parseString(attrs, "description");
|
||||
final String acronym = parseString(attrs, "acronym");
|
||||
final List<MacroCmd> commands = new ArrayList<>(1);
|
||||
int entry = 0;
|
||||
for (Node b = c.getFirstChild(); b != null; b = b.getNextSibling())
|
||||
{
|
||||
if ("command".equals(b.getNodeName()))
|
||||
{
|
||||
attrs = b.getAttributes();
|
||||
final MacroType type = parseEnum(attrs, MacroType.class, "type");
|
||||
int d1 = 0;
|
||||
int d2 = 0;
|
||||
final String cmd = b.getTextContent();
|
||||
switch (type)
|
||||
{
|
||||
case SKILL:
|
||||
{
|
||||
d1 = parseInteger(attrs, "skillId"); // Skill ID
|
||||
d2 = parseInteger(attrs, "skillLvl", 0); // Skill level
|
||||
break;
|
||||
}
|
||||
case ACTION:
|
||||
{
|
||||
// Not handled by client.
|
||||
d1 = parseInteger(attrs, "actionId");
|
||||
break;
|
||||
}
|
||||
case TEXT:
|
||||
{
|
||||
// Doesn't have numeric parameters.
|
||||
break;
|
||||
}
|
||||
case SHORTCUT:
|
||||
{
|
||||
d1 = parseInteger(attrs, "page"); // Page
|
||||
d2 = parseInteger(attrs, "slot", 0); // Slot
|
||||
break;
|
||||
}
|
||||
case ITEM:
|
||||
{
|
||||
// Not handled by client.
|
||||
d1 = parseInteger(attrs, "itemId");
|
||||
break;
|
||||
}
|
||||
case DELAY:
|
||||
{
|
||||
d1 = parseInteger(attrs, "delay"); // Delay in seconds
|
||||
break;
|
||||
}
|
||||
}
|
||||
commands.add(new MacroCmd(entry++, type, d1, d2, cmd));
|
||||
}
|
||||
}
|
||||
_macroPresets.put(macroId, new Macro(macroId, icon, name, description, acronym, commands));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a node an create a shortcut from it.
|
||||
* @param pageId the page ID
|
||||
* @param b the node to parse
|
||||
* @return the new shortcut
|
||||
*/
|
||||
private Shortcut createShortcut(int pageId, Node b)
|
||||
{
|
||||
final NamedNodeMap attrs = b.getAttributes();
|
||||
final int slotId = parseInteger(attrs, "slotId");
|
||||
final ShortcutType shortcutType = parseEnum(attrs, ShortcutType.class, "shortcutType");
|
||||
final int shortcutId = parseInteger(attrs, "shortcutId");
|
||||
final int shortcutLevel = parseInteger(attrs, "shortcutLevel", 0);
|
||||
final int characterType = parseInteger(attrs, "characterType", 0);
|
||||
return new Shortcut(slotId, pageId, shortcutType, shortcutId, shortcutLevel, characterType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the shortcut list.
|
||||
* @param cId the class ID for the shortcut list
|
||||
* @return the shortcut list for the give class ID
|
||||
*/
|
||||
public List<Shortcut> getShortcutList(ClassId cId)
|
||||
{
|
||||
return _initialShortcutData.get(cId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the shortcut list.
|
||||
* @param cId the class ID for the shortcut list
|
||||
* @return the shortcut list for the give class ID
|
||||
*/
|
||||
public List<Shortcut> getShortcutList(int cId)
|
||||
{
|
||||
return _initialShortcutData.get(ClassId.getClassId(cId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the global shortcut list.
|
||||
* @return the global shortcut list
|
||||
*/
|
||||
public List<Shortcut> getGlobalMacroList()
|
||||
{
|
||||
return _initialGlobalShortcutList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register all the available shortcuts for the given player.
|
||||
* @param player the player
|
||||
*/
|
||||
public void registerAllShortcuts(L2PcInstance player)
|
||||
{
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Register global shortcuts.
|
||||
for (Shortcut shortcut : _initialGlobalShortcutList)
|
||||
{
|
||||
int shortcutId = shortcut.getId();
|
||||
switch (shortcut.getType())
|
||||
{
|
||||
case ITEM:
|
||||
{
|
||||
final L2ItemInstance item = player.getInventory().getItemByItemId(shortcutId);
|
||||
if (item == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
shortcutId = item.getObjectId();
|
||||
break;
|
||||
}
|
||||
case SKILL:
|
||||
{
|
||||
if (!player.getSkills().containsKey(shortcutId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MACRO:
|
||||
{
|
||||
final Macro macro = _macroPresets.get(shortcutId);
|
||||
if (macro == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
player.registerMacro(macro);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Register shortcut
|
||||
final Shortcut newShortcut = new Shortcut(shortcut.getSlot(), shortcut.getPage(), shortcut.getType(), shortcutId, shortcut.getLevel(), shortcut.getCharacterType());
|
||||
player.sendPacket(new ShortCutRegister(newShortcut));
|
||||
player.registerShortCut(newShortcut);
|
||||
}
|
||||
|
||||
// Register class specific shortcuts.
|
||||
if (_initialShortcutData.containsKey(player.getClassId()))
|
||||
{
|
||||
for (Shortcut shortcut : _initialShortcutData.get(player.getClassId()))
|
||||
{
|
||||
int shortcutId = shortcut.getId();
|
||||
switch (shortcut.getType())
|
||||
{
|
||||
case ITEM:
|
||||
{
|
||||
final L2ItemInstance item = player.getInventory().getItemByItemId(shortcutId);
|
||||
if (item == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
shortcutId = item.getObjectId();
|
||||
break;
|
||||
}
|
||||
case SKILL:
|
||||
{
|
||||
if (!player.getSkills().containsKey(shortcut.getId()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MACRO:
|
||||
{
|
||||
final Macro macro = _macroPresets.get(shortcutId);
|
||||
if (macro == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
player.registerMacro(macro);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Register shortcut
|
||||
final Shortcut newShortcut = new Shortcut(shortcut.getSlot(), shortcut.getPage(), shortcut.getType(), shortcutId, shortcut.getLevel(), shortcut.getCharacterType());
|
||||
player.sendPacket(new ShortCutRegister(newShortcut));
|
||||
player.registerShortCut(newShortcut);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of InitialEquipmentData.
|
||||
* @return single instance of InitialEquipmentData
|
||||
*/
|
||||
public static InitialShortcutData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final InitialShortcutData _instance = new InitialShortcutData();
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.CrystalizationData;
|
||||
import com.l2jserver.gameserver.model.holders.ItemChanceHolder;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public final class ItemCrystalizationData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, CrystalizationData> _items = new HashMap<>();
|
||||
|
||||
protected ItemCrystalizationData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
parseDatapackFile("data/CrystalizableItems.xml");
|
||||
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _items.size() + " Items");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("crystalizable_item".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
final int id = parseInteger(d.getAttributes(), "id");
|
||||
final CrystalizationData data = new CrystalizationData(id);
|
||||
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
|
||||
{
|
||||
if ("item".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
NamedNodeMap attrs = c.getAttributes();
|
||||
final int itemId = parseInteger(attrs, "id");
|
||||
final long itemCount = parseLong(attrs, "count");
|
||||
final double itemChance = parseDouble(attrs, "chance");
|
||||
data.addItem(new ItemChanceHolder(itemId, itemChance, itemCount));
|
||||
}
|
||||
}
|
||||
_items.put(id, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CrystalizationData getCrystalization(int itemId)
|
||||
{
|
||||
return _items.get(itemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of ItemCrystalizationData.
|
||||
* @return single instance of ItemCrystalizationData
|
||||
*/
|
||||
public static final ItemCrystalizationData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final ItemCrystalizationData _instance = new ItemCrystalizationData();
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public class KarmaData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, Double> _karmaTable = new HashMap<>();
|
||||
|
||||
public KarmaData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
_karmaTable.clear();
|
||||
parseDatapackFile("data/stats/chars/pcKarmaIncrease.xml");
|
||||
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded " + _karmaTable.size() + " karma modifiers.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("pcKarmaIncrease".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("increase".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
attrs = d.getAttributes();
|
||||
_karmaTable.put(parseInteger(attrs, "lvl"), parseDouble(attrs, "val"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param level
|
||||
* @return {@code double} modifier used to calculate karma lost upon death.
|
||||
*/
|
||||
public double getMultiplier(int level)
|
||||
{
|
||||
return _karmaTable.get(level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of KarmaData.
|
||||
* @return single instance of KarmaData
|
||||
*/
|
||||
public static KarmaData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final KarmaData _instance = new KarmaData();
|
||||
}
|
||||
}
|
@ -0,0 +1,395 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.DOMException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
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.MultiSellList;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jserver.gameserver.network.serverpackets.UserInfo;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
import com.l2jserver.util.file.filter.NumericNameFilter;
|
||||
|
||||
public final class MultisellData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, ListContainer> _entries = new HashMap<>();
|
||||
|
||||
public static final int PAGE_SIZE = 40;
|
||||
// Special IDs.
|
||||
public static final int PC_BANG_POINTS = -100;
|
||||
public static final int CLAN_REPUTATION = -200;
|
||||
public static final int FAME = -300;
|
||||
// Misc
|
||||
private static final FileFilter NUMERIC_FILTER = new NumericNameFilter();
|
||||
|
||||
protected MultisellData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_entries.clear();
|
||||
parseDatapackDirectory("data/multisell", false);
|
||||
if (Config.CUSTOM_MULTISELL_LOAD)
|
||||
{
|
||||
parseDatapackDirectory("data/multisell/custom", false);
|
||||
}
|
||||
|
||||
verify();
|
||||
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded " + _entries.size() + " multisell lists.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc, File f)
|
||||
{
|
||||
try
|
||||
{
|
||||
int id = Integer.parseInt(f.getName().replaceAll(".xml", ""));
|
||||
int entryId = 1;
|
||||
Node att;
|
||||
final ListContainer list = new ListContainer(id);
|
||||
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
list.setApplyTaxes(parseBoolean(n.getAttributes(), "applyTaxes", false));
|
||||
list.setNewMultisell(parseBoolean(n.getAttributes(), "isNewMultisell", false));
|
||||
list.setMaintainEnchantment(parseBoolean(n.getAttributes(), "maintainEnchantment", false));
|
||||
|
||||
att = n.getAttributes().getNamedItem("useRate");
|
||||
if (att != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
list.setUseRate(Double.valueOf(att.getNodeValue()));
|
||||
if (list.getUseRate() <= 1e-6)
|
||||
{
|
||||
throw new NumberFormatException("The value cannot be 0"); // threat 0 as invalid value
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
list.setUseRate(Config.class.getField(att.getNodeValue()).getDouble(Config.class));
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
LOGGER.warning(e1.getMessage() + doc.getLocalName());
|
||||
list.setUseRate(1.0);
|
||||
}
|
||||
|
||||
}
|
||||
catch (DOMException e)
|
||||
{
|
||||
LOGGER.warning(e.getMessage() + doc.getLocalName());
|
||||
}
|
||||
}
|
||||
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("item".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
Entry e = parseEntry(d, entryId++, list);
|
||||
list.getEntries().add(e);
|
||||
}
|
||||
else if ("npcs".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
|
||||
{
|
||||
if ("npc".equalsIgnoreCase(b.getNodeName()))
|
||||
{
|
||||
if (Util.isDigit(b.getTextContent()))
|
||||
{
|
||||
list.allowNpc(Integer.parseInt(b.getTextContent()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_entries.put(id, list);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.SEVERE, getClass().getSimpleName() + ": Error in file " + f, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileFilter getCurrentFileFilter()
|
||||
{
|
||||
return NUMERIC_FILTER;
|
||||
}
|
||||
|
||||
private final Entry parseEntry(Node n, int entryId, ListContainer list)
|
||||
{
|
||||
Node first = n.getFirstChild();
|
||||
final Entry entry = new Entry(entryId);
|
||||
|
||||
NamedNodeMap attrs;
|
||||
Node att;
|
||||
StatsSet set;
|
||||
|
||||
for (n = first; n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("ingredient".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
attrs = n.getAttributes();
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
entry.addIngredient(new Ingredient(set));
|
||||
}
|
||||
else if ("production".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
attrs = n.getAttributes();
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
entry.addProduct(new Ingredient(set));
|
||||
}
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will generate the multisell list for the items.<br>
|
||||
* There exist various parameters in multisells that affect the way they will appear:
|
||||
* <ol>
|
||||
* <li>Inventory only:
|
||||
* <ul>
|
||||
* <li>If true, only show items of the multisell for which the "primary" ingredients are already in the player's inventory. By "primary" ingredients we mean weapon and armor.</li>
|
||||
* <li>If false, show the entire list.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>Maintain enchantment: presumably, only lists with "inventory only" set to true should sometimes have this as true. This makes no sense otherwise...
|
||||
* <ul>
|
||||
* <li>If true, then the product will match the enchantment level of the ingredient.<br>
|
||||
* If the player has multiple items that match the ingredient list but the enchantment levels differ, then the entries need to be duplicated to show the products and ingredients for each enchantment level.<br>
|
||||
* For example: If the player has a crystal staff +1 and a crystal staff +3 and goes to exchange it at the mammon, the list should have all exchange possibilities for the +1 staff, followed by all possibilities for the +3 staff.</li>
|
||||
* <li>If false, then any level ingredient will be considered equal and product will always be at +0</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>Apply taxes: Uses the "taxIngredient" entry in order to add a certain amount of adena to the ingredients.
|
||||
* <li>
|
||||
* <li>Additional product and ingredient multipliers.</li>
|
||||
* </ol>
|
||||
* @param listId
|
||||
* @param player
|
||||
* @param npc
|
||||
* @param inventoryOnly
|
||||
* @param productMultiplier
|
||||
* @param ingredientMultiplier
|
||||
*/
|
||||
public final void separateAndSend(int listId, L2PcInstance player, L2Npc npc, boolean inventoryOnly, double productMultiplier, double ingredientMultiplier)
|
||||
{
|
||||
ListContainer template = _entries.get(listId);
|
||||
if (template == null)
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": can't find list id: " + listId + " requested by player: " + player.getName() + ", npcId:" + (npc != null ? npc.getId() : 0));
|
||||
return;
|
||||
}
|
||||
|
||||
if (((npc != null) && !template.isNpcAllowed(npc.getId())) || ((npc == null) && template.isNpcOnly()))
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": player " + player + " attempted to open multisell " + listId + " from npc " + npc + " which is not allowed!");
|
||||
return;
|
||||
}
|
||||
|
||||
final PreparedListContainer list = new PreparedListContainer(template, inventoryOnly, player, npc);
|
||||
|
||||
// Pass through this only when multipliers are different from 1
|
||||
if ((productMultiplier != 1) || (ingredientMultiplier != 1))
|
||||
{
|
||||
list.getEntries().forEach(entry ->
|
||||
{
|
||||
// Math.max used here to avoid dropping count to 0
|
||||
entry.getProducts().forEach(product -> product.setItemCount((long) Math.max(product.getItemCount() * productMultiplier, 1)));
|
||||
|
||||
// Math.max used here to avoid dropping count to 0
|
||||
entry.getIngredients().forEach(ingredient -> ingredient.setItemCount((long) Math.max(ingredient.getItemCount() * ingredientMultiplier, 1)));
|
||||
});
|
||||
}
|
||||
int index = 0;
|
||||
do
|
||||
{
|
||||
// send list at least once even if size = 0
|
||||
player.sendPacket(new MultiSellList(list, index));
|
||||
index += PAGE_SIZE;
|
||||
}
|
||||
while (index < list.getEntries().size());
|
||||
|
||||
player.setMultiSell(list);
|
||||
}
|
||||
|
||||
public final void separateAndSend(int listId, L2PcInstance player, L2Npc npc, boolean inventoryOnly)
|
||||
{
|
||||
separateAndSend(listId, player, npc, inventoryOnly, 1, 1);
|
||||
}
|
||||
|
||||
public static final boolean hasSpecialIngredient(int id, long amount, L2PcInstance player)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case CLAN_REPUTATION:
|
||||
if (player.getClan() == null)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_ARE_NOT_A_CLAN_MEMBER_AND_CANNOT_PERFORM_THIS_ACTION);
|
||||
break;
|
||||
}
|
||||
if (!player.isClanLeader())
|
||||
{
|
||||
player.sendPacket(SystemMessageId.ONLY_THE_CLAN_LEADER_IS_ENABLED);
|
||||
break;
|
||||
}
|
||||
if (player.getClan().getReputationScore() < amount)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_CLAN_REPUTATION_IS_TOO_LOW);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
case FAME:
|
||||
if (player.getFame() < amount)
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_DON_T_HAVE_ENOUGH_FAME_TO_DO_THAT);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static final boolean takeSpecialIngredient(int id, long amount, L2PcInstance player)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case CLAN_REPUTATION:
|
||||
player.getClan().takeReputationScore((int) amount, true);
|
||||
SystemMessage smsg = SystemMessage.getSystemMessage(SystemMessageId.S1_POINT_S_HAVE_BEEN_DEDUCTED_FROM_THE_CLAN_S_REPUTATION);
|
||||
smsg.addLong(amount);
|
||||
player.sendPacket(smsg);
|
||||
return true;
|
||||
case FAME:
|
||||
player.setFame(player.getFame() - (int) amount);
|
||||
player.sendPacket(new UserInfo(player));
|
||||
// player.sendPacket(new ExBrExtraUserInfo(player));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static final void giveSpecialProduct(int id, long amount, L2PcInstance player)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case CLAN_REPUTATION:
|
||||
player.getClan().addReputationScore((int) amount, true);
|
||||
break;
|
||||
case FAME:
|
||||
player.setFame((int) (player.getFame() + amount));
|
||||
player.sendPacket(new UserInfo(player));
|
||||
// player.sendPacket(new ExBrExtraUserInfo(player));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private final void verify()
|
||||
{
|
||||
ListContainer list;
|
||||
final Iterator<ListContainer> iter = _entries.values().iterator();
|
||||
while (iter.hasNext())
|
||||
{
|
||||
list = iter.next();
|
||||
|
||||
for (Entry ent : list.getEntries())
|
||||
{
|
||||
for (Ingredient ing : ent.getIngredients())
|
||||
{
|
||||
if (!verifyIngredient(ing))
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": can't find ingredient with itemId: " + ing.getItemId() + " in list: " + list.getListId());
|
||||
}
|
||||
}
|
||||
for (Ingredient ing : ent.getProducts())
|
||||
{
|
||||
if (!verifyIngredient(ing))
|
||||
{
|
||||
LOGGER.warning(getClass().getSimpleName() + ": 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:
|
||||
return ing.getTemplate() != null;
|
||||
}
|
||||
}
|
||||
|
||||
public static MultisellData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final MultisellData _instance = new MultisellData();
|
||||
}
|
||||
}
|
870
trunk/java/com/l2jserver/gameserver/data/xml/impl/NpcData.java
Normal file
870
trunk/java/com/l2jserver/gameserver/data/xml/impl/NpcData.java
Normal file
@ -0,0 +1,870 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.enums.AISkillScope;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
import com.l2jserver.gameserver.model.drops.DropListScope;
|
||||
import com.l2jserver.gameserver.model.drops.GeneralDropItem;
|
||||
import com.l2jserver.gameserver.model.drops.GroupedGeneralDropItem;
|
||||
import com.l2jserver.gameserver.model.drops.IDropItem;
|
||||
import com.l2jserver.gameserver.model.effects.L2EffectType;
|
||||
import com.l2jserver.gameserver.model.holders.MinionHolder;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* NPC data parser.
|
||||
* @author NosBit
|
||||
*/
|
||||
public class NpcData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, L2NpcTemplate> _npcs = new ConcurrentHashMap<>();
|
||||
private final Map<String, Integer> _clans = new ConcurrentHashMap<>();
|
||||
private MinionData _minionData;
|
||||
|
||||
protected NpcData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
_minionData = new MinionData();
|
||||
|
||||
parseDatapackDirectory("data/stats/npcs", false);
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _npcs.size() + " NPCs.");
|
||||
|
||||
if (Config.CUSTOM_NPC_DATA)
|
||||
{
|
||||
final int npcCount = _npcs.size();
|
||||
parseDatapackDirectory("data/stats/npcs/custom", true);
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + (_npcs.size() - npcCount) + " Custom NPCs.");
|
||||
}
|
||||
|
||||
_minionData = null;
|
||||
loadNpcsSkillLearn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc, File f)
|
||||
{
|
||||
for (Node node = doc.getFirstChild(); node != null; node = node.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(node.getNodeName()))
|
||||
{
|
||||
for (Node list_node = node.getFirstChild(); list_node != null; list_node = list_node.getNextSibling())
|
||||
{
|
||||
if ("npc".equalsIgnoreCase(list_node.getNodeName()))
|
||||
{
|
||||
NamedNodeMap attrs = list_node.getAttributes();
|
||||
final StatsSet set = new StatsSet();
|
||||
final int npcId = parseInteger(attrs, "id");
|
||||
Map<String, Object> parameters = null;
|
||||
Map<Integer, Skill> skills = null;
|
||||
Set<Integer> clans = null;
|
||||
Set<Integer> ignoreClanNpcIds = null;
|
||||
Map<DropListScope, List<IDropItem>> dropLists = null;
|
||||
set.set("id", npcId);
|
||||
set.set("displayId", parseInteger(attrs, "displayId"));
|
||||
set.set("level", parseByte(attrs, "level"));
|
||||
set.set("type", parseString(attrs, "type"));
|
||||
set.set("name", parseString(attrs, "name"));
|
||||
set.set("usingServerSideName", parseBoolean(attrs, "usingServerSideName"));
|
||||
set.set("title", parseString(attrs, "title"));
|
||||
set.set("usingServerSideTitle", parseBoolean(attrs, "usingServerSideTitle"));
|
||||
for (Node npc_node = list_node.getFirstChild(); npc_node != null; npc_node = npc_node.getNextSibling())
|
||||
{
|
||||
attrs = npc_node.getAttributes();
|
||||
switch (npc_node.getNodeName().toLowerCase())
|
||||
{
|
||||
case "parameters":
|
||||
{
|
||||
if (parameters == null)
|
||||
{
|
||||
parameters = new HashMap<>();
|
||||
}
|
||||
|
||||
for (Node parameters_node = npc_node.getFirstChild(); parameters_node != null; parameters_node = parameters_node.getNextSibling())
|
||||
{
|
||||
attrs = parameters_node.getAttributes();
|
||||
switch (parameters_node.getNodeName().toLowerCase())
|
||||
{
|
||||
case "param":
|
||||
{
|
||||
parameters.put(parseString(attrs, "name"), parseString(attrs, "value"));
|
||||
break;
|
||||
}
|
||||
case "skill":
|
||||
{
|
||||
parameters.put(parseString(attrs, "name"), new SkillHolder(parseInteger(attrs, "id"), parseInteger(attrs, "level")));
|
||||
break;
|
||||
}
|
||||
case "minions":
|
||||
{
|
||||
final List<MinionHolder> minions = new ArrayList<>(1);
|
||||
for (Node minions_node = parameters_node.getFirstChild(); minions_node != null; minions_node = minions_node.getNextSibling())
|
||||
{
|
||||
if (minions_node.getNodeName().equalsIgnoreCase("npc"))
|
||||
{
|
||||
attrs = minions_node.getAttributes();
|
||||
minions.add(new MinionHolder(parseInteger(attrs, "id"), parseInteger(attrs, "count"), parseInteger(attrs, "respawnTime"), parseInteger(attrs, "weightPoint")));
|
||||
}
|
||||
}
|
||||
|
||||
if (!minions.isEmpty())
|
||||
{
|
||||
parameters.put(parseString(parameters_node.getAttributes(), "name"), minions);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "race":
|
||||
case "sex":
|
||||
set.set(npc_node.getNodeName(), npc_node.getTextContent().toUpperCase());
|
||||
break;
|
||||
case "equipment":
|
||||
{
|
||||
set.set("chestId", parseInteger(attrs, "chest"));
|
||||
set.set("rhandId", parseInteger(attrs, "rhand"));
|
||||
set.set("lhandId", parseInteger(attrs, "lhand"));
|
||||
set.set("weaponEnchant", parseInteger(attrs, "weaponEnchant"));
|
||||
break;
|
||||
}
|
||||
case "acquire":
|
||||
{
|
||||
set.set("expRate", parseDouble(attrs, "expRate"));
|
||||
set.set("sp", parseDouble(attrs, "sp"));
|
||||
set.set("raidPoints", parseDouble(attrs, "raidPoints"));
|
||||
break;
|
||||
}
|
||||
case "stats":
|
||||
{
|
||||
set.set("baseSTR", parseInteger(attrs, "str"));
|
||||
set.set("baseINT", parseInteger(attrs, "int"));
|
||||
set.set("baseDEX", parseInteger(attrs, "dex"));
|
||||
set.set("baseWIT", parseInteger(attrs, "wit"));
|
||||
set.set("baseCON", parseInteger(attrs, "con"));
|
||||
set.set("baseMEN", parseInteger(attrs, "men"));
|
||||
for (Node stats_node = npc_node.getFirstChild(); stats_node != null; stats_node = stats_node.getNextSibling())
|
||||
{
|
||||
attrs = stats_node.getAttributes();
|
||||
switch (stats_node.getNodeName().toLowerCase())
|
||||
{
|
||||
case "vitals":
|
||||
{
|
||||
set.set("baseHpMax", parseDouble(attrs, "hp"));
|
||||
set.set("baseHpReg", parseDouble(attrs, "hpRegen"));
|
||||
set.set("baseMpMax", parseDouble(attrs, "mp"));
|
||||
set.set("baseMpReg", parseDouble(attrs, "mpRegen"));
|
||||
break;
|
||||
}
|
||||
case "attack":
|
||||
{
|
||||
set.set("basePAtk", parseDouble(attrs, "physical"));
|
||||
set.set("baseMAtk", parseDouble(attrs, "magical"));
|
||||
set.set("baseRndDam", parseInteger(attrs, "random"));
|
||||
set.set("baseCritRate", parseInteger(attrs, "critical"));
|
||||
set.set("accuracy", parseDouble(attrs, "accuracy"));// TODO: Implement me
|
||||
set.set("basePAtkSpd", parseInteger(attrs, "attackSpeed"));
|
||||
set.set("reuseDelay", parseInteger(attrs, "reuseDelay"));// TODO: Implement me
|
||||
set.set("baseAtkType", parseString(attrs, "type"));
|
||||
set.set("baseAtkRange", parseInteger(attrs, "range"));
|
||||
set.set("distance", parseInteger(attrs, "distance"));// TODO: Implement me
|
||||
set.set("width", parseInteger(attrs, "width"));// TODO: Implement me
|
||||
break;
|
||||
}
|
||||
case "defence":
|
||||
{
|
||||
set.set("basePDef", parseDouble(attrs, "physical"));
|
||||
set.set("baseMDef", parseDouble(attrs, "magical"));
|
||||
set.set("evasion", parseInteger(attrs, "evasion"));// TODO: Implement me
|
||||
set.set("baseShldDef", parseInteger(attrs, "shield"));
|
||||
set.set("baseShldRate", parseInteger(attrs, "shieldRate"));
|
||||
break;
|
||||
}
|
||||
case "attribute":
|
||||
{
|
||||
for (Node attribute_node = stats_node.getFirstChild(); attribute_node != null; attribute_node = attribute_node.getNextSibling())
|
||||
{
|
||||
attrs = attribute_node.getAttributes();
|
||||
switch (attribute_node.getNodeName().toLowerCase())
|
||||
{
|
||||
case "attack":
|
||||
{
|
||||
String attackAttributeType = parseString(attrs, "type");
|
||||
switch (attackAttributeType.toUpperCase())
|
||||
{
|
||||
case "FIRE":
|
||||
set.set("baseFire", parseInteger(attrs, "value"));
|
||||
break;
|
||||
case "WATER":
|
||||
set.set("baseWater", parseInteger(attrs, "value"));
|
||||
break;
|
||||
case "WIND":
|
||||
set.set("baseWind", parseInteger(attrs, "value"));
|
||||
break;
|
||||
case "EARTH":
|
||||
set.set("baseEarth", parseInteger(attrs, "value"));
|
||||
break;
|
||||
case "DARK":
|
||||
set.set("baseDark", parseInteger(attrs, "value"));
|
||||
break;
|
||||
case "HOLY":
|
||||
set.set("baseHoly", parseInteger(attrs, "value"));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "defence":
|
||||
{
|
||||
set.set("baseFireRes", parseInteger(attrs, "fire"));
|
||||
set.set("baseWaterRes", parseInteger(attrs, "water"));
|
||||
set.set("baseWindRes", parseInteger(attrs, "wind"));
|
||||
set.set("baseEarthRes", parseInteger(attrs, "earth"));
|
||||
set.set("baseHolyRes", parseInteger(attrs, "holy"));
|
||||
set.set("baseDarkRes", parseInteger(attrs, "dark"));
|
||||
set.set("baseElementRes", parseInteger(attrs, "default"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "speed":
|
||||
{
|
||||
for (Node speed_node = stats_node.getFirstChild(); speed_node != null; speed_node = speed_node.getNextSibling())
|
||||
{
|
||||
attrs = speed_node.getAttributes();
|
||||
switch (speed_node.getNodeName().toLowerCase())
|
||||
{
|
||||
case "walk":
|
||||
{
|
||||
set.set("baseWalkSpd", parseDouble(attrs, "ground"));
|
||||
set.set("baseSwimWalkSpd", parseDouble(attrs, "swim"));
|
||||
set.set("baseFlyWalkSpd", parseDouble(attrs, "fly"));
|
||||
break;
|
||||
}
|
||||
case "run":
|
||||
{
|
||||
set.set("baseRunSpd", parseDouble(attrs, "ground"));
|
||||
set.set("baseSwimRunSpd", parseDouble(attrs, "swim"));
|
||||
set.set("baseFlyRunSpd", parseDouble(attrs, "fly"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "hit_time":
|
||||
set.set("hit_time", npc_node.getTextContent());// TODO: Implement me default 600 (value in ms)
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "status":
|
||||
{
|
||||
set.set("unique", parseBoolean(attrs, "unique"));
|
||||
set.set("attackable", parseBoolean(attrs, "attackable"));
|
||||
set.set("targetable", parseBoolean(attrs, "targetable"));
|
||||
set.set("talkable", parseBoolean(attrs, "talkable"));
|
||||
set.set("undying", parseBoolean(attrs, "undying"));
|
||||
set.set("showName", parseBoolean(attrs, "showName"));
|
||||
set.set("flying", parseBoolean(attrs, "flying"));
|
||||
set.set("canMove", parseBoolean(attrs, "canMove"));
|
||||
set.set("noSleepMode", parseBoolean(attrs, "noSleepMode"));
|
||||
set.set("passableDoor", parseBoolean(attrs, "passableDoor"));
|
||||
set.set("hasSummoner", parseBoolean(attrs, "hasSummoner"));
|
||||
set.set("canBeSown", parseBoolean(attrs, "canBeSown"));
|
||||
break;
|
||||
}
|
||||
case "skill_list":
|
||||
{
|
||||
skills = new HashMap<>();
|
||||
for (Node skill_list_node = npc_node.getFirstChild(); skill_list_node != null; skill_list_node = skill_list_node.getNextSibling())
|
||||
{
|
||||
if ("skill".equalsIgnoreCase(skill_list_node.getNodeName()))
|
||||
{
|
||||
attrs = skill_list_node.getAttributes();
|
||||
final int skillId = parseInteger(attrs, "id");
|
||||
final int skillLevel = parseInteger(attrs, "level");
|
||||
final Skill skill = SkillData.getInstance().getSkill(skillId, skillLevel);
|
||||
if (skill != null)
|
||||
{
|
||||
skills.put(skill.getId(), skill);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warning("[" + f.getName() + "] skill not found. NPC ID: " + npcId + " Skill ID:" + skillId + " Skill Level: " + skillLevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "shots":
|
||||
{
|
||||
set.set("soulShot", parseInteger(attrs, "soul"));
|
||||
set.set("spiritShot", parseInteger(attrs, "spirit"));
|
||||
set.set("shotShotChance", parseInteger(attrs, "shotChance"));
|
||||
set.set("spiritShotChance", parseInteger(attrs, "spiritChance"));
|
||||
break;
|
||||
}
|
||||
case "corpse_time":
|
||||
set.set("corpseTime", npc_node.getTextContent());
|
||||
break;
|
||||
case "ex_crt_effect":
|
||||
set.set("ex_crt_effect", npc_node.getTextContent()); // TODO: Implement me default ? type boolean
|
||||
break;
|
||||
case "s_npc_prop_hp_rate":
|
||||
set.set("s_npc_prop_hp_rate", npc_node.getTextContent()); // TODO: Implement me default 1 type double
|
||||
break;
|
||||
case "ai":
|
||||
{
|
||||
set.set("aiType", parseString(attrs, "type"));
|
||||
set.set("aggroRange", parseInteger(attrs, "aggroRange"));
|
||||
set.set("clanHelpRange", parseInteger(attrs, "clanHelpRange"));
|
||||
set.set("dodge", parseInteger(attrs, "dodge"));
|
||||
set.set("isChaos", parseBoolean(attrs, "isChaos"));
|
||||
set.set("isAggressive", parseBoolean(attrs, "isAggressive"));
|
||||
for (Node ai_node = npc_node.getFirstChild(); ai_node != null; ai_node = ai_node.getNextSibling())
|
||||
{
|
||||
attrs = ai_node.getAttributes();
|
||||
switch (ai_node.getNodeName().toLowerCase())
|
||||
{
|
||||
case "skill":
|
||||
{
|
||||
set.set("minSkillChance", parseInteger(attrs, "minChance"));
|
||||
set.set("maxSkillChance", parseInteger(attrs, "maxChance"));
|
||||
set.set("primarySkillId", parseInteger(attrs, "primaryId"));
|
||||
set.set("shortRangeSkillId", parseInteger(attrs, "shortRangeId"));
|
||||
set.set("shortRangeSkillChance", parseInteger(attrs, "shortRangeChance"));
|
||||
set.set("longRangeSkillId", parseInteger(attrs, "longRangeId"));
|
||||
set.set("longRangeSkillChance", parseInteger(attrs, "longRangeChance"));
|
||||
break;
|
||||
}
|
||||
case "clan_list":
|
||||
{
|
||||
for (Node clan_list_node = ai_node.getFirstChild(); clan_list_node != null; clan_list_node = clan_list_node.getNextSibling())
|
||||
{
|
||||
attrs = clan_list_node.getAttributes();
|
||||
switch (clan_list_node.getNodeName().toLowerCase())
|
||||
{
|
||||
case "clan":
|
||||
{
|
||||
if (clans == null)
|
||||
{
|
||||
clans = new HashSet<>(1);
|
||||
}
|
||||
clans.add(getOrCreateClanId(clan_list_node.getTextContent()));
|
||||
break;
|
||||
}
|
||||
case "ignore_npc_id":
|
||||
{
|
||||
if (ignoreClanNpcIds == null)
|
||||
{
|
||||
ignoreClanNpcIds = new HashSet<>(1);
|
||||
}
|
||||
ignoreClanNpcIds.add(Integer.parseInt(clan_list_node.getTextContent()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "drop_lists":
|
||||
{
|
||||
for (Node drop_lists_node = npc_node.getFirstChild(); drop_lists_node != null; drop_lists_node = drop_lists_node.getNextSibling())
|
||||
{
|
||||
DropListScope dropListScope = null;
|
||||
|
||||
try
|
||||
{
|
||||
dropListScope = Enum.valueOf(DropListScope.class, drop_lists_node.getNodeName().toUpperCase());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
|
||||
if (dropListScope != null)
|
||||
{
|
||||
if (dropLists == null)
|
||||
{
|
||||
dropLists = new EnumMap<>(DropListScope.class);
|
||||
}
|
||||
|
||||
List<IDropItem> dropList = new ArrayList<>();
|
||||
parseDropList(f, drop_lists_node, dropListScope, dropList);
|
||||
dropLists.put(dropListScope, Collections.unmodifiableList(dropList));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "collision":
|
||||
{
|
||||
for (Node collision_node = npc_node.getFirstChild(); collision_node != null; collision_node = collision_node.getNextSibling())
|
||||
{
|
||||
attrs = collision_node.getAttributes();
|
||||
switch (collision_node.getNodeName().toLowerCase())
|
||||
{
|
||||
case "radius":
|
||||
{
|
||||
set.set("collision_radius", parseDouble(attrs, "normal"));
|
||||
set.set("collisionRadiusGrown", parseDouble(attrs, "grown"));
|
||||
break;
|
||||
}
|
||||
case "height":
|
||||
{
|
||||
set.set("collision_height", parseDouble(attrs, "normal"));
|
||||
set.set("collisionHeightGrown", parseDouble(attrs, "grown"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
L2NpcTemplate template = _npcs.get(npcId);
|
||||
if (template == null)
|
||||
{
|
||||
template = new L2NpcTemplate(set);
|
||||
_npcs.put(template.getId(), template);
|
||||
}
|
||||
else
|
||||
{
|
||||
template.set(set);
|
||||
}
|
||||
|
||||
if (_minionData._tempMinions.containsKey(npcId))
|
||||
{
|
||||
if (parameters == null)
|
||||
{
|
||||
parameters = new HashMap<>();
|
||||
}
|
||||
parameters.putIfAbsent("Privates", _minionData._tempMinions.get(npcId));
|
||||
}
|
||||
|
||||
if (parameters != null)
|
||||
{
|
||||
// Using unmodifiable map parameters of template are not meant to be changed at runtime.
|
||||
template.setParameters(new StatsSet(Collections.unmodifiableMap(parameters)));
|
||||
}
|
||||
else
|
||||
{
|
||||
template.setParameters(StatsSet.EMPTY_STATSET);
|
||||
}
|
||||
|
||||
if (skills != null)
|
||||
{
|
||||
Map<AISkillScope, List<Skill>> aiSkillLists = null;
|
||||
for (Skill skill : skills.values())
|
||||
{
|
||||
if (!skill.isPassive())
|
||||
{
|
||||
if (aiSkillLists == null)
|
||||
{
|
||||
aiSkillLists = new EnumMap<>(AISkillScope.class);
|
||||
}
|
||||
|
||||
List<AISkillScope> aiSkillScopes = new ArrayList<>();
|
||||
final AISkillScope shortOrLongRangeScope = skill.getCastRange() <= 150 ? AISkillScope.SHORT_RANGE : AISkillScope.SHORT_RANGE;
|
||||
if (skill.isSuicideAttack())
|
||||
{
|
||||
aiSkillScopes.add(AISkillScope.SUICIDE);
|
||||
}
|
||||
else
|
||||
{
|
||||
aiSkillScopes.add(AISkillScope.GENERAL);
|
||||
|
||||
if (skill.isContinuous())
|
||||
{
|
||||
if (!skill.isDebuff())
|
||||
{
|
||||
aiSkillScopes.add(AISkillScope.BUFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
aiSkillScopes.add(AISkillScope.DEBUFF);
|
||||
aiSkillScopes.add(AISkillScope.COT);
|
||||
aiSkillScopes.add(shortOrLongRangeScope);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (skill.hasEffectType(L2EffectType.DISPEL, L2EffectType.DISPEL_BY_SLOT))
|
||||
{
|
||||
aiSkillScopes.add(AISkillScope.NEGATIVE);
|
||||
aiSkillScopes.add(shortOrLongRangeScope);
|
||||
}
|
||||
else if (skill.hasEffectType(L2EffectType.HEAL))
|
||||
{
|
||||
aiSkillScopes.add(AISkillScope.HEAL);
|
||||
}
|
||||
else if (skill.hasEffectType(L2EffectType.PHYSICAL_ATTACK, L2EffectType.PHYSICAL_ATTACK_HP_LINK, L2EffectType.MAGICAL_ATTACK, L2EffectType.DEATH_LINK, L2EffectType.HP_DRAIN))
|
||||
{
|
||||
aiSkillScopes.add(AISkillScope.ATTACK);
|
||||
aiSkillScopes.add(AISkillScope.UNIVERSAL);
|
||||
aiSkillScopes.add(shortOrLongRangeScope);
|
||||
}
|
||||
else if (skill.hasEffectType(L2EffectType.SLEEP))
|
||||
{
|
||||
aiSkillScopes.add(AISkillScope.IMMOBILIZE);
|
||||
}
|
||||
else if (skill.hasEffectType(L2EffectType.STUN, L2EffectType.ROOT))
|
||||
{
|
||||
aiSkillScopes.add(AISkillScope.IMMOBILIZE);
|
||||
aiSkillScopes.add(shortOrLongRangeScope);
|
||||
}
|
||||
else if (skill.hasEffectType(L2EffectType.MUTE, L2EffectType.FEAR))
|
||||
{
|
||||
aiSkillScopes.add(AISkillScope.COT);
|
||||
aiSkillScopes.add(shortOrLongRangeScope);
|
||||
}
|
||||
else if (skill.hasEffectType(L2EffectType.PARALYZE))
|
||||
{
|
||||
aiSkillScopes.add(AISkillScope.IMMOBILIZE);
|
||||
aiSkillScopes.add(shortOrLongRangeScope);
|
||||
}
|
||||
else if (skill.hasEffectType(L2EffectType.DMG_OVER_TIME, L2EffectType.DMG_OVER_TIME_PERCENT))
|
||||
{
|
||||
aiSkillScopes.add(shortOrLongRangeScope);
|
||||
}
|
||||
else if (skill.hasEffectType(L2EffectType.RESURRECTION))
|
||||
{
|
||||
aiSkillScopes.add(AISkillScope.RES);
|
||||
}
|
||||
else
|
||||
{
|
||||
aiSkillScopes.add(AISkillScope.UNIVERSAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (AISkillScope aiSkillScope : aiSkillScopes)
|
||||
{
|
||||
List<Skill> aiSkills = aiSkillLists.get(aiSkillScope);
|
||||
if (aiSkills == null)
|
||||
{
|
||||
aiSkills = new ArrayList<>();
|
||||
aiSkillLists.put(aiSkillScope, aiSkills);
|
||||
}
|
||||
|
||||
aiSkills.add(skill);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template.setSkills(skills);
|
||||
template.setAISkillLists(aiSkillLists);
|
||||
}
|
||||
else
|
||||
{
|
||||
template.setSkills(null);
|
||||
template.setAISkillLists(null);
|
||||
}
|
||||
|
||||
template.setClans(clans);
|
||||
template.setIgnoreClanNpcIds(ignoreClanNpcIds);
|
||||
|
||||
template.setDropLists(dropLists);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDropList(File f, Node drop_list_node, DropListScope dropListScope, List<IDropItem> drops)
|
||||
{
|
||||
for (Node drop_node = drop_list_node.getFirstChild(); drop_node != null; drop_node = drop_node.getNextSibling())
|
||||
{
|
||||
NamedNodeMap attrs = drop_node.getAttributes();
|
||||
switch (drop_node.getNodeName().toLowerCase())
|
||||
{
|
||||
case "group":
|
||||
{
|
||||
GroupedGeneralDropItem dropItem = dropListScope.newGroupedDropItem(parseDouble(attrs, "chance"));
|
||||
List<IDropItem> groupedDropList = new ArrayList<>(2);
|
||||
for (Node group_node = drop_node.getFirstChild(); group_node != null; group_node = group_node.getNextSibling())
|
||||
{
|
||||
parseDropListItem(group_node, dropListScope, groupedDropList);
|
||||
}
|
||||
|
||||
List<GeneralDropItem> items = new ArrayList<>(groupedDropList.size());
|
||||
for (IDropItem item : groupedDropList)
|
||||
{
|
||||
if (item instanceof GeneralDropItem)
|
||||
{
|
||||
items.add((GeneralDropItem) item);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.warning("[" + f + "] grouped general drop item supports only general drop item.");
|
||||
}
|
||||
}
|
||||
dropItem.setItems(items);
|
||||
|
||||
drops.add(dropItem);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
parseDropListItem(drop_node, dropListScope, drops);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDropListItem(Node drop_list_item, DropListScope dropListScope, List<IDropItem> drops)
|
||||
{
|
||||
NamedNodeMap attrs = drop_list_item.getAttributes();
|
||||
switch (drop_list_item.getNodeName().toLowerCase())
|
||||
{
|
||||
case "item":
|
||||
{
|
||||
final IDropItem dropItem = dropListScope.newDropItem(parseInteger(attrs, "id"), parseLong(attrs, "min"), parseLong(attrs, "max"), parseDouble(attrs, "chance"));
|
||||
if (dropItem != null)
|
||||
{
|
||||
drops.add(dropItem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets or creates a clan id if it doesnt exists.
|
||||
* @param clanName the clan name to get or create its id
|
||||
* @return the clan id for the given clan name
|
||||
*/
|
||||
private int getOrCreateClanId(String clanName)
|
||||
{
|
||||
Integer id = _clans.get(clanName.toUpperCase());
|
||||
if (id == null)
|
||||
{
|
||||
id = _clans.size();
|
||||
_clans.put(clanName.toUpperCase(), id);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the clan id
|
||||
* @param clanName the clan name to get its id
|
||||
* @return the clan id for the given clan name if it exists, -1 otherwise
|
||||
*/
|
||||
public int getClanId(String clanName)
|
||||
{
|
||||
Integer id = _clans.get(clanName.toUpperCase());
|
||||
return id != null ? id : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the template.
|
||||
* @param id the template Id to get.
|
||||
* @return the template for the given id.
|
||||
*/
|
||||
public L2NpcTemplate getTemplate(int id)
|
||||
{
|
||||
return _npcs.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the template by name.
|
||||
* @param name of the template to get.
|
||||
* @return the template for the given name.
|
||||
*/
|
||||
public L2NpcTemplate getTemplateByName(String name)
|
||||
{
|
||||
for (L2NpcTemplate npcTemplate : _npcs.values())
|
||||
{
|
||||
if (npcTemplate.getName().equalsIgnoreCase(name))
|
||||
{
|
||||
return npcTemplate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all templates matching the filter.
|
||||
* @param filter
|
||||
* @return the template list for the given filter
|
||||
*/
|
||||
public List<L2NpcTemplate> getTemplates(Predicate<L2NpcTemplate> filter)
|
||||
{
|
||||
//@formatter:off
|
||||
return _npcs.values().stream()
|
||||
.filter(filter)
|
||||
.collect(Collectors.toList());
|
||||
//@formatter:on
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the all of level.
|
||||
* @param lvls of all the templates to get.
|
||||
* @return the template list for the given level.
|
||||
*/
|
||||
public List<L2NpcTemplate> getAllOfLevel(int... lvls)
|
||||
{
|
||||
return getTemplates(template -> Util.contains(lvls, template.getLevel()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the all monsters of level.
|
||||
* @param lvls of all the monster templates to get.
|
||||
* @return the template list for the given level.
|
||||
*/
|
||||
public List<L2NpcTemplate> getAllMonstersOfLevel(int... lvls)
|
||||
{
|
||||
return getTemplates(template -> Util.contains(lvls, template.getLevel()) && template.isType("L2Monster"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the all npc starting with.
|
||||
* @param text of all the NPC templates which its name start with.
|
||||
* @return the template list for the given letter.
|
||||
*/
|
||||
public List<L2NpcTemplate> getAllNpcStartingWith(String text)
|
||||
{
|
||||
return getTemplates(template -> template.isType("L2Npc") && template.getName().startsWith(text));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the all npc of class type.
|
||||
* @param classTypes of all the templates to get.
|
||||
* @return the template list for the given class type.
|
||||
*/
|
||||
public List<L2NpcTemplate> getAllNpcOfClassType(String... classTypes)
|
||||
{
|
||||
return getTemplates(template -> Util.contains(classTypes, template.getType(), true));
|
||||
}
|
||||
|
||||
public void loadNpcsSkillLearn()
|
||||
{
|
||||
_npcs.values().forEach(template ->
|
||||
{
|
||||
final List<ClassId> teachInfo = SkillLearnData.getInstance().getSkillLearnData(template.getId());
|
||||
if (teachInfo != null)
|
||||
{
|
||||
template.addTeachInfo(teachInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This class handles minions from Spawn System<br>
|
||||
* Once Spawn System gets reworked delete this class<br>
|
||||
* @author Zealar
|
||||
*/
|
||||
private final class MinionData implements IXmlReader
|
||||
{
|
||||
public final Map<Integer, List<MinionHolder>> _tempMinions = new HashMap<>();
|
||||
|
||||
protected MinionData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_tempMinions.clear();
|
||||
parseDatapackFile("data/minionData.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _tempMinions.size() + " minions data.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node node = doc.getFirstChild(); node != null; node = node.getNextSibling())
|
||||
{
|
||||
if ("list".equals(node.getNodeName()))
|
||||
{
|
||||
for (Node list_node = node.getFirstChild(); list_node != null; list_node = list_node.getNextSibling())
|
||||
{
|
||||
if ("npc".equals(list_node.getNodeName()))
|
||||
{
|
||||
final List<MinionHolder> minions = new ArrayList<>(1);
|
||||
NamedNodeMap attrs = list_node.getAttributes();
|
||||
int id = parseInteger(attrs, "id");
|
||||
for (Node npc_node = list_node.getFirstChild(); npc_node != null; npc_node = npc_node.getNextSibling())
|
||||
{
|
||||
if ("minion".equals(npc_node.getNodeName()))
|
||||
{
|
||||
attrs = npc_node.getAttributes();
|
||||
minions.add(new MinionHolder(parseInteger(attrs, "id"), parseInteger(attrs, "count"), parseInteger(attrs, "respawnTime"), 0));
|
||||
}
|
||||
}
|
||||
_tempMinions.put(id, minions);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of NpcData.
|
||||
* @return single instance of NpcData
|
||||
*/
|
||||
public static NpcData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final NpcData _instance = new NpcData();
|
||||
}
|
||||
}
|
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.options.Options;
|
||||
import com.l2jserver.gameserver.model.options.OptionsSkillHolder;
|
||||
import com.l2jserver.gameserver.model.options.OptionsSkillType;
|
||||
import com.l2jserver.gameserver.model.stats.Stats;
|
||||
import com.l2jserver.gameserver.model.stats.functions.FuncTemplate;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public class OptionData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, Options> _optionData = new HashMap<>();
|
||||
|
||||
protected OptionData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
_optionData.clear();
|
||||
parseDatapackDirectory("data/stats/options", false);
|
||||
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _optionData.size() + " Options.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
int id;
|
||||
Options op;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("option".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
id = parseInteger(d.getAttributes(), "id");
|
||||
op = new Options(id);
|
||||
|
||||
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
|
||||
{
|
||||
switch (cd.getNodeName())
|
||||
{
|
||||
case "for":
|
||||
{
|
||||
for (Node fd = cd.getFirstChild(); fd != null; fd = fd.getNextSibling())
|
||||
{
|
||||
switch (fd.getNodeName())
|
||||
{
|
||||
case "add":
|
||||
case "sub":
|
||||
case "mul":
|
||||
case "div":
|
||||
case "set":
|
||||
case "share":
|
||||
case "enchant":
|
||||
case "enchanthp":
|
||||
{
|
||||
parseFuncs(fd.getAttributes(), fd.getNodeName(), op);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "active_skill":
|
||||
{
|
||||
op.setActiveSkill(new SkillHolder(parseInteger(cd.getAttributes(), "id"), parseInteger(cd.getAttributes(), "level")));
|
||||
break;
|
||||
}
|
||||
case "passive_skill":
|
||||
{
|
||||
op.setPassiveSkill(new SkillHolder(parseInteger(cd.getAttributes(), "id"), parseInteger(cd.getAttributes(), "level")));
|
||||
break;
|
||||
}
|
||||
case "attack_skill":
|
||||
{
|
||||
op.addActivationSkill(new OptionsSkillHolder(parseInteger(cd.getAttributes(), "id"), parseInteger(cd.getAttributes(), "level"), parseDouble(cd.getAttributes(), "chance"), OptionsSkillType.ATTACK));
|
||||
break;
|
||||
}
|
||||
case "magic_skill":
|
||||
{
|
||||
op.addActivationSkill(new OptionsSkillHolder(parseInteger(cd.getAttributes(), "id"), parseInteger(cd.getAttributes(), "level"), parseDouble(cd.getAttributes(), "chance"), OptionsSkillType.MAGIC));
|
||||
break;
|
||||
}
|
||||
case "critical_skill":
|
||||
{
|
||||
op.addActivationSkill(new OptionsSkillHolder(parseInteger(cd.getAttributes(), "id"), parseInteger(cd.getAttributes(), "level"), parseDouble(cd.getAttributes(), "chance"), OptionsSkillType.CRITICAL));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_optionData.put(op.getId(), op);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseFuncs(NamedNodeMap attrs, String functionName, Options op)
|
||||
{
|
||||
Stats stat = Stats.valueOfXml(parseString(attrs, "stat"));
|
||||
double val = parseDouble(attrs, "val");
|
||||
int order = -1;
|
||||
final Node orderNode = attrs.getNamedItem("order");
|
||||
if (orderNode != null)
|
||||
{
|
||||
order = Integer.parseInt(orderNode.getNodeValue());
|
||||
}
|
||||
op.addFunc(new FuncTemplate(null, null, functionName, order, stat, val));
|
||||
}
|
||||
|
||||
public Options getOptions(int id)
|
||||
{
|
||||
return _optionData.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of OptionsData.
|
||||
* @return single instance of OptionsData
|
||||
*/
|
||||
public static final OptionData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final OptionData _instance = new OptionData();
|
||||
}
|
||||
}
|
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.enums.MountType;
|
||||
import com.l2jserver.gameserver.model.L2PetData;
|
||||
import com.l2jserver.gameserver.model.L2PetLevelData;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
|
||||
/**
|
||||
* This class parse and hold all pet parameters.<br>
|
||||
* TODO: load and use all pet parameters.
|
||||
* @author Zoey76 (rework)
|
||||
*/
|
||||
public final class PetDataTable implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, L2PetData> _pets = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new pet data table.
|
||||
*/
|
||||
protected PetDataTable()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_pets.clear();
|
||||
parseDatapackDirectory("data/stats/pets", false);
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _pets.size() + " Pets.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
Node n = doc.getFirstChild();
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if (d.getNodeName().equals("pet"))
|
||||
{
|
||||
int npcId = parseInteger(d.getAttributes(), "id");
|
||||
int itemId = parseInteger(d.getAttributes(), "itemId");
|
||||
// index ignored for now
|
||||
L2PetData data = new L2PetData(npcId, itemId);
|
||||
for (Node p = d.getFirstChild(); p != null; p = p.getNextSibling())
|
||||
{
|
||||
if (p.getNodeName().equals("set"))
|
||||
{
|
||||
attrs = p.getAttributes();
|
||||
String type = attrs.getNamedItem("name").getNodeValue();
|
||||
if ("food".equals(type))
|
||||
{
|
||||
for (String foodId : attrs.getNamedItem("val").getNodeValue().split(";"))
|
||||
{
|
||||
data.addFood(Integer.valueOf(foodId));
|
||||
}
|
||||
}
|
||||
else if ("load".equals(type))
|
||||
{
|
||||
data.setLoad(parseInteger(attrs, "val"));
|
||||
}
|
||||
else if ("hungry_limit".equals(type))
|
||||
{
|
||||
data.setHungryLimit(parseInteger(attrs, "val"));
|
||||
}
|
||||
else if ("sync_level".equals(type))
|
||||
{
|
||||
data.setSyncLevel(parseInteger(attrs, "val") == 1);
|
||||
}
|
||||
// evolve ignored
|
||||
}
|
||||
else if (p.getNodeName().equals("skills"))
|
||||
{
|
||||
for (Node s = p.getFirstChild(); s != null; s = s.getNextSibling())
|
||||
{
|
||||
if (s.getNodeName().equals("skill"))
|
||||
{
|
||||
attrs = s.getAttributes();
|
||||
data.addNewSkill(parseInteger(attrs, "skillId"), parseInteger(attrs, "skillLvl"), parseInteger(attrs, "minLvl"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (p.getNodeName().equals("stats"))
|
||||
{
|
||||
for (Node s = p.getFirstChild(); s != null; s = s.getNextSibling())
|
||||
{
|
||||
if (s.getNodeName().equals("stat"))
|
||||
{
|
||||
final int level = Integer.parseInt(s.getAttributes().getNamedItem("level").getNodeValue());
|
||||
final StatsSet set = new StatsSet();
|
||||
for (Node bean = s.getFirstChild(); bean != null; bean = bean.getNextSibling())
|
||||
{
|
||||
if (bean.getNodeName().equals("set"))
|
||||
{
|
||||
attrs = bean.getAttributes();
|
||||
if (attrs.getNamedItem("name").getNodeValue().equals("speed_on_ride"))
|
||||
{
|
||||
set.set("walkSpeedOnRide", attrs.getNamedItem("walk").getNodeValue());
|
||||
set.set("runSpeedOnRide", attrs.getNamedItem("run").getNodeValue());
|
||||
set.set("slowSwimSpeedOnRide", attrs.getNamedItem("slowSwim").getNodeValue());
|
||||
set.set("fastSwimSpeedOnRide", attrs.getNamedItem("fastSwim").getNodeValue());
|
||||
if (attrs.getNamedItem("slowFly") != null)
|
||||
{
|
||||
set.set("slowFlySpeedOnRide", attrs.getNamedItem("slowFly").getNodeValue());
|
||||
}
|
||||
if (attrs.getNamedItem("fastFly") != null)
|
||||
{
|
||||
set.set("fastFlySpeedOnRide", attrs.getNamedItem("fastFly").getNodeValue());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
set.set(attrs.getNamedItem("name").getNodeValue(), attrs.getNamedItem("val").getNodeValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
data.addNewStat(level, new L2PetLevelData(set));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_pets.put(npcId, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param itemId
|
||||
* @return
|
||||
*/
|
||||
public L2PetData getPetDataByItemId(int itemId)
|
||||
{
|
||||
for (L2PetData data : _pets.values())
|
||||
{
|
||||
if (data.getItemId() == itemId)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pet level data.
|
||||
* @param petId the pet Id.
|
||||
* @param petLevel the pet level.
|
||||
* @return the pet's parameters for the given Id and level.
|
||||
*/
|
||||
public L2PetLevelData getPetLevelData(int petId, int petLevel)
|
||||
{
|
||||
final L2PetData pd = getPetData(petId);
|
||||
if (pd != null)
|
||||
{
|
||||
return pd.getPetLevelData(petLevel);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pet data.
|
||||
* @param petId the pet Id.
|
||||
* @return the pet data
|
||||
*/
|
||||
public L2PetData getPetData(int petId)
|
||||
{
|
||||
if (!_pets.containsKey(petId))
|
||||
{
|
||||
LOGGER.info(getClass().getSimpleName() + ": Missing pet data for npcid: " + petId);
|
||||
}
|
||||
return _pets.get(petId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pet min level.
|
||||
* @param petId the pet Id.
|
||||
* @return the pet min level
|
||||
*/
|
||||
public int getPetMinLevel(int petId)
|
||||
{
|
||||
return _pets.get(petId).getMinLevel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pet items by npc.
|
||||
* @param npcId the NPC ID to get its summoning item
|
||||
* @return summoning item for the given NPC ID
|
||||
*/
|
||||
public int getPetItemsByNpc(int npcId)
|
||||
{
|
||||
return _pets.get(npcId).getItemId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is mountable.
|
||||
* @param npcId the NPC Id to verify.
|
||||
* @return {@code true} if the given Id is from a mountable pet, {@code false} otherwise.
|
||||
*/
|
||||
public static boolean isMountable(int npcId)
|
||||
{
|
||||
return MountType.findByNpcId(npcId) != MountType.NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of PetDataTable.
|
||||
* @return this class unique instance.
|
||||
*/
|
||||
public static PetDataTable getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final PetDataTable _instance = new PetDataTable();
|
||||
}
|
||||
}
|
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2PcTemplate;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
|
||||
/**
|
||||
* Loads player's base stats.
|
||||
* @author Forsaiken, Zoey76, GKR
|
||||
*/
|
||||
public final class PlayerTemplateData implements IXmlReader
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(PlayerTemplateData.class.getName());
|
||||
|
||||
private final Map<ClassId, L2PcTemplate> _playerTemplates = new HashMap<>();
|
||||
|
||||
private int _dataCount = 0;
|
||||
|
||||
protected PlayerTemplateData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_playerTemplates.clear();
|
||||
parseDatapackDirectory("data/stats/chars/baseStats", false);
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _playerTemplates.size() + " character templates.");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _dataCount + " level up gain records.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
int classId = 0;
|
||||
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("classId".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
classId = Integer.parseInt(d.getTextContent());
|
||||
}
|
||||
else if ("staticData".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
StatsSet set = new StatsSet();
|
||||
set.set("classId", classId);
|
||||
List<Location> creationPoints = new ArrayList<>();
|
||||
|
||||
for (Node nd = d.getFirstChild(); nd != null; nd = nd.getNextSibling())
|
||||
{
|
||||
// Skip odd nodes
|
||||
if (nd.getNodeName().equals("#text"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nd.getChildNodes().getLength() > 1)
|
||||
{
|
||||
for (Node cnd = nd.getFirstChild(); cnd != null; cnd = cnd.getNextSibling())
|
||||
{
|
||||
// use L2CharTemplate(superclass) fields for male collision height and collision radius
|
||||
if (nd.getNodeName().equalsIgnoreCase("collisionMale"))
|
||||
{
|
||||
if (cnd.getNodeName().equalsIgnoreCase("radius"))
|
||||
{
|
||||
set.set("collision_radius", cnd.getTextContent());
|
||||
}
|
||||
else if (cnd.getNodeName().equalsIgnoreCase("height"))
|
||||
{
|
||||
set.set("collision_height", cnd.getTextContent());
|
||||
}
|
||||
}
|
||||
if ("node".equalsIgnoreCase(cnd.getNodeName()))
|
||||
{
|
||||
attrs = cnd.getAttributes();
|
||||
creationPoints.add(new Location(parseInteger(attrs, "x"), parseInteger(attrs, "y"), parseInteger(attrs, "z")));
|
||||
}
|
||||
else if ("walk".equalsIgnoreCase(cnd.getNodeName()))
|
||||
{
|
||||
set.set("baseWalkSpd", cnd.getTextContent());
|
||||
}
|
||||
else if ("run".equalsIgnoreCase(cnd.getNodeName()))
|
||||
{
|
||||
set.set("baseRunSpd", cnd.getTextContent());
|
||||
}
|
||||
else if ("slowSwim".equals(cnd.getNodeName()))
|
||||
{
|
||||
set.set("baseSwimWalkSpd", cnd.getTextContent());
|
||||
}
|
||||
else if ("fastSwim".equals(cnd.getNodeName()))
|
||||
{
|
||||
set.set("baseSwimRunSpd", cnd.getTextContent());
|
||||
}
|
||||
else if (!cnd.getNodeName().equals("#text"))
|
||||
{
|
||||
set.set((nd.getNodeName() + cnd.getNodeName()), cnd.getTextContent());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
set.set(nd.getNodeName(), nd.getTextContent());
|
||||
}
|
||||
}
|
||||
// calculate total pdef and mdef from parts
|
||||
set.set("basePDef", (set.getInt("basePDefchest", 0) + set.getInt("basePDeflegs", 0) + set.getInt("basePDefhead", 0) + set.getInt("basePDeffeet", 0) + set.getInt("basePDefgloves", 0) + set.getInt("basePDefunderwear", 0) + set.getInt("basePDefcloak", 0)));
|
||||
set.set("baseMDef", (set.getInt("baseMDefrear", 0) + set.getInt("baseMDeflear", 0) + set.getInt("baseMDefrfinger", 0) + set.getInt("baseMDefrfinger", 0) + set.getInt("baseMDefneck", 0)));
|
||||
|
||||
_playerTemplates.put(ClassId.getClassId(classId), new L2PcTemplate(set, creationPoints));
|
||||
}
|
||||
else if ("lvlUpgainData".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
for (Node lvlNode = d.getFirstChild(); lvlNode != null; lvlNode = lvlNode.getNextSibling())
|
||||
{
|
||||
if ("level".equalsIgnoreCase(lvlNode.getNodeName()))
|
||||
{
|
||||
attrs = lvlNode.getAttributes();
|
||||
int level = parseInteger(attrs, "val");
|
||||
|
||||
for (Node valNode = lvlNode.getFirstChild(); valNode != null; valNode = valNode.getNextSibling())
|
||||
{
|
||||
String nodeName = valNode.getNodeName();
|
||||
|
||||
if ((nodeName.startsWith("hp") || nodeName.startsWith("mp") || nodeName.startsWith("cp")) && _playerTemplates.containsKey(ClassId.getClassId(classId)))
|
||||
{
|
||||
_playerTemplates.get(ClassId.getClassId(classId)).setUpgainValue(nodeName, level, Double.parseDouble(valNode.getTextContent()));
|
||||
_dataCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public L2PcTemplate getTemplate(ClassId classId)
|
||||
{
|
||||
return _playerTemplates.get(classId);
|
||||
}
|
||||
|
||||
public L2PcTemplate getTemplate(int classId)
|
||||
{
|
||||
return _playerTemplates.get(ClassId.getClassId(classId));
|
||||
}
|
||||
|
||||
public static final PlayerTemplateData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final PlayerTemplateData _instance = new PlayerTemplateData();
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
|
||||
/**
|
||||
* This class holds the Player Xp Percent Lost Data for each level for players.
|
||||
* @author Zealar
|
||||
*/
|
||||
public final class PlayerXpPercentLostData implements IXmlReader
|
||||
{
|
||||
private final int _maxlevel = ExperienceData.getInstance().getMaxLevel();
|
||||
private final double[] _playerXpPercentLost = new double[_maxlevel + 1];
|
||||
|
||||
protected PlayerXpPercentLostData()
|
||||
{
|
||||
Arrays.fill(_playerXpPercentLost, 1.);
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
parseDatapackFile("data/stats/chars/playerXpPercentLost.xml");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("xpLost".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
NamedNodeMap attrs = d.getAttributes();
|
||||
_playerXpPercentLost[parseInteger(attrs, "level")] = parseDouble(attrs, "val");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double getXpPercent(final int level)
|
||||
{
|
||||
if (level > _maxlevel)
|
||||
{
|
||||
LOGGER.warning("Require to high level inside PlayerXpPercentLostData (" + level + ")");
|
||||
return _playerXpPercentLost[_maxlevel];
|
||||
}
|
||||
return _playerXpPercentLost[level];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of PlayerXpPercentLostData.
|
||||
* @return single instance of PlayerXpPercentLostData.
|
||||
*/
|
||||
public static PlayerXpPercentLostData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final PlayerXpPercentLostData _instance = new PlayerXpPercentLostData();
|
||||
}
|
||||
}
|
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.L2RecipeInstance;
|
||||
import com.l2jserver.gameserver.model.L2RecipeList;
|
||||
import com.l2jserver.gameserver.model.L2RecipeStatInstance;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* The Class RecipeData.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public class RecipeData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, L2RecipeList> _recipes = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new recipe data.
|
||||
*/
|
||||
protected RecipeData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_recipes.clear();
|
||||
parseDatapackFile("data/recipes.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _recipes.size() + " recipes.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
// TODO: Cleanup checks enforced by XSD.
|
||||
final List<L2RecipeInstance> recipePartList = new ArrayList<>();
|
||||
final List<L2RecipeStatInstance> recipeStatUseList = new ArrayList<>();
|
||||
final List<L2RecipeStatInstance> recipeAltStatChangeList = new ArrayList<>();
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
RECIPES_FILE: for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("item".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
recipePartList.clear();
|
||||
recipeStatUseList.clear();
|
||||
recipeAltStatChangeList.clear();
|
||||
NamedNodeMap attrs = d.getAttributes();
|
||||
Node att;
|
||||
int id = -1;
|
||||
boolean haveRare = false;
|
||||
StatsSet set = new StatsSet();
|
||||
|
||||
att = attrs.getNamedItem("id");
|
||||
if (att == null)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Missing id for recipe item, skipping");
|
||||
continue;
|
||||
}
|
||||
id = Integer.parseInt(att.getNodeValue());
|
||||
set.set("id", id);
|
||||
|
||||
att = attrs.getNamedItem("recipeId");
|
||||
if (att == null)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Missing recipeId for recipe item id: " + id + ", skipping");
|
||||
continue;
|
||||
}
|
||||
set.set("recipeId", Integer.parseInt(att.getNodeValue()));
|
||||
|
||||
att = attrs.getNamedItem("name");
|
||||
if (att == null)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Missing name for recipe item id: " + id + ", skipping");
|
||||
continue;
|
||||
}
|
||||
set.set("recipeName", att.getNodeValue());
|
||||
|
||||
att = attrs.getNamedItem("craftLevel");
|
||||
if (att == null)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Missing level for recipe item id: " + id + ", skipping");
|
||||
continue;
|
||||
}
|
||||
set.set("craftLevel", Integer.parseInt(att.getNodeValue()));
|
||||
|
||||
att = attrs.getNamedItem("type");
|
||||
if (att == null)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Missing type for recipe item id: " + id + ", skipping");
|
||||
continue;
|
||||
}
|
||||
set.set("isDwarvenRecipe", att.getNodeValue().equalsIgnoreCase("dwarven"));
|
||||
|
||||
att = attrs.getNamedItem("successRate");
|
||||
if (att == null)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Missing successRate for recipe item id: " + id + ", skipping");
|
||||
continue;
|
||||
}
|
||||
set.set("successRate", Integer.parseInt(att.getNodeValue()));
|
||||
|
||||
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
|
||||
{
|
||||
if ("statUse".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
String statName = c.getAttributes().getNamedItem("name").getNodeValue();
|
||||
int value = Integer.parseInt(c.getAttributes().getNamedItem("value").getNodeValue());
|
||||
try
|
||||
{
|
||||
recipeStatUseList.add(new L2RecipeStatInstance(statName, value));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Error in StatUse parameter for recipe item id: " + id + ", skipping");
|
||||
continue RECIPES_FILE;
|
||||
}
|
||||
}
|
||||
else if ("altStatChange".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
String statName = c.getAttributes().getNamedItem("name").getNodeValue();
|
||||
int value = Integer.parseInt(c.getAttributes().getNamedItem("value").getNodeValue());
|
||||
try
|
||||
{
|
||||
recipeAltStatChangeList.add(new L2RecipeStatInstance(statName, value));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.severe(getClass().getSimpleName() + ": Error in AltStatChange parameter for recipe item id: " + id + ", skipping");
|
||||
continue RECIPES_FILE;
|
||||
}
|
||||
}
|
||||
else if ("ingredient".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
int ingId = Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue());
|
||||
int ingCount = Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue());
|
||||
recipePartList.add(new L2RecipeInstance(ingId, ingCount));
|
||||
}
|
||||
else if ("production".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
set.set("itemId", Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue()));
|
||||
set.set("count", Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue()));
|
||||
}
|
||||
else if ("productionRare".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
set.set("rareItemId", Integer.parseInt(c.getAttributes().getNamedItem("id").getNodeValue()));
|
||||
set.set("rareCount", Integer.parseInt(c.getAttributes().getNamedItem("count").getNodeValue()));
|
||||
set.set("rarity", Integer.parseInt(c.getAttributes().getNamedItem("rarity").getNodeValue()));
|
||||
haveRare = true;
|
||||
}
|
||||
}
|
||||
|
||||
L2RecipeList recipeList = new L2RecipeList(set, haveRare);
|
||||
for (L2RecipeInstance recipePart : recipePartList)
|
||||
{
|
||||
recipeList.addRecipe(recipePart);
|
||||
}
|
||||
for (L2RecipeStatInstance recipeStatUse : recipeStatUseList)
|
||||
{
|
||||
recipeList.addStatUse(recipeStatUse);
|
||||
}
|
||||
for (L2RecipeStatInstance recipeAltStatChange : recipeAltStatChangeList)
|
||||
{
|
||||
recipeList.addAltStatChange(recipeAltStatChange);
|
||||
}
|
||||
|
||||
_recipes.put(id, recipeList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the recipe list.
|
||||
* @param listId the list id
|
||||
* @return the recipe list
|
||||
*/
|
||||
public L2RecipeList getRecipeList(int listId)
|
||||
{
|
||||
return _recipes.get(listId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the recipe by item id.
|
||||
* @param itemId the item id
|
||||
* @return the recipe by item id
|
||||
*/
|
||||
public L2RecipeList getRecipeByItemId(int itemId)
|
||||
{
|
||||
for (L2RecipeList find : _recipes.values())
|
||||
{
|
||||
if (find.getRecipeId() == itemId)
|
||||
{
|
||||
return find;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the all item ids.
|
||||
* @return the all item ids
|
||||
*/
|
||||
public int[] getAllItemIds()
|
||||
{
|
||||
int[] idList = new int[_recipes.size()];
|
||||
int i = 0;
|
||||
for (L2RecipeList rec : _recipes.values())
|
||||
{
|
||||
idList[i++] = rec.getRecipeId();
|
||||
}
|
||||
return idList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the valid recipe list.
|
||||
* @param player the player
|
||||
* @param id the recipe list id
|
||||
* @return the valid recipe list
|
||||
*/
|
||||
public L2RecipeList getValidRecipeList(L2PcInstance player, int id)
|
||||
{
|
||||
L2RecipeList recipeList = _recipes.get(id);
|
||||
if ((recipeList == null) || (recipeList.getRecipes().length == 0))
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": No recipe for: " + id);
|
||||
player.isInCraftMode(false);
|
||||
return null;
|
||||
}
|
||||
return recipeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of RecipeData.
|
||||
* @return single instance of RecipeData
|
||||
*/
|
||||
public static RecipeData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Class SingletonHolder.
|
||||
*/
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final RecipeData _instance = new RecipeData();
|
||||
}
|
||||
}
|
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
|
||||
/**
|
||||
* @author NosBit
|
||||
*/
|
||||
public class SecondaryAuthData implements IXmlReader
|
||||
{
|
||||
private final Set<String> _forbiddenPasswords = new HashSet<>();
|
||||
private boolean _enabled = false;
|
||||
private int _maxAttempts = 5;
|
||||
private int _banTime = 480;
|
||||
private String _recoveryLink = "";
|
||||
|
||||
protected SecondaryAuthData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
_forbiddenPasswords.clear();
|
||||
parseFile(new File("config/SecondaryAuth.xml"));
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _forbiddenPasswords.size() + " forbidden passwords.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
try
|
||||
{
|
||||
for (Node node = doc.getFirstChild(); node != null; node = node.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(node.getNodeName()))
|
||||
{
|
||||
for (Node list_node = node.getFirstChild(); list_node != null; list_node = list_node.getNextSibling())
|
||||
{
|
||||
if ("enabled".equalsIgnoreCase(list_node.getNodeName()))
|
||||
{
|
||||
_enabled = Boolean.parseBoolean(list_node.getTextContent());
|
||||
}
|
||||
else if ("maxAttempts".equalsIgnoreCase(list_node.getNodeName()))
|
||||
{
|
||||
_maxAttempts = Integer.parseInt(list_node.getTextContent());
|
||||
}
|
||||
else if ("banTime".equalsIgnoreCase(list_node.getNodeName()))
|
||||
{
|
||||
_banTime = Integer.parseInt(list_node.getTextContent());
|
||||
}
|
||||
else if ("recoveryLink".equalsIgnoreCase(list_node.getNodeName()))
|
||||
{
|
||||
_recoveryLink = list_node.getTextContent();
|
||||
}
|
||||
else if ("forbiddenPasswords".equalsIgnoreCase(list_node.getNodeName()))
|
||||
{
|
||||
for (Node forbiddenPasswords_node = list_node.getFirstChild(); forbiddenPasswords_node != null; forbiddenPasswords_node = forbiddenPasswords_node.getNextSibling())
|
||||
{
|
||||
if ("password".equalsIgnoreCase(forbiddenPasswords_node.getNodeName()))
|
||||
{
|
||||
_forbiddenPasswords.add(forbiddenPasswords_node.getTextContent());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "Failed to load secondary auth data from xml.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
public int getMaxAttempts()
|
||||
{
|
||||
return _maxAttempts;
|
||||
}
|
||||
|
||||
public int getBanTime()
|
||||
{
|
||||
return _banTime;
|
||||
}
|
||||
|
||||
public String getRecoveryLink()
|
||||
{
|
||||
return _recoveryLink;
|
||||
}
|
||||
|
||||
public Set<String> getForbiddenPasswords()
|
||||
{
|
||||
return _forbiddenPasswords;
|
||||
}
|
||||
|
||||
public boolean isForbiddenPassword(String password)
|
||||
{
|
||||
return _forbiddenPasswords.contains(password);
|
||||
}
|
||||
|
||||
public static SecondaryAuthData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final SecondaryAuthData _instance = new SecondaryAuthData();
|
||||
}
|
||||
}
|
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.idfactory.IdFactory;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.VehiclePathPoint;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2ShuttleInstance;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
|
||||
import com.l2jserver.gameserver.model.shuttle.L2ShuttleData;
|
||||
import com.l2jserver.gameserver.model.shuttle.L2ShuttleEngine;
|
||||
import com.l2jserver.gameserver.model.shuttle.L2ShuttleStop;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public final class ShuttleData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, L2ShuttleData> _shuttles = new HashMap<>();
|
||||
private final Map<Integer, L2ShuttleInstance> _shuttleInstances = new HashMap<>();
|
||||
|
||||
protected ShuttleData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
if (!_shuttleInstances.isEmpty())
|
||||
{
|
||||
for (L2ShuttleInstance shuttle : _shuttleInstances.values())
|
||||
{
|
||||
shuttle.deleteMe();
|
||||
}
|
||||
_shuttleInstances.clear();
|
||||
}
|
||||
parseDatapackFile("data/shuttledata.xml");
|
||||
init();
|
||||
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _shuttles.size() + " Shuttles.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
StatsSet set;
|
||||
Node att;
|
||||
L2ShuttleData data;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("shuttle".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
attrs = d.getAttributes();
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
data = new L2ShuttleData(set);
|
||||
for (Node b = d.getFirstChild(); b != null; b = b.getNextSibling())
|
||||
{
|
||||
if ("doors".equalsIgnoreCase(b.getNodeName()))
|
||||
{
|
||||
for (Node a = b.getFirstChild(); a != null; a = a.getNextSibling())
|
||||
{
|
||||
if ("door".equalsIgnoreCase(a.getNodeName()))
|
||||
{
|
||||
attrs = a.getAttributes();
|
||||
data.addDoor(parseInteger(attrs, "id"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ("stops".equalsIgnoreCase(b.getNodeName()))
|
||||
{
|
||||
for (Node a = b.getFirstChild(); a != null; a = a.getNextSibling())
|
||||
{
|
||||
if ("stop".equalsIgnoreCase(a.getNodeName()))
|
||||
{
|
||||
attrs = a.getAttributes();
|
||||
L2ShuttleStop stop = new L2ShuttleStop(parseInteger(attrs, "id"));
|
||||
|
||||
for (Node z = a.getFirstChild(); z != null; z = z.getNextSibling())
|
||||
{
|
||||
if ("dimension".equalsIgnoreCase(z.getNodeName()))
|
||||
{
|
||||
attrs = z.getAttributes();
|
||||
stop.addDimension(new Location(parseInteger(attrs, "x"), parseInteger(attrs, "y"), parseInteger(attrs, "z")));
|
||||
}
|
||||
}
|
||||
data.addStop(stop);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ("routes".equalsIgnoreCase(b.getNodeName()))
|
||||
{
|
||||
for (Node a = b.getFirstChild(); a != null; a = a.getNextSibling())
|
||||
{
|
||||
if ("route".equalsIgnoreCase(a.getNodeName()))
|
||||
{
|
||||
attrs = a.getAttributes();
|
||||
List<Location> locs = new ArrayList<>();
|
||||
for (Node z = a.getFirstChild(); z != null; z = z.getNextSibling())
|
||||
{
|
||||
if ("loc".equalsIgnoreCase(z.getNodeName()))
|
||||
{
|
||||
attrs = z.getAttributes();
|
||||
locs.add(new Location(parseInteger(attrs, "x"), parseInteger(attrs, "y"), parseInteger(attrs, "z")));
|
||||
}
|
||||
}
|
||||
|
||||
VehiclePathPoint[] route = new VehiclePathPoint[locs.size()];
|
||||
int i = 0;
|
||||
for (Location loc : locs)
|
||||
{
|
||||
route[i++] = new VehiclePathPoint(loc);
|
||||
}
|
||||
data.addRoute(route);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_shuttles.put(data.getId(), data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
for (L2ShuttleData data : _shuttles.values())
|
||||
{
|
||||
final L2ShuttleInstance shuttle = new L2ShuttleInstance(IdFactory.getInstance().getNextId(), new L2CharTemplate(new StatsSet()));
|
||||
shuttle.setData(data);
|
||||
shuttle.setHeading(data.getLocation().getHeading());
|
||||
shuttle.setLocationInvisible(data.getLocation());
|
||||
shuttle.spawnMe();
|
||||
shuttle.getStat().setMoveSpeed(300);
|
||||
shuttle.getStat().setRotationSpeed(0);
|
||||
shuttle.registerEngine(new L2ShuttleEngine(data, shuttle));
|
||||
shuttle.runEngine(1000);
|
||||
_shuttleInstances.put(shuttle.getObjectId(), shuttle);
|
||||
}
|
||||
}
|
||||
|
||||
public L2ShuttleInstance getShuttle(int id)
|
||||
{
|
||||
for (L2ShuttleInstance shuttle : _shuttleInstances.values())
|
||||
{
|
||||
if ((shuttle.getObjectId() == id) || (shuttle.getId() == id))
|
||||
{
|
||||
return shuttle;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ShuttleData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final ShuttleData _instance = new ShuttleData();
|
||||
}
|
||||
}
|
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.SiegeScheduleDate;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public class SiegeScheduleData implements IXmlReader
|
||||
{
|
||||
private final List<SiegeScheduleDate> _scheduleData = new ArrayList<>();
|
||||
|
||||
protected SiegeScheduleData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
_scheduleData.clear();
|
||||
parseDatapackFile("config/SiegeSchedule.xml");
|
||||
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _scheduleData.size() + " siege schedulers.");
|
||||
if (_scheduleData.isEmpty())
|
||||
{
|
||||
_scheduleData.add(new SiegeScheduleDate(new StatsSet()));
|
||||
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Emergency Loaded: " + _scheduleData.size() + " default siege schedulers.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node cd = n.getFirstChild(); cd != null; cd = cd.getNextSibling())
|
||||
{
|
||||
switch (cd.getNodeName())
|
||||
{
|
||||
case "schedule":
|
||||
{
|
||||
final StatsSet set = new StatsSet();
|
||||
final NamedNodeMap attrs = cd.getAttributes();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
Node node = attrs.item(i);
|
||||
String key = node.getNodeName();
|
||||
String val = node.getNodeValue();
|
||||
if ("day".equals(key))
|
||||
{
|
||||
if (!Util.isDigit(val))
|
||||
{
|
||||
val = Integer.toString(getValueForField(val));
|
||||
}
|
||||
}
|
||||
set.set(key, val);
|
||||
}
|
||||
_scheduleData.add(new SiegeScheduleDate(set));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getValueForField(String field)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Calendar.class.getField(field).getInt(Calendar.class);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.log(Level.WARNING, "", e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public List<SiegeScheduleDate> getScheduleDates()
|
||||
{
|
||||
return _scheduleData;
|
||||
}
|
||||
|
||||
public static final SiegeScheduleData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final SiegeScheduleData _instance = new SiegeScheduleData();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
|
||||
/**
|
||||
* Holds all skill learn data for all npcs.
|
||||
* @author xban1x
|
||||
*/
|
||||
public final class SkillLearnData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, List<ClassId>> _skillLearn = new HashMap<>();
|
||||
|
||||
protected SkillLearnData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
_skillLearn.clear();
|
||||
parseDatapackFile("data/skillLearn.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _skillLearn.size() + " Skill Learn data.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node node = doc.getFirstChild(); node != null; node = node.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(node.getNodeName()))
|
||||
{
|
||||
for (Node list_node = node.getFirstChild(); list_node != null; list_node = list_node.getNextSibling())
|
||||
{
|
||||
if ("npc".equalsIgnoreCase(list_node.getNodeName()))
|
||||
{
|
||||
final List<ClassId> classIds = new ArrayList<>();
|
||||
for (Node c = list_node.getFirstChild(); c != null; c = c.getNextSibling())
|
||||
{
|
||||
if ("classId".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
classIds.add(ClassId.getClassId(Integer.parseInt(c.getTextContent())));
|
||||
}
|
||||
}
|
||||
_skillLearn.put(parseInteger(list_node.getAttributes(), "id"), classIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param npcId
|
||||
* @return {@link List} of {@link ClassId}'s that this npcId can teach.
|
||||
*/
|
||||
public List<ClassId> getSkillLearnData(int npcId)
|
||||
{
|
||||
return _skillLearn.get(npcId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of SkillLearnData.
|
||||
* @return single instance of SkillLearnData
|
||||
*/
|
||||
public static SkillLearnData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final SkillLearnData _instance = new SkillLearnData();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.idfactory.IdFactory;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2StaticObjectInstance;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2CharTemplate;
|
||||
|
||||
/**
|
||||
* This class loads and holds all static object data.
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public final class StaticObjectData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, L2StaticObjectInstance> _staticObjects = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new static objects.
|
||||
*/
|
||||
protected StaticObjectData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_staticObjects.clear();
|
||||
parseDatapackFile("data/staticObjects.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _staticObjects.size() + " static object templates.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
Node att;
|
||||
StatsSet set;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("object".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
attrs = d.getAttributes();
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
addObject(set);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize an static object based on the stats set and add it to the map.
|
||||
* @param set the stats set to add.
|
||||
*/
|
||||
private void addObject(StatsSet set)
|
||||
{
|
||||
L2StaticObjectInstance obj = new L2StaticObjectInstance(IdFactory.getInstance().getNextId(), new L2CharTemplate(new StatsSet()), set.getInt("id"));
|
||||
obj.setType(set.getInt("type", 0));
|
||||
obj.setName(set.getString("name"));
|
||||
obj.setMap(set.getString("texture", "none"), set.getInt("map_x", 0), set.getInt("map_y", 0));
|
||||
obj.spawnMe(set.getInt("x"), set.getInt("y"), set.getInt("z"));
|
||||
_staticObjects.put(obj.getObjectId(), obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the static objects.
|
||||
* @return a collection of static objects.
|
||||
*/
|
||||
public Collection<L2StaticObjectInstance> getStaticObjects()
|
||||
{
|
||||
return _staticObjects.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of StaticObjects.
|
||||
* @return single instance of StaticObjects
|
||||
*/
|
||||
public static StaticObjectData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final StaticObjectData _instance = new StaticObjectData();
|
||||
}
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.teleporter.TeleportHolder;
|
||||
import com.l2jserver.gameserver.model.teleporter.TeleportLocation;
|
||||
import com.l2jserver.gameserver.model.teleporter.TeleportType;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public class TeleportersData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, TeleportHolder> _teleporters = new HashMap<>();
|
||||
|
||||
protected TeleportersData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_teleporters.clear();
|
||||
parseDatapackDirectory("data/teleporters", true);
|
||||
LOGGER.log(Level.INFO, "Loaded: " + _teleporters.size() + " npc teleporters.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node listNode = doc.getFirstChild(); listNode != null; listNode = listNode.getNextSibling())
|
||||
{
|
||||
if ("list".equals(listNode.getNodeName()))
|
||||
{
|
||||
for (Node npcNode = listNode.getFirstChild(); npcNode != null; npcNode = npcNode.getNextSibling())
|
||||
{
|
||||
if ("npc".equals(npcNode.getNodeName()))
|
||||
{
|
||||
final int id = parseInteger(npcNode.getAttributes(), "id");
|
||||
final TeleportHolder holder = new TeleportHolder(id);
|
||||
for (Node tpNode = npcNode.getFirstChild(); tpNode != null; tpNode = tpNode.getNextSibling())
|
||||
{
|
||||
if ("teleport".equals(tpNode.getNodeName()))
|
||||
{
|
||||
final TeleportType type = parseEnum(tpNode.getAttributes(), TeleportType.class, "type", TeleportType.NORMAL);
|
||||
for (Node locNode = tpNode.getFirstChild(); locNode != null; locNode = locNode.getNextSibling())
|
||||
{
|
||||
if ("location".equals(locNode.getNodeName()))
|
||||
{
|
||||
final NamedNodeMap attrs = locNode.getAttributes();
|
||||
final int nextId = holder.getLocations(type).size() + 1;
|
||||
final StatsSet set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
final Node locationNode = attrs.item(i);
|
||||
set.set(locationNode.getNodeName(), locationNode.getNodeValue());
|
||||
}
|
||||
holder.addLocation(type, new TeleportLocation(nextId, set));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_teleporters.put(id, holder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TeleportHolder getHolder(int npcId)
|
||||
{
|
||||
return _teleporters.get(npcId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the single instance of TeleportersData.
|
||||
* @return single instance of TeleportersData
|
||||
*/
|
||||
public static TeleportersData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final TeleportersData _instance = new TeleportersData();
|
||||
}
|
||||
}
|
@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.transform.Transform;
|
||||
import com.l2jserver.gameserver.model.actor.transform.TransformLevelData;
|
||||
import com.l2jserver.gameserver.model.actor.transform.TransformTemplate;
|
||||
import com.l2jserver.gameserver.model.holders.AdditionalItemHolder;
|
||||
import com.l2jserver.gameserver.model.holders.AdditionalSkillHolder;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExBasicActionList;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public final class TransformData implements IXmlReader
|
||||
{
|
||||
private final Map<Integer, Transform> _transformData = new HashMap<>();
|
||||
|
||||
protected TransformData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void load()
|
||||
{
|
||||
_transformData.clear();
|
||||
parseDatapackDirectory("data/stats/transformations", false);
|
||||
LOGGER.log(Level.INFO, getClass().getSimpleName() + ": Loaded: " + _transformData.size() + " transform templates.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
NamedNodeMap attrs;
|
||||
Node att;
|
||||
StatsSet set;
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("transform".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
attrs = d.getAttributes();
|
||||
set = new StatsSet();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
final Transform transform = new Transform(set);
|
||||
for (Node cd = d.getFirstChild(); cd != null; cd = cd.getNextSibling())
|
||||
{
|
||||
boolean isMale = "Male".equalsIgnoreCase(cd.getNodeName());
|
||||
if ("Male".equalsIgnoreCase(cd.getNodeName()) || "Female".equalsIgnoreCase(cd.getNodeName()))
|
||||
{
|
||||
TransformTemplate templateData = null;
|
||||
for (Node z = cd.getFirstChild(); z != null; z = z.getNextSibling())
|
||||
{
|
||||
switch (z.getNodeName())
|
||||
{
|
||||
case "common":
|
||||
{
|
||||
for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
|
||||
{
|
||||
switch (s.getNodeName())
|
||||
{
|
||||
case "base":
|
||||
case "stats":
|
||||
case "defense":
|
||||
case "magicDefense":
|
||||
case "collision":
|
||||
case "moving":
|
||||
{
|
||||
attrs = s.getAttributes();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
set.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
templateData = new TransformTemplate(set);
|
||||
transform.setTemplate(isMale, templateData);
|
||||
break;
|
||||
}
|
||||
case "skills":
|
||||
{
|
||||
if (templateData == null)
|
||||
{
|
||||
templateData = new TransformTemplate(set);
|
||||
transform.setTemplate(isMale, templateData);
|
||||
}
|
||||
for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
|
||||
{
|
||||
if ("skill".equals(s.getNodeName()))
|
||||
{
|
||||
attrs = s.getAttributes();
|
||||
int skillId = parseInteger(attrs, "id");
|
||||
int skillLevel = parseInteger(attrs, "level");
|
||||
templateData.addSkill(new SkillHolder(skillId, skillLevel));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "actions":
|
||||
{
|
||||
if (templateData == null)
|
||||
{
|
||||
templateData = new TransformTemplate(set);
|
||||
transform.setTemplate(isMale, templateData);
|
||||
}
|
||||
set.set("actions", z.getTextContent());
|
||||
final int[] actions = set.getIntArray("actions", " ");
|
||||
templateData.setBasicActionList(new ExBasicActionList(actions));
|
||||
break;
|
||||
}
|
||||
case "additionalSkills":
|
||||
{
|
||||
if (templateData == null)
|
||||
{
|
||||
templateData = new TransformTemplate(set);
|
||||
transform.setTemplate(isMale, templateData);
|
||||
}
|
||||
for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
|
||||
{
|
||||
if ("skill".equals(s.getNodeName()))
|
||||
{
|
||||
attrs = s.getAttributes();
|
||||
int skillId = parseInteger(attrs, "id");
|
||||
int skillLevel = parseInteger(attrs, "level");
|
||||
int minLevel = parseInteger(attrs, "minLevel");
|
||||
templateData.addAdditionalSkill(new AdditionalSkillHolder(skillId, skillLevel, minLevel));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "items":
|
||||
{
|
||||
if (templateData == null)
|
||||
{
|
||||
templateData = new TransformTemplate(set);
|
||||
transform.setTemplate(isMale, templateData);
|
||||
}
|
||||
for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
|
||||
{
|
||||
if ("item".equals(s.getNodeName()))
|
||||
{
|
||||
attrs = s.getAttributes();
|
||||
int itemId = parseInteger(attrs, "id");
|
||||
boolean allowed = parseBoolean(attrs, "allowed");
|
||||
templateData.addAdditionalItem(new AdditionalItemHolder(itemId, allowed));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "levels":
|
||||
{
|
||||
if (templateData == null)
|
||||
{
|
||||
templateData = new TransformTemplate(set);
|
||||
transform.setTemplate(isMale, templateData);
|
||||
}
|
||||
|
||||
final StatsSet levelsSet = new StatsSet();
|
||||
for (Node s = z.getFirstChild(); s != null; s = s.getNextSibling())
|
||||
{
|
||||
if ("level".equals(s.getNodeName()))
|
||||
{
|
||||
attrs = s.getAttributes();
|
||||
for (int i = 0; i < attrs.getLength(); i++)
|
||||
{
|
||||
att = attrs.item(i);
|
||||
levelsSet.set(att.getNodeName(), att.getNodeValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
templateData.addLevelData(new TransformLevelData(levelsSet));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_transformData.put(transform.getId(), transform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Transform getTransform(int id)
|
||||
{
|
||||
return _transformData.get(id);
|
||||
}
|
||||
|
||||
public boolean transformPlayer(int id, L2PcInstance player)
|
||||
{
|
||||
final Transform transform = getTransform(id);
|
||||
if (transform != null)
|
||||
{
|
||||
player.transform(transform);
|
||||
}
|
||||
return transform != null;
|
||||
}
|
||||
|
||||
public static TransformData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final TransformData _instance = new TransformData();
|
||||
}
|
||||
}
|
203
trunk/java/com/l2jserver/gameserver/data/xml/impl/UIData.java
Normal file
203
trunk/java/com/l2jserver/gameserver/data/xml/impl/UIData.java
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2015 L2J Server
|
||||
*
|
||||
* This file is part of L2J Server.
|
||||
*
|
||||
* L2J Server 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.
|
||||
*
|
||||
* L2J Server 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.data.xml.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import com.l2jserver.gameserver.data.xml.IXmlReader;
|
||||
import com.l2jserver.gameserver.model.ActionKey;
|
||||
|
||||
/**
|
||||
* UI Data parser.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public class UIData implements IXmlReader
|
||||
{
|
||||
private static final Logger LOGGER = Logger.getLogger(UIData.class.getName());
|
||||
|
||||
private final Map<Integer, List<ActionKey>> _storedKeys = new HashMap<>();
|
||||
private final Map<Integer, List<Integer>> _storedCategories = new HashMap<>();
|
||||
|
||||
protected UIData()
|
||||
{
|
||||
load();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load()
|
||||
{
|
||||
_storedKeys.clear();
|
||||
_storedCategories.clear();
|
||||
parseDatapackFile("data/ui/ui_en.xml");
|
||||
LOGGER.info(getClass().getSimpleName() + ": Loaded " + _storedKeys.size() + " keys " + _storedCategories.size() + " categories.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parseDocument(Document doc)
|
||||
{
|
||||
for (Node n = doc.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if ("list".equalsIgnoreCase(n.getNodeName()))
|
||||
{
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("category".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
parseCategory(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseCategory(Node n)
|
||||
{
|
||||
final int cat = parseInteger(n.getAttributes(), "id");
|
||||
for (Node d = n.getFirstChild(); d != null; d = d.getNextSibling())
|
||||
{
|
||||
if ("commands".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
parseCommands(cat, d);
|
||||
}
|
||||
else if ("keys".equalsIgnoreCase(d.getNodeName()))
|
||||
{
|
||||
parseKeys(cat, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseCommands(int cat, Node d)
|
||||
{
|
||||
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
|
||||
{
|
||||
if ("cmd".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
addCategory(_storedCategories, cat, Integer.parseInt(c.getTextContent()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseKeys(int cat, Node d)
|
||||
{
|
||||
for (Node c = d.getFirstChild(); c != null; c = c.getNextSibling())
|
||||
{
|
||||
if ("key".equalsIgnoreCase(c.getNodeName()))
|
||||
{
|
||||
final ActionKey akey = new ActionKey(cat);
|
||||
for (int i = 0; i < c.getAttributes().getLength(); i++)
|
||||
{
|
||||
final Node att = c.getAttributes().item(i);
|
||||
final int val = Integer.parseInt(att.getNodeValue());
|
||||
switch (att.getNodeName())
|
||||
{
|
||||
case "cmd":
|
||||
{
|
||||
akey.setCommandId(val);
|
||||
break;
|
||||
}
|
||||
case "key":
|
||||
{
|
||||
akey.setKeyId(val);
|
||||
break;
|
||||
}
|
||||
case "toggleKey1":
|
||||
{
|
||||
akey.setToogleKey1(val);
|
||||
break;
|
||||
}
|
||||
case "toggleKey2":
|
||||
{
|
||||
akey.setToogleKey2(val);
|
||||
break;
|
||||
}
|
||||
case "showType":
|
||||
{
|
||||
akey.setShowStatus(val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
addKey(_storedKeys, cat, akey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a category to the stored categories.
|
||||
* @param map the map to store the category
|
||||
* @param cat the category
|
||||
* @param cmd the command
|
||||
*/
|
||||
public static void addCategory(Map<Integer, List<Integer>> map, int cat, int cmd)
|
||||
{
|
||||
if (!map.containsKey(cat))
|
||||
{
|
||||
map.put(cat, new ArrayList<Integer>());
|
||||
}
|
||||
map.get(cat).add(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and insert an Action Key into the stored keys.
|
||||
* @param map the map to store the key
|
||||
* @param cat the category
|
||||
* @param akey the action key
|
||||
*/
|
||||
public static void addKey(Map<Integer, List<ActionKey>> map, int cat, ActionKey akey)
|
||||
{
|
||||
if (!map.containsKey(cat))
|
||||
{
|
||||
map.put(cat, new ArrayList<ActionKey>());
|
||||
}
|
||||
map.get(cat).add(akey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the categories
|
||||
*/
|
||||
public Map<Integer, List<Integer>> getCategories()
|
||||
{
|
||||
return _storedCategories;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the keys
|
||||
*/
|
||||
public Map<Integer, List<ActionKey>> getKeys()
|
||||
{
|
||||
return _storedKeys;
|
||||
}
|
||||
|
||||
public static UIData getInstance()
|
||||
{
|
||||
return SingletonHolder._instance;
|
||||
}
|
||||
|
||||
private static class SingletonHolder
|
||||
{
|
||||
protected static final UIData _instance = new UIData();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user