Created
January 10, 2014 00:27
-
-
Save aadnk/8344761 to your computer and use it in GitHub Desktop.
FakeWither for 1.7.2. Remember to add the appropriate classes from PacketWrapper.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.comphenix.example; | |
import com.comphenix.protocol.events.PacketContainer; | |
import java.lang.reflect.InvocationTargetException; | |
import java.util.logging.Level; | |
import org.bukkit.Bukkit; | |
import org.bukkit.Location; | |
import org.bukkit.entity.EntityType; | |
import org.bukkit.entity.Player; | |
import com.comphenix.protocol.ProtocolManager; | |
import com.comphenix.protocol.wrappers.WrappedDataWatcher; | |
// You could also use a full-fledged API like RemoteEntities | |
public class FakeWither { | |
public static final byte INVISIBLE = 0x20; | |
// Just a guess | |
private static final int HEALTH_RANGE = 80 * 80; | |
// Next entity ID | |
private static int NEXT_ID = 6000; | |
private static final int METADATA_WITHER_HEALTH = 6; // 1.5.2 -> Change to 16 | |
// Metadata indices | |
private static final int METADATA_FLAGS = 0; | |
private static final int METADATA_NAME = 10; // 1.5.2 -> Change to 5 | |
private static final int METADATA_SHOW_NAME = 11; // 1.5.2 -> Change to 6 | |
// Unique ID | |
private int id = NEXT_ID++; | |
// Default health | |
private int health = 300; | |
private boolean visible; | |
private String customName; | |
private boolean created; | |
private Location location; | |
private ProtocolManager manager; | |
public FakeWither(Location location, ProtocolManager manager) { | |
this.location = location; | |
this.manager = manager; | |
} | |
public int getHealth() { | |
return health; | |
} | |
public void setHealth(int health) { | |
// Update the health of the entity | |
if (created) { | |
WrappedDataWatcher watcher = new WrappedDataWatcher(); | |
watcher.setObject(METADATA_WITHER_HEALTH, (float) health); // 1.5.2 -> Change to (int) | |
sendMetadata(watcher); | |
} | |
this.health = health; | |
} | |
public void setVisible(boolean visible) { | |
// Make visible or invisible | |
if (created) { | |
WrappedDataWatcher watcher = new WrappedDataWatcher(); | |
watcher.setObject(METADATA_FLAGS, visible ? (byte)0 : INVISIBLE); | |
sendMetadata(watcher); | |
} | |
this.visible = visible; | |
} | |
public void setCustomName(String name) { | |
if (created) { | |
WrappedDataWatcher watcher = new WrappedDataWatcher(); | |
if (name != null) { | |
watcher.setObject(METADATA_NAME, name); | |
watcher.setObject(METADATA_SHOW_NAME, (byte) 1); | |
} else { | |
// Hide custom name | |
watcher.setObject(METADATA_SHOW_NAME, (byte) 0); | |
} | |
// Only players nearby when this is sent will see this name | |
sendMetadata(watcher); | |
} | |
this.customName = name; | |
} | |
private void sendMetadata(WrappedDataWatcher watcher) { | |
WrapperPlayServerEntityMetadata update = new WrapperPlayServerEntityMetadata(); | |
update.setEntityId(id); | |
update.setEntityMetadata(watcher.getWatchableObjects()); | |
broadcastPacket(update.getHandle(), true); | |
} | |
public int getId() { | |
return id; | |
} | |
public void create() { | |
WrapperPlayServerSpawnEntityLiving spawnMob = new WrapperPlayServerSpawnEntityLiving(); | |
WrappedDataWatcher watcher = new WrappedDataWatcher(); | |
watcher.setObject(METADATA_FLAGS, visible ? (byte)0 : INVISIBLE); | |
watcher.setObject(METADATA_WITHER_HEALTH, (float) health); // 1.5.2 -> Change to (int) | |
if (customName != null) { | |
watcher.setObject(METADATA_NAME, customName); | |
watcher.setObject(METADATA_SHOW_NAME, (byte) 1); | |
} | |
spawnMob.setEntityID(id); | |
spawnMob.setType(EntityType.WITHER); | |
spawnMob.setX(location.getX()); | |
spawnMob.setY(location.getY()); | |
spawnMob.setZ(location.getZ()); | |
spawnMob.setMetadata(watcher); | |
broadcastPacket(spawnMob.getHandle(), true); | |
created = true; | |
} | |
public void destroy() { | |
if (!created) | |
throw new IllegalStateException("Cannot kill a killed entity."); | |
WrapperPlayServerEntityDestroy destroyMe = new WrapperPlayServerEntityDestroy(); | |
destroyMe.setEntities(new int[] { id }); | |
broadcastPacket(destroyMe.getHandle(), false); | |
created = false; | |
} | |
private void broadcastPacket(PacketContainer packet, boolean onlyNearby) { | |
for (Player player : Bukkit.getServer().getOnlinePlayers()) { | |
// Must be within the range | |
if (!onlyNearby || player.getLocation().distanceSquared(location) < HEALTH_RANGE) { | |
try { | |
manager.sendServerPacket(player, packet); | |
} catch (InvocationTargetException e) { | |
Bukkit.getLogger().log(Level.WARNING, "Cannot send " + packet + " to " + player, e); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment