Take damage & Summon packets

Fixed some oddities with other player clients when dealing with summons
(spawning, taking damage or attacking). Fixed damage dealt to player not
apearing if the player is a GM on hiding and other players in the area
are GMs as well.
This commit is contained in:
ronancpl
2017-07-04 15:54:32 -03:00
parent c2cbc96975
commit b3734cbaf7
58 changed files with 100 additions and 48 deletions

View File

@@ -1,4 +1,4 @@
#Fri, 30 Jun 2017 16:23:30 -0300 #Tue, 04 Jul 2017 15:35:40 -0300
C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2= C\:\\Nexon\\MapleSolaxia\\MapleSolaxiaV2=

BIN
dist/MapleSolaxia.jar vendored

Binary file not shown.

View File

@@ -50,4 +50,5 @@ Admin/GM commands:
Project: Project:
* Organized project code. * Organized project code.
* Highly configurable server (see server flags at ServerConstants). * Highly configurable server (see server flags at ServerConstants).
* Fixed/added some missing packets for MoveEnvironment and summons.
--------------------------- ---------------------------

View File

@@ -351,4 +351,8 @@ Corrigido bug no esquema de recupera
30 Junho 2017, 30 Junho 2017,
Corrigido bug em mecânica de hpDec que permitia aos jogadores postergarem o efeito de decréscimo de HP. Corrigido bug em mecânica de hpDec que permitia aos jogadores postergarem o efeito de decréscimo de HP.
Elaborada funcionalidade que permite salvar o "tempo até expirar" para quests com janela de tempo muito alta (as que usam "timeLimit2"). Elaborada funcionalidade que permite salvar o "tempo até expirar" para quests com janela de tempo muito alta (as que usam "timeLimit2").
03 Julho 2017,
Corrigido cliente não mostrando dano tomado pelo player se ele está com GM escondido para os outros GMs.
Corrigido cliente não mostrando dano dado pelo summon para outros players.

View File

@@ -2,6 +2,12 @@
<project-private xmlns="http://www.netbeans.org/ns/project-private/1"> <project-private xmlns="http://www.netbeans.org/ns/project-private/1">
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="1"/> <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="1"/>
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2"> <open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
<group/> <group>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/SendOpcode.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/maps/MapleMapObjectType.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/server/maps/MapleSummon.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/net/server/channel/handlers/DamageSummonHandler.java</file>
<file>file:/C:/Nexon/MapleSolaxia/MapleSolaxiaV2/src/tools/MaplePacketCreator.java</file>
</group>
</open-files> </open-files>
</project-private> </project-private>

View File

