Servitor improvements.

This commit is contained in:
MobiusDev
2017-09-07 01:20:26 +00:00
parent eb4f43f5c2
commit 9baee86367
24 changed files with 1710 additions and 1666 deletions

View File

@@ -62,7 +62,7 @@ public enum NpcInfoType implements IUpdateTypeComponent
// 4 // 4
TITLE_NPCSTRINGID(0x20, 4), TITLE_NPCSTRINGID(0x20, 4),
PVP_FLAG(0x21, 1), PVP_FLAG(0x21, 1),
NAME_COLOR(0x22, 4), REPUTATION(0x22, 4),
CLAN(0x23, (5 * 4)), CLAN(0x23, (5 * 4)),
ABNORMALS(0x24, 0), ABNORMALS(0x24, 0),
VISUAL_STATE(0x25, 1); VISUAL_STATE(0x25, 1);

View File

@@ -191,20 +191,19 @@ public abstract class L2Summon extends L2Playable
{ {
L2World.getInstance().forEachVisibleObject(this, L2PcInstance.class, player -> L2World.getInstance().forEachVisibleObject(this, L2PcInstance.class, player ->
{ {
if (player == getOwner())
{
player.sendPacket(new PetInfo(this, 1));
return;
}
if (isPet()) if (isPet())
{ {
player.sendPacket(new ExPetInfo(this, player, 1)); player.sendPacket(new ExPetInfo(this, player, 1));
} }
else else
{ {
if (player == getOwner()) player.sendPacket(new SummonInfo(this, player, 1));
{
player.sendPacket(new PetInfo(this, 1));
}
else
{
player.sendPacket(new SummonInfo(this, player, 1));
}
} }
}); });
} }
@@ -364,6 +363,8 @@ public abstract class L2Summon extends L2Playable
public void deleteMe(L2PcInstance owner) public void deleteMe(L2PcInstance owner)
{ {
super.deleteMe();
if (owner != null) if (owner != null)
{ {
owner.sendPacket(new PetDelete(getSummonType(), getObjectId())); owner.sendPacket(new PetDelete(getSummonType(), getObjectId()));
@@ -372,16 +373,7 @@ public abstract class L2Summon extends L2Playable
{ {
party.broadcastToPartyMembers(owner, new ExPartyPetWindowDelete(this)); party.broadcastToPartyMembers(owner, new ExPartyPetWindowDelete(this));
} }
}
// pet will be deleted along with all his items
if (getInventory() != null)
{
getInventory().destroyAllItems("pet deleted", getOwner(), this);
}
decayMe();
if (owner != null)
{
if (isPet()) if (isPet())
{ {
owner.setPet(null); owner.setPet(null);
@@ -391,7 +383,13 @@ public abstract class L2Summon extends L2Playable
owner.removeServitor(getObjectId()); owner.removeServitor(getObjectId());
} }
} }
super.deleteMe();
// pet will be deleted along with all his items
if (getInventory() != null)
{
getInventory().destroyAllItems("pet deleted", getOwner(), this);
}
decayMe();
} }
public void unSummon(L2PcInstance owner) public void unSummon(L2PcInstance owner)
@@ -842,7 +840,7 @@ public abstract class L2Summon extends L2Playable
// Check if the L2PcInstance is the owner of the Pet // Check if the L2PcInstance is the owner of the Pet
if (activeChar == getOwner()) if (activeChar == getOwner())
{ {
activeChar.sendPacket(new PetInfo(this, 1)); activeChar.sendPacket(new PetInfo(this, isDead() ? 0 : 1));
// The PetInfo packet wipes the PartySpelled (list of active spells' icons). Re-add them // The PetInfo packet wipes the PartySpelled (list of active spells' icons). Re-add them
updateEffectIcons(true); updateEffectIcons(true);
if (isPet()) if (isPet())

View File

@@ -147,6 +147,11 @@ public class ExPetInfo extends AbstractMaskPacket<NpcInfoType>
addComponentType(NpcInfoType.SUMMONED); addComponentType(NpcInfoType.SUMMONED);
} }
if (summon.getReputation() != 0)
{
addComponentType(NpcInfoType.REPUTATION);
}
if (summon.getOwner().getClan() != null) if (summon.getOwner().getClan() != null)
{ {
_clanId = summon.getOwner().getAppearance().getVisibleClanId(); _clanId = summon.getOwner().getAppearance().getVisibleClanId();
@@ -366,9 +371,9 @@ public class ExPetInfo extends AbstractMaskPacket<NpcInfoType>
{ {
packet.writeC(_summon.getPvpFlag()); // PVP flag packet.writeC(_summon.getPvpFlag()); // PVP flag
} }
if (containsMask(NpcInfoType.NAME_COLOR)) if (containsMask(NpcInfoType.REPUTATION))
{ {
packet.writeD(0x00); // Name color packet.writeD(_summon.getReputation()); // Name color
} }
if (containsMask(NpcInfoType.CLAN)) if (containsMask(NpcInfoType.CLAN))
{ {

View File

@@ -400,7 +400,7 @@ public class NpcInfo extends AbstractMaskPacket<NpcInfoType>
{ {
packet.writeC(_npc.getPvpFlag()); // PVP flag packet.writeC(_npc.getPvpFlag()); // PVP flag
} }
if (containsMask(NpcInfoType.NAME_COLOR)) if (containsMask(NpcInfoType.REPUTATION))
{ {
packet.writeD(0x00); // Name color packet.writeD(0x00); // Name color
} }

View File

@@ -65,8 +65,11 @@ public class PetInfo implements IClientOutgoingPacket
_maxFed = sum.getLifeTime(); _maxFed = sum.getLifeTime();
} }
// _statusMask |= 0x01; // Auto attackable status if (summon.isBetrayed())
// _statusMask |= 0x02; // can be chatted with {
_statusMask |= 0x01; // Auto attackable status
}
_statusMask |= 0x02; // can be chatted with
if (summon.isRunning()) if (summon.isRunning())
{ {

View File

@@ -147,6 +147,11 @@ public class SummonInfo extends AbstractMaskPacket<NpcInfoType>
addComponentType(NpcInfoType.SUMMONED); addComponentType(NpcInfoType.SUMMONED);
} }
if (summon.getReputation() != 0)
{
addComponentType(NpcInfoType.REPUTATION);
}
if (summon.getOwner().getClan() != null) if (summon.getOwner().getClan() != null)
{ {
_clanId = summon.getOwner().getAppearance().getVisibleClanId(); _clanId = summon.getOwner().getAppearance().getVisibleClanId();
@@ -366,9 +371,9 @@ public class SummonInfo extends AbstractMaskPacket<NpcInfoType>
{ {
packet.writeC(_summon.getPvpFlag()); // PVP flag packet.writeC(_summon.getPvpFlag()); // PVP flag
} }
if (containsMask(NpcInfoType.NAME_COLOR)) if (containsMask(NpcInfoType.REPUTATION))
{ {
packet.writeD(0x00); // Name color packet.writeD(_summon.getReputation()); // Name color
} }
if (containsMask(NpcInfoType.CLAN)) if (containsMask(NpcInfoType.CLAN))
{ {

View File

@@ -62,7 +62,7 @@ public enum NpcInfoType implements IUpdateTypeComponent
// 4 // 4
TITLE_NPCSTRINGID(0x20, 4), TITLE_NPCSTRINGID(0x20, 4),
PVP_FLAG(0x21, 1), PVP_FLAG(0x21, 1),
NAME_COLOR(0x22, 4), REPUTATION(0x22, 4),
CLAN(0x23, (5 * 4)), CLAN(0x23, (5 * 4)),
ABNORMALS(0x24, 0), ABNORMALS(0x24, 0),
VISUAL_STATE(0x25, 1); VISUAL_STATE(0x25, 1);

View File

@@ -191,20 +191,19 @@ public abstract class L2Summon extends L2Playable
{ {
L2World.getInstance().forEachVisibleObject(this, L2PcInstance.class, player -> L2World.getInstance().forEachVisibleObject(this, L2PcInstance.class, player ->
{ {
if (player == getOwner())
{
player.sendPacket(new PetInfo(this, 1));
return;
}
if (isPet()) if (isPet())
{ {
player.sendPacket(new ExPetInfo(this, player, 1)); player.sendPacket(new ExPetInfo(this, player, 1));
} }
else else
{ {
if (player == getOwner()) player.sendPacket(new SummonInfo(this, player, 1));
{
player.sendPacket(new PetInfo(this, 1));
}
else
{
player.sendPacket(new SummonInfo(this, player, 1));
}
} }
}); });
} }
@@ -364,6 +363,8 @@ public abstract class L2Summon extends L2Playable
public void deleteMe(L2PcInstance owner) public void deleteMe(L2PcInstance owner)
{ {
super.deleteMe();
if (owner != null) if (owner != null)
{ {
owner.sendPacket(new PetDelete(getSummonType(), getObjectId())); owner.sendPacket(new PetDelete(getSummonType(), getObjectId()));
@@ -372,16 +373,7 @@ public abstract class L2Summon extends L2Playable
{ {
party.broadcastToPartyMembers(owner, new ExPartyPetWindowDelete(this)); party.broadcastToPartyMembers(owner, new ExPartyPetWindowDelete(this));
} }
}
// pet will be deleted along with all his items
if (getInventory() != null)
{
getInventory().destroyAllItems("pet deleted", getOwner(), this);
}
decayMe();
if (owner != null)
{
if (isPet()) if (isPet())
{ {
owner.setPet(null); owner.setPet(null);
@@ -391,7 +383,13 @@ public abstract class L2Summon extends L2Playable
owner.removeServitor(getObjectId()); owner.removeServitor(getObjectId());
} }
} }
super.deleteMe();
// pet will be deleted along with all his items
if (getInventory() != null)
{
getInventory().destroyAllItems("pet deleted", getOwner(), this);
}
decayMe();
} }
public void unSummon(L2PcInstance owner) public void unSummon(L2PcInstance owner)
@@ -842,7 +840,7 @@ public abstract class L2Summon extends L2Playable
// Check if the L2PcInstance is the owner of the Pet // Check if the L2PcInstance is the owner of the Pet
if (activeChar == getOwner()) if (activeChar == getOwner())
{ {
activeChar.sendPacket(new PetInfo(this, 1)); activeChar.sendPacket(new PetInfo(this, isDead() ? 0 : 1));
// The PetInfo packet wipes the PartySpelled (list of active spells' icons). Re-add them // The PetInfo packet wipes the PartySpelled (list of active spells' icons). Re-add them
updateEffectIcons(true); updateEffectIcons(true);
if (isPet()) if (isPet())

View File

@@ -147,6 +147,11 @@ public class ExPetInfo extends AbstractMaskPacket<NpcInfoType>
addComponentType(NpcInfoType.SUMMONED); addComponentType(NpcInfoType.SUMMONED);
} }
if (summon.getReputation() != 0)
{
addComponentType(NpcInfoType.REPUTATION);
}
if (summon.getOwner().getClan() != null) if (summon.getOwner().getClan() != null)
{ {
_clanId = summon.getOwner().getAppearance().getVisibleClanId(); _clanId = summon.getOwner().getAppearance().getVisibleClanId();
@@ -366,9 +371,9 @@ public class ExPetInfo extends AbstractMaskPacket<NpcInfoType>
{ {
packet.writeC(_summon.getPvpFlag()); // PVP flag packet.writeC(_summon.getPvpFlag()); // PVP flag
} }
if (containsMask(NpcInfoType.NAME_COLOR)) if (containsMask(NpcInfoType.REPUTATION))
{ {
packet.writeD(0x00); // Name color packet.writeD(_summon.getReputation()); // Name color
} }
if (containsMask(NpcInfoType.CLAN)) if (containsMask(NpcInfoType.CLAN))
{ {

View File

@@ -400,7 +400,7 @@ public class NpcInfo extends AbstractMaskPacket<NpcInfoType>
{ {
packet.writeC(_npc.getPvpFlag()); // PVP flag packet.writeC(_npc.getPvpFlag()); // PVP flag
} }
if (containsMask(NpcInfoType.NAME_COLOR)) if (containsMask(NpcInfoType.REPUTATION))
{ {
packet.writeD(0x00); // Name color packet.writeD(0x00); // Name color
} }

View File

@@ -65,8 +65,11 @@ public class PetInfo implements IClientOutgoingPacket
_maxFed = sum.getLifeTime(); _maxFed = sum.getLifeTime();
} }
// _statusMask |= 0x01; // Auto attackable status if (summon.isBetrayed())
// _statusMask |= 0x02; // can be chatted with {
_statusMask |= 0x01; // Auto attackable status
}
_statusMask |= 0x02; // can be chatted with
if (summon.isRunning()) if (summon.isRunning())
{ {

View File

@@ -147,6 +147,11 @@ public class SummonInfo extends AbstractMaskPacket<NpcInfoType>
addComponentType(NpcInfoType.SUMMONED); addComponentType(NpcInfoType.SUMMONED);
} }
if (summon.getReputation() != 0)
{
addComponentType(NpcInfoType.REPUTATION);
}
if (summon.getOwner().getClan() != null) if (summon.getOwner().getClan() != null)
{ {
_clanId = summon.getOwner().getAppearance().getVisibleClanId(); _clanId = summon.getOwner().getAppearance().getVisibleClanId();
@@ -366,9 +371,9 @@ public class SummonInfo extends AbstractMaskPacket<NpcInfoType>
{ {
packet.writeC(_summon.getPvpFlag()); // PVP flag packet.writeC(_summon.getPvpFlag()); // PVP flag
} }
if (containsMask(NpcInfoType.NAME_COLOR)) if (containsMask(NpcInfoType.REPUTATION))
{ {
packet.writeD(0x00); // Name color packet.writeD(_summon.getReputation()); // Name color
} }
if (containsMask(NpcInfoType.CLAN)) if (containsMask(NpcInfoType.CLAN))
{ {

View File

@@ -62,7 +62,7 @@ public enum NpcInfoType implements IUpdateTypeComponent
// 4 // 4
TITLE_NPCSTRINGID(0x20, 4), TITLE_NPCSTRINGID(0x20, 4),
PVP_FLAG(0x21, 1), PVP_FLAG(0x21, 1),
NAME_COLOR(0x22, 4), REPUTATION(0x22, 4),
CLAN(0x23, (5 * 4)), CLAN(0x23, (5 * 4)),
ABNORMALS(0x24, 0), ABNORMALS(0x24, 0),
VISUAL_STATE(0x25, 1); VISUAL_STATE(0x25, 1);

View File

@@ -147,6 +147,11 @@ public class ExPetInfo extends AbstractMaskPacket<NpcInfoType>
addComponentType(NpcInfoType.SUMMONED); addComponentType(NpcInfoType.SUMMONED);
} }
if (summon.getReputation() != 0)
{
addComponentType(NpcInfoType.REPUTATION);
}
if (summon.getOwner().getClan() != null) if (summon.getOwner().getClan() != null)
{ {
_clanId = summon.getOwner().getAppearance().getVisibleClanId(); _clanId = summon.getOwner().getAppearance().getVisibleClanId();
@@ -366,9 +371,9 @@ public class ExPetInfo extends AbstractMaskPacket<NpcInfoType>
{ {
packet.writeC(_summon.getPvpFlag()); // PVP flag packet.writeC(_summon.getPvpFlag()); // PVP flag
} }
if (containsMask(NpcInfoType.NAME_COLOR)) if (containsMask(NpcInfoType.REPUTATION))
{ {
packet.writeD(0x00); // Name color packet.writeD(_summon.getReputation()); // Name color
} }
if (containsMask(NpcInfoType.CLAN)) if (containsMask(NpcInfoType.CLAN))
{ {

View File

@@ -400,7 +400,7 @@ public class NpcInfo extends AbstractMaskPacket<NpcInfoType>
{ {
packet.writeC(_npc.getPvpFlag()); // PVP flag packet.writeC(_npc.getPvpFlag()); // PVP flag
} }
if (containsMask(NpcInfoType.NAME_COLOR)) if (containsMask(NpcInfoType.REPUTATION))
{ {
packet.writeD(0x00); // Name color packet.writeD(0x00); // Name color
} }

View File

@@ -65,8 +65,11 @@ public class PetInfo implements IClientOutgoingPacket
_maxFed = sum.getLifeTime(); _maxFed = sum.getLifeTime();
} }
// _statusMask |= 0x01; // Auto attackable status if (summon.isBetrayed())
// _statusMask |= 0x02; // can be chatted with {
_statusMask |= 0x01; // Auto attackable status
}
_statusMask |= 0x02; // can be chatted with
if (summon.isRunning()) if (summon.isRunning())
{ {

View File

@@ -1,397 +1,402 @@
/* /*
* This file is part of the L2J Mobius project. * This file is part of the L2J Mobius project.
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.l2jmobius.gameserver.network.serverpackets; package com.l2jmobius.gameserver.network.serverpackets;
import java.util.Set; import java.util.Set;
import com.l2jmobius.commons.network.PacketWriter; import com.l2jmobius.commons.network.PacketWriter;
import com.l2jmobius.gameserver.enums.NpcInfoType; import com.l2jmobius.gameserver.enums.NpcInfoType;
import com.l2jmobius.gameserver.enums.Team; import com.l2jmobius.gameserver.enums.Team;
import com.l2jmobius.gameserver.model.actor.L2Summon; import com.l2jmobius.gameserver.model.actor.L2Summon;
import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance; import com.l2jmobius.gameserver.model.actor.instance.L2PcInstance;
import com.l2jmobius.gameserver.model.skills.AbnormalVisualEffect; import com.l2jmobius.gameserver.model.skills.AbnormalVisualEffect;
import com.l2jmobius.gameserver.model.zone.ZoneId; import com.l2jmobius.gameserver.model.zone.ZoneId;
import com.l2jmobius.gameserver.network.OutgoingPackets; import com.l2jmobius.gameserver.network.OutgoingPackets;
/** /**
* @author Sdw * @author Sdw
*/ */
public class SummonInfo extends AbstractMaskPacket<NpcInfoType> public class SummonInfo extends AbstractMaskPacket<NpcInfoType>
{ {
private final L2Summon _summon; private final L2Summon _summon;
private final L2PcInstance _attacker; private final L2PcInstance _attacker;
private final int _val; private final int _val;
private final byte[] _masks = new byte[] private final byte[] _masks = new byte[]
{ {
(byte) 0x00, (byte) 0x00,
(byte) 0x0C, (byte) 0x0C,
(byte) 0x0C, (byte) 0x0C,
(byte) 0x00, (byte) 0x00,
(byte) 0x00 (byte) 0x00
}; };
private int _initSize = 0; private int _initSize = 0;
private int _blockSize = 0; private int _blockSize = 0;
private int _clanCrest = 0; private int _clanCrest = 0;
private int _clanLargeCrest = 0; private int _clanLargeCrest = 0;
private int _allyCrest = 0; private int _allyCrest = 0;
private int _allyId = 0; private int _allyId = 0;
private int _clanId = 0; private int _clanId = 0;
private int _statusMask = 0; private int _statusMask = 0;
private final String _title; private final String _title;
private final Set<AbnormalVisualEffect> _abnormalVisualEffects; private final Set<AbnormalVisualEffect> _abnormalVisualEffects;
public SummonInfo(L2Summon summon, L2PcInstance attacker, int val) public SummonInfo(L2Summon summon, L2PcInstance attacker, int val)
{ {
_summon = summon; _summon = summon;
_attacker = attacker; _attacker = attacker;
_title = (summon.getOwner() != null) && summon.getOwner().isOnline() ? summon.getOwner().getName() : ""; _title = (summon.getOwner() != null) && summon.getOwner().isOnline() ? summon.getOwner().getName() : "";
_val = val; _val = val;
_abnormalVisualEffects = summon.getCurrentAbnormalVisualEffects(); _abnormalVisualEffects = summon.getCurrentAbnormalVisualEffects();
if (summon.getTemplate().getDisplayId() != summon.getTemplate().getId()) if (summon.getTemplate().getDisplayId() != summon.getTemplate().getId())
{ {
_masks[2] |= 0x10; _masks[2] |= 0x10;
addComponentType(NpcInfoType.NAME); addComponentType(NpcInfoType.NAME);
} }
addComponentType(NpcInfoType.ATTACKABLE, NpcInfoType.UNKNOWN1, NpcInfoType.TITLE, NpcInfoType.ID, NpcInfoType.POSITION, NpcInfoType.ALIVE, NpcInfoType.RUNNING); addComponentType(NpcInfoType.ATTACKABLE, NpcInfoType.UNKNOWN1, NpcInfoType.TITLE, NpcInfoType.ID, NpcInfoType.POSITION, NpcInfoType.ALIVE, NpcInfoType.RUNNING);
if (summon.getHeading() > 0) if (summon.getHeading() > 0)
{ {
addComponentType(NpcInfoType.HEADING); addComponentType(NpcInfoType.HEADING);
} }
if ((summon.getStat().getPAtkSpd() > 0) || (summon.getStat().getMAtkSpd() > 0)) if ((summon.getStat().getPAtkSpd() > 0) || (summon.getStat().getMAtkSpd() > 0))
{ {
addComponentType(NpcInfoType.ATK_CAST_SPEED); addComponentType(NpcInfoType.ATK_CAST_SPEED);
} }
if (summon.getRunSpeed() > 0) if (summon.getRunSpeed() > 0)
{ {
addComponentType(NpcInfoType.SPEED_MULTIPLIER); addComponentType(NpcInfoType.SPEED_MULTIPLIER);
} }
if ((summon.getWeapon() > 0) || (summon.getArmor() > 0)) if ((summon.getWeapon() > 0) || (summon.getArmor() > 0))
{ {
addComponentType(NpcInfoType.EQUIPPED); addComponentType(NpcInfoType.EQUIPPED);
} }
if (summon.getTeam() != Team.NONE) if (summon.getTeam() != Team.NONE)
{ {
addComponentType(NpcInfoType.TEAM); addComponentType(NpcInfoType.TEAM);
} }
if (summon.isInsideZone(ZoneId.WATER) || summon.isFlying()) if (summon.isInsideZone(ZoneId.WATER) || summon.isFlying())
{ {
addComponentType(NpcInfoType.SWIM_OR_FLY); addComponentType(NpcInfoType.SWIM_OR_FLY);
} }
if (summon.isFlying()) if (summon.isFlying())
{ {
addComponentType(NpcInfoType.FLYING); addComponentType(NpcInfoType.FLYING);
} }
if (summon.getMaxHp() > 0) if (summon.getMaxHp() > 0)
{ {
addComponentType(NpcInfoType.MAX_HP); addComponentType(NpcInfoType.MAX_HP);
} }
if (summon.getMaxMp() > 0) if (summon.getMaxMp() > 0)
{ {
addComponentType(NpcInfoType.MAX_MP); addComponentType(NpcInfoType.MAX_MP);
} }
if (summon.getCurrentHp() <= summon.getMaxHp()) if (summon.getCurrentHp() <= summon.getMaxHp())
{ {
addComponentType(NpcInfoType.CURRENT_HP); addComponentType(NpcInfoType.CURRENT_HP);
} }
if (summon.getCurrentMp() <= summon.getMaxMp()) if (summon.getCurrentMp() <= summon.getMaxMp())
{ {
addComponentType(NpcInfoType.CURRENT_MP); addComponentType(NpcInfoType.CURRENT_MP);
} }
if (!_abnormalVisualEffects.isEmpty()) if (!_abnormalVisualEffects.isEmpty())
{ {
addComponentType(NpcInfoType.ABNORMALS); addComponentType(NpcInfoType.ABNORMALS);
} }
if (summon.getTemplate().getWeaponEnchant() > 0) if (summon.getTemplate().getWeaponEnchant() > 0)
{ {
addComponentType(NpcInfoType.ENCHANT); addComponentType(NpcInfoType.ENCHANT);
} }
if (summon.getTransformationDisplayId() > 0) if (summon.getTransformationDisplayId() > 0)
{ {
addComponentType(NpcInfoType.TRANSFORMATION); addComponentType(NpcInfoType.TRANSFORMATION);
} }
if (summon.isShowSummonAnimation()) if (summon.isShowSummonAnimation())
{ {
addComponentType(NpcInfoType.SUMMONED); addComponentType(NpcInfoType.SUMMONED);
} }
if (summon.getOwner().getClan() != null) if (summon.getReputation() != 0)
{ {
_clanId = summon.getOwner().getAppearance().getVisibleClanId(); addComponentType(NpcInfoType.REPUTATION);
_clanCrest = summon.getOwner().getAppearance().getVisibleClanCrestId(); }
_clanLargeCrest = summon.getOwner().getAppearance().getVisibleClanLargeCrestId();
_allyCrest = summon.getOwner().getAppearance().getVisibleAllyId(); if (summon.getOwner().getClan() != null)
_allyId = summon.getOwner().getAppearance().getVisibleAllyCrestId(); {
_clanId = summon.getOwner().getAppearance().getVisibleClanId();
addComponentType(NpcInfoType.CLAN); _clanCrest = summon.getOwner().getAppearance().getVisibleClanCrestId();
} _clanLargeCrest = summon.getOwner().getAppearance().getVisibleClanLargeCrestId();
_allyCrest = summon.getOwner().getAppearance().getVisibleAllyId();
addComponentType(NpcInfoType.COLOR_EFFECT); _allyId = summon.getOwner().getAppearance().getVisibleAllyCrestId();
// TODO: Confirm me addComponentType(NpcInfoType.CLAN);
if (summon.isInCombat()) }
{
_statusMask |= 0x01; addComponentType(NpcInfoType.COLOR_EFFECT);
}
if (summon.isDead()) // TODO: Confirm me
{ if (summon.isInCombat())
_statusMask |= 0x02; {
} _statusMask |= 0x01;
if (summon.isTargetable()) }
{ if (summon.isDead())
_statusMask |= 0x04; {
} _statusMask |= 0x02;
}
_statusMask |= 0x08; if (summon.isTargetable())
{
if (_statusMask != 0) _statusMask |= 0x04;
{ }
addComponentType(NpcInfoType.VISUAL_STATE);
} _statusMask |= 0x08;
}
if (_statusMask != 0)
@Override {
protected byte[] getMasks() addComponentType(NpcInfoType.VISUAL_STATE);
{ }
return _masks; }
}
@Override
@Override protected byte[] getMasks()
protected void onNewMaskAdded(NpcInfoType component) {
{ return _masks;
calcBlockSize(_summon, component); }
}
@Override
private void calcBlockSize(L2Summon summon, NpcInfoType type) protected void onNewMaskAdded(NpcInfoType component)
{ {
switch (type) calcBlockSize(_summon, component);
{ }
case ATTACKABLE:
case UNKNOWN1: private void calcBlockSize(L2Summon summon, NpcInfoType type)
{ {
_initSize += type.getBlockLength(); switch (type)
break; {
} case ATTACKABLE:
case TITLE: case UNKNOWN1:
{ {
_initSize += type.getBlockLength() + (_title.length() * 2); _initSize += type.getBlockLength();
break; break;
} }
case NAME: case TITLE:
{ {
_blockSize += type.getBlockLength() + (summon.getName().length() * 2); _initSize += type.getBlockLength() + (_title.length() * 2);
break; break;
} }
default: case NAME:
{ {
_blockSize += type.getBlockLength(); _blockSize += type.getBlockLength() + (summon.getName().length() * 2);
break; break;
} }
} default:
} {
_blockSize += type.getBlockLength();
@Override break;
public boolean write(PacketWriter packet) }
{ }
OutgoingPackets.SUMMON_INFO.writeId(packet); }
packet.writeD(_summon.getObjectId()); @Override
packet.writeC(_val); // 0=teleported 1=default 2=summoned public boolean write(PacketWriter packet)
packet.writeH(37); // mask_bits_37 {
packet.writeB(_masks); OutgoingPackets.SUMMON_INFO.writeId(packet);
// Block 1 packet.writeD(_summon.getObjectId());
packet.writeC(_initSize); packet.writeC(_val); // 0=teleported 1=default 2=summoned
packet.writeH(37); // mask_bits_37
if (containsMask(NpcInfoType.ATTACKABLE)) packet.writeB(_masks);
{
packet.writeC(_summon.isAutoAttackable(_attacker) ? 0x01 : 0x00); // Block 1
} packet.writeC(_initSize);
if (containsMask(NpcInfoType.UNKNOWN1))
{ if (containsMask(NpcInfoType.ATTACKABLE))
packet.writeD(0x00); // unknown {
} packet.writeC(_summon.isAutoAttackable(_attacker) ? 0x01 : 0x00);
if (containsMask(NpcInfoType.TITLE)) }
{ if (containsMask(NpcInfoType.UNKNOWN1))
packet.writeS(_title); {
} packet.writeD(0x00); // unknown
}
// Block 2 if (containsMask(NpcInfoType.TITLE))
packet.writeH(_blockSize); {
if (containsMask(NpcInfoType.ID)) packet.writeS(_title);
{ }
packet.writeD(_summon.getTemplate().getDisplayId() + 1000000);
} // Block 2
if (containsMask(NpcInfoType.POSITION)) packet.writeH(_blockSize);
{ if (containsMask(NpcInfoType.ID))
packet.writeD(_summon.getX()); {
packet.writeD(_summon.getY()); packet.writeD(_summon.getTemplate().getDisplayId() + 1000000);
packet.writeD(_summon.getZ()); }
} if (containsMask(NpcInfoType.POSITION))
if (containsMask(NpcInfoType.HEADING)) {
{ packet.writeD(_summon.getX());
packet.writeD(_summon.getHeading()); packet.writeD(_summon.getY());
} packet.writeD(_summon.getZ());
if (containsMask(NpcInfoType.UNKNOWN2)) }
{ if (containsMask(NpcInfoType.HEADING))
packet.writeD(0x00); // Unknown {
} packet.writeD(_summon.getHeading());
if (containsMask(NpcInfoType.ATK_CAST_SPEED)) }
{ if (containsMask(NpcInfoType.UNKNOWN2))
packet.writeD(_summon.getPAtkSpd()); {
packet.writeD(_summon.getMAtkSpd()); packet.writeD(0x00); // Unknown
} }
if (containsMask(NpcInfoType.SPEED_MULTIPLIER)) if (containsMask(NpcInfoType.ATK_CAST_SPEED))
{ {
packet.writeE((float) _summon.getStat().getMovementSpeedMultiplier()); packet.writeD(_summon.getPAtkSpd());
packet.writeE(_summon.getStat().getAttackSpeedMultiplier()); packet.writeD(_summon.getMAtkSpd());
} }
if (containsMask(NpcInfoType.EQUIPPED)) if (containsMask(NpcInfoType.SPEED_MULTIPLIER))
{ {
packet.writeD(_summon.getWeapon()); packet.writeE((float) _summon.getStat().getMovementSpeedMultiplier());
packet.writeD(_summon.getArmor()); // Armor id? packet.writeE(_summon.getStat().getAttackSpeedMultiplier());
packet.writeD(0x00); }
} if (containsMask(NpcInfoType.EQUIPPED))
if (containsMask(NpcInfoType.ALIVE)) {
{ packet.writeD(_summon.getWeapon());
packet.writeC(_summon.isDead() ? 0x00 : 0x01); packet.writeD(_summon.getArmor()); // Armor id?
} packet.writeD(0x00);
if (containsMask(NpcInfoType.RUNNING)) }
{ if (containsMask(NpcInfoType.ALIVE))
packet.writeC(_summon.isRunning() ? 0x01 : 0x00); {
} packet.writeC(_summon.isDead() ? 0x00 : 0x01);
if (containsMask(NpcInfoType.SWIM_OR_FLY)) }
{ if (containsMask(NpcInfoType.RUNNING))
packet.writeC(_summon.isInsideZone(ZoneId.WATER) ? 0x01 : _summon.isFlying() ? 0x02 : 0x00); {
} packet.writeC(_summon.isRunning() ? 0x01 : 0x00);
if (containsMask(NpcInfoType.TEAM)) }
{ if (containsMask(NpcInfoType.SWIM_OR_FLY))
packet.writeC(_summon.getTeam().getId()); {
} packet.writeC(_summon.isInsideZone(ZoneId.WATER) ? 0x01 : _summon.isFlying() ? 0x02 : 0x00);
if (containsMask(NpcInfoType.ENCHANT)) }
{ if (containsMask(NpcInfoType.TEAM))
packet.writeD(_summon.getTemplate().getWeaponEnchant()); {
} packet.writeC(_summon.getTeam().getId());
if (containsMask(NpcInfoType.FLYING)) }
{ if (containsMask(NpcInfoType.ENCHANT))
packet.writeD(_summon.isFlying() ? 0x01 : 00); {
} packet.writeD(_summon.getTemplate().getWeaponEnchant());
if (containsMask(NpcInfoType.CLONE)) }
{ if (containsMask(NpcInfoType.FLYING))
packet.writeD(0x00); // Player ObjectId with Decoy {
} packet.writeD(_summon.isFlying() ? 0x01 : 00);
if (containsMask(NpcInfoType.COLOR_EFFECT)) }
{ if (containsMask(NpcInfoType.CLONE))
// No visual effect {
packet.writeD(0x00); // Unknown packet.writeD(0x00); // Player ObjectId with Decoy
} }
if (containsMask(NpcInfoType.DISPLAY_EFFECT)) if (containsMask(NpcInfoType.COLOR_EFFECT))
{ {
packet.writeD(0x00); // No visual effect
} packet.writeD(0x00); // Unknown
if (containsMask(NpcInfoType.TRANSFORMATION)) }
{ if (containsMask(NpcInfoType.DISPLAY_EFFECT))
packet.writeD(_summon.getTransformationDisplayId()); // Transformation ID {
} packet.writeD(0x00);
if (containsMask(NpcInfoType.CURRENT_HP)) }
{ if (containsMask(NpcInfoType.TRANSFORMATION))
packet.writeD((int) _summon.getCurrentHp()); {
} packet.writeD(_summon.getTransformationDisplayId()); // Transformation ID
if (containsMask(NpcInfoType.CURRENT_MP)) }
{ if (containsMask(NpcInfoType.CURRENT_HP))
packet.writeD((int) _summon.getCurrentMp()); {
} packet.writeD((int) _summon.getCurrentHp());
if (containsMask(NpcInfoType.MAX_HP)) }
{ if (containsMask(NpcInfoType.CURRENT_MP))
packet.writeD(_summon.getMaxHp()); {
} packet.writeD((int) _summon.getCurrentMp());
if (containsMask(NpcInfoType.MAX_MP)) }
{ if (containsMask(NpcInfoType.MAX_HP))
packet.writeD(_summon.getMaxMp()); {
} packet.writeD(_summon.getMaxHp());
if (containsMask(NpcInfoType.SUMMONED)) }
{ if (containsMask(NpcInfoType.MAX_MP))
packet.writeC(_summon.isShowSummonAnimation() ? 0x02 : 00); // 2 - do some animation on spawn {
} packet.writeD(_summon.getMaxMp());
if (containsMask(NpcInfoType.UNKNOWN12)) }
{ if (containsMask(NpcInfoType.SUMMONED))
packet.writeD(0x00); {
packet.writeD(0x00); packet.writeC(_summon.isShowSummonAnimation() ? 0x02 : 00); // 2 - do some animation on spawn
} }
if (containsMask(NpcInfoType.NAME)) if (containsMask(NpcInfoType.UNKNOWN12))
{ {
packet.writeS(_summon.getName()); packet.writeD(0x00);
} packet.writeD(0x00);
if (containsMask(NpcInfoType.NAME_NPCSTRINGID)) }
{ if (containsMask(NpcInfoType.NAME))
packet.writeD(-1); // NPCStringId for name {
} packet.writeS(_summon.getName());
if (containsMask(NpcInfoType.TITLE_NPCSTRINGID)) }
{ if (containsMask(NpcInfoType.NAME_NPCSTRINGID))
packet.writeD(-1); // NPCStringId for title {
} packet.writeD(-1); // NPCStringId for name
if (containsMask(NpcInfoType.PVP_FLAG)) }
{ if (containsMask(NpcInfoType.TITLE_NPCSTRINGID))
packet.writeC(_summon.getPvpFlag()); // PVP flag {
} packet.writeD(-1); // NPCStringId for title
if (containsMask(NpcInfoType.NAME_COLOR)) }
{ if (containsMask(NpcInfoType.PVP_FLAG))
packet.writeD(0x00); // Name color {
} packet.writeC(_summon.getPvpFlag()); // PVP flag
if (containsMask(NpcInfoType.CLAN)) }
{ if (containsMask(NpcInfoType.REPUTATION))
packet.writeD(_clanId); {
packet.writeD(_clanCrest); packet.writeD(_summon.getReputation()); // Name color
packet.writeD(_clanLargeCrest); }
packet.writeD(_allyId); if (containsMask(NpcInfoType.CLAN))
packet.writeD(_allyCrest); {
} packet.writeD(_clanId);
packet.writeD(_clanCrest);
if (containsMask(NpcInfoType.VISUAL_STATE)) packet.writeD(_clanLargeCrest);
{ packet.writeD(_allyId);
packet.writeC(_statusMask); packet.writeD(_allyCrest);
} }
if (containsMask(NpcInfoType.ABNORMALS)) if (containsMask(NpcInfoType.VISUAL_STATE))
{ {
packet.writeH(_abnormalVisualEffects.size()); packet.writeC(_statusMask);
for (AbnormalVisualEffect abnormalVisualEffect : _abnormalVisualEffects) }
{
packet.writeH(abnormalVisualEffect.getClientId()); if (containsMask(NpcInfoType.ABNORMALS))
} {
} packet.writeH(_abnormalVisualEffects.size());
return true; for (AbnormalVisualEffect abnormalVisualEffect : _abnormalVisualEffects)
} {
packet.writeH(abnormalVisualEffect.getClientId());
}
}
return true;
}
} }

