com.l2jfree.gameserver.gameobjects.templates.L2NpcTemplate.java Source code

Java tutorial

Introduction

Here is the source code for com.l2jfree.gameserver.gameobjects.templates.L2NpcTemplate.java

Source

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

import java.lang.reflect.Constructor;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javolution.util.FastList;
import javolution.util.FastMap;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.l2jfree.gameserver.gameobjects.base.ClassId;
import com.l2jfree.gameserver.model.L2MinionData;
import com.l2jfree.gameserver.model.drop.L2DropCategory;
import com.l2jfree.gameserver.model.drop.L2DropData;
import com.l2jfree.gameserver.model.quest.Quest;
import com.l2jfree.gameserver.model.skills.L2Skill;
import com.l2jfree.gameserver.model.skills.Stats;
import com.l2jfree.gameserver.templates.StatsSet;

/**
 * This cl contains all generic data of a L2Spawn object.<BR><BR>
 * 
 * <B><U> Data</U> :</B><BR><BR>
 * <li>npcId, type, name, sex</li>
 * <li>rewardExp, rewardSp</li>
 * <li>aggroRange, factionId, factionRange</li>
 * <li>rhand, lhand, armor</li>
 * <li>isUndead</li>
 * <li>_drops</li>
 * <li>_minions</li>
 * <li>_teachInfo</li>
 * <li>_skills</li>
 * <li>_questsStart</li><BR><BR>
 * 
 * this template has property that will be set by setters.
 * <br/>
 * <br/>
 * <font color="red">
 * <b>Property don't change in the time, this is just a template, not the currents status
 * of characters !</b>
 * </font>
 * 
 * @version $Revision: 1.1.2.4 $ $Date: 2005/04/02 15:57:51 $
 */
public final class L2NpcTemplate extends L2CreatureTemplate {
    /**
     * Logger
     */
    private final static Log _log = LogFactory.getLog(L2NpcTemplate.class);

    private int _npcId;
    private int _idTemplate;
    private final String _type;
    private final Class<?> _clazz;
    private String _name;
    private boolean _serverSideName;
    private String _title;
    private boolean _serverSideTitle;
    private String _sex;
    private byte _level;
    private int _rewardExp;
    private int _rewardSp;
    private int _aggroRange;
    private int _rhand;
    private int _lhand;
    private int _armor;
    private String _factionId;
    private int _factionRange;
    private int _absorbLevel;
    private AbsorbCrystalType _absorbType;
    private short _ss;
    private short _bss;
    private short _ssRate;
    private int _npcFaction;
    private String _npcFactionName;
    private String _jClass;
    private AIType _ai;
    private final boolean _isQuestMonster;
    private final boolean _dropHerbs;
    private final float _baseVitalityDivider;

    private Race _race;

    /** The table containing all Item that can be dropped by L2NpcInstance using this L2NpcTemplate*/
    private L2DropCategory[] _categories;

    /** The table containing all Minions that must be spawn with the L2NpcInstance using this L2NpcTemplate*/
    private L2MinionData[] _minions;

    /** The list of class that this NpcTemplate can Teach */
    private EnumSet<ClassId> _teachInfo;

    /** List of skills of this npc */
    private FastMap<Integer, L2Skill> _skills;

    /** List of resist stats for this npc*/
    private Map<Stats, Double> _vulnerabilities;

    /** contains a list of quests for each event type (questStart, questAttack, questKill, etc)*/
    private Quest[][] _questEvents;

    public static enum AbsorbCrystalType {
        LAST_HIT, FULL_PARTY, PARTY_ONE_RANDOM
    }

    public static enum AIType {
        FIGHTER, ARCHER, BALANCED, MAGE, HEALER, CORPSE
    }

