Custom CPQ (NPC Script)

Joined
Jun 23, 2012
Messages
554
Reaction score
70
EDIT: Updated as of 4/26/2013 to fix a functional error in which the opposing party could not summon monsters because they did not have the necessary items to set the variables in the NPC to true.

Hey, it's Thane Krios and I bring to you the Custom CPQ add-on that was released several years ago under my decently ancient account: lfatelhighdef. It's been a long time since I've released anything so I've decided to rework and improve my past release. There were several issues with it in the past, mainly with the scripts themselves, but I believe I've worked out all the kinks. I tested this alone, and not with the recommended 4 people to ensure it works flawlessly with parties, but after re-reading the code twice I do believe it doesn't contain any serious issues.


What is the Custom CPQ?
Custom CPQ was an idea that entered my mind a few years ago (2 or 3 years ago). I, myself, am no Java coder and am only versed in the language of Java script. I'd self taught myself since 2008ish and had been looking for a more challenging endeavor to take upon myself. The product in the end was CPQ.

  • CPQ is a remake of the renowned Carnival PQ of pre-bb Maplestory
  • Whoever kills all mobs first wins
  • Players must be levels 30-50
  • Upon entering the lobby, the leader must speak to the assistant to begin the PQ.
  • The PQ cannot begin if there is no other team present.
  • Monsters spawn when conditions are met, and players must eliminate all monsters.
  • Upon death monsters drop Maple Coins, which are used to summon more mobs through the assistants
  • Upon elimination of mobs, the victorious party will be taken to the victory stage, and the loser to their defeated stage. Parties gain respective exp according to the EXP rates of their servers


NOTE: Please set the drop rate for Maple Coin near or at 50%. Too low may make the PQ end too quickly, and too high will make it never ending

Assistant Blue and Red (NPC script IDs are 2042009 and 2042004)
PHP:
/*Map: Monster Carnival Room 4 Lobby: mapt* Credits go to Thane Krios (alias: lfatelhighdef)*/
var status;
var min = 2;
var max = 6;
var coin = 4001129;
var startspiece = 4001254; // this is the item given to players to let the NPC know whether or not the PQ has began.
// IMPORTANT
// Change it to some undroppable item so they cannot abuse respawning. And make sure to change Spiegelmann's removal of the item so that players do not keep the PQ starting item when they leave
// IMPORTANT
var map = 980000400;
var mapt = 980000300;
var starts = 0;
var finish;
var leave;
var players;
var mobs = [[9300128, 9300129, 9300130, 9300131, 9300132, 9300133, 9300134, 9300135, 9300136],[2,2,3,4,4,5,6,10,20,30], 
["Brown Teddy", "Bloctopus", "Ratz", "Chronos", "Toy Trojan", "Tick-Tock", "Robo", "King Block", "Master Chronos", "Rombot"]]; // mobs, cost // name
// brown teddy, bloctopus, ratz, chronos, toy trojan, tick-tock, robo, king block, master chronos, rombot

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

