Package lineage2.gameserver.data.xml.parser

Source Code of lineage2.gameserver.data.xml.parser.StatParser

/*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package lineage2.gameserver.data.xml.parser;

import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import lineage2.commons.data.xml.AbstractDirParser;
import lineage2.commons.data.xml.AbstractHolder;
import lineage2.gameserver.model.entity.residence.ResidenceType;
import lineage2.gameserver.stats.StatTemplate;
import lineage2.gameserver.stats.Stats;
import lineage2.gameserver.stats.conditions.Condition;
import lineage2.gameserver.stats.conditions.ConditionCastleDark;
import lineage2.gameserver.stats.conditions.ConditionCastleDarkClanLeader;
import lineage2.gameserver.stats.conditions.ConditionCastleLight;
import lineage2.gameserver.stats.conditions.ConditionCastleLightClanLeader;
import lineage2.gameserver.stats.conditions.ConditionLogicAnd;
import lineage2.gameserver.stats.conditions.ConditionLogicNot;
import lineage2.gameserver.stats.conditions.ConditionLogicOr;
import lineage2.gameserver.stats.conditions.ConditionPlayerClassId;
import lineage2.gameserver.stats.conditions.ConditionPlayerInstanceZone;
import lineage2.gameserver.stats.conditions.ConditionPlayerMinMaxDamage;
import lineage2.gameserver.stats.conditions.ConditionPlayerOlympiad;
import lineage2.gameserver.stats.conditions.ConditionPlayerRace;
import lineage2.gameserver.stats.conditions.ConditionPlayerResidence;
import lineage2.gameserver.stats.conditions.ConditionSlotItemId;
import lineage2.gameserver.stats.conditions.ConditionTargetPlayable;
import lineage2.gameserver.stats.conditions.ConditionUsingItemType;
import lineage2.gameserver.stats.conditions.ConditionUsingSkill;
import lineage2.gameserver.stats.conditions.ConditionZoneType;
import lineage2.gameserver.stats.funcs.FuncTemplate;
import lineage2.gameserver.stats.triggers.TriggerInfo;
import lineage2.gameserver.stats.triggers.TriggerType;
import lineage2.gameserver.templates.item.ArmorTemplate;
import lineage2.gameserver.templates.item.WeaponTemplate;

import org.dom4j.Attribute;
import org.dom4j.Element;

/**
* @author Mobius
* @version $Revision: 1.0 $
*/
public abstract class StatParser<H extends AbstractHolder> extends AbstractDirParser<H>
{
  /**
   * Constructor for StatParser.
   * @param holder H
   */
  protected StatParser(H holder)
  {
    super(holder);
  }
 
  /**
   * Method parseFirstCond.
   * @param sub Element
   * @return Condition
   */
  protected Condition parseFirstCond(Element sub)
  {
    List<Element> e = sub.elements();
    if (e.isEmpty())
    {
      return null;
    }
    Element element = e.get(0);
    return parseCond(element);
  }
 
  /**
   * Method parseCond.
   * @param element Element
   * @return Condition
   */
  protected Condition parseCond(Element element)
  {
    String name = element.getName();
    if (name.equalsIgnoreCase("and"))
    {
      return parseLogicAnd(element);
    }
    else if (name.equalsIgnoreCase("or"))
    {
      return parseLogicOr(element);
    }
    else if (name.equalsIgnoreCase("not"))
    {
      return parseLogicNot(element);
    }
    else if (name.equalsIgnoreCase("target"))
    {
      return parseTargetCondition(element);
    }
    else if (name.equalsIgnoreCase("player"))
    {
      return parsePlayerCondition(element);
    }
    else if (name.equalsIgnoreCase("using"))
    {
      return parseUsingCondition(element);
    }
    else if (name.equalsIgnoreCase("zone"))
    {
      return parseZoneCondition(element);
    }
    return null;
  }
 
  /**
   * Method parseLogicAnd.
   * @param n Element
   * @return Condition
   */
  protected Condition parseLogicAnd(Element n)
  {
    ConditionLogicAnd cond = new ConditionLogicAnd();
    for (Iterator<Element> iterator = n.elementIterator(); iterator.hasNext();)
    {
      Element condElement = iterator.next();
      cond.add(parseCond(condElement));
    }
    if ((cond._conditions == null) || (cond._conditions.length == 0))
    {
      error("Empty <and> condition in " + getCurrentFileName());
    }
    return cond;
  }
 
  /**
   * Method parseLogicOr.
   * @param n Element
   * @return Condition
   */
  protected Condition parseLogicOr(Element n)
  {
    ConditionLogicOr cond = new ConditionLogicOr();
    for (Iterator<Element> iterator = n.elementIterator(); iterator.hasNext();)
    {
      Element condElement = iterator.next();
      cond.add(parseCond(condElement));
    }
    if ((cond._conditions == null) || (cond._conditions.length == 0))
    {
      error("Empty <or> condition in " + getCurrentFileName());
    }
    return cond;
  }
 
