Package l2p.gameserver.skills

Source Code of l2p.gameserver.skills.DocumentBase

package l2p.gameserver.skills;

import l2p.gameserver.model.L2Character.TargetDirection;
import l2p.gameserver.model.L2Skill;
import l2p.gameserver.skills.conditions.Condition;
import l2p.gameserver.skills.conditions.ConditionAgathion;
import l2p.gameserver.skills.conditions.ConditionFirstEffectSuccess;
import l2p.gameserver.skills.conditions.ConditionGameTime;
import l2p.gameserver.skills.conditions.ConditionGameTime.CheckGameTime;
import l2p.gameserver.skills.conditions.ConditionHasSkill;
import l2p.gameserver.skills.conditions.ConditionInstanceOf;
import l2p.gameserver.skills.conditions.ConditionInstancedZone;
import l2p.gameserver.skills.conditions.ConditionLogicAnd;
import l2p.gameserver.skills.conditions.ConditionLogicNot;
import l2p.gameserver.skills.conditions.ConditionLogicOr;
import l2p.gameserver.skills.conditions.ConditionNoble;
import l2p.gameserver.skills.conditions.ConditionPlayerClassId;
import l2p.gameserver.skills.conditions.ConditionPlayerHasBuff;
import l2p.gameserver.skills.conditions.ConditionPlayerHasBuffId;
import l2p.gameserver.skills.conditions.ConditionPlayerMaxLevel;
import l2p.gameserver.skills.conditions.ConditionPlayerMaxPK;
import l2p.gameserver.skills.conditions.ConditionPlayerMinHp;
import l2p.gameserver.skills.conditions.ConditionPlayerMinLevel;
import l2p.gameserver.skills.conditions.ConditionPlayerPercentCp;
import l2p.gameserver.skills.conditions.ConditionPlayerPercentHp;
import l2p.gameserver.skills.conditions.ConditionPlayerPercentMp;
import l2p.gameserver.skills.conditions.ConditionPlayerRace;
import l2p.gameserver.skills.conditions.ConditionPlayerRiding;
import l2p.gameserver.skills.conditions.ConditionPlayerRiding.CheckPlayerRiding;
import l2p.gameserver.skills.conditions.ConditionPlayerState;
import l2p.gameserver.skills.conditions.ConditionPlayerState.CheckPlayerState;
import l2p.gameserver.skills.conditions.ConditionSlotItemId;
import l2p.gameserver.skills.conditions.ConditionTargetAggro;
import l2p.gameserver.skills.conditions.ConditionTargetCastleDoor;
import l2p.gameserver.skills.conditions.ConditionTargetClan;
import l2p.gameserver.skills.conditions.ConditionTargetDirection;
import l2p.gameserver.skills.conditions.ConditionTargetHasBuff;
import l2p.gameserver.skills.conditions.ConditionTargetHasBuffId;
import l2p.gameserver.skills.conditions.ConditionTargetMob;
import l2p.gameserver.skills.conditions.ConditionTargetMobId;
import l2p.gameserver.skills.conditions.ConditionTargetPlayable;
import l2p.gameserver.skills.conditions.ConditionTargetPlayerRace;
import l2p.gameserver.skills.conditions.ConditionTargetRace;
import l2p.gameserver.skills.conditions.ConditionUsingArmor;
import l2p.gameserver.skills.conditions.ConditionUsingItemType;
import l2p.gameserver.skills.conditions.ConditionUsingSkill;
import l2p.gameserver.skills.conditions.ConditionZone;
import l2p.gameserver.skills.effects.EffectTemplate;
import l2p.gameserver.skills.funcs.FuncTemplate;
import l2p.gameserver.templates.L2Armor.ArmorType;
import l2p.gameserver.templates.L2Item;
import l2p.gameserver.templates.L2Weapon.WeaponType;
import l2p.gameserver.templates.StatsSet;
import l2p.util.GArray;
import l2p.util.Util;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

abstract class DocumentBase
{
  static Logger _log = Logger.getLogger(DocumentBase.class.getName());
  private File file;
  protected HashMap<String, Object[]> tables;