function action(mode, type, selection) {
	if (mode == -1) {
		return;
		cm.dispose(); 
	} else if (mode == 0) {
		status--;
	} else {
		status++;
	}
	if (status == 0) {
			var party = cm.partyMembersInMap(); var count = cm.getPlayerCount(map); var countt = cm.getPlayerCount(mapt); var mob = cm.getMonsterCount(map); 
			var mobt = cm.getMonsterCount(mapt); var yours = cm.getMapId(); var your = cm.getMonsterCount(yours);
			(count == 0 || countt == 0 ? players = 0 : players = 1); // note to self, change players back
			(!cm.haveItem(startspiece,1) ? starts = 0 : starts = 1); // if they do not have starting item then the PQ has not begun
			(cm.haveItem(startspiece,1) && cm.getMapId()==map && countt < 1 ? finish = 0 : cm.haveItem(startspiece,1) && cm.getMapId()==map && mob == 0 ? finish = 1 : 
			cm.haveItem(startspiece,1) && cm.getMapId()==mapt && count < 1 ? finish = 0 : cm.haveItem(startspiece,1) && cm.getMapId()==mapt && mobt == 0 ? finish = 1 : finish = -1);
			// the above is a series of checks to see which team has won, and which team has lost. 0 = lose, 1 = win
		if (cm.getParty() == null) {
			cm.warp(980000504);
			cm.sendOk("You have been warped out due to not being in a party.");
			cm.dispose();
                } else if (!cm.haveItem(startspiece,1) && (mob > 0 || mobt > 0)) {
			cm.givePartyItems(startspiece, 1, cm.getPartyMembers());
                        cm.mapMessage(5, "Your party has been updated to active. You will now be able to summon monsters.");
			cm.dispose();
		} else if (finish == 0) {
			cm.warpParty(980000404);
			cm.mapMessage(5, "Sorry! The enemy team has won the match. Please talk to Spiegelmann to gain your rewards!");
			cm.dispose();
		} else if (finish == 1) {
			cm.warpParty(980000403);
			cm.mapMessage(5, "Congratulations! You have won the carnival game! Please talk to Spiegelmann for a handsome reward for your participation!");
			cm.dispose();
		} else if (players == 0) {
			leave = 1;
			cm.sendYesNo("You must wait for an opposing party to enter before you can starts the PQ. Would you like to leave?\r\n\r\n#eChoosing to leave will exit your entire party.#n");
		} else if (starts == 0) {
			if (!cm.isLeader()) {
				cm.sendOk("Please wait for the leaders to begin the PQ. Both teams are ready and able-bodied to begin the game.");
				cm.dispose();
			} else if (!cm.haveItem(startspiece,1)) {
				if (cm.getMapId()==map) {
					cm.givePartyItems(startspiece, 1, cm.getPartyMembers());
					cm.mapMessage(5, "You have been given a Shiny Maple Coin. Do not drop this item. If you do, then you will be unable to spawn any more monsters.");
					cm.summonMobAtPosition(9300133,3,-111,162);
					cm.summonMobAtPosition(9300136,3,231,162);
					cm.summonMobAtPosition(9300136,3,36,162);
					cm.summonMobAtPosition(9300133,3,185,162);
					cm.summonMobAtPosition(9300136,3,295,-138);
					cm.summonMobAtPosition(9300133,3,115,-138);				
					cm.spawnMobOnDiffMap(mapt,9300133,3,-111,162);
					cm.spawnMobOnDiffMap(mapt, 9300136,3,231,162);
					cm.spawnMobOnDiffMap(mapt, 9300136,3,36,162);
					cm.spawnMobOnDiffMap(mapt, 9300133,3,185,162);
					cm.spawnMobOnDiffMap(mapt, 9300136,3,295,-138);
					cm.spawnMobOnDiffMap(mapt, 9300133,3,115,-138);
					cm.dispose();
				} else {
					cm.summonMobAtPosition(9300133,3,-111,162);
					cm.summonMobAtPosition(9300136,3,231,162);
					cm.summonMobAtPosition(9300136,3,36,162);
					cm.summonMobAtPosition(9300133,3,185,162);
					cm.summonMobAtPosition(9300136,3,295,-138);
					cm.summonMobAtPosition(9300133,3,115,-138);				
					cm.spawnMobOnDiffMap(map,9300133,3,-111,162);
					cm.spawnMobOnDiffMap(map, 9300136,3,231,162);
					cm.spawnMobOnDiffMap(map, 9300136,3,36,162);
					cm.spawnMobOnDiffMap(map, 9300133,3,185,162);
					cm.spawnMobOnDiffMap(map, 9300136,3,295,-138);
					cm.spawnMobOnDiffMap(map, 9300133,3,115,-138);
				}
			}
		} else {
			txt = "These are the monsters that you can summon on the opposing map. You will spawn a total of #e21#n mobs on the other side each time you select a mob to spawn.";
			for (var i = 0; i < mobs[0].length; i++)
			txt += "\r\n#L"+i+"##o"+mobs[0][i]+"# - #b"+mobs[1][i]+"#k #i"+coin+"#";
			cm.sendSimple(txt);
			}
		} else if (status == 1) {
			if (leave == 1) {
				cm.warpParty(980000000);
				cm.dispose();
			} else if (!cm.haveItem(coin, mobs[1][selection])) {
					cm.sendOk("You cannot summon this monster, #b#o"+mobs[0][selection]+"##k. You are lacking #b"+(mobs[1][selection] - cm.haveItem(coin))+"#k #i"+coin+"#.");
					cm.dispose();
				} else {
					if (cm.getMapId()==map) {
						cm.mapMessage(5, ""+cm.getPlayer().getName+" has summoned 21 "+mobs[2][selection]+" on the enemy's side!");
						cm.gainItem(coin, -mobs[1][selection]);
						cm.spawnMobOnDiffMap(mapt, mobs[0][selection], 7, -207, 162);
						cm.spawnMobOnDiffMap(mapt,mobs[0][selection], 7, 221, -138);
						cm.spawnMobOnDiffMap(mapt, mobs[0][selection], 7, 232, 162);
						cm.dispose();
					} else {
						cm.mapMessage(5, ""+cm.getPlayer().getName+" has summoned 21 "+mobs[2][selection]+" on the enemy's side!");
						cm.gainItem(coin, -mobs[1][selection]);
						cm.spawnMobOnDiffMap(map, mobs[0][selection], 7, -207, 162);
						cm.spawnMobOnDiffMap(map,mobs[0][selection], 7, 221, -138);
						cm.spawnMobOnDiffMap(map, mobs[0][selection], 7, 232, 162);
						cm.dispose();
				}
			}
		}
	}


