Skip to content

Instantly share code, notes, and snippets.

@yannicklamprecht
Last active June 17, 2024 20:17
Show Gist options
  • Save yannicklamprecht/639acba127a54f5617e1281f099b7aff to your computer and use it in GitHub Desktop.
Save yannicklamprecht/639acba127a54f5617e1281f099b7aff to your computer and use it in GitHub Desktop.
private Map<UUID, DisguiseData> uuidDisguiseDataMap = new HashMap<>();
@EventHandler
public void onPlayerInteract(PlayerInteractEvent playerInteractEvent) {
if (playerInteractEvent.getAction().isLeftClick() || playerInteractEvent.getAction() == Action.RIGHT_CLICK_AIR) {
return;
}
if (!playerInteractEvent.hasItem()) {
return;
}
var stack = playerInteractEvent.getItem();
if (stack == null) {
return;
}
if (playerInteractEvent.getInteractionPoint() == null) {
return;
}
var player = playerInteractEvent.getPlayer();
if (stack.getItemMeta() instanceof SpawnEggMeta) {
final Class<? extends Entity> entityClass = forStack(stack).orElse(Zombie.class);
spawnPlayerLikeEntity(player, entityClass, playerInteractEvent.getInteractionPoint());
playerInteractEvent.setCancelled(true);
} else if (stack.getItemMeta() instanceof ArmorStandMeta) {
spawnPlayerLikeEntity(player, ArmorStand.class, playerInteractEvent.getInteractionPoint());
playerInteractEvent.setCancelled(true);
}
}
@EventHandler
public void onEntitiesLoad(EntitiesLoadEvent event) {
for (final Entity entity : event.getEntities()) {
final DisguiseData data = uuidDisguiseDataMap.get(entity.getUniqueId());
if(data != null) {
entity.setDisguiseData(data);
}
}
}
private Optional<Class<? extends Entity>> forStack(ItemStack stack) {
if (stack.getItemMeta() instanceof SpawnEggMeta) {
Class<? extends Entity> type = switch (stack.getType()) {
case Material.ARMADILLO_SPAWN_EGG -> Armadillo.class;
case Material.ALLAY_SPAWN_EGG -> Allay.class;
case Material.AXOLOTL_SPAWN_EGG -> Axolotl.class;
case Material.BAT_SPAWN_EGG -> Bat.class;
case Material.BEE_SPAWN_EGG -> Bee.class;
case Material.BLAZE_SPAWN_EGG -> Blaze.class;
case Material.BOGGED_SPAWN_EGG -> Bogged.class;
case Material.BREEZE_SPAWN_EGG -> Breeze.class;
case Material.CAT_SPAWN_EGG -> Cat.class;
case Material.CAMEL_SPAWN_EGG -> Camel.class;
case Material.CAVE_SPIDER_SPAWN_EGG -> CaveSpider.class;
case Material.CHICKEN_SPAWN_EGG -> Chicken.class;
case Material.COD_SPAWN_EGG -> Cod.class;
case Material.COW_SPAWN_EGG -> Cow.class;
case Material.CREEPER_SPAWN_EGG -> Creeper.class;
case Material.DOLPHIN_SPAWN_EGG -> Dolphin.class;
case Material.DONKEY_SPAWN_EGG -> Donkey.class;
case Material.DROWNED_SPAWN_EGG -> Drowned.class;
case Material.ELDER_GUARDIAN_SPAWN_EGG -> ElderGuardian.class;
case Material.ENDER_DRAGON_SPAWN_EGG -> EnderDragon.class;
case Material.ENDERMAN_SPAWN_EGG -> Enderman.class;
case Material.ENDERMITE_SPAWN_EGG -> Endermite.class;
case Material.EVOKER_SPAWN_EGG -> Evoker.class;
case Material.FOX_SPAWN_EGG -> Fox.class;
case Material.FROG_SPAWN_EGG -> Frog.class;
case Material.GHAST_SPAWN_EGG -> Ghast.class;
case Material.GLOW_SQUID_SPAWN_EGG -> GlowSquid.class;
case Material.GOAT_SPAWN_EGG -> Goat.class;
case Material.GUARDIAN_SPAWN_EGG -> Guardian.class;
case Material.HOGLIN_SPAWN_EGG -> Hoglin.class;
case Material.HORSE_SPAWN_EGG -> Horse.class;
case Material.HUSK_SPAWN_EGG -> Husk.class;
case Material.IRON_GOLEM_SPAWN_EGG -> IronGolem.class;
case Material.LLAMA_SPAWN_EGG -> Llama.class;
case Material.MAGMA_CUBE_SPAWN_EGG -> MagmaCube.class;
case Material.MOOSHROOM_SPAWN_EGG -> EntityType.MOOSHROOM.getEntityClass();
case Material.MULE_SPAWN_EGG -> Mule.class;
case Material.OCELOT_SPAWN_EGG -> Ocelot.class;
case Material.PANDA_SPAWN_EGG -> Panda.class;
case Material.PARROT_SPAWN_EGG -> Parrot.class;
case Material.PHANTOM_SPAWN_EGG -> Phantom.class;
case Material.PIGLIN_BRUTE_SPAWN_EGG -> PiglinBrute.class;
case Material.PIGLIN_SPAWN_EGG -> Piglin.class;
case Material.PIG_SPAWN_EGG -> Pig.class;
case Material.PILLAGER_SPAWN_EGG -> Pillager.class;
case Material.POLAR_BEAR_SPAWN_EGG -> PolarBear.class;
case Material.PUFFERFISH_SPAWN_EGG -> EntityType.PUFFERFISH.getEntityClass();
case Material.RABBIT_SPAWN_EGG -> Rabbit.class;
case Material.RAVAGER_SPAWN_EGG -> Ravager.class;
case Material.SALMON_SPAWN_EGG -> Salmon.class;
case Material.SHEEP_SPAWN_EGG -> Sheep.class;
case Material.SHULKER_SPAWN_EGG -> Shulker.class;
case Material.SILVERFISH_SPAWN_EGG -> Silverfish.class;
case Material.SKELETON_HORSE_SPAWN_EGG -> SkeletonHorse.class;
case Material.SKELETON_SPAWN_EGG -> Skeleton.class;
case Material.SLIME_SPAWN_EGG -> Slime.class;
case Material.SNIFFER_SPAWN_EGG -> Sniffer.class;
case Material.SNOW_GOLEM_SPAWN_EGG -> EntityType.SNOW_GOLEM.getEntityClass();
case Material.SPIDER_SPAWN_EGG -> Spider.class;
case Material.SQUID_SPAWN_EGG -> Squid.class;
case Material.STRAY_SPAWN_EGG -> Stray.class;
case Material.STRIDER_SPAWN_EGG -> Strider.class;
case Material.TADPOLE_SPAWN_EGG -> Turtle.class;
case Material.TRADER_LLAMA_SPAWN_EGG -> TraderLlama.class;
case Material.TROPICAL_FISH_SPAWN_EGG -> TropicalFish.class;
case Material.TURTLE_SPAWN_EGG -> Turtle.class;
case Material.VEX_SPAWN_EGG -> Vex.class;
case Material.VILLAGER_SPAWN_EGG -> Villager.class;
case Material.VINDICATOR_SPAWN_EGG -> Vindicator.class;
case Material.WARDEN_SPAWN_EGG -> Warden.class;
case Material.WANDERING_TRADER_SPAWN_EGG -> WanderingTrader.class;
case Material.WITCH_SPAWN_EGG -> Witch.class;
case Material.WITHER_SPAWN_EGG -> Wither.class;
case Material.WITHER_SKELETON_SPAWN_EGG -> WitherSkeleton.class;
case Material.WOLF_SPAWN_EGG -> Wolf.class;
case Material.ZOGLIN_SPAWN_EGG -> Zoglin.class;
case Material.ZOMBIE_HORSE_SPAWN_EGG -> ZombieHorse.class;
case Material.ZOMBIE_SPAWN_EGG -> Zombie.class;
case Material.ZOMBIE_VILLAGER_SPAWN_EGG -> ZombieVillager.class;
case Material.ZOMBIFIED_PIGLIN_SPAWN_EGG -> EntityType.ZOMBIFIED_PIGLIN.getEntityClass();
default -> null;
};
return Optional.ofNullable(type);
}
return Optional.empty();
}
private void spawnPlayerLikeEntity(Player player, Class<? extends Entity> entityClass, Location location) {
player.getWorld().spawn(location, entityClass, entity -> {
var disguiseData = DisguiseData
.player(player.getPlayerProfile()).listed(false)
.skinParts(Bukkit.getServer().newSkinPartsBuilder().withJacket(true).withCape(true).withHat(true).build())
.build();
uuidDisguiseDataMap.put(entity.getUniqueId(), disguiseData);
entity.setDisguiseData(disguiseData);
entity.customName(Component.text("Gollum"));
Scoreboard scoreboard = player.getScoreboard();
Team team = scoreboard.getTeam("test");
if (team == null) {
team = scoreboard.registerNewTeam("test");
}
team.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS);
team.addEntry(entity.getScoreboardEntryName());
team.prefix(Component.text("Happy Coding ", NamedTextColor.GOLD));
team.suffix(Component.text(" :D", NamedTextColor.RED));
team.addEntry(entity.getName());
});
}
@EventHandler
public void onSpawn(PlayerInteractEvent playerInteractEvent) {
if (playerInteractEvent.getAction().isLeftClick() || playerInteractEvent.getAction() == Action.RIGHT_CLICK_AIR) {
return;
}
if (!playerInteractEvent.hasItem()) {
return;
}
var stack = playerInteractEvent.getItem();
if (stack == null || !(MaterialTags.SPAWN_EGGS.isTagged(stack) || stack.getType() == Material.ARMOR_STAND)) {
return;
}
if (playerInteractEvent.getInteractionPoint() == null) {
return;
}
var player = playerInteractEvent.getPlayer();
switch (stack.getType()) {
case ARMOR_STAND -> spawnOtherEntity(ArmorStand.class, DisguiseData.entity(EntityType.BEE), playerInteractEvent.getInteractionPoint());
case SHULKER_SPAWN_EGG -> spawnPlayerLikeEntity(player, Shulker.class, playerInteractEvent.getInteractionPoint());
};
playerInteractEvent.setCancelled(true);
}
private void spawnOtherEntity(Class<? extends Entity> entityClass, EntityTypeDisguise entityTypeDisguise, Location location) {
location.getWorld().spawn(location, entityClass, entity -> {
entity.setDisguiseData(entityTypeDisguise);
});
}
private void spawnPlayerLikeEntity(Player player, Class<? extends Entity> entityClass, Location location) {
player.getWorld().spawn(location, entityClass, entity -> {
entity.setDisguiseData(DisguiseData
.player(player.getPlayerProfile()).listed(false)
.skinParts(Bukkit.getServer().newSkinPartsBuilder().withJacket(true).withCape(true).withHat(true).build())
.build());
entity.customName(Component.text("Gollum"));
Scoreboard scoreboard = player.getScoreboard();
Team team = scoreboard.getTeam("test");
if (team == null) {
team = scoreboard.registerNewTeam("test");
}
team.setOption(Team.Option.NAME_TAG_VISIBILITY, Team.OptionStatus.ALWAYS);
team.addEntry(entity.getScoreboardEntryName());
team.prefix(Component.text("Happy Coding ", NamedTextColor.GOLD));
team.suffix(Component.text(" :D", NamedTextColor.RED));
team.addEntry(entity.getName());
});
}
// this currently is not 100% supported as Attributes of the player are sent to the client
// which don't correspond with the disguised type.
//
getServer().getCommandMap().register("disguise", new BukkitCommand("disguise", "disguise as entity", "<entity type>", List.of()) {
@Override
public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
if (args.length == 0) {
return false;
}
if (!(sender instanceof Player player)) {
sender.sendRichMessage("<red>You need to be a player.");
return true;
}
try {
final EntityType type = EntityType.valueOf(args[0].toUpperCase());
player.setDisguiseData(DisguiseData.entity(type));
player.sendRichMessage("<green>Disguised as " + type.name());
} catch (IllegalArgumentException e) {
player.sendRichMessage("<red>Invalid entity type");
return true;
}
return true;
}
@Override
public @NotNull List<String> tabComplete(@NotNull final CommandSender sender, @NotNull final String alias, final @NotNull String[] args) throws IllegalArgumentException {
return Arrays.stream(EntityType.values()).map(EntityType::name).toList();
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment