Majority of the credits to DestinyMS. Since its source got leaked, might as well remake this.
If you can't tell, this is a Party Quest. I just dumbed it down a bit, and made it possible for every server to have it. So technically, this doesn't even belong to me, but whatever. I quit this bs, Verizon FiOS is being a complete 'tard these days.
You need to know how to compile, and some basic Java terms.
So, let's start by defining the points for the PQ. These are bossPoints.
In src/net/sf/odinms/MapleClient/MapleCharacter.java (strongly recommended to open with Netbeans)
Place:
Code:
private int bossPoints;
That goes in the top sections, where all the private ints' are.
Find:
Code:
int buddyCapacity = rs.getInt("buddyCapacity");
Place under:
Code:
ret.bossPoints = rs.getInt("bosspoints");
Find
Place afterNote: if bosspoints = ? is your last term before WHERE id = ?, don't place the comma after the bosspoints = ? mark.
Find
Place after
Find
You should get something like this:
ps.setInt(33, marriageQuestLevel);
Well, technically, the 33 could be any number. If you looked under it, there are more ps.setInt(xx, [term]);
Place
Code:
ps.setInt([NUMBER]+1, bossPoints);
Beneath it, BUT, you must change all the ps.setint(xx, [term]); after it, and add 1 until the last term.
In most cases, it should be ps.setInt(xx, world);
If you don't understand, take a look (YOUR NUMBERS WON'T MATCH MINE, and you WON'T HAVE BOSSREPEATS):
Code:
ps.setInt(40, bossPoints);
ps.setInt(41, bossRepeats);
if (update) {
ps.setInt(42, id);
} else {
ps.setInt(43, accountid);
ps.setString(44, name);
ps.setInt(45, world);
}
int updateRows = ps.executeUpdate();
if (!update) {
ResultSet rs = ps.getGeneratedKeys();
Yeah.
Now, to define bossPoints...
Go to the bottom, and add:
Code:
public void setBossPoints(int points) {
bossPoints = points;
}
public int getBossPoints() {
return bossPoints;
}
Note that the } { mark an algorithm paragraph, so remember that...
Okay, moving on to defining them in src/net/sf/odinms/scripting/events/EventInstanceManager.java
Go to the bottom, and add...
Code:
public void saveAllBossQuestPoints(int bossPoints) {
for (MapleCharacter character : chars) {
int points = character.getBossPoints();
character.setBossPoints(points + bossPoints);
}
}
public void saveBossQuestPoints(int bossPoints, MapleCharacter character) {
int points = character.getBossPoints();
character.setBossPoints(points + bossPoints);
}
There, now compile and you're done for defining.
Now to the NPCs.
DestinyMS used 1, I decided to use 3 'cause I suck at this.
There are asterisks in them, so download them: here <- THE EVENT .JS is included, there's asteriks in it as well. >.>
I believe I left the credits for the reward one, not sure. >.>
Waiting Room Warper
Code:
//Yarly
var status = 0;
var price = 2000000;
var map = Array(240010501);
function start() {
status = -1;
action(1, 0, 0);
}
function action(mode, type, selection) {
if (mode == -1)
cm.dispose();
else {
if (mode == 0 && status == 0)
cm.dispose();
if (mode == 1)
status++;
else
status--;
if (status == 0)
cm.sendSimple("Hey, I'll take you to the BOSSPQ waiting room, if you want to fight him, you may might need some #b#v2000005##k, so you can recover some HP if you have been hit by #rthe bosses#k.\r\n#L1#I would like to buy 10 for ****000 Mesos!#l\r\n\#L2#No thanks, take me there now.#l");
else if (status == 1) {
if (selection == 1) {
if(cm.getMeso() >= 100000) {
cm.gainMeso(-100000);
cm.gainItem(2000005, 10);
cm.sendOk("Thank you for buying the potion. Use it as well!");
} else {
cm.sendOk("Sorry, you don't have enough mesos to buy them!");
}
cm.dispose();
}
else if (selection == 2) {
if(cm.getLevel() > 49)
cm.warp(240050000, 0);
else
cm.sendOk("I'm sorry. You need to be atleast level #r50#k or above to enter.");
cm.dispose();
}
}
}
}
BossPQ Starter:
Code:
/*
BossQuest NPC Starter
*/
var status = 0;
var minLevel = 50;
var maxLevel = 255;
var minPlayers = 1;
var maxPlayers = 6;
function start() {
status = -1;
action(1, 0, 0);
}
function action(mode, type, selection) {
if (mode == -1) {
cm.dispose();
} else {
if (mode == 0 && status == 0) {
cm.dispose();
return;
}
if (mode == 1)
status++;
else
status--;
if (status == 0) {
if (cm.getParty() == null) { // no party
cm.sendOk("Welcome,#g #h ##k, to the waiting room for the Boss Quest. I hope you have trained well.\r\n\\r\n\You may do this solo, or form a party, and tell the leader to talk to me.\r\n\\r\n\#rMake sure you're between level 50 and 250. GMs accompanying you may be level 255.#k");
cm.dispose();
return;
}
if (!cm.isLeader()) { // not party leader
cm.sendOk("If you want to try the quest, tell your leader to talk to me.");
cm.dispose();
}
else {
// check if all party members are within 50-200 range, etc.
var party = cm.getParty().getMembers();
var mapId = cm.getChar().getMapId();
var next = true;
var levelValid = 0;
var inMap = 0;
// Temp removal for testing
if (party.size() < minPlayers || party.size() > maxPlayers)
next = false;
else {
for (var i = 0; i < party.size() && next; i++) {
if ((party.get(i).getLevel() >= minLevel) && (party.get(i).getLevel() <= maxLevel))
levelValid += 1;
if (party.get(i).getMapid() == mapId)
inMap += 1;
}
if (levelValid < minPlayers || inMap < minPlayers)
next = false;
}
if (next) {
cm.sendOk("Okay, good luck.");
var em = cm.getEventManager("BossQuest");
if (em == null) {
cm.sendOk("This PQ is currently disabled by David. Please be patient.");
}
else {
em.startInstance(cm.getParty(),cm.getChar().getMap());
party = cm.getChar().getEventInstance().getPlayers();
}
cm.dispose();
}
else {
cm.sendOk("You don't have a party of at least 1. Please make sure all your members are present and qualified to participate in this quest. I see #b" + levelValid.toString() + " #kmembers are in the right level range, and #b" + inMap.toString() + "#k are here. If this seems wrong, #blog out and log back in,#k or reform the party.");
cm.dispose();
}
}
}
else {
cm.sendOk("I'm broken.");
cm.dispose();
}
}
}
BossPoints exchanger:
Code:
/* BossPQ NPC - Credits to Quasar I think
*/
var mil5 = new Array(2022273, 2022179, 2022245, 2022068);
var mil15 = new Array(1032048, 1382045, 1382046, 1382047, 1382048, 1372035, 1372036, 1372037, 1372038, 1302106, 1472072);
var mil30 = new Array(2340000, 2049**** 1382049, 1382050, 1382051, 1382052, 1372039, 1372040, 1372041, 1372042, 1302107);
var mil50 = new Array(1472073, 1302081, 1312037, 1322060, 1402046, 1412033, 1422037, 1482023);
var mil75 = new Array(2070018, 1072344, 1082223);
var status = 0;
var prize;
var chosen;
function numberFormat(nStr,prefix){
var prefix = prefix || '';
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) x1 = x1.replace(rgx, '$1' + ',' + '$2');
return prefix + x1 + x2;
}
function start() {
status = -1;
action(1, 0, 0);
}
function action(mode, type, selection) {
if (mode == -1) {
cm.dispose();
}
else {
if (mode == 0) {
cm.sendOk("Come back if you want to trade in your points.");
cm.dispose();
return;
}
if (mode == 1)
status++;
else
status--;
if (status == 0) {
cm.sendNext("Hello, I'm the trader of the Boss Quest Points.");
}
else if (status == 1) {
chosen = 0;
cm.sendSimple("Choose: #b\r\n#L0#Trade your Boss Points in for prizes.#l\r\n\#L1#Trade your Boss Points in for mesos.#l");
}
else if (status == 2) {
if (selection == 0) {
cm.sendSimple("We currently have a few trade packages. What prize you get all comes down to luck, but the more Boss Quest Points you trade, the better the prizes!#b\r\n#L0#5,000,000 Boss Quest Points#l\r\n#L1#15,000,000 Boss Quest Points#l\r\n#L2#30,000,000 Boss Quest Points#l\r\n#L3#50,000,000 Boss Quest Points#l\r\n#L4#75,000,000 Boss Quest Points#l");
chosen = 0;
}
else if (selection == 1) {
var maximum = (Math.floor((2147483648 - cm.getChar().getMeso()) / 100) * 20);
cm.sendGetNumber("For every #b10#k Boss Quest Points, you can trade for #b100#k mesos. How many Boss Quest Points would you like to trade?", 10, 10, maximum);
chosen = 1;
}
}
else if (status == 3) {
var quantity;
var selStr;
if (chosen == 0) {
if (selection == 0) {
prize = 0;
selStr = "You can win the following prizes: #b";
selStr += "#t" + mil5[0] + "#";
for (var i = 1; i < mil5.length; i++){
selStr += ", #t" + mil5[i] + "#";
}
selStr += "#k\r\nWould you like to trade your Boss Quest points to win one of the above prizes?";
cm.sendYesNo(selStr);
}
if (selection == 1) {
prize = 1;
selStr = "You can win the following prizes: #b";
selStr += "#t" + mil15[0] + "#";
for (var i = 1; i < mil15.length; i++){
selStr += ", #t" + mil15[i] + "#";
}
selStr += "#k\r\nWould you like to trade your Boss Quest points to win one of the above prizes?";
cm.sendYesNo(selStr);
}
if (selection == 2) {
prize = 2;
selStr = "You can win the following prizes: #b";
selStr += "#t" + mil30[0] + "#";
for (var i = 1; i < mil30.length; i++){
selStr += ", #t" + mil30[i] + "#";
}
selStr += "#k\r\nWould you like to trade your Boss Quest points to win one of the above prizes?";
cm.sendYesNo(selStr);
}
if (selection == 3) {
prize = 3;
selStr = "You can win the following prizes: #b";
selStr += "#t" + mil50[0] + "#";
for (var i = 1; i < mil50.length; i++){
selStr += ", #t" + mil50[i] + "#";
}
selStr += "#k\r\nWould you like to trade your Boss Quest points to win one of the above prizes?";
cm.sendYesNo(selStr);
}
if (selection == 4) {
prize = 4;
selStr = "You can win the following prizes: #b";
selStr += "#t" + mil75[0] + "#";
for (var i = 1; i < mil75.length; i++){
selStr += ", #t" + mil75[i] + "#";
}
selStr += "#k\r\nWould you like to trade your Boss Quest points to win one of the above prizes?";
cm.sendYesNo(selStr);
}
}
else if (chosen == 1) {
quantity = selection;
if (quantity % 10 != 0) {
cm.sendOk("Only multiples of #b10#k are allowed when trading Boss Quest Points for mesos!");
}
else if (cm.getChar().getBossPoints() < quantity) {
cm.sendOk("You do not have #b" + numberFormat(quantity) + "#k Boss Quest Points! Please try trading a different amount, or come back later when you have enough!");
}
else {
cm.getChar().setBossPoints(cm.getChar().getBossPoints() - quantity);
cm.gainMeso(quantity * 10);
cm.sendOk("After trading you now have #b" + numberFormat(cm.getChar().getBossPoints()) + "#k Boss Quest Points and #b" + numberFormat(cm.getChar().getMeso()) + "#k mesos! \r\nThank you for doing business, I wish you the best of luck on your future ventures into The Boss Quest!");
}
cm.dispose();
return;
}
}
else if (status == 4) {
var quantity = 1;
var win;
if (prize == 0) {
if (cm.getChar().getBossPoints() < 5000000) {
cm.sendOk("You do not have #b 5,000,000 #k Boss Quest Points to trade with. Sorry!");
cm.dispose();
return;
}
var win = mil5[Math.floor(Math.random() * mil5.length)];
if (win == 2022179) quantity = Math.floor(Math.random() * 5);
else quantity = Math.floor(Math.random() * 20);
cm.gainItem(win, quantity);
cm.getChar().setBossPoints(cm.getChar().getBossPoints() - 5000000);
}
else if (prize == 1) {
if (cm.getChar().getBossPoints() < 5000000) {
cm.sendOk("You do not have #b5,000,000#k Boss Quest Points to trade with. Sorry!");
cm.dispose();
return;
}
var win = mil15[Math.floor(Math.random() * mil15.length)];
cm.gainItem(win, quantity, true);
cm.getChar().setBossPoints(cm.getChar().getBossPoints() - 15000000);
}
else if (prize == 2) {
if (cm.getChar().getBossPoints() < 15000000) {
cm.sendOk("You do not have #b15,000,000#k Boss Quest Points to trade with. Sorry!");
cm.dispose();
return;
}
var win = mil30[Math.floor(Math.random() * mil30.length)];
cm.gainItem(win, quantity, true);
cm.getChar().setBossPoints(cm.getChar().getBossPoints() - 30000000);
}
else if (prize == 3) {
if (cm.getChar().getBossPoints() < 30000000) {
cm.sendOk("You do not have #b30,000,000#k Boss Quest Points to trade with. Sorry!");
cm.dispose();
return;
}
var win = mil50[Math.floor(Math.random() * mil50.length)];
cm.gainItem(win, quantity, true);
cm.getChar().setBossPoints(cm.getChar().getBossPoints() - 50000000);
}
else if (prize == 4) {
if (cm.getChar().getBossPoints() < 75000000) {
cm.sendOk("You do not have #b75,000,000#k Boss Quest Points to trade with. Sorry!");
cm.dispose();
return;
}
var win = mil75[Math.floor(Math.random() * mil75.length)];
cm.gainItem(win, quantity, true);
cm.getChar().setBossPoints(cm.getChar().getBossPoints() - 75000000);
}
cm.sendOk("You have been awarded with your prize. I hope you are pleased! Good luck in your future ventures into The Boss Quest.");
cm.dispose();
return;
}
}
}
Right, those are the NPCs, now the event.js...
Author is Groat. Credits to him.
Save as BossQuest.js
Remember to enable in World.properties
Code:
// @Author Groat
// Boss Quest
importPackage(net.sf.odinms.world);
importPackage(net.sf.odinms.client);
var exitMap;
var instanceId;
var monster;
monster = new Array(
3220000, // Stumpy,
9300003, // Slime King
4130103, // Rombot
9300012, // Alishar
8220001, // Yeti on Skis
8220000, // Elliza
9300119, // Lord Pirate
9300152, // Angry Franken Lloyd
9300039, // Papa Pixie
93000*** // Knight Statue B
9300028, // Ergoth
9400549, // Headless Horseman
8180001, // Griffey
8180000, // Manon
8500001, // Papulatus
9400575, // Big Foot
9400014, // Black Crow
8800002, // Zakum Body 3
9400121, // Female Boss
9400300 // The Boss
);
function init() {
}
function monsterValue(eim, mobId) {
return 1;
}
function setup(partyid) {
exitMap = em.getChannelServer().getMapFactory().getMap(200000000);
var instanceName = "BossQuest" + partyid;
var eim = em.newInstance(instanceName);
var mf = eim.getMapFactory();
var map = mf.getMap(240060200, false, true, false);
map.toggleDrops();
eim.setProperty("points", 0);
eim.setProperty("monster_number", 0);
eim.schedule("beginQuest", 5000);
return eim;
}
function playerEntry(eim, player) {
var map = eim.getMapInstance(240060200);
player.changeMap(map, map.getPortal(0));
}
function playerDead(eim, player) {
}
function playerRevive(eim, player) {
player.setHp(player.getMaxHp());
playerExit(eim, player);
return false;
}
function playerDisconnected(eim, player) {
removePlayer(eim, player);
}
function leftParty(eim, player) {
playerExit(eim, player);
}
function disbandParty(eim) {
var party = eim.getPlayers();
for (var i = 0; i < party.size(); i++) {
playerExit(eim, party.get(i));
}
}
function playerExit(eim, player) {
var party = eim.getPlayers();
var dispose = false;
if (party.size() == 1) {
dispose = true;
}
eim.saveBossQuestPoints(parseInt(eim.getProperty("points")), player);
player.getClient().getSession().write(net.sf.odinms.tools.MaplePacketCreator.serverNotice(6, "[The Boss Quest] Your current points have been awarded, spend them as you wish. Better luck next time!"));
eim.unregisterPlayer(player);
player.changeMap(exitMap, exitMap.getPortal(0));
if (dispose) {
eim.dispose();
}
}
function removePlayer(eim, player) {
var party = eim.getPlayers();
var dispose = false;
if (party.size() == 1) {
dispose = true;
}
eim.saveBossQuestPoints(parseInt(eim.getProperty("points")), player);
eim.unregisterPlayer(player);
player.getMap().removePlayer(player);
player.setMap(exitMap);
if (dispose) {
eim.dispose();
}
}
function clearPQ(eim) {
var party = eim.getPlayers();
for (var i = 0; i < party.size(); i++) {
playerExit(eim, party.get(i));
}
}
function allMonstersDead(eim) {
var monster_number = parseInt(eim.getProperty("monster_number"));
var points = parseInt(eim.getProperty("points"));
var monster_end = java.lang.System.currentTimeMillis();
var monster_time = Math.round((monster_end - parseInt(eim.getProperty("monster_start"))) / 1000);
if (3600 - monster_time <= 0) points += monster_number * 10000;
else points += (monster_number * 10000) + ((3600 - monster_time) * (monster_number + 1));
monster_number++;
eim.setProperty("points", points);
eim.setProperty("monster_number", monster_number);
var map = eim.getMapInstance(240060200);
if (monster_number > 19) {
map.broadcastMessage(net.sf.odinms.tools.MaplePacketCreator.serverNotice(6, "[The Boss Quest] Congratulations! Your team has defeated all the bosses with " + points + " points!"));
map.broadcastMessage(net.sf.odinms.tools.MaplePacketCreator.serverNotice(6, "[The Boss Quest] The points have been awarded, spend them as you wish."));
disbandParty();
}
else {
map.broadcastMessage(net.sf.odinms.tools.MaplePacketCreator.serverNotice(6, "[The Boss Quest] Your team now has " + points + " points! The next boss will spawn in 10 seconds."));
map.broadcastMessage(net.sf.odinms.tools.MaplePacketCreator.getClock(10));
eim.schedule("monsterSpawn", 10000);
}
}
function monsterSpawn(eim) {
var mob = net.sf.odinms.server.life.MapleLifeFactory.getMonster(monster[parseInt(eim.getProperty("monster_number"))]);
var overrideStats = new net.sf.odinms.server.life.MapleMonsterStats();
if (parseInt(eim.getProperty("monster_number")) > 16) overrideStats.setHp(mob.getHp());
else overrideStats.setHp(mob.getHp() * 2);
overrideStats.setExp(mob.getExp());
overrideStats.setMp(mob.getMaxMp());
mob.setOverrideStats(overrideStats);
if (parseInt(eim.getProperty("monster_number")) > 16) mob.setHp(mob.getHp());
else mob.setHp(mob.getHp() * 2);
eim.registerMonster(mob);
var map = eim.getMapInstance(240060200);
map.spawnMonsterOnGroundBelow(mob, new java.awt.Point(**** 100));
eim.setProperty("monster_start", java.lang.System.currentTimeMillis());
}
function beginQuest(eim) {
var map = eim.getMapInstance(240060200);
map.broadcastMessage(net.sf.odinms.tools.MaplePacketCreator.serverNotice(6, "[The Boss Quest] The creatures of the darkness are coming in 30 seconds. Prepare for the worst!"));
eim.schedule("monsterSpawn", 30000);
map.broadcastMessage(net.sf.odinms.tools.MaplePacketCreator.getClock(30));
}
function cancelSchedule() {
}
And last but not least (well, sort of):
SQL query for characters:
Code:
ALTER TABLE `characters` ADD `bosspoints` INT NOT NULL DEFAULT '0';
Execute. Done. Place NPCs into server. Fun.
SS's?






Oh, and a tip before I leave...
Code:
@echo off
title Copy odinms.jars
color 5e
XCOPY odinms.jar "C:\Program Files\Java\jre6\lib\ext" /Y
XCOPY odinms.jar "C:\Program Files\Java\jdk1.6.0_10\jre\lib\ext" /Y
echo Done.
pause
exit
Save that as a batch file, but in your dist folder, and run it each time you compile. this way you don't have to go and manually copy paste each time.
Not sure if this be a leak. But you can't exactly leak what's already leaked right? 
Oh and one last thing, it's er, easy to customize. It's made with arrays, so it doesn't take a genius to add bosses/rewards to the system...