package handling.channel.handler;
import clientside.MapleBuffStat;
import clientside.MapleCharacter;
import clientside.MapleClient;
import clientside.MapleJob;
import clientside.PlayerStats;
import clientside.Skill;
import clientside.SkillFactory;
import clientside.SkillMacro;
import client.inventory.Item;
import client.inventory.MapleInventoryType;
import client.status.MonsterStatus;
import client.status.MonsterStatusEffect;
import clientside.MapleStat;
import constants.GameConstants;
import handling.channel.ChannelServer;
import java.awt.Point;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.List;
import server.MapleInventoryManipulator;
import server.MapleItemInformationProvider;
import server.MaplePortal;
import server.MapleStatEffect;
import server.Randomizer;
import server.Timer.CloneTimer;
import server.life.MapleMonster;
import server.life.MobAttackInfo;
import server.life.MobSkill;
import server.life.MobSkillFactory;
import server.maps.FieldLimitType;
import server.maps.MapleMap;
import server.maps.MapleMapObject;
import server.maps.MapleMapObjectType;
import server.movement.LifeMovementFragment;
import server.quest.MapleQuest;
import tools.FileoutputUtil;
import tools.Pair;
import tools.data.LittleEndianAccessor;
import tools.packet.CField;
import tools.packet.CWvsContext;
import tools.packet.JobPacket;
import tools.packet.MTSCSPacket;
import tools.packet.MobPacket;
public class PlayerHandler {
public static int xx = 0;
public static int isFinisher(int skillid) {
switch (skillid) {
case 1111003:
return GameConstants.GMS ? 1 : 10;
case 1111005:
return GameConstants.GMS ? 2 : 10;
case 11111002:
return GameConstants.GMS ? 1 : 10;
case 11111003:
return GameConstants.GMS ? 2 : 10;
}
return 0;
}
public static void ChangeSkillMacro(LittleEndianAccessor slea, MapleCharacter chr) {
int num = slea.readByte();
for (int i = 0; i < num; i++) {
String name = slea.readMapleAsciiString();
int shout = slea.readByte();
int skill1 = slea.readInt();
int skill2 = slea.readInt();
int skill3 = slea.readInt();
SkillMacro macro = new SkillMacro(skill1, skill2, skill3, name, shout, i);
chr.updateMacros(i, macro);
}
}
public static final void ChangeKeymap(LittleEndianAccessor slea, MapleCharacter chr) {
if ((slea.available() > 8L) && (chr != null)) {
slea.skip(4);
int numChanges = slea.readInt();
for (int i = 0; i < numChanges; i++) {
int key = slea.readInt();
byte type = slea.readByte();
int action = slea.readInt();
chr.changeKeybinding(key, type, action);
}
} else if (chr != null) {
int type = slea.readInt();
int data = slea.readInt();
switch (type) {
case 1:
if (data <= 0) {
chr.getQuestRemove(MapleQuest.getInstance(122221));
} else {
chr.getQuestNAdd(MapleQuest.getInstance(122221)).setCustomData(String.valueOf(data));
}
break;
case 2:
if (data <= 0) {
chr.getQuestRemove(MapleQuest.getInstance(122223));
} else {
chr.getQuestNAdd(MapleQuest.getInstance(122223)).setCustomData(String.valueOf(data));
}
break;
}
}
}
public static final void ANGELICCHANGE(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
if ((chr == null) || (chr.getMap() == null)) {
return;
}
chr.getMap().broadcastMessage(chr, CField.showAnelicbuster(chr.getId(), slea.readInt()), false);
chr.getMap().broadcastMessage(chr, CField.updateCharLook(chr), false);
c.getSession().write(CWvsContext.enableActions());
}
public static final void UseTitle(int itemId, MapleClient c, MapleCharacter chr) {
if ((chr == null) || (chr.getMap() == null)) {
return;
}
Item toUse = chr.getInventory(MapleInventoryType.SETUP).findById(itemId);
if (toUse == null) {
return;
}
if (itemId <= 0) {
chr.getQuestRemove(MapleQuest.getInstance(124000));
} else {
chr.getQuestNAdd(MapleQuest.getInstance(124000)).setCustomData(String.valueOf(itemId));
}
chr.getMap().broadcastMessage(chr, CField.showTitle(chr.getId(), itemId), false);
c.getSession().write(CWvsContext.enableActions());
}
public static final void UseChair(int itemId, MapleClient c, MapleCharacter chr) {
if ((chr == null) || (chr.getMap() == null)) {
return;
}
Item toUse = chr.getInventory(MapleInventoryType.SETUP).findById(itemId);
if (toUse == null) {
return;
}
if ((GameConstants.isFishingMap(chr.getMapId())) && (itemId == 3011000)) {
chr.startFishingTask();
}
chr.setChair(itemId);
chr.getMap().broadcastMessage(chr, CField.showChair(chr.getId(), itemId), false);
c.getSession().write(CWvsContext.enableActions());
}
public static void absorbingDF(LittleEndianAccessor slea, final MapleClient c) {
int size = slea.readInt();
int room = 0;
byte unk = 0;
int sn;
for (int i = 0; i < size; i++) {
room = GameConstants.demonAvenger(c.getPlayer().getJob()) || c.getPlayer().getJob() == 212 ? 0 : slea.readInt();
unk = slea.readByte();
sn = slea.readInt();
if (GameConstants.isDemon(c.getPlayer().getJob())) {
// c.getPlayer().addMP(c.getPlayer().getStat().getForce(room));
}
if (GameConstants.angelic(c.getPlayer().getJob())) {
boolean rand = Randomizer.isSuccess(80);
if (sn > 0) {
if (rand) {
c.getSession().write(JobPacket.AngelicPacket.SoulSeekerRegen(c.getPlayer(), sn));
}
}
}
if ((GameConstants.demonAvenger(c.getPlayer().getJob())) && slea.available() >= 8) {
// c.getPlayer().getMap().broadcastMessage(MainPacketCreator.ShieldChacingRe(c.getPlayer().getId(), slea.readInt(), slea.readInt(), unk, c.getPlayer().getKeyValue2("schacing")));
}
if (c.getPlayer().getJob() == 212) {
// c.getPlayer().getMap().broadcastMessage(MainPacketCreator.MegidoFlameRe(c.getPlayer().getId(), unk, slea.readInt()));
}
}
}
public static void LinkSkill(final LittleEndianAccessor slea, final MapleClient c, final MapleCharacter chr) {
//slea: [76 7F 31 01] [35 00 00 00]
int skill = slea.readInt();
int cid = slea.readInt();
boolean found = false;
for (MapleCharacter chr2 : c.loadCharacters(c.getPlayer().getWorld())) {
if (chr2.getId() == cid) {
found = true;
}
}
if (GameConstants.getLinkSkillByJob(chr.getJob()) != skill || !found || chr.getLevel() > 70) {
c.getPlayer().dropMessage(1, "An error has occured.");
c.getSession().write(CWvsContext.enableActions());
return;
}
MapleCharacter.addLinkSkill(cid, skill);
}
public static final void CancelChair(short id, MapleClient c, MapleCharacter chr) {
if (id == -1) {
chr.cancelFishingTask();
chr.setChair(0);
c.getSession().write(CField.cancelChair(-1));
if (chr.getMap() != null) {
chr.getMap().broadcastMessage(chr, CField.showChair(chr.getId(), 0), false);
}
} else {
chr.setChair(id);
c.getSession().write(CField.cancelChair(id));
}
}
public static final void TrockAddMap(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
byte addrem = slea.readByte();
byte vip = slea.readByte();
if (vip == 1) {
if (addrem == 0) {
chr.deleteFromRegRocks(slea.readInt());
} else if (addrem == 1) {
if (!FieldLimitType.VipRock.check(chr.getMap().getFieldLimit())) {
chr.addRegRockMap();
} else {
chr.dropMessage(1, "This map is not available to enter for the list.");
}
}
} else if (vip == 2) {
if (addrem == 0) {
chr.deleteFromRocks(slea.readInt());
} else if (addrem == 1) {
if (!FieldLimitType.VipRock.check(chr.getMap().getFieldLimit())) {
chr.addRockMap();
} else {
chr.dropMessage(1, "This map is not available to enter for the list.");
}
}
} else if (vip == 3) {
if (addrem == 0) {
chr.deleteFromHyperRocks(slea.readInt());
} else if (addrem == 1) {
if (!FieldLimitType.VipRock.check(chr.getMap().getFieldLimit())) {
chr.addHyperRockMap();
} else {
chr.dropMessage(1, "This map is not available to enter for the list.");
}
}
}
c.getSession().write(MTSCSPacket.OnMapTransferResult(chr, vip, addrem == 0));
}
public static void CharInfoRequest(final int objectid, final MapleClient c, final MapleCharacter chr) {
if (c.getPlayer() == null || c.getPlayer().getMap() == null) {
return;
}
final MapleCharacter player = c.getPlayer().getMap().getCharacterById(objectid);
c.getSession().write(CWvsContext.enableActions());
if (player != null) {
c.getSession().write(CWvsContext.charInfo(player, c.getPlayer().getId() == objectid));
}
}
public static final void TakeDamage(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
try {
slea.skip(4);
slea.readInt();
byte type = slea.readByte();
slea.skip(1);
int damage = slea.readInt();
slea.skip(2);
boolean isDeadlyAttack = false;
boolean pPhysical = false;
int oid = 0;
int monsteridfrom = 0;
int fake = 0;
int mpattack = 0;
int skillid = 0;
int pID = 0;
int pDMG = 0;
byte direction = 0;
byte pType = 0;
Point pPos = new Point(0, 0);
MapleMonster attacker = null;
if ((chr == null) || (chr.isHidden()) || (chr.getMap() == null)) {
c.getSession().write(CWvsContext.enableActions());
return;
}
if ((chr.isGM()) && (chr.isInvincible())) {
c.getSession().write(CWvsContext.enableActions());
return;
}
PlayerStats stats = chr.getStat();
if ((type != -2) && (type != -3) && (type != -4)) {
monsteridfrom = slea.readInt();
oid = slea.readInt();
attacker = chr.getMap().getMonsterByOid(oid);
direction = slea.readByte();
if ((attacker == null) || (attacker.getId() != monsteridfrom) || (attacker.getLinkCID() > 0) || (attacker.isFake()) || (attacker.getStats().isFriendly())) {
return;
}
if (chr.getMapId() == 915000300) {
MapleMap to = chr.getClient().getChannelServer().getMapFactory().getMap(915000200);
chr.dropMessage(5, "You've been found out! Retreat!");
chr.changeMap(to, to.getPortal(1));
return;
}
if ((type != -1) && (damage > 0)) {
MobAttackInfo attackInfo = attacker.getStats().getMobAttack(type);
if (attackInfo != null) {
if ((attackInfo.isElement) && (stats.TER > 0) && (Randomizer.nextInt(100) < stats.TER)) {
// System.out.println(new StringBuilder().append("Avoided ER from mob id: ").append(monsteridfrom).toString());
// return;
}
if (attackInfo.isDeadlyAttack()) {
isDeadlyAttack = true;
mpattack = stats.getMp() - 1;
} else {
mpattack += attackInfo.getMpBurn();
}
MobSkill skill = MobSkillFactory.getMobSkill(attackInfo.getDiseaseSkill(), attackInfo.getDiseaseLevel());
if ((skill != null) && ((damage == -1) || (damage > 0))) {
skill.applyEffect(chr, attacker, false);
}
attacker.setMp(attacker.getMp() - attackInfo.getMpCon());
}
}
skillid = slea.readInt();
pDMG = slea.readInt();
byte defType = slea.readByte();
slea.skip(1);
if (defType == 1) {
Skill bx = SkillFactory.getSkill(31110008);
int bof = chr.getTotalSkillLevel(bx);
if (bof > 0) {
MapleStatEffect eff = bx.getEffect(bof);
if (Randomizer.nextInt(100) <= eff.getX()) {
chr.handleForceGain(oid, 31110008, eff.getZ());
}
}
}
if (skillid != 0) {
pPhysical = slea.readByte() > 0;
pID = slea.readInt();
pType = slea.readByte();
slea.skip(4);
pPos = slea.readPos();
}
}
if ((GameConstants.isluminous(chr.getJob())) && (chr.getBuffedValue(MapleBuffStat.Black_Blessing) != null)) {
if (chr.getBuffedValue(MapleBuffStat.Black_Blessing) != null) {
chr.applyBlackBlessingBuff(-1);
}
// chr.checkLunarTide();
}
if (damage == -1) {
fake = 4020002 + (chr.getJob() / 10 - 40) * 100000;
if ((fake != 4120002) && (fake != 4220002)) {
fake = 4120002;
}
if ((type == -1) && (chr.getJob() == 122) && (attacker != null) && (chr.getInventory(MapleInventoryType.EQUIPPED).getItem((short) -10) != null) && (chr.getTotalSkillLevel(1220006) > 0)) {
MapleStatEffect eff = SkillFactory.getSkill(1220006).getEffect(chr.getTotalSkillLevel(1220006));
attacker.applyStatus(chr, new MonsterStatusEffect(MonsterStatus.STUN, Integer.valueOf(1), 1220006, null, false), false, eff.getDuration(), true, eff);
fake = 1220006;
}
if (chr.getTotalSkillLevel(fake) > 0);
} else if ((damage < -1) || (damage > 200000)) {
c.getSession().write(CWvsContext.enableActions());
return;
}
if ((chr.getStat().dodgeChance > 0) && (Randomizer.nextInt(100) < chr.getStat().dodgeChance)) {
c.getSession().write(CField.EffectPacket.showForeignEffect(20));
return;
}
if ((pPhysical) && (skillid == 1201007) && (chr.getTotalSkillLevel(1201007) > 0)) {
damage -= pDMG;
if (damage > 0) {
MapleStatEffect eff = SkillFactory.getSkill(1201007).getEffect(chr.getTotalSkillLevel(1201007));
long enemyDMG = Math.min(damage * (eff.getY() / 100), attacker.getMobMaxHp() / 2L);
if (enemyDMG > pDMG) {
enemyDMG = pDMG;
}
if (enemyDMG > 1000L) {
enemyDMG = 1000L;
}
attacker.damage(chr, enemyDMG, true, 1201007);
} else {
damage = 1;
}
}
Pair modify = chr.modifyDamageTaken(damage, attacker);
damage = ((Double) modify.left).intValue();
if (damage > 0) {
if (chr.getBuffedValue(MapleBuffStat.MORPH) != null) {
chr.cancelMorphs();
}
boolean mpAttack = (chr.getBuffedValue(MapleBuffStat.MECH_CHANGE) != null) && (chr.getBuffSource(MapleBuffStat.MECH_CHANGE) != 35121005);
if (chr.getBuffedValue(MapleBuffStat.MAGIC_GUARD) != null) {
int hploss = 0, mploss = 0;
if (isDeadlyAttack) {
if (stats.getHp() > 1) {
hploss = stats.getHp() - 1;
}
if (stats.getMp() > 1) {
mploss = stats.getMp() - 1;
}
if (chr.getBuffedValue(MapleBuffStat.INFINITY) != null) {
mploss = 0;
}
chr.addMPHP(-hploss, -mploss);
//} else if (mpattack > 0) {
// chr.addMPHP(-damage, -mpattack);
} else {
mploss = (int) (damage * (chr.getBuffedValue(MapleBuffStat.MAGIC_GUARD).doubleValue() / 100.0)) + mpattack;
// c.getPlayer().dropMessage(6, "Magicguard MP damage: " + mploss + " Guard value: " + (chr.getBuffedValue(MapleBuffStat.MAGIC_GUARD).doubleValue() / 100.0));
hploss = damage - mploss;
if (chr.getBuffedValue(MapleBuffStat.INFINITY) != null) {
mploss = 0;
} else if (mploss > stats.getMp()) {
mploss = stats.getMp();
hploss = damage - mploss + mpattack;
}
chr.addMPHP(-hploss, -mploss);
}
}
if (chr.getTotalSkillLevel(SkillFactory.getSkill(27000003)) > 0) {
int hploss = 0;
int mploss = 0;
if (isDeadlyAttack) {
if (stats.getHp() > 1) {
hploss = stats.getHp() - 1;
}
if (stats.getMp() > 1) {
mploss = stats.getMp() - 1;
}
chr.addMPHP(-hploss, -mploss);
} else {
double lost = SkillFactory.getSkill(27000003).getEffect(chr.getTotalSkillLevel(SkillFactory.getSkill(27000003))).getX() / 100.0D;
mploss = (int) (damage * lost + mpattack);
hploss = damage - mploss;
if (mploss > stats.getMp()) {
mploss = stats.getMp();
hploss = damage - mploss + mpattack;
}
chr.addMPHP(-hploss, -mploss);
}
} else if (chr.getStat().mesoGuardMeso > 0.0D) {
int mesoloss = (int) (damage * (chr.getStat().mesoGuardMeso / 100.0D));
if (chr.getMeso() < mesoloss) {
chr.gainMeso(-chr.getMeso(), false);
chr.cancelBuffStats(new MapleBuffStat[]{MapleBuffStat.MESOGUARD});
} else {
chr.gainMeso(-mesoloss, false);
}
if ((isDeadlyAttack) && (stats.getMp() > 1)) {
mpattack = stats.getMp() - 1;
}
chr.addMPHP(-damage, -mpattack);
} else if (isDeadlyAttack) {
chr.addMPHP(stats.getHp() > 1 ? -(stats.getHp() - 1) : 0, (stats.getMp() > 1) && (!mpAttack) ? -(stats.getMp() - 1) : 0);
} else {
chr.addMPHP(-damage, mpAttack ? 0 : -mpattack);
}
if (!GameConstants.GMS) {
chr.handleBattleshipHP(-damage);
}
if ((chr.inPVP()) && (chr.getStat().getHPPercent() <= 20)) {
chr.getStat();
SkillFactory.getSkill(PlayerStats.getSkillByJob(93, chr.getJob())).getEffect(1).applyTo(chr);
}
}
byte offset = 0;
int offset_d = 0;
if (slea.available() == 1L) {
offset = slea.readByte();
if ((offset == 1) && (slea.available() >= 4L)) {
offset_d = slea.readInt();
}
if ((offset < 0) || (offset > 2)) {
offset = 0;
}
}
chr.getMap().broadcastMessage(chr, CField.damagePlayer(chr.getId(), type, damage, monsteridfrom, direction, skillid, pDMG, pPhysical, pID, pType, pPos, offset, offset_d, fake), false);
} catch (ArrayIndexOutOfBoundsException dd) {
}
}
public static final void AranCombo(MapleClient c, MapleCharacter chr, int toAdd) {
if ((chr != null) && (chr.getJob() >= 2000) && (chr.getJob() <= 2112)) {
short combo = chr.getCombo();
long curr = System.currentTimeMillis();
if ((combo > 0) && (curr - chr.getLastCombo() > 7000L)) {
combo = 0;
}
combo = (short) Math.min(30000, combo + toAdd);
chr.setLastCombo(curr);
chr.setCombo(combo);
c.getSession().write(CField.testCombo(combo));
switch (combo) {
case 10:
case 20:
case 30:
case 40:
case 50:
case 60:
case 70:
case 80:
case 90:
case 100:
if (chr.getSkillLevel(21000000) >= combo / 10) {
SkillFactory.getSkill(21000000).getEffect(combo / 10).applyComboBuff(chr, combo);
}
break;
}
}
}
public static final void UseItemEffect(int itemId, MapleClient c, MapleCharacter chr) {
Item toUse = chr.getInventory((itemId == 4290001) || (itemId == 4290000) ? MapleInventoryType.ETC : MapleInventoryType.CASH).findById(itemId);
if ((toUse == null) || (toUse.getItemId() != itemId) || (toUse.getQuantity() < 1)) {
c.getSession().write(CWvsContext.enableActions());
return;
}
if (itemId != 5510000) {
chr.setItemEffect(itemId);
}
chr.getMap().broadcastMessage(chr, CField.itemEffect(chr.getId(), itemId), false);
}
public static final void CancelItemEffect(int id, MapleCharacter chr) {
chr.cancelEffect(MapleItemInformationProvider.getInstance().getItemEffect(-id), false, -1L);
}
public static final void CancelBuffHandler(int sourceid, MapleCharacter chr) {
if ((chr == null) || (chr.getMap() == null)) {
return;
}
Skill skill = SkillFactory.getSkill(sourceid);
switch (sourceid) {
// // case 33001001: //��Ծ� ���̵�
// // chr.send(CWvsContext.cancelJaguarRiding());
// // break;
case 11101022: //��
chr.send(CField.cancelPollingMoon());
chr.getMap().broadcastMessage(chr, CField.cancelPollingMoon(), false);
break;
case 11111022: //����¡ ��
chr.send(CField.cancelLizingSun());
chr.getMap().broadcastMessage(chr, CField.cancelLizingSun(), false);
break;
case 4341052:
chr.getStat().setHp(0, chr);
chr.updateSingleStat(MapleStat.HP, 0);
chr.getClient().getSession().write(CWvsContext.enableActions());
break;
default: {
if (skill.isChargeSkill()) {
chr.setKeyDownSkill_Time(0L);
chr.getMap().broadcastMessage(chr, CField.skillCancel(chr, sourceid), false);
} else {
if (skill.getEffect(1).isMonsterRiding()) {
chr.cancelEffect(skill.getEffect(1), false, -1);
chr.getClient().getSession().write(CWvsContext.BuffPacket.cancelRiding());
if (chr.getBuffedValue(MapleBuffStat.SOARING) != null) {
chr.cancelEffectFromBuffStat(MapleBuffStat.SOARING);
}
} else {
chr.cancelEffect(skill.getEffect(1), false, -1);
}
}
break;
}
}
}
public static final void CancelMech(LittleEndianAccessor slea, MapleCharacter chr) {
if (chr == null) {
return;
}
int sourceid = slea.readInt();
if ((sourceid % 10000 < 1000) && (SkillFactory.getSkill(sourceid) == null)) {
sourceid += 1000;
}
Skill skill = SkillFactory.getSkill(sourceid);
if (skill == null) {
return;
}
if (skill.isChargeSkill()) {
chr.setKeyDownSkill_Time(0L);
chr.getMap().broadcastMessage(chr, CField.skillCancel(chr, sourceid), false);
} else {
chr.cancelEffect(skill.getEffect(slea.readByte()), false, -1L);
}
}
public static final void QuickSlot(LittleEndianAccessor slea, MapleCharacter chr) {
if ((slea.available() == 32L) && (chr != null)) {
StringBuilder ret = new StringBuilder();
for (int i = 0; i < 8; i++) {
ret.append(slea.readInt()).append(",");
}
ret.deleteCharAt(ret.length() - 1);
chr.getQuestNAdd(MapleQuest.getInstance(123000)).setCustomData(ret.toString());
}
}
public static final void SkillEffect(LittleEndianAccessor slea, MapleCharacter chr) {
int skillId = slea.readInt();
if (skillId >= 91000000) {
chr.getClient().getSession().write(CWvsContext.enableActions());
return;
}
byte level = slea.readByte();
short direction = slea.readShort();
byte unk = slea.readByte();
Skill skill = SkillFactory.getSkill(GameConstants.getLinkedAranSkill(skillId));
if ((chr == null) || (skill == null) || (chr.getMap() == null)) {
return;
}
int skilllevel_serv = chr.getTotalSkillLevel(skill);
if ((skilllevel_serv > 0) && (skilllevel_serv == level) && ((skillId == 33101005) || (skill.isChargeSkill()))) {
chr.setKeyDownSkill_Time(System.currentTimeMillis());
if (skillId == 33101005) {
chr.setLinkMid(slea.readInt(), 0);
}
chr.getMap().broadcastMessage(chr, CField.skillEffect(chr, skillId, level, direction, unk), false);
}
}
public static void SpecialMove(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
if ((chr == null) || (chr.hasBlockedInventory()) || (chr.getMap() == null) || (slea.available() < 9L)) {
c.getSession().write(CWvsContext.enableActions());
return;
}
slea.skip(4);
int skillid = slea.readInt();
if (skillid >= 91000000 && skillid < 100000000) {
c.getSession().write(CWvsContext.enableActions());
return;
}
if (skillid == 23111008) {
skillid += Randomizer.nextInt(2);
}
int xy1 = 0;
int xy2 = 0;
if (skillid == 65111100) {
xy1 = slea.readShort();
xy2 = slea.readShort();
int soulnum = slea.readByte();
int scheck = 0;
int scheck2 = 0;
if (soulnum == 1) {
scheck = slea.readInt();
} else if (soulnum == 2) {
scheck = slea.readInt();
scheck2 = slea.readInt();
}
c.getSession().write(JobPacket.AngelicPacket.SoulSeeker(chr, skillid, soulnum, scheck, scheck2));
c.getSession().write(JobPacket.AngelicPacket.unlockSkill());
c.getSession().write(JobPacket.AngelicPacket.RechargeEffect());
c.getSession().write(CWvsContext.enableActions());
return;
}
if (skillid >= 100000000) {
slea.readByte(); //zero
}
int skillLevel = slea.readByte();
// System.err.println(skillLevel);
Skill skill = SkillFactory.getSkill(skillid);
if ((skill == null) || ((GameConstants.isAngel(skillid)) && (chr.getStat().equippedSummon % 10000 != skillid % 10000)) || ((chr.inPVP()) && (skill.isPVPDisabled()))) {
c.getSession().write(CWvsContext.enableActions());
return;
}
int levelCheckSkill = 0;
if ((GameConstants.isPhantom(chr.getJob())) && (!GameConstants.isPhantom(skillid / 10000))) {
int skillJob = skillid / 10000;
if (skillJob % 100 == 0) {
levelCheckSkill = 24001001;
} else if (skillJob % 10 == 0) {
levelCheckSkill = 24101001;
} else if (skillJob % 10 == 1) {
levelCheckSkill = 24111001;
} else {
levelCheckSkill = 24121001;
}
}
if ((levelCheckSkill == 0) && ((chr.getTotalSkillLevel(GameConstants.getLinkedAttackSkill(skillid)) <= 0) || (chr.getTotalSkillLevel(GameConstants.getLinkedAttackSkill(skillid)) != skillLevel))) {
if ((!GameConstants.isMulungSkill(skillid)) && (!GameConstants.isPyramidSkill(skillid)) && (chr.getTotalSkillLevel(GameConstants.getLinkedAttackSkill(skillid)) <= 0) && !GameConstants.isAngel(skillid)) {
c.getSession().write(CWvsContext.enableActions());
return;
}
if (GameConstants.isMulungSkill(skillid)) {
if (chr.getMapId() / 10000 != 92502) {
return;
}
if (chr.getMulungEnergy() < 10000) {
return;
}
chr.mulung_EnergyModify(false);
} else if ((GameConstants.isPyramidSkill(skillid))
&& (chr.getMapId() / 10000 != 92602) && (chr.getMapId() / 10000 != 92601)) {
return;
}
}
skillLevel = chr.getTotalSkillLevel(GameConstants.getLinkedAttackSkill(skillid));
MapleStatEffect effect = chr.inPVP() ? skill.getPVPEffect(skillLevel) : skill.getEffect(skillLevel);
if ((effect.isMPRecovery()) && (chr.getStat().getHp() < chr.getStat().getMaxHp() / 100 * 10)) {
c.getPlayer().dropMessage(5, "You do not have the HP to use this skill.");
c.getSession().write(CWvsContext.enableActions());
return;
}
if ((effect.getCooldown(chr) > 0) && (!chr.isGM())) {
if (chr.skillisCooling(skillid) && skillid != 24121005) {
c.getSession().write(CWvsContext.enableActions());
return;
}
if ((skillid != 5221006) && (skillid != 35111002)) {
c.getSession().write(CField.skillCooldown(skillid, effect.getCooldown(chr)));
chr.addCooldown(skillid, System.currentTimeMillis(), effect.getCooldown(chr) * 1000);
}
}
int mobID;
MapleMonster mob;
switch (skillid) {
case 1121001:
case 1221001:
case 1321001:
case 9001020:
case 9101020:
case 31111003:
byte number_of_mobs = slea.readByte();
slea.skip(3);
for (int i = 0; i < number_of_mobs; i++) {
int mobId = slea.readInt();
mob = chr.getMap().getMonsterByOid(mobId);
if (mob == null) {
continue;
}
mob.switchController(chr, mob.isControllerHasAggro());
mob.applyStatus(chr, new MonsterStatusEffect(MonsterStatus.STUN, Integer.valueOf(1), skillid, null, false), false, effect.getDuration(), true, effect);
}
chr.getMap().broadcastMessage(chr, CField.EffectPacket.showBuffeffect(chr.getId(), skillid, 1, chr.getLevel(), skillLevel, slea.readByte()), chr.getTruePosition());
c.getSession().write(CWvsContext.enableActions());
break;
case 30001061:
mobID = slea.readInt();
mob = chr.getMap().getMonsterByOid(mobID);
if (mob != null) {
boolean success = (mob.getHp() <= mob.getMobMaxHp() / 2L) && (mob.getId() >= 9304000) && (mob.getId() < 9305000);
chr.getMap().broadcastMessage(chr, CField.EffectPacket.showBuffeffect(chr.getId(), skillid, 1, chr.getLevel(), skillLevel, (byte) (success ? 1 : 0)), chr.getTruePosition());
if (success) {
chr.getQuestNAdd(MapleQuest.getInstance(GameConstants.JAGUAR)).setCustomData(String.valueOf((mob.getId() - 9303999) * 10));
chr.getMap().killMonster(mob, chr, true, false, (byte) 1);
chr.cancelEffectFromBuffStat(MapleBuffStat.MONSTER_RIDING);
c.getSession().write(CWvsContext.updateJaguar(chr));
} else {
chr.dropMessage(5, "The monster has too much physical strength, so you cannot catch it.");
}
}
c.getSession().write(CWvsContext.enableActions());
break;
case 30001062:
chr.dropMessage(5, "No monsters can be summoned. Capture a monster first.");
c.getSession().write(CWvsContext.enableActions());
break;
case 33101005:
mobID = chr.getFirstLinkMid();
mob = chr.getMap().getMonsterByOid(mobID);
chr.setKeyDownSkill_Time(0L);
chr.getMap().broadcastMessage(chr, CField.skillCancel(chr, skillid), false);
if (mob != null) {
boolean success = (mob.getStats().getLevel() < chr.getLevel()) && (mob.getId() < 9000000) && (!mob.getStats().isBoss());
if (success) {
chr.getMap().broadcastMessage(MobPacket.suckMonster(mob.getObjectId(), chr.getId()));
chr.getMap().killMonster(mob, chr, false, false, (byte) -1);
} else {
chr.dropMessage(5, "The monster has too much physical strength, so you cannot catch it.");
}
} else {
chr.dropMessage(5, "No monster was sucked. The skill failed.");
}
c.getSession().write(CWvsContext.enableActions());
break;
case 20040216:
case 20040217:
case 20040220:
case 20041239:
chr.changeLuminousMode(skillid);
c.getSession().write(CWvsContext.enableActions());
break;
case 11101022:
case 11111022:
case 11121005:
case 11121011:
case 11121012:
chr.changeWarriorStance(skillid);
c.getSession().write(CWvsContext.enableActions());
break;
case 4341003:
chr.setKeyDownSkill_Time(0L);
chr.getMap().broadcastMessage(chr, CField.skillCancel(chr, skillid), false);
default:
Point pos = null;
if ((slea.available() == 5L) || (slea.available() == 7L)) {
pos = slea.readPos();
}
if (effect.isMagicDoor()) {
if (!FieldLimitType.MysticDoor.check(chr.getMap().getFieldLimit())) {
effect.applyTo(c.getPlayer(), pos);
} else {
c.getSession().write(CWvsContext.enableActions());
}
} else {
int mountid = MapleStatEffect.parseMountInfo(c.getPlayer(), skill.getId());
if ((mountid != 0) && (mountid != GameConstants.getMountItem(skill.getId(), c.getPlayer())) && (!c.getPlayer().isIntern()) && (c.getPlayer().getBuffedValue(MapleBuffStat.MONSTER_RIDING) == null) && (c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((byte) -122) == null)
&& (!GameConstants.isMountItemAvailable(mountid, c.getPlayer().getJob()))) {
c.getSession().write(CWvsContext.enableActions());
return;
}
// System.err.println("pos " + pos);
// System.err.println("effect " + effect.getSourceId());
effect.applyTo(c.getPlayer(), pos);
}
}
if (GameConstants.angelic(chr.getJob())) {
int Recharge = effect.getOnActive();
if (Recharge > -1) {
if (Randomizer.isSuccess(Recharge)) {
c.getSession().write(JobPacket.AngelicPacket.unlockSkill());
c.getSession().write(JobPacket.AngelicPacket.showRechargeEffect());
if (c.getPlayer().isGM()) {
c.getSession().write(JobPacket.AngelicPacket.unlockSkill());
// c.getSession().write(AngelicPacket.showRechargeEffect());
} else {
c.getSession().write(JobPacket.AngelicPacket.lockSkill(skillid));
}
}
c.getSession().write(CWvsContext.enableActions());
} else {
if (c.getPlayer().isGM()) {
c.getSession().write(JobPacket.AngelicPacket.unlockSkill());
// c.getSession().write(AngelicPacket.showRechargeEffect());
} else {
c.getSession().write(JobPacket.AngelicPacket.lockSkill(skillid));
}
}
}
}
public static void closeRangeAttack(LittleEndianAccessor slea, MapleClient c, final MapleCharacter chr, final boolean energy) {
if ((chr == null) || ((energy) && (chr.getBuffedValue(MapleBuffStat.ENERGY_CHARGE) == null) && (chr.getBuffedValue(MapleBuffStat.ASURA) == null) && (chr.getBuffedValue(MapleBuffStat.BODY_PRESSURE) == null) && (chr.getBuffedValue(MapleBuffStat.DARK_AURA) == null) && (chr.getBuffedValue(MapleBuffStat.TORNADO) == null) && (chr.getBuffedValue(MapleBuffStat.SUMMON) == null) && (chr.getBuffedValue(MapleBuffStat.RAINING_MINES) == null) && (chr.getBuffedValue(MapleBuffStat.TELEPORT_MASTERY) == null))) {
c.getPlayer().getClient().getSession().write(CWvsContext.enableActions());
return;
}
if (chr.getBuffedValue(MapleBuffStat.SOARING) != null) {
c.getPlayer().dropMessage(6, "Can't attack while soaring.");
c.getPlayer().getClient().getSession().write(CWvsContext.enableActions());
return;
}
if ((chr.hasBlockedInventory()) || (chr.getMap() == null)) {
c.getPlayer().getClient().getSession().write(CWvsContext.enableActions());
return;
}
try {
AttackInfo attack = DamageParse.parseDmgM(slea, chr);
if (attack == null) {
c.getSession().write(CWvsContext.enableActions());
return;
}
final boolean mirror = chr.getBuffedValue(MapleBuffStat.SHADOWPARTNER) != null;
double maxdamage = chr.getStat().getCurrentMaxBaseDamage();
Item shield = c.getPlayer().getInventory(MapleInventoryType.EQUIPPED).getItem((short) -10);
int attackCount = (shield != null) && (shield.getItemId() / 10000 == 134) ? 2 : 1;
int skillLevel = 0;
MapleStatEffect effect = null;
Skill skill = null;
if (attack.skill != 0) {
skill = SkillFactory.getSkill(GameConstants.getLinkedAranSkill(attack.skill));
if ((skill == null) || ((GameConstants.isAngel(attack.skill)) && (chr.getStat().equippedSummon % 10000 != attack.skill % 10000))) {
c.getSession().write(CWvsContext.enableActions());
return;
}
skillLevel = chr.getTotalSkillLevel(skill);
effect = attack.getAttackEffect(chr, skillLevel, skill);
if (effect == null) {
return;
}
maxdamage *= (effect.getDamage() + chr.getStat().getDamageIncrease(attack.skill)) / 100.0D;
attackCount = effect.getAttackCount();
if (GameConstants.demonAvenger(chr.getJob())) {
int exceedMax = chr.getSkillLevel(31220044) > 0 ? 20 : 20;
chr.showInfo("Info", false, "exceedMax;" + exceedMax);
if (chr.getExceed() + 1 > exceedMax) {
chr.setExceed((short) exceedMax);
} else {
chr.gainExceed((short) 1);
}
}
if ((effect.getCooldown(chr) > 0) && (!chr.isGM()) && (!energy)) {
if (chr.skillisCooling(attack.skill)) {
c.getSession().write(CWvsContext.enableActions());
return;
}
c.getSession().write(CField.skillCooldown(attack.skill, effect.getCooldown(chr)));
chr.addCooldown(attack.skill, System.currentTimeMillis(), effect.getCooldown(chr) * 1000);
}
}
attack = DamageParse.Modify_AttackCrit(attack, chr, 1, effect);
attackCount *= (mirror ? 2 : 1);
if (!energy) {
int numFinisherOrbs = 0;
Integer comboBuff = chr.getBuffedValue(MapleBuffStat.COMBO);
if (isFinisher(attack.skill) > 0) {
if (comboBuff != null) {
numFinisherOrbs = comboBuff.intValue() - 1;
}
if (numFinisherOrbs <= 0) {
return;
}
chr.handleOrbconsume(isFinisher(attack.skill));
if (!GameConstants.GMS) {
maxdamage *= numFinisherOrbs;
}
}
}
chr.checkFollow();
if (!chr.isHidden()) {
chr.getMap().broadcastMessage(chr, CField.closeRangeAttack(chr.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, attack.allDamage, energy, chr.getLevel(), chr.getStat().passive_mastery(), attack.animation, attack.charge), chr.getTruePosition());
} else {
chr.getMap().broadcastGMMessage(chr, CField.closeRangeAttack(chr.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, attack.allDamage, energy, chr.getLevel(), chr.getStat().passive_mastery(), attack.animation, attack.charge), false);
}
if (chr.getBuffedValue(MapleBuffStat.moon1) != null) {
xx++;
if (xx % 2 == 0) {
SkillFactory.getSkill(11111022).getEffect(30).applyTo(c.getPlayer());
} else {
SkillFactory.getSkill(11101022).getEffect(30).applyTo(c.getPlayer());
}
}
DamageParse.applyAttack(attack, skill, c.getPlayer(), attackCount, maxdamage, effect, mirror ? AttackType.NON_RANGED_WITH_MIRROR : AttackType.NON_RANGED);
WeakReference<MapleCharacter>[] clones = chr.getClones();
for (int i = 0; i < clones.length; i++) {
if (clones[i].get() != null) {
final MapleCharacter clone = clones[i].get();
// CloneTimer.getInstance().schedule(new Runnable() {
// public void run() {
if (!chr.isHidden()) {
chr.getMap().broadcastMessage(clone, CField.closeRangeAttack(clone.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, attack.allDamage, energy, chr.getLevel(), chr.getStat().passive_mastery(), attack.animation, attack.charge), clone.getTruePosition());
} else {
chr.getMap().broadcastGMMessage(clone, CField.closeRangeAttack(clone.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, attack.allDamage, energy, chr.getLevel(), chr.getStat().passive_mastery(), attack.animation, attack.charge), false);
}
DamageParse.applyAttack(attack, skill, c.getPlayer(), attackCount, maxdamage, effect, mirror ? AttackType.NON_RANGED_WITH_MIRROR : AttackType.NON_RANGED);
}
}
} catch (ArrayIndexOutOfBoundsException dd) {
}
}
public static void rangedAttack(LittleEndianAccessor slea, MapleClient c, final MapleCharacter chr) {
try {
if (chr == null) {
c.getPlayer().getClient().getSession().write(CWvsContext.enableActions());
return;
}
if ((chr.hasBlockedInventory()) || (chr.getMap() == null)) {
c.getPlayer().getClient().getSession().write(CWvsContext.enableActions());
return;
}
if (chr.getBuffedValue(MapleBuffStat.SOARING) != null) {
c.getPlayer().dropMessage(6, "Can't attack while soaring.");
c.getPlayer().getClient().getSession().write(CWvsContext.enableActions());
return;
}
AttackInfo attack = DamageParse.parseDmgR(slea, chr);
if (attack == null) {
c.getSession().write(CWvsContext.enableActions());
return;
}
int bulletCount = 1;
int skillLevel = 0;
MapleStatEffect effect = null;
Skill skill = null;
boolean AOE = attack.skill == 4111004;
boolean noBullet = ((chr.getJob() >= 3500) && (chr.getJob() <= 3512)) || (GameConstants.isCannon(chr.getJob())) || (GameConstants.angelic(chr.getJob())) || (GameConstants.xenon(chr.getJob())) || (GameConstants.demonAvenger(chr.getJob())) || (GameConstants.kaiser(chr.getJob())) || (GameConstants.isJett(chr.getJob())) || (GameConstants.isPhantom(chr.getJob())) || (GameConstants.isMercedes(chr.getJob()));
if (attack.skill != 0) {
skill = SkillFactory.getSkill(GameConstants.getLinkedAranSkill(attack.skill));
if ((skill == null) || ((GameConstants.isAngel(attack.skill)) && (chr.getStat().equippedSummon % 10000 != attack.skill % 10000))) {
c.getSession().write(CWvsContext.enableActions());
return;
}
skillLevel = chr.getTotalSkillLevel(skill);
effect = attack.getAttackEffect(chr, skillLevel, skill);
if (effect == null) {
return;
}
switch (attack.skill) {
case 1077:
case 1078:
case 1079:
case 11077:
case 11078:
case 11079:
case 4111013:
case 4121003:
case 4221003:
case 5121002:
case 5121013:
case 5121016:
case 5201001:
case 5211008:
case 5221013:
case 5221016:
case 5221017:
case 5321001:
case 5711000:
case 5721001:
case 5721003:
case 5721004:
case 5721006:
case 5721007:
case 5921002:
case 11101004:
case 13101005:
case 13111007:
case 14101006:
case 14111008:
case 15111007:
case 21000004:
case 21100004:
case 21100007:
case 21110004:
case 21110011:
case 21120006:
case 33101002:
case 33101007:
case 33121001:
case 33121002:
case 13101020:
case 51001004:
case 51111007:
case 42121002:
case 51121008:
AOE = true;
bulletCount = effect.getAttackCount();
break;
case 35111004:
case 35121005:
case 35121013:
AOE = true;
bulletCount = 6;
break;
default:
bulletCount = effect.getBulletCount();
}
if ((noBullet) && (effect.getBulletCount() < effect.getAttackCount())) {
bulletCount = effect.getAttackCount();
}
if ((noBullet) && (effect.getBulletCount() < effect.getAttackCount())) {
bulletCount = effect.getAttackCount();
}
if ((effect.getCooldown(chr) > 0) && (!chr.isGM()) && (((attack.skill != 35111004) && (attack.skill != 35121013)) || (chr.getBuffSource(MapleBuffStat.MECH_CHANGE) != attack.skill))) {
if (chr.skillisCooling(attack.skill)) {
c.getSession().write(CWvsContext.enableActions());
return;
}
c.getSession().write(CField.skillCooldown(attack.skill, effect.getCooldown(chr)));
chr.addCooldown(attack.skill, System.currentTimeMillis(), effect.getCooldown(chr) * 1000);
}
}
attack = DamageParse.Modify_AttackCrit(attack, chr, 2, effect);
Integer ShadowPartner = chr.getBuffedValue(MapleBuffStat.SHADOWPARTNER);
if (ShadowPartner != null) {
bulletCount *= 2;
}
int projectile = 0;
int visProjectile = 0;
if ((!AOE) && (chr.getBuffedValue(MapleBuffStat.SOULARROW) == null) && (!noBullet)) {
Item ipp = chr.getInventory(MapleInventoryType.USE).getItem((short) attack.slot);
if (ipp == null) {
return;
}
projectile = ipp.getItemId();
if (attack.csstar > 0) {
if (chr.getInventory(MapleInventoryType.CASH).getItem((short) attack.csstar) == null) {
return;
}
visProjectile = chr.getInventory(MapleInventoryType.CASH).getItem((short) attack.csstar).getItemId();
} else {
visProjectile = projectile;
}
if (chr.getBuffedValue(MapleBuffStat.SPIRIT_CLAW) == null) {
int bulletConsume = bulletCount;
if ((effect != null) && (effect.getBulletConsume() != 0)) {
bulletConsume = effect.getBulletConsume() * (ShadowPartner != null ? 2 : 1);
}
if ((chr.getJob() == 412) && (bulletConsume > 0) && (ipp.getQuantity() < MapleItemInformationProvider.getInstance().getSlotMax(projectile))) {
Skill expert = SkillFactory.getSkill(4120010);
if (chr.getTotalSkillLevel(expert) > 0) {
MapleStatEffect eff = expert.getEffect(chr.getTotalSkillLevel(expert));
if (eff.makeChanceResult()) {
ipp.setQuantity((short) (ipp.getQuantity() + 1));
c.getSession().write(CWvsContext.InventoryPacket.updateInventorySlot(MapleInventoryType.USE, ipp, false));
bulletConsume = 0;
c.getSession().write(CWvsContext.InventoryPacket.getInventoryStatus());
}
}
}
if ((bulletConsume > 0) && (!MapleInventoryManipulator.removeById(c, MapleInventoryType.USE, projectile, bulletConsume, false, true))) {
chr.dropMessage(5, "You do not have enough arrows/bullets/stars.");
return;
}
}
} else if ((chr.getJob() >= 3500) && (chr.getJob() <= 3512)) {
visProjectile = 2333000;
} else if (GameConstants.isCannon(chr.getJob())) {
visProjectile = 2333001;
}
int projectileWatk = 0;
if (projectile != 0) {
projectileWatk = MapleItemInformationProvider.getInstance().getWatkForProjectile(projectile);
}
PlayerStats statst = chr.getStat();
double basedamage;
switch (attack.skill) {
case 4001344:
case 4121007:
case 14001004:
case 14111005:
basedamage = Math.max(statst.getCurrentMaxBaseDamage(), statst.getTotalLuk() * 5.0F * (statst.getTotalWatk() + projectileWatk) / 100.0F);
break;
case 4111004:
basedamage = 53000.0D;
break;
default:
basedamage = statst.getCurrentMaxBaseDamage();
switch (attack.skill) {
case 3101005:
basedamage *= effect.getX() / 100.0D;
}
break;
}
if (effect != null) {
basedamage *= (effect.getDamage() + statst.getDamageIncrease(attack.skill)) / 100.0D;
long money = effect.getMoneyCon();
if (money != 0L) {
if (money > chr.getMeso()) {
money = chr.getMeso();
}
chr.gainMeso(-money, false);
}
}
chr.checkFollow();
if (!chr.isHidden()) {
if (attack.skill == 3211006) {
chr.getMap().broadcastMessage(chr, CField.strafeAttack(chr.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, visProjectile, attack.allDamage, attack.position, chr.getLevel(), chr.getStat().passive_mastery(), attack.animation, chr.getTotalSkillLevel(3220010)), chr.getTruePosition());
} else {
chr.getMap().broadcastMessage(chr, CField.rangedAttack(chr.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, visProjectile, attack.allDamage, attack.position, chr.getLevel(), chr.getStat().passive_mastery(), attack.animation), chr.getTruePosition());
}
} else if (attack.skill == 3211006) {
chr.getMap().broadcastGMMessage(chr, CField.strafeAttack(chr.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, visProjectile, attack.allDamage, attack.position, chr.getLevel(), chr.getStat().passive_mastery(), attack.animation, chr.getTotalSkillLevel(3220010)), false);
} else {
chr.getMap().broadcastGMMessage(chr, CField.rangedAttack(chr.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, visProjectile, attack.allDamage, attack.position, chr.getLevel(), chr.getStat().passive_mastery(), attack.animation), false);
}
DamageParse.applyAttack(attack, skill, chr, bulletCount, basedamage, effect, ShadowPartner != null ? AttackType.RANGED_WITH_SHADOWPARTNER : AttackType.RANGED);
WeakReference<MapleCharacter>[] clones = chr.getClones();
for (int i = 0; i < clones.length; i++) {
if (clones[i].get() != null) {
final MapleCharacter clone = clones[i].get();
if (!chr.isHidden()) {
if (attack.skill == 3211006) {
chr.getMap().broadcastMessage(clone, CField.strafeAttack(clone.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, visProjectile, attack.allDamage, attack.position, chr.getLevel(), chr.getStat().passive_mastery(), attack.animation, chr.getTotalSkillLevel(3220010)), chr.getTruePosition());
} else {
chr.getMap().broadcastMessage(clone, CField.rangedAttack(clone.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, visProjectile, attack.allDamage, attack.position, chr.getLevel(), chr.getStat().passive_mastery(), attack.animation), chr.getTruePosition());
}
} else if (attack.skill == 3211006) {
chr.getMap().broadcastGMMessage(clone, CField.strafeAttack(clone.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, visProjectile, attack.allDamage, attack.position, chr.getLevel(), chr.getStat().passive_mastery(), attack.animation, chr.getTotalSkillLevel(3220010)), false);
} else {
chr.getMap().broadcastGMMessage(clone, CField.rangedAttack(clone.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, visProjectile, attack.allDamage, attack.position, chr.getLevel(), chr.getStat().passive_mastery(), attack.animation), false);
}
DamageParse.applyAttack(attack, skill, chr, bulletCount, basedamage, effect, ShadowPartner != null ? AttackType.RANGED_WITH_SHADOWPARTNER : AttackType.RANGED);
}
}
} catch(NullPointerException npe) {
}
}
public static final void MagicDamage(LittleEndianAccessor slea, MapleClient c, final MapleCharacter chr) {
if ((chr == null) || (chr.hasBlockedInventory()) || (chr.getMap() == null)) {
c.getPlayer().getClient().getSession().write(CWvsContext.enableActions());
return;
}
if (chr.getBuffedValue(MapleBuffStat.SOARING) != null) {
c.getPlayer().dropMessage(6, "Can't attack while soaring.");
c.getPlayer().getClient().getSession().write(CWvsContext.enableActions());
return;
}
int bulletCount = 1;
AttackInfo attack = DamageParse.parseDmgMa(slea, chr);
if (attack == null) {
c.getSession().write(CWvsContext.enableActions());
return;
}
Skill skill = SkillFactory.getSkill(GameConstants.getLinkedAranSkill(attack.skill));
if ((skill == null) || ((GameConstants.isAngel(attack.skill)) && (chr.getStat().equippedSummon % 10000 != attack.skill % 10000))) {
c.getSession().write(CWvsContext.enableActions());
return;
}
int skillLevel = chr.getTotalSkillLevel(skill);
MapleStatEffect effect = attack.getAttackEffect(chr, skillLevel, skill);
if (effect == null) {
c.getPlayer().getClient().getSession().write(CWvsContext.enableActions());
return;
}
attack = DamageParse.Modify_AttackCrit(attack, chr, 3, effect);
double maxdamage = chr.getStat().getCurrentMaxBaseDamage() * (effect.getDamage() + chr.getStat().getDamageIncrease(attack.skill)) / 100.0D;
if (GameConstants.isPyramidSkill(attack.skill)) {
maxdamage = 1.0D;
} else if ((GameConstants.isBeginnerJob(skill.getId() / 10000)) && (skill.getId() % 10000 == 1000)) {
maxdamage = 40.0D;
}
if ((effect.getCooldown(chr) > 0) && (!chr.isGM())) {
if (chr.skillisCooling(attack.skill)) {
c.getSession().write(CWvsContext.enableActions());
return;
}
c.getSession().write(CField.skillCooldown(attack.skill, effect.getCooldown(chr)));
chr.addCooldown(attack.skill, System.currentTimeMillis(), effect.getCooldown(chr) * 1000);
}
chr.checkFollow();
if (!chr.isHidden()) {
chr.getMap().broadcastMessage(chr, CField.magicAttack(chr.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, attack.allDamage, attack.charge, chr.getLevel(), attack.animation), chr.getTruePosition());
} else {
chr.getMap().broadcastGMMessage(chr, CField.magicAttack(chr.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, attack.allDamage, attack.charge, chr.getLevel(), attack.animation), false);
}
switch (attack.skill) {
case 27101100: // ���ǵ� ����
case 27101202: // ���̵� ������
case 27111100: // ����Ʈ�� ����Ʈ
case 27111202: // �콺�Ǿ�
case 27121100: // ����Ʈ ���÷���
case 27121202: // ����Į����
case 2121006:
case 2221003:
case 2221006:
case 32111003:
case 2221007:
// case 2321054:
case 2221012:
case 2321007:
case 2111003: // ������ �̽�Ʈ
case 2121003: // �̽�Ʈ �̷���
case 22181002: //��ũ����
bulletCount = effect.getAttackCount();
DamageParse.applyAttack(attack, skill, chr, bulletCount, maxdamage, effect, AttackType.RANGED);
break;
default:
DamageParse.applyAttackMagic(attack, skill, c.getPlayer(), effect, maxdamage);
break;
}
if (skill.getId() >= 27100000 && skill.getId() < 27120400 && attack.targets > 0 && chr.getLuminousState() < 20040000) {
//chr.changeSkillLevel(SkillFactory.getSkill(20040216), (byte) 1, (byte) 1);
//chr.changeSkillLevel(SkillFactory.getSkill(20040217), (byte) 1, (byte) 1);
//chr.changeSkillLevel(SkillFactory.getSkill(20040220), (byte) 1, (byte) 1);
//chr.changeSkillLevel(SkillFactory.getSkill(20041239), (byte) 1, (byte) 1);
chr.setLuminousState(GameConstants.getLuminousSkillMode(skill.getId()));
c.getSession().write(JobPacket.LuminousPacket.giveLuminousState(GameConstants.getLuminousSkillMode(skill.getId()), chr.getLightGauge(), chr.getDarkGauge(), 0));
SkillFactory.getSkill(GameConstants.getLuminousSkillMode(skill.getId())).getEffect(1).applyTo(chr);
}
WeakReference<MapleCharacter>[] clones = chr.getClones();
for (int i = 0; i < clones.length; i++) {
if (clones[i].get() != null) {
final MapleCharacter clone = clones[i].get();
if (!chr.isHidden()) {
chr.getMap().broadcastMessage(clone, CField.magicAttack(clone.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, attack.allDamage, attack.charge, chr.getLevel(), attack.animation), chr.getTruePosition());
} else {
chr.getMap().broadcastGMMessage(clone, CField.magicAttack(clone.getId(), attack.tbyte, attack.skill, skillLevel, attack.display, attack.speed, attack.allDamage, attack.charge, chr.getLevel(), attack.animation), false);
}
switch (attack.skill) {
case 27101100: // ���ǵ� ����
case 27101202: // ���̵� ������
case 27111100: // ����Ʈ�� ����Ʈ
case 27111202: // �콺�Ǿ�
case 27121100: // ����Ʈ ���÷���
case 27121202: // ����Į����
case 2121006:
case 2221003:
case 2221006:
case 32111003:
case 2221007:
// case 2321054:
case 2221012:
case 2321007:
case 2111003: // ������ �̽�Ʈ
case 2121003: // �̽�Ʈ �̷���
case 22181002: //��ũ����
bulletCount = effect.getAttackCount();
DamageParse.applyAttack(attack, skill, chr, bulletCount, maxdamage, effect, AttackType.RANGED);
break;
default:
DamageParse.applyAttackMagic(attack, skill, c.getPlayer(), effect, maxdamage);
break;
}
}
}
}
public static final void DropMeso(int meso, MapleCharacter chr) {
if ((!chr.isAlive()) || (meso < 10) || (meso > 50000) || (meso > chr.getMeso())) {
chr.getClient().getSession().write(CWvsContext.enableActions());
return;
}
chr.gainMeso(-meso, false, true);
chr.getMap().spawnMesoDrop(meso, chr.getTruePosition(), chr, chr, true, (byte) 0);
}
public static final void ChangeAndroidEmotion(int emote, MapleCharacter chr) {
if ((emote > 0) && (chr != null) && (chr.getMap() != null) && (!chr.isHidden()) && (emote <= 17) && (chr.getAndroid() != null)) {
chr.getMap().broadcastMessage(CField.showAndroidEmotion(chr.getId(), emote));
}
}
public static void MoveAndroid(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
slea.skip(12);
List res = MovementParse.parseMovement(slea, 3);
if ((res != null) && (chr != null) && (!res.isEmpty()) && (chr.getMap() != null) && (chr.getAndroid() != null)) {
Point pos = new Point(chr.getAndroid().getPos());
chr.getAndroid().updatePosition(res);
chr.getMap().broadcastMessage(chr, CField.moveAndroid(chr.getId(), pos, res), false);
}
}
public static void MoveHaku(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
slea.skip(17);
List res = MovementParse.parseMovement(slea, 6);
if ((res != null) && (chr != null) && (!res.isEmpty()) && (chr.getMap() != null) && (chr.getHaku() != null)) {
Point pos = new Point(chr.getHaku().getPosition());
chr.getHaku().updatePosition(res);
chr.getMap().broadcastMessage(chr, CField.moveHaku(chr.getId(), chr.getHaku().getObjectId(), pos, res), false);
}
}
public static void ChangeHaku(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
int oid = slea.readInt();
if (chr.getHaku() != null) {
chr.getHaku().sendstats();
chr.getMap().broadcastMessage(chr, CField.spawnHaku_change0(chr.getId()), true);
chr.getMap().broadcastMessage(chr, CField.spawnHaku_change1(chr.getHaku()), true);
chr.getMap().broadcastMessage(chr, CField.spawnHaku_bianshen(chr.getId(), oid, chr.getHaku().getstats()), true);
}
}
public static final void ChangeEmotion(final int emote, MapleCharacter chr) {
if (emote > 7) {
int emoteid = 5159992 + emote;
MapleInventoryType type = GameConstants.getInventoryType(emoteid);
if (chr.getInventory(type).findById(emoteid) == null) {
return;
}
}
if ((emote > 0) && (chr != null) && (chr.getMap() != null) && (!chr.isHidden())) {
chr.getMap().broadcastMessage(chr, CField.facialExpression(chr, emote), false);
WeakReference<MapleCharacter>[] clones = chr.getClones();
for (int i = 0; i < clones.length; i++) {
if (clones[i].get() != null) {
final MapleCharacter clone = clones[i].get();
CloneTimer.getInstance().schedule(new Runnable() {
@Override
public void run() {
clone.getMap().broadcastMessage(CField.facialExpression(clone, emote));
}
}, 500 * i + 500);
}
}
}
}
public static final void Heal(LittleEndianAccessor slea, MapleCharacter chr) {
if (chr == null) {
return;
}
slea.readInt();
if (slea.available() >= 8L) {
slea.skip((slea.available() >= 12L) && (GameConstants.GMS) ? 8 : 4);
}
int healHP = slea.readShort();
int healMP = slea.readShort();
PlayerStats stats = chr.getStat();
if (stats.getHp() <= 0) {
return;
}
long now = System.currentTimeMillis();
if ((healHP != 0) && (chr.canHP(now + 1000L))) {
if (healHP > stats.getHealHP()) {
healHP = (int) stats.getHealHP();
}
chr.addHP(healHP);
}
if ((healMP != 0) && (!GameConstants.isDemon(chr.getJob())) && (chr.canMP(now + 1000L))) {
if (healMP > stats.getHealMP()) {
healMP = (int) stats.getHealMP();
}
chr.addMP(healMP);
}
}
public static final void MovePlayer(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
slea.skip(22);
if (chr == null) {
return;
}
final Point Original_Pos = chr.getPosition();
List res;
try {
res = MovementParse.parseMovement(slea, 1);
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println(new StringBuilder().append("AIOBE Type1:\n").append(slea.toString(true)).toString());
return;
}
if ((res != null) && (c.getPlayer().getMap() != null)) {
if (slea.available() != 18L) {
return;
}
final MapleMap map = c.getPlayer().getMap();
if (chr.isHidden()) {
chr.setLastRes(res);
c.getPlayer().getMap().broadcastGMMessage(chr, CField.movePlayer(chr.getId(), res, Original_Pos), false);
} else {
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), CField.movePlayer(chr.getId(), res, Original_Pos), false);
}
MovementParse.updatePosition(res, chr, 0);
final Point pos = chr.getTruePosition();
map.movePlayer(chr, pos);
if ((chr.getFollowId() > 0) && (chr.isFollowOn()) && (chr.isFollowInitiator())) {
MapleCharacter fol = map.getCharacterById(chr.getFollowId());
if (fol != null) {
Point original_pos = fol.getPosition();
fol.getClient().getSession().write(CField.moveFollow(Original_Pos, original_pos, pos, res));
MovementParse.updatePosition(res, fol, 0);
map.movePlayer(fol, pos);
map.broadcastMessage(fol, CField.movePlayer(fol.getId(), res, original_pos), false);
} else {
chr.checkFollow();
}
}
WeakReference<MapleCharacter>[] clones = chr.getClones();
for (int i = 0; i < clones.length; i++) {
if (clones[i].get() != null) {
final MapleCharacter clone = clones[i].get();
final List<LifeMovementFragment> res3 = res;
CloneTimer.getInstance().schedule(new Runnable() {
public void run() {
try {
if (clone.getMap() == map) {
if (clone.isHidden()) {
map.broadcastGMMessage(clone, CField.movePlayer(clone.getId(), res3, Original_Pos), false);
} else {
map.broadcastMessage(clone, CField.movePlayer(clone.getId(), res3, Original_Pos), false);
}
MovementParse.updatePosition(res3, clone, 0);
map.movePlayer(clone, pos);
}
} catch (Exception e) {
//very rarely swallowed
}
}
}, 50 * i + 150);
}
}
int count = c.getPlayer().getFallCounter();
boolean samepos = (pos.y > c.getPlayer().getOldPosition().y) && (Math.abs(pos.x - c.getPlayer().getOldPosition().x) < 5);
if ((samepos) && ((pos.y > map.getBottom() + 250) || (map.getFootholds().findBelow(pos) == null))) {
if (count > 5) {
c.getPlayer().changeMap(map, map.getPortal(0));
c.getPlayer().setFallCounter(0);
} else {
count++;
c.getPlayer().setFallCounter(count);
}
} else if (count > 0) {
c.getPlayer().setFallCounter(0);
}
c.getPlayer().setOldPosition(pos);
if ((!samepos) && (c.getPlayer().getBuffSource(MapleBuffStat.DARK_AURA) == 32120000)) {
c.getPlayer().getStatForBuff(MapleBuffStat.DARK_AURA).applyMonsterBuff(c.getPlayer());
} else if ((!samepos) && (c.getPlayer().getBuffSource(MapleBuffStat.YELLOW_AURA) == 32120001)) {
c.getPlayer().getStatForBuff(MapleBuffStat.YELLOW_AURA).applyMonsterBuff(c.getPlayer());
}
}
}
public static final void ChangeMapSpecial(String portal_name, MapleClient c, MapleCharacter chr) {
if ((chr == null) || (chr.getMap() == null)) {
return;
}
MaplePortal portal = chr.getMap().getPortal(portal_name);
if ((portal != null) && (!chr.hasBlockedInventory())) {
portal.enterPortal(c);
} else {
c.getSession().write(CWvsContext.enableActions());
}
}
public static final void ChangeMap(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
if ((chr == null) || (chr.getMap() == null)) {
return;
}
if (slea.available() != 0L) {
slea.readByte();
int targetid = slea.readInt();
if (GameConstants.GMS) {
slea.readInt();
}
MaplePortal portal = chr.getMap().getPortal(slea.readMapleAsciiString());
if (slea.available() >= 7L) {
slea.readInt();
}
slea.skip(1);
boolean wheel = (slea.readShort() > 0) && (!GameConstants.isEventMap(chr.getMapId())) && (chr.haveItem(5510000, 1, false, true)) && (chr.getMapId() / 1000000 != 925);
if ((targetid != -1) && (!chr.isAlive())) {
chr.setStance(0);
if ((chr.getEventInstance() != null) && (chr.getEventInstance().revivePlayer(chr)) && (chr.isAlive())) {
return;
}
if (chr.getPyramidSubway() != null) {
chr.getStat().setHp(50, chr);
chr.getPyramidSubway().fail(chr);
return;
}
if (!wheel) {
chr.getStat().setHp(50, chr);
MapleMap to = chr.getMap().getReturnMap();
chr.changeMap(to, to.getPortal(0));
} else {
c.getSession().write(CField.EffectPacket.useWheel((byte) (chr.getInventory(MapleInventoryType.CASH).countById(5510000) - 1)));
chr.getStat().setHp(chr.getStat().getMaxHp() / 100 * 40, chr);
MapleInventoryManipulator.removeById(c, MapleInventoryType.CASH, 5510000, 1, true, false);
MapleMap to = chr.getMap();
chr.changeMap(to, to.getPortal(0));
}
} else if ((targetid != -1) && (chr.isIntern())) {
MapleMap to = ChannelServer.getInstance(c.getChannel()).getMapFactory().getMap(targetid);
if (to != null) {
chr.changeMap(to, to.getPortal(0));
} else {
chr.dropMessage(5, "Map is NULL. Use !warp <mapid> instead.");
}
} else if ((targetid != -1) && (!chr.isIntern())) {
int divi = chr.getMapId() / 100;
boolean unlock = false;
boolean warp = false;
if (divi == 9130401) {
warp = (targetid / 100 == 9130400) || (targetid / 100 == 9130401);
if (targetid / 10000 != 91304) {
warp = true;
unlock = true;
targetid = 130030000;
}
} else if (divi == 9130400) {
warp = (targetid / 100 == 9130400) || (targetid / 100 == 9130401);
if (targetid / 10000 != 91304) {
warp = true;
unlock = true;
targetid = 130030000;
}
} else if (divi == 9140900) {
warp = (targetid == 914090011) || (targetid == 914090012) || (targetid == 914090013) || (targetid == 140090000);
} else if ((divi == 9120601) || (divi == 9140602) || (divi == 9140603) || (divi == 9140604) || (divi == 9140605)) {
warp = (targetid == 912060100) || (targetid == 912060200) || (targetid == 912060300) || (targetid == 912060400) || (targetid == 912060500) || (targetid == 3000100);
unlock = true;
} else if (divi == 9101500) {
warp = (targetid == 910150006) || (targetid == 101050010);
unlock = true;
} else if ((divi == 9140901) && (targetid == 140000000)) {
unlock = true;
warp = true;
} else if ((divi == 9240200) && (targetid == 924020000)) {
unlock = true;
warp = true;
} else if ((targetid == 980040000) && (divi >= 9800410) && (divi <= 9800450)) {
warp = true;
} else if ((divi == 9140902) && ((targetid == 140030000) || (targetid == 140000000))) {
unlock = true;
warp = true;
} else if ((divi == 9000900) && (targetid / 100 == 9000900) && (targetid > chr.getMapId())) {
warp = true;
} else if ((divi / 1000 == 9000) && (targetid / 100000 == 9000)) {
unlock = (targetid < 900090000) || (targetid > 900090004);
warp = true;
} else if ((divi / 10 == 1020) && (targetid == 1020000)) {
unlock = true;
warp = true;
} else if ((chr.getMapId() == 900090101) && (targetid == 100030100)) {
unlock = true;
warp = true;
} else if ((chr.getMapId() == 2010000) && (targetid == 104000000)) {
unlock = true;
warp = true;
} else if ((chr.getMapId() == 106020001) || (chr.getMapId() == 106020502)) {
if (targetid == chr.getMapId() - 1) {
unlock = true;
warp = true;
}
} else if ((chr.getMapId() == 0) && (targetid == 10000)) {
unlock = true;
warp = true;
} else if ((chr.getMapId() == 931000011) && (targetid == 931000012)) {
unlock = true;
warp = true;
} else if ((chr.getMapId() == 931000021) && (targetid == 931000030)) {
unlock = true;
warp = true;
}
if (unlock) {
c.getSession().write(CField.UIPacket.IntroDisableUI(false));
c.getSession().write(CField.UIPacket.IntroLock(false));
c.getSession().write(CWvsContext.enableActions());
}
if (warp) {
MapleMap to = ChannelServer.getInstance(c.getChannel()).getMapFactory().getMap(targetid);
chr.changeMap(to, to.getPortal(0));
}
} else if ((portal != null) && (!chr.hasBlockedInventory())) {
portal.enterPortal(c);
} else {
c.getSession().write(CWvsContext.enableActions());
}
}
}
public static final void InnerPortal(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
if ((chr == null) || (chr.getMap() == null)) {
return;
}
MaplePortal portal = chr.getMap().getPortal(slea.readMapleAsciiString());
int toX = slea.readShort();
int toY = slea.readShort();
if (portal == null) {
return;
}
if ((portal.getPosition().distanceSq(chr.getTruePosition()) > 22500.0D) && (!chr.isGM())) {
return;
}
chr.getMap().movePlayer(chr, new Point(toX, toY));
chr.checkFollow();
}
public static void ReIssueMedal(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
try {
final MapleQuest q = MapleQuest.getInstance(slea.readShort());
final int itemid = q.getMedalItem();
if (itemid != slea.readInt() || itemid <= 0 || q == null || chr.getQuestStatus(q.getId()) != 2) {
c.getSession().write(CField.UIPacket.reissueMedal(itemid, 4));
return;
}
if (chr.haveItem(itemid, 1, true, true)) {
c.getSession().write(CField.UIPacket.reissueMedal(itemid, 3));
return;
}
if (!MapleInventoryManipulator.checkSpace(c, itemid, (short) 1, "")) {
c.getSession().write(CField.UIPacket.reissueMedal(itemid, 2));
return;
}
if (chr.getMeso() < 100) {
c.getSession().write(CField.UIPacket.reissueMedal(itemid, 1));
return;
}
chr.gainMeso(-100, true, true);
MapleInventoryManipulator.addById(c, itemid, (short) 1, "Redeemed item through medal quest " + q.getId() + " on " + FileoutputUtil.CurrentReadable_Date());
c.getSession().write(CField.UIPacket.reissueMedal(itemid, 0));
} catch (ArrayIndexOutOfBoundsException ee) {
}
}
}