View File

@@ -62,7 +62,7 @@ public enum NpcInfoType implements IUpdateTypeComponent
// 4 // 4
TITLE_NPCSTRINGID(0x20, 4), TITLE_NPCSTRINGID(0x20, 4),
PVP_FLAG(0x21, 1), PVP_FLAG(0x21, 1),
NAME_COLOR(0x22, 4), REPUTATION(0x22, 4),
CLAN(0x23, (5 * 4)), CLAN(0x23, (5 * 4)),
ABNORMALS(0x24, 0), ABNORMALS(0x24, 0),
VISUAL_STATE(0x25, 1); VISUAL_STATE(0x25, 1);

View File

@@ -191,20 +191,19 @@ public abstract class L2Summon extends L2Playable
{ {
L2World.getInstance().forEachVisibleObject(this, L2PcInstance.class, player -> L2World.getInstance().forEachVisibleObject(this, L2PcInstance.class, player ->
{ {
if (player == getOwner())
{
player.sendPacket(new PetInfo(this, 1));
return;
}
if (isPet()) if (isPet())
{ {
player.sendPacket(new ExPetInfo(this, player, 1)); player.sendPacket(new ExPetInfo(this, player, 1));
} }
else else
{ {
if (player == getOwner()) player.sendPacket(new SummonInfo(this, player, 1));
{
player.sendPacket(new PetInfo(this, 1));
}
else
{
player.sendPacket(new SummonInfo(this, player, 1));
}
} }
}); });
} }
@@ -364,6 +363,8 @@ public abstract class L2Summon extends L2Playable
public void deleteMe(L2PcInstance owner) public void deleteMe(L2PcInstance owner)
{ {
super.deleteMe();
if (owner != null) if (owner != null)
{ {
owner.sendPacket(new PetDelete(getSummonType(), getObjectId())); owner.sendPacket(new PetDelete(getSummonType(), getObjectId()));
@@ -372,16 +373,7 @@ public abstract class L2Summon extends L2Playable
{ {
party.broadcastToPartyMembers(owner, new ExPartyPetWindowDelete(this)); party.broadcastToPartyMembers(owner, new ExPartyPetWindowDelete(this));
} }
}
// pet will be deleted along with all his items
if (getInventory() != null)
{
getInventory().destroyAllItems("pet deleted", getOwner(), this);
}
decayMe();
if (owner != null)
{
if (isPet()) if (isPet())
{ {
owner.setPet(null); owner.setPet(null);
@@ -391,7 +383,13 @@ public abstract class L2Summon extends L2Playable
owner.removeServitor(getObjectId()); owner.removeServitor(getObjectId());
} }
} }
super.deleteMe();
// pet will be deleted along with all his items
if (getInventory() != null)
{
getInventory().destroyAllItems("pet deleted", getOwner(), this);
}
decayMe();
} }
public void unSummon(L2PcInstance owner) public void unSummon(L2PcInstance owner)
@@ -842,7 +840,7 @@ public abstract class L2Summon extends L2Playable
// Check if the L2PcInstance is the owner of the Pet // Check if the L2PcInstance is the owner of the Pet
if (activeChar == getOwner()) if (activeChar == getOwner())
{ {
activeChar.sendPacket(new PetInfo(this, 1)); activeChar.sendPacket(new PetInfo(this, isDead() ? 0 : 1));
// The PetInfo packet wipes the PartySpelled (list of active spells' icons). Re-add them // The PetInfo packet wipes the PartySpelled (list of active spells' icons). Re-add them
updateEffectIcons(true); updateEffectIcons(true);
if (isPet()) if (isPet())

View File

@@ -147,6 +147,11 @@ public class ExPetInfo extends AbstractMaskPacket<NpcInfoType>
addComponentType(NpcInfoType.SUMMONED); addComponentType(NpcInfoType.SUMMONED);
} }
if (summon.getReputation() != 0)
{
addComponentType(NpcInfoType.REPUTATION);
}
if (summon.getOwner().getClan() != null) if (summon.getOwner().getClan() != null)
{ {
_clanId = summon.getOwner().getAppearance().getVisibleClanId(); _clanId = summon.getOwner().getAppearance().getVisibleClanId();
@@ -366,9 +371,9 @@ public class ExPetInfo extends AbstractMaskPacket<NpcInfoType>
{ {
packet.writeC(_summon.getPvpFlag()); // PVP flag packet.writeC(_summon.getPvpFlag()); // PVP flag
} }
if (containsMask(NpcInfoType.NAME_COLOR)) if (containsMask(NpcInfoType.REPUTATION))
{ {
packet.writeD(0x00); // Name color packet.writeD(_summon.getReputation()); // Name color
} }
if (containsMask(NpcInfoType.CLAN)) if (containsMask(NpcInfoType.CLAN))
{ {

View File

@@ -400,7 +400,7 @@ public class NpcInfo extends AbstractMaskPacket<NpcInfoType>
{ {
packet.writeC(_npc.getPvpFlag()); // PVP flag packet.writeC(_npc.getPvpFlag()); // PVP flag
} }
if (containsMask(NpcInfoType.NAME_COLOR)) if (containsMask(NpcInfoType.REPUTATION))
{ {
packet.writeD(0x00); // Name color packet.writeD(0x00); // Name color
} }

View File

@@ -65,8 +65,11 @@ public class PetInfo implements IClientOutgoingPacket
_maxFed = sum.getLifeTime(); _maxFed = sum.getLifeTime();
} }
// _statusMask |= 0x01; // Auto attackable status if (summon.isBetrayed())
// _statusMask |= 0x02; // can be chatted with {
_statusMask |= 0x01; // Auto attackable status
}
_statusMask |= 0x02; // can be chatted with
if (summon.isRunning()) if (summon.isRunning())
{ {

View File

@@ -147,6 +147,11 @@ public class SummonInfo extends AbstractMaskPacket<NpcInfoType>
addComponentType(NpcInfoType.SUMMONED); addComponentType(NpcInfoType.SUMMONED);
} }
if (summon.getReputation() != 0)
{
addComponentType(NpcInfoType.REPUTATION);
}
if (summon.getOwner().getClan() != null) if (summon.getOwner().getClan() != null)
{ {
_clanId = summon.getOwner().getAppearance().getVisibleClanId(); _clanId = summon.getOwner().getAppearance().getVisibleClanId();
@@ -366,9 +371,9 @@ public class SummonInfo extends AbstractMaskPacket<NpcInfoType>
{ {
packet.writeC(_summon.getPvpFlag()); // PVP flag packet.writeC(_summon.getPvpFlag()); // PVP flag
} }
if (containsMask(NpcInfoType.NAME_COLOR)) if (containsMask(NpcInfoType.REPUTATION))
{ {
packet.writeD(0x00); // Name color packet.writeD(_summon.getReputation()); // Name color
} }
if (containsMask(NpcInfoType.CLAN)) if (containsMask(NpcInfoType.CLAN))
{ {