Missing Pirate questlines + Find & MoveLife update + Party-Map patch
Implemented missing scripts for Aerial Strike, Hypnotize and Time Leap skill questlines. Fixed an deadlock issue within player's inventory and status. Fixed skill spam detection disconnecting players when legitimatelly spamming Flash Jump or Heal. Fixed party members map location not being properly updated after changing maps. Rehauled MoveLife handler. Improved packet read of attack and skill elements, properly reflecting incoming actions to other player on the map. Reviewed an issue with equipments MaxHP/MaxMP getting unsynced with player's MaxHP/MaxMP, resulting in differences within server-client view of a player's pool. Fixed mobs not being spawned by dojo bosses after enough spawn actions were instanced. Implemented proper Mob.wz linked mob data support. Fixed /find not identifying a player's channel properly. Fixed Echo of Hero not affecting other player in the map. Fixed commands warp and goto not taking player off events/expeditions properly. Fixed storage expansion not being registered on DB when buying the cash item. Fixed party leadership being reassigned after changing channels. Implemented suggested level range limit between party members on the EXP share system. Players whose level range from the attacker exceeds the estipulated threshold will not receive any EXP from the action. Happy Thanksgiving Day everyone!!!
This commit is contained in:
@@ -27,6 +27,7 @@ package net.server.audit.locks;
|
||||
public enum MonitoredLockType {
|
||||
UNDEFINED,
|
||||
CHARACTER_CHR,
|
||||
CHARACTER_CPN,
|
||||
CHARACTER_EFF,
|
||||
CHARACTER_PET,
|
||||
CHARACTER_PRT,
|
||||
|
||||
@@ -32,8 +32,7 @@ public final class AutoAggroHandler extends AbstractMaplePacketHandler {
|
||||
|
||||
@Override
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
if(c.getPlayer().isHidden())
|
||||
return; // Don't auto aggro GM's in hide...
|
||||
if (c.getPlayer().isHidden()) return; // Don't auto aggro GM's in hide...
|
||||
|
||||
MapleMap map = c.getPlayer().getMap();
|
||||
int oid = slea.readInt();
|
||||
|
||||
@@ -63,7 +63,7 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
||||
final int snCS = slea.readInt();
|
||||
CashItem cItem = CashItemFactory.getItem(snCS);
|
||||
if (!canBuy(cItem, cs.getCash(useNX))) {
|
||||
FilePrinter.printError(FilePrinter.ITEM, "Denied to sell cash item with SN " + cItem.getSN());
|
||||
FilePrinter.printError(FilePrinter.ITEM, "Denied to sell cash item with SN " + snCS); // preventing NPE here thanks to MedicOP
|
||||
c.enableCSActions();
|
||||
return;
|
||||
}
|
||||
@@ -185,7 +185,10 @@ public final class CashOperationHandler extends AbstractMaplePacketHandler {
|
||||
c.enableCSActions();
|
||||
return;
|
||||
}
|
||||
if (chr.getStorage().gainSlots(8)) {
|
||||
if (chr.getStorage().gainSlots(8)) { // thanks ABaldParrot & Thora for detecting storage issues here
|
||||
FilePrinter.print(FilePrinter.STORAGE + c.getAccountName() + ".txt", c.getPlayer().getName() + " bought 8 slots to their account storage.\r\n");
|
||||
chr.setUsedStorage();
|
||||
|
||||
c.announce(MaplePacketCreator.showBoughtStorageSlots(chr.getStorage().getSlots()));
|
||||
cs.gainCash(cash, cItem, chr.getWorld());
|
||||
c.announce(MaplePacketCreator.showCash(chr));
|
||||
|
||||
@@ -194,14 +194,15 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
|
||||
restancePlayer(mc);
|
||||
break;
|
||||
case 0x07:
|
||||
allianceId = mc.getGuild().getAllianceId();
|
||||
|
||||
cid = slea.readInt();
|
||||
name = slea.readMapleAsciiString();
|
||||
if (cid != mc.getId() || !name.equals(mc.getName()) || mc.getGuildId() <= 0) {
|
||||
System.out.println("[hax] " + mc.getName() + " tried to quit guild under the name \"" + name + "\" and current guild id of " + mc.getGuildId() + ".");
|
||||
return;
|
||||
}
|
||||
|
||||
allianceId = mc.getGuild().getAllianceId();
|
||||
|
||||
c.announce(MaplePacketCreator.updateGP(mc.getGuildId(), 0));
|
||||
Server.getInstance().leaveGuild(mc.getMGC());
|
||||
|
||||
@@ -209,6 +210,7 @@ public final class GuildOperationHandler extends AbstractMaplePacketHandler {
|
||||
if(allianceId > 0) Server.getInstance().getAlliance(allianceId).updateAlliancePackets(mc);
|
||||
|
||||
mc.getMGC().setGuildId(0);
|
||||
mc.getMGC().setGuildRank(5);
|
||||
mc.saveGuildStatus();
|
||||
restancePlayer(mc);
|
||||
break;
|
||||
|
||||
@@ -216,8 +216,8 @@ public final class InventorySortHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
|
||||
for (Item item : itemarray) {
|
||||
inventory.removeSlot(item.getPosition());
|
||||
mods.add(new ModifyInventory(3, item));
|
||||
inventory.removeSlot(item.getPosition());
|
||||
mods.add(new ModifyInventory(3, item));
|
||||
}
|
||||
|
||||
int invTypeCriteria = (MapleInventoryType.getByType(invType) == MapleInventoryType.EQUIP) ? 3 : 1;
|
||||
|
||||
@@ -37,7 +37,8 @@ import tools.Randomizer;
|
||||
import tools.data.input.SeekableLittleEndianAccessor;
|
||||
|
||||
/**
|
||||
* @author Jay Estrella/ Modified by kevintjuh93
|
||||
* @author Jay Estrella
|
||||
* @author kevintjuh93
|
||||
*/
|
||||
public final class ItemRewardHandler extends AbstractMaplePacketHandler {
|
||||
@Override
|
||||
|
||||
@@ -47,8 +47,7 @@ public final class MobDamageMobFriendlyHandler extends AbstractMaplePacketHandle
|
||||
}
|
||||
|
||||
int damage = Randomizer.nextInt(((monster.getMaxHp() / 13 + monster.getPADamage() * 10)) * 2 + 500) / 10; //Beng's formula.
|
||||
// int damage = monster.getStats().getPADamage() + monster.getStats().getPDDamage() - 1;
|
||||
|
||||
|
||||
if (monster.getHp() - damage < 1) { // friendly dies
|
||||
if(monster.getId() == 9300102) {
|
||||
monster.getMap().broadcastMessage(MaplePacketCreator.serverNotice(6, "The Watch Hog has been injured by the aliens. Better luck next time..."));
|
||||
@@ -60,8 +59,10 @@ public final class MobDamageMobFriendlyHandler extends AbstractMaplePacketHandle
|
||||
monster.getMap().broadcastMessage(MaplePacketCreator.serverNotice(6, "Juliet has fainted in the middle of the combat."));
|
||||
} else if(monster.getId() == 9300138) { //romeo
|
||||
monster.getMap().broadcastMessage(MaplePacketCreator.serverNotice(6, "Romeo has fainted in the middle of the combat."));
|
||||
} else if(monster.getId() == 9400322 || monster.getId() == 9400327 || monster.getId() == 9400332) {
|
||||
} else if(monster.getId() == 9400322 || monster.getId() == 9400327 || monster.getId() == 9400332) { //snowman
|
||||
monster.getMap().broadcastMessage(MaplePacketCreator.serverNotice(6, "The Snowman has melted on the heat of the battle."));
|
||||
} else if(monster.getId() == 9300162) { //delli
|
||||
monster.getMap().broadcastMessage(MaplePacketCreator.serverNotice(6, "Delli vanished after the ambush, sheets still laying on the ground..."));
|
||||
}
|
||||
|
||||
c.getPlayer().getMap().killFriendlies(monster);
|
||||
|
||||
@@ -26,6 +26,7 @@ import client.MapleClient;
|
||||
import java.awt.Point;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import constants.ServerConstants;
|
||||
import server.life.MapleMonster;
|
||||
import server.life.MapleMonsterInformationProvider;
|
||||
//import server.life.MobAttackInfo;
|
||||
@@ -63,10 +64,10 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler {
|
||||
MapleMonster monster = (MapleMonster) mmo;
|
||||
List<MapleCharacter> banishPlayers = null;
|
||||
|
||||
byte pNibbles = slea.readByte();
|
||||
byte pNibbles = slea.readByte();
|
||||
byte rawActivity = slea.readByte();
|
||||
slea.readByte();
|
||||
slea.readByte();
|
||||
int skillId = slea.readByte() & 0xff;
|
||||
int skillLv = slea.readByte() & 0xff;
|
||||
short pOption = slea.readShort();
|
||||
slea.skip(8);
|
||||
|
||||
@@ -74,65 +75,69 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler {
|
||||
rawActivity = (byte) (rawActivity & 0xFF >> 1);
|
||||
}
|
||||
|
||||
boolean isAttack = inRangeInclusive(rawActivity, 12, 20);
|
||||
boolean isSkill = inRangeInclusive(rawActivity, 21, 25);
|
||||
|
||||
byte attackId = (byte) (isAttack ? rawActivity - 12 : -1);
|
||||
isSkill |= (pNibbles != 0);
|
||||
|
||||
boolean nextMovementCouldBeSkill = true;
|
||||
boolean pUnk = (pNibbles & 0xF0) != 0;
|
||||
|
||||
boolean isAttack = inRangeInclusive(rawActivity, 24, 41);
|
||||
boolean isSkill = inRangeInclusive(rawActivity, 42, 59);
|
||||
|
||||
boolean currentController = (monster.getController() == player);
|
||||
|
||||
MobSkill toUse = null;
|
||||
int useSkillId = 0, useSkillLevel = 0;
|
||||
|
||||
int rnd = 0;
|
||||
MobSkill nextUse = null;
|
||||
int nextSkillId = 0, nextSkillLevel = 0;
|
||||
|
||||
boolean nextMovementCouldBeSkill = !(isSkill || (pNibbles != 0));
|
||||
|
||||
int castPos;
|
||||
if (isSkill) {
|
||||
int noSkills = monster.getNoSkills();
|
||||
if (noSkills > 0) {
|
||||
int rndSkill = Randomizer.nextInt(noSkills);
|
||||
|
||||
Pair<Integer, Integer> skillToUse = monster.getSkills().get(rndSkill);
|
||||
useSkillId = skillToUse.getLeft();
|
||||
useSkillLevel = skillToUse.getRight();
|
||||
useSkillId = skillId;
|
||||
useSkillLevel = skillLv;
|
||||
|
||||
castPos = monster.getSkillPos(useSkillId, useSkillLevel);
|
||||
if (castPos != -1) {
|
||||
toUse = MobSkillFactory.getMobSkill(useSkillId, useSkillLevel);
|
||||
|
||||
rnd = rndSkill;
|
||||
nextMovementCouldBeSkill = false;
|
||||
}
|
||||
}
|
||||
|
||||
int mobMp;
|
||||
if (toUse != null && toUse.getHP() >= (int) (((float) monster.getHp() / monster.getMaxHp()) * 100) && monster.canUseSkill(toUse)) {
|
||||
mobMp = monster.getMp();
|
||||
|
||||
int animationTime = MapleMonsterInformationProvider.getInstance().getMobSkillAnimationTime(toUse);
|
||||
if(animationTime > 0 && toUse.getSkillId() != 129) {
|
||||
toUse.applyDelayedEffect(player, monster, true, animationTime);
|
||||
} else {
|
||||
banishPlayers = new LinkedList<>();
|
||||
toUse.applyEffect(player, monster, true, banishPlayers);
|
||||
if (monster.canUseSkill(toUse)) {
|
||||
int animationTime = MapleMonsterInformationProvider.getInstance().getMobSkillAnimationTime(toUse);
|
||||
if(animationTime > 0 && toUse.getSkillId() != 129) {
|
||||
toUse.applyDelayedEffect(player, monster, true, animationTime);
|
||||
} else {
|
||||
banishPlayers = new LinkedList<>();
|
||||
toUse.applyEffect(player, monster, true, banishPlayers);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int atkStatus = monster.canUseAttack((attackId - 13) / 2);
|
||||
castPos = (rawActivity - 24) / 2;
|
||||
|
||||
int atkStatus = monster.canUseAttack(castPos, isSkill);
|
||||
if (atkStatus < 1) {
|
||||
if (!currentController) {
|
||||
return;
|
||||
}
|
||||
|
||||
mobMp = atkStatus < 0 ? 0 : monster.getMp();
|
||||
} else {
|
||||
mobMp = monster.getMp();
|
||||
rawActivity = -1;
|
||||
pOption = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int mobMp = monster.getMp();
|
||||
if (nextMovementCouldBeSkill) {
|
||||
int noSkills = monster.getNoSkills();
|
||||
if (noSkills > 0) {
|
||||
int rndSkill = Randomizer.nextInt(noSkills);
|
||||
|
||||
Pair<Integer, Integer> skillToUse = monster.getSkills().get(rndSkill);
|
||||
nextSkillId = skillToUse.getLeft();
|
||||
nextSkillLevel = skillToUse.getRight();
|
||||
nextUse = MobSkillFactory.getMobSkill(nextSkillId, nextSkillLevel);
|
||||
|
||||
if (!(nextUse != null && nextUse.getHP() >= (int) (((float) monster.getHp() / monster.getMaxHp()) * 100) && mobMp >= nextUse.getMpCon())) {
|
||||
nextSkillId = 0;
|
||||
nextSkillLevel = 0;
|
||||
nextUse = null;
|
||||
}
|
||||
}
|
||||
|
||||
useSkillId = 0;
|
||||
useSkillLevel = 0;
|
||||
rawActivity = -1;
|
||||
pOption = 0;
|
||||
|
||||
toUse = null;
|
||||
}
|
||||
|
||||
slea.readByte();
|
||||
@@ -151,9 +156,6 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler {
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else if (rawActivity == -1 && monster.isControllerKnowsAboutAggro() && !monster.isMobile() && !monster.isFirstAttack()) {
|
||||
monster.setControllerHasAggro(false);
|
||||
monster.setControllerKnowsAboutAggro(false);
|
||||
}
|
||||
|
||||
aggro = monster.isControllerHasAggro();
|
||||
@@ -164,13 +166,17 @@ public final class MoveLifeHandler extends AbstractMovementPacketHandler {
|
||||
monster.unlockMonster();
|
||||
}
|
||||
|
||||
if (toUse != null) {
|
||||
c.announce(MaplePacketCreator.moveMonsterResponse(objectid, moveid, mobMp, aggro, toUse.getSkillId(), toUse.getSkillLevel()));
|
||||
if (nextUse != null) {
|
||||
c.announce(MaplePacketCreator.moveMonsterResponse(objectid, moveid, mobMp, aggro, nextSkillId, nextSkillLevel));
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.moveMonsterResponse(objectid, moveid, mobMp, aggro));
|
||||
}
|
||||
|
||||
if (res != null) {
|
||||
if (ServerConstants.USE_DEBUG_SHOW_RCVD_MVLIFE) {
|
||||
System.out.println((isSkill ? "SKILL " : (isAttack ? "ATTCK " : " ")) + "castPos: " + castPos + " rawAct: " + rawActivity + " opt: " + pOption + " skillID: " + useSkillId + " skillLV: " + useSkillLevel + " " + "allowSkill: " + nextMovementCouldBeSkill);
|
||||
}
|
||||
|
||||
map.broadcastMessage(player, MaplePacketCreator.moveMonster(objectid, nextMovementCouldBeSkill, rawActivity, useSkillId, useSkillLevel, pOption, startPos, res), monster.getPosition());
|
||||
updatePosition(res, monster, -2);
|
||||
map.moveMonster(monster, monster.getPosition());
|
||||
|
||||
@@ -37,7 +37,7 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ronan (multi-pot consumption feature)
|
||||
* @author Ronan - multi-pot consumption feature
|
||||
*/
|
||||
public final class PetAutoPotHandler extends AbstractMaplePacketHandler {
|
||||
short slot;
|
||||
|
||||
@@ -49,7 +49,7 @@ import tools.data.input.SeekableLittleEndianAccessor;
|
||||
/**
|
||||
*
|
||||
* @author Matze
|
||||
* @author Ronan (concurrency safety & reviewed minigames)
|
||||
* @author Ronan - concurrency safety & reviewed minigames
|
||||
*/
|
||||
public final class PlayerInteractionHandler extends AbstractMaplePacketHandler {
|
||||
public enum Action {
|
||||
|
||||
@@ -224,6 +224,7 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
|
||||
if (playerGuild == null) {
|
||||
player.deleteGuild(player.getGuildId());
|
||||
player.getMGC().setGuildId(0);
|
||||
player.getMGC().setGuildRank(5);
|
||||
} else {
|
||||
playerGuild.getMGC(player.getId()).setCharacter(player);
|
||||
player.setMGC(playerGuild.getMGC(player.getId()));
|
||||
|
||||
@@ -51,7 +51,7 @@ import client.inventory.Item;
|
||||
|
||||
/**
|
||||
* @author Jvlaple
|
||||
* @author Ronan (major overhaul on Ring handling mechanics)
|
||||
* @author Ronan - major overhaul on Ring handling mechanics
|
||||
*/
|
||||
public final class RingActionHandler extends AbstractMaplePacketHandler {
|
||||
private static int getBoxId(int useItemId) {
|
||||
|
||||
@@ -48,7 +48,7 @@ public final class SpecialMoveHandler extends AbstractMaplePacketHandler {
|
||||
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
|
||||
MapleCharacter chr = c.getPlayer();
|
||||
slea.readInt();
|
||||
chr.getAutobanManager().setTimestamp(4, Server.getInstance().getCurrentTimestamp(), 5);
|
||||
chr.getAutobanManager().setTimestamp(4, Server.getInstance().getCurrentTimestamp(), 28);
|
||||
int skillid = slea.readInt();
|
||||
|
||||
/*
|
||||
@@ -132,7 +132,11 @@ public final class SpecialMoveHandler extends AbstractMaplePacketHandler {
|
||||
}
|
||||
if (chr.isAlive()) {
|
||||
if (skill.getId() != Priest.MYSTIC_DOOR) {
|
||||
skill.getEffect(skillLevel).applyTo(chr, pos);
|
||||
if (skill.getId() % 10000000 != 1005) {
|
||||
skill.getEffect(skillLevel).applyTo(chr, pos);
|
||||
} else {
|
||||
skill.getEffect(skillLevel).applyEchoOfHero(chr);
|
||||
}
|
||||
} else if(chr.canDoor()) {
|
||||
//update door lists
|
||||
chr.cancelMagicDoor();
|
||||
|
||||
@@ -83,12 +83,14 @@ public final class WhisperHandler extends AbstractMaplePacketHandler {
|
||||
c.getPlayer().getAutobanManager().spam(7);
|
||||
} else if (mode == 5) { // - /find
|
||||
String recipient = slea.readMapleAsciiString();
|
||||
MapleCharacter victim = c.getChannelServer().getPlayerStorage().getCharacterByName(recipient);
|
||||
MapleCharacter victim = c.getWorldServer().getPlayerStorage().getCharacterByName(recipient);
|
||||
if (victim != null && c.getPlayer().gmLevel() >= victim.gmLevel()) {
|
||||
if (victim.getCashShop().isOpened()) {
|
||||
if (victim.getCashShop().isOpened()) { // in CashShop
|
||||
c.announce(MaplePacketCreator.getFindReply(victim.getName(), -1, 2));
|
||||
//} else if (victim.inMTS()) {
|
||||
// c.announce(MaplePacketCreator.getFindReply(victim.getName(), -1, 0));
|
||||
} else if (victim.isAwayFromWorld()) { // in MTS
|
||||
c.announce(MaplePacketCreator.getFindReply(victim.getName(), -1, 0));
|
||||
} else if (victim.getClient().getChannel() != c.getChannel()) { // in another channel, issue detected thanks to MedicOP
|
||||
c.announce(MaplePacketCreator.getFindReply(victim.getName(), victim.getClient().getChannel() - 1, 3));
|
||||
} else {
|
||||
c.announce(MaplePacketCreator.getFindReply(victim.getName(), victim.getMap().getId(), 1));
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ import net.server.audit.locks.factory.MonitoredReentrantLockFactory;
|
||||
/**
|
||||
*
|
||||
* @author kevintjuh93
|
||||
* @author Ronan (thread-oriented world schedules, guild queue, marriages & party chars)
|
||||
* @author Ronan - thread-oriented world schedules, guild queue, marriages & party chars
|
||||
*/
|
||||
public class World {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user