NPC Generator

Joined
Aug 21, 2009
Messages
1,149
Reaction score
599
Hello there.

I just... lost another bet with Moogra, as most of the times (all of them), so, as a loser... I gotta release something to RaGEZONE, doesn't matter what.

So, this time (3th time?) I'm releasing a NPC script generator.

Let me explain what is this about.

This will generate a NPC based on the packets you obtain from sniffing the NEXON's packets, obviously, it will be in our Java base NPC scripting version, otherwise it would be pointless.

Things you gotta know, is that this code was made to work only in Snow sniffer format, as I really dislike MapleShark format, so I regularly re-format the logs from MapleShark to Snow Format, because MapleShark is actually pretty good as a sniffer. You can change this anytime, because the source is technically yours.

Another thing to know, is that it's not 100% complete, as it may not completely do ALL the NPC's scripts, it was made for basic NPC's that give or takes mesos and warp you. The rest can be easily done as well, it's not that complex. However, as it's a release, it works as expected, it may just not fulfill all your needs.

Another thing is, the code is not "pro", so feel free to critic it, I just spend actually 1 hour on this to pay my debt.

Enough talk...

EDIT:

Oh yeah, I made the file to read "RandomLog.txt", you can change it to whatever you want, or make it read a whole directory, it's up to however wants to use this.

UPDATE:

The code has been updated to work even better and fixed tons of bugs it originally had. Still, it may not always works, but the range of non-working cases have been reduced.

NPCScriptGenerator.java
PHP:
package server;

import condition.Condition;
import condition.Location;
import npc.NPCMessage;
import npc.NPC;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.codec.DecoderException;
import packet.Reader;
import player.Player;
import server.instruction.Instruction;
import server.instruction.Mesos;
import server.instruction.Warp;

/**
 *
 * @author XxOsirisxX
 */
public class NPCScriptGenerator {

    private Player player;
    private Map<Integer, NPC> npcs;
    private int npcMessageFlow;
    private int currentNpcId;
    private boolean npcTalk;
    private boolean npcMoreTalk;
    private boolean readNpc;
    private boolean readPlayer;
    private int instructionType = -1;
    private int selectedOption = -1;

    public static void main(String[] args) {
        new NPCScriptGenerator().start();
    }