Spiegelmann at main map
PHP:
var server = "DynastyMS";
var status;
var min = 2;
var max = 6;

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 later then.");
			cm.dispose();
			return;
		}
		if (mode == 1)
			status++;
		else
			status--;
	var party = cm.partyMembersInMap();
	var open = true;
	var players = cm.getPlayerCount(980000100);
    if (status == 0) {
	if (cm.getMapId()==100000000) {
		if (cm.getLevel() < 30 || cm.getLevel() > 50) {
			cm.sendOk("You are not eligible for #rCustom CPQ#k. It is available only for levels #r30-50#k.");
			cm.dispose();
	} else {
		cm.sendYesNo("Would you like to go to #bCPQ#k?");
	}
	} else if (cm.getMapId()!=980000000) {
			cm.sendOk("Hey, you can start #bCPQ#k with me in Kerning City.");
			cm.dispose();
	} else if (cm.getParty() == null) {
		cm.sendNext("Hey! Welcome to the #rCustom Monster Carnival#k of #d"+server+"#k.");
	} else if (!cm.isLeader()) {
		cm.sendOk("You are not the leader. Please have the leader speak to me to initiate the #rMonster Carnival#k.");
		cm.dispose();
	} else {
		cm.sendYesNo("Good. Your party is ready. Have you spoken to another party's leader and decided upon the map you wish to take on?");
	} 
	} else if (status == 1) {
	if (cm.getMapId()==100000000) {
		cm.warp(980000000);
		cm.dispose();
	} else if (cm.getParty() == null) {
		cm.sendNext("In this #rMonster Carnival#k, you will need #b2#k parties. You can find some at the lobby and speak to each party's leaders for a match to be set up.");
	} else {
		cm.sendSimple("Choose from the maps. You must have the correct number of players according to each map.\r\n\r\n#L0#Map 0 - #L1#Map 0 Challenger#b (2 - 4 players only)#k\r\n#L2#Map 1 - #L3#Map 1 Challenger #b(2 - 4 players only)#k\r\n#L4#Map 2 - #L5#Map 2 Challenger #b(3 - 6 players only)#k #e"+
		"UNAVAILABLE#n");
	}
	} else if (status == 2) {
	var party = cm.partyMembersInMap();
	 if (cm.getParty() == null) {
		cm.sendNext("Each party will choose what map they wish to be on. When choosing a map, the selection adjacent to it is the map in which the opposite party will be in.\r\n\r\n#bExample: #k#bMap 1#k - 1st Party : #bMap 2#k - 2nd Party");
	} else if (selection == 0 && cm.getPlayerCount(980000100) < 1 && party >= 2 && party <= 4) {
		cm.warpParty(980000100);
		cm.dispose();
	} else if (selection == 1 && cm.getPlayerCount(980000200) < 1 && party >= 2 && party <= 4) {
		cm.warpParty(980000200);
		cm.dispose();
	} else if (selection == 2 && cm.getPlayerCount(980000400) < 1 && party >= 2 && party <= 4) {
		cm.warpParty(980000400);
		cm.dispose();
	} else if (selection == 3 && cm.getPlayerCount(980000300) < 1 && party >= 2 && party <= 4) {
		cm.warpParty(980000300);
		cm.dispose();
	} else if (selection == 4 && cm.getPlayerCount(980000500) < 1 && party >= 3 && party <= 6) {
		cm.warpParty(980000500);
		cm.dispose();
	} else if (selection == 5 && cm.getPlayerCount(980000600) < 1 && party >= 3 && party <= 6) {
		cm.warpParty(980000600);
		cm.dispose();
	} else {
		cm.sendOk("There is already a party inside participating in the #rPQ#k, or the number of people in your party are incorrect for this map.");
		cm.dispose();
	}
	} else if (status == 3) {
	if (cm.getParty() == null) {
		cm.sendOk("A large group of monsters will spawn for both maps. Players must eliminate the horde of monsters as fast as they can. The monsters will drop a certain item used for spawning monsters to your opponent's map. Whoever kills all monsters on the map first wins.");
		cm.dispose();
			}
		}
	}

Spiegelmann at defeat and victorious stages
PHP:
/*Map: Monster Carnival Room 4 Lobby: 980000400*/

var status;
var min = 2;
var max = 6;
var coin = 4001129;
var scoin = 4001254;

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 later then.");
			return;
		}
		if (mode == 1)
			status++;
		else
			status--;
    if (status == 0) {
	var party = cm.partyMembersInMap();
	if (cm.getMapId()!=103000000) {
	if (cm.getMapId()==980000403 || cm.getMapId()==980000103 || cm.getMapId()==980000503) {
		cm.sendOk("Hey! Good job on winning! Your party has received #r6,000#k EXP TIMES the current EXP rate");
		cm.mapMessage(6,"[CPQ Assistant] Good job on winning! The party members in the map will receive 6,000 EXP TIMES the current EXP rate.");
	} else if (cm.getParty()){
		cm.sendOk("Aww! Better luck next time. You'll do better. Your party has received #r2,000#k EXP TIMES the current EXP rate.");
		cm.mapMessage(6,"[CPQ Assistant] Aww! Better luck next time! Party members in the map will receive 2,000 EXP TIMES the current EXP rate.");
	} else {
		cm.sendOk("I'll warp you out right now.");
		}
	} else {
		cm.sendYesNo("Do you want join the #bMonster Carnival#k?");
	}
	} else if (status == 1) {
	var party = cm.partyMembersInMap();
	if (cm.getMapId()!=103000000) {
	if (cm.getMapId()==980000403 || cm.getMapId()==980000103 || cm.getMapId()==980000503) {
		cm.warp(980000000);
		cm.gainExp(6000 * 15);
		cm.removeAll(scoin)
		cm.removeAll(coin);
		cm.dispose();
	} else if (cm.getParty()){
		cm.warp(980000000);
		cm.gainExp(2000 * 15);
		cm.removeAll(scoin);
		cm.removeAll(coin);
		cm.dispose();
	} else {
		cm.warp(100000000);
		cm.dispose();
				}
	} else {
		cm.warp(980000000);
		cm.dispose();
			}
		}
	}

cm.getPlayerCount(map) function
PHP:
public int getPlayerCount(int mapid) {
        return c.getChannelServer().getMapFactory().getMap(mapid).getCharacters().size();
    }

cm.getMonsterCount function
PHP:
public int getMonsterCount (int map) {
            return c.getChannelServer().getMapFactory().getMap(map).getMonsterCount();
    }

cm.summonMobAtPosition function
PHP:
public void summonMobAtPosition(int mobid, int amount, int posx, int posy) {
        if (amount <= 1) {
            MapleMonster npcmob = MapleLifeFactory.getMonster(mobid);
            npcmob.setHp(npcmob.getMaxHp());
            getPlayer().getMap().spawnMonsterOnGroudBelow(npcmob, new Point(posx, posy));
        } else {
            for (int i = 0; i < amount; i++) {
                MapleMonster npcmob = MapleLifeFactory.getMonster(mobid);
                npcmob.setHp(npcmob.getMaxHp());
                getPlayer().getMap().spawnMonsterOnGroudBelow(npcmob, new Point(posx, posy));
            }
        }
    }