    public static enum Race {
        UNDEAD, MAGICCREATURE, BEAST, ANIMAL, PLANT, HUMANOID, SPIRIT, ANGEL, DEMON, DRAGON, GIANT, BUG, FAIRIE, HUMAN, ELVE, DARKELVE, ORC, DWARVE, OTHER, NONLIVING, SIEGEWEAPON, DEFENDINGARMY, MERCENARIE, UNKNOWN, KAMAEL, NONE;

        public Stats getOffensiveStat() {
            switch (this) {
            case BEAST:
                return Stats.PATK_MONSTERS;
            case ANIMAL:
                return Stats.PATK_ANIMALS;
            case PLANT:
                return Stats.PATK_PLANTS;
            case DRAGON:
                return Stats.PATK_DRAGONS;
            case BUG:
                return Stats.PATK_INSECTS;
            case GIANT:
                return Stats.PATK_GIANTS;
            case MAGICCREATURE:
                return Stats.PATK_MAGIC;
            default:
                return null;
            }
        }

        public Stats getDefensiveStat() {
            switch (this) {
            case BEAST:
                return Stats.PDEF_MONSTERS;
            case ANIMAL:
                return Stats.PDEF_ANIMALS;
            case PLANT:
                return Stats.PDEF_PLANTS;
            case DRAGON:
                return Stats.PDEF_DRAGONS;
            case BUG:
                return Stats.PDEF_INSECTS;
            case GIANT:
                return Stats.PDEF_GIANTS;
            case MAGICCREATURE:
                return Stats.PDEF_MAGIC;
            default:
                return null;
            }
        }
    }

    /**
     * Constructor of L2Creature.<BR>
     * 
     * @param set The StatsSet object to transfer data to the method
     * @throws ClassNotFoundException
     */
    public L2NpcTemplate(StatsSet set) throws ClassNotFoundException {
        super(set);
        _npcId = set.getInteger("npcId");
        _idTemplate = set.getInteger("idTemplate");
        if (getNpcId() == 30995)
            _type = "L2RaceManager";
        else if (31046 <= getNpcId() && getNpcId() <= 31053)
            _type = "L2SymbolMaker";
        else
            _type = set.getString("type").intern(); // implementing class name
        _clazz = Class.forName("com.l2jfree.gameserver.gameobjects.instance." + _type + "Instance");
        _name = set.getString("name").intern();
        _serverSideName = set.getBool("serverSideName");
        _title = set.getString("title").intern();
        _isQuestMonster = _title.equalsIgnoreCase("Quest Monster");
        _serverSideTitle = set.getBool("serverSideTitle");
        _sex = set.getString("sex").intern();
        _level = set.getByte("level");
        _rewardExp = set.getInteger("rewardExp");
        _rewardSp = set.getInteger("rewardSp");
        _aggroRange = set.getInteger("aggroRange");
        _rhand = set.getInteger("rhand");
        _lhand = set.getInteger("lhand");
        _armor = set.getInteger("armor");
        setFactionId(set.getString("factionId", null));
        _factionRange = set.getInteger("factionRange");
        _absorbLevel = set.getInteger("absorb_level");
        _absorbType = AbsorbCrystalType.valueOf(set.getString("absorb_type"));
        _ss = set.getShort("ss");
        _bss = set.getShort("bss");
        _ssRate = set.getShort("ssRate");
        _npcFaction = set.getInteger("NPCFaction", 0);
        _npcFactionName = set.getString("NPCFactionName", "Devine Clan").intern();
        _jClass = set.getString("jClass").intern();
        _dropHerbs = set.getBool("drop_herbs");

        String ai = set.getString("AI");
        if (ai.equalsIgnoreCase("archer"))
            _ai = AIType.ARCHER;
        else if (ai.equalsIgnoreCase("balanced"))
            _ai = AIType.BALANCED;
        else if (ai.equalsIgnoreCase("mage"))
            _ai = AIType.MAGE;
        else if (ai.equalsIgnoreCase("healer"))
            _ai = AIType.HEALER;
        else if (ai.equalsIgnoreCase("corpse"))
            _ai = AIType.CORPSE;
        else
            _ai = AIType.FIGHTER;

        _race = null;
        _teachInfo = null;

        // all NPCs has 20 resistance to all attributes
        setBaseFireRes(getBaseFireRes() + 20);
        setBaseWindRes(getBaseWindRes() + 20);
        setBaseWaterRes(getBaseWaterRes() + 20);
        setBaseEarthRes(getBaseEarthRes() + 20);
        setBaseHolyRes(getBaseHolyRes() + 20);
        setBaseDarkRes(getBaseDarkRes() + 20);

        // can be loaded from db
        _baseVitalityDivider = getLevel() > 0 && getRewardExp() > 0
                ? getBaseHpMax() * 9 * getLevel() * getLevel() / (100 * getRewardExp())
                : 0;
    }

