Skip to content

Instantly share code, notes, and snippets.

@aadnk
Created January 10, 2014 00:27
Show Gist options
  • Save aadnk/8344761 to your computer and use it in GitHub Desktop.
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.
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