  /**
   * Method parseLogicNot.
   * @param n Element
   * @return Condition
   */
  protected Condition parseLogicNot(Element n)
  {
    for (Object element : n.elements())
    {
      return new ConditionLogicNot(parseCond((Element) element));
    }
    error("Empty <not> condition in " + getCurrentFileName());
    return null;
  }
 
  /**
   * Method parseTargetCondition.
   * @param element Element
   * @return Condition
   */
  protected Condition parseTargetCondition(Element element)
  {
    Condition cond = null;
    for (Iterator<Attribute> iterator = element.attributeIterator(); iterator.hasNext();)
    {
      Attribute attribute = iterator.next();
      String name = attribute.getName();
      String value = attribute.getValue();
      if (name.equalsIgnoreCase("pvp"))
      {
        cond = joinAnd(cond, new ConditionTargetPlayable(Boolean.valueOf(value)));
      }
    }
    return cond;
  }
 
  /**
   * Method parseZoneCondition.
   * @param element Element
   * @return Condition
   */
  protected Condition parseZoneCondition(Element element)
  {
    Condition cond = null;
    for (Iterator<Attribute> iterator = element.attributeIterator(); iterator.hasNext();)
    {
      Attribute attribute = iterator.next();
      String name = attribute.getName();
      String value = attribute.getValue();
      if (name.equalsIgnoreCase("type"))
      {
        cond = joinAnd(cond, new ConditionZoneType(value));
      }
    }
    return cond;
  }
 
  /**
   * Method parsePlayerCondition.
   * @param element Element
   * @return Condition
   */
  protected Condition parsePlayerCondition(Element element)
  {
    Condition cond = null;
    for (Iterator<Attribute> iterator = element.attributeIterator(); iterator.hasNext();)
    {
      Attribute attribute = iterator.next();
      String name = attribute.getName();
      String value = attribute.getValue();
      if (name.equalsIgnoreCase("residence"))
      {
        String[] st = value.split(";");
        cond = joinAnd(cond, new ConditionPlayerResidence(Integer.parseInt(st[1]), ResidenceType.valueOf(st[0])));
      }
      else if (name.equalsIgnoreCase("classId"))
      {
        cond = joinAnd(cond, new ConditionPlayerClassId(value.split(",")));
      }
      else if (name.equalsIgnoreCase("olympiad"))
      {
        cond = joinAnd(cond, new ConditionPlayerOlympiad(Boolean.valueOf(value)));
      }
      else if (name.equalsIgnoreCase("instance_zone"))
      {
        cond = joinAnd(cond, new ConditionPlayerInstanceZone(Integer.parseInt(value)));
      }
      else if (name.equalsIgnoreCase("race"))
      {
        cond = joinAnd(cond, new ConditionPlayerRace(value));
      }
      else if (name.equalsIgnoreCase("damage"))
      {
        String[] st = value.split(";");
        cond = joinAnd(cond, new ConditionPlayerMinMaxDamage(Double.parseDouble(st[0]), Double.parseDouble(st[1])));
      }
      else if (name.equalsIgnoreCase("castleLight"))
      {
        cond = joinAnd(cond, new ConditionCastleLight());
      }
      else if (name.equalsIgnoreCase("castleLightClanLeader"))
      {
        cond = joinAnd(cond, new ConditionCastleLightClanLeader());
      }
      else if (name.equalsIgnoreCase("castleDark"))
      {
        cond = joinAnd(cond, new ConditionCastleDark());
      }
      else if (name.equalsIgnoreCase("castleDarkClanLeader"))
      {
        cond = joinAnd(cond, new ConditionCastleDarkClanLeader());
      }
    }
    return cond;
  }
 
  /**
   * Method parseUsingCondition.
   * @param element Element
   * @return Condition
   */
  protected Condition parseUsingCondition(Element element)
  {
    Condition cond = null;
    for (Iterator<Attribute> iterator = element.attributeIterator(); iterator.hasNext();)
    {
      Attribute attribute = iterator.next();
      String name = attribute.getName();
      String value = attribute.getValue();
      if (name.equalsIgnoreCase("slotitem"))
      {
        StringTokenizer st = new StringTokenizer(value, ";");
        int id = Integer.parseInt(st.nextToken().trim());
        int slot = Integer.parseInt(st.nextToken().trim());
        int enchant = 0;
        if (st.hasMoreTokens())
        {
          enchant = Integer.parseInt(st.nextToken().trim());
        }
        cond = joinAnd(cond, new ConditionSlotItemId(slot, id, enchant));
      }
      else if (name.equalsIgnoreCase("kind") || name.equalsIgnoreCase("weapon"))
      {
        long mask = 0;
        StringTokenizer st = new StringTokenizer(value, ",");
        tokens:
        while (st.hasMoreTokens())
        {
          String item = st.nextToken().trim();
          for (WeaponTemplate.WeaponType wt : WeaponTemplate.WeaponType.VALUES)
          {
            if (wt.toString().equalsIgnoreCase(item))
            {
              mask |= wt.mask();
              continue tokens;
            }
          }
          for (ArmorTemplate.ArmorType at : ArmorTemplate.ArmorType.VALUES)
          {
            if (at.toString().equalsIgnoreCase(item))
            {
              mask |= at.mask();
              continue tokens;
            }
          }
          error("Invalid item kind: \"" + item + "\" in " + getCurrentFileName());
        }
        if (mask != 0)
        {
          cond = joinAnd(cond, new ConditionUsingItemType(mask));
        }
      }
      else if (name.equalsIgnoreCase("skill"))
      {
        cond = joinAnd(cond, new ConditionUsingSkill(Integer.parseInt(value)));
      }
    }
    return cond;
  }
 
