Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Custom Quest System v2.0

Initiate Mage
Joined
Mar 31, 2016
Messages
1
Reaction score
0
Custom Quest System v2.0

Introduction:
Well, I already made such a system a few years ago:
http://forum.ragezone.com/f427/custom-quest-system-v1-6-a-797167/
But it was very limited and not comparable to a real quest system.

This one should be closer to it.

I like questing and I liked custom maple servers. Sadly back then (dunno
about today) I didn't ever found both.
I'm pretty sure custom quests would improve the overall gameplay if used
correctly​

Offtopic:
Can't just update the old thread, as I wasn't around ragezone for long and
forgot my pw. So releasing this on a new account.

I was new to 'programming' back then and still am, have mercy :blush:​


Ontopic:
A quest includes hunting mobs and/or collecting items. You are free to add as
many different mobs/items to a quest as you want.
Characters can work on multiple quests at a time.
NPCs can offer a list of multiple quests at a time as well.​


New class MapleCQuest
PHP:
package client;


import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import tools.DatabaseConnection;
import java.util.ArrayList;
import java.util.List;
import tools.Pair;




public class MapleCQuest {


    private int id;
    private String name;
    private int npcId;
    private int mesoReward;
    private int expReward;
    
    private ArrayList<Integer> itemReward = new ArrayList<>();
    private ArrayList<Integer> irAmount = new ArrayList<>();
    private ArrayList<Integer> mobId = new ArrayList<>();
    private ArrayList<Integer> mobGoal = new ArrayList<>();
    private ArrayList<Integer> itemId = new ArrayList<>();
    private ArrayList<Integer> itemGoal = new ArrayList<>();
    
    public MapleCQuest(int id) {
        this.id = id;
    }    
    
    public void loadDataById(int qid) {
        try {
            PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT * FROM cquestdata1 WHERE questid = ?");
            ps.setInt(1, qid);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                id = qid;
                name = rs.getString("name");
                npcId = rs.getInt("npcid");
                mesoReward = rs.getInt("mesoreward");
                expReward = rs.getInt("expreward");        
            }
            rs.close();
            ps.close();
            ps = DatabaseConnection.getConnection().prepareStatement("SELECT * FROM cquestdata2 WHERE questid = ?");
            ps.setInt(1, qid);
            rs = ps.executeQuery();
            while (rs.next()) {
                if (rs.getInt("itemreward") != 0) {
                    itemReward.add(rs.getInt("itemreward"));
                }
                if (rs.getInt("iramount") != 0) {
                    irAmount.add(rs.getInt("iramount"));
                }
                if (rs.getInt("mobid") != 0) {
                    mobId.add(rs.getInt("mobid"));
                }
                if (rs.getInt("mobgoal") != 0) {
                    mobGoal.add(rs.getInt("mobgoal"));
                }
                if (rs.getInt("itemid") != 0) {
                    itemId.add(rs.getInt("itemid"));
                }
                if (rs.getInt("itemgoal") != 0) {
                    itemGoal.add(rs.getInt("itemgoal"));
                }
            }
            rs.close();
            ps.close();
            
        } catch (SQLException se) {
            System.out.println(se);
        }
    }
    
    public void loadData() {
        loadDataById(this.id);
    }
    
    public List<Pair<Integer, String>> getNames(List questIDs) {
        List<Pair<Integer, String>> pairs = new ArrayList<>();
        StringBuilder sb = new StringBuilder();
        sb.append("SELECT name,questid FROM cquestdata1 WHERE");
        for (int x = 0; x < questIDs.size(); x++) {
            sb.append(" questid =").append(" " + questIDs.get(x));
            if (x != (questIDs.size() - 1)) {
                sb.append(" OR");
            }
        }


        try {
            PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement(sb.toString());
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                pairs.add(new Pair<>(rs.getInt("questid"), rs.getString("name")));
            }
            rs.close();
            ps.close();
        } catch (SQLException se) {
            System.out.println(se);
        } 
        
        return pairs;
    }
    
    public int getId() {
        return id;
    }
    
    public String getName() {
        return name;
    }
    
    public int getNpcId() {
        return npcId;
    }
    
    public int getMesoReward() {
        return mesoReward;
    }
    
    public int getExpReward() {
        return expReward;
    }


    public ArrayList<Integer> getItemRewardList() {
        return itemReward;
    }
    
    public ArrayList<Integer> getRewardAmountList() {
        return irAmount;
    }
    
    public ArrayList<Integer> getMobList() {
        return mobId;
    }
    
    public ArrayList<Integer> getMobGoalList() {
        return mobGoal;
    }
    
    public ArrayList<Integer> getItemCollectList() {
        return itemId;
    }
    
    public ArrayList<Integer> getItemGoalList() {
        return itemGoal;
    }
    


}