    private void start() {
        initiate();
        String filename = "dkpackets.txt";
        Reader read;
        try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
            String line;
            restartAttributes();
            List<Instruction> instructions = new LinkedList<Instruction>();

            while ((line = br.readLine()) != null) {
                if (line.contains("Sent")) {
                    if (line.contains("NPC_TALK ")) {
                        npcTalk = true;
                        npcMessageFlow = 0;
                    } else if (line.contains("NPC_TALK_MORE ") && npcTalk) {
                        npcMoreTalk = true;
                    }
                    continue;
                }
                if (readPlayer) {
                    boolean playerLoggedIn = line.length() > 200;
                    read = new Reader(line);
                    read.skip(2);
                    int channel = read.readInt();
                    int mapId;
                    if (!playerLoggedIn) {
                        read.skip(5);
                        mapId = read.readInt();
                    } else {
                        read.skip(109);
                        mapId = read.readInt();
                    }
                    player = new Player();
                    player.setMapId(mapId);
                    player.setChannel(channel + 1);
                    readPlayer = false;
                }
                if (npcMoreTalk) {
                    read = new Reader(line);
                    read.skip(2);
                    byte previousMessageType = read.readByte();
                    npcTalk = read.readByte() == 1;
                    switch (previousMessageType) {
                        case 0x02: //Text
                            String textInput = read.readMapleString();
                            break;
                        case 0x03: //Numbers
                        case 0x04: //Options
                            int selection = read.readInt();
                            selectedOption = selection;
                            break;
                    }
                    npcMoreTalk = false;
                } else {
                    if (instructionType > -1) {
                        read = new Reader(line);
                        switch (instructionType) {
                            case 0x00: //WARP
                                read.skip(11);
                                int mapId = read.readInt();
                                byte spawnPoint = read.readByte();
                                Warp warp = new Warp();
                                warp.setMapId(mapId);
                                warp.setSpawnPoint(spawnPoint);
                                instructions.add(warp);
                                applyDummyConversation(instructions);
                                instructions = new LinkedList<Instruction>();
                                restartAttributes();
                                break;
                            case 0x01: //SHOW_STATUS_INFO
                                byte type = read.readByte();
                                if (type == 5) { //Mesos
                                    int amount = read.readInt();
                                    Mesos mesos = new Mesos();
                                    mesos.setAmount(amount);
                                    instructions.add(mesos);
                                } else if (type == 0) { //Inventory - Mesos Included

                                }
                                break;
                        }
                        instructionType = -1;
                        continue;
                    }
                    if (!npcTalk) {
                        if (line.contains("Received")) {
                            if (line.contains("WARP_TO_MAP ")) {
                                readPlayer = true;
                            }
                            continue;
                        }
                    }
                    if (npcTalk) {
                        if (line.contains("Received")) {
                            if (line.contains("NPC_TALK ")) {
                                readNpc = true;
                            } else if (line.contains("WARP_TO_MAP ")) {
                                instructionType = 0;
                            } else if (line.contains("SHOW_STATUS_INFO ")) {
                                instructionType = 1;
                            } else if (line.contains("OPEN_NPC_SHOP ")) {
                                restartAttributes();
                            } else if (line.contains("UPDATE_SKILLS")) {
                                restartAttributes();
                            } else if (line.contains("OPEN_STORAGE")) {
                                restartAttributes();
                            }
                            continue;
                        }

                        if (readNpc) {
                            read = new Reader(line);
                            read.skip(3);
                            int npcId = read.readInt();
                            byte messageType = read.readByte();
                            read.skip(1);
                            String message = read.readMapleString();
                            byte messageButtons = 0;
                            if (messageType == 0) {
                                messageButtons |= read.readByte() << 1; //Previous
                                messageButtons |= read.readByte(); //Next
                            }
                            currentNpcId = npcId;
                            NPC npc;
                            if (npcs.containsKey(npcId)) {
                                npc = npcs.get(npcId);
                            } else {
                                npc = new NPC(npcId);
                            }
                            npc.applyConversation(npcMessageFlow, player, messageType, message, messageButtons, selectedOption, instructions);
                            npcs.put(npcId, npc);
                            npcMessageFlow++;
                            instructions = new LinkedList<Instruction>();
                            readNpc = false;
                        }
                    }
                }
            }
            adjustCondition();
            generateScripts();
        } catch (IOException ioe) {
            System.err.println("Error while reading the file " + filename + ".");
        } catch (DecoderException de) {
            System.err.println("Error while trying to decode string in file " + filename + ".");
        }
    }
    
    private void adjustCondition() {
        for (NPC npc : npcs.values()) {
            npc.adjustConditions();
        }
    }

    private void initiate() {
        npcs = new LinkedHashMap<Integer, NPC>();
    }

    private void restartAttributes() {
        npcMessageFlow = 0;
        currentNpcId = 0;
        npcTalk = false;
        npcMoreTalk = false;
        readNpc = false;
        instructionType = -1;
        selectedOption = -1;
        readPlayer = false;
    }

    private void generateScripts() {
        for (NPC npc : npcs.values()) {
            String filename = npc.getId() + ".txt";
            try (final BufferedWriter bw = new BufferedWriter(new FileWriter(filename))) {

                StringBuilder sb = new StringBuilder();
                sb.append("status = -1;\r\n\r\n");
                sb.append("function start() {\r\n\t");
                for (int n = 0; n < npc.getMessages().get(0).size(); n++) {
                    List<Condition> conditions = npc.getMessages().get(0).get(n).getConditions();
                    int conditionSize = 0;
                    if (npc.getMessages().get(0).get(n).getConditions() != null) {
                        conditionSize = conditions.size();
                        sb.append(getScriptConditions(conditions));
                    }
                    sb.append(getScriptMessageType(npc.getMessages().get(0).get(n)));
                    for (int x = 0; x < conditionSize; x++) {
                        sb.append("\t}\r\n");
                    }
                }
                if (npc.getMessages().size() == 1) {
                    sb.append("\tcm.dispose();\r\n");
                }
                sb.append("}\r\n\r\n");
                if (npc.getMessages().size() > 1) {
                    sb.append("function action(mode, type, selection) {\r\n");
                    sb.append("\tstatus++;\r\n");
                    sb.append("\tif ((mode == 0 && type == 4) || mode == -1) {\r\n");
                    sb.append("\t\tcm.dispose();\r\n");
                    sb.append("\t\treturn;\r\n");
                    sb.append("\t}\r\n");
                    sb.append("\tif (mode == 0 && type == 0) {\r\n");
                    sb.append("\t\tstatus -= 2;\r\n");
                    sb.append("\t}\r\n");
                    for (int i = 1; i < npc.getMessages().size(); i++) {
                        if (i > 1) {
                            sb.append(" else if (status == ").append(i - 1).append(") {\r\n\t");
                        } else {
                            sb.append("\tif (status == ").append(i - 1).append(") {\r\n\t");
                        }
                        for (int n = 0; n < npc.getMessages().get(i).size(); n++) {
                            NPCMessage data = npc.getMessages().get(i).get(n);
                            if (data.getConditions() != null) {
                                sb.append(getScriptConditions(data.getConditions()));
                            }
                            sb.append(getScriptOptions(data.getSelectedOption()));
                            sb.append("\t");
                            if (data.getSelectedOption() > -1) {
                                sb.append("\t\t");
                            }
                            sb.append(getScriptInstructions(data.getInstructions()));
                            sb.append(getScriptMessageType(data));
                            if (data.getSelectedOption() > -1) {
                                sb.append("\t\t}\r\n");
                            }
                            if (data.getConditions() != null) {
                                for (int x = 0; x < data.getConditions().size(); x++) {
                                    sb.append("\t\t}\r\n");
                                }
                            }
                        }
                        sb.append("\t}");
                    }
                    sb.append("\r\n");
                    sb.append("}");
                }
                bw.append(sb);
                bw.close();
            } catch (IOException ioe) {
                System.err.println("Error while writing the file " + filename + ".");
            }
        }
    }

    private void applyDummyConversation(List<Instruction> instructions) {
        NPC npc;
        if (npcs.containsKey(currentNpcId)) {
            npc = npcs.get(currentNpcId);
        } else {
            npc = new NPC(currentNpcId);
        }
        npc.applyConversation(npcMessageFlow, player, -1, "", (byte) 0, -1, instructions);
    }

    private StringBuilder getScriptConditions(List<Condition> conditions) {
        StringBuilder ret = new StringBuilder();
        for (Condition condition : conditions) {
            if (condition instanceof Location) {
                Location location = (Location) condition;
                ret.append("\tif (cm.getMapId() == ").append(location.getMapId()).append(") {\r\n");
            }
        }
        return ret;
    }

    private StringBuilder getScriptOptions(int selectedOption) {
        StringBuilder ret = new StringBuilder();
        if (selectedOption > -1) {
            ret.append("\tif (selection == ").append(selectedOption).append(") {\r\n");
        }
        return ret;
    }

    private StringBuilder getScriptInstructions(List<Instruction> instructions) {
        StringBuilder ret = new StringBuilder();
        for (Instruction instruction : instructions) {
            if (instruction instanceof Mesos) {
                Mesos mesos = (Mesos) instruction;
                ret.append("\t\tcm.gainMesos(").append(mesos.getAmount()).append(");\r\n");
            } else if (instruction instanceof Warp) {
                Warp warp = (Warp) instruction;
                ret.append("\t\tcm.warp(").append(warp.getMapId()).append(", ").append(warp.getSpawnPoint()).append(");\r\n");
            }
            if (instruction.isDispose()) {
                ret.append("\t\tcm.dispose();\r\n");
            }
        }
        return ret;
    }

    private StringBuilder getScriptMessageType(NPCMessage message) {
        StringBuilder ret = new StringBuilder();
        switch (message.getMessageType()) {
            case 0x00: //Next | Prev | OK
                switch (message.getMessageButtons()) {
                    case 0x00: //OK
                        ret.append("cm.sendOk(\"").append(message.getMessage()).append("\");\r\n");
                        break;
                    case 0x01: //Next
                        ret.append("cm.sendNext(\"").append(message.getMessage()).append("\");\r\n");
                        break;
                    case 0x02: //Previous
                        ret.append("cm.sendPrev(\"").append(message.getMessage()).append("\");\r\n");
                        break;
                    case 0x03: //Next | Previous
                        ret.append("cm.sendNextPrev(\"").append(message.getMessage()).append("\");\r\n");
                        break;
                }
                break;
            case 0x01: //Yes | No
                ret.append("cm.sendYesNo(\"").append(message.getMessage()).append("\");\r\n");
                break;
            case 0x02: //Text
                ret.append("cm.sendGetText(\"").append(message.getMessage()).append("\");\r\n");
                break;
            case 0x03: //Numbers
                ret.append("cm.sendGetNumber(\"").append(message.getMessage()).append("\");\r\n");
                break;
            case 0x04: //Options
                ret.append("cm.sendSimple(\"").append(message.getMessage()).append("\");\r\n");
                break;
            case 0x07: //Style
                ret.append("cm.sendStyle(\"").append(message.getMessage()).append("\");\r\n");
                break;
            case 0x0C: //Accept | Decline
                ret.append("cm.sendAcceptDecline(\"").append(message.getMessage()).append("\");\r\n");
                break;
            case 0x0E: //Locations
                ret.append("cm.sendPlaces();\r\n");
                break;
        }
        return ret;
    }
}