  DocumentBase(File file)
  {
    this.file = file;
    tables = new HashMap<String, Object[]>();
  }

  Document parse()
  {
    Document doc;
    try
    {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      factory.setValidating(false);
      factory.setIgnoringComments(true);
      doc = factory.newDocumentBuilder().parse(file);
    }
    catch(Exception e)
    {
      _log.log(Level.SEVERE, "Error loading file " + file, e);
      return null;
    }
    try
    {
      parseDocument(doc);
    }
    catch(Exception e)
    {
      _log.log(Level.SEVERE, "Error in file " + file, e);
      return null;
    }
    return doc;
  }

  protected abstract void parseDocument(Document doc);
  protected abstract Object getTableValue(String name);
  protected abstract Object getTableValue(String name, int idx);

  protected void resetTable()
  {
    tables = new HashMap<String, Object[]>();
  }

  protected void setTable(String name, Object[] table)
  {
    tables.put(name, table);
  }

  protected void parseTemplate(Node n, Object template)
  {
    n = n.getFirstChild();
    if(n == null)
    {
      return;
    }
    for(; n != null; n = n.getNextSibling())
    {
      String nodeName = n.getNodeName();
      if("add".equalsIgnoreCase(nodeName))
      {
        attachFunc(n, template, "Add");
      }
      else if("sub".equalsIgnoreCase(nodeName))
      {
        attachFunc(n, template, "Sub");
      }
      else if("mul".equalsIgnoreCase(nodeName))
      {
        attachFunc(n, template, "Mul");
      }
      else if("div".equalsIgnoreCase(nodeName))
      {
        attachFunc(n, template, "Div");
      }
      else if("set".equalsIgnoreCase(nodeName))
      {
        attachFunc(n, template, "Set");
      }
      else if("enchant".equalsIgnoreCase(nodeName))
      {
        attachFunc(n, template, "Enchant");
      }
      else if("effect".equalsIgnoreCase(nodeName))
      {
        if(template instanceof EffectTemplate)
        {
          throw new RuntimeException("Nested effects");
        }
        attachEffect(n, template);
      }
      else if(template instanceof EffectTemplate)
      {
        if("def".equalsIgnoreCase(nodeName))
        {
          parseBeanSet(n, ((EffectTemplate) template).getParam(), new Integer(((L2Skill) ((EffectTemplate) template).getParam().getObject("object")).getLevel()));
        }
        else
        {
          Condition cond = parseCondition(n);
          if(cond != null)
          {
            ((EffectTemplate) template).attachCond(cond);
          }
        }
      }
    }
  }

  protected void attachFunc(Node n, Object template, String name)
  {
    Stats stat = Stats.valueOfXml(n.getAttributes().getNamedItem("stat").getNodeValue());
    String order = n.getAttributes().getNamedItem("order").getNodeValue();
    int ord = parseNumber(order).intValue();
    Condition applyCond = parseCondition(n.getFirstChild());
    double val = 0;
    if(n.getAttributes().getNamedItem("val") != null)
    {
      val = parseNumber(n.getAttributes().getNamedItem("val").getNodeValue()).doubleValue();
    }
    FuncTemplate ft = new FuncTemplate(applyCond, name, stat, ord, val);
    if(template instanceof L2Item)
    {
      ((L2Item) template).attachFunction(ft);
    }
    else if(template instanceof L2Skill)
    {
      ((L2Skill) template).attach(ft);
    }
    else if(template instanceof EffectTemplate)
    {
      ((EffectTemplate) template).attachFunc(ft);
    }
  }