cm.spawnMobOnDiffMap Function
PHP:
public void spawnMobOnDiffMap(int mapid, int mobid, int amount, int xpos, int ypos) {
        MapleMap target = c.getChannelServer().getMapFactory().getMap(mapid);
        for (int x = 0; x < amount; x++) {
            target.spawnMonsterOnGroundBelow(MapleLifeFactory.getMonster(mobid), new Point(xpos, ypos));
        }
    }

cm.mapMessage
PHP:
public void mapMessage(int type, String message) {
        getPlayer().getMap().broadcastMessage(MaplePacketCreator.serverNotice(type, message));
    }

Credits go to me and my alias (lfatelhighdef), and Kevintjuh93 for his wonderful v83 source.
One can find the initial release of this PQ here: http://forum.ragezone.com/f427/add-custom-cpq-727685/

PS: Only Assistant Red and Blue were edited during this recent endeavor. Spiegelmann has remained untouched since 2011.

Screen Shots
v83 localhost 2013-04-24 20-46-50-55 - Custom CPQ (NPC Script) - RaGEZONE Forums v83 localhost 2013-04-24 20-47-38-90 - Custom CPQ (NPC Script) - RaGEZONE Forums v83 localhost 2013-04-24 20-47-41-23 - Custom CPQ (NPC Script) - RaGEZONE Forums v83 localhost 2013-04-24 20-48-00-52 - Custom CPQ (NPC Script) - RaGEZONE Forums v83 localhost 2013-04-24 20-48-02-42 - Custom CPQ (NPC Script) - RaGEZONE Forums
 
Last edited:
can you explain to me the process of how 2 parties will do the pq?

It's based all on logic and conditions. I'll make new comments in the script below.

PHP:
/*Map: Monster Carnival Room 4 Lobby: mapt* Credits go to Thane Krios (alias: lfatelhighdef)*/
var status;
var coin = 4001129; // currency for summoning mobs
var startspiece = 4001254; // this is the item piece the NPC shall check to decide whether or not the PQ has started
// IMPORTANT
// Change it to some undroppable item so they cannot abuse respawning. And make sure to change Spiegelmann's removal of the item so that players do not keep the PQ starting item when they leave
// IMPORTANT
var map = 980000400; // map 2
var mapt = 980000300; // map 1
var starts = 0; // depending on what # starts is equal to will allow players to summon mobs, or have to continue waiting.
var finish; // depending on what value finish is, 0 = defeat and 1 = victory, will decide where the parties will go upon loss/defeat.
var leave; // this is set to 1 if there is only one party on either map. As a result, in the next status the NPC will know to warp the party out if they do not want to wait.
var players; // depending on what value this is will tell the NPC that both maps have a sufficient amount of people.
var mobs = [[9300128, 9300129, 9300130, 9300131, 9300132, 9300133, 9300134, 9300135, 9300136],[2,2,3,4,4,5,6,10,20,30], 
["Brown Teddy", "Bloctopus", "Ratz", "Chronos", "Toy Trojan", "Tick-Tock", "Robo", "King Block", "Master Chronos", "Rombot"]]; // mobs, cost, name
// brown teddy, bloctopus, ratz, chronos, toy trojan, tick-tock, robo, king block, master chronos, rombot

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