NPC.java

PHP:
package npc;

import condition.Condition;
import condition.Location;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import player.Player;
import server.instruction.Instruction;

/**
 *
 * @author XxOsirisxX
 */
public class NPC {

    private static int messageChainId = 0;
    private final int id;
    private Map<Integer, List<NPCMessage>> messages;

    public NPC(int id) {
        this.id = id;
    }

    public void applyConversation(int flow, Player player, int messageType, String message, byte messageButtons, int selectedOption, List<Instruction> instructions) {
        if (messages == null) {
            messages = new LinkedHashMap<Integer, List<NPCMessage>>();
        }
        if (flow == 0) {
            messageChainId++;
        }
        NPCMessage newMessage = new NPCMessage(messageChainId, player, messageType, message, messageButtons, selectedOption, instructions, null);
        List<NPCMessage> actualMessages = new LinkedList<NPCMessage>();
        if (messages.get(flow) != null) {
            boolean repeated = false;
            for (NPCMessage m : messages.get(flow)) {
                if (m.getMessage().equals(newMessage.getMessage())) {
                    repeated = true;
                    break;
                }
            }
            if (repeated) {
                return;
            }

            actualMessages = messages.get(flow);
            byte conditionType = 0;
            for (int i = 0; i < messages.get(flow).size(); i++) {
                List<Condition> oldCondition;
                NPCMessage storedMessage = messages.get(flow).get(i);
                if (storedMessage.getConditions() != null) {
                    oldCondition = storedMessage.getConditions();
                } else {
                    oldCondition = new LinkedList<Condition>();
                }
                if (storedMessage.getPlayer().getMapId() != player.getMapId()) {
                    conditionType |= 1;
                    boolean repeatedCondition = false;
                    if (storedMessage.getConditions() != null) {
                        for (Condition c : storedMessage.getConditions()) {
                            if (c instanceof Location) {
                                repeatedCondition = true;
                                break;
                            }
                        }
                    }
                    if (repeatedCondition) {
                        continue;
                    }
                    Location location = new Location();
                    location.setMapId(storedMessage.getPlayer().getMapId());
                    oldCondition.add(location);
                    storedMessage.setConditions(oldCondition);
                }
            }
            List<Condition> newCondition = new LinkedList<Condition>();
            if ((conditionType & 0x01) == 0x01) {
                Location location = new Location();
                location.setMapId(player.getMapId());
                newCondition.add(location);
                newMessage.setConditions(newCondition);
            }
        }
        actualMessages.add(newMessage);
        messages.put(flow, actualMessages);
    }