  protected void attachEffect(Node n, Object template)
  {
    NamedNodeMap attrs = n.getAttributes();
    StatsSet set = new StatsSet();
    set.set("name", attrs.getNamedItem("name").getNodeValue());
    set.set("object", template);
    //TODO set.set("attachCond", attachCond);
    if(attrs.getNamedItem("count") != null)
    {
      set.set("count", parseNumber(attrs.getNamedItem("count").getNodeValue()).intValue());
    }
    if(attrs.getNamedItem("time") != null)
    {
      set.set("time", parseNumber(attrs.getNamedItem("time").getNodeValue()).intValue());
    }
    set.set("value", attrs.getNamedItem("val") != null ? parseNumber(attrs.getNamedItem("val").getNodeValue()).doubleValue() : 0.);
    set.set("abnormal", AbnormalEffect.NULL);
    set.set("abnormal2", AbnormalEffect.NULL);
    if(attrs.getNamedItem("abnormal") != null)
    {
      AbnormalEffect ae = AbnormalEffect.getByName(attrs.getNamedItem("abnormal").getNodeValue());
      if(ae.isSpecial())
      {
        set.set("abnormal2", ae);
      }
      else
      {
        set.set("abnormal", ae);
      }
    }
    if(attrs.getNamedItem("stackType") != null)
    {
      set.set("stackType", attrs.getNamedItem("stackType").getNodeValue());
    }
    if(attrs.getNamedItem("stackType2") != null)
    {
      set.set("stackType2", attrs.getNamedItem("stackType2").getNodeValue());
    }
    if(attrs.getNamedItem("stackOrder") != null)
    {
      set.set("stackOrder", parseNumber(attrs.getNamedItem("stackOrder").getNodeValue()).intValue());
    }
    if(attrs.getNamedItem("applyOnCaster") != null)
    {
      set.set("applyOnCaster", Boolean.valueOf(attrs.getNamedItem("applyOnCaster").getNodeValue()));
    }
    if(attrs.getNamedItem("displayId") != null)
    {
      set.set("displayId", parseNumber(attrs.getNamedItem("displayId").getNodeValue()).intValue());
    }
    if(attrs.getNamedItem("displayLevel") != null)
    {
      set.set("displayLevel", parseNumber(attrs.getNamedItem("displayLevel").getNodeValue()).intValue());
    }
    if(attrs.getNamedItem("cancelOnAction") != null)
    {
      set.set("cancelOnAction", Boolean.valueOf(attrs.getNamedItem("cancelOnAction").getNodeValue()));
    }
    if(attrs.getNamedItem("isOffensive") != null)
    {
      set.set("isOffensive", Boolean.valueOf(attrs.getNamedItem("isOffensive").getNodeValue()));
    }
    EffectTemplate lt = new EffectTemplate(set);
    parseTemplate(n, lt);
    if(template instanceof L2Skill)
    {
      ((L2Skill) template).attach(lt);
    }
  }

  protected Condition parseCondition(Node n)
  {
    while(n != null && n.getNodeType() != Node.ELEMENT_NODE)
    {
      n = n.getNextSibling();
    }
    if(n == null)
    {
      return null;
    }
    if("and".equalsIgnoreCase(n.getNodeName()))
    {
      return parseLogicAnd(n);
    }
    if("or".equalsIgnoreCase(n.getNodeName()))
    {
      return parseLogicOr(n);
    }
    if("not".equalsIgnoreCase(n.getNodeName()))
    {
      return parseLogicNot(n);
    }
    if("player".equalsIgnoreCase(n.getNodeName()))
    {
      return parsePlayerCondition(n);
    }
    if("target".equalsIgnoreCase(n.getNodeName()))
    {
      return parseTargetCondition(n);
    }
    if("has".equalsIgnoreCase(n.getNodeName()))
    {
      return parseHasCondition(n);
    }
    if("using".equalsIgnoreCase(n.getNodeName()))
    {
      return parseUsingCondition(n);
    }
    if("game".equalsIgnoreCase(n.getNodeName()))
    {
      return parseGameCondition(n);
    }
    if("zone".equalsIgnoreCase(n.getNodeName()))
    {
      return parseZoneCondition(n);
    }
    if("InstancedZone".equalsIgnoreCase(n.getNodeName()))
    {
      return parseInstancedZoneCondition(n);
    }
    return null;
  }

