Jump to content

[Guide]How to make a new status!


Recommended Posts

Hello! I found in my computer the follow code.

 

Step 1 : Make a new name for it

 

Come up with a unique name for the class, something that will define that class. I will call mine "Villain", and it will be the antagonist of the actual Hero class that it is already in game.

 

So, the name itself it's suggesting that this class has a huge anger, and it's the kind of serial Killer, so the skills should fit like a glove for this class (of course, using the actual animations that are in the Lineage 2 Client, and I refer on the end of the guide about the Client modification Policy).

 

Step 2 : Make some new skills

 

So let's pretend that the skills are made, but now how do I call them on the character every time he logs in? Well, it's pretty simple actually you just need to do this :

 

In your favorite IDE (Eclipse, Netbeans) depends from person to person and open the following package : com.l2jserver.gameserver.datatables.

 

1. Once you have opened the package, right click it, and make a new .java file called : VillainSkillTable.java

 

*NOTE : I have used the HeroSkillTable as an example, and I just edited what I needed for my class. This is how it should look like this.

 

Code:

 

/*

* Villain Skill Table - Contains the ID's of the skills.

* And much more.

*/

package com.l2jserver.gameserver.datatables;

 

import com.l2jserver.gameserver.model.L2Skill;

 

public class VillainSkillTable

{

    private static final L2Skill[] _VillainSkills = new L2Skill[3];

    private static final int[] _VillainSkillsId = {ID1, ID2, ID3 .... ,ID n}; //The Skills for Villan.

   

    private VillainSkillTable()

    {

        for (int i=0; i<_VillainSkillsId.length; i++)

            _VillainSkills = SkillTable.getInstance().getInfo(_VillainSkillsId, 1);

    }

   

    public static VillainSkillTable getInstance()

    {

        return SingletonHolder._instance;

    }

   

    public static L2Skill[] getVillainSkills()

    {

        return _VillainSkills;

    }

   

    public static boolean isVillainSkill(int skillid)

    {

        /*

        * Do not perform checks directly on L2Skill array,

        * it will cause errors due to SkillTable not initialized

        */

        for (int id : _VillainSkillsId)

        {

            if (id == skillid)

                return true;

        }

       

        return false;

    }

   

    @SuppressWarnings("synthetic-access")

    private static class SingletonHolder

    {

        protected static final VillainSkillTable _instance = new VillainSkillTable();

    }

}

 

 

Your skills go between { ID1, ID2, ID3 } , BUT be careful on the following line : private static final L2Skill[] _VillainSkills = new L2Skill[3]; ... That 3 between the brackets is the number of your skills. In the case you have 4,6,9,10 skills for your new class you need to change that to the number of skills you have.

 

For example : If you have 6 skills that line will look like this -> private static final L2Skill[] _VillainSkills= new L2Skill[ 6];

 

Ok, we are done with the skills, just save the file and we are done with it. BUT be careful to be in the datatables package.

 

Step 3 : L2PcInstance modifications

 

Time to move, and make some adjustments to L2PcInstance which is in the following package : com.l2jserver.gameserver.model.actor.instance;

 

First modification will be to add the VillainSkillTable.java which we made earlier into the imports. So, below HeroSkillTable import, add the folowing :

 

Code:

 

import com.l2jserver.gameserver.datatables.VillainSkillTable;

 

 

 

Now, scroll down a bit and you should find this line // Character Character SQL String Definitions:

Below that line you should have the INSERT_INTO_CHARACTER SQL Statement. Now, my suggestion would be to put the villain column right after the nobles one, so it should look like this :

 

Code:

 

INSERT_INTO_CHARACTER = ... newbie,nobless,villain,power_grade,last_recom_date ...

 

 

Also, BE SURE TO ADD ANOTHER "?" (Question mark) sign into the values, so that there will be no problems on the GS loading, so it will not give you errors.

 

Now, below that line you have the UPDATE_CHARACTER, add a villain=? just after the nobles one. It should look like this :

 

Code:

 

UPDATE_CHARACTER = ... newbie=?,nobless=?,villain=?,power_grade=?,subpledge=? ...

 

 

Again below the UPDATE_CHARACTER , you have the RESTORE_CHARACTER line. Add a villain after the nobles also. It should look like this :

 

Code:

 

RESTORE_CHARACTER = ...  newbie, nobless, villain, power_grade, ...

 

 

Step 3.1 : Adding new methods, booleans, and many more - Still in L2PcInstance

 

What we need to do now, is to create a new private boolean for the villain, which will tell the server if the character that entered the game is a villain or not.

 

In the file, search for this line : private boolean _hero = false;, now.....BELOW it, add a new line private boolean _villain = false;

 

 

Now, we need to tell the GS to add the skills  of villain to the character that just entered (the character must be a Villain in order to get them) :

 

Code:

 

//Add the Villain Skills if the Character is Villain

        if (isVillain())

            setVillain(true);

 

 

