Knights' Seal & I. MaxHP + Adherent mob status + Script point-warps

Fixed Seal skill not working for Blaze Wizard.
Added a check against Seal skill on bosses.
Reviewed improper usage of "random spawn point arrival" at several warps on scripts.
Refactored CPQ modules fetching players from the channel storage, this should be unneeded after a recent update on the player object from MPC.
Added door objects as a visible map object for the player server-side view component.
Fixed a few scenarios where mobs would unexpectedly show up impervious to mob status.
Fixed scenario where a player wouldn't receive disease informations from other players after changing maps.
Fixed some magic-type skills (such as Magic Claw or Freeze) not displaying damage value for other players when the player is within melee-range from the mob.
Added check for whether a given quest is scripted before trying to find the script.
Fixed registering items onto MTS leading to loss of a few of its properties (expiration, item level, etc).
Fixed "Improved MaxHP" skill gains not working for Thunderbreakers.
Refactored pet autopot to also apply on HP/MP consumption by items/skills.
Added portal sound effect on Mystic Doors.
This commit is contained in:
ronancpl
2019-09-13 03:04:44 -03:00
parent 259c2e5ba1
commit e169971384
115 changed files with 783 additions and 540 deletions
+3 -5
View File
@@ -12,9 +12,8 @@ Known issues:
- Dragon Roar doesn't show the stun effect to players.
- Cygnus job 'Final Attack' skills not functional.
- Steal skill doesn't deduct the loot from the drop pool from a mob.
- Using Shark Wave with Transformation on female thunderbreakers will cause consecutive attacks to proc immediately.
- Snipe will show much higher damage value than actually applicable to the attacker.
- Some monster status such as freeze and weapon/magic reflect doesn't behave properly in certain scenarios. Freeze seems to not work on mobs with low OID or are starters from server boot time.
- Some monster status such as weapon/magic reflect doesn't behave properly in certain scenarios.
- On low-end connections, things such as command summoning a player that is currently logging in (already visible to other players) may cause the player to freeze, consequently freezing the account as well since the server-side disconnection doesn't happen.
- Reportedly, there are cases where mob positions fail to sync between player's client-view.
- Visual equip EXP watch value will present stuttering for early levels requirement (EXP needed less than 100), and requirement at level 200 will not progress at all due to the level cap in client.
@@ -32,14 +31,13 @@ Missing features list:
---------------------------
** Others **
- Family system
- MTS
---------------------------
---------------------------
** Quest **
- Family & Medal quests.
- Medal quests.
---------------------------
@@ -50,7 +48,7 @@ Missing features list:
---------------------------
** Packet issues & advanced PQs **
- Mystic Doors (won't deploy players properly is some situations, only destination map matches).
- Mystic Doors (won't deploy players properly in some situations, only destination map matches).
- Nett's Pyramid Party Quest
---------------------------
+25 -1
View File
@@ -2111,4 +2111,28 @@ Corrigido informações de mount não sendo atualizado para o jogador assim que
Revisado sistema criado para manutenção de pacotes enviados através do IoSession, tal sistema agora atuando como uma "pool" ao invés de uma "factory".
29 Agosto 2019,
Revisado uso de loop em espera ocupada no sistema de manutenção de pacotes enviados. Em geral, threads que solicitam anúncio de pacotes não necessitam evitar esperar até que cada pacote seja enviado.
Revisado uso de loop em espera ocupada no sistema de manutenção de pacotes enviados. Em geral, threads que solicitam anúncio de pacotes não necessitam evitar esperar até que cada pacote seja enviado.
30 Agosto 2019,
Corrigido skill Seal não atuando devidamente para Blaze Wizard.
Corrigido skill Seal atuando em bosses.
Refatorado funções ainda utilizando invocável desabstraindo o mesmo, assim evitando múltiplos casts de tipo ao decorrer da busca pelo motor de scripts.
02 - 03 Setembro 2019,
Revisado pontos de spawn usados em warps em vários scripts do servidor.
Refatorado métodos da CPQ buscando jogadores pelo storage de canais. Não deveria mais haver necessidade já que a partir de uma atualização recente membros offline contém objeto de jogador nulo, e ao reentrar o MPC já assume o novo objeto de jogador.
05 - 06 Setembro 2019,
Adicionado doors em mapas de cidade como objetos visíveis em campo.
Corrigido aplicação de status de mobs, onde em várias ocasiões os mobs poderiam parecer inafetáveis aos mesmos.
07 Setembro 2019,
Corrigido jogador não recebendo informações de debuffs em outros jogadores ao trocar de mapas.
10 - 12 Setembro 2019,
Corrigido algumas skills de tipo "mágico", que não usam cargas, não mostrando dano para outros jogadores quando golpe ocorre suficientemente perto.
Adicionado checagem por evidência de disponibilidade de scripts em quests.
Corrigido inscrição de itens no MTS levando a certos atributos de itens sendo perdidos no processo.
Adicionado ganho de MaxHP extra da skill para Thunderbreakers, em ambos casos de aumento de nível e de MaxHP usando AP.
Refatorado ação de autopots, permitindo o mesmo a agir imediatamente após detecção de perda suficiente de HP/MP ao usar itens ou skills.
Adicionado efeito sonoro de portal ao atravessar Mystic Door.
+1
View File
@@ -245,6 +245,7 @@ function monsterKilled(mob, eim) {
eim.clearPQ();
eim.dispatchUpdateQuestMobCount(bossMobId, entryMap);
eim.dispatchUpdateQuestMobCount(9101003, entryMap); // thanks Atoot for noticing quest not getting updated after boss kill
mob.getMap().broadcastBalrogVictory(eim.getLeader().getName());
} else {
if(count == 1) {
+1 -1
View File
@@ -24,7 +24,7 @@ function respawn(eim){}
function playerEntry(eim, player){
var cave = eim.getMapInstance(eventMap + 10 * eim.getIntProperty("nex"));
player.changeMap(cave);
player.changeMap(cave, 1);
}
function scheduledTimeout(eim){
+1 -1
View File
@@ -24,7 +24,7 @@ function respawn(eim){}
function playerEntry(eim, player){
var cave = eim.getMapInstance(eventMap);
player.changeMap(cave);
player.changeMap(cave, 1);
}
function scheduledTimeout(eim){
+1 -1
View File
@@ -63,7 +63,7 @@ function respawn(eim) {
function playerEntry(eim, player) {
var amplifierMap = eim.getMapInstance(entryMap.getId());
player.changeMap(amplifierMap);
player.changeMap(amplifierMap, 1);
eim.schedule("timeOut", timer);
}
+1 -1
View File
@@ -63,7 +63,7 @@ function respawn(eim) {
function playerEntry(eim, player) {
var amplifierMap = eim.getMapInstance(entryMap.getId());
player.changeMap(amplifierMap);
player.changeMap(amplifierMap, 1);
eim.schedule("timeOut", timer);
}
+1 -1
View File
@@ -66,7 +66,7 @@ function action(mode, type, selection) {
ticketSelection = selection;
if (ticketSelection > -1) {
cm.gainItem(4031035 + ticketSelection, -1);
cm.warp(103000897 + (ticketSelection * 3));
cm.warp(103000897 + (ticketSelection * 3), "st00"); // thanks IxianMace for noticing a few scripts having misplaced warp SP's
hasTicket = false;
cm.dispose();
return;
+1 -1
View File
@@ -28,6 +28,6 @@ function start() {
cm.gainItem(4031039,1);
else
cm.gainItem(4020000 + ((Math.random()*5)|0), 1);
cm.warp(103000100);
cm.warp(103000100, 0);
cm.dispose();
}
+1 -1
View File
@@ -28,6 +28,6 @@ function start() {
cm.gainItem(4031040,1);
else
cm.gainItem(prizes[parseInt(Math.random() * prizes.length)],1);
cm.warp(103000100);
cm.warp(103000100, 0);
cm.dispose();
}
+1 -1
View File
@@ -28,6 +28,6 @@ function start() {
cm.gainItem(4031041,1);
else
cm.gainItem(prizes[parseInt(Math.random() * prizes.length)],1);
cm.warp(103000100);
cm.warp(103000100, 0);
cm.dispose();
}
+1 -1
View File
@@ -53,7 +53,7 @@ function action(mode, type, selection) {
cm.sendOk("Oh, you don't have the money, right? Sorry, I can't let you in.");
} else {
cm.gainMeso(-5000);
cm.warp(193000000);
cm.warp(193000000, "out00");
}
cm.dispose();
+1 -1
View File
@@ -28,7 +28,7 @@ function action(mode, type, selection) {
}
} else if(status == 1){
if(cm.getEventInstance().isEventCleared()) {
cm.warp(cm.getMapId() == 105100300 ? 105100301 : 105100401);
cm.warp(cm.getMapId() == 105100300 ? 105100301 : 105100401, 0);
} else {
cm.warp(105100100);
}
+1 -1
View File
@@ -69,7 +69,7 @@ function action(mode, type, selection) {
cm.gainItem(4031010, -1);
cm.sendOk("You will have to collect me #b30 #t4031013##k. Good luck.")
} else if (status == 4) {
cm.warp(108000100);
cm.warp(108000100, 0);
cm.dispose();
}
else {
+1 -1
View File
@@ -222,7 +222,7 @@ function action(mode, type, selection) {
cm.sendOk("All the training maps are currently in use. Please try again later.");
cm.dispose();
} else {
cm.warp(map);
cm.warp(map, 0);
cm.dispose();
return;
}
+1 -1
View File
@@ -278,7 +278,7 @@ function action(mode, type, selection) {
if(cm.getMap().countMonsters() > 0) {
cm.sendNext("This is the hidden room of the tower. After eliminating all monsters on this room, talk to me to gain access to the treasure room, leaving the center tower access behind.");
} else {
cm.warp(920011100);
cm.warp(920011100, "st00");
}
break;
}
+1 -1
View File
@@ -33,7 +33,7 @@ var status = 0;
function start() {
if(cm.haveItem(4031450, 1)) {
cm.warp(921100100);
cm.warp(921100100, 1);
cm.dispose();
return;
}
+1 -1
View File
@@ -54,7 +54,7 @@ function action(mode, type, selection) {
cm.sendYesNo("Would you like to leave the bonus stage?");
}
else {
cm.warp(922011100);
cm.warp(922011100, "st00");
cm.dispose();
}
}
+1 -1
View File
@@ -44,7 +44,7 @@ function action(mode, type, selection){
}
else if(status == 1) {
cm.warp(exitMap);
cm.warp(exitMap, "st00");
cm.dispose();
}
}
+1 -1
View File
@@ -34,7 +34,7 @@ function action(mode, type, selection) {
cm.dispose();
else {
if(cm.getMapId() > 240050400) cm.warp(240050600);
else cm.warp(240040700);
else cm.warp(240040700, "out00");
cm.dispose();
}
+1 -1
View File
@@ -330,7 +330,7 @@ function action(mode, type, selection) {
cm.sendYesNo("So, you're giving up? You're really going to leave?");
} else {
if (mode == 1) {
cm.warp(925020002);
cm.warp(925020002, "st00");
}
cm.dispose();
return;
+1 -1
View File
@@ -225,7 +225,7 @@ function action(mode, type, selection) {
cm.sendAcceptDecline("So, you're giving up? You're really going to leave?");
} else {
if (mode == 1) {
cm.warp(925020002);
cm.warp(925020002, "st00");
}
cm.dispose();
}
+1 -1
View File
@@ -30,7 +30,7 @@
*/
function start() {
if(cm.isQuestStarted(3310) && !cm.haveItem(4031709, 1)) {
cm.warp(926120100);
cm.warp(926120100, "out00");
} else {
cm.sendNext("Alchemy....and Alchemist.....both of them are important. But more importantly, it is the Magatia that tolerate everything. The honor of Magatia should be protected by me.");
}
+1 -1
View File
@@ -33,7 +33,7 @@
function start() {
if(cm.isQuestStarted(3335) && !cm.haveItem(4031695, 1)) {
cm.warp(926120300);
cm.warp(926120300, "out00");
cm.dispose();
} else {
cm.sendOk("Emotion that I feel is real? Or just illusion coming from mechanical error?");
+1 -1
View File
@@ -50,7 +50,7 @@ function action(mode, type, selection) {
if(status == 0) {
cm.sendYesNo("We must keep fighting to save Romeo, please keep your pace. If you are not feeling so well to continue, your companions and I will understand... So, are you going to retreat?");
} else if(status == 1) {
cm.warp(926110700);
cm.warp(926110700, 0);
cm.dispose();
}
} else {
+1 -1
View File
@@ -50,7 +50,7 @@ function action(mode, type, selection) {
if(status == 0) {
cm.sendYesNo("We must keep fighting to save Juliet, please keep your pace. If you are not feeling so well to continue, your companions and I will understand... So, are you going to retreat?");
} else if(status == 1) {
cm.warp(926100700);
cm.warp(926100700, 0);
cm.dispose();
}
} else {
+4 -4
View File
@@ -93,7 +93,7 @@ function action(mode, type, selection) {
cm.sendYesNo("We must keep fighting to save Romeo, please keep your pace. If you are not feeling so well to continue, your companions and I will understand... So, are you going to retreat?");
}
} else {
cm.warp(926110700);
cm.warp(926110700, 0);
cm.dispose();
}
} else {
@@ -111,15 +111,15 @@ function action(mode, type, selection) {
if(cm.canHold(4001160)) {
cm.gainItem(4001160, 1);
if(eim.getIntProperty("normalClear") == 1) cm.warp(926110600);
else cm.warp(926110500);
if(eim.getIntProperty("normalClear") == 1) cm.warp(926110600, 0);
else cm.warp(926110500, 0);
} else {
cm.sendOk("Make sure you have a space on your ETC inventory.");
}
cm.dispose();
} else {
cm.warp(926110600);
cm.warp(926110600, 0);
cm.dispose();
}
}
+4 -4
View File
@@ -93,7 +93,7 @@ function action(mode, type, selection) {
cm.sendYesNo("We must keep fighting to save Juliet, please keep your pace. If you are not feeling so well to continue, your companions and I will understand... So, are you going to retreat?");
}
} else {
cm.warp(926100700);
cm.warp(926100700, 0);
cm.dispose();
}
} else {
@@ -111,15 +111,15 @@ function action(mode, type, selection) {
if(cm.canHold(4001159)) {
cm.gainItem(4001159, 1);
if(eim.getIntProperty("normalClear") == 1) cm.warp(926100600);
else cm.warp(926100500);
if(eim.getIntProperty("normalClear") == 1) cm.warp(926100600, 0);
else cm.warp(926100500, 0);
} else {
cm.sendOk("Make sure you have a space on your ETC inventory.");
}
cm.dispose();
} else {
cm.warp(926100600);
cm.warp(926100600, 0);
cm.dispose();
}
}
+1 -1
View File
@@ -51,7 +51,7 @@ function action(mode, type, selection) {
} else {
if(!cm.isQuestCompleted(7770)) cm.completeQuest(7770);
cm.warp(926110600);
cm.warp(926110600, 0);
cm.dispose();
}
}
+2 -2
View File
@@ -92,10 +92,10 @@ function action(mode, type, selection) {
cm.gainItem(4001169, -20);
cm.getEventInstance().warpEventTeam(930000500);
} else {
cm.warp(930000800);
cm.warp(930000800, 0);
}
} else {
cm.warp(930000800);
cm.warp(930000800, 0);
}
cm.dispose();
+1 -1
View File
@@ -19,7 +19,7 @@ function action(mode, type, selection) {
cm.removeAll(4001163);
cm.removeAll(4001169);
cm.removeAll(2270004);
cm.warp(930000800);
cm.warp(930000800, 0);
cm.dispose();
}
}
+1 -1
View File
@@ -25,7 +25,7 @@ function action(mode, type, selection) {
}
} else if(status == 1) {
if (!cm.haveItem(4001163)) {
cm.warp(930000800);
cm.warp(930000800, 0);
} else {
cm.getEventInstance().warpEventTeam(930000600);
}
+1 -1
View File
@@ -59,7 +59,7 @@ function action(mode, type, selection) {
cm.divideTeams();
cm.getEvent().minusLimit();
cm.warp(cm.getEvent().getMapId());
cm.warp(cm.getEvent().getMapId(), 0);
cm.dispose();
} else {
cm.sendNext("Either the event has not been started, you already have the #bScroll of Secrets#k, or you have already participated in this event within the last 24 hours. Please try again later!");
+1 -1
View File
@@ -55,7 +55,7 @@ function action(mode, type, selection) {
cm.sendOk("Very well. Remember, there you can assemble a team or take on the fightings on your own, it's up to you. Good luck!");
} else if(status == 4) {
cm.getPlayer().saveLocation("BOSSPQ");
cm.warp(970030000);
cm.warp(970030000, "out00");
cm.dispose();
}
}
+2 -2
View File
@@ -71,10 +71,10 @@ function action(mode, type, selection) {
cm.warp(980030000, 3);
break;
case 5:
cm.warp(926010000);
cm.warp(926010000, 4);
break;
case 6:
cm.warp(910320000);
cm.warp(910320000, 2);
break;
}
cm.dispose();
+2 -2
View File
@@ -66,10 +66,10 @@ function action(mode, type, selection) {
cm.warp(980030000, 3);
break;
case 5:
cm.warp(926010000);
cm.warp(926010000, 4);
break;
case 6:
cm.warp(910320000);
cm.warp(910320000, 2);
break;
}
cm.dispose();
+1 -1
View File
@@ -45,7 +45,7 @@ function action(mode, type, selection){
if (completed) {
cm.getEventInstance().clearPQ();
} else {
cm.warp(923010100);
cm.warp(923010100, 0);
}
cm.dispose();
+1 -1
View File
@@ -49,7 +49,7 @@ function action(mode, type, selection) {
cm.sendOk("Please check and see if you have " + price + " mesos to enter this place.");
else {
cm.gainMeso(-price);
cm.warp(801000100 + 100 * cm.getPlayer().getGender());
cm.warp(801000100 + 100 * cm.getPlayer().getGender(), "out00");
}
cm.dispose();
}
+1 -1
View File
@@ -50,7 +50,7 @@ function action(mode, type, selection) {
cm.dispose();
}
} else {
cm.warp(801040000);
cm.warp(801040000, "in00");
cm.dispose();
}
}
+2 -2
View File
@@ -30,9 +30,9 @@ function action(mode, type, selection) {
cm.dispose();
} else {
if (mode == 0) {
cm.sendOk("If you want to return to #m801000000#, then talk to me");
cm.sendOk("If you want to return to #m801000000#, then talk to me.");
cm.dispose();
} if (mode == 1) {
} else if (mode == 1) {
status++;
}
if (status == 1) {
+1 -1
View File
@@ -60,7 +60,7 @@ function action(mode, type, selection) {
}
}
cm.warp(541010110);
cm.warp(541010110, 0);
cm.dispose();
}
}
+1 -1
View File
@@ -62,6 +62,7 @@ function writeFeatureTab_Skills() {
addFeature("Chair Mastery - map chair boosts HP/MP rec.");
addFeature("Mu Lung Dojo skills functional.");
addFeature("Monster Magnet skill no longer crashes players.");
addFeature("HP/MP consumption from skills triggers pet autopot.");
}
function writeFeatureTab_Quests() {
@@ -278,7 +279,6 @@ function writeFeatureTab_Project() {
addFeature("Protected many flaws with login management system.");
addFeature("Developed a robust anti-exploit login coordinator.");
addFeature("Revised uniqueness aspect of logged in accounts.");
addFeature("Developed pooling system for IoSession sent packets.");
addFeature("Usage of HikariCP to improve DB connection calls.");
addFeature("Usage of Java Threadpool to improve runnable calls.");
addFeature("Developed many survey tools for content profiling.");
+1 -1
View File
@@ -23,7 +23,7 @@ function action(mode, type, selection){
else if(status == 1){
if(cm.getText() == "Open Sesame"){
if(cm.isQuestCompleted(3925))
cm.warp(260010402);
cm.warp(260010402, 1);
else
cm.playerMessage(5, "Although you said the right answer, the door will not budge.");
+2 -5
View File
@@ -1,8 +1,5 @@
function enter(pi) {
if ( pi.getPlayer().getTeam() == 0 ) {
pi.warp( pi.getMapId() - 100);
} else {
pi.warp( pi.getMapId() - 100);
}
pi.playPortalSound();
pi.warp( pi.getMapId() - 100);
return true;
}
+2 -2
View File
@@ -32,7 +32,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warpParty(dungeonid + i);
pi.warpParty(dungeonid + i, "out00");
return true;
}
}
@@ -44,7 +44,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warp(dungeonid + i);
pi.warp(dungeonid + i, "out00");
return true;
}
}
+2 -2
View File
@@ -34,7 +34,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warpParty(dungeonid + i);
pi.warpParty(dungeonid + i, "out00");
return true;
}
}
@@ -46,7 +46,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warp(dungeonid + i);
pi.warp(dungeonid + i, "out00");
return true;
}
}
+2 -2
View File
@@ -34,7 +34,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warpParty(dungeonid + i);
pi.warpParty(dungeonid + i, "out00");
return true;
}
}
@@ -46,7 +46,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warp(dungeonid + i);
pi.warp(dungeonid + i, "out00");
return true;
}
}
+2 -2
View File
@@ -34,7 +34,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warpParty(dungeonid + i);
pi.warpParty(dungeonid + i, "out00");
return true;
}
}
@@ -46,7 +46,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warp(dungeonid + i);
pi.warp(dungeonid + i, "out00");
return true;
}
}
+2 -2
View File
@@ -34,7 +34,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warpParty(dungeonid + i);
pi.warpParty(dungeonid + i, "out00");
return true;
}
}
@@ -46,7 +46,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warp(dungeonid + i);
pi.warp(dungeonid + i, "out00");
return true;
}
}
+2 -2
View File
@@ -34,7 +34,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warpParty(dungeonid + i);
pi.warpParty(dungeonid + i, "out00");
return true;
}
}
@@ -46,7 +46,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warp(dungeonid + i);
pi.warp(dungeonid + i, "out00");
return true;
}
}
+2 -2
View File
@@ -32,7 +32,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warpParty(dungeonid + i);
pi.warpParty(dungeonid + i, "out00");
return true;
}
}
@@ -44,7 +44,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warp(dungeonid + i);
pi.warp(dungeonid + i, "out00");
return true;
}
}
+2 -2
View File
@@ -32,7 +32,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warpParty(dungeonid + i);
pi.warpParty(dungeonid + i, "out00");
return true;
}
}
@@ -44,7 +44,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warp(dungeonid + i);
pi.warp(dungeonid + i, "out00");
return true;
}
}
+2 -2
View File
@@ -32,7 +32,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warpParty(dungeonid + i);
pi.warpParty(dungeonid + i, "out00");
return true;
}
}
@@ -44,7 +44,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warp(dungeonid + i);
pi.warp(dungeonid + i, "out00");
return true;
}
}
+2 -2
View File
@@ -32,7 +32,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warpParty(dungeonid + i);
pi.warpParty(dungeonid + i, "out00");
return true;
}
}
@@ -44,7 +44,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warp(dungeonid + i);
pi.warp(dungeonid + i, "out00");
return true;
}
}
+2 -2
View File
@@ -32,7 +32,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warpParty(dungeonid + i);
pi.warpParty(dungeonid + i, "out00");
return true;
}
}
@@ -44,7 +44,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warp(dungeonid + i);
pi.warp(dungeonid + i, "out00");
return true;
}
}
+2 -2
View File
@@ -32,7 +32,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warpParty(dungeonid + i);
pi.warpParty(dungeonid + i, "out00");
return true;
}
}
@@ -44,7 +44,7 @@ function enter(pi) {
for (var i = 0; i < dungeons; i++) {
if(pi.startDungeonInstance(dungeonid + i)) {
pi.playPortalSound();
pi.warp(dungeonid + i);
pi.warp(dungeonid + i, "out00");
return true;
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
function enter(pi) {
pi.playPortalSound();
pi.warp(pi.getMapId() + 100);
pi.warp(pi.getMapId() + 100, 0);
return true;
}
+1 -1
View File
@@ -19,7 +19,7 @@
*/
/*
Vs Pink Bean - Ressurection stage portal
Vs Pink Bean - Resurrection stage portal
@author Ronan
*/
+1 -1
View File
@@ -50,7 +50,7 @@ function enter(pi) {
}
} else {
pi.playPortalSound();
pi.warp(922020300);
pi.warp(922020300, 0);
return true;
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
//Author: kevintjuh93
function enter(pi) {
pi.playPortalSound(); pi.warp(922240100 + (pi.getPlayer().getMapId() - 922240000));
pi.playPortalSound(); pi.warp(922240100 + (pi.getPlayer().getMapId() - 922240000), 0);
return true;
}
+1 -1
View File
@@ -1,6 +1,6 @@
function enter(pi) {
if (pi.getMap().getReactorByName("jnr6_out").getState() == 1) {
pi.playPortalSound(); pi.warp(926110300);
pi.playPortalSound(); pi.warp(926110300, 0);
return true;
} else {
pi.playerMessage(5, "The portal is not opened yet.");
+1 -1
View File
@@ -21,7 +21,7 @@
function enter(pi) {
if(pi.isQuestStarted(3935) && !pi.haveItem(4031574, 1)) {
if(pi.getWarpMap(926000010).countPlayers() == 0) {
pi.playPortalSound(); pi.warp(926000010);
pi.playPortalSound(); pi.warp(926000010, 0);
return true;
} else {
pi.message("Someone is already trying this map.");
+1 -1
View File
@@ -24,6 +24,6 @@
@Author Ronan
*/
function enter(pi) {
pi.playPortalSound(); pi.warp(670010800);
pi.playPortalSound(); pi.warp(670010800, 0);
return true;
}
+1 -1
View File
@@ -16,7 +16,7 @@ function start(mode, type, selection) {
} else {
qm.forceStartQuest();
qm.warp(912060200);
qm.warp(912060200, 0);
}
qm.dispose();
}
+1 -1
View File
@@ -48,7 +48,7 @@ function start(mode, type, selection) {
qm.sendOk("There is someone currently in this map, come back later.");
qm.dispose();
} else {
qm.warp(926000000);
qm.warp(926000000, "st00");
qm.forceStartQuest();
qm.dispose();
}
+1 -1
View File
@@ -28,5 +28,5 @@
function act(){
rm.playerMessage(5,"You have found a secret factory!");
rm.warp(Math.random() < .5 ? 922000020 : 922000021);
rm.warp(Math.random() < .5 ? 922000020 : 922000021, 0);
}
+5
View File
@@ -16325,6 +16325,9 @@ CREATE TABLE IF NOT EXISTS `mts_items` (
`position` int(11) DEFAULT '0',
`upgradeslots` int(11) DEFAULT '0',
`level` int(11) DEFAULT '0',
`itemlevel` int(11) NOT NULL DEFAULT '1',
`itemexp` int(11) unsigned NOT NULL DEFAULT '0',
`ringid` int(11) NOT NULL DEFAULT '-1',
`str` int(11) DEFAULT '0',
`dex` int(11) DEFAULT '0',
`int` int(11) DEFAULT '0',
@@ -16348,6 +16351,8 @@ CREATE TABLE IF NOT EXISTS `mts_items` (
`transfer` int(2) DEFAULT '0',
`vicious` int(2) unsigned NOT NULL DEFAULT '0',
`flag` int(2) unsigned NOT NULL DEFAULT '0',
`expiration` bigint(20) NOT NULL DEFAULT '-1',
`giftFrom` varchar(26) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
@@ -26,5 +26,6 @@ package client;
public interface AbstractCharacterListener {
public void onHpChanged(int oldHp);
public void onHpmpPoolUpdate();
public void onStatUpdate();
public void onAnnounceStatPoolUpdate();
}
+10 -1
View File
@@ -220,6 +220,10 @@ public abstract class AbstractMapleCharacterObject extends AbstractAnimatedMaple
listener.onHpmpPoolUpdate();
}
private void dispatchStatUpdated() {
listener.onStatUpdate();
}
private void dispatchStatPoolUpdateAnnounced() {
listener.onAnnounceStatPoolUpdate();
}
@@ -299,6 +303,7 @@ public abstract class AbstractMapleCharacterObject extends AbstractAnimatedMaple
try {
statUpdates.clear();
boolean poolUpdate = false;
boolean statUpdate = false;
if (hpMpPool != null) {
short newHp = (short) (hpMpPool >> 48);
@@ -370,7 +375,7 @@ public abstract class AbstractMapleCharacterObject extends AbstractAnimatedMaple
statUpdates.put(MapleStat.AVAILABLEAP, remainingAp);
}
poolUpdate = true; // recalc stats
statUpdate = true;
}
if (newSp != null) {
@@ -385,6 +390,10 @@ public abstract class AbstractMapleCharacterObject extends AbstractAnimatedMaple
if (poolUpdate) {
dispatchHpmpPoolUpdated();
}
if (statUpdate) {
dispatchStatUpdated();
}
if (!silent) {
dispatchStatPoolUpdateAnnounced();
+79 -24
View File
@@ -91,6 +91,7 @@ import server.life.MobSkillFactory;
import server.maps.FieldLimit;
import server.maps.MapleHiredMerchant;
import server.maps.MapleDoor;
import server.maps.MapleDoorObject;
import server.maps.MapleDragon;
import server.maps.MapleMap;
import server.maps.MapleMapEffect;
@@ -136,6 +137,7 @@ import client.inventory.manipulator.MapleCashidGenerator;
import client.inventory.manipulator.MapleInventoryManipulator;
import client.newyear.NewYearCardRecord;
import client.processor.FredrickProcessor;
import client.processor.PetAutopotProcessor;
import constants.ExpTable;
import constants.GameConstants;
import constants.ItemConstants;
@@ -145,6 +147,7 @@ import constants.skills.Beginner;
import constants.skills.Bishop;
import constants.skills.BlazeWizard;
import constants.skills.Bowmaster;
import constants.skills.Brawler;
import constants.skills.Buccaneer;
import constants.skills.Corsair;
import constants.skills.Crusader;
@@ -166,7 +169,7 @@ import constants.skills.Priest;
import constants.skills.Ranger;
import constants.skills.Shadower;
import constants.skills.Sniper;
import constants.skills.Swordsman;
import constants.skills.Warrior;
import constants.skills.ThunderBreaker;
import org.apache.mina.util.ConcurrentHashSet;
@@ -357,6 +360,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
}
}
@Override
public void onStatUpdate() {
recalcLocalStats();
}
@Override
public void onAnnounceStatPoolUpdate() {
List<Pair<MapleStat, Integer>> statup = new ArrayList<>(8);
@@ -1647,7 +1655,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
for(MapleDoor door : partyDoors.values()) {
for(MapleCharacter pchar : partyMembers) {
door.getTownDoor().sendDestroyData(pchar.getClient(), true);
MapleDoorObject mdo = door.getTownDoor();
mdo.sendDestroyData(pchar.getClient(), true);
pchar.removeVisibleMapObject(mdo);
}
}
@@ -1655,7 +1665,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
Collection<MapleDoor> leaverDoors = partyLeaver.getDoors();
for(MapleDoor door : leaverDoors) {
for(MapleCharacter pchar : partyMembers) {
door.getTownDoor().sendDestroyData(pchar.getClient(), true);
MapleDoorObject mdo = door.getTownDoor();
mdo.sendDestroyData(pchar.getClient(), true);
pchar.removeVisibleMapObject(mdo);
}
}
}
@@ -1666,7 +1678,9 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
if(door != null) {
for(MapleCharacter pchar : partyMembers) {
door.getTownDoor().sendSpawnData(pchar.getClient());
MapleDoorObject mdo = door.getTownDoor();
mdo.sendSpawnData(pchar.getClient());
pchar.addVisibleMapObject(mdo);
}
}
}
@@ -1677,17 +1691,24 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
if(partyDoors != null) {
for(MapleDoor door : partyDoors.values()) {
door.getTownDoor().sendDestroyData(partyLeaver.getClient(), true);
MapleDoorObject mdo = door.getTownDoor();
mdo.sendDestroyData(partyLeaver.getClient(), true);
partyLeaver.removeVisibleMapObject(mdo);
}
}
for(MapleDoor door : leaverDoors) {
door.getTownDoor().sendDestroyData(partyLeaver.getClient(), true);
MapleDoorObject mdo = door.getTownDoor();
mdo.sendDestroyData(partyLeaver.getClient(), true);
partyLeaver.removeVisibleMapObject(mdo);
}
for(MapleDoor door : leaverDoors) {
door.updateDoorPortal(partyLeaver);
door.getTownDoor().sendSpawnData(partyLeaver.getClient());
MapleDoorObject mdo = door.getTownDoor();
mdo.sendSpawnData(partyLeaver.getClient());
partyLeaver.addVisibleMapObject(mdo);
}
}
}
@@ -2697,6 +2718,24 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
}
}
public void collectDiseases() {
for (MapleCharacter chr : map.getAllPlayers()) {
int cid = chr.getId();
for (Entry<MapleDisease, Pair<Long, MobSkill>> di : chr.getAllDiseases().entrySet()) {
MapleDisease disease = di.getKey();
MobSkill skill = di.getValue().getRight();
final List<Pair<MapleDisease, Integer>> debuff = Collections.singletonList(new Pair<>(disease, Integer.valueOf(skill.getX())));
if (disease != MapleDisease.SLOW) {
this.announce(MaplePacketCreator.giveForeignDebuff(cid, debuff, skill));
} else {
this.announce(MaplePacketCreator.giveForeignSlowDebuff(cid, debuff, skill));
}
}
}
}
public void giveDebuff(final MapleDisease disease, MobSkill skill) {
if (!hasDisease(disease) && getDiseasesSize() < 2) {
if (!(disease == MapleDisease.SEDUCE || disease == MapleDisease.STUN)) {
@@ -6063,12 +6102,8 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
}
public boolean hasEntered(String script, int mapId) {
if (entered.containsKey(mapId)) {
if (entered.get(mapId).equals(script)) {
return true;
}
}
return false;
String e = entered.get(mapId);
return script.equals(e);
}
public void hasGivenFame(MapleCharacter to) {
@@ -6416,7 +6451,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
addhp += Randomizer.rand(12, 16);
addmp += Randomizer.rand(10, 12);
} else if (job.isA(MapleJob.WARRIOR) || job.isA(MapleJob.DAWNWARRIOR1)) {
improvingMaxHP = isCygnus() ? SkillFactory.getSkill(DawnWarrior.MAX_HP_INCREASE) : SkillFactory.getSkill(Swordsman.IMPROVED_MAX_HP_INCREASE);
improvingMaxHP = isCygnus() ? SkillFactory.getSkill(DawnWarrior.MAX_HP_INCREASE) : SkillFactory.getSkill(Warrior.IMPROVED_MAXHP);
if (job.isA(MapleJob.CRUSADER)) {
improvingMaxMP = SkillFactory.getSkill(1210000);
} else if (job.isA(MapleJob.DAWNWARRIOR2)) {
@@ -6437,7 +6472,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
addhp += 30000;
addmp += 30000;
} else if (job.isA(MapleJob.PIRATE) || job.isA(MapleJob.THUNDERBREAKER1)) {
improvingMaxHP = isCygnus() ? SkillFactory.getSkill(ThunderBreaker.IMPROVE_MAX_HP) : SkillFactory.getSkill(5100000);
improvingMaxHP = isCygnus() ? SkillFactory.getSkill(ThunderBreaker.IMPROVE_MAX_HP) : SkillFactory.getSkill(Brawler.IMPROVE_MAX_HP);
improvingMaxHPLevel = getSkillLevel(improvingMaxHP);
addhp += Randomizer.rand(22, 28);
addmp += Randomizer.rand(18, 23);
@@ -6446,7 +6481,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
int aids = Randomizer.rand(4, 8);
addmp += aids + Math.floor(aids * 0.1);
}
if (improvingMaxHPLevel > 0 && (job.isA(MapleJob.WARRIOR) || job.isA(MapleJob.PIRATE) || job.isA(MapleJob.DAWNWARRIOR1))) {
if (improvingMaxHPLevel > 0 && (job.isA(MapleJob.WARRIOR) || job.isA(MapleJob.PIRATE) || job.isA(MapleJob.DAWNWARRIOR1) || job.isA(MapleJob.THUNDERBREAKER1))) {
addhp += improvingMaxHP.getEffect(improvingMaxHPLevel).getX();
}
if (improvingMaxMPLevel > 0 && (job.isA(MapleJob.MAGICIAN) || job.isA(MapleJob.CRUSADER) || job.isA(MapleJob.BLAZEWIZARD1))) {
@@ -7920,7 +7955,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
client.announce(MaplePacketCreator.updatePlayerStats(hpmpupdate, true, this));
}
if (oldmaxhp != localmaxhp) {
if (oldmaxhp != localmaxhp) { // thanks Wh1SK3Y for pointing out a deadlock occuring related to party members HP
updatePartyMemberHP();
}
} finally {
@@ -8072,15 +8107,11 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
}
public void resetEnteredScript() {
if (entered.containsKey(map.getId())) {
entered.remove(map.getId());
}
entered.remove(map.getId());
}
public void resetEnteredScript(int mapId) {
if (entered.containsKey(mapId)) {
entered.remove(mapId);
}
entered.remove(mapId);
}
public void resetEnteredScript(String script) {
@@ -9102,11 +9133,35 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
}
updateHpMp(nextHp, nextMp);
return true;
} finally {
statWlock.unlock();
effLock.unlock();
}
// autopot on HPMP deplete... thanks shavit for finding out D. Roar doesn't trigger autopot request
if (hpchange < 0) {
MapleKeyBinding autohpPot = this.getKeymap().get(91);
if (autohpPot != null) {
int autohpItemid = autohpPot.getAction();
Item autohpItem = this.getInventory(MapleInventoryType.USE).findById(autohpItemid);
if (autohpItem != null) {
PetAutopotProcessor.runAutopotAction(client, autohpItem.getPosition(), autohpItemid);
}
}
}
if (mpchange < 0) {
MapleKeyBinding autompPot = this.getKeymap().get(92);
if (autompPot != null) {
int autompItemid = autompPot.getAction();
Item autompItem = this.getInventory(MapleInventoryType.USE).findById(autompItemid);
if (autompItem != null) {
PetAutopotProcessor.runAutopotAction(client, autompItem.getPosition(), autompItemid);
}
}
}
return true;
}
public void setInventory(MapleInventoryType type, MapleInventory inv) {
+5 -1
View File
@@ -217,7 +217,11 @@ public class MapleFamily {
int repsToSenior = rsEntries.getInt("reptosenior");
String precepts = rsEntries.getString("precepts");
//Timestamp lastResetTime = rsEntries.getTimestamp("lastresettime"); //taken care of by FamilyDailyResetWorker
MapleFamily family = Server.getInstance().getWorld(world).getFamily(familyid);
World wserv = Server.getInstance().getWorld(world);
if (wserv == null) {
continue;
}
MapleFamily family = wserv.getFamily(familyid);
if(family == null) {
family = new MapleFamily(familyid, world);
Server.getInstance().getWorld(world).addFamily(familyid, family);
+2 -2
View File
@@ -68,7 +68,7 @@ import constants.skills.Shadower;
import constants.skills.Sniper;
import constants.skills.Spearman;
import constants.skills.SuperGM;
import constants.skills.Swordsman;
import constants.skills.Warrior;
import constants.skills.ThunderBreaker;
import constants.skills.WhiteKnight;
import constants.skills.WindArcher;
@@ -189,7 +189,7 @@ public class SkillFactory {
case Beginner.MONSTER_RIDER:
case Beginner.ECHO_OF_HERO:
case Beginner.MAP_CHAIR:
case Swordsman.IRON_BODY:
case Warrior.IRON_BODY:
case Fighter.AXE_BOOSTER:
case Fighter.POWER_GUARD:
case Fighter.RAGE:
+2 -1
View File
@@ -38,6 +38,7 @@ import constants.skills.BlazeWizard;
import constants.skills.Brawler;
import constants.skills.DawnWarrior;
import constants.skills.Magician;
import constants.skills.ThunderBreaker;
import constants.skills.Warrior;
import java.util.ArrayList;
import java.util.Collection;
@@ -697,7 +698,7 @@ public class AssignAPProcessor {
}
} else if (job.isA(MapleJob.PIRATE) || job.isA(MapleJob.THUNDERBREAKER1)) {
if(!usedAPReset) {
Skill increaseHP = SkillFactory.getSkill(Brawler.IMPROVE_MAX_HP);
Skill increaseHP = SkillFactory.getSkill(job.isA(MapleJob.PIRATE) ? Brawler.IMPROVE_MAX_HP : ThunderBreaker.IMPROVE_MAX_HP);
int sLvl = player.getSkillLevel(increaseHP);
if(sLvl > 0)
@@ -37,7 +37,6 @@ import java.sql.Timestamp;
import java.util.LinkedList;
import java.util.List;
import client.inventory.manipulator.MapleInventoryManipulator;
import constants.ServerConstants;
import java.util.Collections;
import net.server.Server;
import net.server.world.World;
@@ -0,0 +1,178 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
Copyleft (L) 2016 - 2019 RonanLana (HeavenMS)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation version 3 as published by
the Free Software Foundation. You may not use, modify or distribute
this program under any other version of the GNU Affero General Public
License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package client.processor;
import client.MapleCharacter;
import client.MapleClient;
import client.inventory.Item;
import client.inventory.MapleInventory;
import client.inventory.MapleInventoryType;
import client.inventory.manipulator.MapleInventoryManipulator;
import constants.ServerConstants;
import java.util.List;
import server.MapleItemInformationProvider;
import server.MapleStatEffect;
import tools.MaplePacketCreator;
/**
*
* @author Ronan - multi-pot consumption feature
*/
public class PetAutopotProcessor {
private static class AutopotAction {
private MapleClient c;
private short slot;
private int itemId;
private Item toUse;
private List<Item> toUseList;
private boolean hasHpGain, hasMpGain;
private int maxHp, maxMp, curHp, curMp;
private double incHp, incMp;
private boolean cursorOnNextAvailablePot(MapleCharacter chr) {
if(toUseList == null) {
toUseList = chr.getInventory(MapleInventoryType.USE).linkedListById(itemId);
}
toUse = null;
while(!toUseList.isEmpty()) {
Item it = toUseList.remove(0);
if(it.getQuantity() > 0) {
toUse = it;
slot = it.getPosition();
return true;
}
}
return false;
}
public AutopotAction(MapleClient c, short slot, int itemId) {
this.c = c;
this.slot = slot;
this.itemId = itemId;
}
public void run() {
MapleClient c = this.c;
MapleCharacter chr = c.getPlayer();
if (!chr.isAlive()) {
c.announce(MaplePacketCreator.enableActions());
return;
}
int useCount = 0, qtyCount = 0;
MapleStatEffect stat = null;
MapleInventory useInv = chr.getInventory(MapleInventoryType.USE);
useInv.lockInventory();
try {
toUse = useInv.getItem(slot);
if (toUse != null) {
if (toUse.getItemId() != itemId) {
c.announce(MaplePacketCreator.enableActions());
return;
}
toUseList = null;
// from now on, toUse becomes the "cursor" for the current pot being used
if (toUse.getQuantity() <= 0) {
if (!cursorOnNextAvailablePot(chr)) {
c.announce(MaplePacketCreator.enableActions());
return;
}
}
stat = MapleItemInformationProvider.getInstance().getItemEffect(toUse.getItemId());
hasHpGain = stat.getHp() > 0 || stat.getHpRate() > 0.0;
hasMpGain = stat.getMp() > 0 || stat.getMpRate() > 0.0;
maxHp = chr.getCurrentMaxHp();
maxMp = chr.getCurrentMaxMp();
curHp = chr.getHp();
curMp = chr.getMp();
incHp = stat.getHp();
if(incHp <= 0 && hasHpGain) incHp = Math.ceil(maxHp * stat.getHpRate());
incMp = stat.getMp();
if(incMp <= 0 && hasMpGain) incMp = Math.ceil(maxMp * stat.getMpRate());
if (ServerConstants.USE_COMPULSORY_AUTOPOT) {
if (hasHpGain) {
qtyCount = (int) Math.ceil(((ServerConstants.PET_AUTOHP_RATIO * maxHp) - curHp) / incHp);
}
if (hasMpGain) {
qtyCount = Math.max(qtyCount, (int) Math.ceil(((ServerConstants.PET_AUTOMP_RATIO * maxMp) - curMp) / incMp));
}
} else {
qtyCount = 1; // non-compulsory autopot concept thanks to marcuswoon
}
while (true) {
short qtyToUse = (short) Math.min(qtyCount, toUse.getQuantity());
MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, qtyToUse, false);
curHp += (incHp * qtyToUse);
curMp += (incMp * qtyToUse);
useCount += qtyToUse;
qtyCount -= qtyToUse;
if(toUse.getQuantity() == 0 && qtyCount > 0) {
// depleted out the current slot, fetch for more
if(!cursorOnNextAvailablePot(chr)) {
break; // no more pots available
}
} else {
break; // gracefully finished it's job, quit the loop
}
}
}
} finally {
useInv.unlockInventory();
}
for (int i = 0; i < useCount; i++) {
stat.applyTo(chr);
}
chr.announce(MaplePacketCreator.enableActions());
}
}
public static void runAutopotAction(MapleClient c, short slot, int itemid) {
AutopotAction action = new AutopotAction(c, slot, itemid);
action.run();
}
}
+1 -1
View File
@@ -135,7 +135,7 @@ public class ServerConstants {
public static final boolean USE_MAKER_FEE_HEURISTICS = true; //Apply compiled values for stimulants and reagents into the Maker fee calculations (max error revolves around 50k mesos). Set false to use basic constant values instead (results are never higher than requested by the client-side).
//Custom Configuration
public static final boolean USE_ENABLE_CUSTOM_NPC_SCRIPT = true;//Enables usage of custom HeavenMS NPC scripts (Agent E, Coco, etc). Will not disable Abdula (it's actually useful for the gameplay), quests or NPC shops.
public static final boolean USE_ENABLE_CUSTOM_NPC_SCRIPT = true;//Enables usage of custom HeavenMS NPC scripts (Agent E, Coco, etc). Will not disable Abdula (it's actually useful for the gameplay) or quests.
public static final boolean USE_STARTER_MERGE = false; //Allows any players to use the Equipment Merge custom mechanic (as opposed to the high-level, Maker lv3 requisites).
//Commands Configuration
-1
View File
@@ -47,7 +47,6 @@ public class Aran {
public static final int HIDDEN_FULL_TRIPLE = 21110008;
public static final int SMART_KNOCKBACK = 21111001;
public static final int OVER_SWING = 21120002;
public static final int HIGH_DEFENSE = 21120004;
public static final int COMBO_TEMPEST = 21120006;
public static final int COMBO_BARRIER = 21120007;
public static final int HIDDEN_OVER_DOUBLE = 21120009;
-31
View File
@@ -1,31 +0,0 @@
/*
This file is part of the OdinMS Maple Story Server
Copyright (C) 2008 Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation version 3 as published by
the Free Software Foundation. You may not use, modify or distribute
this program under any other version of the GNU Affero General Public
License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package constants.skills;
/**
*
* @author BubblesDev
*/
public class Swordsman {
public static final int IMPROVED_MAX_HP_INCREASE = 1000001;
public static final int IRON_BODY = 1000003;
}
+1
View File
@@ -11,4 +11,5 @@ package constants.skills;
public class Warrior {
public static final int IMPROVED_HPREC = 1000000;
public static final int IMPROVED_MAXHP = 1000001;
public static final int IRON_BODY = 1000003;
}
+14 -6
View File
@@ -677,6 +677,7 @@ public class Server {
MapleCharacter player = c.getPlayer();
if(player != null && player.isLoggedinWorld()) {
player.announceDiseases();
player.collectDiseases();
}
}
@@ -1111,18 +1112,25 @@ public class Server {
public MapleGuild getGuild(int id, int world, MapleCharacter mc) {
synchronized (guilds) {
if (guilds.get(id) != null) {
return guilds.get(id);
MapleGuild g = guilds.get(id);
if (g != null) {
return g;
}
MapleGuild g = new MapleGuild(id, world);
g = new MapleGuild(id, world);
if (g.getId() == -1) {
return null;
}
if(mc != null) {
mc.setMGC(g.getMGC(mc.getId()));
if(g.getMGC(mc.getId()) == null) System.out.println("null for " + mc.getName() + " when loading guild " + id);
g.getMGC(mc.getId()).setCharacter(mc);
MapleGuildCharacter mgc = g.getMGC(mc.getId());
if (mgc != null) {
mc.setMGC(mgc);
mgc.setCharacter(mc);
} else {
FilePrinter.printError(FilePrinter.GUILD_CHAR_ERROR, "Could not find " + mc.getName() + " when loading guild " + id + ".");
}
g.setOnline(mc.getId(), true, mc.getClient().getChannel());
}
@@ -653,16 +653,16 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
// Find the base damage to base futher calculations on.
// Several skills have their own formula in this section.
long calcDmgMax = 0;
long calcDmgMax = 0;
if(magic && ret.skill != 0) {
calcDmgMax = (chr.getTotalMagic() * chr.getTotalMagic() / 1000 + chr.getTotalMagic()) / 30 + chr.getTotalInt() / 200;
if(magic && ret.skill != 0) { // thanks onechord for noticing a few false positives stemming from maxdmg as 0
calcDmgMax = (long) (Math.ceil((chr.getTotalMagic() * Math.ceil(chr.getTotalMagic() / 1000.0) + chr.getTotalMagic()) / 30.0) + Math.ceil(chr.getTotalInt() / 200.0));
} else if(ret.skill == 4001344 || ret.skill == NightWalker.LUCKY_SEVEN || ret.skill == NightLord.TRIPLE_THROW) {
calcDmgMax = (chr.getTotalLuk() * 5) * chr.getTotalWatk() / 100;
calcDmgMax = (long) ((chr.getTotalLuk() * 5) * Math.ceil(chr.getTotalWatk() / 100.0));
} else if(ret.skill == DragonKnight.DRAGON_ROAR) {
calcDmgMax = (chr.getTotalStr() * 4 + chr.getTotalDex()) * chr.getTotalWatk() / 100;
calcDmgMax = (long) ((chr.getTotalStr() * 4 + chr.getTotalDex()) * Math.ceil(chr.getTotalWatk() / 100.0));
} else if(ret.skill == NightLord.VENOMOUS_STAR || ret.skill == Shadower.VENOMOUS_STAB) {
calcDmgMax = (int) (18.5 * (chr.getTotalStr() + chr.getTotalLuk()) + chr.getTotalDex() * 2) / 100 * chr.calculateMaxBaseDamage(chr.getTotalWatk());
calcDmgMax = (long) (Math.ceil((18.5 * (chr.getTotalStr() + chr.getTotalLuk()) + chr.getTotalDex() * 2) / 100.0) * chr.calculateMaxBaseDamage(chr.getTotalWatk()));
} else {
calcDmgMax = chr.calculateMaxBaseDamage(chr.getTotalWatk());
}
@@ -124,7 +124,11 @@ public final class AllianceOperationHandler extends AbstractMaplePacketHandler {
Server.getInstance().resetAllianceGuildPlayersRank(guildid);
chr.getMGC().setAllianceRank(2);
Server.getInstance().getGuild(chr.getGuildId()).getMGC(chr.getId()).setAllianceRank(2);
MapleGuild g = Server.getInstance().getGuild(chr.getGuildId());
if (g != null) {
g.getMGC(chr.getId()).setAllianceRank(2);
}
chr.saveGuildStatus();
Server.getInstance().allianceMessage(alliance.getId(), MaplePacketCreator.addGuildToAlliance(alliance, guildid, c), -1, -1);
@@ -33,7 +33,6 @@ import client.MapleBuffStat;
import client.MapleCharacter;
import client.MapleClient;
import client.MapleJob;
import client.MapleStat;
import client.Skill;
import client.SkillFactory;
import constants.GameConstants;
@@ -47,6 +46,7 @@ import constants.skills.Rogue;
import constants.skills.WindArcher;
public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
MapleCharacter chr = c.getPlayer();
@@ -152,6 +152,12 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
equip.setWdef((short) rs.getInt("wdef"));
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
equip.setLevel((byte) rs.getInt("level"));
equip.setItemLevel(rs.getByte("itemlevel"));
equip.setItemExp(rs.getInt("itemexp"));
equip.setRingId(rs.getInt("ringid"));
equip.setExpiration(rs.getLong("expiration"));
equip.setGiftFrom(rs.getString("giftFrom"));
items.add(new MTSItemInfo((Item) equip, rs.getInt("price") + 100 + (int) (rs.getInt("price") * 0.1), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
}
}
@@ -209,7 +215,12 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
equip.setWdef((short) rs.getInt("wdef"));
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
equip.setLevel((byte) rs.getInt("level"));
equip.setItemLevel(rs.getByte("itemlevel"));
equip.setItemExp(rs.getInt("itemexp"));
equip.setRingId(rs.getInt("ringid"));
equip.setFlag((short) rs.getInt("flag"));
equip.setExpiration(rs.getLong("expiration"));
equip.setGiftFrom(rs.getString("giftFrom"));
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
}
}
@@ -256,7 +267,12 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
equip.setWdef((short) rs.getInt("wdef"));
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
equip.setLevel((byte) rs.getInt("level"));
equip.setItemLevel(rs.getByte("itemlevel"));
equip.setItemExp(rs.getInt("itemexp"));
equip.setRingId(rs.getInt("ringid"));
equip.setFlag((short) rs.getInt("flag"));
equip.setExpiration(rs.getLong("expiration"));
equip.setGiftFrom(rs.getString("giftFrom"));
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
}
}
+69 -32
View File
@@ -160,48 +160,55 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
}
if (!i.getInventoryType().equals(MapleInventoryType.EQUIP)) {
Item item = (Item) i;
ps = con.prepareStatement("INSERT INTO mts_items (tab, type, itemid, quantity, seller, price, owner, sellername, sell_ends) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
ps = con.prepareStatement("INSERT INTO mts_items (tab, type, itemid, quantity, expiration, giftFrom, seller, price, owner, sellername, sell_ends) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
ps.setInt(1, 1);
ps.setInt(2, (int) invType.getType());
ps.setInt(3, item.getItemId());
ps.setInt(4, quantity);
ps.setInt(5, c.getPlayer().getId());
ps.setInt(6, price);
ps.setString(7, item.getOwner());
ps.setString(8, c.getPlayer().getName());
ps.setString(9, date);
ps.setLong(5, item.getExpiration());
ps.setString(6, item.getGiftFrom());
ps.setInt(7, c.getPlayer().getId());
ps.setInt(8, price);
ps.setString(9, item.getOwner());
ps.setString(10, c.getPlayer().getName());
ps.setString(11, date);
} else {
Equip equip = (Equip) i;
ps = con.prepareStatement("INSERT INTO mts_items (tab, type, itemid, quantity, seller, price, upgradeslots, level, str, dex, `int`, luk, hp, mp, watk, matk, wdef, mdef, acc, avoid, hands, speed, jump, locked, owner, sellername, sell_ends, vicious, flag) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
ps = con.prepareStatement("INSERT INTO mts_items (tab, type, itemid, quantity, expiration, giftFrom, seller, price, upgradeslots, level, str, dex, `int`, luk, hp, mp, watk, matk, wdef, mdef, acc, avoid, hands, speed, jump, locked, owner, sellername, sell_ends, vicious, flag, itemexp, itemlevel, ringid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
ps.setInt(1, 1);
ps.setInt(2, (int) invType.getType());
ps.setInt(3, equip.getItemId());
ps.setInt(4, quantity);
ps.setInt(5, c.getPlayer().getId());
ps.setInt(6, price);
ps.setInt(7, equip.getUpgradeSlots());
ps.setInt(8, equip.getLevel());
ps.setInt(9, equip.getStr());
ps.setInt(10, equip.getDex());
ps.setInt(11, equip.getInt());
ps.setInt(12, equip.getLuk());
ps.setInt(13, equip.getHp());
ps.setInt(14, equip.getMp());
ps.setInt(15, equip.getWatk());
ps.setInt(16, equip.getMatk());
ps.setInt(17, equip.getWdef());
ps.setInt(18, equip.getMdef());
ps.setInt(19, equip.getAcc());
ps.setInt(20, equip.getAvoid());
ps.setInt(21, equip.getHands());
ps.setInt(22, equip.getSpeed());
ps.setInt(23, equip.getJump());
ps.setInt(24, 0);
ps.setString(25, equip.getOwner());
ps.setString(26, c.getPlayer().getName());
ps.setString(27, date);
ps.setInt(28, equip.getVicious());
ps.setInt(29, equip.getFlag());
ps.setLong(5, equip.getExpiration());
ps.setString(6, equip.getGiftFrom());
ps.setInt(7, c.getPlayer().getId());
ps.setInt(8, price);
ps.setInt(9, equip.getUpgradeSlots());
ps.setInt(10, equip.getLevel());
ps.setInt(11, equip.getStr());
ps.setInt(12, equip.getDex());
ps.setInt(13, equip.getInt());
ps.setInt(14, equip.getLuk());
ps.setInt(15, equip.getHp());
ps.setInt(16, equip.getMp());
ps.setInt(17, equip.getWatk());
ps.setInt(18, equip.getMatk());
ps.setInt(19, equip.getWdef());
ps.setInt(20, equip.getMdef());
ps.setInt(21, equip.getAcc());
ps.setInt(22, equip.getAvoid());
ps.setInt(23, equip.getHands());
ps.setInt(24, equip.getSpeed());
ps.setInt(25, equip.getJump());
ps.setInt(26, 0);
ps.setString(27, equip.getOwner());
ps.setString(28, c.getPlayer().getName());
ps.setString(29, date);
ps.setInt(30, equip.getVicious());
ps.setInt(31, equip.getFlag());
ps.setInt(32, equip.getItemExp());
ps.setByte(33, equip.getItemLevel()); // thanks Jefe for noticing missing itemlevel labels
ps.setInt(34, equip.getRingId());
}
ps.executeUpdate();
ps.close();
@@ -320,8 +327,13 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
equip.setWdef((short) rs.getInt("wdef"));
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
equip.setLevel((byte) rs.getInt("level"));
equip.setItemLevel(rs.getByte("itemlevel"));
equip.setItemExp(rs.getInt("itemexp"));
equip.setRingId(rs.getInt("ringid"));
equip.setVicious((byte) rs.getInt("vicious"));
equip.setFlag((short) rs.getInt("flag"));
equip.setExpiration(rs.getLong("expiration"));
equip.setGiftFrom(rs.getString("giftFrom"));
equip.setPosition(c.getPlayer().getInventory(ItemConstants.getInventoryType(rs.getInt("itemid"))).getNextFreeSlot());
i = equip.copy();
}
@@ -569,6 +581,11 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
equip.setLevel((byte) rs.getInt("level"));
equip.setFlag((short) rs.getInt("flag"));
equip.setItemLevel(rs.getByte("itemlevel"));
equip.setItemExp(rs.getInt("itemexp"));
equip.setRingId(rs.getInt("ringid"));
equip.setExpiration(rs.getLong("expiration"));
equip.setGiftFrom(rs.getString("giftFrom"));
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
}
}
@@ -623,7 +640,12 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
equip.setWdef((short) rse.getInt("wdef"));
equip.setUpgradeSlots((byte) rse.getInt("upgradeslots"));
equip.setLevel((byte) rse.getInt("level"));
equip.setItemLevel(rs.getByte("itemlevel"));
equip.setItemExp(rs.getInt("itemexp"));
equip.setRingId(rs.getInt("ringid"));
equip.setFlag((short) rs.getInt("flag"));
equip.setExpiration(rs.getLong("expiration"));
equip.setGiftFrom(rs.getString("giftFrom"));
items.add(new MTSItemInfo((Item) equip, rse.getInt("price"), rse.getInt("id"), rse.getInt("seller"), rse.getString("sellername"), rse.getString("sell_ends")));
}
}
@@ -686,7 +708,12 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
equip.setWdef((short) rs.getInt("wdef"));
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
equip.setLevel((byte) rs.getInt("level"));
equip.setItemLevel(rs.getByte("itemlevel"));
equip.setItemExp(rs.getInt("itemexp"));
equip.setRingId(rs.getInt("ringid"));
equip.setFlag((short) rs.getInt("flag"));
equip.setExpiration(rs.getLong("expiration"));
equip.setGiftFrom(rs.getString("giftFrom"));
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
}
}
@@ -747,7 +774,12 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
equip.setWdef((short) rs.getInt("wdef"));
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
equip.setLevel((byte) rs.getInt("level"));
equip.setItemLevel(rs.getByte("itemlevel"));
equip.setItemExp(rs.getInt("itemexp"));
equip.setRingId(rs.getInt("ringid"));
equip.setFlag((short) rs.getInt("flag"));
equip.setExpiration(rs.getLong("expiration"));
equip.setGiftFrom(rs.getString("giftFrom"));
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
}
}
@@ -841,7 +873,12 @@ public final class MTSHandler extends AbstractMaplePacketHandler {
equip.setWdef((short) rs.getInt("wdef"));
equip.setUpgradeSlots((byte) rs.getInt("upgradeslots"));
equip.setLevel((byte) rs.getInt("level"));
equip.setItemLevel(rs.getByte("itemlevel"));
equip.setItemExp(rs.getInt("itemexp"));
equip.setRingId(rs.getInt("ringid"));
equip.setFlag((short) rs.getInt("flag"));
equip.setExpiration(rs.getLong("expiration"));
equip.setGiftFrom(rs.getString("giftFrom"));
items.add(new MTSItemInfo((Item) equip, rs.getInt("price"), rs.getInt("id"), rs.getInt("seller"), rs.getString("sellername"), rs.getString("sell_ends")));
}
}
@@ -62,9 +62,13 @@ public final class MagicDamageHandler extends AbstractDealDamageHandler {
c.announce(MaplePacketCreator.getEnergy("energy", chr.getDojoEnergy()));
}
int charge = (attack.skill == Evan.FIRE_BREATH || attack.skill == Evan.ICE_BREATH || attack.skill == FPArchMage.BIG_BANG || attack.skill == ILArchMage.BIG_BANG || attack.skill == Bishop.BIG_BANG) ? attack.charge : -1;
byte[] packet = MaplePacketCreator.magicAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, charge, attack.speed, attack.direction, attack.display);
byte[] packet;
if ((attack.skill == Evan.FIRE_BREATH || attack.skill == Evan.ICE_BREATH || attack.skill == FPArchMage.BIG_BANG || attack.skill == ILArchMage.BIG_BANG || attack.skill == Bishop.BIG_BANG)) {
packet = MaplePacketCreator.magicAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, attack.charge, attack.speed, attack.direction, attack.display);
} else {
packet = MaplePacketCreator.closeRangeAttack(chr, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, attack.speed, attack.direction, attack.display);
}
chr.getMap().broadcastMessage(chr, packet, false, true);
MapleStatEffect effect = attack.getAttackEffect(chr, null);
Skill skill = SkillFactory.getSkill(attack.skill);
@@ -36,7 +36,6 @@ import server.life.MobSkillFactory;
import server.maps.MapleMap;
import server.maps.MapleMapObject;
import server.maps.MapleMapObjectType;
import server.movement.LifeMovementFragment;
import tools.MaplePacketCreator;
import tools.Pair;
import tools.Randomizer;
@@ -4,167 +4,39 @@
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
Copyleft (L) 2016 - 2018 RonanLana (HeavenMS)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation version 3 as published by
the Free Software Foundation. You may not use, modify or distribute
this program under any other version of the GNU Affero General Public
License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.server.channel.handlers;
import client.MapleClient;
import client.MapleCharacter;
import client.inventory.Item;
import client.inventory.MapleInventory;
import client.inventory.MapleInventoryType;
import client.processor.PetAutopotProcessor;
import net.AbstractMaplePacketHandler;
import client.inventory.manipulator.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import server.MapleStatEffect;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
import constants.ServerConstants;
import java.util.List;
/**
*
* @author Ronan - multi-pot consumption feature
*/
public final class PetAutoPotHandler extends AbstractMaplePacketHandler {
short slot;
int itemId;
Item toUse;
List<Item> toUseList;
boolean hasHpGain, hasMpGain;
int maxHp, maxMp, curHp, curMp;
double incHp, incMp;
@Override
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
if (!c.getPlayer().isAlive()) {
c.announce(MaplePacketCreator.enableActions());
return;
}
slea.readByte();
slea.readLong();
slea.readInt();
slot = slea.readShort();
itemId = slea.readInt();
short slot = slea.readShort();
int itemId = slea.readInt();
MapleCharacter chr = c.getPlayer();
MapleInventory useInv = chr.getInventory(MapleInventoryType.USE);
int useCount = 0, qtyCount = 0;
MapleStatEffect stat = null;
useInv.lockInventory();
try {
toUse = useInv.getItem(slot);
if (toUse != null) {
if (toUse.getItemId() != itemId) {
c.announce(MaplePacketCreator.enableActions());
return;
}
toUseList = null;
// from now on, toUse becomes the "cursor" for the current pot being used
if (toUse.getQuantity() <= 0) {
if (!cursorOnNextAvailablePot(chr)) {
c.announce(MaplePacketCreator.enableActions());
return;
}
}
stat = MapleItemInformationProvider.getInstance().getItemEffect(toUse.getItemId());
hasHpGain = stat.getHp() > 0 || stat.getHpRate() > 0.0;
hasMpGain = stat.getMp() > 0 || stat.getMpRate() > 0.0;
maxHp = chr.getCurrentMaxHp();
maxMp = chr.getCurrentMaxMp();
curHp = chr.getHp();
curMp = chr.getMp();
incHp = stat.getHp();
if(incHp <= 0 && hasHpGain) incHp = Math.ceil(maxHp * stat.getHpRate());
incMp = stat.getMp();
if(incMp <= 0 && hasMpGain) incMp = Math.ceil(maxMp * stat.getMpRate());
if (ServerConstants.USE_COMPULSORY_AUTOPOT) {
if (hasHpGain) {
qtyCount = (int) Math.ceil(((ServerConstants.PET_AUTOHP_RATIO * maxHp) - curHp) / incHp);
}
if (hasMpGain) {
qtyCount = Math.max(qtyCount, (int) Math.ceil(((ServerConstants.PET_AUTOMP_RATIO * maxMp) - curMp) / incMp));
}
} else {
qtyCount = 1; // non-compulsory autopot concept thanks to marcuswoon
}
while (true) {
short qtyToUse = (short) Math.min(qtyCount, toUse.getQuantity());
MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.USE, slot, qtyToUse, false);
curHp += (incHp * qtyToUse);
curMp += (incMp * qtyToUse);
useCount += qtyToUse;
qtyCount -= qtyToUse;
if(toUse.getQuantity() == 0 && qtyCount > 0) {
// depleted out the current slot, fetch for more
if(!cursorOnNextAvailablePot(chr)) {
break; // no more pots available
}
} else {
break; // gracefully finished it's job, quit the loop
}
}
}
} finally {
useInv.unlockInventory();
}
for (int i = 0; i < useCount; i++) {
stat.applyTo(chr);
}
chr.announce(MaplePacketCreator.enableActions());
PetAutopotProcessor.runAutopotAction(c, slot, itemId);
}
private boolean cursorOnNextAvailablePot(MapleCharacter chr) {
if(toUseList == null) {
toUseList = chr.getInventory(MapleInventoryType.USE).linkedListById(itemId);
}
toUse = null;
while(!toUseList.isEmpty()) {
Item it = toUseList.remove(0);
if(it.getQuantity() > 0) {
toUse = it;
slot = it.getPosition();
return true;
}
}
return false;
}
}
@@ -268,11 +268,12 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
if(familyEntry != null) {
familyEntry.setCharacter(player);
player.setFamilyEntry(familyEntry);
c.announce(MaplePacketCreator.getFamilyInfo(familyEntry));
familyEntry.announceToSenior(MaplePacketCreator.sendFamilyLoginNotice(player.getName(), true), true);
} else {
FilePrinter.printError(FilePrinter.FAMILY_ERROR, "Player " + player.getName() + "'s family doesn't have an entry for them. (" + f.getID() + ")");
}
c.announce(MaplePacketCreator.getFamilyInfo(familyEntry));
familyEntry.announceToSenior(MaplePacketCreator.sendFamilyLoginNotice(player.getName(), true), true);
} else {
FilePrinter.printError(FilePrinter.FAMILY_ERROR, "Player " + player.getName() + " has an invalid family ID. (" + player.getFamilyId() + ")");
c.announce(MaplePacketCreator.getFamilyInfo(null));
@@ -379,8 +380,6 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
final List<Pair<MapleDisease, Integer>> debuff = Collections.singletonList(new Pair<>(e.getKey(), Integer.valueOf(e.getValue().getRight().getX())));
c.announce(MaplePacketCreator.giveDebuff(debuff, e.getValue().getRight()));
}
player.announceDiseases();
}
} else {
if(player.isRidingBattleship()) {
@@ -26,6 +26,8 @@ import client.MapleClient;
import java.util.Collections;
import java.util.List;
import net.AbstractMaplePacketHandler;
import server.life.MapleMonster;
import server.maps.MapleMapObject;
import tools.MaplePacketCreator;
import tools.Pair;
import tools.data.input.SeekableLittleEndianAccessor;
@@ -48,5 +50,21 @@ public final class PlayerMapTransitionHandler extends AbstractMaplePacketHandler
final List<Pair<MapleBuffStat, Integer>> stat = Collections.singletonList(new Pair<>(MapleBuffStat.HOMING_BEACON, 0));
chr.announce(MaplePacketCreator.giveBuff(1, beaconid, stat));
}
for (MapleMapObject mo : chr.getMap().getMonsters()) { // thanks BHB, IxianMace, Jefe for noticing several issues regarding mob statuses (such as freeze)
MapleMonster m = (MapleMonster) mo;
if (m.getSpawnEffect() == 0 || m.getHp() < m.getMaxHp()) { // avoid effect-spawning mobs
if (m.getController() == chr) {
c.announce(MaplePacketCreator.stopControllingMonster(m.getObjectId()));
m.sendDestroyData(c);
m.aggroRedirectController();
} else {
m.sendDestroyData(c);
}
m.aggroSwitchController(chr, false);
m.sendSpawnData(c);
}
}
}
}
@@ -244,7 +244,7 @@ public final class TakeDamageHandler extends AbstractMaplePacketHandler {
Skill highDef = SkillFactory.getSkill(Aran.HIGH_DEFENSE);
int hdLevel = chr.getSkillLevel(highDef);
if (highDef != null && hdLevel > 0) {
damage *= (highDef.getEffect(hdLevel).getX() / 1000.0);
damage *= Math.ceil(highDef.getEffect(hdLevel).getX() / 1000.0);
}
}
Integer mesoguard = chr.getBuffedValue(MapleBuffStat.MESOGUARD);
+1 -9
View File
@@ -580,14 +580,6 @@ public class MapleGuild {
}
membersLock.lock();
members.sort(new Comparator<MapleGuildCharacter>() {
@Override
public int compare(MapleGuildCharacter t, MapleGuildCharacter o) {
if(t.getGuildRank() <= 1 && o.getGuildRank() > 1) return -1;
else if(t.getGuildRank() > 1 && o.getGuildRank() <= 1) return 1;
else return 0;
}
});
try {
this.broadcast(MaplePacketCreator.changeRank(mgc));
} finally {
@@ -597,7 +589,7 @@ public class MapleGuild {
public void setGuildNotice(String notice) {
this.notice = notice;
writeToDB(false);
this.writeToDB(false);
membersLock.lock();
try {
+2 -2
View File
@@ -130,7 +130,7 @@ public class MapleParty {
public Collection<MaplePartyCharacter> getMembers() {
lock.lock();
try {
return Collections.unmodifiableList(members);
return new LinkedList<>(members);
} finally {
lock.unlock();
}
@@ -139,7 +139,7 @@ public class MapleParty {
public List<MaplePartyCharacter> getPartyMembers() {
lock.lock();
try {
return Collections.unmodifiableList(members);
return new LinkedList<>(members);
} finally {
lock.unlock();
}
+1 -3
View File
@@ -65,9 +65,7 @@ public abstract class AbstractScriptManager {
}
protected NashornScriptEngine getScriptEngine(String path, MapleClient c) {
String cachePath = "scripts/" + path;
NashornScriptEngine engine = c.getScriptEngine(cachePath);
NashornScriptEngine engine = c.getScriptEngine("scripts/" + path);
if (engine == null) {
engine = getScriptEngine(path);
c.setScriptEngine(path, engine);
+4 -4
View File
@@ -31,7 +31,6 @@ import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.script.Invocable;
import javax.script.ScriptException;
import constants.ServerConstants;
@@ -59,6 +58,7 @@ import java.util.Queue;
import java.util.Set;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import jdk.nashorn.api.scripting.NashornScriptEngine;
import net.server.audit.LockCollector;
import net.server.audit.locks.MonitoredLockType;
import net.server.audit.locks.MonitoredReentrantLock;
@@ -72,7 +72,7 @@ import server.ThreadManager;
* @author Ronan
*/
public class EventManager {
private Invocable iv;
private NashornScriptEngine iv;
private Channel cserv;
private World wserv;
private Server server;
@@ -95,7 +95,7 @@ public class EventManager {
private static final int maxLobbys = 8; // an event manager holds up to this amount of concurrent lobbys
public EventManager(Channel cserv, Invocable iv, String name) {
public EventManager(Channel cserv, NashornScriptEngine iv, String name) {
this.server = Server.getInstance();
this.iv = iv;
this.cserv = cserv;
@@ -256,7 +256,7 @@ public class EventManager {
return cserv;
}
public Invocable getIv() {
public NashornScriptEngine getIv() {
return iv;
}
+6 -6
View File
@@ -27,8 +27,8 @@ import java.util.Map.Entry;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import jdk.nashorn.api.scripting.NashornScriptEngine;
import net.server.channel.Channel;
import scripting.AbstractScriptManager;
@@ -41,11 +41,11 @@ public class EventScriptManager extends AbstractScriptManager {
private class EventEntry {
public EventEntry(Invocable iv, EventManager em) {
public EventEntry(NashornScriptEngine iv, EventManager em) {
this.iv = iv;
this.em = em;
}
public Invocable iv;
public NashornScriptEngine iv;
public EventManager em;
}
private Map<String, EventEntry> events = new LinkedHashMap<>();
@@ -54,7 +54,7 @@ public class EventScriptManager extends AbstractScriptManager {
super();
for (String script : scripts) {
if (!script.equals("")) {
Invocable iv = getScriptEngine("event/" + script + ".js");
NashornScriptEngine iv = getScriptEngine("event/" + script + ".js");
events.put(script, new EventEntry(iv, new EventManager(cserv, iv, script)));
}
}
@@ -71,7 +71,7 @@ public class EventScriptManager extends AbstractScriptManager {
public void init() {
for (EventEntry entry : events.values()) {
try {
((ScriptEngine) entry.iv).put("em", entry.em);
entry.iv.put("em", entry.em);
entry.iv.invokeFunction("init", (Object) null);
} catch (Exception ex) {
Logger.getLogger(EventScriptManager.class.getName()).log(Level.SEVERE, null, ex);
@@ -88,7 +88,7 @@ public class EventScriptManager extends AbstractScriptManager {
Channel cserv = events.values().iterator().next().em.getChannelServer();
for (Entry<String, EventEntry> entry : events.entrySet()) {
String script = entry.getKey();
Invocable iv = getScriptEngine("event/" + script + ".js");
NashornScriptEngine iv = getScriptEngine("event/" + script + ".js");
events.put(script, new EventEntry(iv, new EventManager(cserv, iv, script)));
}
}
+31 -46
View File
@@ -21,23 +21,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package scripting.map;
import client.MapleCharacter;
import client.MapleClient;
import constants.ServerConstants;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.HashMap;
import java.util.Map;
import javax.script.Compilable;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import jdk.nashorn.api.scripting.NashornScriptEngine;
import scripting.AbstractScriptManager;
import tools.FilePrinter;
public class MapScriptManager {
public class MapScriptManager extends AbstractScriptManager {
private static MapScriptManager instance = new MapScriptManager();
@@ -45,7 +41,7 @@ public class MapScriptManager {
return instance;
}
private Map<String, Invocable> scripts = new HashMap<>();
private Map<String, NashornScriptEngine> scripts = new HashMap<>();
private ScriptEngineFactory sef;
private MapScriptManager() {
@@ -57,53 +53,42 @@ public class MapScriptManager {
scripts.clear();
}
public boolean scriptExists(String scriptName, boolean firstUser) {
File scriptFile = new File("scripts/map/" + (firstUser ? "onFirstUserEnter/" : "onUserEnter/") + scriptName + ".js");
return scriptFile.exists();
}
public void runMapScript(MapleClient c, String scriptName, boolean firstUser) {
if (scripts.containsKey(scriptName)) {
public boolean runMapScript(MapleClient c, String mapScriptPath, boolean firstUser) {
if (firstUser) {
MapleCharacter chr = c.getPlayer();
int mapid = chr.getMapId();
if (chr.hasEntered(mapScriptPath, mapid)) {
return false;
} else {
chr.enteredScript(mapScriptPath, mapid);
}
}
NashornScriptEngine iv = scripts.get(mapScriptPath);
if (iv != null) {
try {
scripts.get(scriptName).invokeFunction("start", new MapScriptMethods(c));
iv.invokeFunction("start", new MapScriptMethods(c));
return true;
} catch (final ScriptException | NoSuchMethodException e) {
e.printStackTrace();
}
return;
}
String type = firstUser ? "onFirstUserEnter/" : "onUserEnter/";
File scriptFile = new File("scripts/map/" + type + scriptName + ".js");
if (!scriptExists(scriptName, firstUser)) {
return;
}
FileReader fr = null;
ScriptEngine se = sef.getScriptEngine();
try {
fr = new FileReader(scriptFile);
// java 8 support here thanks to Arufonsu
if (ServerConstants.JAVA_8){
se.eval("load('nashorn:mozilla_compat.js');" + System.lineSeparator());
iv = getScriptEngine("map/" + mapScriptPath + ".js");
if (iv == null) {
return false;
}
((Compilable) se).compile(fr).eval();
final Invocable script = ((Invocable) se);
scripts.put(scriptName, script);
script.invokeFunction("start", new MapScriptMethods(c));
scripts.put(mapScriptPath, iv);
iv.invokeFunction("start", new MapScriptMethods(c));
return true;
} catch (final UndeclaredThrowableException | ScriptException ute) {
FilePrinter.printError(FilePrinter.MAP_SCRIPT + type + scriptName + ".txt", ute);
FilePrinter.printError(FilePrinter.MAP_SCRIPT + mapScriptPath + ".txt", ute);
} catch (final Exception e) {
FilePrinter.printError(FilePrinter.MAP_SCRIPT + type + scriptName + ".txt", e);
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
FilePrinter.printError(FilePrinter.MAP_SCRIPT + mapScriptPath + ".txt", e);
}
return false;
}
}
+14 -19
View File
@@ -679,12 +679,11 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
try {
final MapleMap map, mapExit;
Channel cs = c.getChannelServer();
PlayerStorage ps = cs.getPlayerStorage();
map = cs.getMapFactory().getMap(980000100 + 100 * field);
mapExit = cs.getMapFactory().getMap(980000000);
for (MaplePartyCharacter mpc : c.getPlayer().getParty().getMembers()) {
final MapleCharacter mc = ps.getCharacterById(mpc.getId());
final MapleCharacter mc = mpc.getPlayer();
if (mc != null) {
mc.setChallenged(false);
mc.changeMap(map, map.getPortal(0));
@@ -715,9 +714,8 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
}
public void cancelCPQLobby() {
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
for (MaplePartyCharacter mpc : c.getPlayer().getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
MapleCharacter mc = mpc.getPlayer();
if (mc != null) {
mc.clearCpqTimer();
}
@@ -741,11 +739,11 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
final MapleMap lobbyMap = getPlayer().getMap();
if (challenger != null) {
if (challenger.getParty() == null) {
throw new RuntimeException("Nao existe oponente!");
throw new RuntimeException("No opponent found!");
}
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
MapleCharacter mc = mpc.getPlayer();
if (mc != null) {
mc.changeMap(lobbyMap, lobbyMap.getPortal(0));
TimerManager tMan = TimerManager.getInstance();
@@ -758,7 +756,7 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
}
}
for (MaplePartyCharacter mpc : getPlayer().getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
MapleCharacter mc = mpc.getPlayer();
if (mc != null) {
TimerManager tMan = TimerManager.getInstance();
tMan.schedule(new Runnable() {
@@ -776,15 +774,14 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
@Override
public void run() {
try {
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
for (MaplePartyCharacter mpc : getPlayer().getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
MapleCharacter mc = mpc.getPlayer();
if (mc != null) {
mc.setMonsterCarnival(null);
}
}
for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
MapleCharacter mc = mpc.getPlayer();
if (mc != null) {
mc.setMonsterCarnival(null);
}
@@ -809,11 +806,11 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
final MapleMap lobbyMap = getPlayer().getMap();
if (challenger != null) {
if (challenger.getParty() == null) {
throw new RuntimeException("Não existe oponente!");
throw new RuntimeException("No opponent found!");
}
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
MapleCharacter mc = mpc.getPlayer();
if (mc != null) {
mc.changeMap(lobbyMap, lobbyMap.getPortal(0));
mapClock(10);
@@ -826,15 +823,14 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
@Override
public void run() {
try {
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
for (MaplePartyCharacter mpc : getPlayer().getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
MapleCharacter mc = mpc.getPlayer();
if (mc != null) {
mc.setMonsterCarnival(null);
}
}
for (MaplePartyCharacter mpc : challenger.getParty().getMembers()) {
MapleCharacter mc = ps.getCharacterById(mpc.getId());
MapleCharacter mc = mpc.getPlayer();
if (mc != null) {
mc.setMonsterCarnival(null);
}
@@ -907,12 +903,11 @@ public class NPCConversationManager extends AbstractPlayerInteraction {
try {
final MapleMap map, mapExit;
Channel cs = c.getChannelServer();
PlayerStorage ps = c.getChannelServer().getPlayerStorage();
mapExit = cs.getMapFactory().getMap(980030000);
map = cs.getMapFactory().getMap(980031000 + 1000 * field);
for (MaplePartyCharacter mpc : c.getPlayer().getParty().getMembers()) {
final MapleCharacter mc = ps.getCharacterById(mpc.getId());
final MapleCharacter mc = mpc.getPlayer();
if (mc != null) {
mc.setChallenged(false);
mc.changeMap(map, map.getPortal(0));
+4 -6
View File
@@ -29,8 +29,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import jdk.nashorn.api.scripting.NashornScriptEngine;
@@ -54,10 +52,10 @@ public class NPCScriptManager extends AbstractScriptManager {
}
private Map<MapleClient, NPCConversationManager> cms = new HashMap<>();
private Map<MapleClient, Invocable> scripts = new HashMap<>();
private Map<MapleClient, NashornScriptEngine> scripts = new HashMap<>();
public boolean isNpcScriptAvailable(MapleClient c, String fileName) {
Invocable iv = null;
NashornScriptEngine iv = null;
if (fileName != null) {
iv = getScriptEngine("npc/" + fileName + ".js", c);
}
@@ -96,7 +94,7 @@ public class NPCScriptManager extends AbstractScriptManager {
NashornScriptEngine iv = getScriptEngine("npc/" + filename + ".js", c);
if (iv == null) {
c.getPlayer().dropMessage(1, npc + "");
c.getPlayer().dropMessage(1, "NPC " + npc + " is uncoded.");
cm.dispose();
return;
}
@@ -173,7 +171,7 @@ public class NPCScriptManager extends AbstractScriptManager {
}
public void action(MapleClient c, byte mode, byte type, int selection) {
Invocable iv = scripts.get(c);
NashornScriptEngine iv = scripts.get(c);
if (iv != null) {
try {
c.setClickedNPC();
+19 -44
View File
@@ -22,23 +22,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package scripting.portal;
import client.MapleClient;
import constants.ServerConstants;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.HashMap;
import java.util.Map;
import javax.script.Compilable;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import jdk.nashorn.api.scripting.NashornScriptEngine;
import scripting.AbstractScriptManager;
import server.maps.MaplePortal;
import tools.FilePrinter;
public class PortalScriptManager {
public class PortalScriptManager extends AbstractScriptManager {
private static PortalScriptManager instance = new PortalScriptManager();
@@ -46,7 +40,7 @@ public class PortalScriptManager {
return instance;
}
private Map<String, PortalScript> scripts = new HashMap<>();
private Map<String, NashornScriptEngine> scripts = new HashMap<>();
private ScriptEngineFactory sef;
private PortalScriptManager() {
@@ -54,47 +48,28 @@ public class PortalScriptManager {
sef = sem.getEngineByName("javascript").getFactory();
}
private PortalScript getPortalScript(String scriptName) {
if (scripts.containsKey(scriptName)) {
return scripts.get(scriptName);
private NashornScriptEngine getPortalScript(String scriptName) {
String scriptPath = "portal/" + scriptName + ".js";
NashornScriptEngine iv = scripts.get(scriptPath);
if (iv != null) {
return iv;
}
File scriptFile = new File("scripts/portal/" + scriptName + ".js");
if (!scriptFile.exists()) {
scripts.put(scriptName, null);
iv = getScriptEngine(scriptPath);
if (iv == null) {
return null;
}
FileReader fr = null;
ScriptEngine portal = sef.getScriptEngine();
try {
fr = new FileReader(scriptFile);
// java 8 support here thanks to Arufonsu
if (ServerConstants.JAVA_8){
portal.eval("load('nashorn:mozilla_compat.js');" + System.lineSeparator());
}
((Compilable) portal).compile(fr).eval();
} catch (ScriptException | IOException | UndeclaredThrowableException e) {
FilePrinter.printError(FilePrinter.PORTAL + scriptName + ".txt", e);
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
PortalScript script = ((Invocable) portal).getInterface(PortalScript.class);
scripts.put(scriptName, script);
return script;
scripts.put(scriptPath, iv);
return iv;
}
public boolean executePortalScript(MaplePortal portal, MapleClient c) {
try {
PortalScript script = getPortalScript(portal.getScriptName());
if (script != null) {
return script.enter(new PortalPlayerInteraction(c, portal));
NashornScriptEngine iv = getPortalScript(portal.getScriptName());
if (iv != null) {
boolean couldWarp = (boolean) iv.invokeFunction("enter", new PortalPlayerInteraction(c, portal));
return couldWarp;
}
} catch (UndeclaredThrowableException ute) {
FilePrinter.printError(FilePrinter.PORTAL + portal.getScriptName() + ".txt", ute);

Some files were not shown because too many files have changed in this diff Show More