    public void adjustConditions() {
        for (Entry allMessages : messages.entrySet()) {
            List<NPCMessage> npcMessages = (List<NPCMessage>) allMessages.getValue();
            List<NPCMessage> npcMessages2 = (List<NPCMessage>) allMessages.getValue();
            for (NPCMessage message : npcMessages) {
                if (message.getConditions() != null) {
                    int uniqueId = 0;
                    Condition locationCondition = null;
                    for (Condition conditions : message.getConditions()) {
                        if (conditions instanceof Location) {
                            uniqueId = message.getMessageChainId();
                            locationCondition = conditions;
                        }
                    }
                    if (uniqueId > 0) {

                        for (List<NPCMessage> msg : messages.values()) {
                            for (NPCMessage messagex : msg) {
                                if (messagex.getMessageChainId() == uniqueId) {
                                    if (messagex.getConditions() == null) {
                                        messagex.setConditions(message.getConditions());
                                    } else {
                                        List<Condition> conditions = messagex.getConditions();
                                        boolean ignore = false;
                                        for (Condition all : conditions) {
                                            if (all instanceof Location) {
                                                ignore = true;
                                                break;
                                            }
                                        }
                                        if (ignore) {
                                            continue;
                                        }
                                        conditions.add(locationCondition);
                                        messagex.setConditions(conditions);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public int getId() {
        return id;
    }

    public Map<Integer, List<NPCMessage>> getMessages() {
        return messages;
    }

}

NPCMessage.java

PHP:
package npc;

import condition.Condition;
import java.util.List;
import player.Player;
import server.instruction.Instruction;

/**
 *
 * @author XxOsirisxX
 */
public class NPCMessage {
    
    private int messageChainId;
    private int messageType;
    private int selectedOption;
    private byte messageButtons;
    private String message;
    private List<Instruction> instructions;
    private List<Condition> conditions;
    private Player player;
    
    public NPCMessage(int messageChainId, Player player, int messageType, String message, byte messageButtons, int selectedOption, List<Instruction> instructions, List<Condition> conditions) {
        this.messageChainId = messageChainId;
        this.player = player;
        this.messageType = messageType;
        this.message = message;
        this.messageButtons = messageButtons;
        this.instructions = instructions;
        this.selectedOption = selectedOption;
        this.conditions = conditions;
    }

    public Player getPlayer() {
        return player;
    }

    public void setPlayer(Player player) {
        this.player = player;
    }

    public int getMessageType() {
        return messageType;
    }

    public void setMessageType(int messageType) {
        this.messageType = messageType;
    }

    public byte getMessageButtons() {
        return messageButtons;
    }

    public void setMessageButtons(byte messageButtons) {
        this.messageButtons = messageButtons;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getSelectedOption() {
        return selectedOption;
    }

    public void setSelectedOption(int selectedOption) {
        this.selectedOption = selectedOption;
    }

    public List<Instruction> getInstructions() {
        return instructions;
    }

    public void setInstructions(List<Instruction> instructions) {
        this.instructions = instructions;
    }

    public List<Condition> getConditions() {
        return conditions;
    }

    public void setConditions(List<Condition> conditions) {
        this.conditions = conditions;
    }

    public int getMessageChainId() {
        return messageChainId;
    }

    public void setMessageChainId(int messageChainId) {
        this.messageChainId = messageChainId;
    }
    
}

Instruction.java
PHP:
package server.instruction;

/**
 *
 * @author XxOsirisxX
 */
public abstract class Instruction {
    
    private boolean dispose;
    
    public Instruction(boolean dispose) {
        this.dispose = dispose;
    }

    public boolean isDispose() {
        return dispose;
    }
    
}

Mesos.java

PHP:
package server.instruction;

/**
 *
 * @author XxOsirisxX
 */
public class Mesos extends Instruction {
    
    private int amount;
    
    public Mesos() {
        super(false);
    }

    public int getAmount() {
        return amount;
    }

    public void setAmount(int amount) {
        this.amount = amount;
    }
   
}

Warp.java
PHP:
package server.instruction;

/**
 *
 * @author XxOsirisxX
 */
public class Warp extends Instruction {
    
    private int mapId;
    private short spawnPoint;
    
    public Warp() {
        super(true);
    }

    public int getMapId() {
        return mapId;
    }

    public void setMapId(int mapId) {
        this.mapId = mapId;
    }

    public short getSpawnPoint() {
        return spawnPoint;
    }

    public void setSpawnPoint(short spawnPoint) {
        this.spawnPoint = spawnPoint;
    }
}

Player.java

PHP:
package player;

/**
 *
 * @author XxOsirisxX
 */
public class Player {
    
    private int channel;
    private int mapId;

    public int getMapId() {
        return mapId;
    }

    public void setMapId(int mapId) {
        this.mapId = mapId;
    }

    public int getChannel() {
        return channel;
    }

    public void setChannel(int channel) {
        this.channel = channel;
    }

}

Reader.java

PHP:
package packet;

import java.io.UnsupportedEncodingException;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

/**
 *
 * @author XxOsirisxX
 */
public class Reader {
    
    private StringBuilder packetString;
    
    public Reader(String packetString) {
        this.packetString = new StringBuilder(packetString.replace(" ", ""));
    }
    
    public byte readByte() {
        return Byte.parseByte(readString(0, 2), 16);
    }
    
    public short readShort() {
        return Short.parseShort(readString(2, 4) + readString(0, 2), 16);
    }
    
    public int readInt() {
        return (int) Long.parseLong(readString(6, 8) + readString(4, 6) + readString(2, 4) + readString(0, 2), 16);
    }
    
    public long readLong() {
        return Long.parseLong(readString(14, 16) + readString(12, 14) + readString(10, 12) + readString(8, 10) + readString(6, 8) + readString(4, 6) + readString(2, 4) + readString(0, 2), 16);
    }
    
    public String readMapleString() throws DecoderException, UnsupportedEncodingException {
        short messageLenght = readShort();
        return new String(Hex.decodeHex(readString(0, messageLenght * 2).toCharArray()), "UTF8");
    }
    
    public void skip(int pairs) {
        readString(0, pairs * 2);
    }
    
    private String readString(int start, int end) {
        String data = packetString.substring(start, end);
        packetString = packetString.delete(start, end);
        return data;
    }
}

Character.java

PHP:
package condition;

/**
 *
 * @author XxOsirisxX
 */
public class Character extends Condition {
    
    private int level;
    private int mesos;

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public int getMesos() {
        return mesos;
    }

    public void setMesos(int mesos) {
        this.mesos = mesos;
    }
    
    
}

Condition.java

PHP:
package condition;

/**
 *
 * @author XxOsirisxX
 */
public abstract class Condition {
    
    
}

Location.java

PHP:
package condition;

/**
 *
 * @author XxOsirisxX
 */
public class Location extends Condition {
    
    private int mapId;
    private short xposition;
    private short yposition;

    public int getMapId() {
        return mapId;
    }

    public void setMapId(int mapId) {
        this.mapId = mapId;
    }

    public short getXposition() {
        return xposition;
    }

    public void setXposition(short xposition) {
        this.xposition = xposition;
    }

    public short getYposition() {
        return yposition;
    }

    public void setYposition(short yposition) {
        this.yposition = yposition;
    }
    
}

Screenshot
XxОsirisxX - NPC Generator - RaGEZONE Forums
 
Last edited:
The code has been updated, has the original post state.

I know this probably won't be used at all :3, but just wanted to make it clear once again...

There are cases this may not work as expected, due to SO MUCH validations that may not has been taken in consideration, and mostly also because I don't even have GMS, I'm doing this from my old sniff logs, which I'm pretty sure things hasn't changed much since then...

I added something I called as "Condition" to make conditionals for the NPC, such as "cm.getMesos() > x" and these kinds of checks, currently, it's only working for map location, as an NPC can appear in different maps, however, I made the class for these checks already.

Oh yeah, reason for the progress, is that I lost again a bet against Moogra...
 
The code has been updated, has the original post state.

I know this probably won't be used at all :3, but just wanted to make it clear once again...

There are cases this may not work as expected, due to SO MUCH validations that may not has been taken in consideration, and mostly also because I don't even have GMS, I'm doing this from my old sniff logs, which I'm pretty sure things hasn't changed much since then...

I added something I called as "Condition" to make conditionals for the NPC, such as "cm.getMesos() > x" and these kinds of checks, currently, it's only working for map location, as an NPC can appear in different maps, however, I made the class for these checks already.

Oh yeah, reason for the progress, is that I lost again a bet against Moogra...
I can see this being used by those who want to make a "GMS-like" npcs. This makes it easier to those who don't want to type all that stuff up.
 
Damn man, haven't been on RageZone since '11. Thought this was already released or something.

Good work though, looks clean!. Thanks for sharing.
 
Actually it's the 6th time you released something! Good release though, as this is pretty cool. Let's go play again :P

Why an abstract class with no abstract methods though?
 
Actually it's the 6th time you released something! Good release though, as this is pretty cool. Let's go play again :P

Why an abstract class with no abstract methods though?

One day, I actually went through 200 pages of post and acquired all the releases. Tic Tac Toe NPC, a few others, and now this. I think 6 is correct. You guys amuse me with the bets, leaving me to ask what you two always bet on? Sports? Very useful release, it will certainly help the progress of shootsource fork I've been working on for a few months! Somewhat excited to show you both.
 
It's java, why would you compile it in visual studio? Compile with your java ide
sunnyboy

I compiled with netbeans and got a .jar file and wrapped it into an exe. When I run it though I get error:

caused by: java.lang.classnotfoundexception: org.apache.commons.codec.decoderexception

Even though I downloaded the file and added it into the library and have no error when compiling.
 
Last edited:
Back