Next, find this line : private boolean createDb(), scroll down and check for statement.setInt(35, isNoble() ? 1 :0);, below that line add the following : statement.setInt(36, isVillain() ? 1 :0);. BE CAREFUL on the numbers of the statements, if the number is used, just start modifying the above numbers, until it fits the Villain one.

 

Find the following line : player.setNoble(rset.getInt("nobless")==1);. Below it, insert this line : player.setVillain(rset.getInt("villain")==1);. Will explain later what everything does .

 

 

Again find the following statement : statement.setInt(41, isNoble() ? 1 : 0); and add below it, the following : statement.setInt(42, isVillain() ? 1 : 0);. AGAIN, if the numbers do not match, or a number is missing, start adding or modify the numbers until it fits.

 

Now, we need to create a public method which will be called when the character is set to Villain, so that the skills will be called also.

 

Code:

 

    public void setVillain(boolean villainval)

    {

        if (villainval && _baseClass == _activeClass)

        {

            for (L2Skill s : VillainSkillTable.getVillainSkills())

                addSkill(s, false); //This method does NOT save the Villain Skill into the DataBase, just like Hero Skills.

        }

        else

        {

            for (L2Skill s : VillainSkillTable.getVillainSkills())

                super.removeSkill(s); //Removes the skills for the Non-Villain Characters.

        }

        _villain = villainval;

       

        sendSkillList();

    }

 

 

Now a public boolean, which makes our life easier Cheesy

 

Code:

 

    public boolean isVillain()

    {

        return _villain;

    }

 

 

Step 3.2 : Adjustments to EnterWorld.java

 

EnterWorld.java is in the following package : com.l2jserver.gameserver.network.clientpackets;

 

Now, find the following line : setPledgeClass(activeChar);, and BELOW it add this :

 

 

Code:

 

        //Set Character to Villain and put the aura if char is Villain

        if (activeChar.isVillain())

            activeChar.setVillain(true);

 

 

At the end of the file, you have the Pledge Level, and after the hero pledge, add the villain pledge like this :

 

 

Code:

 

if (activeChar.isVillain() && pledgeClass < 8)

pledgeClass = 8;

 

 

Step 4 : The Glow - Finally, xD

 

In the Lineage 2 world the items from the below list are called ABNORMAL EFFECTS. BUT, be careful to test them in game and see which one you want for your new class.

 

 

Code:

 

    NULL,

    BLEEDING,

    POISON,

    REDCIRCLE,

    ICE,

    WIND,

    FEAR,

    STUN,

    SLEEP,

    MUTED,

    ROOT,

    HOLD_1,

    HOLD_2,

    UNKNOWN_13,

    BIG_HEAD,

    FLAME,

    UNKNOWN_16,

    GROW,

    FLOATING_ROOT,

    DANCE_STUNNED,

    FIREROOT_STUN,

    STEALTH,

    IMPRISIONING_1,

    IMPRISIONING_2,

    MAGIC_CIRCLE,

    ICE2,

    EARTHQUAKE,

    UNKNOWN_27,

    INVULNERABLE,

    VITALITY,

    REAL_TARGET,

    DEATH_MARK,

    SKULL_FEAR,

    CONFUSED,

   

    // special effects

    S_INVINCIBLE,

    S_AIR_STUN,

    S_AIR_ROOT,

    S_BAGUETTE_SWORD,

    S_YELLOW_AFFRO,

    S_PINK_AFFRO,

    S_BLACK_AFFRO,

    S_UNKNOWN8,

    STIGMA_SHILIEN,

 

 

For my Villain class, I will use the VITALITY effect, because it's nice, and fits the class.

 

Step 4.1 - Adding the effect to the character

 

Ok, we need to modify 2 files for this to work. First file is Userinfo.java, which is located in the following package com.l2jserver.gameserver.network.serverpackets;

 

Find the following line : writeC(_activeChar.isInPartyMatchRoom() ? 1 : 0);, and add below it the folowing :

 

 

Code:

 

        int vabnormal = _activeChar.getAbnormalEffect();

        if (_activeChar.isVillain())

        {

            vabnormal |= AbnormalEffect.VITALITY.getMask();

        }

        if (_activeChar.getAppearance().getInvisible() && _activeChar.isGM())

        {

            vabnormal |= AbnormalEffect.STEALTH.getMask();

        }

        writeD(vabnormal);

 

 

The second file is CharInfo.java which is in the same package as the UserInfo.java.

 

Find the following line : writeD(_activeChar.getClanId()); //clan id, and ABOVE IT, insert the following code

 

 

Code:

 

                int vabnormal = _activeChar.getAbnormalEffect();

                if (_activeChar.isVillain())

                {

                    vabnormal |= AbnormalEffect.VITALITY.getMask();

                }

                if (gmSeeInvis)

                {

                    vabnormal |= AbnormalEffect.STEALTH.getMask();

                }

                writeD(vabnormal);

 

 

 

Now, search for this line : writeC(_activeChar.isInPartyMatchRoom() ? 1 : 0);, and insert the following code BELOW :

 

 