    /**
     * Add the class id this npc can teach
     * @param classId
     */
    public void addTeachInfo(ClassId classId) {
        if (_teachInfo == null)
            _teachInfo = EnumSet.noneOf(ClassId.class);
        _teachInfo.add(classId);
    }

    /**
     * @return the teach infos
     */
    public Set<ClassId> getTeachInfo() {
        return _teachInfo;
    }

    /**
     * Check if this npc can teach to this class
     * @param classId
     * @return true if this npc can teach to this class
     */
    public boolean canTeach(ClassId classId) {
        if (_teachInfo == null)
            return false;

        // If the player is on a third class, fetch the class teacher
        // information for its parent class.
        if (classId.level() == 3)
            return _teachInfo.contains(classId.getParent());

        return _teachInfo.contains(classId);
    }

    /**
     * add a drop to a given category.  If the category does not exist, create it.
     * @param drop
     * @param categoryType
     */
    public synchronized void addDropData(L2DropData drop, int categoryType) {
        if (drop.isQuestDrop()) {
            //          if (_questDrops == null)
            //              _questDrops = new FastList<L2DropData>(0);
            //          _questDrops.add(drop);
        } else {
            // if the category doesn't already exist, create it first
            if (_categories == null)
                _categories = new L2DropCategory[0];
            synchronized (_categories) {
                boolean catExists = false;
                for (L2DropCategory cat : _categories)
                    // if the category exists, add the drop to this category.
                    if (cat.getCategoryType() == categoryType) {
                        cat.addDropData(drop);
                        catExists = true;
                        break;
                    }
                // if the category doesn't exit, create it and add the drop
                if (!catExists) {
                    L2DropCategory cat = new L2DropCategory(categoryType);
                    cat.addDropData(drop);
                    _categories = ArrayUtils.add(_categories, cat);
                }
            }
        }
    }

    public void addRaidData(L2MinionData minion) {
        if (_minions == null)
            _minions = new L2MinionData[] { minion };
        else
            _minions = ArrayUtils.add(_minions, minion);
    }

    public void addSkill(L2Skill skill) {
        if (_skills == null)
            _skills = new FastMap<Integer, L2Skill>().setShared(true);

        _skills.put(skill.getId(), skill);
    }

    public void clearSkills() {
        if (_skills != null)
            _skills.clear();
    }

    public void addVulnerability(Stats id, double vuln) {
        if (vuln == 1) {
            if (_vulnerabilities != null)
                _vulnerabilities.remove(id);
            return;
        }

        if (_vulnerabilities == null)
            _vulnerabilities = new FastMap<Stats, Double>();
        _vulnerabilities.put(id, vuln);
    }

    public double getVulnerability(Stats id) {
        if (_vulnerabilities == null)
            return 1;
        Double vuln = _vulnerabilities.get(id);
        return vuln == null ? 1 : vuln.doubleValue();
    }

    public double removeVulnerability(Stats id) {
        return _vulnerabilities.remove(id);
    }

    /**
     * Return the list of all possible UNCATEGORIZED drops of this L2NpcTemplate.<BR><BR>
     * @return the drop categories
     */
    public L2DropCategory[] getDropData() {
        return _categories;
    }