function action(mode, type, selection) {
    if (mode == -1) {
        return;
        cm.dispose(); 
    } else if (mode == 0) {
        status--;
    } else {
        status++;
    }
    if (status == 0) {
            var party = cm.partyMembersInMap();  // # of party members in the player's map
			var count = cm.getPlayerCount(map);  // # of party members in variable map
			var countt = cm.getPlayerCount(mapt); // # of party members in variable mapt
			var mob = cm.getMonsterCount(map); // same thing as above, except checks the # of monsters in the map
            var mobt = cm.getMonsterCount(mapt);  // same thing as above sentence, but for different map
			var yours = cm.getMapId(); // retrieves the player's map id... not sure why I still have it here. Didn't use it the entire script.
			var your = cm.getMonsterCount(yours); // didn't use this the entire time. 
            (count == 0 || countt == 0 ? players = 0 : players = 1); 
			/* if the # of players in count (variable for # of players in "map") is = 0, or if the # of players in countt = 0, then set players = 0 
				Otherwise, in all other cases set players = 1. In shorter terms, when players = 0, there conditions for the PQ in terms of players have not been met. When
				players = 1, then yes, this condition is met.*/
            (!cm.haveItem(startspiece,1) ? starts = 0 : starts = 1); 
			/* if the player does not have the starting piece (the one that deems whether or not the PQ has begun), then set variable starts = 0. In all other cases set "starts" = 1
				Basically, when starts = 0, the PQ has not begun. When starts = 1, then it has begun.*/
            (cm.haveItem(startspiece,1) && cm.getMapId()==map && countt < 1 ? finish = 0 : cm.haveItem(startspiece,1) && cm.getMapId()==map && mob == 0 ? finish = 1 : 
            cm.haveItem(startspiece,1) && cm.getMapId()==mapt && count < 1 ? finish = 0 : cm.haveItem(startspiece,1) && cm.getMapId()==mapt && mobt == 0 ? finish = 1 : finish = -1);
            /* THIS is what determines which party will win or lose. 
				
				1) (cm.haveItem(startspiece,1) && cm.getMapId()==map && countt < 1 ? finish = 0) -- this is the first bit you see. Basically, if the PQ has begun and the player is in 
				"map" and the number of players in the opposing map is = 0, then set finish = 0. (In other terms, if there are no players in the opposing map and the PQ has begun, that means
				the player's party themselves have lost the PQ, and that the opposing party has won and therefore been warped out first.
				
				2) (cm.haveItem(startspiece,1) && cm.getMapId()==map && mob == 0 ? finish = 1) -- This is the victory condition for the player's party. If the PQ has begun and they are in
				the map "map", and the mob count in their map is = 0, then set their finish condition to VICTORY (AKA 1)
				
				3) ( cm.haveItem(startspiece,1) && cm.getMapId()==mapt && count < 1 ? finish = 0) -- This is the defeat condition, however, on the OTHER map. If the PQ has begun and 
				their map is "mapt", and the player count in the opposing map is = 0, then set the player's party finish condition to DEFEAT (AKA 0)
				
				4) (cm.haveItem(startspiece,1) && cm.getMapId()==mapt && mobt == 0 ? finish = 1) -- This is the victory condition. Again, it is applicable to the other map. If the PQ has
				begun and their map is "mapt", and the mob count on "mapt" is = 0, then the player's party has finished their conditions to win and the party's finish condition is VICTORY
				(AKA --> 1)
				*/
        if (cm.getParty() == null) { // if one does not have a party then they are kicked out from the PQ.
            cm.warp(980000504);
            cm.sendOk("You have been warped out due to not being in a party.");
            cm.dispose();
		} else if (!cm.haveItem(startspiece,1) && (mob > 0 || mobt > 0)) { // if the party does not have the startspiece, but the PQ has already begun
			cm.givePartyItems(startspiece, 1, cm.getPartyMembers());
			cm.mapMessage(5, "Your party has been updated to active. You will now be able to summon monsters.");
			cm.dispose();
        } else if (finish == 0) { // This is where the victory conditions settle in. If their victory condition is 0, (AKA Defeat), then warp them to the defeated map and send the defeat message
            cm.warpParty(980000404);
            cm.mapMessage(5, "Sorry! The enemy team has won the match. Please talk to Spiegelmann to gain your rewards!");
            cm.dispose();
        } else if (finish == 1) { // if they are the winners, then send them to the victory map and send the victory declaration
            cm.warpParty(980000403);
            cm.mapMessage(5, "Congratulations! You have won the carnival game! Please talk to Spiegelmann for a handsome reward for your participation!");
            cm.dispose();
        } else if (players == 0) { // When players == 0, it is parallel to stating that one of the maps do not meet the requirements for # of people.
            leave = 1; // sets their leave status to 1
            cm.sendYesNo("You must wait for an opposing party to enter before you can starts the PQ. Would you like to leave?\r\n\r\n#eChoosing to leave will exit your entire party.#n");
        } else if (starts == 0) { // starts = 0, or in other wards, the PQ has not started. Basically starts only = 0 when players do not have the starting item the NPC gives when the PQ begins.
            if (!cm.isLeader()) { // if you aren't the leader
                cm.sendOk("Please wait for the leaders to begin the PQ. Both teams are ready and able-bodied to begin the game.");
                cm.dispose();
            } else if (!cm.haveItem(startspiece,1)) { 
			/* By elimination, the player who reaches this condition IS the leader. 
				If the leader does not have the start piece, then the PQ has not begun. Since we have fulfilled all the checks up to this point,
				this means there are a sufficient amount of players to begin the PQ, the NPC will initiate the PQ by giving
				everyone in the party the "startspiece" so that it can keep track of their progress*/
				
				// the two following if statements below just summon mobs in both maps to begin the PQ. It also gives the party that initiated the PQ the startspiece.
                if (cm.getMapId()==map) { 
                    cm.givePartyItems(startspiece, 1, cm.getPartyMembers());
                    cm.mapMessage(5, "You have been given a Shiny Maple Coin. Do not drop this item. If you do, then you will be unable to spawn any more monsters.");
                    cm.summonMobAtPosition(9300133,3,-111,162);
                    cm.summonMobAtPosition(9300136,3,231,162);
                    cm.summonMobAtPosition(9300136,3,36,162);
                    cm.summonMobAtPosition(9300133,3,185,162);
                    cm.summonMobAtPosition(9300136,3,295,-138);
                    cm.summonMobAtPosition(9300133,3,115,-138);                
                    cm.spawnMobOnDiffMap(mapt,9300133,3,-111,162);
                    cm.spawnMobOnDiffMap(mapt, 9300136,3,231,162);
                    cm.spawnMobOnDiffMap(mapt, 9300136,3,36,162);
                    cm.spawnMobOnDiffMap(mapt, 9300133,3,185,162);
                    cm.spawnMobOnDiffMap(mapt, 9300136,3,295,-138);
                    cm.spawnMobOnDiffMap(mapt, 9300133,3,115,-138);
                    cm.dispose();
                } else {
                    cm.summonMobAtPosition(9300133,3,-111,162);
                    cm.summonMobAtPosition(9300136,3,231,162);
                    cm.summonMobAtPosition(9300136,3,36,162);
                    cm.summonMobAtPosition(9300133,3,185,162);
                    cm.summonMobAtPosition(9300136,3,295,-138);
                    cm.summonMobAtPosition(9300133,3,115,-138);                
                    cm.spawnMobOnDiffMap(map,9300133,3,-111,162);
                    cm.spawnMobOnDiffMap(map, 9300136,3,231,162);
                    cm.spawnMobOnDiffMap(map, 9300136,3,36,162);
                    cm.spawnMobOnDiffMap(map, 9300133,3,185,162);
                    cm.spawnMobOnDiffMap(map, 9300136,3,295,-138);
                    cm.spawnMobOnDiffMap(map, 9300133,3,115,-138);
                }
            }
        } else {
		// THE classic infinite loop array. It increases variable "i" each time "i" is less than the length of the array and its sub arrays. Very useful for listing large amounts of items, mobs, or maps
            txt = "These are the monsters that you can summon on the opposing map. You will spawn a total of #e21#n mobs on the other side each time you select a mob to spawn.";
            for (var i = 0; i < mobs[0].length; i++)
            txt += "\r\n#L"+i+"##o"+mobs[0][i]+"# - #b"+mobs[1][i]+"#k #i"+coin+"#";
            cm.sendSimple(txt);
            }
        } else if (status == 1) {
            if (leave == 1) { // If the party had wanted to leave earlier, this is where they get warped.
                cm.warpParty(980000000);
                cm.dispose();
            } else if (!cm.haveItem(coin, mobs[1][selection])) { // if the # of coins the player has is insufficient to summon hte mob. 
                    cm.sendOk("You cannot summon this monster, #b#o"+mobs[0][selection]+"##k. You are lacking #b"+(mobs[1][selection] - cm.haveItem(coin))+"#k #i"+coin+"#.");
                    cm.dispose();
                } else {
				// the checks below will determine where the monsters are summoned. If the player is in "map", then mobs will be spawned on "mapt". Same with vice versa. There is also a notice to their party that their teammate has just summoned more monsters.
                    if (cm.getMapId()==map) { 
                        cm.mapMessage(5, ""+cm.getPlayer().getName+" has summoned 21 "+mobs[2][selection]+" on the enemy's side!");
                        cm.gainItem(coin, -mobs[1][selection]);
                        cm.spawnMobOnDiffMap(mapt, mobs[0][selection], 7, -207, 162);
                        cm.spawnMobOnDiffMap(mapt,mobs[0][selection], 7, 221, -138);
                        cm.spawnMobOnDiffMap(mapt, mobs[0][selection], 7, 232, 162);
                        cm.dispose();
                    } else {
                        cm.mapMessage(5, ""+cm.getPlayer().getName+" has summoned 21 "+mobs[2][selection]+" on the enemy's side!");
                        cm.gainItem(coin, -mobs[1][selection]);
                        cm.spawnMobOnDiffMap(map, mobs[0][selection], 7, -207, 162);
                        cm.spawnMobOnDiffMap(map,mobs[0][selection], 7, 221, -138);
                        cm.spawnMobOnDiffMap(map, mobs[0][selection], 7, 232, 162);
                        cm.dispose();
                }
            }
        }
    }