  protected Condition parseLogicAnd(Node n)
  {
    ConditionLogicAnd cond = new ConditionLogicAnd();
    for(n = n.getFirstChild(); n != null; n = n.getNextSibling())
    {
      if(n.getNodeType() == Node.ELEMENT_NODE)
      {
        cond.add(parseCondition(n));
      }
    }
    if(cond._conditions == null || cond._conditions.length == 0)
    {
      _log.severe("Empty <and> condition in " + file);
    }
    return cond;
  }

  protected Condition parseLogicOr(Node n)
  {
    ConditionLogicOr cond = new ConditionLogicOr();
    for(n = n.getFirstChild(); n != null; n = n.getNextSibling())
    {
      if(n.getNodeType() == Node.ELEMENT_NODE)
      {
        cond.add(parseCondition(n));
      }
    }
    if(cond._conditions == null || cond._conditions.length == 0)
    {
      _log.severe("Empty <or> condition in " + file);
    }
    return cond;
  }

  protected Condition parseLogicNot(Node n)
  {
    for(n = n.getFirstChild(); n != null; n = n.getNextSibling())
    {
      if(n.getNodeType() == Node.ELEMENT_NODE)
      {
        return new ConditionLogicNot(parseCondition(n));
      }
    }
    _log.severe("Empty <not> condition in " + file);
    return null;
  }