Code:

 

            int vabnormal = _activeChar.getAbnormalEffect();

            if (_activeChar.isVillain())

            {

                vabnormal |= AbnormalEffect.VITALITY.getMask();

            }

            if (gmSeeInvis)

            {

                vabnormal |= AbnormalEffect.STEALTH.getMask();

            }

            writeD(vabnormal);

 

 

 

Step 4.2 - L2Skill - Inserting the skills, so that the server will know what it calls

 

Ok, go ahead and open L2Skill.java, which is in the following package com.l2jserver.gameserver.model;

 

Now, IMPORT the Villain Skill Table, we made in the begging of the guide, just like this :

 

 

Code:

 

import com.l2jserver.gameserver.datatables.VillainSkillTable;

 

 

Find the following line : private final boolean _isHeroSkill;, and below it, add the following line : private final boolean _isVillainSkill; //If true the skill is a Villain Skill.

 

Find the following line : _isHeroSkill = HeroSkillTable.isHeroSkill(_id);, and below it add the following line : _isVillainSkill = VillainSkillTable.isVillainSkill(_id);

 

Now, find this line : public final boolean isHeroSkill(), and below the }, add this code :

 

 

Code:

 

    public final boolean isVillainSkill()

    {

        return _isVillainSkill;

    }

 

 

Step 5 - Gameserver imports, and Olympiad restriction.

 

Of course, since this is a hero like class, we need to restrict it to join the olympiad games. Open the Olympiad.java file, which is in the following package : com.l2jserver.gameserver.model.olympiad;

 

What do we need to do here? Well, we shall make a check that if the character is noblese and it's a Villain, he will not be able to join the Olympiad Games. Search for the following line : if (!noble.isNoble()). After the } add the following code :

 

 

Code:

 

        if (!noble.isVillain())

        {

            sm = new SystemMessage (SystemMessageId.VILLANS_ARE_FORBIDDEN_TO_JOIN_THE_OLYMPIAD_GAMES);

            noble.sendPacket(sm);

            return false;

        }

 

 

And finally, it is the GameServer.java file, which can be found in the following package : com.l2jserver.gameserver;.

 

Open it, and the first thing we need to add is the import for the VillainSkills table. Find the HeroSkillsTable import, and below it insert the following :

import com.l2jserver.gameserver.datatables.VillainSkillTable;.

 

Find the following line : HeroSkillTable.getInstance();, and BELOW it, insert the following line : VillainSkillTable.getInstance();

 

DATAPACK SIDE

 

Step 1 : Adding a command to make a character Villain

 

The first Step is to add a command, which just like the //sethero will set the targeted character a Villain. Start by opening up the AdminAdmin.java file.

 

In the ADMIN_COMMANDS string, start by adding below the admin_sethero, another command that will suite your new class, or a command that you want in order to change that character into your new class. In my case, I will add admin_setvillain.

 

Now, we will need to make the command work, otherwise it will do nothing. So add the following code just below the admin_sethero one.

 

 

Code:

 

        else if (command.startsWith("admin_setvillain"))

        {

            L2PcInstance target = null;

           

            if (activeChar.getTarget() instanceof L2PcInstance)

            {

                target = (L2PcInstance) activeChar.getTarget();

                target.setVillain(target.isVillain() ? false : true);

            }

            else

            {

                target = activeChar;

                target.setVillain(target.isVillain() ? false : true);

            }

            target.broadcastUserInfo();

        }

 

 

Step 2 : SQL adjustments

 

First, open the characters.sql. Now, we need to add the column we defined into the L2PcInstance. It should look like this :

 

 

Code:

 

  `villain` TINYINT UNSIGNED NOT NULL DEFAULT 0,

 

 

It should be BELOW the nobles one.

 

Next, open the admin_command_access_rights, and add the following below the admin_sethero command.

 

Code:

 

('admin_setvillain','1'),

 

 

CONGRATS, you have successfully created your new Class.

 

Pastebin Link : http://pastebin.com/1U0sYZkH

 

Credits: Wink for creating, Crystalia for fixing some things.

 

Have fun with this, and good luck with your creations!

Link to comment
Share on other sites

This is not a new class. It's like a new 'status' for characters, like hero status or nobless status. Anyway it's a nice guide, but the only new thing is the effect for the character.

 

Also try to remove the code tags, it will be easier to read.

 

GJ.

Link to comment
Share on other sites

This isn't a new class root like for example Orc archers or something. This is like that donator mod (isDonator) in this case its IsVillain or something. If you do create a new root client wont read the data for the new class and it will be a complete pain to make engine/client accept it.

 

You should change the title, it's quite misleading.

Link to comment
Share on other sites

dafuq did i just read

 

http://docs.oracle.com/javase/tutorial/java/concepts/class.html

 

Re-edit this shit pl0x

Maybe he is newbie in world of java, don't think and act like a master, please :D

On Topic: Good guide, continue in this way and I gonna give you reputation!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...