Add to MapleCharacter
PHP:
    private ArrayList<Integer> acceptedQuests = new ArrayList<>();
    private ArrayList<Integer> itemsToCollect = new ArrayList<>();
    private ArrayList<Integer> itemsAmount = new ArrayList<>();
    private ArrayList<Integer> itemsGoal = new ArrayList<>();
    private ArrayList<Integer> mobsToKill = new ArrayList<>();
    private ArrayList<Integer> mobsAmount = new ArrayList<>();
    private ArrayList<Integer> mobsProgress = new ArrayList<>();
    private ArrayList<Integer> mobsGoal = new ArrayList<>();
    private ArrayList<Integer> finishedQuests = new ArrayList<>();

    
    public ArrayList<Integer> getAcceptedQuests() {
        return acceptedQuests;
    }
    
    public ArrayList<Integer> getItemsToCollect() {
        return itemsToCollect;
    }
    
    public ArrayList<Integer> getItemsGoal() {
        return itemsGoal;
    }
    
    public ArrayList<Integer> getItemsAmount() {
        return itemsAmount;
    }
    
    public ArrayList<Integer> getMobsToKill() {
        return mobsToKill;
    }
    
    public ArrayList<Integer> getMobsProgress() {
        return mobsProgress;
    }
    
    public ArrayList<Integer> getMobsAmount() {
        return mobsAmount;
    }
    
    public ArrayList<Integer> getMobsGoal() {
        return mobsGoal;
    }
    
    public ArrayList<Integer> getFinishedQuests() {
        return finishedQuests;
    }


    public boolean hasFinished(int questId) {
        return finishedQuests.contains(questId);
    }
    
    public void startQuest(int questId, boolean loadFromDb, MapleCharacter chr) {
        MapleCQuest quest = new MapleCQuest(questId);
        quest.loadData();
        chr.itemsAmount.add(quest.getItemCollectList().size());
        chr.itemsToCollect.add(questId);
        chr.itemsToCollect.addAll(quest.getItemCollectList());
        chr.itemsGoal.add(questId);
        chr.itemsGoal.addAll(quest.getItemGoalList());
        chr.mobsAmount.add(quest.getMobList().size());
        
        if (!loadFromDb) {    
            chr.acceptedQuests.add(questId);
            chr.mobsToKill.add(questId);
            chr.mobsToKill.addAll(quest.getMobList());
            chr.mobsProgress.add(questId);
            chr.mobsGoal.add(questId);
            chr.mobsGoal.addAll(quest.getMobGoalList());
            for (int helicopterpenis = 0; helicopterpenis < quest.getMobList().size(); helicopterpenis++) {
                chr.mobsProgress.add(0);
            }
        }
    }
    
    public void startQuest(int questId) {
        startQuest(questId, false, client.getPlayer());
    }
    
    public void finishQuest(int questId, boolean cancelQuest) {
        int index = acceptedQuests.indexOf(questId);
        acceptedQuests.remove(index);
        int mobindex = (int) mobsToKill.indexOf(questId);
        int itemindex = (int) itemsToCollect.indexOf(questId);
        int mobremove = (int) mobsAmount.get(index) + 1;
        int itemremove = (int) itemsAmount.get(index) + 1;
        mobsAmount.remove(index);
        itemsAmount.remove(index);
        for (int x = 0; x < mobremove; x++) {
            mobsToKill.remove(mobindex);
            mobsProgress.remove(mobindex);
            mobsGoal.remove(mobindex);
        }


        for (int x = 0; x < itemremove; x++) {
            itemsToCollect.remove(itemindex);
            itemsGoal.remove(itemindex);
        }
        if (!hasFinished(questId) && !cancelQuest) { // repeatable quests?
            finishedQuests.add(questId);
        }
    }
    
    public void cancelQuest(int questId) {
        finishQuest(questId, true);
    }
    
    public void addProgressByQuest(int questId, int mobId, int addProgress) {
        int index = acceptedQuests.indexOf(questId);
        int toCheck = (int) mobsAmount.get(index);
        int mobIndex = mobsToKill.indexOf(questId);
        for (int x = 1; x < (toCheck + 1); x++) {
            int idFromList = (int) mobsToKill.get((mobIndex + x));
            if (idFromList == mobId) {
                int progress = (int) mobsProgress.get((mobIndex + x));
                mobsProgress.set((mobIndex + x), (progress + addProgress));
            }
        }
    }    
    
    public void addMobProgress(int mobId, int addProgress) {
        ArrayList<Integer> tempList = new ArrayList<>();
        tempList.addAll(mobsToKill);
        while (tempList.contains(mobId)) {
            int index = tempList.indexOf(mobId);
            tempList.set(index, 0);
            int progress = (int) mobsProgress.get(index);
            mobsProgress.set(index, (progress + addProgress));
        }        
    }
    
    public void addMobProgress(int mobId) {
        addMobProgress(mobId, 1);
    }
        
    public boolean compareProgressWithGoal(int questId, int type) {
        int index = acceptedQuests.indexOf(questId);
        int toCheck = 0;
        int index2 = 1;
        int equalsGoal = 0;
        switch (type) {
            case 0:
                toCheck = (int) mobsAmount.get(index);
                if (toCheck > 0) {
                    index2 += mobsProgress.indexOf(questId);
                    for (int x = 0; x < toCheck; x++) {
                        int progress = (int) mobsProgress.get((index2 + x));
                        int goal = (int) mobsGoal.get((index2 + x));
                        if (progress >= goal) {
                            equalsGoal++;
                        }
                    }
                }
                break;
            case 1:
                toCheck = (int) itemsAmount.get(index);
                if (toCheck > 0) {    
                    index2 += itemsToCollect.indexOf(questId);
                    for (int x = 0; x < toCheck; x++) {
                        int progress = getItemQuantity((int) itemsToCollect.get((index2 + x)));
                        int goal = (int) itemsGoal.get((index2 + x));
                        if (progress >= goal) {
                            equalsGoal++;
                        }
                    }
                }
                break;
        }
        if (equalsGoal >= toCheck) {
            return true;
        }
        return false;
    }
    
    public boolean compareMobPWG(int questId) {
        return compareProgressWithGoal(questId, 0);
    }
    
    public boolean compareItemPWG(int questId) {
        return compareProgressWithGoal(questId, 1);
    }
    
    public static void loadQuestData(MapleCharacter chr) {        
        try {
            PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("SELECT * FROM cqueststatus WHERE charid = ? ORDER BY questid");
            ps.setInt(1, chr.id);
            ResultSet rs = ps.executeQuery();
            while (rs.next()) {
                if (rs.getInt("status") == 0) {
                    chr.acceptedQuests.add(rs.getInt("questid"));
                } else {
                    chr.finishedQuests.add(rs.getInt("questid"));
                }
            }
            rs.close();
            ps.close();
            ps = DatabaseConnection.getConnection().prepareStatement("SELECT questid,mobid,progress,goal FROM cquestprogress WHERE charid = ? ORDER BY questid");
            ps.setInt(1, chr.id);
            rs = ps.executeQuery();
            while (rs.next()) {
                if(!chr.mobsToKill.contains(rs.getInt("questid"))) {
                    chr.mobsToKill.add(rs.getInt("questid"));
                }
                chr.mobsToKill.add(rs.getInt("mobid"));
                if (!chr.mobsGoal.contains(rs.getInt("questid"))) {
                    chr.mobsGoal.add(rs.getInt("questid"));
                }
                chr.mobsGoal.add(rs.getInt("goal"));
                if (!chr.mobsProgress.contains(rs.getInt("questid"))) {
                    chr.mobsProgress.add(rs.getInt("questid"));
                }
                chr.mobsProgress.add(rs.getInt("progress"));
            }
            rs.close();    
            ps.close();
        } catch (SQLException se) {
            System.out.println(se);
        }
        
        for (int x = 0; x < chr.acceptedQuests.size(); x++) {
            int questId = (int) chr.acceptedQuests.get(x);
            chr.startQuest(questId, true, chr);
        }
    }
    
    public void saveQuestDataToDb() {
        try {
            PreparedStatement ps = DatabaseConnection.getConnection().prepareStatement("DELETE FROM cquestprogress WHERE charid = ?");
            ps.setInt(1, this.id);
            ps.executeUpdate();
            ps = DatabaseConnection.getConnection().prepareStatement("INSERT INTO cquestprogress (`charid`, `questid`, `mobid`, `progress`, `goal`) VALUES (?, ?, ?, ?, ?)");
            ps.setInt(1, this.id);
            int questId = 0;
            for (int x = 0; x < mobsProgress.size(); x++) {
                if (acceptedQuests.contains(mobsProgress.get(x))) {
                    questId = (int) mobsProgress.get(x);
                } else {
                    ps.setInt(2, questId);
                    ps.setInt(3, (int) mobsToKill.get(x));
                    ps.setInt(4, (int) mobsProgress.get(x));
                    ps.setInt(5, (int) mobsGoal.get(x));
                    ps.addBatch();
                }
            }
            ps.executeBatch();
            ps = DatabaseConnection.getConnection().prepareStatement("DELETE FROM cqueststatus WHERE charid = ?");
            ps.setInt(1, this.id);
            ps.executeUpdate();
            ps = DatabaseConnection.getConnection().prepareStatement("INSERT INTO cqueststatus (`charid`, `questid`, `status`) VALUES (?, ?, ?)");
            ps.setInt(1, this.id);
            for (int x = 0; x < acceptedQuests.size(); x++) {
                ps.setInt(2, (int) acceptedQuests.get(x));
                ps.setInt(3, 0);
                ps.addBatch();
            }
            for (int x = 0; x < finishedQuests.size(); x++) {
                ps.setInt(2, (int) finishedQuests.get(x));
                ps.setInt(3, 1);
                ps.addBatch();
            }
            ps.executeBatch();
            ps.close();
        } catch (SQLException se) {
            System.out.println(se);
        }
    }



