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=

BIN
dist/MapleSolaxia.jar vendored

Binary file not shown.

View File

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

View File

@@ -352,3 +352,7 @@ Corrigido bug no esquema de recupera
30 Junho 2017,
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").
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">
<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">
<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>
</project-private>

View File

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

View File

@@ -2068,6 +2068,9 @@ public class Commands {
MapleMapItem mapItem = (MapleMapItem) item;
if (mapItem.getMeso() > 0) {
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) {
int petId = MaplePet.createPet(mapItem.getItem().getItemId());
if (petId == -1) {

View File

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

View File

@@ -27,25 +27,28 @@ import client.MapleClient;
import client.SkillFactory;
import net.AbstractMaplePacketHandler;
import server.maps.MapleSummon;
import server.maps.MapleMapObject;
import tools.MaplePacketCreator;
import tools.data.input.SeekableLittleEndianAccessor;
public final class DamageSummonHandler extends AbstractMaplePacketHandler {
public final void handlePacket(SeekableLittleEndianAccessor slea, MapleClient c) {
int skillid = slea.readInt(); //Bugged? might not be skillid.
int unkByte = slea.readByte();
int oid = slea.readInt();
slea.skip(1); // -1
int damage = slea.readInt();
int monsterIdFrom = slea.readInt();
if (SkillFactory.getSkill(skillid) != null) {
MapleCharacter player = c.getPlayer();
MapleSummon summon = player.getSummonByKey(skillid);
if (summon != null) {
MapleMapObject mmo = player.getMap().getMapObject(oid);
if(mmo != null && mmo instanceof MapleSummon) {
MapleSummon summon = (MapleSummon) mmo;
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.getMap().broadcastMessage(chr, MaplePacketCreator.showHpHealed(chr.getId(), healHP), false);
chr.checkBerserk();
chr.checkBerserk(chr.isHidden());
abm.spam(0, timestamp);
}
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);
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) {
packet = MaplePacketCreator.magicAttack(player, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, attack.charge, 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;
byte[] packet = MaplePacketCreator.magicAttack(player, attack.skill, attack.skilllevel, attack.stance, attack.numAttackedAndDamage, attack.allDamage, charge, attack.speed, attack.direction, attack.display);
player.getMap().broadcastMessage(player, packet, false, true);
MapleStatEffect effect = attack.getAttackEffect(player, null);
Skill skill = SkillFactory.getSkill(attack.skill);

View File

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

View File

@@ -33,9 +33,10 @@ import server.MapleStatEffect;
import server.life.MapleMonster;
import server.maps.MapleSummon;
import tools.MaplePacketCreator;
import tools.data.input.LittleEndianAccessor;
import tools.data.input.SeekableLittleEndianAccessor;
public final class SummonDamageHandler extends AbstractMaplePacketHandler {
public final class SummonDamageHandler extends AbstractDealDamageHandler {
public final class SummonAttackEntry {
private int monsterOid;
@@ -84,7 +85,7 @@ public final class SummonDamageHandler extends AbstractMaplePacketHandler {
int damage = slea.readInt();
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) {
int damage = attackEntry.getDamage();
MapleMonster target = player.getMap().getMonsterByOid(attackEntry.getMonsterOid());

View File

@@ -224,7 +224,11 @@ public final class TakeDamageHandler extends AbstractMaplePacketHandler {
}
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);
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) {
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);
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();
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);
}
@@ -1105,7 +1109,7 @@ public class MapleStatEffect {
}
if (hpR != 0) {
hpchange += (int) (applyfrom.getCurrentMaxHp() * hpR) / (applyfrom.hasDisease(MapleDisease.ZOMBIFY) ? 2 : 1);
applyfrom.checkBerserk();
applyfrom.checkBerserk(applyfrom.isHidden());
}
if (primary) {
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^)
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);
hp -= damage;

View File

@@ -1997,6 +1997,25 @@ public class MaplePacketCreator {
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) {
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
@@ -2013,6 +2032,7 @@ public class MaplePacketCreator {
}
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) {
final MaplePacketLittleEndianWriter mplew = new MaplePacketLittleEndianWriter();
@@ -3507,13 +3527,13 @@ public class MaplePacketCreator {
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();
mplew.writeShort(SendOpcode.DAMAGE_SUMMON.getValue());
mplew.writeInt(cid);
mplew.writeInt(summonSkillId);
mplew.write(unkByte);
mplew.writeInt(damage);
mplew.writeInt(oid);
mplew.write(12);
mplew.writeInt(damage); // damage display doesn't seems to work...
mplew.writeInt(monsterIdFrom);
mplew.write(0);
return mplew.getPacket();