  /**
   * Method joinAnd.
   * @param cond Condition
   * @param c Condition
   * @return Condition
   */
  protected Condition joinAnd(Condition cond, Condition c)
  {
    if (cond == null)
    {
      return c;
    }
    if (cond instanceof ConditionLogicAnd)
    {
      ((ConditionLogicAnd) cond).add(c);
      return cond;
    }
    ConditionLogicAnd and = new ConditionLogicAnd();
    and.add(cond);
    and.add(c);
    return and;
  }
 
  /**
   * Method parseFor.
   * @param forElement Element
   * @param template StatTemplate
   */
  protected void parseFor(Element forElement, StatTemplate template)
  {
    for (Iterator<Element> iterator = forElement.elementIterator(); iterator.hasNext();)
    {
      Element element = iterator.next();
      final String elementName = element.getName();
      if (elementName.equalsIgnoreCase("add"))
      {
        attachFunc(element, template, "Add");
      }
      else if (elementName.equalsIgnoreCase("set"))
      {
        attachFunc(element, template, "Set");
      }
      else if (elementName.equalsIgnoreCase("sub"))
      {
        attachFunc(element, template, "Sub");
      }
      else if (elementName.equalsIgnoreCase("mul"))
      {
        attachFunc(element, template, "Mul");
      }
      else if (elementName.equalsIgnoreCase("div"))
      {
        attachFunc(element, template, "Div");
      }
      else if (elementName.equalsIgnoreCase("enchant"))
      {
        attachFunc(element, template, "Enchant");
      }
    }
  }
 
  /**
   * Method parseTriggers.
   * @param f Element
   * @param triggerable StatTemplate
   */
  protected void parseTriggers(Element f, StatTemplate triggerable)
  {
    for (Iterator<Element> iterator = f.elementIterator(); iterator.hasNext();)
    {
      Element element = iterator.next();
      int id = parseNumber(element.attributeValue("id")).intValue();
      int level = parseNumber(element.attributeValue("level")).intValue();
      TriggerType t = TriggerType.valueOf(element.attributeValue("type"));
      double chance = parseNumber(element.attributeValue("chance")).doubleValue();
      TriggerInfo trigger = new TriggerInfo(id, level, t, chance);
      triggerable.addTrigger(trigger);
      for (Iterator<Element> subIterator = element.elementIterator(); subIterator.hasNext();)
      {
        Element subElement = subIterator.next();
        Condition condition = parseFirstCond(subElement);
        if (condition != null)
        {
          trigger.addCondition(condition);
        }
      }
    }
  }
 
  /**
   * Method attachFunc.
   * @param n Element
   * @param template StatTemplate
   * @param name String
   */
  protected void attachFunc(Element n, StatTemplate template, String name)
  {
    Stats stat = Stats.valueOfXml(n.attributeValue("stat"));
    String order = n.attributeValue("order");
    int ord = parseNumber(order).intValue();
    Condition applyCond = parseFirstCond(n);
    double val = 0;
    if (n.attributeValue("value") != null)
    {
      val = parseNumber(n.attributeValue("value")).doubleValue();
    }
    template.attachFunc(new FuncTemplate(applyCond, name, stat, ord, val));
  }
 
  /**
   * Method parseNumber.
   * @param value String
   * @return Number
   */
  protected Number parseNumber(String value)
  {
    if (value.charAt(0) == '#')
    {
      value = getTableValue(value).toString();
    }
    try
    {
      if (value.indexOf('.') == -1)
      {
        int radix = 10;
        if ((value.length() > 2) && value.substring(0, 2).equalsIgnoreCase("0x"))
        {
          value = value.substring(2);
          radix = 16;
        }
        return Integer.valueOf(value, radix);
      }
      return Double.valueOf(value);
    }
    catch (NumberFormatException e)
    {
      return null;
    }
  }
 
  /**
   * Method getTableValue.
   * @param name String
   * @return Object
   */
  protected abstract Object getTableValue(String name);
}
TOP

Related Classes of lineage2.gameserver.data.xml.parser.StatParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.