[Add-On] How to use PlayerNPCs

Junior Spellweaver
Joined
Jan 30, 2011
Messages
106
Reaction score
21
How to use PlayerNPCs
This tutorial is to teach the noobs out there that can't use PlayerNPCs. I don't think anyone posted this, I've used google to find it and also used the ragezone search. All I saw was about people asking for help on how to add PlayerNPCs, delete them, change names, and serval questions. Anyways let's start the tutorial.

You will have to add some things to make the PlayerNPC to work:
For those that don't have the PlayerNPC command here:
Add this in your commands.java or whatever your commands are at
PHP:
} else if (sub[0].equals("playernpc")) {
    chr.playerNPC(c.getChannelServer().getPlayerStorage().getCharacterByName(sub[1]), Integer.parseInt(sub[2]));
}
Also add this at MapleCharacter.java
PHP:
    public void playerNPC(MapleCharacter v, int scriptId) {
        int npcId;
        try {
            Connection con = DatabaseConnection.getConnection();
            PreparedStatement ps = con.prepareStatement("SELECT id FROM playernpcs WHERE ScriptId = ?");
            ps.setInt(1, scriptId);
            ResultSet rs = ps.executeQuery();
            if (!rs.next()) {
                rs.close();
                ps = con.prepareStatement("INSERT INTO playernpcs (name, hair, face, skin, x, cy, map, ScriptId, Foothold, rx0, rx1) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS);
                ps.setString(1, v.getName());
                ps.setInt(2, v.getHair());
                ps.setInt(3, v.getFace());
                ps.setInt(4, v.getSkinColor().getId());
                ps.setInt(5, getPosition().x);
                ps.setInt(6, getPosition().y);
                ps.setInt(7, getMapId());
                ps.setInt(8, scriptId);
                ps.setInt(9, getMap().getFootholds().findBelow(getPosition()).getId());
                ps.setInt(10, getPosition().x + 50);
                ps.setInt(11, getPosition().x - 50);
                ps.executeUpdate();
                rs = ps.getGeneratedKeys();
                rs.next();
                npcId = rs.getInt(1);
                ps.close();
                ps = con.prepareStatement("INSERT INTO playernpcs_equip (NpcId, equipid, equippos) VALUES (?, ?, ?)");
                ps.setInt(1, npcId);
                for (IItem equip : getInventory(MapleInventoryType.EQUIPPED)) {
                    int position = Math.abs(equip.getPosition());
                    if ((position < 12 && position > 0) || (position > 100 && position < 112)) {
                        ps.setInt(2, equip.getItemId());
                        ps.setInt(3, equip.getPosition());
                        ps.addBatch();
                    }
                }
                ps.executeBatch();
                ps.close();
                rs.close();
                ps = con.prepareStatement("SELECT * FROM playernpcs WHERE ScriptId = ?");
                ps.setInt(1, scriptId);
                rs = ps.executeQuery();
                rs.next();
                PlayerNPCs pn = new PlayerNPCs(rs);
                for (ChannelServer channel : ChannelServer.getAllInstances()) {
                    MapleMap m = channel.getMapFactory().getMap(getMapId());
                    m.broadcastMessage(MaplePacketCreator.spawnPlayerNPC(pn));
                    m.broadcastMessage(MaplePacketCreator.getPlayerNPC(pn));
                    m.addMapObject(pn);
                }
            }
            ps.close();
            rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
For those that don't have a PlayerNPCs.java at src>server>maps then make a .java file and add this:
PHP:
/*
	This file is part of the OdinMS Maple Story Server
    Copyright (C) 2008 Patrick Huy <[email protected]>
		       Matthias Butz <[email protected]>
		       Jan Christian Meyer <[email protected]>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as
    published by the Free Software Foundation version 3 as published by
    the Free Software Foundation. You may not use, modify or distribute
    this program under any other version of the GNU Affero General Public
    License.

    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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package server.maps;

import java.awt.Point;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;
import client.MapleClient;
import java.sql.SQLException;
import tools.DatabaseConnection;
import tools.MaplePacketCreator;

/**
 *
 * @author XoticStory
 */
public class PlayerNPCs extends AbstractMapleMapObject {
    private Map<Byte, Integer> equips = new HashMap<Byte, Integer>();
    private int npcId, face, hair;
    private byte skin,dir;
    private String name = "";
    private int FH, RX0, RX1, CY;

    public PlayerNPCs(ResultSet rs) {
        try {
            CY = rs.getInt("cy");
            name = rs.getString("name");
            hair = rs.getInt("hair");
            face = rs.getInt("face");
            skin = rs.getByte("skin");
            FH = rs.getInt("Foothold");
            RX0 = rs.getInt("rx0");
            RX1 = rs.getInt("rx1");
            npcId = rs.getInt("ScriptId");
            setPosition(new Point(rs.getInt("x"), CY));
            PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT equippos, equipid FROM playernpcs_equip WHERE NpcId = ?");
            ps.setInt(1, rs.getInt("id"));
            ResultSet rs2 = ps.executeQuery();
            while (rs2.next()) {
                equips.put(rs2.getByte("equippos"), rs2.getInt("equipid"));
            }
            rs2.close();
            ps.close();
        } catch (SQLException e) {
        }
    }

    public Map<Byte, Integer> getEquips() {
        return equips;
    }

    public int getId() {
        return npcId;
    }

    public int getFH() {
        return FH;
    }

    public int getRX0() {
        return RX0;
    }

    public int getDir() {
        return dir;
    }

    public int getRX1() {
        return RX1;
    }

    public int getCY() {
        return CY;
    }

    public byte getSkin() {
        return skin;
    }

    public String getName() {
        return name;
    }

    public int getFace() {
        return face;
    }

    public int getHair() {
        return hair;
    }

    @Override
    public void sendDestroyData(MapleClient client) {
        return;
    }

    @Override
    public MapleMapObjectType getType() {
        return MapleMapObjectType.PLAYER_NPC;
    }

    @Override
    public void sendSpawnData(MapleClient client) {
        client.getSession().write(MaplePacketCreator.spawnPlayerNPC(this));
        client.getSession().write(MaplePacketCreator.getPlayerNPC(this));
    }
}
For those that don't have playernpcs on your mysql database execute this:
PHP:
--
-- Definition of table `playernpcs`
--

DROP TABLE IF EXISTS `playernpcs`;
CREATE TABLE `playernpcs` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(13) NOT NULL,
  `hair` int(11) NOT NULL,
  `face` int(11) NOT NULL,
  `skin` int(11) NOT NULL,
  `x` int(11) NOT NULL,
  `cy` int(11) NOT NULL default '0',
  `map` int(11) NOT NULL,
  `gender` int(11) NOT NULL default '0',
  `dir` int(11) NOT NULL default '0',
  `ScriptId` int(10) unsigned NOT NULL default '0',
  `Foothold` int(11) NOT NULL default '0',
  `rx0` int(11) NOT NULL default '0',
  `rx1` int(11) NOT NULL default '0',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `playernpcs`
--

/*!40000 ALTER TABLE `playernpcs` DISABLE KEYS */;
/*!40000 ALTER TABLE `playernpcs` ENABLE KEYS */;


--
-- Definition of table `playernpcs_equip`
--

DROP TABLE IF EXISTS `playernpcs_equip`;
CREATE TABLE `playernpcs_equip` (
  `id` int(11) NOT NULL auto_increment,
  `NpcId` int(11) NOT NULL default '0',
  `equipid` int(11) NOT NULL,
  `type` int(11) NOT NULL default '0',
  `equippos` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `playernpcs_equip`
--

/*!40000 ALTER TABLE `playernpcs_equip` DISABLE KEYS */;
/*!40000 ALTER TABLE `playernpcs_equip` ENABLE KEYS */;
How to add PlayerNPCs:
Code:
!playernpc [name] [9901200~9901299] 
(Ex:!playernpc Remixes 9901202)
Script ids for PlayerNPCs that are safe are 9901200~9901299, So that means you can only use those ids for playernpcs.
How to delete PlayerNPCs:
Code:
Mysql Database>[playernpcs] table>Find the ID you want to delete
How to make it wear clothes:
Code:
First way: This is easy, but there might be someone that doesn't know how.. If your making a PlayerNPC of you, then just wear the clothes you want and use the command.
Second way: If your trying to make a PlayerNPC of someone else. You have to wear the clothes and the player that your going to make as PlayerNPC will just do the hair. Then when you use the command, you and the player will be combined.

How to change the PlayerNPCs name:
Code:
Mysql Database>[playernpcs] table>Find the NPC you want to get it changed.

Script ids you can use for PlayerNPCs:
Code:
You can only use 9901200~9901299 for PlayerNPCs, other script ids are for other NPCs. As i said you can't use other script ids, because those script ids are already used for another NPC. So just know that you can use 9901200~9901299.

How to make a script for PlayerNPC:
This is extremely easy, but I'll still go ahead and teach you.
PHP:
var status;

function start() {
    status = -1;
    action(1, 0, 0);
}

function action(mode, type, selection) {
    if (mode == 1) {
        status++;
    }else{
        status--;
    }
    if (status == 0) {
This is how you start the script, but this is the type of way using (status). So for example it will be:
PHP:
var status;

function start() {
    status = -1;
    action(1, 0, 0);
}

function action(mode, type, selection) {
    if (mode == 1) {
        status++;
    }else{
        status--;
    }
    if (status == 0) {
        cm.sendNext("Go ahead and press Next so I can proceed to the next status.");
    } else if (status == 1) {
        cm.sendSimple("Would you like to see how I use status again? \r\n #L0# Yes. #l \r\n #L1# No. #l");
    } else if (status == 2) {
        if (selection == 0) {
            cm.sendOk("Here I am, in another status. As you can see from the script, this window is in status 2.");
            cm.dispose();
        } else if (selection == 1) {
            cm.sendOk("Well, sucks to be you, don't it? This window is also in status 2 :) ");
            cm.dispose();
        }
    }
}
For not using a status:
PHP:
function start() {
    cm.sendOk("I am an NPC without a status.");
    cm.dispose();
}
Another Way:
PHP:
function start() {
    cm.sendOk("Here is another example of an NPC without status.");
}

function action(mode, type, selection) {
    cm.warp(100000000, 0);
    cm.gainItem(4001126, 1);
    cm.sendOk("See? Here, I warped you and gave you an item without using status.");
    cm.dispose();
}
To learn more on how to script your own NPC
Read tutorials on how:
Learning NPCs, Start to Finish : Shawn
Learning NPC scripts(beginner guide) : get31720



Thanks for reading... And your welcome for the people that knew how to use it now ;)
If it doesn't work please post below, and if i did something wrong just post what I have made a mistake. (This will help me on elaborate this tutorial)

Credits:
Shawn for the awesome NPC tutorial
get31720 for also making a NPC tutorial
SoulFist for giving me opinions on adding how to script PlayerNPCs
Remixes(Me) for this Tutorial
Sharky for pointing out what should be added(This helped me alot)
BryantFTW for making a video, on How to make a PlayerNPC(Spawning)
You guys for reading ;)
 
Last edited by a moderator:
Re: How to use PlayerNPCs

Good job Remixes, you have a lot of "teh n00bz"

---------- Post added at 01:03 PM ---------- Previous post was at 01:02 PM ----------

Edit: You should also include how to make the script. (extremely easy) but also very essential.
 
Re: How to use PlayerNPCs

Good job Remixes, you have a lot of "teh n00bz"

---------- Post added at 01:03 PM ---------- Previous post was at 01:02 PM ----------

Edit: You should also include how to make the script. (extremely easy) but also very essential.

Thanks, I just added it now ;P
 
Re: How to use PlayerNPCs

You know there's way more to playernpc's than adding that command, right? If I were to add that command to a source now, it wouldn't do anything but give me errors in Netbeans. There's multiple methods your missing, like the method playerNPC in MapleCharacter and the methods for loading playerNPC's. Also, since this is a tutorial, which playernpc script id's are safe, which are not, why can't some of them be used, and how do I enable the unusable ones? And also, what if I want to make a playernpc of another person? These questions are mostly rhetorical, just bringing up things others might ask.
Not bad, but perhaps you should elaborate on this tutorial.
 
Last edited:
Re: How to use PlayerNPCs

You know there's way more to playernpc's than adding that command, right? If I were to add that command to a source now, it wouldn't do anything but give me errors in Netbeans. There's multiple methods your missing, like the method playerNPC in MapleCharacter and the methods for loading playerNPC's. Also, since this is a tutorial, which playernpc script id's are safe, which are not, why can't some of them be used, and how do I enable the unusable ones? And also, what if I want to make a playernpc of another person? These questions are mostly rhetorical, just bringing up things others might ask.
Not bad, but perhaps you should elaborate on this tutorial.

Thanks for pointing out somethings. I'll be adding as you said ;)

Sharky can you read it again for me and point some things again, I kinda editted things that you told me to add.
 
Last edited:
Re: How to use PlayerNPCs

Better, but your script IDs are off. I think it's more like 9901001~9901318 or so. But a lot of the script IDs in there don't work and crash the map, so that's what I was referring to when I said "unusable" IDs.
 
Re: How to use PlayerNPCs

Better, but your script IDs are off. I think it's more like 9901001~9901318 or so. But a lot of the script IDs in there don't work and crash the map, so that's what I was referring to when I said "unusable" IDs.

I think it was 9901200~9901299, anyways thanks for pointing out alot of things. =D
 
Re: How to use PlayerNPCs

Remixes I have no idea how to use this but I think your amazing. If you could direct me to a even more noob-friendly one it would be greatly appreciated.
 
Re: How to use PlayerNPCs

Are you sure that just by making a script named [PlayerNPCScriptID.js] and putting it in your NPCs folder will work? I did that and my PlayerNPC isn't saying anything, sec restarting server
 
Re: How to use PlayerNPCs

Are you sure that just by making a script named [PlayerNPCScriptID.js] and putting it in your NPCs folder will work? I did that and my PlayerNPC isn't saying anything, sec restarting server

It won't work if you do PlayerNPCScriptId.js
for ex you have to do like this: 9901288.js
Oh by the way you do have to restart your server to make it talk.
 
Re: How to use PlayerNPCs

Updated a video, made by BryantFTW(How to make a PlayerNPC)
This video is just about how to spawn the PlayerNPC.
NOTE: Those not show how to compile the command.
 
Back