Add to NPCConversationManager
PHP:
        private MapleCQuest quest = new MapleCQuest(0);    private ArrayList<Integer> avq = new ArrayList<>(); // available quests



    private boolean isType(int itemId, ItemType type) {
        return ItemType.getItemType(itemId).equals(type);
    }
    
    public void loadQuestData(int questId) {
        quest = new MapleCQuest(questId);
        quest.loadData();        
    }


    public void startCQuest(int questId) {
        getPlayer().startQuest(questId);
    }
    
    public void cancelCQuest(int questId) {
        getPlayer().cancelQuest(questId);
    }
    
    public void finishCQuest(int questId) {
        getPlayer().finishQuest(questId, false);
    }
    
    public boolean inProgress(int questId) {
        return getPlayer().getAcceptedQuests().contains(questId);
    }
    
    public boolean reqToFinish(int questId) {
        return (getPlayer().compareMobPWG(questId) && getPlayer().compareItemPWG(questId));
    }
    
    public void addToAVQ(int questId) {
        avq.add(questId);
    }
    
    public ArrayList<Integer> getAVQ() {
        return avq;
    }
    
    public boolean noAvailableQuest(List avQuests) {
        return getPlayer().getAcceptedQuests().containsAll(avQuests);
    }
    
    public void showAvailableQuests(String msg, List avQuests) { 
        quest = new MapleCQuest(0);
        StringBuilder sb = new StringBuilder();
        String avIcon = "#fUI/UIWindow.img/QuestIcon/3/0#";
        
        sb.append(msg).append("\r\n\r\n").append(avIcon).append("\r\n\r\n");
        
        for (int x = 0; x < avQuests.size(); x++) {
            if (!getPlayer().hasFinished((int) avQuests.get(x))) {
                boolean inProg = getPlayer().getAcceptedQuests().contains((int) avQuests.get(x));
                String avOrProg = "#e[" + (inProg ? "#dIn Prog." : "#rAvailable") + "#k]#n";
                
                Pair<Integer, String> idName = quest.getNames(avQuests).get(x);
                sb.append("#L").append(idName.getLeft()).append("#"); //selection id
                sb.append(avOrProg).append(" ").append(idName.getRight()).append("#l");
                sb.append("\r\n");
            }
        }
        
        sendSimple(sb.toString());
    }
    
    public void rewardPlayer() {
        gainMeso(quest.getMesoReward());
        gainExp(quest.getExpReward());
        for (int x = 0; x < quest.getItemRewardList().size(); x++) {
            int amount = quest.getRewardAmountList().get(x);
            gainItem((int) quest.getItemRewardList().get(x), (short) amount);
        }
    }
    
    public void rewardInfo(String msg) {
        StringBuilder sb = new StringBuilder();
        
        String rewardIcon = "#fUI/UIWindow.img/QuestIcon/4/0#";
        String expIcon = "#fUI/UIWindow.img/QuestIcon/8/0#";
        String mesoIcon = "#fUI/UIWindow.img/QuestIcon/7/0#";
        int rExp = quest.getExpReward();
        int rMeso = quest.getMesoReward();
        ArrayList<Integer> rItem = quest.getItemRewardList();
        ArrayList<Integer> rAmount = quest.getRewardAmountList();
        
        sb.append(msg).append("\r\n\r\n");
        sb.append(rewardIcon).append("\r\n\r\n");
        if (rExp > 0) {
            sb.append(expIcon).append(rExp).append("\r\n");
        }
        if (rMeso > 0) {
            sb.append(mesoIcon).append(rMeso).append("\r\n");
        }
        sb.append("\r\n");
        
        for (int x = 0; x < rItem.size(); x++) {
            int item = (int) rItem.get(x);
            String itemIcon = "#i" + item + "#";
            String itemName = "#t" + item + "#";
            sb.append(itemIcon).append(itemName).append(" x").append(rAmount.get(x)).append("\r\n");
            
        }
        
        sendOk(sb.toString());
    }
    
    public void pqaSelection() {
        StringBuilder sb = new StringBuilder();
        sb.append("Hi I'm your Personal Quest Assistant!").append("\r\n");
        sb.append("How can I help you?").append("\r\n\r\n").append("#b");
        sb.append("#L0#").append("Show me all ongoing quests").append("#l").append("\r\n");
        sb.append("#L1#").append("Show me all my completed quests").append("#l").append("\r\n");
        sendSimple(sb.toString());
    } 
    
    public void pqaFinished() {
        StringBuilder sb = new StringBuilder();
        if (!getPlayer().getFinishedQuests().isEmpty()) {
            sb.append("Of course. Here is a list of quests you have completed:").append("\r\n\r\n").append("#b");
            for (Pair<Integer, String> qPair : quest.getNames(getPlayer().getFinishedQuests())) {
                sb.append("[ ").append(qPair.getRight()).append(" ]").append("\r\n");
            }
            sb.append("\r\n").append("#k").append("You have completed a total of ").append("#b");
            sb.append(getPlayer().getFinishedQuests().size()).append("#k").append(" quests! Good job.");
        } else {
            sb.append("Sorry, you have not completed any quests so far. :(");
        }
        sendPrev(sb.toString());
    }
    
    public void pqaInProgress() { //selection is questid
        StringBuilder sb = new StringBuilder();
        if (!getPlayer().getAcceptedQuests().isEmpty()) {
            sb.append("Of course. Here is a list of quests you are working on right now:").append("\r\n\r\n").append("#b");
            for (Pair<Integer, String> qPair : quest.getNames(getPlayer().getAcceptedQuests())) {
                sb.append("#L").append(qPair.getLeft()).append("#").append(qPair.getRight()).append("#l").append("\r\n");
            }
            sendSimple(sb.toString());
        } else {
            sb.append("There are no quests in your journal yet!");
            sendPrev(sb.toString());
        }
    }
    
    public void pqaQuestInfo(int selection) {
        MapleCQuest cq = new MapleCQuest(selection);
        MapleCharacter p = getPlayer();
        cq.loadData();
        StringBuilder sb = new StringBuilder();
        int index1 = p.getAcceptedQuests().indexOf(selection);
        int mIndex = p.getMobsToKill().indexOf(selection) + 1;
        int iIndex = p.getItemsToCollect().indexOf(selection) + 1;
        int toDisplayMob = (int) p.getMobsAmount().get(index1);
        int toDisplayItem = (int) p.getItemsAmount().get(index1);


        sb.append("Here's your requested information").append("\r\n\r\n");
        sb.append("#e").append(cq.getName()).append("#n").append("\r\n\r\n");
        sb.append("Progress:").append("\r\n\r\n");
        
        for (int x = 0; x < toDisplayMob; x++) {
            int mob = (int) p.getMobsToKill().get(mIndex + x);
            String mName = "#o" + mob + "#";//getMobName(mob);
            int progress = (int) p.getMobsProgress().get(mIndex + x);
            int goal = (int) p.getMobsGoal().get(mIndex + x);
            
            String color = "#r";
            if (progress >= (goal * 2 / 3) && progress < goal) {
                color = "#d"; //would like to know if there's orange instead
            } else if (progress >= goal) {
                color = "#g";
            }
            
            sb.append(mName).append(": ").append(color).append(progress).append("#k").append(" / ").append(goal);
            sb.append("\r\n");    
        }
        if (toDisplayMob > 0) {
            sb.append("\r\n");
        }
        
        for (int x = 0; x < toDisplayItem; x++) {
            int item = (int) p.getItemsToCollect().get(iIndex + x);
            String iName = "#t" + item + "#";//getItemName(item);
            int progress = itemQuantity(item);
            int goal = (int) p.getItemsGoal().get(iIndex + x);
            
            String color = "#r";
            if (progress >= (goal * 2 / 3) && progress < goal) {
                color = "#d";
            } else if (progress >= goal) {
                color = "#g";
            }
            
            sb.append(iName).append(": ").append(color).append(progress).append("#k").append(" / ").append(goal);
            sb.append("\r\n");
        }
        sendPrev(sb.toString());
    }