tl;dr --> To be simplistic and efficient, I only really needed to use map checks to determine where to spawn monsters and award victories. If you read my script you'll understand why. Any scripter or coder who skims through this will understand immediately.


pastebin:
 
Last edited:
It's based all on logic and conditions. I'll make new comments in the script below.

PHP:
/*Map: Monster Carnival Room 4 Lobby: mapt* Credits go to Thane Krios (alias: lfatelhighdef)*/
var status;
var coin = 4001129; // currency for summoning mobs
var startspiece = 4001254; // this is the item piece the NPC shall check to decide whether or not the PQ has started
// IMPORTANT
// Change it to some undroppable item so they cannot abuse respawning. And make sure to change Spiegelmann's removal of the item so that players do not keep the PQ starting item when they leave
// IMPORTANT
var map = 980000400; // map 2
var mapt = 980000300; // map 1
var starts = 0; // depending on what # starts is equal to will allow players to summon mobs, or have to continue waiting.
var finish; // depending on what value finish is, 0 = defeat and 1 = victory, will decide where the parties will go upon loss/defeat.
var leave; // this is set to 1 if there is only one party on either map. As a result, in the next status the NPC will know to warp the party out if they do not want to wait.
var players; // depending on what value this is will tell the NPC that both maps have a sufficient amount of people.
var mobs = [[9300128, 9300129, 9300130, 9300131, 9300132, 9300133, 9300134, 9300135, 9300136],[2,2,3,4,4,5,6,10,20,30], 
["Brown Teddy", "Bloctopus", "Ratz", "Chronos", "Toy Trojan", "Tick-Tock", "Robo", "King Block", "Master Chronos", "Rombot"]]; // mobs, cost, name
// brown teddy, bloctopus, ratz, chronos, toy trojan, tick-tock, robo, king block, master chronos, rombot

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