    /**
     * Return the list of all possible item drops of this L2NpcTemplate.<BR>
     * (ie full drops and part drops, mats, miscellaneous & UNCATEGORIZED)<BR><BR>
     */
    public List<L2DropData> getAllDropData() {
        if (_categories == null)
            return null;
        FastList<L2DropData> lst = new FastList<L2DropData>();
        for (L2DropCategory tmp : _categories) {
            lst.addAll(tmp.getAllDrops());
        }
        return lst;
    }

    /**
     * Empty all possible drops of this L2NpcTemplate.<BR><BR>
     */
    public synchronized void clearAllDropData() {
        if (_categories == null)
            return;

        for (L2DropCategory category : _categories)
            category.clearAllDrops();

        _categories = null;
    }

    /**
     * Return the list of all Minions that must be spawn with the L2NpcInstance using this L2NpcTemplate.<BR><BR>
     */
    public L2MinionData[] getMinionData() {
        return _minions;
    }

    public Map<Integer, L2Skill> getSkills() {
        return _skills == null ? null : _skills.unmodifiable();
    }

    public void addQuestEvent(Quest.QuestEventType EventType, Quest q) {
        if (_questEvents == null)
            _questEvents = new Quest[Quest.QuestEventType.values().length][];

        if (_questEvents[EventType.ordinal()] == null) {
            _questEvents[EventType.ordinal()] = new Quest[] { q };
        } else {
            Quest[] _quests = _questEvents[EventType.ordinal()];
            int len = _quests.length;

            // if only one registration per npc is allowed for this event type
            // then only register this NPC if not already registered for the specified event.
            // if a quest allows multiple registrations, then register regardless of count
            // In all cases, check if this new registration is replacing an older copy of the SAME quest
            if (!EventType.isMultipleRegistrationAllowed()) {
                if (_quests[0].getName().equals(q.getName()))
                    _quests[0] = q;
                else
                    _log.warn("Quest event not allowed in multiple quests.  Skipped addition of Event Type \""
                            + EventType + "\" for NPC \"" + _name + "\" and quest \"" + q.getName() + "\".");
            } else {
                // be ready to add a new quest to a new copy of the list, with larger size than previously.
                Quest[] tmp = new Quest[len + 1];
                // loop through the existing quests and copy them to the new list.  While doing so, also
                // check if this new quest happens to be just a replacement for a previously loaded quest.
                // If so, just save the updated reference and do NOT use the new list. Else, add the new
                // quest to the end of the new list
                for (int i = 0; i < len; i++) {
                    if (_quests[i].getName().equals(q.getName())) {
                        _quests[i] = q;
                        return;
                    }
                    tmp[i] = _quests[i];
                }
                tmp[len] = q;
                _questEvents[EventType.ordinal()] = tmp;
            }
        }
    }

    public Quest[] getEventQuests(Quest.QuestEventType EventType) {
        if (_questEvents == null)
            return null;
        return _questEvents[EventType.ordinal()];
    }

