Package games.stendhal.server.core.config

Source Code of games.stendhal.server.core.config.CreaturesXMLLoader

/* $Id: CreaturesXMLLoader.java,v 1.14 2010/12/03 19:51:15 martinfuchs Exp $ */
/***************************************************************************
*                   (C) Copyright 2003-2010 - Stendhal                    *
***************************************************************************
***************************************************************************
*                                                                         *
*   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 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
***************************************************************************/
package games.stendhal.server.core.config;

import games.stendhal.common.constants.Nature;
import games.stendhal.server.core.rule.defaultruleset.DefaultCreature;
import games.stendhal.server.entity.creature.impl.DropItem;
import games.stendhal.server.entity.creature.impl.EquipItem;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public final class CreaturesXMLLoader extends DefaultHandler {
  /** the logger instance. */
  private static final Logger logger = Logger.getLogger(CreaturesXMLLoader.class);

  private String name;

  private String clazz;

  private String subclass;

  private String description;

  private String text;

  private String tileid;

  private int atk;

  private int def;

  private int hp;

  private double speed;

  private int sizeWidth;

  private int sizeHeight;

  private int xp;

  private int level;

  private int respawn;

  private List<DropItem> dropsItems;

  private List<EquipItem> equipsItems;

  private LinkedHashMap<String, LinkedList<String>> creatureSays;

  private Map<String, String> aiProfiles;

  private List<DefaultCreature> list;
 
  private String corpseName;
 
  private int corpseWidth;
 
  private int corpseHeight;

  private boolean drops;

  private boolean equips;

  private boolean ai;

  private boolean says;

  private boolean attributes;
 
  private boolean abilities;

  /** Susceptibilities of a creature */
  private EnumMap<Nature, Double> susceptibilities;
 
  /** Type of the damage caused by the creature */
  private Nature damageType;

  CreaturesXMLLoader() {
    // hide constructor, use the CreatureGroupsXMLLoader instead
  }

  public List<DefaultCreature> load(final URI ref) throws SAXException {
    list = new LinkedList<DefaultCreature>();
    // Use the default (non-validating) parser
    final SAXParserFactory factory = SAXParserFactory.newInstance();
    try {
      // Parse the input
      final SAXParser saxParser = factory.newSAXParser();

      InputStream is = CreaturesXMLLoader.class.getResourceAsStream(ref.getPath());

      if (is == null) {
        throw new FileNotFoundException("cannot find resource '" + ref
            + "' in classpath");
      }

      try {
        saxParser.parse(is, this);
      } finally {
        is.close();
      }
    } catch (final ParserConfigurationException t) {
      logger.error(t);
    } catch (final IOException e) {
      logger.error(e);
      throw new SAXException(e);
    }
    return list;
  }

  @Override
  public void startDocument() {
    // do nothing
  }

  @Override
  public void endDocument() {
    // do nothing
  }

  @Override
  public void startElement(final String namespaceURI, final String lName, final String qName,
      final Attributes attrs) {
    text = "";
    if (qName.equals("creature")) {
      name = attrs.getValue("name");
      drops = false;
      ai = false;
      dropsItems = new LinkedList<DropItem>();
      equipsItems = new LinkedList<EquipItem>();
      creatureSays = new LinkedHashMap<String, LinkedList<String>>();
      aiProfiles = new LinkedHashMap<String, String>();
      description = null;
      damageType = Nature.CUT;
      susceptibilities = new EnumMap<Nature, Double>(Nature.class);
    } else if (qName.equals("type")) {
      clazz = attrs.getValue("class");
      subclass = attrs.getValue("subclass");

      tileid = "../../tileset/logic/creature/" + attrs.getValue("tileid");
    } else if (qName.equals("level")) {
      level = Integer.parseInt(attrs.getValue("value"));
    } else if (qName.equals("experience")) {
      // XP rewarded is right now 5% of the creature real XP
      xp = Integer.parseInt(attrs.getValue("value")) * 20;
    } else if (qName.equals("equips")) {
      equips = true;
    } else if (qName.equals("slot") && equips) {
      String item = null;
      String slot = null;
      int quantity = 1;

      for (int i = 0; i < attrs.getLength(); i++) {
        if (attrs.getQName(i).equals("item")) {
          item = attrs.getValue(i);
        } else if (attrs.getQName(i).equals("name")) {
          slot = attrs.getValue(i);
        } else if (attrs.getQName(i).equals("quantity")) {
          quantity = Integer.parseInt(attrs.getValue(i));
        }
      }
      if ((item != null) && (slot != null)) {
        equipsItems.add(new EquipItem(slot, item, quantity));
      }
    } else if (qName.equals("respawn")) {
      respawn = Integer.parseInt(attrs.getValue("value"));
    } else if (qName.equals("corpse")) {
      corpseName = attrs.getValue("name");
      String value = attrs.getValue("width");
     
      // Default to 1 for width and height to save the fingers
      // of the people writing the creatures
      if (value != null) {
        corpseWidth = Integer.parseInt(value);
      } else {
        corpseWidth = 1;
      }

      value = attrs.getValue("height");
      if (value != null) {
        corpseHeight = Integer.parseInt(value);
      } else {
        corpseHeight = 1;
      }
    } else if (qName.equals("drops")) {
      drops = true;
    } else if (qName.equals("item") && drops) {
      String tempName = null;
      Double probability = null;
      String range = null;

      for (int i = 0; i < attrs.getLength(); i++) {
        if (attrs.getQName(i).equals("value")) {
          tempName = attrs.getValue(i);
        } else if (attrs.getQName(i).equals("probability")) {
          probability = Double.parseDouble(attrs.getValue(i));
        } else if (attrs.getQName(i).equals("quantity")) {
          range = attrs.getValue(i);
        }
      }

      if ((tempName != null) && (probability != null) && (range != null)) {
        logger.debug(tempName + ":" + probability + ":" + range);
        if (range.contains("[")) {
          range = range.replace("[", "");
          range = range.replace("]", "");
          final String[] amount = range.split(",");

          dropsItems.add(new DropItem(tempName, probability,
              Integer.parseInt(amount[0]),
              Integer.parseInt(amount[1])));
        } else {
          dropsItems.add(new DropItem(tempName, probability,
              Integer.parseInt(range)));
        }
      }
    } else if (qName.equals("attributes")) {
      attributes = true;
    } else if (attributes && qName.equals("atk")) {
      atk = Integer.parseInt(attrs.getValue("value"));
    } else if (attributes && qName.equals("def")) {
      def = Integer.parseInt(attrs.getValue("value"));
    } else if (attributes && qName.equals("hp")) {
      hp = Integer.parseInt(attrs.getValue("value"));
    } else if (attributes && qName.equals("speed")) {
      speed = Double.parseDouble(attrs.getValue("value"));
    } else if (attributes && qName.equals("size")) {
      final String[] size = attrs.getValue("value").split(",");

      sizeWidth = Integer.parseInt(size[0]);
      sizeHeight = Integer.parseInt(size[1]);
    } else if (qName.equals("ai")) {
      ai = true;
    } else if (ai && qName.equals("profile")) {
      aiProfiles.put(attrs.getValue("name"), attrs.getValue("params"));
    } else if (ai && qName.equals("says")) {
      says = true;
    } else if (says && qName.equals("noise")) {
      final String states = attrs.getValue("state");
      final String value = attrs.getValue("value");
      final List<String> keys=Arrays.asList(states.split(" "));
      // no such state in noises, will add it
      for (int i=0; i<keys.size(); i++) {
        final String key=keys.get(i);
        if(creatureSays.get(key)==null) {
          final LinkedList<String> ll=new LinkedList<String>();
          ll.add(value);
          creatureSays.put(key, ll);
          // no such value in existing state, will add it
        } else if (creatureSays.get(key).indexOf(value)==-1) {
          creatureSays.get(key).add(value);
          // both state and value already exists
        } else {
          logger.warn("CreatureXMLLoader: creature ("+name+
                "): double definition for noise \""+key+"\" ("+value+")");
        }
      }
    } else if (qName.equals("abilities")) {
      abilities = true;
    } else if (abilities && qName.equals("damage")) {
      damageType = Nature.parse(attrs.getValue("type"));
    } else if (abilities && qName.equals("susceptibility")) {
      Nature type = Nature.parse(attrs.getValue("type"));
      Double value = Double.valueOf(attrs.getValue("value"));
      susceptibilities.put(type, value);
    }
  }

  @Override
  public void endElement(final String namespaceURI, final String sName, final String qName) {
    if (qName.equals("creature")) {
      if (!tileid.contains(":")) {
        logger.error("Corrupt XML file: Bad tileid for creature("
            + name + ")");
        return;
      }

      final DefaultCreature creature = new DefaultCreature(clazz, subclass,
          name, tileid);
      creature.setRPStats(hp, atk, def, speed);
      creature.setLevel(level, xp);
      creature.setSize(sizeWidth, sizeHeight);
      creature.setEquipedItems(equipsItems);
     
      creature.setCorpse(corpseName, corpseWidth, corpseHeight);
      corpseName = null;
      corpseWidth = corpseHeight = 1;
     
      creature.setDropItems(dropsItems);
      creature.setAIProfiles(aiProfiles);
      creature.setNoiseLines(creatureSays);
      creature.setRespawnTime(respawn);
      creature.setDescription(description);
      creature.setSusceptibilities(susceptibilities);
      creature.setDamageType(damageType);
      list.add(creature);
    } else if (qName.equals("attributes")) {
      attributes = false;
    } else if (qName.equals("equips")) {
      equips = false;
    } else if (qName.equals("drops")) {
      drops = false;
    } else if (ai && qName.equals("says")) {
      says = false;
    } else if (qName.equals("ai")) {
      ai = false;
    } else if (qName.equals("description")) {
      if (text != null) {
        description = text.trim();
      }
      text = "";
    } else if (qName.equals("abilities")) {
      abilities = false;
    }
  }

  @Override
  public void characters(final char[] buf, final int offset, final int len) {
    text = text + (new String(buf, offset, len)).trim() + " ";
  }
}
TOP

Related Classes of games.stendhal.server.core.config.CreaturesXMLLoader

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.