function action(mode, type, selection) {
    if (mode == -1) {
        return;
        cm.dispose(); 
    } else if (mode == 0) {
        status--;
    } else {
        status++;
    }
    if (status == 0) {
            var party = cm.partyMembersInMap();  // # of party members in the player's map
			var count = cm.getPlayerCount(map);  // # of party members in variable map
			var countt = cm.getPlayerCount(mapt); // # of party members in variable mapt
			var mob = cm.getMonsterCount(map); // same thing as above, except checks the # of monsters in the map
            var mobt = cm.getMonsterCount(mapt);  // same thing as above sentence, but for different map
			var yours = cm.getMapId(); // retrieves the player's map id... not sure why I still have it here. Didn't use it the entire script.
			var your = cm.getMonsterCount(yours); // didn't use this the entire time. 
            (count == 0 || countt == 0 ? players = 0 : players = 1); 
			/* if the # of players in count (variable for # of players in "map") is = 0, or if the # of players in countt = 0, then set players = 0 
				Otherwise, in all other cases set players = 1. In shorter terms, when players = 0, there conditions for the PQ in terms of players have not been met. When
				players = 1, then yes, this condition is met.*/
            (!cm.haveItem(startspiece,1) ? starts = 0 : starts = 1); 
			/* if the player does not have the starting piece (the one that deems whether or not the PQ has begun), then set variable starts = 0. In all other cases set "starts" = 1
				Basically, when starts = 0, the PQ has not begun. When starts = 1, then it has begun.*/
            (cm.haveItem(startspiece,1) && cm.getMapId()==map && countt < 1 ? finish = 0 : cm.haveItem(startspiece,1) && cm.getMapId()==map && mob == 0 ? finish = 1 : 
            cm.haveItem(startspiece,1) && cm.getMapId()==mapt && count < 1 ? finish = 0 : cm.haveItem(startspiece,1) && cm.getMapId()==mapt && mobt == 0 ? finish = 1 : finish = -1);
            /* THIS is what determines which party will win or lose. 
				
				1) (cm.haveItem(startspiece,1) && cm.getMapId()==map && countt < 1 ? finish = 0) -- this is the first bit you see. Basically, if the PQ has begun and the player is in 
				"map" and the number of players in the opposing map is = 0, then set finish = 0. (In other terms, if there are no players in the opposing map and the PQ has begun, that means
				the player's party themselves have lost the PQ, and that the opposing party has won and therefore been warped out first.
				
				2) (cm.haveItem(startspiece,1) && cm.getMapId()==map && mob == 0 ? finish = 1) -- This is the victory condition for the player's party. If the PQ has begun and they are in
				the map "map", and the mob count in their map is = 0, then set their finish condition to VICTORY (AKA 1)
				
				3) ( cm.haveItem(startspiece,1) && cm.getMapId()==mapt && count < 1 ? finish = 0) -- This is the defeat condition, however, on the OTHER map. If the PQ has begun and 
				their map is "mapt", and the player count in the opposing map is = 0, then set the player's party finish condition to DEFEAT (AKA 0)
				
				4) (cm.haveItem(startspiece,1) && cm.getMapId()==mapt && mobt == 0 ? finish = 1) -- This is the victory condition. Again, it is applicable to the other map. If the PQ has
				begun and their map is "mapt", and the mob count on "mapt" is = 0, then the player's party has finished their conditions to win and the party's finish condition is VICTORY
				(AKA --> 1)
				*/
        if (cm.getParty() == null) { // if one does not have a party then they are kicked out from the PQ.
            cm.warp(980000504);
            cm.sendOk("You have been warped out due to not being in a party.");
            cm.dispose();
		} else if (!cm.haveItem(startspiece,1) && (mob > 0 || mobt > 0)) { // if the party does not have the startspiece, but the PQ has already begun
			cm.givePartyItems(startspiece, 1, cm.getPartyMembers());
			cm.mapMessage(5, "Your party has been updated to active. You will now be able to summon monsters.");
			cm.dispose();
        } else if (finish == 0) { // This is where the victory conditions settle in. If their victory condition is 0, (AKA Defeat), then warp them to the defeated map and send the defeat message
            cm.warpParty(980000404);
            cm.mapMessage(5, "Sorry! The enemy team has won the match. Please talk to Spiegelmann to gain your rewards!");
            cm.dispose();
        } else if (finish == 1) { // if they are the winners, then send them to the victory map and send the victory declaration
            cm.warpParty(980000403);
            cm.mapMessage(5, "Congratulations! You have won the carnival game! Please talk to Spiegelmann for a handsome reward for your participation!");
            cm.dispose();
        } else if (players == 0) { // When players == 0, it is parallel to stating that one of the maps do not meet the requirements for # of people.
            leave = 1; // sets their leave status to 1
            cm.sendYesNo("You must wait for an opposing party to enter before you can starts the PQ. Would you like to leave?\r\n\r\n#eChoosing to leave will exit your entire party.#n");
        } else if (starts == 0) { // starts = 0, or in other wards, the PQ has not started. Basically starts only = 0 when players do not have the starting item the NPC gives when the PQ begins.
            if (!cm.isLeader()) { // if you aren't the leader
                cm.sendOk("Please wait for the leaders to begin the PQ. Both teams are ready and able-bodied to begin the game.");
                cm.dispose();
            } else if (!cm.haveItem(startspiece,1)) { 
			/* By elimination, the player who reaches this condition IS the leader. 
				If the leader does not have the start piece, then the PQ has not begun. Since we have fulfilled all the checks up to this point,
				this means there are a sufficient amount of players to begin the PQ, the NPC will initiate the PQ by giving
				everyone in the party the "startspiece" so that it can keep track of their progress*/
				
				// the two following if statements below just summon mobs in both maps to begin the PQ. It also gives the party that initiated the PQ the startspiece.
                if (cm.getMapId()==map) { 
                    cm.givePartyItems(startspiece, 1, cm.getPartyMembers());
                    cm.mapMessage(5, "You have been given a Shiny Maple Coin. Do not drop this item. If you do, then you will be unable to spawn any more monsters.");
                    cm.summonMobAtPosition(9300133,3,-111,162);
                    cm.summonMobAtPosition(9300136,3,231,162);
                    cm.summonMobAtPosition(9300136,3,36,162);
                    cm.summonMobAtPosition(9300133,3,185,162);
                    cm.summonMobAtPosition(9300136,3,295,-138);
                    cm.summonMobAtPosition(9300133,3,115,-138);                
                    cm.spawnMobOnDiffMap(mapt,9300133,3,-111,162);
                    cm.spawnMobOnDiffMap(mapt, 9300136,3,231,162);
                    cm.spawnMobOnDiffMap(mapt, 9300136,3,36,162);
                    cm.spawnMobOnDiffMap(mapt, 9300133,3,185,162);
                    cm.spawnMobOnDiffMap(mapt, 9300136,3,295,-138);
                    cm.spawnMobOnDiffMap(mapt, 9300133,3,115,-138);
                    cm.dispose();
                } else {
                    cm.summonMobAtPosition(9300133,3,-111,162);
                    cm.summonMobAtPosition(9300136,3,231,162);
                    cm.summonMobAtPosition(9300136,3,36,162);
                    cm.summonMobAtPosition(9300133,3,185,162);
                    cm.summonMobAtPosition(9300136,3,295,-138);
                    cm.summonMobAtPosition(9300133,3,115,-138);                
                    cm.spawnMobOnDiffMap(map,9300133,3,-111,162);
                    cm.spawnMobOnDiffMap(map, 9300136,3,231,162);
                    cm.spawnMobOnDiffMap(map, 9300136,3,36,162);
                    cm.spawnMobOnDiffMap(map, 9300133,3,185,162);
                    cm.spawnMobOnDiffMap(map, 9300136,3,295,-138);
                    cm.spawnMobOnDiffMap(map, 9300133,3,115,-138);
                }
            }
        } else {
		// THE classic infinite loop array. It increases variable "i" each time "i" is less than the length of the array and its sub arrays. Very useful for listing large amounts of items, mobs, or maps
            txt = "These are the monsters that you can summon on the opposing map. You will spawn a total of #e21#n mobs on the other side each time you select a mob to spawn.";
            for (var i = 0; i < mobs[0].length; i++)
            txt += "\r\n#L"+i+"##o"+mobs[0][i]+"# - #b"+mobs[1][i]+"#k #i"+coin+"#";
            cm.sendSimple(txt);
            }
        } else if (status == 1) {
            if (leave == 1) { // If the party had wanted to leave earlier, this is where they get warped.
                cm.warpParty(980000000);
                cm.dispose();
            } else if (!cm.haveItem(coin, mobs[1][selection])) { // if the # of coins the player has is insufficient to summon hte mob. 
                    cm.sendOk("You cannot summon this monster, #b#o"+mobs[0][selection]+"##k. You are lacking #b"+(mobs[1][selection] - cm.haveItem(coin))+"#k #i"+coin+"#.");
                    cm.dispose();
                } else {
				// the checks below will determine where the monsters are summoned. If the player is in "map", then mobs will be spawned on "mapt". Same with vice versa. There is also a notice to their party that their teammate has just summoned more monsters.
                    if (cm.getMapId()==map) { 
                        cm.mapMessage(5, ""+cm.getPlayer().getName+" has summoned 21 "+mobs[2][selection]+" on the enemy's side!");
                        cm.gainItem(coin, -mobs[1][selection]);
                        cm.spawnMobOnDiffMap(mapt, mobs[0][selection], 7, -207, 162);
                        cm.spawnMobOnDiffMap(mapt,mobs[0][selection], 7, 221, -138);
                        cm.spawnMobOnDiffMap(mapt, mobs[0][selection], 7, 232, 162);
                        cm.dispose();
                    } else {
                        cm.mapMessage(5, ""+cm.getPlayer().getName+" has summoned 21 "+mobs[2][selection]+" on the enemy's side!");
                        cm.gainItem(coin, -mobs[1][selection]);
                        cm.spawnMobOnDiffMap(map, mobs[0][selection], 7, -207, 162);
                        cm.spawnMobOnDiffMap(map,mobs[0][selection], 7, 221, -138);
                        cm.spawnMobOnDiffMap(map, mobs[0][selection], 7, 232, 162);
                        cm.dispose();
                }
            }
        }
    }

