"Exp-party" Pi + Event script disabled on dispose + Personal loot fix

Refactored event scripts, no longer triggering after the event is deemed disposed.
Added MCPQ access in Dimensional Doors.
Revised Crusader/Dawn Warrior's Combo Attack, no longer resetting orbs after recasting during active time.
Added 4th job advancement handing out Maple Warrior skill book.
Fixed several issues with not being able to collect drops within owned exclusivity time when back-and-forth changing maps.
Revised visual EXP gain. Players that participated most in the defeat of the mob has the gain displayed in white, else yellow, somewhat similar to GMS.
Fixed client not disconnecting properly after closing the game inside MTS/Cash Shop, leading to no update on account's login state.
Fixed wrongly inputted PIC in anti-multiclient system blocking accounts to login under the same IP.
Fixed parameterless command inputs counting as "one empty command".
This commit is contained in:
ronancpl
2019-04-04 14:02:15 -03:00
parent 0b6951527d
commit a15713dfa2
42 changed files with 344 additions and 198 deletions
+1 -2
View File
@@ -5,8 +5,6 @@ Vcoc - Freelance Developer
---------------------------
Known issues:
- Everytime two people click on an npc at the same time, one of them dcs and the other needs to @dispose to talk to the npc.
- If multiple people hit boxes/reactors at the same time, they both dc with invalid pointer error.
- Some criticals (e.g. from Aran skills) will not show up as crit for other players.
- Deadlocks may start appearing if the server stays online long enough with many players logged in.
- If there are multiple bosses that shows HPBar on the map, if a player hits more than one the HPBar may start flickering on the screen.
@@ -57,6 +55,7 @@ Missing features list:
---------------------------
** Skills **
- Check autoban system
- Attack speed reference for autoban, brought here thanks to GitGud: https://ayumilovemaple.wordpress.com/2009/09/06/maplestory-attack-speed-reference/
---------------------------
+19 -1
View File
@@ -1014,7 +1014,7 @@ Modificado sistema de EXP de mounts de forma a favorecer usar Revitalizer quando
Retirado aspecto aleatório de ganho de closeness em pets ao usar o Pet Food, adicionado proteção a acesso concorrente.
Corrigido script da Arwen não retirando itens ao gerar certos itens.
Corrigido script de viagem para Florina levando jogadores a Lith Harbor mesmo quando entrando por outras regiões.
Corrigido Stance, Berserk, Ninja Storm, Concentrate, Mage skills and other 4th job skills questlines.
Corrigido Stance, Berserk, Ninja Storm, Concentrate, Mage skills e outras questlines de skills de 4th job.
Novo release: Light.
05 - 06 Junho 2018,
@@ -1769,6 +1769,24 @@ Corrigido bug na CPQ em tempo estendido não mostrando devidamente o efeito visu
27 Março 2019,
Corrigido possibilidade de bloqueio de volta do jogador ao jogo, ao utilizar o sistema de MTS/Cash Shop. Problema ocorria devido a mudanças concorrentes de login states ao fazer a transição de volta ao jogo.
Corrigido instância de eventos finalizada ainda utilizando os scripts, levando a possíveis inconsistências em jogo. Premissa é: não deveriam existir mais ações de script após se finalizar uma instância.
Ajustado Dimensional Door, agora permitindo jogadores a entrar no saguão de espera das MCPQs.
Corrigido combo resetando orbs ao reusar a skill ainda ativa.
Adicionado ganho de skill book Maple Warrior ao iniciar 4th job.
28 Março 2019,
Corrigido problema com jogador não conseguindo coletar próprio drop se o mesmo estiver em party e for enviado para outro mapa e o mesmo retornar em tempo de exclusividade de coleta.
Corrigido problema com jogador não conseguindo coletar drops de party após o mesmo voltar do MTS/Cash Shop ainda em tempo de exclusividade de coleta.
Corrigido problema com jogador não conseguindo coletar drops com tempo de exclusividade de coleta já expirado.
Revisado visão de ganho de EXP. Jogadores que participaram mais no dano de mob percebem o ganho de EXP em branco, caso contrário em amarelo.
Corrigido possibilidade de congelamento de tela ao tentar trocar de canais. Problema ocorria devido a mudanças concorrentes de login states ao fazer a transição de volta ao jogo.
01 Abril 2019,
Adicionado mensagens ao spawnar mobs em boxes da LMPQ.
Revisado conteúdo de ganho de EXP, onde mensagens de ganho simples (sem "party bonus") aparecem em amarelo caso o jogador ganhou experiência sem qualquer contribuição de dano no mob.
Corrigido cliente não desconectando apropriadamente após fechar o jogo dentro do MTS/Cash Shop, levando a não-update de login state na DB.
Corrigido inserção de PIC errado no sistema anti-multicliente impossibilitando contas de logarem usando um mesmo IP.
04 Abril 2019,
Corrigido comandos sem parâmetros contabilizando feed de "um parâmetro vazio".
Ajustado moderadamente drop rate de vários equipamentos na DB.
+32 -22
View File
@@ -3,6 +3,7 @@ var timeLimit = 15; //15 minutes
var eventTimer = 1000 * 60 * timeLimit;
var exitMap = 240070000;
var eventMap = 240070010;
var eventBossIds = [7120100, 7120101, 7120102, 8120100, 8120101, 8140510];
function init(){}
@@ -43,21 +44,26 @@ function playerRevive(eim, player){
function playerDead(eim, player){}
function playerDisconnected(eim, player) {
var party = eim.getPlayers();
for(var i = 0; i < party.size(); i++){
if(party.get(i).equals(player))
removePlayer(eim, player);
else
playerExit(eim, party.get(i));
if (eim.isEventTeamLackingNow(true, minPlayers, player)) {
eim.unregisterPlayer(player);
end(eim);
}
eim.dispose();
else
eim.unregisterPlayer(player);
}
function monsterValue(eim, mobId){
return -1;
}
function end(eim) {
var party = eim.getPlayers();
for (var i = 0; i < party.size(); i++) {
playerExit(eim, party.get(i));
}
eim.dispose();
}
function leftParty(eim, player){}
function disbandParty(eim){}
@@ -69,28 +75,32 @@ function playerExit(eim, player){
player.changeMap(exitMap);
}
function changedMap(eim, player, mapId){
if(mapId != (eventMap + 10 * eim.getIntProperty("nex"))){
removePlayer(eim, player);
eim.stopEventTimer();
eim.setEventCleared();
eim.dispose();
}
}
function removePlayer(eim, player){
function changedMap(eim, player, mapid){
if (mapid != (eventMap + 10 * eim.getIntProperty("nex"))) {
if (eim.isEventTeamLackingNow(true, minPlayers, player)) {
eim.unregisterPlayer(player);
player.getMap().removePlayer(player);
player.setMap(exitMap);
end(eim);
}
else
eim.unregisterPlayer(player);
}
}
function cancelSchedule(){}
function dispose(){}
function clearPQ(eim){}
function clearPQ(eim){
eim.stopEventTimer();
eim.setEventCleared();
}
function monsterKilled(mob, eim){}
function monsterKilled(mob, eim){
if (mob.getId() == eventBossIds[eim.getIntProperty("nex")]) {
eim.showClearEffect();
eim.clearPQ();
}
}
function allMonstersDead(eim){}
+1 -1
View File
@@ -6,7 +6,7 @@
**/
var cpqMinLvl = 51;
var cpqMaxLvl = 69;
var cpqMaxLvl = 70;
var cpqMinAmt = 2;
var cpqMaxAmt = 6;
+5
View File
@@ -59,6 +59,7 @@ function action(mode, type, selection) {
}
} else if(status == 1) {
if (mode >= 1 && cm.getJobId() % 100 % 10 != 2) {
if (cm.canHold(2280003, 1)) {
cm.changeJobById(cm.getJobId() + 1);
if(cm.getJobId() == 112) {
cm.teachSkill(1121001, 0, 10, -1);
@@ -73,6 +74,10 @@ function action(mode, type, selection) {
cm.teachSkill(1320005, 0, 10, -1);
cm.teachSkill(1321007, 0, 10, -1);
}
cm.gainItem(2280003, 1);
} else {
cm.sendOk("Please have one slot available on #bUSE#k inventory to receive a skill book.");
}
} else if(mode >= 0 && cm.getJobId() % 100 % 10 == 2) {
// TEMP until I can get the quest fixed...
if(cm.getJobId() == 112) {
+5
View File
@@ -60,6 +60,7 @@ function action(mode, type, selection) {
}
} else if(status == 1) {
if (mode >= 1 && cm.getJobId() % 100 % 10 != 2) {
if (cm.canHold(2280003, 1)) {
cm.changeJobById(cm.getJobId() + 1);
if(cm.getJobId() == 212) {
cm.teachSkill(2121001, 0, 10, -1);
@@ -74,6 +75,10 @@ function action(mode, type, selection) {
cm.teachSkill(2321002, 0, 10, -1);
cm.teachSkill(2321005, 0, 10, -1);
}
cm.gainItem(2280003, 1);
} else {
cm.sendOk("Please have one slot available on #bUSE#k inventory to receive a skill book.");
}
} else if( mode >= 1 && cm.getJobId() % 100 % 10 == 2) {
if(cm.getJobId() == 212) {
if(cm.getPlayer().getSkillLevel(2121007) == 0)
+5
View File
@@ -60,6 +60,7 @@ function action(mode, type, selection) {
}
} else if(status == 1) {
if (mode >= 1 && cm.getJobId() % 100 % 10 != 2) {
if (cm.canHold(2280003, 1)) {
cm.changeJobById(cm.getJobId() + 1);
if(cm.getJobId() == 312) {
cm.teachSkill(3121002, 0, 10, -1);
@@ -70,6 +71,10 @@ function action(mode, type, selection) {
cm.teachSkill(3220004, 0, 10, -1);
cm.teachSkill(3221006, 0, 10, -1);
}
cm.gainItem(2280003, 1);
} else {
cm.sendOk("Please have one slot available on #bUSE#k inventory to receive a skill book.");
}
} else if(mode >= 0 && cm.getJobId() % 100 % 10 == 2) {
if(cm.getJobId() == 312) {
if(cm.getPlayer().getSkillLevel(3121008) == 0)
+5
View File
@@ -60,6 +60,7 @@ function action(mode, type, selection) {
}
} else if(status == 1) {
if (mode >= 1 && cm.getJobId() % 100 % 10 != 2) {
if (cm.canHold(2280003, 1)) {
cm.changeJobById(cm.getJobId() + 1);
if(cm.getJobId() == 412) {
cm.teachSkill(4120002, 0, 10, -1);
@@ -70,6 +71,10 @@ function action(mode, type, selection) {
cm.teachSkill(4220005, 0, 10, -1);
cm.teachSkill(4221007, 0, 10, -1);
}
cm.gainItem(2280003, 1);
} else {
cm.sendOk("Please have one slot available on #bUSE#k inventory to receive a skill book.");
}
} else if(mode >= 1 && cm.getJobId() % 100 % 10 == 2) {
if(cm.getJobId() == 412) {
if(cm.getPlayer().getSkillLevel(4121008) == 0)
+5
View File
@@ -60,6 +60,7 @@ function action(mode, type, selection) {
}
} else if(status == 1) {
if (mode >= 1 && cm.getJobId() % 100 % 10 != 2) {
if (cm.canHold(2280003, 1)) {
cm.changeJobById(cm.getJobId() + 1);
if(cm.getJobId() == 512) {
cm.teachSkill(5121001, 0, 10, -1);
@@ -72,6 +73,10 @@ function action(mode, type, selection) {
cm.teachSkill(5221004, 0, 10, -1);
cm.teachSkill(5220011, 0, 10, -1);
}
cm.gainItem(2280003, 1);
} else {
cm.sendOk("Please have one slot available on #bUSE#k inventory to receive a skill book.");
}
} else if(mode >= 1 && cm.getJobId() % 100 % 10 == 2) {
if(cm.getJobId() == 512) {
if(cm.getPlayer().getSkillLevel(5121003) == 0)
+2 -2
View File
@@ -56,10 +56,10 @@ function action(mode, type, selection) {
cm.sendNext("It seems like you want to start your journey without taking the training program. Then, I will let you move on to the training ground. Be careful~");
}else if(status == 1){
cm.warp(1, 0);
dispose();
cm.dispose();
}else{
cm.warp(40000, 0);
dispose();
cm.dispose();
}
}else
if(status == 0)
+5 -2
View File
@@ -33,14 +33,15 @@ function action(mode, type, selection) {
selStr += "#1# Mu Lung Dojo";
}
/*if (cm.getLevel() >= 30 && cm.getLevel() <= 50) { NOT IMPLEMENTED
if (cm.getLevel() >= 30 && cm.getLevel() <= 50) { // MC 1 & 2 recalled thanks to ---
selStr += "#2# Monster Carnival 1";
}
if (cm.getLevel() >= 51 && cm.getLevel() <= 70) { NOT IMPLEMENTED
if (cm.getLevel() >= 51 && cm.getLevel() <= 70) {
selStr += "#3# Monster Carnival 2";
}
/*
if (cm.getLevel() >= 40) { NOT IMPLEMENTED
selStr += "#5# Nett's Pyramid";
}
@@ -62,9 +63,11 @@ function action(mode, type, selection) {
cm.warp(925020000, 0);
break;
case 2:
cm.getPlayer().saveLocation("MONSTER_CARNIVAL");
cm.warp(980000000, 3);
break;
case 3:
cm.getPlayer().saveLocation("MONSTER_CARNIVAL");
cm.warp(980030000, 3);
break;
case 5:
+6
View File
@@ -55,8 +55,14 @@ function end(mode, type, selection) {
qm.dispose();
return;
}
if (!qm.canHold(2280003, 1)) {
qm.sendOk("Hey, your #buse#k inventory is full. I need you to make at least 1 empty slot to complete this quest.");
qm.dispose();
return;
}
qm.gainItem(1142132, true);
qm.gainItem(2280003, 1);
qm.changeJobById(2112);
qm.completeQuest();
+1
View File
@@ -28,4 +28,5 @@
function act(){
rm.spawnMonster(9400210, 2);
rm.spawnMonster(9400209, 2);
rm.mapMessage(5, "Some monsters are summoned.");
}
+1
View File
@@ -28,4 +28,5 @@
function act(){
rm.spawnMonster(9400211, 2);
rm.spawnMonster(9400212, 2);
rm.mapMessage(5, "Some monsters are summoned.");
}
+1
View File
@@ -28,4 +28,5 @@
function act(){
rm.spawnMonster(9400213, 2);
rm.spawnMonster(9400214, 2);
rm.mapMessage(5, "Some monsters are summoned.");
}
+1
View File
@@ -28,4 +28,5 @@
function act(){
rm.spawnMonster(9400215, 2);
rm.spawnMonster(9400216, 2);
rm.mapMessage(5, "Some monsters are summoned.");
}
+1
View File
@@ -28,4 +28,5 @@
function act(){
rm.spawnMonster(9400217, 2);
rm.spawnMonster(9400218, 2);
rm.mapMessage(5, "Some monsters are summoned.");
}
+2
View File
@@ -23914,3 +23914,5 @@ SET minimum_quantity = CASE
WHEN dropperid = 9500369 AND itemid = 2060000 THEN 24
ELSE maximum_quantity END
;
UPDATE drop_data SET `chance`=1287 WHERE `chance`=1500;
+19 -5
View File
@@ -2992,8 +2992,7 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
int equip = (int) Math.min((long)(gain / 10) * pendantExp, Integer.MAX_VALUE);
long total = (long) gain + equip + party;
gainExpInternal(total, equip, party, show, inChat, white);
gainExpInternal((long) gain, equip, party, show, inChat, white);
}
public void loseExp(int loss, boolean show, boolean inChat) {
@@ -3004,8 +3003,23 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
gainExpInternal(-loss, 0, 0, show, inChat, white);
}
private void announceExpGain(long gain, int equip, int party, boolean inChat, boolean white) {
gain = Math.min(gain, Integer.MAX_VALUE);
if (gain == 0) {
if (party == 0) {
return;
}
gain = party;
party = 0;
white = false;
}
client.announce(MaplePacketCreator.getShowExpGain((int) gain, equip, party, inChat, white));
}
private synchronized void gainExpInternal(long gain, int equip, int party, boolean show, boolean inChat, boolean white) { // need of method synchonization here detected thanks to MedicOP
long total = Math.max(gain, -exp.get());
long total = Math.max(gain + equip + party, -exp.get());
if (level < getMaxLevel() && (allowExpGain || this.getEventInstance() != null)) {
long leftover = 0;
@@ -3016,8 +3030,8 @@ public class MapleCharacter extends AbstractMapleCharacterObject {
leftover = nextExp - Integer.MAX_VALUE;
}
updateSingleStat(MapleStat.EXP, exp.addAndGet((int) total));
if (show && gain != 0) {
client.announce(MaplePacketCreator.getShowExpGain((int)Math.min(gain, Integer.MAX_VALUE), equip, party, inChat, white));
if (show) {
announceExpGain(gain, equip, party, inChat, white);
}
while (exp.get() >= ExpTable.getExpNeededForLevel(level)) {
levelUp(true);
+2 -1
View File
@@ -1474,7 +1474,6 @@ public class MapleClient {
player.unregisterChairBuff();
server.getPlayerBuffStorage().addBuffsToStorage(player.getId(), player.getAllBuffs());
server.getPlayerBuffStorage().addDiseasesToStorage(player.getId(), player.getAllDiseases());
player.setSessionTransitionState();
player.setDisconnectedFromChannelWorld();
player.notifyMapTransferToPartner(-1);
player.removeIncomingInvites();
@@ -1491,7 +1490,9 @@ public class MapleClient {
player.getMap().removePlayer(player);
player.clearBanishPlayerData();
player.getClient().getChannelServer().removePlayer(player);
player.getClient().updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
player.setSessionTransitionState();
try {
announce(MaplePacketCreator.getChannelChange(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1])));
} catch (IOException e) {
+1 -1
View File
@@ -113,7 +113,7 @@ public class CommandsExecutor {
return;
}
String[] params;
if (lowercaseParams.length > 0) {
if (lowercaseParams.length > 0 && !lowercaseParams[0].isEmpty()) {
params = Arrays.copyOfRange(lowercaseParams, 0, lowercaseParams.length);
} else {
params = new String[]{};
@@ -53,6 +53,7 @@ public class WarpWorldCommand extends Command {
c.getWorldServer().removePlayer(player);
player.getMap().removePlayer(player);//LOL FORGOT THIS ><
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
player.setSessionTransitionState();
player.setWorld(worldb);
player.saveCharToDB();//To set the new world :O (true because else 2 player instances are created, one in both worlds)
c.announce(MaplePacketCreator.getChannelChange(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1])));
-2
View File
@@ -150,8 +150,6 @@ public class ServerConstants {
public static final float PARTY_BONUS_EXP_RATE = 1.0f; //Rate for the party exp bonus reward.
public static final double PQ_BONUS_EXP_RATE = 0.5; //Rate for the PQ exp reward.
public static final int PARTY_EXPERIENCE_MOD = 1; //Change for event stuff.
//Miscellaneous Configuration
public static String TIMEZONE = "GMT-3";
public static boolean USE_DISPLAY_NUMBERS_WITH_COMMA = true; //Enforce comma on displayed strings (use this when USE_UNITPRICE_WITH_COMMA is active and you still want to display comma-separated values).
+1
View File
@@ -329,6 +329,7 @@ public enum SendOpcode {
CHARGE_PARAM_RESULT(0x143),
QUERY_CASH_RESULT(0x144),
CASHSHOP_OPERATION(0x145),
CASHSHOP_PURCHASE_EXP_CHANGED(0x146), // found thanks to Arnah (Vertisy)
CASHSHOP_GIFT_INFO_RESULT(0x147),
CASHSHOP_CHECK_NAME_CHANGE(0x148),
CASHSHOP_CHECK_NAME_CHANGE_POSSIBLE_RESULT(0x149),
@@ -25,6 +25,7 @@ import net.AbstractMaplePacketHandler;
import server.CashShop;
import tools.data.input.SeekableLittleEndianAccessor;
import tools.MaplePacketCreator;
import tools.Pair;
/**
*
@@ -36,11 +37,14 @@ public class CashShopSurpriseHandler extends AbstractMaplePacketHandler {
CashShop cs = c.getPlayer().getCashShop();
if(cs.isOpened()) {
Item cssItem = cs.openCashShopSurprise();
Pair<Item, Item> cssResult = cs.openCashShopSurprise();
if(cssItem != null) {
if(cssResult != null) {
//Item cssItem = cssResult.getLeft(), cssBox = cssResult.getRight();
//c.announce(MaplePacketCreator.onCashGachaponOpenSuccess(c.getAccID(), cssBox.getSN(), cssBox.getQuantity(), cssItem, cssItem.getItemId(), cssItem.getQuantity(), true));
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0xA4));
} else {
//c.announce(MaplePacketCreator.onCashItemGachaponOpenFailed());
c.announce(MaplePacketCreator.showCashShopMessage((byte) 0x00));
}
}
@@ -61,7 +61,9 @@ public final class ChangeMapHandler extends AbstractMaplePacketHandler {
}
String[] socket = c.getChannelServer().getIP().split(":");
chr.getCashShop().open(false);
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
chr.setSessionTransitionState();
try {
c.announce(MaplePacketCreator.getChannelChange(InetAddress.getByName(socket[0]), Integer.parseInt(socket[1])));
} catch (UnknownHostException ex) {
@@ -65,7 +65,6 @@ public class EnterCashShopHandler extends AbstractMaplePacketHandler {
mc.unregisterChairBuff();
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(mc.getId(), mc.getAllBuffs());
Server.getInstance().getPlayerBuffStorage().addDiseasesToStorage(mc.getId(), mc.getAllDiseases());
mc.setSessionTransitionState();
mc.setAwayFromChannelWorld();
mc.notifyMapTransferToPartner(-1);
mc.removeIncomingInvites();
@@ -91,7 +91,6 @@ public final class EnterMTSHandler extends AbstractMaplePacketHandler {
chr.unregisterChairBuff();
Server.getInstance().getPlayerBuffStorage().addBuffsToStorage(chr.getId(), chr.getAllBuffs());
Server.getInstance().getPlayerBuffStorage().addDiseasesToStorage(chr.getId(), chr.getAllDiseases());
chr.setSessionTransitionState();
chr.setAwayFromChannelWorld();
chr.notifyMapTransferToPartner(-1);
chr.removeIncomingInvites();
@@ -439,7 +439,7 @@ public class MapleSessionCoordinator {
}
try {
String nibbleHwid = (String) session.removeAttribute(MapleClient.CLIENT_NIBBLEHWID);
String nibbleHwid = (String) session.getAttribute(MapleClient.CLIENT_NIBBLEHWID); // thanks Paxum for noticing account stuck after PIC failure
if (nibbleHwid != null) {
onlineRemoteHwids.remove(nibbleHwid);
@@ -51,11 +51,6 @@ public class CharSelectedWithPicHandler extends AbstractMaplePacketHandler {
c.updateHWID(hwid);
IoSession session = c.getSession();
AntiMulticlientResult res = MapleSessionCoordinator.getInstance().attemptGameSession(session, c.getAccID(), hwid);
if (res != AntiMulticlientResult.SUCCESS) {
c.announce(MaplePacketCreator.getAfterLoginError(parseAntiMulticlientError(res)));
return;
}
if (c.hasBannedMac() || c.hasBannedHWID()) {
MapleSessionCoordinator.getInstance().closeSession(c.getSession(), true);
@@ -82,6 +77,12 @@ public class CharSelectedWithPicHandler extends AbstractMaplePacketHandler {
return;
}
AntiMulticlientResult res = MapleSessionCoordinator.getInstance().attemptGameSession(session, c.getAccID(), hwid);
if (res != AntiMulticlientResult.SUCCESS) {
c.announce(MaplePacketCreator.getAfterLoginError(parseAntiMulticlientError(res)));
return;
}
server.unregisterLoginState(c);
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
server.setCharacteridInTransition(session, charId);
@@ -59,11 +59,6 @@ public class ViewAllCharSelectedWithPicHandler extends AbstractMaplePacketHandle
}
IoSession session = c.getSession();
AntiMulticlientResult res = MapleSessionCoordinator.getInstance().attemptGameSession(session, c.getAccID(), hwid);
if (res != AntiMulticlientResult.SUCCESS) {
c.announce(MaplePacketCreator.getAfterLoginError(parseAntiMulticlientError(res)));
return;
}
Server server = Server.getInstance();
if(!server.haveCharacterEntry(c.getAccID(), charId)) {
@@ -88,6 +83,12 @@ public class ViewAllCharSelectedWithPicHandler extends AbstractMaplePacketHandle
return;
}
AntiMulticlientResult res = MapleSessionCoordinator.getInstance().attemptGameSession(session, c.getAccID(), hwid);
if (res != AntiMulticlientResult.SUCCESS) {
c.announce(MaplePacketCreator.getAfterLoginError(parseAntiMulticlientError(res)));
return;
}
server.unregisterLoginState(c);
c.updateLoginState(MapleClient.LOGIN_SERVER_TRANSITION);
server.setCharacteridInTransition(session, charId);
+34 -37
View File
@@ -22,8 +22,6 @@
package scripting.event;
import java.io.File;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import tools.Pair;
import java.util.ArrayList;
import java.util.LinkedList;
@@ -51,20 +49,12 @@ import server.life.MapleMonster;
import server.maps.MapleMap;
import server.maps.MapleMapFactory;
import server.maps.MapleReactor;
import tools.DatabaseConnection;
import client.MapleCharacter;
import client.SkillFactory;
import client.Skill;
import client.inventory.Item;
import client.inventory.ItemFactory;
import client.inventory.MapleInventory;
import client.inventory.MapleInventoryType;
import client.inventory.manipulator.MapleInventoryManipulator;
import constants.ItemConstants;
import constants.ServerConstants;
import java.awt.Point;
import java.sql.Connection;
import java.util.Arrays;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
@@ -79,7 +69,6 @@ import server.ThreadManager;
import server.life.MapleLifeFactory;
import server.life.MapleNPC;
import tools.MaplePacketCreator;
import tools.Randomizer;
/**
*
@@ -237,6 +226,14 @@ public class EventInstanceManager {
}
public Object invokeScriptFunction(String name, Object... args) throws ScriptException, NoSuchMethodException {
if (!disposed) {
return em.getIv().invokeFunction(name, args);
} else {
return null;
}
}
public synchronized void registerPlayer(final MapleCharacter chr) {
registerPlayer(chr, true);
}
@@ -260,7 +257,7 @@ public class EventInstanceManager {
if (runEntryScript) {
try {
em.getIv().invokeFunction("playerEntry", EventInstanceManager.this, chr);
invokeScriptFunction("playerEntry", EventInstanceManager.this, chr);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
@@ -275,7 +272,7 @@ public class EventInstanceManager {
unregisterPlayer(chr);
try {
em.getIv().invokeFunction("playerExit", EventInstanceManager.this, chr);
invokeScriptFunction("playerExit", EventInstanceManager.this, chr);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
@@ -306,7 +303,7 @@ public class EventInstanceManager {
dismissEventTimer();
try {
em.getIv().invokeFunction("scheduledTimeout", EventInstanceManager.this);
invokeScriptFunction("scheduledTimeout", EventInstanceManager.this);
} catch (ScriptException | NoSuchMethodException ex) {
Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, "Event '" + em.getName() + "' does not implement scheduledTimeout function.", ex);
}
@@ -326,7 +323,7 @@ public class EventInstanceManager {
dismissEventTimer();
try {
em.getIv().invokeFunction("scheduledTimeout", EventInstanceManager.this);
invokeScriptFunction("scheduledTimeout", EventInstanceManager.this);
} catch (ScriptException | NoSuchMethodException ex) {
Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, "Event '" + em.getName() + "' does not implement scheduledTimeout function.", ex);
}
@@ -395,7 +392,7 @@ public class EventInstanceManager {
public void unregisterPlayer(final MapleCharacter chr) {
try {
em.getIv().invokeFunction("playerUnregistered", EventInstanceManager.this, chr);
invokeScriptFunction("playerUnregistered", EventInstanceManager.this, chr);
} catch (ScriptException | NoSuchMethodException ex) {
Logger.getLogger(EventManager.class.getName()).log(Level.SEVERE, "Event '" + em.getName() + "' does not implement playerUnregistered function.", ex);
}
@@ -456,7 +453,7 @@ public class EventInstanceManager {
public void movePlayer(final MapleCharacter chr) {
try {
em.getIv().invokeFunction("moveMap", EventInstanceManager.this, chr);
invokeScriptFunction("moveMap", EventInstanceManager.this, chr);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
@@ -464,19 +461,19 @@ public class EventInstanceManager {
public void changedMap(final MapleCharacter chr, final int mapId) {
try {
em.getIv().invokeFunction("changedMap", EventInstanceManager.this, chr, mapId);
invokeScriptFunction("changedMap", EventInstanceManager.this, chr, mapId);
} catch (ScriptException | NoSuchMethodException ex) {} // optional
}
public void afterChangedMap(final MapleCharacter chr, final int mapId) {
try {
em.getIv().invokeFunction("afterChangedMap", EventInstanceManager.this, chr, mapId);
invokeScriptFunction("afterChangedMap", EventInstanceManager.this, chr, mapId);
} catch (ScriptException | NoSuchMethodException ex) {} // optional
}
public synchronized void changedLeader(final MapleCharacter ldr) {
try {
em.getIv().invokeFunction("changedLeader", EventInstanceManager.this, ldr);
invokeScriptFunction("changedLeader", EventInstanceManager.this, ldr);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
@@ -504,14 +501,14 @@ public class EventInstanceManager {
if (scriptResult > 0) {
try {
em.getIv().invokeFunction("monsterKilled", mob, EventInstanceManager.this, hasKiller);
invokeScriptFunction("monsterKilled", mob, EventInstanceManager.this, hasKiller);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
if (scriptResult > 1) {
try {
em.getIv().invokeFunction("allMonstersDead", EventInstanceManager.this, hasKiller);
invokeScriptFunction("allMonstersDead", EventInstanceManager.this, hasKiller);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
@@ -521,7 +518,7 @@ public class EventInstanceManager {
public void friendlyKilled(final MapleMonster mob, final boolean hasKiller) {
try {
em.getIv().invokeFunction("friendlyKilled", mob, EventInstanceManager.this, hasKiller);
invokeScriptFunction("friendlyKilled", mob, EventInstanceManager.this, hasKiller);
} catch (ScriptException | NoSuchMethodException ex) {} //optional
}
@@ -530,7 +527,7 @@ public class EventInstanceManager {
@Override
public void run() {
try {
em.getIv().invokeFunction("playerDead", EventInstanceManager.this, chr);
invokeScriptFunction("playerDead", EventInstanceManager.this, chr);
} catch (ScriptException | NoSuchMethodException ex) {} // optional
}
});
@@ -538,13 +535,13 @@ public class EventInstanceManager {
public void reviveMonster(final MapleMonster mob) {
try {
em.getIv().invokeFunction("monsterRevive", EventInstanceManager.this, mob);
invokeScriptFunction("monsterRevive", EventInstanceManager.this, mob);
} catch (ScriptException | NoSuchMethodException ex) {} // optional
}
public boolean revivePlayer(final MapleCharacter chr) {
try {
Object b = em.getIv().invokeFunction("playerRevive", EventInstanceManager.this, chr);
Object b = invokeScriptFunction("playerRevive", EventInstanceManager.this, chr);
if (b instanceof Boolean) {
return (Boolean) b;
}
@@ -555,7 +552,7 @@ public class EventInstanceManager {
public void playerDisconnected(final MapleCharacter chr) {
try {
em.getIv().invokeFunction("playerDisconnected", EventInstanceManager.this, chr);
invokeScriptFunction("playerDisconnected", EventInstanceManager.this, chr);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
@@ -568,9 +565,9 @@ public class EventInstanceManager {
int inc;
if (ServerConstants.JAVA_8) {
inc = (int)em.getIv().invokeFunction("monsterValue", EventInstanceManager.this, mob.getId());
inc = (int)invokeScriptFunction("monsterValue", EventInstanceManager.this, mob.getId());
} else {
inc = ((Double) em.getIv().invokeFunction("monsterValue", EventInstanceManager.this, mob.getId())).intValue();
inc = ((Double) invokeScriptFunction("monsterValue", EventInstanceManager.this, mob.getId())).intValue();
}
if (inc != 0) {
@@ -609,12 +606,12 @@ public class EventInstanceManager {
public synchronized void dispose(boolean shutdown) { // should not trigger any event script method after disposed
if(disposed) return;
disposed = true;
try {
em.getIv().invokeFunction("dispose", EventInstanceManager.this);
invokeScriptFunction("dispose", EventInstanceManager.this);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
disposed = true;
ess.dispose();
@@ -690,7 +687,7 @@ public class EventInstanceManager {
@Override
public void run() {
try {
em.getIv().invokeFunction(methodName, EventInstanceManager.this);
invokeScriptFunction(methodName, EventInstanceManager.this);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
@@ -789,7 +786,7 @@ public class EventInstanceManager {
public void leftParty(final MapleCharacter chr) {
try {
em.getIv().invokeFunction("leftParty", EventInstanceManager.this, chr);
invokeScriptFunction("leftParty", EventInstanceManager.this, chr);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
@@ -797,7 +794,7 @@ public class EventInstanceManager {
public void disbandParty() {
try {
em.getIv().invokeFunction("disbandParty", EventInstanceManager.this);
invokeScriptFunction("disbandParty", EventInstanceManager.this);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
@@ -805,7 +802,7 @@ public class EventInstanceManager {
public void clearPQ() {
try {
em.getIv().invokeFunction("clearPQ", EventInstanceManager.this);
invokeScriptFunction("clearPQ", EventInstanceManager.this);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
@@ -813,7 +810,7 @@ public class EventInstanceManager {
public void removePlayer(final MapleCharacter chr) {
try {
em.getIv().invokeFunction("playerExit", EventInstanceManager.this, chr);
invokeScriptFunction("playerExit", EventInstanceManager.this, chr);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
@@ -1081,7 +1078,7 @@ public class EventInstanceManager {
eventStarted = true;
try {
em.getIv().invokeFunction("afterSetup", EventInstanceManager.this);
invokeScriptFunction("afterSetup", EventInstanceManager.this);
} catch (ScriptException | NoSuchMethodException ex) {
ex.printStackTrace();
}
+2 -2
View File
@@ -557,7 +557,7 @@ public class CashShop {
return null;
}
public synchronized Item openCashShopSurprise() {
public synchronized Pair<Item, Item> openCashShopSurprise() {
Item css = getCashShopItemByItemid(5222000);
if(css != null) {
@@ -577,7 +577,7 @@ public class CashShop {
Item item = cItem.toItem();
addToInventory(item);
return item;
return new Pair<>(item, css);
} else {
return null;
}
+7 -2
View File
@@ -1107,7 +1107,7 @@ public class MapleStatEffect {
}
private void applyBuffEffect(MapleCharacter applyfrom, MapleCharacter applyto, boolean primary) {
if (!isMonsterRiding() && !isCouponBuff() && !isMysticDoor() && !isHyperBody()) { // last mystic door already dispelled if it has been used before.
if (!isMonsterRiding() && !isCouponBuff() && !isMysticDoor() && !isHyperBody() && !isCombo()) { // last mystic door already dispelled if it has been used before.
applyto.cancelEffect(this, true, -1);
}
@@ -1190,7 +1190,12 @@ public class MapleStatEffect {
List<Pair<MapleBuffStat, Integer>> dsstat = Collections.singletonList(new Pair<>(MapleBuffStat.WIND_WALK, 0));
mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), dsstat);
} else if (isCombo()) {
mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), statups);
Integer comboCount = applyto.getBuffedValue(MapleBuffStat.COMBO);
if (comboCount == null) comboCount = 0;
List<Pair<MapleBuffStat, Integer>> cbstat = Collections.singletonList(new Pair<>(MapleBuffStat.COMBO, comboCount));
buff = MaplePacketCreator.giveBuff((skill ? sourceid : -sourceid), localDuration, cbstat);
mbuff = MaplePacketCreator.giveForeignBuff(applyto.getId(), cbstat);
} else if (isMonsterRiding()) {
if (sourceid == Corsair.BATTLE_SHIP) {//hp
if (applyto.getBattleshipHp() <= 0) {
+24 -5
View File
@@ -535,15 +535,34 @@ public class MapleMonster extends AbstractLoadedMapleLife {
}
}
private void propagateExperienceGains(Map<MapleCharacter, Float> personalExpReward, Map<MapleCharacter, Float> partyExpReward) {
private static double calcExperienceStandDevThreshold(Map<MapleCharacter, Float> personalExpReward, float exp2) {
float avgExpReward = 0.0f;
for (Float exp : personalExpReward.values()) {
avgExpReward += exp;
}
avgExpReward -= exp2; // clear out the 20% raw exp from last hitting
avgExpReward /= personalExpReward.size();
float varExpReward = 0.0f;
for (Float exp : personalExpReward.values()) {
varExpReward += Math.pow(exp - avgExpReward, 2);
}
varExpReward /= personalExpReward.size();
return avgExpReward + Math.sqrt(varExpReward);
}
private void propagateExperienceGains(Map<MapleCharacter, Float> personalExpReward, Map<MapleCharacter, Float> partyExpReward, float exp2) {
Set<MapleCharacter> expRewardPlayers = new HashSet<>(personalExpReward.keySet());
expRewardPlayers.addAll(partyExpReward.keySet());
double sdevExp = calcExperienceStandDevThreshold(personalExpReward, exp2);
for (MapleCharacter chr : expRewardPlayers) {
Float personalExp = personalExpReward.get(chr);
Float partyExp = partyExpReward.get(chr);
this.giveExpToCharacter(chr, personalExp, partyExp);
this.giveExpToCharacter(chr, personalExp, partyExp, personalExp != null && personalExp >= sdevExp);
}
}
@@ -628,7 +647,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
mc.showUnderleveledInfo(this);
}
propagateExperienceGains(personalExpReward, partyExpReward);
propagateExperienceGains(personalExpReward, partyExpReward, killerLevel != Integer.MAX_VALUE ? exp2 : 0.0f);
}
private float getStatusExpMultiplier(MapleCharacter attacker) {
@@ -663,7 +682,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
return (int) exp;
}
private void giveExpToCharacter(MapleCharacter attacker, Float personalExp, Float partyExp) {
private void giveExpToCharacter(MapleCharacter attacker, Float personalExp, Float partyExp, boolean white) {
if (attacker.isAlive()) {
if (personalExp != null) {
personalExp *= getStatusExpMultiplier(attacker);
@@ -689,7 +708,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
int _partyExp = expValueToInteger(partyExp);
attacker.gainExp(_personalExp, _partyExp, true, false, false);
attacker.gainExp(_personalExp, _partyExp, true, false, white);
attacker.increaseEquipExp(_personalExp);
attacker.updateQuestMobCount(getId());
}
+4 -4
View File
@@ -1069,7 +1069,7 @@ public class MapleMap {
if (chr.needQuestItem(questid, idrop.getItemId())) {
mdrop.lockItem();
try {
c.announce(MaplePacketCreator.dropItemFromMapObject(chr.getParty() != null, mdrop, dropper.getPosition(), dropPos, (byte) 1));
c.announce(MaplePacketCreator.dropItemFromMapObject(chr, mdrop, dropper.getPosition(), dropPos, (byte) 1));
} finally {
mdrop.unlockItem();
}
@@ -1091,7 +1091,7 @@ public class MapleMap {
public void sendPackets(MapleClient c) {
mdrop.lockItem();
try {
c.announce(MaplePacketCreator.dropItemFromMapObject(c.getPlayer().getParty() != null, mdrop, dropper.getPosition(), droppos, (byte) 1));
c.announce(MaplePacketCreator.dropItemFromMapObject(c.getPlayer(), mdrop, dropper.getPosition(), droppos, (byte) 1));
} finally {
mdrop.unlockItem();
}
@@ -2179,7 +2179,7 @@ public class MapleMap {
public void sendPackets(MapleClient c) {
mdrop.lockItem();
try {
c.announce(MaplePacketCreator.dropItemFromMapObject(c.getPlayer().getParty() != null, mdrop, dropper.getPosition(), droppos, (byte) 1));
c.announce(MaplePacketCreator.dropItemFromMapObject(c.getPlayer(), mdrop, dropper.getPosition(), droppos, (byte) 1));
} finally {
mdrop.unlockItem();
}
@@ -2877,7 +2877,7 @@ public class MapleMap {
chrRLock.lock();
try {
for (MapleCharacter chr : characters) {
final byte[] packet = MaplePacketCreator.dropItemFromMapObject(chr.getParty() != null, mdrop, dropperPos, dropPos, mod);
final byte[] packet = MaplePacketCreator.dropItemFromMapObject(chr, mdrop, dropperPos, dropPos, mod);
if (rangeSq < Double.POSITIVE_INFINITY) {
if (rangedFrom.distanceSq(chr.getPosition()) <= rangeSq) {
+20 -2
View File
@@ -23,6 +23,7 @@ package server.maps;
import client.MapleCharacter;
import client.MapleClient;
import client.inventory.Item;
import constants.ServerConstants;
import java.awt.Point;
import java.util.concurrent.locks.Lock;
import tools.MaplePacketCreator;
@@ -35,7 +36,7 @@ public class MapleMapItem extends AbstractMapleMapObject {
protected MapleMapObject dropper;
protected int character_ownerid, party_ownerid, meso, questid = -1;
protected byte type;
protected boolean pickedUp = false, playerDrop;
protected boolean pickedUp = false, playerDrop, partyDrop;
protected long dropTime;
private Lock itemLock = MonitoredReentrantLockFactory.createLock(MonitoredLockType.MAP_ITEM);
@@ -45,6 +46,7 @@ public class MapleMapItem extends AbstractMapleMapObject {
this.dropper = dropper;
this.character_ownerid = owner.getId();
this.party_ownerid = owner.getPartyId();
this.partyDrop = this.party_ownerid != -1;
this.ownerClient = owner.getClient();
this.meso = 0;
this.type = type;
@@ -57,6 +59,7 @@ public class MapleMapItem extends AbstractMapleMapObject {
this.dropper = dropper;
this.character_ownerid = owner.getId();
this.party_ownerid = owner.getPartyId();
this.partyDrop = this.party_ownerid != -1;
this.ownerClient = owner.getClient();
this.meso = 0;
this.type = type;
@@ -70,6 +73,7 @@ public class MapleMapItem extends AbstractMapleMapObject {
this.dropper = dropper;
this.character_ownerid = owner.getId();
this.party_ownerid = owner.getPartyId();
this.partyDrop = this.party_ownerid != -1;
this.ownerClient = owner.getClient();
this.meso = meso;
this.type = type;
@@ -105,6 +109,20 @@ public class MapleMapItem extends AbstractMapleMapObject {
party_ownerid = partyid;
}
public final int getClientsideOwnerId(MapleCharacter player) {
if (this.party_ownerid == -1) {
return this.character_ownerid;
} else {
if (!partyDrop && player.getId() == this.character_ownerid) {
return player.getId();
} else if (player.getPartyId() == this.party_ownerid) {
return player.getId();
} else {
return this.party_ownerid;
}
}
}
public final boolean isFFADrop() {
return type == 2 || type == 3 || hasExpiredOwnershipTime();
}
@@ -187,7 +205,7 @@ public class MapleMapItem extends AbstractMapleMapObject {
if (chr.needQuestItem(questid, getItemId())) {
this.lockItem();
try {
client.announce(MaplePacketCreator.dropItemFromMapObject(chr.getParty() != null, this, null, getPosition(), (byte) 2));
client.announce(MaplePacketCreator.dropItemFromMapObject(chr, this, null, getPosition(), (byte) 2));
} finally {
this.unlockItem();
}
+26 -7
View File
@@ -1668,7 +1668,7 @@ public class MaplePacketCreator {
mplew.writeBool(white);
mplew.writeInt(gain);
mplew.writeBool(inChat);
mplew.writeInt(0); // monster book bonus (Bonus Event Exp)
mplew.writeInt(0); // bonus event exp
mplew.write(0); // third monster kill event
mplew.write(0); // RIP byte, this is always a 0
mplew.writeInt(0); //wedding bonus
@@ -1676,9 +1676,7 @@ public class MaplePacketCreator {
mplew.write(0);
}
int mod = ServerConstants.PARTY_EXPERIENCE_MOD != 1 ? ServerConstants.PARTY_EXPERIENCE_MOD * 100 : 0;
mplew.write(mod); //0 = party bonus, 100 = 1x Bonus EXP, 200 = 2x Bonus EXP
mplew.write(0); //0 = party bonus, 100 = 1x Bonus EXP, 200 = 2x Bonus EXP
mplew.writeInt(party); // party bonus
mplew.writeInt(equip); //equip bonus
mplew.writeInt(0); //Internet Cafe Bonus
@@ -1808,15 +1806,15 @@ public class MaplePacketCreator {
return mplew.getPacket();
}
public static byte[] dropItemFromMapObject(boolean recvrInParty, MapleMapItem drop, Point dropfrom, Point dropto, byte mod) {
public static byte[] dropItemFromMapObject(MapleCharacter player, MapleMapItem drop, Point dropfrom, Point dropto, byte mod) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.DROP_ITEM_FROM_MAPOBJECT.getValue());
mplew.write(mod);
mplew.writeInt(drop.getObjectId());
mplew.writeBool(drop.getMeso() > 0); // 1 mesos, 0 item, 2 and above all item meso bag,
mplew.writeInt(drop.getItemId()); // drop object ID
mplew.writeInt(!drop.isFFADrop() ? (recvrInParty ? drop.getPartyOwnerId() : drop.getOwnerId()) : 0); // owner charid/partyid :)
mplew.write(drop.getDropType()); // 0 = timeout for non-owner, 1 = timeout for non-owner's party, 2 = FFA, 3 = explosive/FFA
mplew.writeInt(drop.getClientsideOwnerId(player)); // owner charid/partyid :)
mplew.write(!drop.hasExpiredOwnershipTime() ? drop.getDropType() : 2); // 0 = timeout for non-owner, 1 = timeout for non-owner's party, 2 = FFA, 3 = explosive/FFA
mplew.writePos(dropto);
mplew.writeInt(drop.getDropper().getObjectId()); // dropper oid, found thanks to Li Jixue
@@ -6760,6 +6758,27 @@ public class MaplePacketCreator {
return mplew.getPacket();
}
// Cash Shop Surprise packets found thanks to Arnah (Vertisy)
public static byte[] onCashItemGachaponOpenFailed(){
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.CASHSHOP_CASH_ITEM_GACHAPON_RESULT.getValue());
mplew.write(189);
return mplew.getPacket();
}
public static byte[] onCashGachaponOpenSuccess(int accountid, long sn, int remainingBoxes, Item item, int itemid, int nSelectedItemCount, boolean bJackpot){
MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.CASHSHOP_CASH_ITEM_GACHAPON_RESULT.getValue());
mplew.write(190);
mplew.writeLong(sn);// sn of the box used
mplew.writeInt(remainingBoxes);
addCashItemInformation(mplew, item, accountid);
mplew.writeInt(itemid);// the itemid of the liSN?
mplew.write(nSelectedItemCount);// the total count now? o.O
mplew.writeBool(bJackpot);// "CashGachaponJackpot"
return mplew.getPacket();
}
private static void getGuildInfo(final MaplePacketLittleEndianWriter mplew, MapleGuild guild) {
mplew.writeInt(guild.getId());
mplew.writeMapleAsciiString(guild.getName());
+12 -12
View File
@@ -103,7 +103,7 @@
<imgdir name="life">
<imgdir name="0">
<string name="type" value="m"/>
<string name="id" value="9300274"/>
<string name="id" value="9500102"/>
<int name="x" value="-374"/>
<int name="y" value="-760"/>
<int name="mobTime" value="0"/>
@@ -116,7 +116,7 @@
</imgdir>
<imgdir name="1">
<string name="type" value="m"/>
<string name="id" value="9300274"/>
<string name="id" value="9500102"/>
<int name="x" value="-172"/>
<int name="y" value="-764"/>
<int name="mobTime" value="0"/>
@@ -129,7 +129,7 @@
</imgdir>
<imgdir name="2">
<string name="type" value="m"/>
<string name="id" value="9300274"/>
<string name="id" value="9500102"/>
<int name="x" value="25"/>
<int name="y" value="-759"/>
<int name="mobTime" value="0"/>
@@ -142,7 +142,7 @@
</imgdir>
<imgdir name="3">
<string name="type" value="m"/>
<string name="id" value="9300274"/>
<string name="id" value="9500102"/>
<int name="x" value="211"/>
<int name="y" value="-768"/>
<int name="mobTime" value="0"/>
@@ -155,7 +155,7 @@
</imgdir>
<imgdir name="4">
<string name="type" value="m"/>
<string name="id" value="9300274"/>
<string name="id" value="9500102"/>
<int name="x" value="377"/>
<int name="y" value="-756"/>
<int name="mobTime" value="0"/>
@@ -168,7 +168,7 @@
</imgdir>
<imgdir name="5">
<string name="type" value="m"/>
<string name="id" value="9300274"/>
<string name="id" value="9500102"/>
<int name="x" value="322"/>
<int name="y" value="-1111"/>
<int name="mobTime" value="0"/>
@@ -181,7 +181,7 @@
</imgdir>
<imgdir name="6">
<string name="type" value="m"/>
<string name="id" value="9300274"/>
<string name="id" value="9500102"/>
<int name="x" value="458"/>
<int name="y" value="-1119"/>
<int name="mobTime" value="0"/>
@@ -194,7 +194,7 @@
</imgdir>
<imgdir name="7">
<string name="type" value="m"/>
<string name="id" value="9300274"/>
<string name="id" value="9500102"/>
<int name="x" value="98"/>
<int name="y" value="-1064"/>
<int name="mobTime" value="0"/>
@@ -207,7 +207,7 @@
</imgdir>
<imgdir name="8">
<string name="type" value="m"/>
<string name="id" value="9300274"/>
<string name="id" value="9500102"/>
<int name="x" value="-41"/>
<int name="y" value="-1062"/>
<int name="mobTime" value="0"/>
@@ -220,7 +220,7 @@
</imgdir>
<imgdir name="9">
<string name="type" value="m"/>
<string name="id" value="9300274"/>
<string name="id" value="9500102"/>
<int name="x" value="-132"/>
<int name="y" value="-1241"/>
<int name="mobTime" value="0"/>
@@ -233,7 +233,7 @@
</imgdir>
<imgdir name="10">
<string name="type" value="m"/>
<string name="id" value="9300274"/>
<string name="id" value="9500102"/>
<int name="x" value="-280"/>
<int name="y" value="-1242"/>
<int name="mobTime" value="0"/>
@@ -246,7 +246,7 @@
</imgdir>
<imgdir name="11">
<string name="type" value="m"/>
<string name="id" value="9300274"/>
<string name="id" value="9500102"/>
<int name="x" value="-332"/>
<int name="y" value="-995"/>
<int name="mobTime" value="0"/>
+1 -1
View File
@@ -8339,7 +8339,7 @@
<int name="npc" value="12100"/>
<imgdir name="mob">
<imgdir name="0">
<int name="id" value="9300274"/>
<int name="id" value="9500102"/>
<int name="count" value="2"/>
</imgdir>
</imgdir>
+2 -2
View File
@@ -2541,8 +2541,8 @@
<string name="name" value="Mai&apos;s Last Training"/>
<string name="parent" value="Mai&apos;s Training!"/>
<int name="order" value="4"/>
<string name="1" value="I defeated the Slimes and brought back the Squishy Liquid to Mai. She seemed to be impressed, and instructed me this time to hunt a really powerful monster. She then told me to hunt #r2 Cynical Orange Mushrooms#k.\n\nCynical Orange Mushroom #r#a10441##k"/>
<string name="2" value="I was able to defeat 2 Cynical Orange Mushrooms and reported the result to Mai."/>
<string name="1" value="I defeated the Slimes and brought back the Squishy Liquid to Mai. She seemed to be impressed, and instructed me this time to hunt a really powerful monster. She then told me to hunt #r2 Orange Mushrooms#k.\n\nOrange Mushroom #r#a10441##k"/>
<string name="2" value="I was able to defeat 2 Orange Mushrooms and reported the result to Mai."/>
<int name="area" value="20"/>
</imgdir>
<imgdir name="10440">
+3 -4
View File
@@ -4503,22 +4503,21 @@
<imgdir name="0">
<string name="0" value="Oh wow! You really brought me Squishy Liquid from the Slime. You&apos;re doing much better than I expected. I think... you&apos;re now ready to take on a really challenging monster."/>
<imgdir name="yes">
<string name="0" value="Alright, this time, you&apos;ll need to take on #r2 Cynical Orange Mushrooms#k. They are pretty tough and powerful, but thankfully they aren&apos;t the Blue Mushrooms you&apos;ll find at Victoria Island. They are basically regular Orange Mushrooms, so if you focus on the combat, you should be able to handle those two."/>
<string name="0" value="So, reports of late shows up a growth on masses of Orange Mushrooms around. Your job, as an aspiring Explorer, is to help us cutting out #r2 Orange Mushrooms#k. They are pretty tough and powerful, but don&apos;t take so much fear from this fact! If you trust in your abilities and focus on the combat, you should be able to handle those two handily."/>
</imgdir>
<imgdir name="no">
<string name="0" value="Hmmm... did I really scare you? Don&apos;t worry. If you are persistent, you&apos;ll be able to handle those two. I won&apos;t make you hunt monsters that you can&apos;t handle, you know."/>
</imgdir>
<string name="1" value="So, reports of late shows up a growth on masses of distempered Orange Mushrooms around. Some explorers seems to not get their job done after they started engaging combat. That has been making some Orange Mushrooms rather... uhh, cynical... towards us humans... "/>
</imgdir>
<imgdir name="1">
<string name="0" value="So you did defeat 2 Cynical Orange Mushrooms. That&apos;s incredible! Seriously, you&apos;re doing much better than I ever thought possible! You may be just a beginner, but I have a feeling that you&apos;ll one day become a legendary hero in Maple World."/>
<string name="0" value="So you did defeat 2 Orange Mushrooms. That&apos;s incredible! Seriously, you&apos;re doing much better than I ever thought possible! You may be just a beginner, but I have a feeling that you&apos;ll one day become a legendary hero in Maple World."/>
<imgdir name="yes">
<string name="0" value="The training is now complete. You may still have some weaknesses here and there, but you&apos;ll be able to overcome that in no time. Keep training!"/>
<string name="1" value="Oh, and I have one last #btest#k for you. Think of it as a final exam. If you aren&apos;t satisfied with your current skill level and want to push further, then meet #bBari#k, who will have a test in store for you."/>
</imgdir>
<imgdir name="stop">
<imgdir name="mob">
<string name="0" value="I don&apos;t think you&apos;ve slayed #r2 Cynical Orange Mushrooms#k yet. Please take care of both, then let me know of the results."/>
<string name="0" value="I don&apos;t think you&apos;ve slayed #r2 Orange Mushrooms#k yet. Please take care of both, then let me know of the results."/>
</imgdir>
</imgdir>
</imgdir>