64public final class SendNpcUpdate
extends OutgoingPacket {
66 public SendNpcUpdate() {
71 public boolean encode(
Player player) {
77 for (Iterator<Npc> itr = player.viewport.
getNpcsInViewport().iterator(); itr.hasNext(); ) {
82 if (npc.atomicPlayerCount.decrementAndGet() < 0) {
83 npc.atomicPlayerCount.set(0);
86 builder.writeBits(1, 1);
87 builder.writeBits(2, 3);
89 updateMovement(builder, npc);
92 updateNpc(maskBuf, npc);
106 if (player.viewport.
add(localNpc)) {
108 addNewNpc(builder, player, localNpc);
109 updateNpc(maskBuf, localNpc);
111 if (localNpc.atomicPlayerCount.incrementAndGet() < 0) {
112 localNpc.atomicPlayerCount.set(0);
118 if (maskBuf.content().readableBytes() > 0) {
119 builder.writeBits(16, 65535);
121 builder.writeBytes(maskBuf.content());
126 }
catch (Exception ex) {
127 ex.printStackTrace();
135 packet.writeBits(16, npc.getIndex());
138 packet.writeBit(
false);
146 final Movement movement = npc.movement;
147 final int runDirection = movement.getRunningDirection();
148 final int walkDirection = movement.getWalkingDirection();
150 if (runDirection != -1) {
151 packet.writeBit(
true)
153 .writeBits(3, walkDirection)
154 .writeBits(3, runDirection)
155 .writeBit(updateRequired);
156 }
else if (walkDirection != -1) {
157 packet.writeBit(
true)
159 .writeBits(3, walkDirection)
160 .writeBit(updateRequired);
162 packet.writeBit(updateRequired);
163 if (updateRequired) {
164 packet.writeBits(2, 0);
176 final EnumSet<UpdateFlag> updateFlags = npc.updateFlags;
178 if (updateFlags.contains(flag) && flag.canApply(npc)) {
179 mask |= flag.npcMask;
183 maskBuf.writeByte(mask);
193 appendAnimationMask(npc, maskBuf);
197 appendGfxMask(npc, maskBuf);
201 appendFaceEntityMask(npc, maskBuf);
205 appendForceChatMask(npc, maskBuf);
209 appendFirstHitMask(npc, maskBuf);
213 appendSecondHitMask(npc, maskBuf);
217 appendTransformationMask(npc, maskBuf);
221 appendFaceCoordinateMask(npc, maskBuf);
234 maskBuf.writeShort(gfx.
getId())
239 Mob mob = npc.interactingWith;
242 index = mob.getIndex();
246 maskBuf.writeShort(index);
248 maskBuf.writeShort(index);
253 maskBuf.writeString(npc.forceChat);
256 private static void appendFaceCoordinateMask(
Npc npc,
PacketBuilder maskBuf) {
261 maskBuf.writeShort(((currentPos.
getX() + currentDir.getDirectionX()) << 1) + 1,
ByteOrder.
LE)
262 .writeShort(((currentPos.
getY() + currentDir.getDirectionY()) << 1) + 1,
ByteOrder.
LE);
269 private static void appendTransformationMask(
Npc npc,
PacketBuilder maskBuf) {
273 private static void appendFirstHitMask(
final Npc npc,
final PacketBuilder updateBlock) {
274 Hit hit = npc.firstHit;
276 boolean multipleHits = hit.getMultipleHits() !=
null;
277 updateBlock.writeByte(multipleHits ? 1 : 0);
279 int max = npc.getMaximumHealth() >= 500 ? 200 : 100;
280 int health = npc.getCurrentHealth() * max / npc.getMaximumHealth();
281 if (health > max) health = max;
284 System.out.println(
"total 1 = " + hit.getMultipleHits().length);
285 updateBlock.writeByte(hit.getMultipleHits().length);
287 for(
int index = 0; index < hit.getMultipleHits().length; index++) {
288 Hit currentHit = hit.getMultipleHits()[index];
296 updateBlock.writeByte(currentHit.
getDamage());
297 updateBlock.writeByte(
id);
310 updateBlock.writeByte(
id);
314 updateBlock.writeByte(health);
315 updateBlock.writeByte(max);
333 private static void appendSecondHitMask(
final Npc npc,
final PacketBuilder updateBlock) {
334 Hit hit = npc.secondHit;
336 Hit[] multipleHits = hit.getMultipleHits();
337 boolean isMultipleHits = multipleHits !=
null;
338 Hit[] multipleHitsArray = isMultipleHits ? Arrays.copyOf(multipleHits, multipleHits.length) :
null;
339 updateBlock.writeByte(isMultipleHits ? 1 : 0);
341 int max = npc.getMaximumHealth() >= 500 ? 200 : 100;
342 int health = npc.getCurrentHealth() * max / npc.getMaximumHealth();
343 if (health > max) health = max;
346 updateBlock.writeByte(multipleHitsArray.length);
347 for (
Hit currentHit : multipleHitsArray) {
348 int id = currentHit.getHitsplat().getId();
351 && currentHit.getDamage() > 0) {
355 updateBlock.writeByte(currentHit.getDamage());
356 updateBlock.writeByte(
id);
357 updateBlock.writeByte(currentHit.getHitIcon().getId());
368 updateBlock.writeByte(
id);
372 updateBlock.writeByte(health);
373 updateBlock.writeByte(max);