tl;dr --> To be simplistic and efficient, I only really needed to use map checks to determine where to spawn monsters and award victories. If you read my script you'll understand why. Any scripter or coder who skims through this will understand immediately.


pastebin:


What does that new script do? An update of new NPC? :p
 
If you read the previous comment that I quoted I was just adding in comments to better explain my script. But yes, there is one new update. It makes it so the other team can now summon mobs. They were unable to previously. It's all in the first sentence in my first post.
 
Great release!
Just a few questions though,

1) Will this work on v117.2 ?
2) Can I change the mob spawned just by editing the MobIDs in Assistant Blue's and Red's Script ?
3) Do i just put all the codes in their respective scripts and put it in the scripts folder where all the NPC's scripts are ?

PS: I'm new to coding ><" pardon me.
Thanks in advance ~
 
Great release!
Just a few questions though,

1) Will this work on v117.2 ?
2) Can I change the mob spawned just by editing the MobIDs in Assistant Blue's and Red's Script ?
3) Do i just put all the codes in their respective scripts and put it in the scripts folder where all the NPC's scripts are ?

PS: I'm new to coding ><" pardon me.
Thanks in advance ~

2013
sounds familiar?

also no cpq in v117
 
I've been hoping someone would release this (or re-release). Been looking for a while.

I don't use moopledev, I use an older revision of shootsource. I'm constantly wondering why the two differ from int or byte, amongst many other things.

So...

Added everything to NPCConversation manager, added the imports, everything going well.
PHP:
    public int getPlayerCount(int mapid) { //DstroyerDev, from Thane Krios
        return c.getChannelServer().getMapFactory().getMap(mapid).getCharacters().size();
    }  
    
    public int countMonster (int map) { //countMonster in MapleMap not getCountMonster
            return c.getChannelServer().getMapFactory().getMap(map).countMonster();
    }

The error I'm getting is with the countMonster:
return c.getChannelServer().getMapFactory().getMap(map).countMonster();

required: int, found: no arguments, reason: actual and formal arguments differ in length

here is my MapleMap method this it is referring to:

PHP:
    public int countMonster(int id) {
        int count = 0;
        for (MapleMapObject m : getMapObjectsInRange(new Point(0, 0), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.MONSTER))) {
            if (((MapleMonster) m).getId() == id) {
                count++;
            }
        }
        return count;
    }

I've messed around a bit, but I can't resolve the issue. I'll promptly admit to being more experienced with java scripts opposed to classes, and any education on why the error is happening, and how to go about fixing it (I do work, no need to spoonfeed), please shed some light my way!
 
Back