  protected Condition parsePlayerCondition(Node n)
  {
    Condition cond = null;
    NamedNodeMap attrs = n.getAttributes();
    for(int i = 0; i < attrs.getLength(); i++)
    {
      Node a = attrs.item(i);
      String nodeName = a.getNodeName();
      if("race".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionPlayerRace(a.getNodeValue()));
      }
      else if("minLevel".equalsIgnoreCase(nodeName))
      {
        int lvl = parseNumber(a.getNodeValue()).intValue();
        cond = joinAnd(cond, new ConditionPlayerMinLevel(lvl));
      }
      else if("maxLevel".equalsIgnoreCase(nodeName))
      {
        int lvl = parseNumber(a.getNodeValue()).intValue();
        cond = joinAnd(cond, new ConditionPlayerMaxLevel(lvl));
      }
      else if("maxPK".equalsIgnoreCase(nodeName))
      {
        int pk = parseNumber(a.getNodeValue()).intValue();
        cond = joinAnd(cond, new ConditionPlayerMaxPK(pk));
      }
      else if("resting".equalsIgnoreCase(nodeName))
      {
        boolean val = Boolean.valueOf(a.getNodeValue());
        cond = joinAnd(cond, new ConditionPlayerState(CheckPlayerState.RESTING, val));
      }
      else if("moving".equalsIgnoreCase(nodeName))
      {
        boolean val = Boolean.valueOf(a.getNodeValue());
        cond = joinAnd(cond, new ConditionPlayerState(CheckPlayerState.MOVING, val));
      }
      else if("running".equalsIgnoreCase(nodeName))
      {
        boolean val = Boolean.valueOf(a.getNodeValue());
        cond = joinAnd(cond, new ConditionPlayerState(CheckPlayerState.RUNNING, val));
      }
      else if("standing".equalsIgnoreCase(nodeName))
      {
        boolean val = Boolean.valueOf(a.getNodeValue());
        cond = joinAnd(cond, new ConditionPlayerState(CheckPlayerState.STANDING, val));
      }
      else if("flying".equalsIgnoreCase(a.getNodeName()))
      {
        boolean val = Boolean.valueOf(a.getNodeValue());
        cond = joinAnd(cond, new ConditionPlayerState(CheckPlayerState.FLYING, val));
      }
      else if("flyingTransform".equalsIgnoreCase(a.getNodeName()))
      {
        boolean val = Boolean.valueOf(a.getNodeValue());
        cond = joinAnd(cond, new ConditionPlayerState(CheckPlayerState.FLYING_TRANSFORM, val));
      }
      else if("percentHP".equalsIgnoreCase(nodeName))
      {
        int percentHP = parseNumber(a.getNodeValue()).intValue();
        cond = joinAnd(cond, new ConditionPlayerPercentHp(percentHP));
      }
      else if("minHP".equalsIgnoreCase(nodeName))
      {
        int minHP = parseNumber(a.getNodeValue()).intValue();
        cond = joinAnd(cond, new ConditionPlayerMinHp(minHP));
      }
      else if("percentMP".equalsIgnoreCase(nodeName))
      {
        int percentMP = parseNumber(a.getNodeValue()).intValue();
        cond = joinAnd(cond, new ConditionPlayerPercentMp(percentMP));
      }
      else if("percentCP".equalsIgnoreCase(nodeName))
      {
        int percentCP = parseNumber(a.getNodeValue()).intValue();
        cond = joinAnd(cond, new ConditionPlayerPercentCp(percentCP));
      }
      else if("agathion".equalsIgnoreCase(nodeName))
      {
        int agathionId = parseNumber(a.getNodeValue()).intValue();
        cond = joinAnd(cond, new ConditionAgathion(agathionId));
      }
      else if("riding".equalsIgnoreCase(nodeName))
      {
        String riding = a.getNodeValue();
        if("strider".equalsIgnoreCase(riding))
        {
          cond = joinAnd(cond, new ConditionPlayerRiding(CheckPlayerRiding.STRIDER));
        }
        else if("wyvern".equalsIgnoreCase(riding))
        {
          cond = joinAnd(cond, new ConditionPlayerRiding(CheckPlayerRiding.WYVERN));
        }
        else if("none".equalsIgnoreCase(riding))
        {
          cond = joinAnd(cond, new ConditionPlayerRiding(CheckPlayerRiding.NONE));
        }
      }
      else if("classId".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionPlayerClassId(parseNumber(a.getNodeValue()).intValue()));
      }
      else if("hasBuffId".equalsIgnoreCase(nodeName))
      {
        StringTokenizer st = new StringTokenizer(a.getNodeValue(), ";");
        int id = Integer.parseInt(st.nextToken().trim());
        int level = -1;
        if(st.hasMoreTokens())
        {
          level = Integer.parseInt(st.nextToken().trim());
        }
        cond = joinAnd(cond, new ConditionPlayerHasBuffId(id, level));
      }
      else if("hasBuff".equalsIgnoreCase(nodeName))
      {
        StringTokenizer st = new StringTokenizer(a.getNodeValue(), ";");
        EffectType et = Enum.valueOf(EffectType.class, st.nextToken().trim());
        int level = -1;
        if(st.hasMoreTokens())
        {
          level = Integer.parseInt(st.nextToken().trim());
        }
        cond = joinAnd(cond, new ConditionPlayerHasBuff(et, level));
      }
      else if("noble".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionNoble(a.getNodeValue()));
      }
    }
    if(cond == null)
    {
      _log.severe("Unrecognized <player> condition in " + file);
    }
    return cond;
  }

  protected Condition parseTargetCondition(Node n)
  {
    Condition cond = null;
    NamedNodeMap attrs = n.getAttributes();
    for(int i = 0; i < attrs.getLength(); i++)
    {
      Node a = attrs.item(i);
      String nodeName = a.getNodeName();
      String nodeValue = a.getNodeValue();
      if("aggro".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionTargetAggro(Boolean.valueOf(nodeValue)));
      }
      else if("pvp".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionTargetPlayable(Boolean.valueOf(nodeValue)));
      }
      else if("mob".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionTargetMob(Boolean.valueOf(nodeValue)));
      }
      else if("mobId".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionTargetMobId(Integer.parseInt(nodeValue)));
      }
      else if("instanceof".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionInstanceOf(nodeValue, true));
      }
      else if("thisinstanceof".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionInstanceOf(nodeValue, false));
      }
      else if("race".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionTargetRace(nodeValue));
      }
      else if("playerRace".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionTargetPlayerRace(nodeValue));
      }
      else if("playerSameClan".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionTargetClan(nodeValue));
      }
      else if("castledoor".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionTargetCastleDoor(Boolean.valueOf(nodeValue)));
      }
      else if("direction".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionTargetDirection(TargetDirection.valueOf(nodeValue.toUpperCase())));
      }
      else if("hasBuffId".equalsIgnoreCase(nodeName))
      {
        StringTokenizer st = new StringTokenizer(nodeValue, ";");
        int id = Integer.parseInt(st.nextToken().trim());
        int level = -1;
        if(st.hasMoreTokens())
        {
          level = Integer.parseInt(st.nextToken().trim());
        }
        cond = joinAnd(cond, new ConditionTargetHasBuffId(id, level));
      }
      else if("hasBuff".equalsIgnoreCase(nodeName))
      {
        StringTokenizer st = new StringTokenizer(nodeValue, ";");
        EffectType et = Enum.valueOf(EffectType.class, st.nextToken().trim());
        int level = -1;
        if(st.hasMoreTokens())
        {
          level = Integer.parseInt(st.nextToken().trim());
        }
        cond = joinAnd(cond, new ConditionTargetHasBuff(et, level));
      }
    }
    if(cond == null)
    {
      _log.severe("Unrecognized <target> condition in " + file);
    }
    return cond;
  }

  protected Condition parseUsingCondition(Node n)
  {
    Condition cond = null;
    NamedNodeMap attrs = n.getAttributes();
    for(int i = 0; i < attrs.getLength(); i++)
    {
      Node a = attrs.item(i);
      String nodeName = a.getNodeName();
      String nodeValue = a.getNodeValue();
      if("kind".equalsIgnoreCase(nodeName))
      {
        long mask = 0;
        StringTokenizer st = new StringTokenizer(nodeValue, ",");
        tokens:
        while(st.hasMoreTokens())
        {
          String item = st.nextToken().trim();
          for(WeaponType wt : WeaponType.values())
          {
            if(wt.toString().equalsIgnoreCase(item))
            {
              mask |= wt.mask();
              continue tokens;
            }
          }
          for(ArmorType at : ArmorType.values())
          {
            if(at.toString().equalsIgnoreCase(item))
            {
              mask |= at.mask();
              continue tokens;
            }
          }
          new IllegalArgumentException("Invalid item kind: " + item).printStackTrace();
        }
        if(mask > 0)
        {
          cond = joinAnd(cond, new ConditionUsingItemType(mask));
        }
      }
      else if("armor".equalsIgnoreCase(nodeName))
      {
        ArmorType armor = ArmorType.valueOf(nodeValue.toUpperCase());
        cond = joinAnd(cond, new ConditionUsingArmor(armor));
      }
      else if("skill".equalsIgnoreCase(nodeName))
      {
        if(Util.isNumber(nodeValue))
        {
          cond = joinAnd(cond, new ConditionUsingSkill(Integer.parseInt(nodeValue)));
        }
        else
        {
          cond = joinAnd(cond, new ConditionUsingSkill(nodeValue));
        }
      }
      else if("slotitem".equalsIgnoreCase(nodeName))
      {
        StringTokenizer st = new StringTokenizer(nodeValue, ";");
        int id = Integer.parseInt(st.nextToken().trim());
        short slot = Short.parseShort(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("direction".equalsIgnoreCase(nodeName))
      {
        TargetDirection Direction = TargetDirection.valueOf(nodeValue.toUpperCase());
        cond = joinAnd(cond, new ConditionTargetDirection(Direction));
      }
      else if("instanceof".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionInstanceOf(nodeValue, true));
      }
      else if("thisinstanceof".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionInstanceOf(nodeValue, false));
      }
    }
    if(cond == null)
    {
      _log.severe("Unrecognized <using> condition in " + file);
    }
    return cond;
  }

  protected Condition parseHasCondition(Node n)
  {
    Condition cond = null;
    NamedNodeMap attrs = n.getAttributes();
    for(int i = 0; i < attrs.getLength(); i++)
    {
      Node a = attrs.item(i);
      String nodeName = a.getNodeName();
      String nodeValue = a.getNodeValue();
      if("skill".equalsIgnoreCase(nodeName))
      {
        StringTokenizer st = new StringTokenizer(nodeValue, ";");
        Integer id = parseNumber(st.nextToken().trim()).intValue();
        short level = parseNumber(st.nextToken().trim()).shortValue();
        cond = joinAnd(cond, new ConditionHasSkill(id, level));
      }
      else if("success".equalsIgnoreCase(nodeName))
      {
        cond = joinAnd(cond, new ConditionFirstEffectSuccess(Boolean.valueOf(nodeValue)));
      }
    }
    if(cond == null)
    {
      _log.severe("Unrecognized <has> condition in " + file);
    }
    return cond;
  }

  protected Condition parseGameCondition(Node n)
  {
    Condition cond = null;
    NamedNodeMap attrs = n.getAttributes();
    for(int i = 0; i < attrs.getLength(); i++)
    {
      Node a = attrs.item(i);
      if("night".equalsIgnoreCase(a.getNodeName()))
      {
        boolean val = Boolean.valueOf(a.getNodeValue());
        cond = joinAnd(cond, new ConditionGameTime(CheckGameTime.NIGHT, val));
      }
    }
    if(cond == null)
    {
      _log.severe("Unrecognized <game> condition in " + file);
    }
    return cond;
  }

  protected Condition parseZoneCondition(Node n)
  {
    Condition cond = null;
    NamedNodeMap attrs = n.getAttributes();
    for(int i = 0; i < attrs.getLength(); i++)
    {
      Node a = attrs.item(i);
      if("type".equalsIgnoreCase(a.getNodeName()))
      {
        cond = joinAnd(cond, new ConditionZone(a.getNodeValue()));
      }
    }
    if(cond == null)
    {
      _log.severe("Unrecognized <zone> condition in " + file);
    }
    return cond;
  }

  protected Condition parseInstancedZoneCondition(Node n)
  {
    Condition cond = null;
    NamedNodeMap attrs = n.getAttributes();
    for(int i = 0; i < attrs.getLength(); i++)
    {
      Node a = attrs.item(i);
      if("name".equalsIgnoreCase(a.getNodeName()))
      {
        cond = joinAnd(cond, new ConditionInstancedZone(a.getNodeValue()));
      }
    }
    if(cond == null)
    {
      _log.severe("Unrecognized <InstancedZone> condition in " + file);
    }
    return cond;
  }

  protected Object[] parseTable(Node n)
  {
    NamedNodeMap attrs = n.getAttributes();
    String name = attrs.getNamedItem("name").getNodeValue();
    if(name.charAt(0) != '#')
    {
      throw new IllegalArgumentException("Table name must start with #");
    }
    StringTokenizer data = new StringTokenizer(n.getFirstChild().getNodeValue());
    GArray<String> array = new GArray<String>();
    while(data.hasMoreTokens())
    {
      array.add(data.nextToken());
    }
    Object[] res = array.toArray(new Object[array.size()]);
    setTable(name, res);
    return res;
  }

  protected void parseBeanSet(Node n, StatsSet set, Integer level)
  {
    String name = n.getAttributes().getNamedItem("name").getNodeValue().trim();
    String value = n.getAttributes().getNamedItem("val").getNodeValue().trim();
    char ch = value.length() == 0 ? ' ' : value.charAt(0);
    if(value.contains("#") && ch != '#') // кошмарная затычка на таблицы в сложных строках вроде triggerActions
    {
      for(String str : value.split("[;: ]+"))
      {
        if(str.charAt(0) == '#')
        {
          value = value.replace(str, String.valueOf(getTableValue(str, level)));
        }
      }
    }
    if(ch == '#')
    {
      Object tableVal = getTableValue(value, level);
      Number parsedVal = parseNumber(tableVal.toString());
      set.set(name, parsedVal == null ? tableVal : String.valueOf(parsedVal));
    }
    else if((Character.isDigit(ch) || ch == '-') && !value.contains(" ") && !value.contains(";"))
    {
      set.set(name, String.valueOf(parseNumber(value)));
    }
    else
    {
      set.set(name, value);
    }
  }

  /**
   * Разбирает параметр Value как число, приводя его к 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;
    }
  }

  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;
  }
}
TOP

Related Classes of l2p.gameserver.skills.DocumentBase

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.