    public void setRace(int raceId) {
        switch (raceId) {
        case 1:
            _race = L2NpcTemplate.Race.UNDEAD;
            break;
        case 2:
            _race = L2NpcTemplate.Race.MAGICCREATURE;
            break;
        case 3:
            _race = L2NpcTemplate.Race.BEAST;
            break;
        case 4:
            _race = L2NpcTemplate.Race.ANIMAL;
            break;
        case 5:
            _race = L2NpcTemplate.Race.PLANT;
            break;
        case 6:
            _race = L2NpcTemplate.Race.HUMANOID;
            break;
        case 7:
            _race = L2NpcTemplate.Race.SPIRIT;
            break;
        case 8:
            _race = L2NpcTemplate.Race.ANGEL;
            break;
        case 9:
            _race = L2NpcTemplate.Race.DEMON;
            break;
        case 10:
            _race = L2NpcTemplate.Race.DRAGON;
            break;
        case 11:
            _race = L2NpcTemplate.Race.GIANT;
            break;
        case 12:
            _race = L2NpcTemplate.Race.BUG;
            break;
        case 13:
            _race = L2NpcTemplate.Race.FAIRIE;
            break;
        case 14:
            _race = L2NpcTemplate.Race.HUMAN;
            break;
        case 15:
            _race = L2NpcTemplate.Race.ELVE;
            break;
        case 16:
            _race = L2NpcTemplate.Race.DARKELVE;
            break;
        case 17:
            _race = L2NpcTemplate.Race.ORC;
            break;
        case 18:
            _race = L2NpcTemplate.Race.DWARVE;
            break;
        case 19:
            _race = L2NpcTemplate.Race.OTHER;
            break;
        case 20:
            _race = L2NpcTemplate.Race.NONLIVING;
            break;
        case 21:
            _race = L2NpcTemplate.Race.SIEGEWEAPON;
            break;
        case 22:
            _race = L2NpcTemplate.Race.DEFENDINGARMY;
            break;
        case 23:
            _race = L2NpcTemplate.Race.MERCENARIE;
            break;
        case 24:
            _race = L2NpcTemplate.Race.UNKNOWN;
            break;
        case 25:
            _race = L2NpcTemplate.Race.KAMAEL;
            break;
        default:
            _race = L2NpcTemplate.Race.NONE;
            break;
        }
    }

    public L2NpcTemplate.Race getRace() {
        if (_race == null)
            _race = L2NpcTemplate.Race.NONE;

        return _race;
    }

    public int getNpcFaction() {
        return _npcFaction;
    }

    public void setNpcFaction(int npcFaction) {
        _npcFaction = npcFaction;
    }

    public String getNpcFactionName() {
        return _npcFactionName;
    }

    /**
     * @return the absorb_level
     */
    public int getAbsorbLevel() {
        return _absorbLevel;
    }

    /**
     * @param absorb_level the absorb_level to set
     */
    public void setAbsorbLevel(int absorb_level) {
        _absorbLevel = absorb_level;
    }

    /**
     * @return the absorb_type
     */
    public AbsorbCrystalType getAbsorbType() {
        return _absorbType;
    }

    /**
     * @param absorb_type the absorb type to set
     */
    public void setAbsorbType(AbsorbCrystalType absorb_type) {
        _absorbType = absorb_type;
    }

    /**
     * @return the aggroRange
     */
    public int getAggroRange() {
        return _aggroRange;
    }

    /**
     * @param aggroRange the aggroRange to set
     */
    public void setAggroRange(int aggroRange) {
        _aggroRange = aggroRange;
    }

    /**
     * @return the armor
     */
    public int getArmor() {
        return _armor;
    }

    /**
     * @param armor the armor to set
     */
    public void setArmor(int armor) {
        _armor = armor;
    }

    /**
     * @return the factionId
     */
    public String getFactionId() {
        return _factionId;
    }

    /**
     * @param factionId the factionId to set
     */
    public void setFactionId(String factionId) {
        if (factionId == null) {
            _factionId = null;
            return;
        }
        _factionId = factionId.intern();
    }

    /**
     * @return the factionRange
     */
    public int getFactionRange() {
        return _factionRange;
    }

    /**
     * @param factionRange the factionRange to set
     */
    public void setFactionRange(int factionRange) {
        _factionRange = factionRange;
    }

    /**
     * @return the idTemplate
     */
    public int getIdTemplate() {
        return _idTemplate;
    }

    /**
     * @param idTemplate the idTemplate to set
     */
    public void setIdTemplate(int idTemplate) {
        _idTemplate = idTemplate;
    }

    /**
     * @return the level
     */
    public byte getLevel() {
        return _level;
    }

    /**
     * @param level the level to set
     */
    public void setLevel(byte level) {
        _level = level;
    }