Execute this
PHP:
DROP TABLE IF EXISTS `cqueststatus`;
DROP TABLE IF EXISTS `cquestprogress`;
DROP TABLE IF EXISTS `cquestdata1`;
DROP TABLE IF EXISTS `cquestdata2`;


CREATE TABLE IF NOT EXISTS `cqueststatus` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `charid` int(11) NOT NULL DEFAULT '0',
  `questid` int(11) NOT NULL DEFAULT '0',
  `status` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;


CREATE TABLE IF NOT EXISTS `cquestprogress` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `charid` int(11) NOT NULL DEFAULT '0',
  `questid` int(11) NOT NULL DEFAULT '0',
  `mobid` int(11) NOT NULL DEFAULT '0',
  `progress` int(11) NOT NULL DEFAULT '0',
  `goal` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;


CREATE TABLE IF NOT EXISTS `cquestdata1` (
  `questid` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(13) NOT NULL DEFAULT '',
  `npcid` int(11) NOT NULL DEFAULT '0',
  `mesoreward` int(11) NOT NULL DEFAULT '0',
  `expreward` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`questid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1000;


CREATE TABLE IF NOT EXISTS `cquestdata2` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `questid` int(11) NOT NULL DEFAULT '0',
  `itemreward` int(11) NOT NULL DEFAULT '0',
  `iramount` int(11) NOT NULL DEFAULT '0',
  `mobid` int(11) NOT NULL DEFAULT '0',
  `mobgoal` int(11) NOT NULL DEFAULT '0',
  `itemid` int(11) NOT NULL DEFAULT '0',
  `itemgoal` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;


Don't forget to add the specific character's quests-save&load to the
general character's saving and loading.
Also add the progress method to killMonster and you're pretty much done!

An example on using the NPC methods:
(Could've missed out some bracket, just an example, don't kill me.)
For an overview of all quests in progress and finished use something similar to this:

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


function action(mode, type, selection) {
    if (mode == -1) {
        cm.dispose();
    } else {
        if (mode == 0 && status == 1) {
            cm.dispose();
            return;
        }
        if (mode == 1) {
            status++;
        } else {
            if (status == 2) {
                selection = 0;
            }
            status--;
        }
        if (status == 0) {
            cm.pqaSelection();
        } else if (status == 1) {
            if (selection == 0) {
                cm.pqaInProgress();
            } else if (selection == 1) {
                cm.pqaFinished();
                cm.dispose();
            }
        } else if (status == 2) {
            cm.pqaQuestInfo(selection);
        } else if (status == 3) {
            cm.dispose();
        }


For an NPC offering quests:
PHP:
var status;
 
function start() {
    status = -1;
    action(1, 0, 0);
}


function action(mode, type, selection) {
    if (mode == -1) {
        cm.dispose();
    } else {
        if (mode == 0 && status == 1) {
            cm.dispose();
            return;
        }
        if (mode == 1) {
            status++;
        } else {
            status--;
        }
        cm.addToAVQ(1000);
        cm.addToAVQ(1100);
        cm.addToAVQ(1200);
        if (!cm.noAvailableQuest(cm.getAVQ())) {
            if (status == 0) {
                cm.showAvailableQuests("Oh hi there", cm.getAVQ());
            } else if (status == 1) {
                script = "" + cm.getNpc() + "_" + selection;
                cm.openNpc(cm.getNpc(), script);
            }
        } else {
            if (status == 0) {
                cm.sendOk("Blubb blubb blubb");
                cm.dispose();
            }
        }
    }
}


Note that NPC opens the same NPC again upon selecting a quest
just using another script (NpcID_QuestID.js)

The new opened conversation:

PHP:
var status;
var questid = 1000;
 
function start() {
    status = -1;
    action(1, 0, 0);
}


function action(mode, type, selection) {
    if (mode == -1) {
        cm.dispose();
    } else {
        if (mode == 0 && status == 1) {
            cm.dispose();
            return;
        }
        if (mode == 1) {
            status++;
        } else {
            status--;
            selection = 0;
        }


        cm.loadQuestData(questid);
        if (!cm.inProgress(questid)) {
            if (status == 0) {
                cm.sendNext("Yo whats up?");
            } else if (status == 1) {
                cm.sendNextPrev("Blablabla");
            } else if (status == 2) {
                cm.sendAcceptDecline("So are you in?");
            } else if (status == 3) {
                cm.startCQuest(questid);
                cm.dispose();
            }
        } else if (cm.inProgress(questid) && !cm.reqToFinish(questid)) {
            if (status == 0) {
                cm.sendOk("Do your poop already");
                cm.dispose();
            }
        } else if (cm.inProgress(questid) && cm.reqToFinish(questid)) {
            if (status == 0) {
                cm.sendNext("Oh wow you did it. Yay");
            } else if (status == 1) {
                cm.rewardInfo("Here is your reward");
            } else if (status == 2) {
                cm.rewardPlayer();
                cm.finishCQuest(questid);
                cm.dispose();
            }
        }
    }
}


Got quite hard to stay focused at the end.
The NPC stuff is a bit messy, gonna try to work on that.
Loading quests from db every time doesn't seem right as well, so
gonna do this first.

Any feedback or suggestion are welcome.

Not sure if pictures are really helpful to present the system, as the only
visuals are the NPC talk. But I'll add them if needed.
 
(O_o(o_O(O_O)o_O)O_o)
Loyal Member
Joined
Apr 9, 2009
Messages
1,088
Reaction score
322
Looks like the foundation for something pretty fun, you should add more quest requirements though imo.
I mean it looks good, pretty clean, just not super extensive or anything.

Also, you should put how to add more quests into your OP, before a dozen people start asking how to add quests. I know it's not complicated to add them, it's just that the people who are most interested in this release will likely not.
 
Elite Diviner
Joined
Mar 24, 2015
Messages
426
Reaction score
416
Looks good, but very basic. If you want to extend it I would suggest adding the possibility of custom quest descriptions, start dialogue and end dialogue (so that just like with real quests, the quest dialogue is different from the normal npc dialogue). Also a feedback system which tells the player how they are progressing and when they have finished a quest.
 
Junior Spellweaver
Joined
Mar 19, 2016
Messages
100
Reaction score
0
Oh thanks, its based in one source or working in all? i like this in metroms.
 
Elite Diviner
Joined
May 4, 2011
Messages
491
Reaction score
105
Looks like the foundation for something pretty fun, you should add more quest requirements though imo.
I mean it looks good, pretty clean, just not super extensive or anything.

Also, you should put how to add more quests into your OP, before a dozen people start asking how to add quests. I know it's not complicated to add them, it's just that the people who are most interested in this release will likely not.

We should add this to "that"
 
Legendary Battlemage
Joined
Mar 7, 2013
Messages
686
Reaction score
43
@Quarphal
How to use bro?

you can explain more .with one script npc?
 
Last edited:
Newbie Spellweaver
Joined
Jun 12, 2016
Messages
45
Reaction score
2
i don't have some methods in repack.

getItemQuantity (In Maplecharacter.java)

private boolean isType(int itemId, ItemType type) {
return
ItemType.getItemType(itemId).equals(type);
}

(at error In ItemType because i don't have it)

my repack is MapleSolaxia
 
Last edited:
Back
Top