package handling.channel.handler;
import client.*;
import client.anticheat.CheatingOffense;
import client.inventory.Item;
import client.inventory.MapleInventory;
import client.inventory.MapleInventoryType;
import constants.GameConstants;
import handling.channel.ChannelServer;
import handling.world.World;
import java.awt.Point;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import server.*;
import server.Timer.CloneTimer;
import server.events.MapleEvent;
import server.events.MapleEventType;
import server.events.MapleSnowball;
import server.life.MapleLifeFactory;
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.AttackPair;
import tools.FileoutputUtil;
import tools.Pair;
import tools.data.LittleEndianAccessor;
import tools.packet.CField;
import tools.packet.CSPacket;
import tools.packet.CWvsContext;
import tools.packet.JobPacket;
import tools.packet.JobPacket.AngelicPacket;
import tools.packet.MobPacket;
public class PlayerHandler {
public static int isFinisher(int skillid) {
switch (skillid) {
case 1111003:
return 1;
case 1111005:
return 2;
case 11111002:
return 1;
case 11111003:
return 2;
}
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 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();
if ((type == 1) && (action >= 1000)) {
Skill skil = SkillFactory.getSkill(action);
if ((skil != null) && (((!skil.isFourthJob()) && (!skil.isBeginnerSkill()) && (skil.isInvisible()) && (chr.getSkillLevel(skil) <= 0)) || (GameConstants.isLinkedAttackSkill(action)) || (action % 10000 < 1000))) {
continue;
}
}
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(GameConstants.HP_ITEM));
} else {
chr.getQuestNAdd(MapleQuest.getInstance(GameConstants.HP_ITEM)).setCustomData(String.valueOf(data));
}
break;
case 2:
if (data <= 0) {
chr.getQuestRemove(MapleQuest.getInstance(GameConstants.MP_ITEM));
} else {
chr.getQuestNAdd(MapleQuest.getInstance(GameConstants.MP_ITEM)).setCustomData(String.valueOf(data));
}
break;
}
}
}
public static void ChangePetBuff(LittleEndianAccessor slea, MapleCharacter chr) {
slea.readInt(); //0
int skill = slea.readInt();
slea.readByte(); //0
if (skill <= 0) {
chr.getQuestRemove(MapleQuest.getInstance(GameConstants.BUFF_ITEM));
} else {
chr.getQuestNAdd(MapleQuest.getInstance(GameConstants.BUFF_ITEM)).setCustomData(String.valueOf(skill));
}
}
public static 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 void AngelicChange(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
if ((chr == null) || (chr.getMap() == null)) {
return;
}
int transform = slea.readInt();
// System.out.println("transform id " + transform);
if (transform == 5010094) {
// System.out.println("acvivate");
chr.getMap().broadcastMessage(chr, CField.showAngelicBuster(chr.getId(), transform), false);
chr.getMap().broadcastMessage(chr, CField.updateCharLook(chr, transform == 5010094), false);
c.getSession().write(CWvsContext.enableActions());
// System.out.println("acvivate done");
} else {
// System.out.println("deacvivate");
// chr.getMap().broadcastMessage(chr, CField.showAngelicBuster(chr.getId(), transform), false);
// chr.getMap().broadcastMessage(chr, CField.updateCharLook(chr, transform == 5010093), false);
// c.getSession().write(CWvsContext.enableActions());
}
}
public static void DressUpTime(LittleEndianAccessor slea, final MapleClient c) {
byte type = slea.readByte();
// System.out.println("abtype " + type);
if (type == 1) {
// PlayerHandler.AngelicChange(slea, c, chr);
if (GameConstants.isAngelicBuster(c.getPlayer().getJob())) {
c.getSession().write(JobPacket.AngelicPacket.DressUpTime(type));
c.getSession().write(JobPacket.AngelicPacket.updateDress(5010094, c.getPlayer()));
// }
} else {
c.getSession().write(CWvsContext.enableActions());
// return;
}
}
}
// if (type != 1) {// || !GameConstants.isAngelicBuster(c.getPlayer().getJob())
// c.getSession().write(CWvsContext.enableActions());
// return;
// }
// c.getSession().write(JobPacket.AngelicPacket.DressUpTime(type));
// }
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.isDemonAvenger(c.getPlayer().getJob()) || c.getPlayer().getJob() == 212 ? 0 : slea.readInt();
unk = slea.readByte();
sn = slea.readInt();
if (GameConstants.isDemonSlayer(c.getPlayer().getJob())) {
// c.getPlayer().addMP(c.getPlayer().getStat().getForce(room));
}
if (GameConstants.isAngelicBuster(c.getPlayer().getJob())) {
boolean rand = Randomizer.isSuccess(80);
if (sn > 0) {
if (rand) {
c.getSession().write(JobPacket.AngelicPacket.SoulSeekerRegen(c.getPlayer(), sn));
}
}
}
if ((GameConstants.isDemonAvenger(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 UseChair(final int itemId, final MapleClient c, final MapleCharacter chr) {
if (chr == null || chr.getMap() == null) {
return;
}
final Item toUse = chr.getInventory(MapleInventoryType.SETUP).findById(itemId);
if (toUse == null) {
chr.getCheatTracker().registerOffense(CheatingOffense.USING_UNAVAILABLE_ITEM, Integer.toString(itemId));
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 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 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 || vip == 5) {
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(CSPacket.OnMapTransferResult(chr, vip, addrem == 0));
}
public static void CharInfoRequest(int objectid, MapleClient c, MapleCharacter chr) {
if (c.getPlayer() == null || c.getPlayer().getMap() == null) {
return;
}
MapleCharacter player = c.getPlayer().getMap().getCharacterById(objectid);
c.getSession().write(CWvsContext.enableActions());
if (player != null/* && (!player.isGM() || c.getPlayer().isGM())*/) {
c.getSession().write(CWvsContext.charInfo(player, c.getPlayer().getId() == objectid));
}
}
public static void AdminCommand(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
if (!c.getPlayer().isGM()) {
return;
}
byte mode = slea.readByte();
String victim;
MapleCharacter target;
switch (mode) {
case 0x00: // Level1~Level8 & Package1~Package2
int[][] toSpawn = MapleItemInformationProvider.getInstance().getSummonMobs(slea.readInt());
for (int[] toSpawnChild : toSpawn) {
if (Randomizer.nextInt(101) <= toSpawnChild[1]) {
c.getPlayer().getMap().spawnMonsterOnGroudBelow(MapleLifeFactory.getMonster(toSpawnChild[0]), c.getPlayer().getPosition());
}
}
c.getSession().write(CWvsContext.enableActions());
break;
case 0x01: { // /d (inv)
byte type = slea.readByte();
MapleInventory in = c.getPlayer().getInventory(MapleInventoryType.getByType(type));
for (byte i = 0; i < in.getSlotLimit(); i++) {
if (in.getItem(i) != null) {
MapleInventoryManipulator.removeFromSlot(c, MapleInventoryType.getByType(type), i, in.getItem(i).getQuantity(), false);
}
return;
}
break;
}
case 0x02: // Exp
c.getPlayer().setExp(slea.readInt());
break;
case 0x03: // /ban <name>
victim = slea.readMapleAsciiString();
String reason = victim + " permanent banned by " + c.getPlayer().getName();
target = c.getChannelServer().getPlayerStorage().getCharacterByName(victim);
if (target != null) {
String readableTargetName = MapleCharacter.makeMapleReadable(target.getName());
String ip = target.getClient().getSession().getRemoteAddress().toString().split(":")[0];
reason += readableTargetName + " (IP: " + ip + ")";
target.ban(reason, false, false);
target.sendPolice("You have been blocked by #bMapleGM #kfor the HACK reason.");
c.getSession().write(CField.getGMEffect(4, (byte) 0));
} else if (MapleCharacter.ban(victim, reason, false)) {
c.getSession().write(CField.getGMEffect(4, (byte) 0));
} else {
c.getSession().write(CField.getGMEffect(6, (byte) 1));
}
break;
case 0x04: // /block <name> <duration (in days)> <HACK/BOT/AD/HARASS/CURSE/SCAM/MISCONDUCT/SELL/ICASH/TEMP/GM/IPROGRAM/MEGAPHONE>
victim = slea.readMapleAsciiString();
int type = slea.readByte(); //reason
int duration = slea.readInt();
String description = slea.readMapleAsciiString();
reason = c.getPlayer().getName() + " used /ban to ban";
target = c.getChannelServer().getPlayerStorage().getCharacterByName(victim);
if (target != null) {
String readableTargetName = MapleCharacter.makeMapleReadable(target.getName());
String ip = target.getClient().getSession().getRemoteAddress().toString().split(":")[0];
reason += readableTargetName + " (IP: " + ip + ")";
if (duration == -1) {
target.ban(description + " " + reason, true);
} else {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, duration);
target.tempban(description, cal, type, false);
target.sendPolice(duration, reason, 6000);
}
c.getSession().write(CField.getGMEffect(4, (byte) 0));
} else if (MapleCharacter.ban(victim, reason, false)) {
c.getSession().write(CField.getGMEffect(4, (byte) 0));
} else {
c.getSession().write(CField.getGMEffect(6, (byte) 1));
}
break;
case 0x10: // /h, information by vana (and tele mode f1) ... hide ofcourse
if (slea.readByte() > 0) {
SkillFactory.getSkill(9101004).getEffect(1).applyTo(c.getPlayer());
} else {
c.getPlayer().dispelBuff(9101004);
}
break;
case 0x11: // Entering a map
switch (slea.readByte()) {
case 0:// /u
StringBuilder sb = new StringBuilder("USERS ON THIS MAP: ");
for (MapleCharacter mc : c.getPlayer().getMap().getCharacters()) {
sb.append(mc.getName());
sb.append(" ");
}
c.getPlayer().dropMessage(5, sb.toString());
break;
case 12:// /uclip and entering a map
break;
}
break;
case 0x12: // Send
victim = slea.readMapleAsciiString();
int mapId = slea.readInt();
c.getChannelServer().getPlayerStorage().getCharacterByName(victim).changeMap(c.getChannelServer().getMapFactory().getMap(mapId));
break;
case 0x15: // Kill
int mobToKill = slea.readInt();
int amount = slea.readInt();
List<MapleMapObject> monsterx = c.getPlayer().getMap().getMapObjectsInRange(c.getPlayer().getPosition(), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.MONSTER));
for (int x = 0; x < amount; x++) {
MapleMonster monster = (MapleMonster) monsterx.get(x);
if (monster.getId() == mobToKill) {
c.getPlayer().getMap().killMonster(monster, c.getPlayer(), false, false, (byte) 1);
}
}
break;
case 0x16: // Questreset
MapleQuest.getInstance(slea.readShort()).forfeit(c.getPlayer());
break;
case 0x17: // Summon
int mobId = slea.readInt();
int quantity = slea.readInt();
for (int i = 0; i < quantity; i++) {
c.getPlayer().getMap().spawnMonsterOnGroudBelow(MapleLifeFactory.getMonster(mobId), c.getPlayer().getPosition());
}
break;
case 0x18: // Maple & Mobhp
int mobHp = slea.readInt();
c.getPlayer().dropMessage(5, "Monsters HP");
List<MapleMapObject> monsters = c.getPlayer().getMap().getMapObjectsInRange(c.getPlayer().getPosition(), Double.POSITIVE_INFINITY, Arrays.asList(MapleMapObjectType.MONSTER));
for (MapleMapObject mobs : monsters) {
MapleMonster monster = (MapleMonster) mobs;
if (monster.getId() == mobHp) {
c.getPlayer().dropMessage(5, monster.getName() + ": " + monster.getHp());
}
}
break;
case 0x1E: // Warn
victim = slea.readMapleAsciiString();
String message = slea.readMapleAsciiString();
target = c.getChannelServer().getPlayerStorage().getCharacterByName(victim);
if (target != null) {
target.getClient().getSession().write(CWvsContext.broadcastMsg(1, message));
c.getSession().write(CField.getGMEffect(0x1E, (byte) 1));
} else {
c.getSession().write(CField.getGMEffect(0x1E, (byte) 0));
}
break;
case 0x24:// /Artifact Ranking
break;
case 0x77: //Testing purpose
if (slea.available() == 4) {
System.out.println(slea.readInt());
} else if (slea.available() == 2) {
System.out.println(slea.readShort());
}
break;
default:
System.out.println("New GM packet encountered (MODE : " + mode + ": " + slea.toString());
break;
}
}
public static void TakeDamage(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
slea.skip(4);
chr.updateTick(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 (GameConstants.isXenon(chr.getJob())) {
if (chr.getSkillLevel(36110004) > 0) {
chr.getMap().broadcastMessage(JobPacket.XenonPacket.EazisSystem(chr.getId(), oid));
}
}
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 (attacker.getId() == 9300166 && chr.getMapId() == 910025200) {
int rocksLost = Randomizer.rand(1, 5);
while (chr.itemQuantity(4031469) < rocksLost) {
rocksLost--;
}
if (rocksLost > 0) {
chr.gainItem(4031469, -rocksLost);
Item toDrop = MapleItemInformationProvider.getInstance().getEquipById(4031469);
for (int i = 0; i < rocksLost; i++) {
chr.getMap().spawnItemDrop(c.getPlayer(), c.getPlayer(), toDrop, c.getPlayer().getPosition(), true, true);
}
}
}
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 (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((byte) -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) {
return;
}
} 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;
}
}
chr.getCheatTracker().checkTakeDamage(damage);
Pair modify = chr.modifyDamageTaken(damage, attacker);
damage = ((Double) modify.left).intValue();
if (damage > 0) {
chr.getCheatTracker().setAttacksWithoutHit(false);
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;
int 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 {
mploss = (int) (damage * (chr.getBuffedValue(MapleBuffStat.MAGIC_GUARD).doubleValue() / 100.0D)) + mpattack;
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);
}
} 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 ((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);
}
public static 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.updateCombo(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) {
break;
}
SkillFactory.getSkill(21000000).getEffect(combo / 10).applyComboBuff(chr, combo);
break;
}
}
}
public static 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 void CancelItemEffect(int id, MapleCharacter chr) {
chr.cancelEffect(MapleItemInformationProvider.getInstance().getItemEffect(-id), false, -1L);
}
public static 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 13101024:
// chr.getMap().broadcastMessage(chr, CField.skillCancel(chr, sourceid), false);
// break;
// case 13111023:
// case 13120008:
// chr.cancelAllBuffs();
// chr.cancelBuffStats(new MapleBuffStat[]{MapleBuffStat.ALBATROSS});
// chr.cancelBuffStats(new MapleBuffStat[]{MapleBuffStat.INDIE_PAD});
// chr.cancelBuffStats(new MapleBuffStat[]{MapleBuffStat.HP_BOOST});
// chr.cancelBuffStats(new MapleBuffStat[]{MapleBuffStat.ATTACK_SPEED});
// chr.cancelBuffStats(new MapleBuffStat[]{MapleBuffStat.CRITICAL_PERCENT_UP});
// chr.getMap().broadcastMessage(chr, CField.skillCancel(chr, sourceid), false);
// break;
case 4341052:
chr.getStat().setHp(0, chr);
chr.updateSingleStat(MapleStat.HP, 0);
chr.getClient().getSession().write(CWvsContext.enableActions());
break;
}
if (skill.isChargeSkill()) {
chr.setKeyDownSkill_Time(0L);
chr.getMap().broadcastMessage(chr, CField.skillCancel(chr, sourceid), false);
} else {
chr.cancelEffect(skill.getEffect(1), false, -1L);
}
}
public static 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 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 void SkillEffect(LittleEndianAccessor slea, MapleCharacter chr) {
int skillId = slea.readInt();
if (skillId >= 91000000 && skillId < 100000000) {
chr.getClient().getSession().write(CWvsContext.enableActions());
return;
}
byte level = slea.readByte();
short direction = slea.readShort();
byte unk = slea.readByte();
Skill skill = SkillFactory.getSkill(GameConstants.getLinkedAttackSkill(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;
}
}
if (GameConstants.isEventMap(chr.getMapId())) {
for (MapleEventType t : MapleEventType.values()) {
MapleEvent e = ChannelServer.getInstance(chr.getClient().getChannel()).getEvent(t);
if ((e.isRunning()) && (!chr.isGM())) {
for (int i : e.getType().mapids) {
if (chr.getMapId() == i) {
chr.dropMessage(5, "You may not use that here.");
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 5201008: { //infinite blast Handler
int itemid = slea.readInt();
MapleStatEffect effectp = SkillFactory.getSkill(skillid).getEffect(chr.getSkillLevel(skillid));
MapleInventoryManipulator.removeById(c, GameConstants.getInventoryType(itemid), itemid, effectp.getBulletConsume(), true, false);
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 31221001:
//case 36100010:
//case 36110012:
//case 36120015:
case 36001005:
case 2121052: {
List<Integer> moblist = new ArrayList<Integer>();
byte count = slea.readByte();
for (byte i = 1; i <= count; i++) {
moblist.add(slea.readInt());
}
if (skillid == 31221001) {
c.getSession().write(JobPacket.XenonPacket.ShieldChacing(chr.getId(), moblist, 31221014));
} else if (skillid == 36001005) {
c.getSession().write(JobPacket.XenonPacket.PinPointRocket(chr.getId(), moblist));
} else if (skillid == 2121052) {
c.getSession().write(JobPacket.XenonPacket.MegidoFlameRe(chr.getId(), moblist.get(0)));
}
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);
// chr.HandleOtherluminous();
c.getSession().write(CWvsContext.enableActions());
break;
case 27121100:
World.Broadcast.broadcastMessage(CField.getGameMessage("PlayerHandler.", (short) 8));
c.getSession().write(JobPacket.LuminousPacket.giveLuminousState(20040216, chr.getLightGauge(), chr.getDarkGauge(), 2000000000));
// chr.HandleOtherluminous();
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 36121054:
// chr.setXenonSurplus((short) 20);
c.getSession().write(CWvsContext.enableActions());
c.getSession().write(JobPacket.XenonPacket.giveAmaranthGenerator());
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.isAngelicBuster(chr.getJob())) {
int Recharge = effect.getOnActive();
if (Recharge > -1) {
if (Randomizer.isSuccess(Recharge)) {
c.getSession().write(AngelicPacket.unlockSkill());
c.getSession().write(AngelicPacket.showRechargeEffect());
if (c.getPlayer().isGM()) {
c.getSession().write(AngelicPacket.unlockSkill());
// c.getSession().write(AngelicPacket.showRechargeEffect());
} else {
c.getSession().write(AngelicPacket.lockSkill(skillid));
}
}
c.getSession().write(CWvsContext.enableActions());
} else {
if (c.getPlayer().isGM()) {
c.getSession().write(AngelicPacket.unlockSkill());
// c.getSession().write(AngelicPacket.showRechargeEffect());
} else {
c.getSession().write(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.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.ASURA) == null) && (chr.getBuffedValue(MapleBuffStat.TELEPORT_MASTERY) == null))) {
return;
}
if ((chr.hasBlockedInventory()) || (chr.getMap() == null)) {
return;
}
// System.out.println(slea.toString());
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((byte) -10);
int attackCount = (shield != null) && (shield.getItemId() / 10000 == 134) ? 2 : 1;
int skillLevel = 0;
MapleStatEffect effect = null;
Skill skill = null;
String dmg = "";
for (AttackPair ae : attack.allDamage) {
for (Pair att : ae.attack) {
dmg += att.getLeft();
dmg += ",";
}
}
if (!dmg.isEmpty()) {
// chr.dropMessage(-1, "Damage: " + dmg);//debug mode
}
if (attack.skill != 0) {
//chr.dropMessage(-1, "Attack Skill: " + attack.skill);//debug mode
skill = SkillFactory.getSkill(GameConstants.getLinkedAttackSkill(attack.skill));
if ((skill == null) || ((GameConstants.isAngel(attack.skill)) && (chr.getStat().equippedSummon % 10000 != attack.skill % 10000))) {
c.getSession().write(CWvsContext.enableActions());
return;
}
if (GameConstants.isDemonAvenger(chr.getJob())) {
int exceedMax = chr.getSkillLevel(31220044) > 0 ? 18 : 20;
// chr.showInfo("Info", false, "exceedMax;" + exceedMax);
if (chr.getExceed() + 1 > exceedMax) {
chr.setExceed((short) exceedMax);
} else {
chr.gainExceed((short) 1);
}
}
if (GameConstants.isExceedAttack(skill.getId())) {
chr.handleExceedAttack(skill.getId());
}
switch (attack.skill) {
case 101001100:
case 101101100:
case 101111100:
case 101121100:
chr.zeroChange(false);
break;
case 101001200:
case 101101200:
case 101111200:
case 101121200:
chr.zeroChange(true);
break;
}
skillLevel = chr.getTotalSkillLevel(skill);
effect = attack.getAttackEffect(chr, skillLevel, skill);
if (effect == null) {
return;
}
if (GameConstants.isEventMap(chr.getMapId())) {
for (MapleEventType t : MapleEventType.values()) {
MapleEvent e = ChannelServer.getInstance(chr.getClient().getChannel()).getEvent(t);
if ((e.isRunning()) && (!chr.isGM())) {
for (int i : e.getType().mapids) {
if (chr.getMapId() == i) {
chr.dropMessage(5, "You may not use that here.");
return;
}
}
}
}
}
if (GameConstants.isAngelicBuster(chr.getJob())) {
int Recharge = effect.getOnActive();
if (Recharge > -1) {
if (Randomizer.isSuccess(Recharge)) {
c.getSession().write(AngelicPacket.unlockSkill());
c.getSession().write(AngelicPacket.showRechargeEffect());
} else {
if (c.getPlayer().isGM()) {
c.getSession().write(AngelicPacket.unlockSkill());
// c.getSession().write(AngelicPacket.showRechargeEffect());
} else {
c.getSession().write(AngelicPacket.lockSkill(attack.skill));
}
}
} else {
if (c.getPlayer().isGM()) {
c.getSession().write(AngelicPacket.unlockSkill());
// c.getSession().write(AngelicPacket.showRechargeEffect());
} else {
c.getSession().write(AngelicPacket.lockSkill(attack.skill));
}
}
}
maxdamage *= (effect.getDamage() + chr.getStat().getDamageIncrease(attack.skill)) / 100.0D;
attackCount = effect.getAttackCount();
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) {
if (((chr.getMapId() == 109060000) || (chr.getMapId() == 109060002) || (chr.getMapId() == 109060004)) && (attack.skill == 0)) {
MapleSnowball.MapleSnowballs.hitSnowball(chr);
}
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));
}
}
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.unk, 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.unk, attack.charge), false);
}
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();
final Skill skil2 = skill;
final int skillLevel2 = skillLevel;
final int attackCount2 = attackCount;
final double maxdamage2 = maxdamage;
final MapleStatEffect eff2 = effect;
final AttackInfo attack2 = DamageParse.DivideAttack(attack, chr.isGM() ? 1 : 4);
Timer.CloneTimer.getInstance().schedule(new Runnable() {
@Override
public void run() {
if (!clone.isHidden()) {
clone.getMap().broadcastMessage(CField.closeRangeAttack(clone.getId(), attack2.tbyte, attack2.skill, skillLevel2, attack2.display, attack2.speed, attack2.allDamage, energy, clone.getLevel(), clone.getStat().passive_mastery(), attack2.unk, attack2.charge));
} else {
clone.getMap().broadcastGMMessage(clone, CField.closeRangeAttack(clone.getId(), attack2.tbyte, attack2.skill, skillLevel2, attack2.display, attack2.speed, attack2.allDamage, energy, clone.getLevel(), clone.getStat().passive_mastery(), attack2.unk, attack2.charge), false);
}
DamageParse.applyAttack(attack2, skil2, chr, attackCount2, maxdamage2, eff2, mirror ? AttackType.NON_RANGED_WITH_MIRROR : AttackType.NON_RANGED);
}
}, 500 * i + 500);
}
}
int bulletCount = 1;
switch (attack.skill) {
case 1201011:
bulletCount = effect.getAttackCount();
DamageParse.applyAttack(attack, skill, chr, skillLevel, maxdamage, effect, AttackType.NON_RANGED);//applyAttack(attack, skill, chr, bulletCount, effect, AttackType.RANGED);
break;
default:
DamageParse.applyAttackMagic(attack, skill, chr, effect, maxdamage);//applyAttackMagic(attack, skill, c.getPlayer(), effect);
break;
}
}
public static void rangedAttack(LittleEndianAccessor slea, MapleClient c, final MapleCharacter chr) {
if (chr == null) {
return;
}
if ((chr.hasBlockedInventory()) || (chr.getMap() == null)) {
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() >= 300 && chr.getJob() <= 322) || (chr.getJob() >= 3500 && chr.getJob() <= 3512) || GameConstants.isCannon(chr.getJob()) || GameConstants.isXenon(chr.getJob()) || GameConstants.isJett(chr.getJob()) || GameConstants.isPhantom(chr.getJob()) || GameConstants.isMercedes(chr.getJob()) || GameConstants.isZero(chr.getJob());
if (attack.skill != 0) {
skill = SkillFactory.getSkill(GameConstants.getLinkedAttackSkill(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;
}
if (GameConstants.isEventMap(chr.getMapId())) {
for (MapleEventType t : MapleEventType.values()) {
MapleEvent e = ChannelServer.getInstance(chr.getClient().getChannel()).getEvent(t);
if ((e.isRunning()) && (!chr.isGM())) {
for (int i : e.getType().mapids) {
if (chr.getMapId() == i) {
chr.dropMessage(5, "You may not use that here.");
return;
}
}
}
}
}
if (GameConstants.isAngelicBuster(chr.getJob())) {
int Recharge = effect.getOnActive();
if (Recharge > -1) {
if (Randomizer.isSuccess(Recharge)) {
c.getSession().write(AngelicPacket.unlockSkill());
c.getSession().write(AngelicPacket.showRechargeEffect());
} else {
if (c.getPlayer().isGM()) {
c.getSession().write(AngelicPacket.unlockSkill());
// c.getSession().write(AngelicPacket.showRechargeEffect());
} else {
c.getSession().write(AngelicPacket.lockSkill(attack.skill));
}
}
} else {
if (c.getPlayer().isGM()) {
c.getSession().write(AngelicPacket.unlockSkill());
// c.getSession().write(AngelicPacket.showRechargeEffect());
} else {
c.getSession().write(AngelicPacket.lockSkill(attack.skill));
}
}
} if (GameConstants.isWindArcher(chr.getJob())) {
int percent = 0, count = 0, skillid = 0, type = 0;
if (c.getPlayer().getSkillLevel(SkillFactory.getSkill(13120003)) > 0) {
if (Randomizer.nextInt(100) < 85) {
skillid = 13120003;
type = 1;
} else {
skillid = 13120010;
type = 1;
}
count = Randomizer.rand(1, 5);
percent = 20;
} else if (c.getPlayer().getSkillLevel(SkillFactory.getSkill(13110022)) > 0) {
if (Randomizer.nextInt(100) < 90) {
skillid = 13110022;
type = 1;
} else {
skillid = 13110027;
type = 1;
}
count = Randomizer.rand(1, 4);
percent = 10;
} else if (c.getPlayer().getSkillLevel(SkillFactory.getSkill(13100022)) > 0) {
if (Randomizer.nextInt(100) < 95) {
skillid = 13100022;
type = 1;
} else {
skillid = 13100027;
type = 1;
}
count = Randomizer.rand(1, 3);
percent = 5;
}
for (AttackPair at : attack.allDamage) {
MapleMonster mob = chr.getMap().getMonsterByOid(at.objectid);
if (Randomizer.nextInt(100) < percent) {
if (mob != null) {
c.getPlayer().getMap().broadcastMessage(c.getPlayer(), JobPacket.WindArcherPacket.TrifleWind(c.getPlayer().getId(), skillid, count, mob.getObjectId(), type), false);
c.getSession().write(JobPacket.WindArcherPacket.TrifleWind(c.getPlayer().getId(), skillid, count, mob.getObjectId(), type));
}
}
}
}
switch (attack.skill) {
case 13101005:
case 21110004: // Ranged but uses attackcount instead
case 14101006: // Vampure
case 21120006:
case 11101004:
// MIHILE
case 51001004: //Soul Blade
case 51111007:
case 51121008:
// END MIHILE
case 1077:
case 1078:
case 1079:
case 11077:
case 11078:
case 11079:
case 15111007:
case 13111007: //Wind Shot
case 33101007:
case 13101020://Fary Spiral
case 33101002:
case 33121002:
case 33121001:
case 21100004:
case 21110011:
case 21100007:
case 21000004:
case 5121002:
case 5921002:
case 4121003:
case 4221003:
case 5221017:
case 5721007:
case 5221016:
case 5721006:
case 5211008:
case 5201001:
case 5721003:
case 5711000:
case 4111013:
case 5121016:
case 5121013:
case 5221013:
case 5721004:
case 5721001:
case 5321001:
case 14111008:
case 60011216://Soul Buster
case 65001100://Star Bubble
// case 2321054:
AOE = true;
bulletCount = effect.getAttackCount();
break;
case 35121005:
case 35111004:
case 35121013:
AOE = true;
bulletCount = 6;
break;
default:
bulletCount = effect.getBulletCount();
break;
}
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 != 0) {
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.unk, 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.unk), 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.unk, 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.unk), 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();
final Skill skil2 = skill;
final MapleStatEffect eff2 = effect;
final double basedamage2 = basedamage;
final int bulletCount2 = bulletCount;
final int visProjectile2 = visProjectile;
final int skillLevel2 = skillLevel;
final AttackInfo attack2 = DamageParse.DivideAttack(attack, chr.isGM() ? 1 : 4);
Timer.CloneTimer.getInstance().schedule(new Runnable() {
@Override
public void run() {
if (!clone.isHidden()) {
if (attack2.skill == 3211006) {
clone.getMap().broadcastMessage(CField.strafeAttack(clone.getId(), attack2.tbyte, attack2.skill, skillLevel2, attack2.display, attack2.speed, visProjectile2, attack2.allDamage, attack2.position, clone.getLevel(), clone.getStat().passive_mastery(), attack2.unk, chr.getTotalSkillLevel(3220010)));
} else {
clone.getMap().broadcastMessage(CField.rangedAttack(clone.getId(), attack2.tbyte, attack2.skill, skillLevel2, attack2.display, attack2.speed, visProjectile2, attack2.allDamage, attack2.position, clone.getLevel(), clone.getStat().passive_mastery(), attack2.unk));
}
} else {
if (attack2.skill == 3211006) {
clone.getMap().broadcastGMMessage(clone, CField.strafeAttack(clone.getId(), attack2.tbyte, attack2.skill, skillLevel2, attack2.display, attack2.speed, visProjectile2, attack2.allDamage, attack2.position, clone.getLevel(), clone.getStat().passive_mastery(), attack2.unk, chr.getTotalSkillLevel(3220010)), false);
} else {
clone.getMap().broadcastGMMessage(clone, CField.rangedAttack(clone.getId(), attack2.tbyte, attack2.skill, skillLevel2, attack2.display, attack2.speed, visProjectile2, attack2.allDamage, attack2.position, clone.getLevel(), clone.getStat().passive_mastery(), attack2.unk), false);
}
}
DamageParse.applyAttack(attack2, skil2, chr, bulletCount2, basedamage2, eff2, AttackType.RANGED);
}
}, 500 * i + 500);
}
}
}
public static void MagicDamage(LittleEndianAccessor slea, MapleClient c, final MapleCharacter chr) {
if ((chr == null) || (chr.hasBlockedInventory()) || (chr.getMap() == null)) {
return;
}
AttackInfo attack = DamageParse.parseDmgMa(slea, chr);
if (attack == null) {
c.getSession().write(CWvsContext.enableActions());
return;
}
Skill skill = SkillFactory.getSkill(GameConstants.getLinkedAttackSkill(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) {
return;
}
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(), 10000));
SkillFactory.getSkill(GameConstants.getLuminousSkillMode(skill.getId())).getEffect(1).applyTo(chr);
}
attack = DamageParse.Modify_AttackCrit(attack, chr, 3, effect);
if (GameConstants.isEventMap(chr.getMapId())) {
for (MapleEventType t : MapleEventType.values()) {
MapleEvent e = ChannelServer.getInstance(chr.getClient().getChannel()).getEvent(t);
if ((e.isRunning()) && (!chr.isGM())) {
for (int i : e.getType().mapids) {
if (chr.getMapId() == i) {
chr.dropMessage(5, "You may not use that here.");
return;
}
}
}
}
}
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.unk), 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.unk), false);
}
DamageParse.applyAttackMagic(attack, skill, c.getPlayer(), effect, maxdamage);
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 Skill skil2 = skill;
final MapleStatEffect eff2 = effect;
final double maxd = maxdamage;
final int skillLevel2 = skillLevel;
final AttackInfo attack2 = DamageParse.DivideAttack(attack, chr.isGM() ? 1 : 4);
Timer.CloneTimer.getInstance().schedule(new Runnable() {
@Override
public void run() {
if (!clone.isHidden()) {
clone.getMap().broadcastMessage(CField.magicAttack(clone.getId(), attack2.tbyte, attack2.skill, skillLevel2, attack2.display, attack2.speed, attack2.allDamage, attack2.charge, clone.getLevel(), attack2.unk));
} else {
clone.getMap().broadcastGMMessage(clone, CField.magicAttack(clone.getId(), attack2.tbyte, attack2.skill, skillLevel2, attack2.display, attack2.speed, attack2.allDamage, attack2.charge, clone.getLevel(), attack2.unk), false);
}
DamageParse.applyAttackMagic(attack2, skil2, chr, eff2, maxd);
}
}, 500 * i + 500);
}
}
int bulletCount = 1;
switch (attack.skill) {
case 27101100: // Sylvan Lance
case 27101202: // Pressure Void
case 27111100: // Spectral Light
case 27111202: // Moonlight Spear
case 27121100: // Reflection
case 27001100:
case 27121202: // Apocalypse
case 2121006: // Paralyze
case 2221003: //
case 2221006: // Chain Lightning
case 2221007: // Blizzard
case 2221012: // Frozen Orb
case 2111003: // Poison Mist
case 2121003: // Myst Eruption
case 22181002: // Dark Fog
case 2321054:
case 27121303:
case 27111303:
case 36121013:
// case 36101009:
// case 36111010:
bulletCount = effect.getAttackCount();
DamageParse.applyAttack(attack, skill, chr, skillLevel, maxdamage, effect, AttackType.RANGED);//applyAttack(attack, skill, chr, bulletCount, effect, AttackType.RANGED);
break;
default:
DamageParse.applyAttackMagic(attack, skill, chr, effect, maxdamage);//applyAttackMagic(attack, skill, c.getPlayer(), effect);
break;
}
}
public static 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);
chr.getCheatTracker().checkDrop(true);
}
public static void ChangeAndroidEmotion(int emote, MapleCharacter chr) {//MIXTAMAL6
if ((emote > 0) && (chr != null) && (chr.getMap() != null) && (!chr.isHidden()) && (emote <= 17) && (chr.getAndroid() != null)) {
chr.getMap().broadcastMessage(CField.showAndroidEmotion(chr.getId(), (byte) emote));
}
}
public static void MoveAndroid(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {//MIXTAMAL6
slea.skip(12);//MIXTAMAL6
final List<LifeMovementFragment> res = MovementParse.parseMovement(slea, 3);//MIXTAMAL6
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 void ChangeEmotion(final int emote, final MapleCharacter chr) {
if (emote > 7) {
final int emoteid = 5159992 + emote;
final MapleInventoryType type = GameConstants.getInventoryType(emoteid);
if (chr.getInventory(type).findById(emoteid) == null) {
chr.getCheatTracker().registerOffense(CheatingOffense.USING_UNAVAILABLE_ITEM, Integer.toString(emoteid));
return;
}
}
if (emote > 0 && chr != null && chr.getMap() != null && !chr.isHidden()) { //O_o
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 void Heal(LittleEndianAccessor slea, MapleCharacter chr) {
if (chr == null) {
return;
}
chr.updateTick(slea.readInt());
if (slea.available() >= 8L) {
slea.skip(slea.available() >= 12L ? 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.isDemonSlayer(chr.getJob())) && (chr.canMP(now + 1000L))) {
if (healMP > stats.getHealMP()) {
healMP = (int) stats.getHealMP();
}
chr.addMP(healMP);
}
}
public static void MovePlayer(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
slea.skip(14);
slea.readInt(); // position
slea.readInt();
if (chr == null) {
return;
}
final Point Original_Pos = chr.getPosition();
List res;
try {
res = MovementParse.parseMovement(slea, 1, chr);
} 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() < 11L) || (slea.available() > 26L)) {
// 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;
Timer.CloneTimer.getInstance().schedule(new Runnable() {
@Override
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
}
}
}, 500 * i + 500);
}
}
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 void ChangeMapSpecial(String portal_name, MapleClient c, MapleCharacter chr) {
if ((chr == null) || (chr.getMap() == null)) {
return;
}
MaplePortal portal = chr.getMap().getPortal(portal_name);
// if (chr.getGMLevel() > ServerConstants.PlayerGMRank.GM.getLevel()) {
// chr.dropMessage(6, new StringBuilder().append(portal.getScriptName()).append(" accessed").toString());
// }
if ((portal != null) && (!chr.hasBlockedInventory())) {
portal.enterPortal(c);
} else {
c.getSession().write(CWvsContext.enableActions());
}
}
public static 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();
slea.readInt();
MaplePortal portal = chr.getMap().getPortal(slea.readMapleAsciiString());
if (slea.available() >= 7L) {
chr.updateTick(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 (chr.getMapId() == 105200111) {
chr.getStat().setHp(500000, chr);
chr.getStat().setMp(500000, chr);
}
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;
} else if ((chr.getMapId() == 105040300) && (targetid == 105040000)) {
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 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())) {
chr.getCheatTracker().registerOffense(CheatingOffense.USING_FARAWAY_PORTAL);
return;
}
chr.getMap().movePlayer(chr, new Point(toX, toY));
chr.checkFollow();
}
public static void snowBall(LittleEndianAccessor slea, MapleClient c) {
c.getSession().write(CWvsContext.enableActions());
}
public static void leftKnockBack(LittleEndianAccessor slea, MapleClient c) {
if (c.getPlayer().getMapId() / 10000 == 10906) {
c.getSession().write(CField.leftKnockBack());
c.getSession().write(CWvsContext.enableActions());
}
}
public static void ReIssueMedal(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
MapleQuest q = MapleQuest.getInstance(slea.readShort());
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, 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, (byte) 1, new StringBuilder().append("Redeemed item through medal quest ").append(q.getId()).append(" on ").append(FileoutputUtil.CurrentReadable_Date()).toString());
c.getSession().write(CField.UIPacket.reissueMedal(itemid, 0));
}
public static void MessengerRanking(LittleEndianAccessor slea, MapleClient c, MapleCharacter chr) {
if (chr == null) {
return;
}
c.getSession().write(CField.messengerOpen(slea.readByte(), null));
}
}