    /**
     * @return the lhand
     */
    public int getLhand() {
        return _lhand;
    }

    /**
     * @param lhand the lhand to set
     */
    public void setLhand(int lhand) {
        _lhand = lhand;
    }

    /**
     * @return the name
     */
    public String getName() {
        return _name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        _name = name;
    }

    /**
     * @return the npcId
     */
    public int getNpcId() {
        return _npcId;
    }

    /**
     * @param npcId the npcId to set
     */
    public void setNpcId(int npcId) {
        _npcId = npcId;
    }

    /**
     * @return the rewardExp
     */
    public int getRewardExp() {
        return _rewardExp;
    }

    /**
     * @param rewardExp the rewardExp to set
     */
    public void setRewardExp(int rewardExp) {
        _rewardExp = rewardExp;
    }

    /**
     * @return the rewardSp
     */
    public int getRewardSp() {
        return _rewardSp;
    }

    /**
     * @param rewardSp the rewardSp to set
     */
    public void setRewardSp(int rewardSp) {
        _rewardSp = rewardSp;
    }

    /**
     * @return the rhand
     */
    public int getRhand() {
        return _rhand;
    }

    /**
     * @param rhand the rhand to set
     */
    public void setRhand(int rhand) {
        _rhand = rhand;
    }

    /**
     * @return the serverSideName
     */
    public boolean isServerSideName() {
        return _serverSideName;
    }

    /**
     * @param serverSideName the serverSideName to set
     */
    public void setServerSideName(boolean serverSideName) {
        _serverSideName = serverSideName;
    }

    /**
     * @return the serverSideTitle
     */
    public boolean isServerSideTitle() {
        return _serverSideTitle;
    }

    /**
     * @param serverSideTitle the serverSideTitle to set
     */
    public void setServerSideTitle(boolean serverSideTitle) {
        _serverSideTitle = serverSideTitle;
    }

    /**
     * @return the sex
     */
    public String getSex() {
        return _sex;
    }

    /**
     * @param sex the sex to set
     */
    public void setSex(String sex) {
        _sex = sex;
    }

    /**
     * @return the title
     */
    public String getTitle() {
        return _title;
    }

    /**
     * @param title the title to set
     */
    public void setTitle(String title) {
        _title = title;
    }

    /**
     * @return the type
     */
    public String getType() {
        return _type;
    }

    public boolean isAssignableTo(Class<?> clazz) {
        return clazz.isAssignableFrom(_clazz);
    }

    public Constructor<?> getDefaultConstructor() throws NoSuchMethodException, SecurityException {
        return _clazz.getConstructor(Integer.TYPE, L2NpcTemplate.class);
    }

    /**
     * @param factionName the nPCFactionName to set
     */
    public void setNPCFactionName(String factionName) {
        _npcFactionName = (factionName == null ? "Devine Clan" : factionName);
    }

    /**
     * @return the jClass
     */
    public String getJClass() {
        return _jClass;
    }

    /**
     * @param class1 the jClass to set
     */
    public void setJClass(String class1) {
        _jClass = class1;
    }

    public short getSS() {
        return _ss;
    }

    public short getBSS() {
        return _bss;
    }

    public short getSSRate() {
        return _ssRate;
    }

    public AIType getAI() {
        return _ai;
    }

    public void setSS(short ss) {
        _ss = ss;
    }

    public void setBSS(short bss) {
        _bss = bss;
    }

    public void setSSRate(short ssrate) {
        _ssRate = ssrate;
    }

    public void setAI(AIType type) {
        _ai = type;
    }

    public boolean isQuestMonster() {
        return _isQuestMonster;
    }

    public boolean dropHerbs() {
        return _dropHerbs;
    }

    public boolean isCustom() {
        return _npcId != _idTemplate;
    }

    public float getBaseVitalityDivider() {
        return _baseVitalityDivider;
    }
}