Several PQ platform patches + Quest complete count + Fast meso drop

Implemented CPQ challenges using the matching system.
Fixed LanguageConstants statically acting for all players.
Fixed OPQ's <On the Way Up> stage sometimes leading players to unexpected platforms.
Fixed EllinPQ fountain not giving Altaire Fragment to players.
Fixed "Lab - Unit" stage on RnJPQ, now using correlated sequences between the units.
Fixed Fredrick handing out negative values of mesos to players.
Improved "goto" command info.
Implemented quest complete count.
Fixed mobs still being "controlled" by players even though it's already dead.
Concurrently protected adding items into inventory.
Concurrently protected EXP gain through Writs of Solomon.
Adjusted smoothly respawn rate of mobs in map (solo players in a map now experiences 75% of mobs spawned).
Fixed mesos not being able to drop so frequently (prior 200ms threshold between drops).
Tweaked matchchecking so that match checking doesn't outright dispose matching members on dismissal (match still sticks to the player until they answer or timeout).
Fixed a dupe case within storage's item store.
Added any-NPC scriptable to the source.
This commit is contained in:
ronancpl
2019-05-02 11:02:07 -03:00
parent b6a91c523f
commit c2fa7883fe
90 changed files with 1454 additions and 611 deletions

View File

@@ -92,7 +92,7 @@ function playerEntry(eim, player) {
function playerUnregistered(eim, player) {}
function playerExit(eim, player) {
var api = player.getClient().getAbstractPlayerInteraction();
var api = player.getAbstractPlayerInteraction();
api.removeAll(4031507);
api.removeAll(4031508);

View File

@@ -237,7 +237,7 @@ function changedMap(eim, player, mapid) {
function afterChangedMap(eim, player, mapid) {
if (mapid == 990000100) {
var texttt = "So, here is the brief. You guys should be warned that, once out on the fortress outskirts, anyone that would not be equipping the #b#t1032033##k will die instantly due to the deteriorated state of the air around there. That being said, once your team moves out, make sure to #bhit the glowing rocks#k in that region and #bequip the dropped item#k before advancing stages. That will protect you thoroughly from the air sickness. Good luck!";
player.getClient().getAbstractPlayerInteraction().npcTalk(9040000, texttt);
player.getAbstractPlayerInteraction().npcTalk(9040000, texttt);
}
}

View File

@@ -52,7 +52,7 @@ function primeMinisterCheck(eim) {
var pIter = map.getAllPlayers().iterator();
while (pIter.hasNext()) {
var player = pIter.next();
if (player.getQuestStatus(2333) == 1 && player.getClient().getAbstractPlayerInteraction().getQuestProgress(2333, mobId) == 0) {
if (player.getQuestStatus(2333) == 1 && player.getAbstractPlayerInteraction().getQuestProgress(2333, mobId) == 0) {
return true;
}
}

View File

@@ -176,6 +176,33 @@ function shuffle(array) {
return array;
}
function generateStg6Combo(eim) { // thanks Chloek3, seth1 for stating generated sequences are supposed to be linked
var matrix = [];
for (var i = 0; i < 4; i++) {
matrix.push([]);
}
for (var j = 0; j < 10; j++) {
var array = [0, 1, 2, 3];
array = shuffle(array);
for (var i = 0; i < 4; i++) {
matrix[i].push(array[i]);
}
}
for (var i = 0; i < 4; i++) {
var comb = "";
for(var j = 0; j < 10; j++) {
var r = matrix[i][j];
comb += r.toString();
}
eim.setProperty("stage6_comb" + (i + 1), comb);
}
}
function afterSetup(eim) {
eim.setIntProperty("escortFail", 0); // refresh friendly status
@@ -390,6 +417,7 @@ function monsterKilled(mob, eim) {
eim.showClearEffect();
eim.giveEventPlayersStageReward(5);
generateStg6Combo(eim);
map.getReactorByName("jnr6_out").forceHitReactor(1);
}
} else if(mob.getId() == 9300151 || mob.getId() == 9300152) {

View File

@@ -176,6 +176,33 @@ function shuffle(array) {
return array;
}
function generateStg6Combo(eim) {
var matrix = [];
for (var i = 0; i < 4; i++) {
matrix.push([]);
}
for (var j = 0; j < 10; j++) {
var array = [0, 1, 2, 3];
array = shuffle(array);
for (var i = 0; i < 4; i++) {
matrix[i].push(array[i]);
}
}
for (var i = 0; i < 4; i++) {
var comb = "";
for(var j = 0; j < 10; j++) {
var r = matrix[i][j];
comb += r.toString();
}
eim.setProperty("stage6_comb" + (i + 1), comb);
}
}
function afterSetup(eim) {
eim.setIntProperty("escortFail", 0); // refresh friendly status
@@ -390,6 +417,7 @@ function monsterKilled(mob, eim) {
eim.showClearEffect();
eim.giveEventPlayersStageReward(5);
generateStg6Combo(eim);
map.getReactorByName("rnj6_out").forceHitReactor(1);
}
} else if(mob.getId() == 9300139 || mob.getId() == 9300140) {

View File

@@ -180,7 +180,7 @@ function playerEntry(eim, player) {
player.changeMap(map, map.getPortal(0));
var texttt = "Hi, my name is Eak, the Chamberlain of the Goddess. Don't be alarmed; you won't be able to see me right now. Back when the Goddess turned into a block of stone, I simultaneously lost my own power. If you gather up the power of the Magic Cloud of Orbis, however, then I'll be able to recover my body and re-transform back to my original self. Please collect #b20#k Magic Clouds and bring them back to me. Right now, you'll only see me as a tiny, flickering light.";
player.getClient().getAbstractPlayerInteraction().npcTalk(2013001, texttt);
player.getAbstractPlayerInteraction().npcTalk(2013001, texttt);
}
function scheduledTimeout(eim) {

View File

@@ -21,9 +21,13 @@
importPackage(Packages.tools);
var exitMap;
var entryMap;
var exitMap;
var otherMap;
var minMapId = 103040410;
var maxMapId = 103040460;
var minPlayers = 1;
var fightTime = 60;
var timer = 1000 * 60 * fightTime;
@@ -80,7 +84,7 @@ function playerDisconnected(eim, player) {
}
function changedMap(eim, player, mapid) {
if(mapid == exitMap.getId()) {
if (mapid < minMapId || mapid > maxMapId) {
if (eim.isEventTeamLackingNow(true, minPlayers, player)) {
eim.unregisterPlayer(player);
end(eim);

View File

@@ -21,9 +21,13 @@
importPackage(Packages.tools);
var exitMap;
var entryMap;
var exitMap;
var otherMap;
var minMapId = 103040410;
var maxMapId = 103040460;
var minPlayers = 1;
var fightTime = 30;
var timer = 1000 * 60 * fightTime;
@@ -80,7 +84,7 @@ function playerDisconnected(eim, player) {
}
function changedMap(eim, player, mapid) {
if(mapid == exitMap.getId()) {
if (mapid < minMapId || mapid > maxMapId) {
if (eim.isEventTeamLackingNow(true, minPlayers, player)) {
eim.unregisterPlayer(player);
end(eim);

View File

@@ -110,7 +110,7 @@ function respawnStages(eim) {
function playerEntry(eim, player) {
eim.setProperty("giftedItemG" + player.getId(), "0");
eim.setProperty("giftedItemB" + player.getId(), "0");
player.getClient().getAbstractPlayerInteraction().gainItem(4000313, 1);
player.getAbstractPlayerInteraction().gainItem(4000313, 1);
var map = eim.getMapInstance(entryMap);
player.changeMap(map, map.getPortal(0));

View File

@@ -110,7 +110,7 @@ function respawnStages(eim) {
function playerEntry(eim, player) {
eim.setProperty("giftedItemG" + player.getId(), "0");
eim.setProperty("giftedItemB" + player.getId(), "0");
player.getClient().getAbstractPlayerInteraction().gainItem(4000313, 1);
player.getAbstractPlayerInteraction().gainItem(4000313, 1);
var map = eim.getMapInstance(entryMap);
player.changeMap(map, map.getPortal(0));

View File

@@ -8,9 +8,23 @@ function start() {
function action(mode, type, selection) {
cm.warpParty(980000000);
cm.cancelCPQLobby();
cm.dispose();
if (mode == -1) {
cm.dispose();
} else {
if (mode == 0 && status == 0) {
cm.dispose();
return;
}
if (mode == 1)
status++;
else
status--;
if (status == 0) {
cm.warpParty(980000000);
cm.cancelCPQLobby();
cm.dispose();
}
}
}

View File

@@ -69,9 +69,13 @@ function action(mode, type, selection) {
if(state == -1) {
cm.sendOk("Heh, it seems you guys have company. Have fun with them, as I politely request my leave.");
} else if (playersTooClose() || eim.getIntProperty("npcShocked") == 0) {
} else if (playersTooClose()) {
cm.sendOk("Oh, hello there. I have been #bmonitoring your moves#k since you guys entered this perimeter. Quite the feat reaching here, I commend all of you. Now, now, look at the time, I've got an appointment right now, I'm afraid I will need to request my leave. But worry not, my #raccessors#k will deal with all of you. Now, if you permit me, I'm leaving now.");
eim.setIntProperty("yuleteTalked", -1);
} else if (eim.getIntProperty("npcShocked") == 0) {
cm.sendOk("Ho~ Aren't you quite the sneaky one? Well, it matters not. I have been #bmonitoring your moves#k since you guys entered this perimeter. Quite the feat reaching here, I commend all of you. Now, now, look at the time, I've got an appointment right now, I'm afraid I will need to request my leave. But worry not, my #raccessors#k will deal with all of you. Now, if you permit me, I'm leaving now.");
eim.setIntProperty("yuleteTalked", -1);
} else {
cm.sendOk("... Hah! What, wh-- How did you get here?! I though I had sealed all paths here! No matter, this situation will be resolved soon. Guys: DEPLOY the #rmaster weapon#k!! You! Yes, you. Don't you think this ends here, look back at your companions, they need some help! I'll be retreating for now.");

View File

@@ -69,9 +69,13 @@ function action(mode, type, selection) {
if(state == -1) {
cm.sendOk("Heh, it seems you guys have company. Have fun with them, as I politely request my leave.");
} else if (playersTooClose() || eim.getIntProperty("npcShocked") == 0) {
} else if (playersTooClose()) {
cm.sendOk("Oh, hello there. I have been #bmonitoring your moves#k since you guys entered this perimeter. Quite the feat reaching here, I commend all of you. Now, now, look at the time, I've got an appointment right now, I'm afraid I will need to request my leave. But worry not, my #raccessors#k will deal with all of you. Now, if you permit me, I'm leaving now.");
eim.setIntProperty("yuleteTalked", -1);
} else if (eim.getIntProperty("npcShocked") == 0) {
cm.sendOk("Ho~ Aren't you quite the sneaky one? Well, it matters not. I have been #bmonitoring your moves#k since you guys entered this perimeter. Quite the feat reaching here, I commend all of you. Now, now, look at the time, I've got an appointment right now, I'm afraid I will need to request my leave. But worry not, my #raccessors#k will deal with all of you. Now, if you permit me, I'm leaving now.");
eim.setIntProperty("yuleteTalked", -1);
} else {
cm.sendOk("... Hah! What, wh-- How did you get here?! I though I had sealed all paths here! No matter, this situation will be resolved soon. Guys: DEPLOY the #rmaster weapon#k!! You! Yes, you. Don't you think this ends here, look back at your companions, they need some help! I'll be retreating for now.");

View File

@@ -344,7 +344,7 @@ function action(mode, type, selection) {
cm.sendOk("You have already confirmed your vows. All that is left is for your partner to confirm now.");
} else {
eim.setIntProperty("weddingStage", 3);
var cmPartner = partner.getClient().getAbstractPlayerInteraction();
var cmPartner = partner.getAbstractPlayerInteraction();
var playerItemId = detectPlayerItemid(player);
var partnerItemId = (playerItemId % 2 == 1) ? playerItemId + 1 : playerItemId - 1;

View File

@@ -159,7 +159,7 @@ function action(mode, type, selection) {
return;
}
if(!cm.getUnclaimedMarriageGifts().isEmpty() || !partner.getClient().getAbstractPlayerInteraction().getUnclaimedMarriageGifts().isEmpty()) {
if(!cm.getUnclaimedMarriageGifts().isEmpty() || !partner.getAbstractPlayerInteraction().getUnclaimedMarriageGifts().isEmpty()) {
cm.sendOk("Eerhm... I'm sorry, something doesn't seem right according to the Amoria's Wedding Gift Registry reserve. Please check in the situation with #b#p9201014##k.");
cm.dispose();
return;
@@ -178,7 +178,7 @@ function action(mode, type, selection) {
var expirationTime = cserv.getRelativeWeddingTicketExpireTime(resStatus);
cm.gainItem(weddingSendTicket,15,false,true,expirationTime);
partner.getClient().getAbstractPlayerInteraction().gainItem(weddingSendTicket,15,false,true,expirationTime);
partner.getAbstractPlayerInteraction().gainItem(weddingSendTicket,15,false,true,expirationTime);
var placeTime = cserv.getWeddingReservationTimeLeft(weddingId);

View File

@@ -111,7 +111,7 @@ function action(mode, type, selection) {
} else if (status == 1) {
var cmPartner;
try {
cmPartner = cm.getMap().getCharacterById(cm.getPlayer().getPartnerId()).getClient().getAbstractPlayerInteraction();
cmPartner = cm.getMap().getCharacterById(cm.getPlayer().getPartnerId()).getAbstractPlayerInteraction();
} catch(err) {
cmPartner = null;
}

View File

@@ -159,7 +159,7 @@ function action(mode, type, selection) {
return;
}
if(!cm.getUnclaimedMarriageGifts().isEmpty() || !partner.getClient().getAbstractPlayerInteraction().getUnclaimedMarriageGifts().isEmpty()) {
if(!cm.getUnclaimedMarriageGifts().isEmpty() || !partner.getAbstractPlayerInteraction().getUnclaimedMarriageGifts().isEmpty()) {
cm.sendOk("Eerhm... I'm sorry, something doesn't seem right according to the Amoria's Wedding Gift Registry reserve. Please check in the situation with #b#p9201014##k.");
cm.dispose();
return;
@@ -178,7 +178,7 @@ function action(mode, type, selection) {
var expirationTime = cserv.getRelativeWeddingTicketExpireTime(resStatus);
cm.gainItem(weddingSendTicket,15,false,true,expirationTime);
partner.getClient().getAbstractPlayerInteraction().gainItem(weddingSendTicket,15,false,true,expirationTime);
partner.getAbstractPlayerInteraction().gainItem(weddingSendTicket,15,false,true,expirationTime);
var placeTime = cserv.getWeddingReservationTimeLeft(weddingId);

View File

@@ -111,7 +111,7 @@ function action(mode, type, selection) {
} else if (status == 1) {
var cmPartner;
try {
cmPartner = cm.getMap().getCharacterById(cm.getPlayer().getPartnerId()).getClient().getAbstractPlayerInteraction();
cmPartner = cm.getMap().getCharacterById(cm.getPlayer().getPartnerId()).getAbstractPlayerInteraction();
} catch(err) {
cmPartner = null;
}

View File

@@ -214,7 +214,7 @@ function action(mode, type, selection) {
cm.sendOk("You have already confirmed your vows. All that is left is for your partner to confirm now.");
} else {
eim.setIntProperty("weddingStage", 3);
var cmPartner = partner.getClient().getAbstractPlayerInteraction();
var cmPartner = partner.getAbstractPlayerInteraction();
var playerItemId = detectPlayerItemid(player);
var partnerItemId = (playerItemId % 2 == 1) ? playerItemId + 1 : playerItemId - 1;

View File

@@ -47,7 +47,7 @@ function writeFeatureTab_PQs() {
addFeature("Brand-new PQs: BossRushPQ, CafePQ.");
addFeature("Mu Lung Dojo.");
addFeature("Monster Carnival 1 & 2 - thanks Dragohe4rt & Jayd!");
addFeature("AriantPQ - thanks Dragohe4rt!");
addFeature("AriantPQ - thanks Dragohe4rt & Jayd!");
addFeature("Capt. Latanica with party fighting the boss.");
addFeature("Filled up missing obligatory event script methods.");
addFeature("Secured uniquety of active lobby-name instances.");
@@ -222,6 +222,7 @@ function writeFeatureTab_Serverpotentials() {
addFeature("SP cap past tier-level, recovered after job upgrade.");
addFeature("Bypassable PIN/PIC system for authenticated users.");
addFeature("Automatic account registration - thanks shavit!");
addFeature("Any NPC scriptable - thanks GabrielSin!");
}
function writeFeatureTab_Commands() {

View File

@@ -18,10 +18,12 @@ function start(chrs) {
function action(mode, type, selection) {
if (mode == -1) {
cm.answerCPQChallenge(false);
cm.getChar().setChallenged(false);
cm.dispose();
} else {
if (mode == 0) {
cm.answerCPQChallenge(false);
cm.getChar().setChallenged(false);
cm.dispose();
return;
@@ -43,16 +45,16 @@ function action(mode, type, selection) {
snd += "#bName: " + party.get(i).getName() + " / (Level: " + party.get(i).getLevel() + ") / " + GameConstants.getJobName(party.get(i).getJobId()) + "#k\r\n\r\n";
cm.sendAcceptDecline(snd + "Would you like to fight this party at the Monster Carnival?");
} else {
return;
cm.answerCPQChallenge(false);
cm.getChar().setChallenged(false);
cm.dispose();
}
} else if (status == 1) {
var ch = cm.getChrById(party.get(0).getId());
if (party.size() == cm.getParty().getMembers().size()) {
cm.startCPQ(ch, ch.getMapId() + 1);
ch.getParty().setEnemy(cm.getPlayer().getParty());
cm.getChar().getParty().setEnemy(ch.getParty());
cm.getChar().setChallenged(false);
cm.answerCPQChallenge(true);
} else {
cm.answerCPQChallenge(false);
cm.getChar().setChallenged(false);
cm.sendOk("The number of players between the teams is not the same.");
}
cm.dispose();

View File

@@ -18,11 +18,12 @@ function start(chrs) {
function action(mode, type, selection) {
if (mode == -1) {
cm.answerCPQChallenge(false);
cm.getChar().setChallenged(false);
cm.dispose();
} else {
if (mode == 0) {
cm.sendOk("Come back once you have thought about it some more.");
cm.answerCPQChallenge(false);
cm.getChar().setChallenged(false);
cm.dispose();
return;
@@ -44,14 +45,18 @@ function action(mode, type, selection) {
snd += "#bName: " + party.get(i).getName() + " / (Level: " + party.get(i).getLevel() + ") / " + GameConstants.getJobName(party.get(i).getJobId()) + "#k\r\n\r\n";
cm.sendAcceptDecline(snd + "Would you like to fight this party at the Monster Carnival?");
} else {
return;
cm.answerCPQChallenge(false);
cm.getChar().setChallenged(false);
cm.dispose();
}
} else if (status == 1) {
var ch = cm.getChrById(party.get(0).getId());
cm.startCPQ2(ch, ch.getMapId() + 1);
ch.getParty().setEnemy(cm.getPlayer().getParty());
cm.getChar().getParty().setEnemy(ch.getParty());
cm.getChar().setChallenged(false);
if (party.size() == cm.getParty().getMembers().size()) {
cm.answerCPQChallenge(true);
} else {
cm.answerCPQChallenge(false);
cm.getChar().setChallenged(false);
cm.sendOk("The number of players between the teams is not the same.");
}
cm.dispose();
}
}

View File

@@ -35,7 +35,7 @@ function enter(pi) {
return false;
}
} else {
if (em.startInstance(pi.getPlayer(), pi.getMap())) {
if (em.startInstance(pi.getPlayer())) { // thanks RedHat for noticing an issue here
pi.playPortalSound();
return true;
} else {
@@ -57,7 +57,7 @@ function enter(pi) {
return false;
}
} else {
if (em.startInstance(pi.getPlayer(), pi.getMap())) {
if (em.startInstance(pi.getPlayer())) {
pi.playPortalSound();
return true;
} else {

View File

@@ -43,11 +43,11 @@ function enter(pi) {
var pRow = Math.floor(portalId / 10);
var pCol = portalId % 10;
if (pCol == parseInt(comb.substring(pRow, pRow + 1), 10)) { //climb
pi.playPortalSound(); pi.warp(pi.getMapId(), (pRow % 4 != 0) ? pi.getPortal().getId() + 4 : (pRow / 4));
} else { //fail
pi.playPortalSound(); pi.warp(pi.getMapId(), 5);
pRow--;
pi.playPortalSound(); pi.warp(pi.getMapId(), (pRow / 4) > 1 ? (pRow / 4) : 5); // thanks Chloek3, seth1 for noticing next plaform issues
}
return true;

View File

@@ -5,7 +5,8 @@ function enter(pi) {
pi.removeAll(4001169);
pi.removeAll(2270004);
if(pi.getMap().getReactorByName("") != null && pi.getMap().getReactorByName("").getState() == 1) {
var spring = pi.getMap().getReactorById(3008000); // thanks Chloek3, seth1 for noticing fragments not being awarded properly
if(spring != null && spring.getState() > 0) {
if(!pi.canHold(4001198, 1)) {
pi.playerMessage(5, "Check for a free space on your ETC inventory before entering this portal.");
return false;

View File

@@ -25,17 +25,6 @@ function enter(pi) {
var mapplayer = "stage6_comb" + (pi.getMapId() % 10);
var eim = pi.getEventInstance();
if(eim.getProperty(mapplayer) == null) {
var comb = "";
for(var i = 0; i < 10; i++) {
var r = Math.floor((Math.random() * 4));
comb += r.toString();
}
eim.setProperty(mapplayer, comb);
}
var comb = eim.getProperty(mapplayer);
var name = pi.getPortal().getName().substring(2, 4);

View File

@@ -67,10 +67,9 @@ function end(mode, type, selection) {
qm.teachSkill(21000000, qm.getPlayer().getSkillLevel(21000000), 10, -1); // Combo Ability Skill
qm.gainExp(2800);
}
qm.sendNext("(You remembered the #bCombo Ability#k skill! You were skeptical of the training at first, since the old man suffers from Alzheimer's and all, but boy, was it effective!)", 2);
qm.showInfo("Effect/BasicEff.img/AranGetSkill");
qm.sendNext("(You remembered the #bCombo Ability#k skill! You were skeptical of the training at first, since the old man suffers from Alzheimer's and all, but boy, was it effective!)", 2);
} else if (status == 4) {
qm.sendPrev("Now report back to #p1201000#. I know she'll be ecstatic when she sees the progress you've made!");
qm.dispose();
qm.sendPrev("Now report back to #p1201000#. I know she'll be ecstatic when she sees the progress you've made!");
qm.dispose();
}
}

View File

@@ -39,7 +39,6 @@ function end(mode, type, selection) {
qm.teachSkill(21001003, qm.getPlayer().getSkillLevel(21001003), 20, -1);
qm.gainExp(3900);
}
qm.showIntro("Effect/BasicEff.img/AranGetSkill");
qm.sendNext('#b(You remembered the Polearm Booster skill!)#k', 2);
} else if (status == 8) {
qm.sendNextPrev("This skill was found in an ancient incomprehensible script. I had a hunch it might be a skill you used in the past, and I think I was right. You're not as strong as you used to be, but you'll get there, in time.", 8);