@@ -872,6 +872,11 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
List<MapleBuffStat> dsstat = Collections.singletonList(MapleBuffStat.DARKSIGHT); List<MapleBuffStat> dsstat = Collections.singletonList(MapleBuffStat.DARKSIGHT);
getMap().broadcastGMMessage(this, MaplePacketCreator.cancelForeignBuff(id, dsstat), false); getMap().broadcastGMMessage(this, MaplePacketCreator.cancelForeignBuff(id, dsstat), false);
getMap().broadcastMessage(this, MaplePacketCreator.spawnPlayerMapobject(this), false); getMap().broadcastMessage(this, MaplePacketCreator.spawnPlayerMapobject(this), false);
for(MapleSummon ms: this.getSummonsValues()) {
getMap().broadcastNONGMMessage(this, MaplePacketCreator.spawnSummon(ms, false), false);
}
updatePartyMemberHP(); updatePartyMemberHP();
} else { } else {
this.hidden = true; this.hidden = true;
@@ -1290,7 +1295,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
this.currentType = type; this.currentType = type;
} }
public void checkBerserk() { public void checkBerserk(final boolean isHidden) {
if (BerserkSchedule != null) { if (BerserkSchedule != null) {
BerserkSchedule.cancel(false); BerserkSchedule.cancel(false);
} }
@@ -1304,7 +1309,8 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
@Override @Override
public void run() { public void run() {
client.announce(MaplePacketCreator.showOwnBerserk(skilllevel, Berserk)); client.announce(MaplePacketCreator.showOwnBerserk(skilllevel, Berserk));
getMap().broadcastMessage(MapleCharacter.this, MaplePacketCreator.showBerserk(getId(), skilllevel, Berserk), false); if(!isHidden) getMap().broadcastMessage(MapleCharacter.this, MaplePacketCreator.showBerserk(getId(), skilllevel, Berserk), false);
else getMap().broadcastGMMessage(MapleCharacter.this, MaplePacketCreator.showBerserk(getId(), skilllevel, Berserk), false);
} }
}, 5000, 3000); }, 5000, 3000);
} }
@@ -1801,15 +1807,16 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
getMap().removeMapObject(summon); getMap().removeMapObject(summon);
removeVisibleMapObject(summon); removeVisibleMapObject(summon);
summons.remove(summonId); summons.remove(summonId);
}
if (summon.getSkill() == DarkKnight.BEHOLDER) { if (summon.getSkill() == DarkKnight.BEHOLDER) {
if (beholderHealingSchedule != null) { if (beholderHealingSchedule != null) {
beholderHealingSchedule.cancel(false); beholderHealingSchedule.cancel(false);
beholderHealingSchedule = null; beholderHealingSchedule = null;
} }
if (beholderBuffSchedule != null) { if (beholderBuffSchedule != null) {
beholderBuffSchedule.cancel(false); beholderBuffSchedule.cancel(false);
beholderBuffSchedule = null; beholderBuffSchedule = null;
}
} }
} }
} else if (stat == MapleBuffStat.DRAGONBLOOD) { } else if (stat == MapleBuffStat.DRAGONBLOOD) {
@@ -4417,7 +4424,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
addHP(-bloodEffect.getX()); addHP(-bloodEffect.getX());
client.announce(MaplePacketCreator.showOwnBuffEffect(bloodEffect.getSourceId(), 5)); client.announce(MaplePacketCreator.showOwnBuffEffect(bloodEffect.getSourceId(), 5));
getMap().broadcastMessage(MapleCharacter.this, MaplePacketCreator.showBuffeffect(getId(), bloodEffect.getSourceId(), 5), false); getMap().broadcastMessage(MapleCharacter.this, MaplePacketCreator.showBuffeffect(getId(), bloodEffect.getSourceId(), 5), false);
checkBerserk(); checkBerserk(isHidden());
} }
}, 4000, 4000); }, 4000, 4000);
} }
@@ -4564,7 +4571,7 @@ public class MapleCharacter extends AbstractAnimatedMapleMapObject {
if (effect.isDragonBlood()) { if (effect.isDragonBlood()) {
prepareDragonBlood(effect); prepareDragonBlood(effect);
} else if (effect.isBerserk()) { } else if (effect.isBerserk()) {
checkBerserk(); checkBerserk(isHidden());
} else if (effect.isBeholder()) { } else if (effect.isBeholder()) {
final int beholder = DarkKnight.BEHOLDER; final int beholder = DarkKnight.BEHOLDER;
if (beholderHealingSchedule != null) { if (beholderHealingSchedule != null) {

View File

@@ -2068,6 +2068,9 @@ public class Commands {
MapleMapItem mapItem = (MapleMapItem) item; MapleMapItem mapItem = (MapleMapItem) item;
if (mapItem.getMeso() > 0) { if (mapItem.getMeso() > 0) {
player.gainMeso(mapItem.getMeso(), true); player.gainMeso(mapItem.getMeso(), true);
} else if(mapItem.getItemId() == 4031865 || mapItem.getItemId() == 4031866) {
// Add NX to account, show effect and make item disappear
player.getCashShop().gainCash(1, mapItem.getItemId() == 4031865 ? 100 : 250);
} else if (mapItem.getItem().getItemId() >= 5000000 && mapItem.getItem().getItemId() <= 5000100) { } else if (mapItem.getItem().getItemId() >= 5000000 && mapItem.getItem().getItemId() <= 5000100) {
int petId = MaplePet.createPet(mapItem.getItem().getItemId()); int petId = MaplePet.createPet(mapItem.getItem().getItemId());
if (petId == -1) { if (petId == -1) {

View File

@@ -255,8 +255,8 @@ public abstract class AbstractDealDamageHandler extends AbstractMaplePacketHandl
if(attack.skill == DragonKnight.DRAGON_ROAR || attack.skill == SuperGM.SUPER_DRAGON_ROAR) if(attack.skill == DragonKnight.DRAGON_ROAR || attack.skill == SuperGM.SUPER_DRAGON_ROAR)
distanceToDetect += 250000; distanceToDetect += 250000;
if(attack.skill == Shadower.BOOMERANG_STEP) if(attack.skill == Shadower.BOOMERANG_STEP)
distanceToDetect += 60000; distanceToDetect += 60000;
if(distance > distanceToDetect) { if(distance > distanceToDetect) {
AutobanFactory.DISTANCE_HACK.alert(player, "Distance Sq to monster: " + distance + " SID: " + attack.skill + " MID: " + monster.getId()); AutobanFactory.DISTANCE_HACK.alert(player, "Distance Sq to monster: " + distance + " SID: " + attack.skill + " MID: " + monster.getId());

View File

@@ -133,7 +133,7 @@ public final class CloseRangeDamageHandler extends AbstractDealDamageHandler {
player.setHp(1); player.setHp(1);
} }
player.updateSingleStat(MapleStat.HP, player.getHp()); player.updateSingleStat(MapleStat.HP, player.getHp());
player.checkBerserk(); player.checkBerserk(player.isHidden());
} }
if (attack.numAttacked > 0 && attack.skill == 1211002) { if (attack.numAttacked > 0 && attack.skill == 1211002) {
boolean advcharge_prob = false; boolean advcharge_prob = false;

View File

@@ -27,25 +27,28 @@ import client.MapleClient;
import client.SkillFactory; import client.SkillFactory;
import net.AbstractMaplePacketHandler; import net.AbstractMaplePacketHandler;
import server.maps.MapleSummon; import server.maps.MapleSummon;
import server.maps.MapleMapObject;
import tools.MaplePacketCreator; import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor; import tools.data.input.SeekableLittleEndianAccessor;
public final class DamageSummonHandler extends AbstractMaplePacketHandler { public final class DamageSummonHandler extends AbstractMaplePacketHandler {
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) { public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
int skillid = slea.readInt(); //Bugged? might not be skillid. int oid = slea.readInt();
int unkByte = slea.readByte(); slea.skip(1); // -1
int damage = slea.readInt(); int damage = slea.readInt();
int monsterIdFrom = slea.readInt(); int monsterIdFrom = slea.readInt();
if (SkillFactory.getSkill(skillid) != null) {
MapleCharacter player = c.getPlayer(); MapleCharacter player = c.getPlayer();
MapleSummon summon = player.getSummonByKey(skillid); MapleMapObject mmo = player.getMap().getMapObject(oid);
if (summon != null) {
summon.addHP(-damage); if(mmo != null && mmo instanceof MapleSummon) {
if (summon.getHP() <= 0) { MapleSummon summon = (MapleSummon) mmo;
player.cancelEffectFromBuffStat(MapleBuffStat.PUPPET);
} summon.addHP(-damage);
if (summon.getHP() <= 0) {
player.cancelEffectFromBuffStat(MapleBuffStat.PUPPET);
} }
player.getMap().broadcastMessage(player, MaplePacketCreator.damageSummon(player.getId(), skillid, damage, unkByte, monsterIdFrom), summon.getPosition()); player.getMap().broadcastMessage(player, MaplePacketCreator.damageSummon(player.getId(), oid, damage, monsterIdFrom), summon.getPosition());
} }
} }
} }

View File

@@ -50,7 +50,7 @@ public final class HealOvertimeHandler extends AbstractMaplePacketHandler {
chr.addHP(healHP); chr.addHP(healHP);
chr.getMap().broadcastMessage(chr, MaplePacketCreator.showHpHealed(chr.getId(), healHP), false); chr.getMap().broadcastMessage(chr, MaplePacketCreator.showHpHealed(chr.getId(), healHP), false);
chr.checkBerserk(); chr.checkBerserk(chr.isHidden());
abm.spam(0, timestamp); abm.spam(0, timestamp);
} }
short healMP = slea.readShort(); short healMP = slea.readShort();

View File

@@ -58,10 +58,9 @@ public final class MagicDamageHandler extends AbstractDealDamageHandler {
} }
} }
byte[] packet = MaplePacketCreator.magicAttack(player, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, -1, attack.speed, attack.direction, attack.display); int charge = (attack.skill == Evan.FIRE_BREATH || attack.skill == Evan.ICE_BREATH || attack.skill == FPArchMage.BIG_BANG || attack.skill == ILArchMage.BIG_BANG || attack.skill == Bishop.BIG_BANG) ? attack.charge : -1;
if (attack.skill == Evan.FIRE_BREATH || attack.skill == Evan.ICE_BREATH || attack.skill == FPArchMage.BIG_BANG || attack.skill == ILArchMage.BIG_BANG || attack.skill == Bishop.BIG_BANG) { byte[] packet = MaplePacketCreator.magicAttack(player, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, charge, attack.speed, attack.direction, attack.display);
packet = MaplePacketCreator.magicAttack(player, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, attack.charge, attack.speed, attack.direction, attack.display);
}
player.getMap().broadcastMessage(player, packet, false, true); player.getMap().broadcastMessage(player, packet, false, true);
MapleStatEffect effect = attack.getAttackEffect(player, null); MapleStatEffect effect = attack.getAttackEffect(player, null);
Skill skill = SkillFactory.getSkill(attack.skill); Skill skill = SkillFactory.getSkill(attack.skill);

View File

@@ -250,7 +250,7 @@ public final class PlayerLoggedinHandler extends AbstractMaplePacketHandler {
player.checkMessenger(); player.checkMessenger();
c.announce(MaplePacketCreator.enableReport()); c.announce(MaplePacketCreator.enableReport());
player.changeSkillLevel(SkillFactory.getSkill(10000000 * player.getJobType() + 12), (byte) (player.getLinkedLevel() / 10), 20, -1); player.changeSkillLevel(SkillFactory.getSkill(10000000 * player.getJobType() + 12), (byte) (player.getLinkedLevel() / 10), 20, -1);
player.checkBerserk(); player.checkBerserk(player.isHidden());
player.expirationTask(); player.expirationTask();
//player.setWorldRates(); //player.setWorldRates();
if (GameConstants.hasSPTable(player.getJob()) && player.getJob().getId() != 2001) { if (GameConstants.hasSPTable(player.getJob()) && player.getJob().getId() != 2001) {

View File

@@ -33,9 +33,10 @@ import server.MapleStatEffect;
import server.life.MapleMonster; import server.life.MapleMonster;
import server.maps.MapleSummon; import server.maps.MapleSummon;
import tools.MaplePacketCreator; import tools.MaplePacketCreator;
import tools.data.input.LittleEndianAccessor;
import tools.data.input.SeekableLittleEndianAccessor; import tools.data.input.SeekableLittleEndianAccessor;
public final class SummonDamageHandler extends AbstractMaplePacketHandler { public final class SummonDamageHandler extends AbstractDealDamageHandler {
public final class SummonAttackEntry { public final class SummonAttackEntry {
private int monsterOid; private int monsterOid;
@@ -84,7 +85,7 @@ public final class SummonDamageHandler extends AbstractMaplePacketHandler {
int damage = slea.readInt(); int damage = slea.readInt();
allDamage.add(new SummonAttackEntry(monsterOid, damage)); allDamage.add(new SummonAttackEntry(monsterOid, damage));
} }
player.getMap().broadcastMessage(player, MaplePacketCreator.summonAttack(player.getId(), summon.getSkill(), direction, allDamage), summon.getPosition()); player.getMap().broadcastMessage(player, MaplePacketCreator.summonAttack(player.getId(), summon.getObjectId(), direction, allDamage), summon.getPosition());
for (SummonAttackEntry attackEntry : allDamage) { for (SummonAttackEntry attackEntry : allDamage) {
int damage = attackEntry.getDamage(); int damage = attackEntry.getDamage();
MapleMonster target = player.getMap().getMonsterByOid(attackEntry.getMonsterOid()); MapleMonster target = player.getMap().getMonsterByOid(attackEntry.getMonsterOid());

View File

@@ -224,7 +224,11 @@ public final class TakeDamageHandler extends AbstractMaplePacketHandler {
} }
if (!player.isHidden()) { if (!player.isHidden()) {
map.broadcastMessage(player, MaplePacketCreator.damagePlayer(damagefrom, monsteridfrom, player.getId(), damage, fake, direction, is_pgmr, pgmr, is_pg, oid, pos_x, pos_y), false); map.broadcastMessage(player, MaplePacketCreator.damagePlayer(damagefrom, monsteridfrom, player.getId(), damage, fake, direction, is_pgmr, pgmr, is_pg, oid, pos_x, pos_y), false);
player.checkBerserk(); player.checkBerserk(true);
}
else {
map.broadcastGMMessage(player, MaplePacketCreator.damagePlayer(damagefrom, monsteridfrom, player.getId(), damage, fake, direction, is_pgmr, pgmr, is_pg, oid, pos_x, pos_y), false);
player.checkBerserk(false);
} }
if (map.getId() >= 925020000 && map.getId() < 925030000) { if (map.getId() >= 925020000 && map.getId() < 925030000) {
player.setDojoEnergy(player.isGM() ? 300 : player.getDojoEnergy() < 300 ? player.getDojoEnergy() + 1 : 0); //Fking gm's player.setDojoEnergy(player.isGM() ? 300 : player.getDojoEnergy() < 300 ? player.getDojoEnergy() + 1 : 0); //Fking gm's

View File

@@ -75,7 +75,7 @@ public final class UseItemHandler extends AbstractMaplePacketHandler {
remove(c, slot); remove(c, slot);
ii.getItemEffect(toUse.getItemId()).applyTo(c.getPlayer()); ii.getItemEffect(toUse.getItemId()).applyTo(c.getPlayer());
c.getPlayer().checkBerserk(); c.getPlayer().checkBerserk(c.getPlayer().isHidden());
} }
} }

View File

@@ -810,6 +810,10 @@ public class MapleStatEffect {
} }
SummonMovementType summonMovementType = getSummonMovementType(); SummonMovementType summonMovementType = getSummonMovementType();
if (overTime || isCygnusFA() || summonMovementType != null) { if (overTime || isCygnusFA() || summonMovementType != null) {
if (summonMovementType != null && pos != null) {
applyto.cancelBuffStats(MapleBuffStat.SUMMON); // if player has a summon already, drop it
}
applyBuffEffect(applyfrom, applyto, primary); applyBuffEffect(applyfrom, applyto, primary);
} }
@@ -1105,7 +1109,7 @@ public class MapleStatEffect {
} }
if (hpR != 0) { if (hpR != 0) {
hpchange += (int) (applyfrom.getCurrentMaxHp() * hpR) / (applyfrom.hasDisease(MapleDisease.ZOMBIFY) ? 2 : 1); hpchange += (int) (applyfrom.getCurrentMaxHp() * hpR) / (applyfrom.hasDisease(MapleDisease.ZOMBIFY) ? 2 : 1);
applyfrom.checkBerserk(); applyfrom.checkBerserk(applyfrom.isHidden());
} }
if (primary) { if (primary) {
if (hpCon != 0) { if (hpCon != 0) {

View File

@@ -209,7 +209,7 @@ public class MapleMonster extends AbstractLoadedMapleLife {
} }
int trueDamage = Math.min(hp, damage); // since magic happens otherwise B^) int trueDamage = Math.min(hp, damage); // since magic happens otherwise B^)
if(ServerConstants.USE_DEBUG == true && from != null) from.dropMessage(5, "Hitted MOB " + this.getId()); if(ServerConstants.USE_DEBUG == true && from != null) from.dropMessage(5, "Hitted MOB " + this.getId() + ", OID " + this.getObjectId());
dispatchMonsterDamaged(from, trueDamage); dispatchMonsterDamaged(from, trueDamage);
hp -= damage; hp -= damage;

View File

@@ -1996,7 +1996,26 @@ public class MaplePacketCreator {
serializeMovementList(mplew, moves); serializeMovementList(mplew, moves);
return mplew.getPacket(); return mplew.getPacket();
} }
public static byte[] summonAttack(int cid, int summonOid, byte direction, List<SummonAttackEntry> allDamage) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
//b2 00 29 f7 00 00 9a a3 04 00 c8 04 01 94 a3 04 00 06 ff 2b 00
mplew.writeShort(SendOpcode.SUMMON_ATTACK.getValue());
mplew.writeInt(cid);
mplew.writeInt(summonOid);
mplew.write(direction);
mplew.write(4);
mplew.write(allDamage.size());
for (SummonAttackEntry attackEntry : allDamage) {
mplew.writeInt(attackEntry.getMonsterOid()); // oid
mplew.write(6); // who knows
mplew.writeInt(attackEntry.getDamage()); // damage
}
return mplew.getPacket();
}
/*
public static byte[] summonAttack(int cid, int summonSkillId, byte direction, List<SummonAttackEntry> allDamage) { public static byte[] summonAttack(int cid, int summonSkillId, byte direction, List<SummonAttackEntry> allDamage) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
//b2 00 29 f7 00 00 9a a3 04 00 c8 04 01 94 a3 04 00 06 ff 2b 00 //b2 00 29 f7 00 00 9a a3 04 00 c8 04 01 94 a3 04 00 06 ff 2b 00
@@ -2013,6 +2032,7 @@ public class MaplePacketCreator {
} }
return mplew.getPacket(); return mplew.getPacket();
} }
*/
public static byte[] closeRangeAttack(MapleCharacter chr, int skill, int skilllevel, int stance, int numAttackedAndDamage, Map<Integer, List<Integer>> damage, int speed, int direction, int display) { public static byte[] closeRangeAttack(MapleCharacter chr, int skill, int skilllevel, int stance, int numAttackedAndDamage, Map<Integer, List<Integer>> damage, int speed, int direction, int display) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
@@ -3506,14 +3526,14 @@ public class MaplePacketCreator {
mplew.writeInt(oid); mplew.writeInt(oid);
return mplew.getPacket(); return mplew.getPacket();
} }
public static byte[] damageSummon(int cid, int summonSkillId, int damage, int unkByte, int monsterIdFrom) { public static byte[] damageSummon(int cid, int oid, int damage, int monsterIdFrom) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter(); final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
mplew.writeShort(SendOpcode.DAMAGE_SUMMON.getValue()); mplew.writeShort(SendOpcode.DAMAGE_SUMMON.getValue());
mplew.writeInt(cid); mplew.writeInt(cid);
mplew.writeInt(summonSkillId); mplew.writeInt(oid);
mplew.write(unkByte); mplew.write(12);
mplew.writeInt(damage); mplew.writeInt(damage); // damage display doesn't seems to work...
mplew.writeInt(monsterIdFrom); mplew.writeInt(monsterIdFrom);
mplew.write(0); mplew.write(0);
return mplew.getPacket(); return mplew.getPacket();