1
0
mirror of https://github.com/PaperMC/Paper.git synced 2025-03-02 11:22:01 +01:00

: Centralize Bukkit and Minecraft entity conversion

By: DerFrZocker <derrieple@gmail.com>
This commit is contained in:
CraftBukkit/Spigot 2023-12-10 10:46:06 +11:00
parent 7656a539b6
commit c90e518928
4 changed files with 754 additions and 929 deletions
paper-server/src
main/java/org/bukkit/craftbukkit
test/java/org/bukkit/craftbukkit/entity

View File

@ -3,222 +3,63 @@ package org.bukkit.craftbukkit;
import com.google.common.base.Preconditions;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.function.Consumer;
import java.util.function.Predicate;
import net.minecraft.core.BlockPosition;
import net.minecraft.core.EnumDirection;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.worldgen.features.TreeFeatures;
import net.minecraft.resources.ResourceKey;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.EntityAreaEffectCloud;
import net.minecraft.world.entity.EntityExperienceOrb;
import net.minecraft.world.entity.EntityInsentient;
import net.minecraft.world.entity.EntityTypes;
import net.minecraft.world.entity.EnumMobSpawn;
import net.minecraft.world.entity.GroupDataEntity;
import net.minecraft.world.entity.decoration.EntityArmorStand;
import net.minecraft.world.entity.decoration.EntityHanging;
import net.minecraft.world.entity.decoration.EntityItemFrame;
import net.minecraft.world.entity.decoration.EntityLeash;
import net.minecraft.world.entity.decoration.EntityPainting;
import net.minecraft.world.entity.item.EntityFallingBlock;
import net.minecraft.world.entity.item.EntityTNTPrimed;
import net.minecraft.world.entity.monster.EntityZombie;
import net.minecraft.world.entity.monster.breeze.Breeze;
import net.minecraft.world.entity.projectile.EntityEgg;
import net.minecraft.world.entity.projectile.EntityEnderSignal;
import net.minecraft.world.entity.projectile.EntityEvokerFangs;
import net.minecraft.world.entity.projectile.EntityFireball;
import net.minecraft.world.entity.projectile.EntityFireworks;
import net.minecraft.world.entity.projectile.EntityPotion;
import net.minecraft.world.entity.projectile.EntitySnowball;
import net.minecraft.world.entity.projectile.EntityTippedArrow;
import net.minecraft.world.entity.vehicle.EntityMinecartChest;
import net.minecraft.world.entity.vehicle.EntityMinecartCommandBlock;
import net.minecraft.world.entity.vehicle.EntityMinecartFurnace;
import net.minecraft.world.entity.vehicle.EntityMinecartHopper;
import net.minecraft.world.entity.vehicle.EntityMinecartMobSpawner;
import net.minecraft.world.entity.vehicle.EntityMinecartRideable;
import net.minecraft.world.entity.vehicle.EntityMinecartTNT;
import net.minecraft.world.level.GeneratorAccessSeed;
import net.minecraft.world.level.biome.BiomeBase;
import net.minecraft.world.level.block.BlockChorusFlower;
import net.minecraft.world.level.block.BlockDiodeAbstract;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.IBlockData;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.feature.WorldGenFeatureConfigured;
import net.minecraft.world.phys.AxisAlignedBB;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.RegionAccessor;
import org.bukkit.TreeType;
import org.bukkit.block.Biome;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData;
import org.bukkit.craftbukkit.block.CraftBiome;
import org.bukkit.craftbukkit.block.CraftBlock;
import org.bukkit.craftbukkit.block.data.CraftBlockData;
import org.bukkit.craftbukkit.entity.CraftEntity;
import org.bukkit.craftbukkit.entity.CraftEntityTypes;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.potion.CraftPotionUtil;
import org.bukkit.craftbukkit.util.BlockStateListPopulator;
import org.bukkit.craftbukkit.util.CraftLocation;
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.util.RandomSourceWrapper;
import org.bukkit.entity.AbstractArrow;
import org.bukkit.entity.AbstractHorse;
import org.bukkit.entity.AbstractSkeleton;
import org.bukkit.entity.AbstractVillager;
import org.bukkit.entity.Allay;
import org.bukkit.entity.Ambient;
import org.bukkit.entity.AreaEffectCloud;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Axolotl;
import org.bukkit.entity.Bat;
import org.bukkit.entity.Bee;
import org.bukkit.entity.Blaze;
import org.bukkit.entity.BlockDisplay;
import org.bukkit.entity.Boat;
import org.bukkit.entity.Camel;
import org.bukkit.entity.Cat;
import org.bukkit.entity.CaveSpider;
import org.bukkit.entity.ChestBoat;
import org.bukkit.entity.ChestedHorse;
import org.bukkit.entity.Chicken;
import org.bukkit.entity.Cod;
import org.bukkit.entity.ComplexLivingEntity;
import org.bukkit.entity.Cow;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Display;
import org.bukkit.entity.Dolphin;
import org.bukkit.entity.Donkey;
import org.bukkit.entity.DragonFireball;
import org.bukkit.entity.Drowned;
import org.bukkit.entity.Egg;
import org.bukkit.entity.ElderGuardian;
import org.bukkit.entity.EnderCrystal;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.EnderPearl;
import org.bukkit.entity.EnderSignal;
import org.bukkit.entity.Enderman;
import org.bukkit.entity.Endermite;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Evoker;
import org.bukkit.entity.EvokerFangs;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.Firework;
import org.bukkit.entity.Fish;
import org.bukkit.entity.Fox;
import org.bukkit.entity.Frog;
import org.bukkit.entity.Ghast;
import org.bukkit.entity.Giant;
import org.bukkit.entity.GlowItemFrame;
import org.bukkit.entity.GlowSquid;
import org.bukkit.entity.Goat;
import org.bukkit.entity.Golem;
import org.bukkit.entity.Guardian;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.Hoglin;
import org.bukkit.entity.Husk;
import org.bukkit.entity.Illager;
import org.bukkit.entity.Illusioner;
import org.bukkit.entity.Interaction;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.ItemDisplay;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LeashHitch;
import org.bukkit.entity.LightningStrike;
import org.bukkit.entity.Horse;
import org.bukkit.entity.LargeFireball;
import org.bukkit.entity.LingeringPotion;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Llama;
import org.bukkit.entity.LlamaSpit;
import org.bukkit.entity.MagmaCube;
import org.bukkit.entity.Marker;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Mule;
import org.bukkit.entity.MushroomCow;
import org.bukkit.entity.Ocelot;
import org.bukkit.entity.Painting;
import org.bukkit.entity.Panda;
import org.bukkit.entity.Parrot;
import org.bukkit.entity.Phantom;
import org.bukkit.entity.Pig;
import org.bukkit.entity.PigZombie;
import org.bukkit.entity.Piglin;
import org.bukkit.entity.PiglinBrute;
import org.bukkit.entity.Pillager;
import org.bukkit.entity.Player;
import org.bukkit.entity.PolarBear;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.PufferFish;
import org.bukkit.entity.Rabbit;
import org.bukkit.entity.Ravager;
import org.bukkit.entity.Salmon;
import org.bukkit.entity.Sheep;
import org.bukkit.entity.Shulker;
import org.bukkit.entity.ShulkerBullet;
import org.bukkit.entity.Silverfish;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.SkeletonHorse;
import org.bukkit.entity.Slime;
import org.bukkit.entity.SmallFireball;
import org.bukkit.entity.Sniffer;
import org.bukkit.entity.Snowball;
import org.bukkit.entity.Snowman;
import org.bukkit.entity.SpectralArrow;
import org.bukkit.entity.Spellcaster;
import org.bukkit.entity.Spider;
import org.bukkit.entity.Squid;
import org.bukkit.entity.Stray;
import org.bukkit.entity.Strider;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.entity.Tadpole;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.TextDisplay;
import org.bukkit.entity.ThrownExpBottle;
import org.bukkit.entity.SizedFireball;
import org.bukkit.entity.SplashPotion;
import org.bukkit.entity.ThrownPotion;
import org.bukkit.entity.TippedArrow;
import org.bukkit.entity.TraderLlama;
import org.bukkit.entity.Trident;
import org.bukkit.entity.TropicalFish;
import org.bukkit.entity.Turtle;
import org.bukkit.entity.Vex;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Vindicator;
import org.bukkit.entity.WanderingTrader;
import org.bukkit.entity.Warden;
import org.bukkit.entity.WindCharge;
import org.bukkit.entity.Witch;
import org.bukkit.entity.Wither;
import org.bukkit.entity.WitherSkeleton;
import org.bukkit.entity.WitherSkull;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.Zoglin;
import org.bukkit.entity.Zombie;
import org.bukkit.entity.ZombieHorse;
import org.bukkit.entity.ZombieVillager;
import org.bukkit.entity.minecart.CommandMinecart;
import org.bukkit.entity.minecart.ExplosiveMinecart;
import org.bukkit.entity.minecart.HopperMinecart;
import org.bukkit.entity.minecart.PoweredMinecart;
import org.bukkit.entity.minecart.SpawnerMinecart;
import org.bukkit.entity.minecart.StorageMinecart;
import org.bukkit.entity.minecart.RideableMinecart;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionData;
import org.bukkit.potion.PotionType;
import org.bukkit.util.Vector;
public abstract class CraftRegionAccessor implements RegionAccessor {
@ -620,406 +461,42 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
Preconditions.checkArgument(location != null, "Location cannot be null");
Preconditions.checkArgument(clazz != null, "Entity class cannot be null");
net.minecraft.world.entity.Entity entity = null;
net.minecraft.world.level.World world = getHandle().getMinecraftWorld();
double x = location.getX();
double y = location.getY();
double z = location.getZ();
float pitch = location.getPitch();
float yaw = location.getYaw();
// order is important for some of these
if (Boat.class.isAssignableFrom(clazz)) {
if (ChestBoat.class.isAssignableFrom(clazz)) {
entity = EntityTypes.CHEST_BOAT.create(world);
} else {
entity = EntityTypes.BOAT.create(world);
}
entity.moveTo(x, y, z, yaw, pitch);
} else if (FallingBlock.class.isAssignableFrom(clazz)) {
BlockPosition pos = BlockPosition.containing(x, y, z);
entity = EntityFallingBlock.fall(world, pos, getHandle().getBlockState(pos));
} else if (Projectile.class.isAssignableFrom(clazz)) {
if (Snowball.class.isAssignableFrom(clazz)) {
entity = new EntitySnowball(world, x, y, z);
} else if (Egg.class.isAssignableFrom(clazz)) {
entity = new EntityEgg(world, x, y, z);
} else if (AbstractArrow.class.isAssignableFrom(clazz)) {
if (TippedArrow.class.isAssignableFrom(clazz)) {
entity = EntityTypes.ARROW.create(world);
((Arrow) entity.getBukkitEntity()).setBasePotionData(new PotionData(PotionType.WATER, false, false));
} else if (SpectralArrow.class.isAssignableFrom(clazz)) {
entity = EntityTypes.SPECTRAL_ARROW.create(world);
} else if (Trident.class.isAssignableFrom(clazz)) {
entity = EntityTypes.TRIDENT.create(world);
} else {
entity = EntityTypes.ARROW.create(world);
}
entity.moveTo(x, y, z, 0, 0);
} else if (ThrownExpBottle.class.isAssignableFrom(clazz)) {
entity = EntityTypes.EXPERIENCE_BOTTLE.create(world);
entity.moveTo(x, y, z, 0, 0);
} else if (EnderPearl.class.isAssignableFrom(clazz)) {
entity = EntityTypes.ENDER_PEARL.create(world);
entity.moveTo(x, y, z, 0, 0);
} else if (ThrownPotion.class.isAssignableFrom(clazz)) {
if (LingeringPotion.class.isAssignableFrom(clazz)) {
entity = new EntityPotion(world, x, y, z);
((EntityPotion) entity).setItem(CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.LINGERING_POTION, 1)));
} else {
entity = new EntityPotion(world, x, y, z);
((EntityPotion) entity).setItem(CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.SPLASH_POTION, 1)));
}
} else if (Fireball.class.isAssignableFrom(clazz)) {
if (SmallFireball.class.isAssignableFrom(clazz)) {
entity = EntityTypes.SMALL_FIREBALL.create(world);
} else if (WitherSkull.class.isAssignableFrom(clazz)) {
entity = EntityTypes.WITHER_SKULL.create(world);
} else if (DragonFireball.class.isAssignableFrom(clazz)) {
entity = EntityTypes.DRAGON_FIREBALL.create(world);
} else if (WindCharge.class.isAssignableFrom(clazz)) {
entity = EntityTypes.WIND_CHARGE.create(world);
} else {
entity = EntityTypes.FIREBALL.create(world);
}
entity.moveTo(x, y, z, yaw, pitch);
Vector direction = location.getDirection().multiply(10);
((EntityFireball) entity).setDirection(direction.getX(), direction.getY(), direction.getZ());
} else if (ShulkerBullet.class.isAssignableFrom(clazz)) {
entity = EntityTypes.SHULKER_BULLET.create(world);
entity.moveTo(x, y, z, yaw, pitch);
} else if (LlamaSpit.class.isAssignableFrom(clazz)) {
entity = EntityTypes.LLAMA_SPIT.create(world);
entity.moveTo(x, y, z, yaw, pitch);
} else if (Firework.class.isAssignableFrom(clazz)) {
entity = new EntityFireworks(world, x, y, z, net.minecraft.world.item.ItemStack.EMPTY);
}
} else if (Minecart.class.isAssignableFrom(clazz)) {
if (PoweredMinecart.class.isAssignableFrom(clazz)) {
entity = new EntityMinecartFurnace(world, x, y, z);
} else if (StorageMinecart.class.isAssignableFrom(clazz)) {
entity = new EntityMinecartChest(world, x, y, z);
} else if (ExplosiveMinecart.class.isAssignableFrom(clazz)) {
entity = new EntityMinecartTNT(world, x, y, z);
} else if (HopperMinecart.class.isAssignableFrom(clazz)) {
entity = new EntityMinecartHopper(world, x, y, z);
} else if (SpawnerMinecart.class.isAssignableFrom(clazz)) {
entity = new EntityMinecartMobSpawner(world, x, y, z);
} else if (CommandMinecart.class.isAssignableFrom(clazz)) {
entity = new EntityMinecartCommandBlock(world, x, y, z);
} else { // Default to rideable minecart for pre-rideable compatibility
entity = new EntityMinecartRideable(world, x, y, z);
}
} else if (EnderSignal.class.isAssignableFrom(clazz)) {
entity = new EntityEnderSignal(world, x, y, z);
} else if (EnderCrystal.class.isAssignableFrom(clazz)) {
entity = EntityTypes.END_CRYSTAL.create(world);
entity.moveTo(x, y, z, 0, 0);
} else if (LivingEntity.class.isAssignableFrom(clazz)) {
if (Chicken.class.isAssignableFrom(clazz)) {
entity = EntityTypes.CHICKEN.create(world);
} else if (Cow.class.isAssignableFrom(clazz)) {
if (MushroomCow.class.isAssignableFrom(clazz)) {
entity = EntityTypes.MOOSHROOM.create(world);
} else {
entity = EntityTypes.COW.create(world);
}
} else if (Golem.class.isAssignableFrom(clazz)) {
if (Snowman.class.isAssignableFrom(clazz)) {
entity = EntityTypes.SNOW_GOLEM.create(world);
} else if (IronGolem.class.isAssignableFrom(clazz)) {
entity = EntityTypes.IRON_GOLEM.create(world);
} else if (Shulker.class.isAssignableFrom(clazz)) {
entity = EntityTypes.SHULKER.create(world);
}
} else if (Creeper.class.isAssignableFrom(clazz)) {
entity = EntityTypes.CREEPER.create(world);
} else if (Ghast.class.isAssignableFrom(clazz)) {
entity = EntityTypes.GHAST.create(world);
} else if (Pig.class.isAssignableFrom(clazz)) {
entity = EntityTypes.PIG.create(world);
} else if (Player.class.isAssignableFrom(clazz)) {
// need a net server handler for this one
} else if (Sheep.class.isAssignableFrom(clazz)) {
entity = EntityTypes.SHEEP.create(world);
} else if (AbstractHorse.class.isAssignableFrom(clazz)) {
if (ChestedHorse.class.isAssignableFrom(clazz)) {
if (Donkey.class.isAssignableFrom(clazz)) {
entity = EntityTypes.DONKEY.create(world);
} else if (Mule.class.isAssignableFrom(clazz)) {
entity = EntityTypes.MULE.create(world);
} else if (Llama.class.isAssignableFrom(clazz)) {
if (TraderLlama.class.isAssignableFrom(clazz)) {
entity = EntityTypes.TRADER_LLAMA.create(world);
} else {
entity = EntityTypes.LLAMA.create(world);
}
}
} else if (SkeletonHorse.class.isAssignableFrom(clazz)) {
entity = EntityTypes.SKELETON_HORSE.create(world);
} else if (ZombieHorse.class.isAssignableFrom(clazz)) {
entity = EntityTypes.ZOMBIE_HORSE.create(world);
} else if (Camel.class.isAssignableFrom(clazz)) {
entity = EntityTypes.CAMEL.create(world);
} else {
entity = EntityTypes.HORSE.create(world);
}
} else if (AbstractSkeleton.class.isAssignableFrom(clazz)) {
if (Stray.class.isAssignableFrom(clazz)) {
entity = EntityTypes.STRAY.create(world);
} else if (WitherSkeleton.class.isAssignableFrom(clazz)) {
entity = EntityTypes.WITHER_SKELETON.create(world);
} else if (Skeleton.class.isAssignableFrom(clazz)) {
entity = EntityTypes.SKELETON.create(world);
}
} else if (Slime.class.isAssignableFrom(clazz)) {
if (MagmaCube.class.isAssignableFrom(clazz)) {
entity = EntityTypes.MAGMA_CUBE.create(world);
} else {
entity = EntityTypes.SLIME.create(world);
}
} else if (Spider.class.isAssignableFrom(clazz)) {
if (CaveSpider.class.isAssignableFrom(clazz)) {
entity = EntityTypes.CAVE_SPIDER.create(world);
} else {
entity = EntityTypes.SPIDER.create(world);
}
} else if (Squid.class.isAssignableFrom(clazz)) {
if (GlowSquid.class.isAssignableFrom(clazz)) {
entity = EntityTypes.GLOW_SQUID.create(world);
} else {
entity = EntityTypes.SQUID.create(world);
}
} else if (Tameable.class.isAssignableFrom(clazz)) {
if (Wolf.class.isAssignableFrom(clazz)) {
entity = EntityTypes.WOLF.create(world);
} else if (Parrot.class.isAssignableFrom(clazz)) {
entity = EntityTypes.PARROT.create(world);
} else if (Cat.class.isAssignableFrom(clazz)) {
entity = EntityTypes.CAT.create(world);
}
} else if (PigZombie.class.isAssignableFrom(clazz)) {
entity = EntityTypes.ZOMBIFIED_PIGLIN.create(world);
} else if (Zombie.class.isAssignableFrom(clazz)) {
if (Husk.class.isAssignableFrom(clazz)) {
entity = EntityTypes.HUSK.create(world);
} else if (ZombieVillager.class.isAssignableFrom(clazz)) {
entity = EntityTypes.ZOMBIE_VILLAGER.create(world);
} else if (Drowned.class.isAssignableFrom(clazz)) {
entity = EntityTypes.DROWNED.create(world);
} else {
entity = new EntityZombie(world);
}
} else if (Giant.class.isAssignableFrom(clazz)) {
entity = EntityTypes.GIANT.create(world);
} else if (Silverfish.class.isAssignableFrom(clazz)) {
entity = EntityTypes.SILVERFISH.create(world);
} else if (Enderman.class.isAssignableFrom(clazz)) {
entity = EntityTypes.ENDERMAN.create(world);
} else if (Blaze.class.isAssignableFrom(clazz)) {
entity = EntityTypes.BLAZE.create(world);
} else if (AbstractVillager.class.isAssignableFrom(clazz)) {
if (Villager.class.isAssignableFrom(clazz)) {
entity = EntityTypes.VILLAGER.create(world);
} else if (WanderingTrader.class.isAssignableFrom(clazz)) {
entity = EntityTypes.WANDERING_TRADER.create(world);
}
} else if (Witch.class.isAssignableFrom(clazz)) {
entity = EntityTypes.WITCH.create(world);
} else if (Wither.class.isAssignableFrom(clazz)) {
entity = EntityTypes.WITHER.create(world);
} else if (ComplexLivingEntity.class.isAssignableFrom(clazz)) {
if (EnderDragon.class.isAssignableFrom(clazz)) {
Preconditions.checkArgument(this.isNormalWorld(), "Cannot spawn entity %s during world generation", clazz.getName());
entity = EntityTypes.ENDER_DRAGON.create(getHandle().getMinecraftWorld());
}
} else if (Ambient.class.isAssignableFrom(clazz)) {
if (Bat.class.isAssignableFrom(clazz)) {
entity = EntityTypes.BAT.create(world);
}
} else if (Rabbit.class.isAssignableFrom(clazz)) {
entity = EntityTypes.RABBIT.create(world);
} else if (Endermite.class.isAssignableFrom(clazz)) {
entity = EntityTypes.ENDERMITE.create(world);
} else if (Guardian.class.isAssignableFrom(clazz)) {
if (ElderGuardian.class.isAssignableFrom(clazz)) {
entity = EntityTypes.ELDER_GUARDIAN.create(world);
} else {
entity = EntityTypes.GUARDIAN.create(world);
}
} else if (ArmorStand.class.isAssignableFrom(clazz)) {
entity = new EntityArmorStand(world, x, y, z);
} else if (PolarBear.class.isAssignableFrom(clazz)) {
entity = EntityTypes.POLAR_BEAR.create(world);
} else if (Vex.class.isAssignableFrom(clazz)) {
entity = EntityTypes.VEX.create(world);
} else if (Illager.class.isAssignableFrom(clazz)) {
if (Spellcaster.class.isAssignableFrom(clazz)) {
if (Evoker.class.isAssignableFrom(clazz)) {
entity = EntityTypes.EVOKER.create(world);
} else if (Illusioner.class.isAssignableFrom(clazz)) {
entity = EntityTypes.ILLUSIONER.create(world);
}
} else if (Vindicator.class.isAssignableFrom(clazz)) {
entity = EntityTypes.VINDICATOR.create(world);
} else if (Pillager.class.isAssignableFrom(clazz)) {
entity = EntityTypes.PILLAGER.create(world);
}
} else if (Turtle.class.isAssignableFrom(clazz)) {
entity = EntityTypes.TURTLE.create(world);
} else if (Phantom.class.isAssignableFrom(clazz)) {
entity = EntityTypes.PHANTOM.create(world);
} else if (Fish.class.isAssignableFrom(clazz)) {
if (Cod.class.isAssignableFrom(clazz)) {
entity = EntityTypes.COD.create(world);
} else if (PufferFish.class.isAssignableFrom(clazz)) {
entity = EntityTypes.PUFFERFISH.create(world);
} else if (Salmon.class.isAssignableFrom(clazz)) {
entity = EntityTypes.SALMON.create(world);
} else if (TropicalFish.class.isAssignableFrom(clazz)) {
entity = EntityTypes.TROPICAL_FISH.create(world);
} else if (Tadpole.class.isAssignableFrom(clazz)) {
entity = EntityTypes.TADPOLE.create(world);
}
} else if (Dolphin.class.isAssignableFrom(clazz)) {
entity = EntityTypes.DOLPHIN.create(world);
} else if (Ocelot.class.isAssignableFrom(clazz)) {
entity = EntityTypes.OCELOT.create(world);
} else if (Ravager.class.isAssignableFrom(clazz)) {
entity = EntityTypes.RAVAGER.create(world);
} else if (Panda.class.isAssignableFrom(clazz)) {
entity = EntityTypes.PANDA.create(world);
} else if (Fox.class.isAssignableFrom(clazz)) {
entity = EntityTypes.FOX.create(world);
} else if (Bee.class.isAssignableFrom(clazz)) {
entity = EntityTypes.BEE.create(world);
} else if (Hoglin.class.isAssignableFrom(clazz)) {
entity = EntityTypes.HOGLIN.create(world);
} else if (Piglin.class.isAssignableFrom(clazz)) {
entity = EntityTypes.PIGLIN.create(world);
} else if (PiglinBrute.class.isAssignableFrom(clazz)) {
entity = EntityTypes.PIGLIN_BRUTE.create(world);
} else if (Strider.class.isAssignableFrom(clazz)) {
entity = EntityTypes.STRIDER.create(world);
} else if (Zoglin.class.isAssignableFrom(clazz)) {
entity = EntityTypes.ZOGLIN.create(world);
} else if (Axolotl.class.isAssignableFrom(clazz)) {
entity = EntityTypes.AXOLOTL.create(world);
} else if (Goat.class.isAssignableFrom(clazz)) {
entity = EntityTypes.GOAT.create(world);
} else if (Allay.class.isAssignableFrom(clazz)) {
entity = EntityTypes.ALLAY.create(world);
} else if (Frog.class.isAssignableFrom(clazz)) {
entity = EntityTypes.FROG.create(world);
} else if (Warden.class.isAssignableFrom(clazz)) {
entity = EntityTypes.WARDEN.create(world);
} else if (Sniffer.class.isAssignableFrom(clazz)) {
entity = EntityTypes.SNIFFER.create(world);
} else if (Breeze.class.isAssignableFrom(clazz)) {
entity = EntityTypes.BREEZE.create(world);
}
if (entity != null) {
entity.absMoveTo(x, y, z, yaw, pitch);
entity.setYHeadRot(yaw); // SPIGOT-3587
}
} else if (Hanging.class.isAssignableFrom(clazz)) {
if (LeashHitch.class.isAssignableFrom(clazz)) {
// SPIGOT-5732: LeashHitch has no direction and is always centered at a block
entity = new EntityLeash(world, BlockPosition.containing(x, y, z));
} else {
BlockFace face = BlockFace.SELF;
BlockFace[] faces = new BlockFace[]{BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH};
int width = 16; // 1 full block, also painting smallest size.
int height = 16; // 1 full block, also painting smallest size.
if (ItemFrame.class.isAssignableFrom(clazz)) {
width = 12;
height = 12;
faces = new BlockFace[]{BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH, BlockFace.UP, BlockFace.DOWN};
}
final BlockPosition pos = BlockPosition.containing(x, y, z);
for (BlockFace dir : faces) {
IBlockData nmsBlock = getHandle().getBlockState(pos.relative(CraftBlock.blockFaceToNotch(dir)));
if (nmsBlock.isSolid() || BlockDiodeAbstract.isDiode(nmsBlock)) {
boolean taken = false;
AxisAlignedBB bb = (ItemFrame.class.isAssignableFrom(clazz))
? EntityItemFrame.calculateBoundingBox(null, pos, CraftBlock.blockFaceToNotch(dir).getOpposite(), width, height)
: EntityHanging.calculateBoundingBox(null, pos, CraftBlock.blockFaceToNotch(dir).getOpposite(), width, height);
List<net.minecraft.world.entity.Entity> list = (List<net.minecraft.world.entity.Entity>) getHandle().getEntities(null, bb);
for (Iterator<net.minecraft.world.entity.Entity> it = list.iterator(); !taken && it.hasNext(); ) {
net.minecraft.world.entity.Entity e = it.next();
if (e instanceof EntityHanging) {
taken = true; // Hanging entities do not like hanging entities which intersect them.
}
}
if (!taken) {
face = dir;
break;
}
}
}
// No valid face found
if (face == BlockFace.SELF) {
// SPIGOT-6387: Allow hanging entities to be placed in midair
face = BlockFace.SOUTH;
randomizeData = false; // Don't randomize if no valid face is found, prevents null painting
}
EnumDirection dir = CraftBlock.blockFaceToNotch(face).getOpposite();
if (Painting.class.isAssignableFrom(clazz)) {
if (isNormalWorld() && randomizeData) {
entity = EntityPainting.create(world, pos, dir).orElse(null);
} else {
entity = new EntityPainting(EntityTypes.PAINTING, getHandle().getMinecraftWorld());
entity.absMoveTo(x, y, z, yaw, pitch);
((EntityPainting) entity).setDirection(dir);
}
} else if (ItemFrame.class.isAssignableFrom(clazz)) {
if (GlowItemFrame.class.isAssignableFrom(clazz)) {
entity = new net.minecraft.world.entity.decoration.GlowItemFrame(world, BlockPosition.containing(x, y, z), dir);
} else {
entity = new EntityItemFrame(world, BlockPosition.containing(x, y, z), dir);
}
}
}
} else if (TNTPrimed.class.isAssignableFrom(clazz)) {
entity = new EntityTNTPrimed(world, x, y, z, null);
} else if (ExperienceOrb.class.isAssignableFrom(clazz)) {
entity = new EntityExperienceOrb(world, x, y, z, 0);
} else if (LightningStrike.class.isAssignableFrom(clazz)) {
entity = EntityTypes.LIGHTNING_BOLT.create(world);
entity.moveTo(location.getX(), location.getY(), location.getZ());
} else if (AreaEffectCloud.class.isAssignableFrom(clazz)) {
entity = new EntityAreaEffectCloud(world, x, y, z);
} else if (EvokerFangs.class.isAssignableFrom(clazz)) {
entity = new EntityEvokerFangs(world, x, y, z, (float) Math.toRadians(yaw), 0, null);
} else if (Marker.class.isAssignableFrom(clazz)) {
entity = EntityTypes.MARKER.create(world);
entity.setPos(x, y, z);
} else if (Interaction.class.isAssignableFrom(clazz)) {
entity = EntityTypes.INTERACTION.create(world);
entity.setPos(x, y, z);
} else if (Display.class.isAssignableFrom(clazz)) {
if (BlockDisplay.class.isAssignableFrom(clazz)) {
entity = EntityTypes.BLOCK_DISPLAY.create(world);
} else if (ItemDisplay.class.isAssignableFrom(clazz)) {
entity = EntityTypes.ITEM_DISPLAY.create(world);
} else if (TextDisplay.class.isAssignableFrom(clazz)) {
entity = EntityTypes.TEXT_DISPLAY.create(world);
}
if (entity != null) {
entity.setPos(x, y, z);
}
// Convert classes which have no direct entity type, but where spawn able by the if cases
Consumer<net.minecraft.world.entity.Entity> runOld = other -> { };
if (clazz == AbstractArrow.class) {
clazz = Arrow.class;
} else if (clazz == AbstractHorse.class) {
clazz = Horse.class;
} else if (clazz == Fireball.class) {
clazz = LargeFireball.class;
} else if (clazz == LingeringPotion.class) {
clazz = ThrownPotion.class;
runOld = other -> ((EntityPotion) other).setItem(CraftItemStack.asNMSCopy(new ItemStack(org.bukkit.Material.LINGERING_POTION, 1)));
} else if (clazz == Minecart.class) {
clazz = RideableMinecart.class;
} else if (clazz == SizedFireball.class) {
clazz = LargeFireball.class;
} else if (clazz == SplashPotion.class) {
clazz = ThrownPotion.class;
} else if (clazz == TippedArrow.class) {
clazz = Arrow.class;
runOld = other -> ((Arrow) other.getBukkitEntity()).setBasePotionType(PotionType.WATER);
}
CraftEntityTypes.EntityTypeData<?, ?> entityTypeData = CraftEntityTypes.getEntityTypeData(clazz);
if (entityTypeData == null || entityTypeData.spawnFunction() == null) {
throw new IllegalArgumentException("Cannot spawn an entity for " + clazz.getName());
}
if (!entityTypeData.entityType().isEnabledByFeature(getHandle().getMinecraftWorld().getWorld())) {
throw new IllegalArgumentException("Cannot spawn an entity for " + clazz.getName() + " because it is not an enabled feature");
}
net.minecraft.world.entity.Entity entity = entityTypeData.spawnFunction().apply(new CraftEntityTypes.SpawnData(getHandle(), location, randomizeData, isNormalWorld()));
if (entity != null) {
runOld.accept(entity);
return entity;
}

View File

@ -15,159 +15,15 @@ import net.minecraft.server.level.EntityPlayer;
import net.minecraft.server.level.PlayerChunkMap;
import net.minecraft.server.level.WorldServer;
import net.minecraft.server.network.ServerPlayerConnection;
import net.minecraft.world.entity.Display;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityAreaEffectCloud;
import net.minecraft.world.entity.EntityCreature;
import net.minecraft.world.entity.EntityExperienceOrb;
import net.minecraft.world.entity.EntityFlying;
import net.minecraft.world.entity.EntityLightning;
import net.minecraft.world.entity.EntityLiving;
import net.minecraft.world.entity.EntityTameableAnimal;
import net.minecraft.world.entity.EntityTypes;
import net.minecraft.world.entity.GlowSquid;
import net.minecraft.world.entity.Interaction;
import net.minecraft.world.entity.Marker;
import net.minecraft.world.entity.ambient.EntityAmbient;
import net.minecraft.world.entity.ambient.EntityBat;
import net.minecraft.world.entity.animal.EntityAnimal;
import net.minecraft.world.entity.animal.EntityBee;
import net.minecraft.world.entity.animal.EntityCat;
import net.minecraft.world.entity.animal.EntityChicken;
import net.minecraft.world.entity.animal.EntityCod;
import net.minecraft.world.entity.animal.EntityCow;
import net.minecraft.world.entity.animal.EntityDolphin;
import net.minecraft.world.entity.animal.EntityFish;
import net.minecraft.world.entity.animal.EntityFox;
import net.minecraft.world.entity.animal.EntityGolem;
import net.minecraft.world.entity.animal.EntityIronGolem;
import net.minecraft.world.entity.animal.EntityMushroomCow;
import net.minecraft.world.entity.animal.EntityOcelot;
import net.minecraft.world.entity.animal.EntityPanda;
import net.minecraft.world.entity.animal.EntityParrot;
import net.minecraft.world.entity.animal.EntityPig;
import net.minecraft.world.entity.animal.EntityPolarBear;
import net.minecraft.world.entity.animal.EntityPufferFish;
import net.minecraft.world.entity.animal.EntityRabbit;
import net.minecraft.world.entity.animal.EntitySalmon;
import net.minecraft.world.entity.animal.EntitySheep;
import net.minecraft.world.entity.animal.EntitySnowman;
import net.minecraft.world.entity.animal.EntitySquid;
import net.minecraft.world.entity.animal.EntityTropicalFish;
import net.minecraft.world.entity.animal.EntityTurtle;
import net.minecraft.world.entity.animal.EntityWaterAnimal;
import net.minecraft.world.entity.animal.EntityWolf;
import net.minecraft.world.entity.animal.allay.Allay;
import net.minecraft.world.entity.animal.axolotl.Axolotl;
import net.minecraft.world.entity.animal.camel.Camel;
import net.minecraft.world.entity.animal.frog.Frog;
import net.minecraft.world.entity.animal.frog.Tadpole;
import net.minecraft.world.entity.animal.goat.Goat;
import net.minecraft.world.entity.animal.horse.EntityHorse;
import net.minecraft.world.entity.animal.horse.EntityHorseAbstract;
import net.minecraft.world.entity.animal.horse.EntityHorseChestedAbstract;
import net.minecraft.world.entity.animal.horse.EntityHorseDonkey;
import net.minecraft.world.entity.animal.horse.EntityHorseMule;
import net.minecraft.world.entity.animal.horse.EntityHorseSkeleton;
import net.minecraft.world.entity.animal.horse.EntityHorseZombie;
import net.minecraft.world.entity.animal.horse.EntityLlama;
import net.minecraft.world.entity.animal.horse.EntityLlamaTrader;
import net.minecraft.world.entity.animal.sniffer.Sniffer;
import net.minecraft.world.entity.boss.EntityComplexPart;
import net.minecraft.world.entity.boss.enderdragon.EntityEnderCrystal;
import net.minecraft.world.entity.boss.enderdragon.EntityEnderDragon;
import net.minecraft.world.entity.boss.wither.EntityWither;
import net.minecraft.world.entity.decoration.EntityArmorStand;
import net.minecraft.world.entity.decoration.EntityHanging;
import net.minecraft.world.entity.decoration.EntityItemFrame;
import net.minecraft.world.entity.decoration.EntityLeash;
import net.minecraft.world.entity.decoration.EntityPainting;
import net.minecraft.world.entity.decoration.GlowItemFrame;
import net.minecraft.world.entity.item.EntityFallingBlock;
import net.minecraft.world.entity.item.EntityItem;
import net.minecraft.world.entity.item.EntityTNTPrimed;
import net.minecraft.world.entity.monster.EntityBlaze;
import net.minecraft.world.entity.monster.EntityCaveSpider;
import net.minecraft.world.entity.monster.EntityCreeper;
import net.minecraft.world.entity.monster.EntityDrowned;
import net.minecraft.world.entity.monster.EntityEnderman;
import net.minecraft.world.entity.monster.EntityEndermite;
import net.minecraft.world.entity.monster.EntityEvoker;
import net.minecraft.world.entity.monster.EntityGhast;
import net.minecraft.world.entity.monster.EntityGiantZombie;
import net.minecraft.world.entity.monster.EntityGuardian;
import net.minecraft.world.entity.monster.EntityGuardianElder;
import net.minecraft.world.entity.monster.EntityIllagerAbstract;
import net.minecraft.world.entity.monster.EntityIllagerIllusioner;
import net.minecraft.world.entity.monster.EntityIllagerWizard;
import net.minecraft.world.entity.monster.EntityMagmaCube;
import net.minecraft.world.entity.monster.EntityMonster;
import net.minecraft.world.entity.monster.EntityPhantom;
import net.minecraft.world.entity.monster.EntityPigZombie;
import net.minecraft.world.entity.monster.EntityPillager;
import net.minecraft.world.entity.monster.EntityRavager;
import net.minecraft.world.entity.monster.EntityShulker;
import net.minecraft.world.entity.monster.EntitySilverfish;
import net.minecraft.world.entity.monster.EntitySkeleton;
import net.minecraft.world.entity.monster.EntitySkeletonAbstract;
import net.minecraft.world.entity.monster.EntitySkeletonStray;
import net.minecraft.world.entity.monster.EntitySkeletonWither;
import net.minecraft.world.entity.monster.EntitySlime;
import net.minecraft.world.entity.monster.EntitySpider;
import net.minecraft.world.entity.monster.EntityStrider;
import net.minecraft.world.entity.monster.EntityVex;
import net.minecraft.world.entity.monster.EntityVindicator;
import net.minecraft.world.entity.monster.EntityWitch;
import net.minecraft.world.entity.monster.EntityZoglin;
import net.minecraft.world.entity.monster.EntityZombie;
import net.minecraft.world.entity.monster.EntityZombieHusk;
import net.minecraft.world.entity.monster.EntityZombieVillager;
import net.minecraft.world.entity.monster.breeze.Breeze;
import net.minecraft.world.entity.monster.hoglin.EntityHoglin;
import net.minecraft.world.entity.monster.piglin.EntityPiglin;
import net.minecraft.world.entity.monster.piglin.EntityPiglinAbstract;
import net.minecraft.world.entity.monster.piglin.EntityPiglinBrute;
import net.minecraft.world.entity.monster.warden.Warden;
import net.minecraft.world.entity.npc.EntityVillager;
import net.minecraft.world.entity.npc.EntityVillagerAbstract;
import net.minecraft.world.entity.npc.EntityVillagerTrader;
import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.entity.projectile.EntityArrow;
import net.minecraft.world.entity.projectile.EntityDragonFireball;
import net.minecraft.world.entity.projectile.EntityEgg;
import net.minecraft.world.entity.projectile.EntityEnderPearl;
import net.minecraft.world.entity.projectile.EntityEnderSignal;
import net.minecraft.world.entity.projectile.EntityEvokerFangs;
import net.minecraft.world.entity.projectile.EntityFireball;
import net.minecraft.world.entity.projectile.EntityFireworks;
import net.minecraft.world.entity.projectile.EntityFishingHook;
import net.minecraft.world.entity.projectile.EntityLargeFireball;
import net.minecraft.world.entity.projectile.EntityLlamaSpit;
import net.minecraft.world.entity.projectile.EntityPotion;
import net.minecraft.world.entity.projectile.EntityProjectile;
import net.minecraft.world.entity.projectile.EntityShulkerBullet;
import net.minecraft.world.entity.projectile.EntitySmallFireball;
import net.minecraft.world.entity.projectile.EntitySnowball;
import net.minecraft.world.entity.projectile.EntitySpectralArrow;
import net.minecraft.world.entity.projectile.EntityThrownExpBottle;
import net.minecraft.world.entity.projectile.EntityThrownTrident;
import net.minecraft.world.entity.projectile.EntityTippedArrow;
import net.minecraft.world.entity.projectile.EntityWitherSkull;
import net.minecraft.world.entity.projectile.WindCharge;
import net.minecraft.world.entity.vehicle.ChestBoat;
import net.minecraft.world.entity.vehicle.EntityBoat;
import net.minecraft.world.entity.vehicle.EntityMinecartAbstract;
import net.minecraft.world.entity.vehicle.EntityMinecartChest;
import net.minecraft.world.entity.vehicle.EntityMinecartCommandBlock;
import net.minecraft.world.entity.vehicle.EntityMinecartFurnace;
import net.minecraft.world.entity.vehicle.EntityMinecartHopper;
import net.minecraft.world.entity.vehicle.EntityMinecartMobSpawner;
import net.minecraft.world.entity.vehicle.EntityMinecartRideable;
import net.minecraft.world.entity.vehicle.EntityMinecartTNT;
import net.minecraft.world.phys.AxisAlignedBB;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.Registry;
import org.bukkit.Server;
import org.bukkit.Sound;
import org.bukkit.World;
@ -181,7 +37,6 @@ import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer;
import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry;
import org.bukkit.craftbukkit.util.CraftChatMessage;
import org.bukkit.craftbukkit.util.CraftLocation;
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
import org.bukkit.craftbukkit.util.CraftSpawnCategory;
import org.bukkit.craftbukkit.util.CraftVector;
import org.bukkit.entity.EntitySnapshot;
@ -218,232 +73,28 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
this.entityType = CraftEntityType.minecraftToBukkit(entity.getType());
}
public static CraftEntity getEntity(CraftServer server, Entity entity) {
/*
* Order is *EXTREMELY* important -- keep it right! =D
*/
// CHECKSTYLE:OFF
if (entity instanceof EntityLiving) {
// Players
if (entity instanceof EntityHuman) {
if (entity instanceof EntityPlayer) { return new CraftPlayer(server, (EntityPlayer) entity); }
else { return new CraftHumanEntity(server, (EntityHuman) entity); }
}
// Water Animals
else if (entity instanceof EntityWaterAnimal) {
if (entity instanceof EntitySquid) {
if (entity instanceof GlowSquid) { return new CraftGlowSquid(server, (GlowSquid) entity); }
else { return new CraftSquid(server, (EntitySquid) entity); }
}
else if (entity instanceof EntityFish) {
if (entity instanceof EntityCod) { return new CraftCod(server, (EntityCod) entity); }
else if (entity instanceof EntityPufferFish) { return new CraftPufferFish(server, (EntityPufferFish) entity); }
else if (entity instanceof EntitySalmon) { return new CraftSalmon(server, (EntitySalmon) entity); }
else if (entity instanceof EntityTropicalFish) { return new CraftTropicalFish(server, (EntityTropicalFish) entity); }
else if (entity instanceof Tadpole) { return new CraftTadpole(server, (Tadpole) entity); }
else { return new CraftFish(server, (EntityFish) entity); }
}
else if (entity instanceof EntityDolphin) { return new CraftDolphin(server, (EntityDolphin) entity); }
else { return new CraftWaterMob(server, (EntityWaterAnimal) entity); }
}
else if (entity instanceof EntityCreature) {
// Animals
if (entity instanceof EntityAnimal) {
if (entity instanceof EntityChicken) { return new CraftChicken(server, (EntityChicken) entity); }
else if (entity instanceof EntityCow) {
if (entity instanceof EntityMushroomCow) { return new CraftMushroomCow(server, (EntityMushroomCow) entity); }
else { return new CraftCow(server, (EntityCow) entity); }
}
else if (entity instanceof EntityPig) { return new CraftPig(server, (EntityPig) entity); }
else if (entity instanceof EntityTameableAnimal) {
if (entity instanceof EntityWolf) { return new CraftWolf(server, (EntityWolf) entity); }
else if (entity instanceof EntityCat) { return new CraftCat(server, (EntityCat) entity); }
else if (entity instanceof EntityParrot) { return new CraftParrot(server, (EntityParrot) entity); }
}
else if (entity instanceof EntitySheep) { return new CraftSheep(server, (EntitySheep) entity); }
else if (entity instanceof EntityHorseAbstract) {
if (entity instanceof EntityHorseChestedAbstract){
if (entity instanceof EntityHorseDonkey) { return new CraftDonkey(server, (EntityHorseDonkey) entity); }
else if (entity instanceof EntityHorseMule) { return new CraftMule(server, (EntityHorseMule) entity); }
else if (entity instanceof EntityLlamaTrader) { return new CraftTraderLlama(server, (EntityLlamaTrader) entity); }
else if (entity instanceof EntityLlama) { return new CraftLlama(server, (EntityLlama) entity); }
} else if (entity instanceof EntityHorse) { return new CraftHorse(server, (EntityHorse) entity); }
else if (entity instanceof EntityHorseSkeleton) { return new CraftSkeletonHorse(server, (EntityHorseSkeleton) entity); }
else if (entity instanceof EntityHorseZombie) { return new CraftZombieHorse(server, (EntityHorseZombie) entity); }
else if (entity instanceof Camel) { return new CraftCamel(server, (Camel) entity); }
}
else if (entity instanceof EntityRabbit) { return new CraftRabbit(server, (EntityRabbit) entity); }
else if (entity instanceof EntityPolarBear) { return new CraftPolarBear(server, (EntityPolarBear) entity); }
else if (entity instanceof EntityTurtle) { return new CraftTurtle(server, (EntityTurtle) entity); }
else if (entity instanceof EntityOcelot) { return new CraftOcelot(server, (EntityOcelot) entity); }
else if (entity instanceof EntityPanda) { return new CraftPanda(server, (EntityPanda) entity); }
else if (entity instanceof EntityFox) { return new CraftFox(server, (EntityFox) entity); }
else if (entity instanceof EntityBee) { return new CraftBee(server, (EntityBee) entity); }
else if (entity instanceof EntityHoglin) { return new CraftHoglin(server, (EntityHoglin) entity); }
else if (entity instanceof EntityStrider) { return new CraftStrider(server, (EntityStrider) entity); }
else if (entity instanceof Axolotl) { return new CraftAxolotl(server, (Axolotl) entity); }
else if (entity instanceof Goat) { return new CraftGoat(server, (Goat) entity); }
else if (entity instanceof Frog) { return new CraftFrog(server, (Frog) entity); }
else if (entity instanceof Sniffer) { return new CraftSniffer(server, (Sniffer) entity); }
else { return new CraftAnimals(server, (EntityAnimal) entity); }
}
// Monsters
else if (entity instanceof EntityMonster) {
if (entity instanceof EntityZombie) {
if (entity instanceof EntityPigZombie) { return new CraftPigZombie(server, (EntityPigZombie) entity); }
else if (entity instanceof EntityZombieHusk) { return new CraftHusk(server, (EntityZombieHusk) entity); }
else if (entity instanceof EntityZombieVillager) { return new CraftVillagerZombie(server, (EntityZombieVillager) entity); }
else if (entity instanceof EntityDrowned) { return new CraftDrowned(server, (EntityDrowned) entity); }
else { return new CraftZombie(server, (EntityZombie) entity); }
}
else if (entity instanceof EntityCreeper) { return new CraftCreeper(server, (EntityCreeper) entity); }
else if (entity instanceof EntityEnderman) { return new CraftEnderman(server, (EntityEnderman) entity); }
else if (entity instanceof EntitySilverfish) { return new CraftSilverfish(server, (EntitySilverfish) entity); }
else if (entity instanceof EntityGiantZombie) { return new CraftGiant(server, (EntityGiantZombie) entity); }
else if (entity instanceof EntitySkeletonAbstract) {
if (entity instanceof EntitySkeletonStray) { return new CraftStray(server, (EntitySkeletonStray) entity); }
else if (entity instanceof EntitySkeletonWither) { return new CraftWitherSkeleton(server, (EntitySkeletonWither) entity); }
else if (entity instanceof EntitySkeleton){ return new CraftSkeleton(server, (EntitySkeleton) entity); }
}
else if (entity instanceof EntityBlaze) { return new CraftBlaze(server, (EntityBlaze) entity); }
else if (entity instanceof EntityWitch) { return new CraftWitch(server, (EntityWitch) entity); }
else if (entity instanceof EntityWither) { return new CraftWither(server, (EntityWither) entity); }
else if (entity instanceof EntitySpider) {
if (entity instanceof EntityCaveSpider) { return new CraftCaveSpider(server, (EntityCaveSpider) entity); }
else { return new CraftSpider(server, (EntitySpider) entity); }
}
else if (entity instanceof EntityEndermite) { return new CraftEndermite(server, (EntityEndermite) entity); }
else if (entity instanceof EntityGuardian) {
if (entity instanceof EntityGuardianElder) { return new CraftElderGuardian(server, (EntityGuardianElder) entity); }
else { return new CraftGuardian(server, (EntityGuardian) entity); }
}
else if (entity instanceof EntityVex) { return new CraftVex(server, (EntityVex) entity); }
else if (entity instanceof EntityIllagerAbstract) {
if (entity instanceof EntityIllagerWizard) {
if (entity instanceof EntityEvoker) { return new CraftEvoker(server, (EntityEvoker) entity); }
else if (entity instanceof EntityIllagerIllusioner) { return new CraftIllusioner(server, (EntityIllagerIllusioner) entity); }
else { return new CraftSpellcaster(server, (EntityIllagerWizard) entity); }
}
else if (entity instanceof EntityVindicator) { return new CraftVindicator(server, (EntityVindicator) entity); }
else if (entity instanceof EntityPillager) { return new CraftPillager(server, (EntityPillager) entity); }
else { return new CraftIllager(server, (EntityIllagerAbstract) entity); }
}
else if (entity instanceof EntityRavager) { return new CraftRavager(server, (EntityRavager) entity); }
else if (entity instanceof EntityPiglinAbstract) {
if (entity instanceof EntityPiglin) return new CraftPiglin(server, (EntityPiglin) entity);
else if (entity instanceof EntityPiglinBrute) { return new CraftPiglinBrute(server, (EntityPiglinBrute) entity); }
else { return new CraftPiglinAbstract(server, (EntityPiglinAbstract) entity); }
}
else if (entity instanceof EntityZoglin) { return new CraftZoglin(server, (EntityZoglin) entity); }
else if (entity instanceof Warden) { return new CraftWarden(server, (Warden) entity); }
else if (entity instanceof Breeze) { return new CraftBreeze(server, (Breeze) entity); }
public static <T extends Entity> CraftEntity getEntity(CraftServer server, T entity) {
Preconditions.checkArgument(entity != null, "Unknown entity");
else { return new CraftMonster(server, (EntityMonster) entity); }
}
else if (entity instanceof EntityGolem) {
if (entity instanceof EntitySnowman) { return new CraftSnowman(server, (EntitySnowman) entity); }
else if (entity instanceof EntityIronGolem) { return new CraftIronGolem(server, (EntityIronGolem) entity); }
else if (entity instanceof EntityShulker) { return new CraftShulker(server, (EntityShulker) entity); }
}
else if (entity instanceof EntityVillagerAbstract) {
if (entity instanceof EntityVillager) { return new CraftVillager(server, (EntityVillager) entity); }
else if (entity instanceof EntityVillagerTrader) { return new CraftWanderingTrader(server, (EntityVillagerTrader) entity); }
else { return new CraftAbstractVillager(server, (EntityVillagerAbstract) entity); }
}
else if (entity instanceof Allay) { return new CraftAllay(server, (Allay) entity); }
else { return new CraftCreature(server, (EntityCreature) entity); }
// Special case human, since bukkit use Player interface for ...
if (entity instanceof EntityHuman && !(entity instanceof EntityPlayer)) {
return new CraftHumanEntity(server, (EntityHuman) entity);
}
// Special case complex part, since there is no extra entity type for them
if (entity instanceof EntityComplexPart complexPart) {
if (complexPart.parentMob instanceof EntityEnderDragon) {
return new CraftEnderDragonPart(server, complexPart);
} else {
return new CraftComplexPart(server, complexPart);
}
// Slimes are a special (and broken) case
else if (entity instanceof EntitySlime) {
if (entity instanceof EntityMagmaCube) { return new CraftMagmaCube(server, (EntityMagmaCube) entity); }
else { return new CraftSlime(server, (EntitySlime) entity); }
}
// Flying
else if (entity instanceof EntityFlying) {
if (entity instanceof EntityGhast) { return new CraftGhast(server, (EntityGhast) entity); }
else if (entity instanceof EntityPhantom) { return new CraftPhantom(server, (EntityPhantom) entity); }
else { return new CraftFlying(server, (EntityFlying) entity); }
}
else if (entity instanceof EntityEnderDragon) {
return new CraftEnderDragon(server, (EntityEnderDragon) entity);
}
// Ambient
else if (entity instanceof EntityAmbient) {
if (entity instanceof EntityBat) { return new CraftBat(server, (EntityBat) entity); }
else { return new CraftAmbient(server, (EntityAmbient) entity); }
}
else if (entity instanceof EntityArmorStand) { return new CraftArmorStand(server, (EntityArmorStand) entity); }
else { return new CraftLivingEntity(server, (EntityLiving) entity); }
}
else if (entity instanceof EntityComplexPart) {
EntityComplexPart part = (EntityComplexPart) entity;
if (part.parentMob instanceof EntityEnderDragon) { return new CraftEnderDragonPart(server, (EntityComplexPart) entity); }
else { return new CraftComplexPart(server, (EntityComplexPart) entity); }
CraftEntityTypes.EntityTypeData<?, T> entityTypeData = CraftEntityTypes.getEntityTypeData(CraftEntityType.minecraftToBukkit(entity.getType()));
if (entityTypeData != null) {
return entityTypeData.convertFunction().apply(server, entity);
}
else if (entity instanceof EntityExperienceOrb) { return new CraftExperienceOrb(server, (EntityExperienceOrb) entity); }
else if (entity instanceof EntityTippedArrow) { return new CraftTippedArrow(server, (EntityTippedArrow) entity); }
else if (entity instanceof EntitySpectralArrow) { return new CraftSpectralArrow(server, (EntitySpectralArrow) entity); }
else if (entity instanceof EntityArrow) {
if (entity instanceof EntityThrownTrident) { return new CraftTrident(server, (EntityThrownTrident) entity); }
else { return new CraftArrow(server, (EntityArrow) entity); }
}
else if (entity instanceof EntityBoat) {
if (entity instanceof ChestBoat) { return new CraftChestBoat(server, (ChestBoat) entity); }
else { return new CraftBoat(server, (EntityBoat) entity); }
}
else if (entity instanceof EntityProjectile) {
if (entity instanceof EntityEgg) { return new CraftEgg(server, (EntityEgg) entity); }
else if (entity instanceof EntitySnowball) { return new CraftSnowball(server, (EntitySnowball) entity); }
else if (entity instanceof EntityPotion) { return new CraftThrownPotion(server, (EntityPotion) entity); }
else if (entity instanceof EntityEnderPearl) { return new CraftEnderPearl(server, (EntityEnderPearl) entity); }
else if (entity instanceof EntityThrownExpBottle) { return new CraftThrownExpBottle(server, (EntityThrownExpBottle) entity); }
}
else if (entity instanceof EntityFallingBlock) { return new CraftFallingBlock(server, (EntityFallingBlock) entity); }
else if (entity instanceof EntityFireball) {
if (entity instanceof EntitySmallFireball) { return new CraftSmallFireball(server, (EntitySmallFireball) entity); }
else if (entity instanceof EntityLargeFireball) { return new CraftLargeFireball(server, (EntityLargeFireball) entity); }
else if (entity instanceof EntityWitherSkull) { return new CraftWitherSkull(server, (EntityWitherSkull) entity); }
else if (entity instanceof EntityDragonFireball) { return new CraftDragonFireball(server, (EntityDragonFireball) entity); }
else if (entity instanceof WindCharge) { return new CraftWindCharge(server, (WindCharge) entity); }
else { return new CraftFireball(server, (EntityFireball) entity); }
}
else if (entity instanceof EntityEnderSignal) { return new CraftEnderSignal(server, (EntityEnderSignal) entity); }
else if (entity instanceof EntityEnderCrystal) { return new CraftEnderCrystal(server, (EntityEnderCrystal) entity); }
else if (entity instanceof EntityFishingHook) { return new CraftFishHook(server, (EntityFishingHook) entity); }
else if (entity instanceof EntityItem) { return new CraftItem(server, (EntityItem) entity); }
else if (entity instanceof EntityLightning) { return new CraftLightningStrike(server, (EntityLightning) entity); }
else if (entity instanceof EntityMinecartAbstract) {
if (entity instanceof EntityMinecartFurnace) { return new CraftMinecartFurnace(server, (EntityMinecartFurnace) entity); }
else if (entity instanceof EntityMinecartChest) { return new CraftMinecartChest(server, (EntityMinecartChest) entity); }
else if (entity instanceof EntityMinecartTNT) { return new CraftMinecartTNT(server, (EntityMinecartTNT) entity); }
else if (entity instanceof EntityMinecartHopper) { return new CraftMinecartHopper(server, (EntityMinecartHopper) entity); }
else if (entity instanceof EntityMinecartMobSpawner) { return new CraftMinecartMobSpawner(server, (EntityMinecartMobSpawner) entity); }
else if (entity instanceof EntityMinecartRideable) { return new CraftMinecartRideable(server, (EntityMinecartRideable) entity); }
else if (entity instanceof EntityMinecartCommandBlock) { return new CraftMinecartCommand(server, (EntityMinecartCommandBlock) entity); }
} else if (entity instanceof EntityHanging) {
if (entity instanceof EntityPainting) { return new CraftPainting(server, (EntityPainting) entity); }
else if (entity instanceof EntityItemFrame) {
if (entity instanceof GlowItemFrame) { return new CraftGlowItemFrame(server, (GlowItemFrame) entity); }
else { return new CraftItemFrame(server, (EntityItemFrame) entity); }
}
else if (entity instanceof EntityLeash) { return new CraftLeash(server, (EntityLeash) entity); }
else { return new CraftHanging(server, (EntityHanging) entity); }
}
else if (entity instanceof EntityTNTPrimed) { return new CraftTNTPrimed(server, (EntityTNTPrimed) entity); }
else if (entity instanceof EntityFireworks) { return new CraftFirework(server, (EntityFireworks) entity); }
else if (entity instanceof EntityShulkerBullet) { return new CraftShulkerBullet(server, (EntityShulkerBullet) entity); }
else if (entity instanceof EntityAreaEffectCloud) { return new CraftAreaEffectCloud(server, (EntityAreaEffectCloud) entity); }
else if (entity instanceof EntityEvokerFangs) { return new CraftEvokerFangs(server, (EntityEvokerFangs) entity); }
else if (entity instanceof EntityLlamaSpit) { return new CraftLlamaSpit(server, (EntityLlamaSpit) entity); }
else if (entity instanceof Marker) { return new CraftMarker(server, (Marker) entity); }
else if (entity instanceof Interaction) { return new CraftInteraction(server, (Interaction) entity); }
else if (entity instanceof Display) {
if (entity instanceof Display.BlockDisplay) { return new CraftBlockDisplay(server, (Display.BlockDisplay) entity); }
else if (entity instanceof Display.ItemDisplay) { return new CraftItemDisplay(server, (Display.ItemDisplay) entity); }
else if (entity instanceof Display.TextDisplay) { return new CraftTextDisplay(server, (Display.TextDisplay) entity); }
else { return new CraftDisplay(server, (Display) entity); }
}
// CHECKSTYLE:ON
throw new AssertionError("Unknown entity " + (entity == null ? null : entity.getClass()));
}

View File

@ -0,0 +1,514 @@
package org.bukkit.craftbukkit.entity;
import com.google.common.base.Preconditions;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Function;
import net.minecraft.core.BlockPosition;
import net.minecraft.core.EnumDirection;
import net.minecraft.world.entity.EntityAreaEffectCloud;
import net.minecraft.world.entity.EntityExperienceOrb;
import net.minecraft.world.entity.EntityTypes;
import net.minecraft.world.entity.boss.enderdragon.EntityEnderDragon;
import net.minecraft.world.entity.decoration.EntityHanging;
import net.minecraft.world.entity.decoration.EntityItemFrame;
import net.minecraft.world.entity.decoration.EntityLeash;
import net.minecraft.world.entity.decoration.EntityPainting;
import net.minecraft.world.entity.item.EntityFallingBlock;
import net.minecraft.world.entity.item.EntityItem;
import net.minecraft.world.entity.item.EntityTNTPrimed;
import net.minecraft.world.entity.projectile.EntityEgg;
import net.minecraft.world.entity.projectile.EntityEnderSignal;
import net.minecraft.world.entity.projectile.EntityEvokerFangs;
import net.minecraft.world.entity.projectile.EntityFireball;
import net.minecraft.world.entity.projectile.EntityFireworks;
import net.minecraft.world.entity.projectile.EntityPotion;
import net.minecraft.world.entity.projectile.EntitySnowball;
import net.minecraft.world.entity.vehicle.EntityMinecartChest;
import net.minecraft.world.entity.vehicle.EntityMinecartCommandBlock;
import net.minecraft.world.entity.vehicle.EntityMinecartFurnace;
import net.minecraft.world.entity.vehicle.EntityMinecartHopper;
import net.minecraft.world.entity.vehicle.EntityMinecartMobSpawner;
import net.minecraft.world.entity.vehicle.EntityMinecartRideable;
import net.minecraft.world.entity.vehicle.EntityMinecartTNT;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.GeneratorAccessSeed;
import net.minecraft.world.level.World;
import net.minecraft.world.level.block.BlockDiodeAbstract;
import net.minecraft.world.level.block.state.IBlockData;
import net.minecraft.world.phys.AxisAlignedBB;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.block.CraftBlock;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.entity.Allay;
import org.bukkit.entity.AreaEffectCloud;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Axolotl;
import org.bukkit.entity.Bat;
import org.bukkit.entity.Bee;
import org.bukkit.entity.Blaze;
import org.bukkit.entity.BlockDisplay;
import org.bukkit.entity.Boat;
import org.bukkit.entity.Breeze;
import org.bukkit.entity.Camel;
import org.bukkit.entity.Cat;
import org.bukkit.entity.CaveSpider;
import org.bukkit.entity.ChestBoat;
import org.bukkit.entity.Chicken;
import org.bukkit.entity.Cod;
import org.bukkit.entity.Cow;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Dolphin;
import org.bukkit.entity.Donkey;
import org.bukkit.entity.DragonFireball;
import org.bukkit.entity.Drowned;
import org.bukkit.entity.Egg;
import org.bukkit.entity.ElderGuardian;
import org.bukkit.entity.EnderCrystal;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.EnderPearl;
import org.bukkit.entity.EnderSignal;
import org.bukkit.entity.Enderman;
import org.bukkit.entity.Endermite;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Evoker;
import org.bukkit.entity.EvokerFangs;
import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Firework;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Fox;
import org.bukkit.entity.Frog;
import org.bukkit.entity.Ghast;
import org.bukkit.entity.Giant;
import org.bukkit.entity.GlowItemFrame;
import org.bukkit.entity.GlowSquid;
import org.bukkit.entity.Goat;
import org.bukkit.entity.Guardian;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.Hoglin;
import org.bukkit.entity.Horse;
import org.bukkit.entity.Husk;
import org.bukkit.entity.Illusioner;
import org.bukkit.entity.Interaction;
import org.bukkit.entity.IronGolem;
import org.bukkit.entity.Item;
import org.bukkit.entity.ItemDisplay;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.LargeFireball;
import org.bukkit.entity.LeashHitch;
import org.bukkit.entity.LightningStrike;
import org.bukkit.entity.Llama;
import org.bukkit.entity.LlamaSpit;
import org.bukkit.entity.MagmaCube;
import org.bukkit.entity.Marker;
import org.bukkit.entity.Mule;
import org.bukkit.entity.MushroomCow;
import org.bukkit.entity.Ocelot;
import org.bukkit.entity.Painting;
import org.bukkit.entity.Panda;
import org.bukkit.entity.Parrot;
import org.bukkit.entity.Phantom;
import org.bukkit.entity.Pig;
import org.bukkit.entity.PigZombie;
import org.bukkit.entity.Piglin;
import org.bukkit.entity.PiglinBrute;
import org.bukkit.entity.Pillager;
import org.bukkit.entity.Player;
import org.bukkit.entity.PolarBear;
import org.bukkit.entity.PufferFish;
import org.bukkit.entity.Rabbit;
import org.bukkit.entity.Ravager;
import org.bukkit.entity.Salmon;
import org.bukkit.entity.Sheep;
import org.bukkit.entity.Shulker;
import org.bukkit.entity.ShulkerBullet;
import org.bukkit.entity.Silverfish;
import org.bukkit.entity.Skeleton;
import org.bukkit.entity.SkeletonHorse;
import org.bukkit.entity.Slime;
import org.bukkit.entity.SmallFireball;
import org.bukkit.entity.Sniffer;
import org.bukkit.entity.Snowball;
import org.bukkit.entity.Snowman;
import org.bukkit.entity.SpectralArrow;
import org.bukkit.entity.Spider;
import org.bukkit.entity.Squid;
import org.bukkit.entity.Stray;
import org.bukkit.entity.Strider;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.entity.Tadpole;
import org.bukkit.entity.TextDisplay;
import org.bukkit.entity.ThrownExpBottle;
import org.bukkit.entity.ThrownPotion;
import org.bukkit.entity.TraderLlama;
import org.bukkit.entity.Trident;
import org.bukkit.entity.TropicalFish;
import org.bukkit.entity.Turtle;
import org.bukkit.entity.Vex;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Vindicator;
import org.bukkit.entity.WanderingTrader;
import org.bukkit.entity.Warden;
import org.bukkit.entity.WindCharge;
import org.bukkit.entity.Witch;
import org.bukkit.entity.Wither;
import org.bukkit.entity.WitherSkeleton;
import org.bukkit.entity.WitherSkull;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.Zoglin;
import org.bukkit.entity.Zombie;
import org.bukkit.entity.ZombieHorse;
import org.bukkit.entity.ZombieVillager;
import org.bukkit.entity.minecart.CommandMinecart;
import org.bukkit.entity.minecart.ExplosiveMinecart;
import org.bukkit.entity.minecart.HopperMinecart;
import org.bukkit.entity.minecart.PoweredMinecart;
import org.bukkit.entity.minecart.RideableMinecart;
import org.bukkit.entity.minecart.SpawnerMinecart;
import org.bukkit.entity.minecart.StorageMinecart;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.Vector;
public final class CraftEntityTypes {
public record EntityTypeData<E extends Entity, M extends net.minecraft.world.entity.Entity>(EntityType entityType,
Class<E> entityClass,
BiFunction<CraftServer, M, CraftEntity> convertFunction,
Function<SpawnData, M> spawnFunction) {
}
public record SpawnData(GeneratorAccessSeed world, Location location, boolean randomizeData, boolean normalWorld) {
double x() {
return location().getX();
}
double y() {
return location().getY();
}
double z() {
return location().getZ();
}
float yaw() {
return location().getYaw();
}
float pitch() {
return location().getPitch();
}
World minecraftWorld() {
return world().getMinecraftWorld();
}
}
private static final BiConsumer<SpawnData, net.minecraft.world.entity.Entity> POS = (spawnData, entity) -> entity.setPos(spawnData.x(), spawnData.y(), spawnData.z());
private static final BiConsumer<SpawnData, net.minecraft.world.entity.Entity> ABS_MOVE = (spawnData, entity) -> {
entity.absMoveTo(spawnData.x(), spawnData.y(), spawnData.z(), spawnData.yaw(), spawnData.pitch());
entity.setYHeadRot(spawnData.yaw()); // SPIGOT-3587
};
private static final BiConsumer<SpawnData, net.minecraft.world.entity.Entity> MOVE = (spawnData, entity) -> entity.moveTo(spawnData.x(), spawnData.y(), spawnData.z(), spawnData.yaw(), spawnData.pitch());
private static final BiConsumer<SpawnData, net.minecraft.world.entity.Entity> MOVE_EMPTY_ROT = (spawnData, entity) -> entity.moveTo(spawnData.x(), spawnData.y(), spawnData.z(), 0, 0);
private static final BiConsumer<SpawnData, EntityFireball> DIRECTION = (spawnData, entity) -> {
Vector direction = spawnData.location().getDirection().multiply(10);
entity.setDirection(direction.getX(), direction.getY(), direction.getZ());
};
private static final Map<Class<?>, EntityTypeData<?, ?>> CLASS_TYPE_DATA = new HashMap<>();
private static final Map<EntityType, EntityTypeData<?, ?>> ENTITY_TYPE_DATA = new HashMap<>();
static {
// Living
register(new EntityTypeData<>(EntityType.ELDER_GUARDIAN, ElderGuardian.class, CraftElderGuardian::new, createLiving(EntityTypes.ELDER_GUARDIAN)));
register(new EntityTypeData<>(EntityType.WITHER_SKELETON, WitherSkeleton.class, CraftWitherSkeleton::new, createLiving(EntityTypes.WITHER_SKELETON)));
register(new EntityTypeData<>(EntityType.STRAY, Stray.class, CraftStray::new, createLiving(EntityTypes.STRAY)));
register(new EntityTypeData<>(EntityType.HUSK, Husk.class, CraftHusk::new, createLiving(EntityTypes.HUSK)));
register(new EntityTypeData<>(EntityType.ZOMBIE_VILLAGER, ZombieVillager.class, CraftVillagerZombie::new, createLiving(EntityTypes.ZOMBIE_VILLAGER)));
register(new EntityTypeData<>(EntityType.SKELETON_HORSE, SkeletonHorse.class, CraftSkeletonHorse::new, createLiving(EntityTypes.SKELETON_HORSE)));
register(new EntityTypeData<>(EntityType.ZOMBIE_HORSE, ZombieHorse.class, CraftZombieHorse::new, createLiving(EntityTypes.ZOMBIE_HORSE)));
register(new EntityTypeData<>(EntityType.ARMOR_STAND, ArmorStand.class, CraftArmorStand::new, createLiving(EntityTypes.ARMOR_STAND)));
register(new EntityTypeData<>(EntityType.DONKEY, Donkey.class, CraftDonkey::new, createLiving(EntityTypes.DONKEY)));
register(new EntityTypeData<>(EntityType.MULE, Mule.class, CraftMule::new, createLiving(EntityTypes.MULE)));
register(new EntityTypeData<>(EntityType.EVOKER, Evoker.class, CraftEvoker::new, createLiving(EntityTypes.EVOKER)));
register(new EntityTypeData<>(EntityType.VEX, Vex.class, CraftVex::new, createLiving(EntityTypes.VEX)));
register(new EntityTypeData<>(EntityType.VINDICATOR, Vindicator.class, CraftVindicator::new, createLiving(EntityTypes.VINDICATOR)));
register(new EntityTypeData<>(EntityType.ILLUSIONER, Illusioner.class, CraftIllusioner::new, createLiving(EntityTypes.ILLUSIONER)));
register(new EntityTypeData<>(EntityType.CREEPER, Creeper.class, CraftCreeper::new, createLiving(EntityTypes.CREEPER)));
register(new EntityTypeData<>(EntityType.SKELETON, Skeleton.class, CraftSkeleton::new, createLiving(EntityTypes.SKELETON)));
register(new EntityTypeData<>(EntityType.SPIDER, Spider.class, CraftSpider::new, createLiving(EntityTypes.SPIDER)));
register(new EntityTypeData<>(EntityType.GIANT, Giant.class, CraftGiant::new, createLiving(EntityTypes.GIANT)));
register(new EntityTypeData<>(EntityType.ZOMBIE, Zombie.class, CraftZombie::new, createLiving(EntityTypes.ZOMBIE)));
register(new EntityTypeData<>(EntityType.SLIME, Slime.class, CraftSlime::new, createLiving(EntityTypes.SLIME)));
register(new EntityTypeData<>(EntityType.GHAST, Ghast.class, CraftGhast::new, createLiving(EntityTypes.GHAST)));
register(new EntityTypeData<>(EntityType.ZOMBIFIED_PIGLIN, PigZombie.class, CraftPigZombie::new, createLiving(EntityTypes.ZOMBIFIED_PIGLIN)));
register(new EntityTypeData<>(EntityType.ENDERMAN, Enderman.class, CraftEnderman::new, createLiving(EntityTypes.ENDERMAN)));
register(new EntityTypeData<>(EntityType.CAVE_SPIDER, CaveSpider.class, CraftCaveSpider::new, createLiving(EntityTypes.CAVE_SPIDER)));
register(new EntityTypeData<>(EntityType.SILVERFISH, Silverfish.class, CraftSilverfish::new, createLiving(EntityTypes.SILVERFISH)));
register(new EntityTypeData<>(EntityType.BLAZE, Blaze.class, CraftBlaze::new, createLiving(EntityTypes.BLAZE)));
register(new EntityTypeData<>(EntityType.MAGMA_CUBE, MagmaCube.class, CraftMagmaCube::new, createLiving(EntityTypes.MAGMA_CUBE)));
register(new EntityTypeData<>(EntityType.WITHER, Wither.class, CraftWither::new, createLiving(EntityTypes.WITHER)));
register(new EntityTypeData<>(EntityType.BAT, Bat.class, CraftBat::new, createLiving(EntityTypes.BAT)));
register(new EntityTypeData<>(EntityType.WITCH, Witch.class, CraftWitch::new, createLiving(EntityTypes.WITCH)));
register(new EntityTypeData<>(EntityType.ENDERMITE, Endermite.class, CraftEndermite::new, createLiving(EntityTypes.ENDERMITE)));
register(new EntityTypeData<>(EntityType.GUARDIAN, Guardian.class, CraftGuardian::new, createLiving(EntityTypes.GUARDIAN)));
register(new EntityTypeData<>(EntityType.SHULKER, Shulker.class, CraftShulker::new, createLiving(EntityTypes.SHULKER)));
register(new EntityTypeData<>(EntityType.PIG, Pig.class, CraftPig::new, createLiving(EntityTypes.PIG)));
register(new EntityTypeData<>(EntityType.SHEEP, Sheep.class, CraftSheep::new, createLiving(EntityTypes.SHEEP)));
register(new EntityTypeData<>(EntityType.COW, Cow.class, CraftCow::new, createLiving(EntityTypes.COW)));
register(new EntityTypeData<>(EntityType.CHICKEN, Chicken.class, CraftChicken::new, createLiving(EntityTypes.CHICKEN)));
register(new EntityTypeData<>(EntityType.SQUID, Squid.class, CraftSquid::new, createLiving(EntityTypes.SQUID)));
register(new EntityTypeData<>(EntityType.WOLF, Wolf.class, CraftWolf::new, createLiving(EntityTypes.WOLF)));
register(new EntityTypeData<>(EntityType.MUSHROOM_COW, MushroomCow.class, CraftMushroomCow::new, createLiving(EntityTypes.MOOSHROOM)));
register(new EntityTypeData<>(EntityType.SNOWMAN, Snowman.class, CraftSnowman::new, createLiving(EntityTypes.SNOW_GOLEM)));
register(new EntityTypeData<>(EntityType.OCELOT, Ocelot.class, CraftOcelot::new, createLiving(EntityTypes.OCELOT)));
register(new EntityTypeData<>(EntityType.IRON_GOLEM, IronGolem.class, CraftIronGolem::new, createLiving(EntityTypes.IRON_GOLEM)));
register(new EntityTypeData<>(EntityType.HORSE, Horse.class, CraftHorse::new, createLiving(EntityTypes.HORSE)));
register(new EntityTypeData<>(EntityType.RABBIT, Rabbit.class, CraftRabbit::new, createLiving(EntityTypes.RABBIT)));
register(new EntityTypeData<>(EntityType.POLAR_BEAR, PolarBear.class, CraftPolarBear::new, createLiving(EntityTypes.POLAR_BEAR)));
register(new EntityTypeData<>(EntityType.LLAMA, Llama.class, CraftLlama::new, createLiving(EntityTypes.LLAMA)));
register(new EntityTypeData<>(EntityType.PARROT, Parrot.class, CraftParrot::new, createLiving(EntityTypes.PARROT)));
register(new EntityTypeData<>(EntityType.VILLAGER, Villager.class, CraftVillager::new, createLiving(EntityTypes.VILLAGER)));
register(new EntityTypeData<>(EntityType.TURTLE, Turtle.class, CraftTurtle::new, createLiving(EntityTypes.TURTLE)));
register(new EntityTypeData<>(EntityType.PHANTOM, Phantom.class, CraftPhantom::new, createLiving(EntityTypes.PHANTOM)));
register(new EntityTypeData<>(EntityType.COD, Cod.class, CraftCod::new, createLiving(EntityTypes.COD)));
register(new EntityTypeData<>(EntityType.SALMON, Salmon.class, CraftSalmon::new, createLiving(EntityTypes.SALMON)));
register(new EntityTypeData<>(EntityType.PUFFERFISH, PufferFish.class, CraftPufferFish::new, createLiving(EntityTypes.PUFFERFISH)));
register(new EntityTypeData<>(EntityType.TROPICAL_FISH, TropicalFish.class, CraftTropicalFish::new, createLiving(EntityTypes.TROPICAL_FISH)));
register(new EntityTypeData<>(EntityType.DROWNED, Drowned.class, CraftDrowned::new, createLiving(EntityTypes.DROWNED)));
register(new EntityTypeData<>(EntityType.DOLPHIN, Dolphin.class, CraftDolphin::new, createLiving(EntityTypes.DOLPHIN)));
register(new EntityTypeData<>(EntityType.CAT, Cat.class, CraftCat::new, createLiving(EntityTypes.CAT)));
register(new EntityTypeData<>(EntityType.PANDA, Panda.class, CraftPanda::new, createLiving(EntityTypes.PANDA)));
register(new EntityTypeData<>(EntityType.PILLAGER, Pillager.class, CraftPillager::new, createLiving(EntityTypes.PILLAGER)));
register(new EntityTypeData<>(EntityType.RAVAGER, Ravager.class, CraftRavager::new, createLiving(EntityTypes.RAVAGER)));
register(new EntityTypeData<>(EntityType.TRADER_LLAMA, TraderLlama.class, CraftTraderLlama::new, createLiving(EntityTypes.TRADER_LLAMA)));
register(new EntityTypeData<>(EntityType.WANDERING_TRADER, WanderingTrader.class, CraftWanderingTrader::new, createLiving(EntityTypes.WANDERING_TRADER)));
register(new EntityTypeData<>(EntityType.FOX, Fox.class, CraftFox::new, createLiving(EntityTypes.FOX)));
register(new EntityTypeData<>(EntityType.BEE, Bee.class, CraftBee::new, createLiving(EntityTypes.BEE)));
register(new EntityTypeData<>(EntityType.HOGLIN, Hoglin.class, CraftHoglin::new, createLiving(EntityTypes.HOGLIN)));
register(new EntityTypeData<>(EntityType.PIGLIN, Piglin.class, CraftPiglin::new, createLiving(EntityTypes.PIGLIN)));
register(new EntityTypeData<>(EntityType.STRIDER, Strider.class, CraftStrider::new, createLiving(EntityTypes.STRIDER)));
register(new EntityTypeData<>(EntityType.ZOGLIN, Zoglin.class, CraftZoglin::new, createLiving(EntityTypes.ZOGLIN)));
register(new EntityTypeData<>(EntityType.PIGLIN_BRUTE, PiglinBrute.class, CraftPiglinBrute::new, createLiving(EntityTypes.PIGLIN_BRUTE)));
register(new EntityTypeData<>(EntityType.AXOLOTL, Axolotl.class, CraftAxolotl::new, createLiving(EntityTypes.AXOLOTL)));
register(new EntityTypeData<>(EntityType.GLOW_SQUID, GlowSquid.class, CraftGlowSquid::new, createLiving(EntityTypes.GLOW_SQUID)));
register(new EntityTypeData<>(EntityType.GOAT, Goat.class, CraftGoat::new, createLiving(EntityTypes.GOAT)));
register(new EntityTypeData<>(EntityType.ALLAY, Allay.class, CraftAllay::new, createLiving(EntityTypes.ALLAY)));
register(new EntityTypeData<>(EntityType.FROG, Frog.class, CraftFrog::new, createLiving(EntityTypes.FROG)));
register(new EntityTypeData<>(EntityType.TADPOLE, Tadpole.class, CraftTadpole::new, createLiving(EntityTypes.TADPOLE)));
register(new EntityTypeData<>(EntityType.WARDEN, Warden.class, CraftWarden::new, createLiving(EntityTypes.WARDEN)));
register(new EntityTypeData<>(EntityType.CAMEL, Camel.class, CraftCamel::new, createLiving(EntityTypes.CAMEL)));
register(new EntityTypeData<>(EntityType.SNIFFER, Sniffer.class, CraftSniffer::new, createLiving(EntityTypes.SNIFFER)));
register(new EntityTypeData<>(EntityType.BREEZE, Breeze.class, CraftBreeze::new, createLiving(EntityTypes.BREEZE)));
Function<SpawnData, EntityEnderDragon> dragonFunction = createLiving(EntityTypes.ENDER_DRAGON);
register(new EntityTypeData<>(EntityType.ENDER_DRAGON, EnderDragon.class, CraftEnderDragon::new, spawnData -> {
Preconditions.checkArgument(spawnData.normalWorld(), "Cannot spawn entity %s during world generation", EnderDragon.class.getName());
return dragonFunction.apply(spawnData);
}));
// Fireball
register(new EntityTypeData<>(EntityType.FIREBALL, LargeFireball.class, CraftLargeFireball::new, createFireball(EntityTypes.FIREBALL)));
register(new EntityTypeData<>(EntityType.SMALL_FIREBALL, SmallFireball.class, CraftSmallFireball::new, createFireball(EntityTypes.SMALL_FIREBALL)));
register(new EntityTypeData<>(EntityType.WITHER_SKULL, WitherSkull.class, CraftWitherSkull::new, createFireball(EntityTypes.WITHER_SKULL)));
register(new EntityTypeData<>(EntityType.DRAGON_FIREBALL, DragonFireball.class, CraftDragonFireball::new, createFireball(EntityTypes.DRAGON_FIREBALL)));
register(new EntityTypeData<>(EntityType.WIND_CHARGE, WindCharge.class, CraftWindCharge::new, createFireball(EntityTypes.WIND_CHARGE)));
// Hanging
register(new EntityTypeData<>(EntityType.PAINTING, Painting.class, CraftPainting::new, createHanging(Painting.class, (spawnData, hangingData) -> {
if (spawnData.normalWorld && hangingData.randomize()) {
return EntityPainting.create(spawnData.minecraftWorld(), hangingData.position(), hangingData.direction()).orElse(null);
} else {
EntityPainting entity = new EntityPainting(EntityTypes.PAINTING, spawnData.minecraftWorld());
entity.absMoveTo(spawnData.x(), spawnData.y(), spawnData.z(), spawnData.yaw(), spawnData.pitch());
entity.setDirection(hangingData.direction());
return entity;
}
}
)));
register(new EntityTypeData<>(EntityType.ITEM_FRAME, ItemFrame.class, CraftItemFrame::new, createHanging(ItemFrame.class, (spawnData, hangingData) -> new EntityItemFrame(spawnData.minecraftWorld(), hangingData.position(), hangingData.direction()))));
register(new EntityTypeData<>(EntityType.GLOW_ITEM_FRAME, GlowItemFrame.class, CraftGlowItemFrame::new, createHanging(GlowItemFrame.class, (spawnData, hangingData) -> new net.minecraft.world.entity.decoration.GlowItemFrame(spawnData.minecraftWorld(), hangingData.position(), hangingData.direction()))));
// Move no rotation
register(new EntityTypeData<>(EntityType.ARROW, Arrow.class, CraftArrow::new, createAndMoveEmptyRot(EntityTypes.ARROW)));
register(new EntityTypeData<>(EntityType.ENDER_PEARL, EnderPearl.class, CraftEnderPearl::new, createAndMoveEmptyRot(EntityTypes.ENDER_PEARL)));
register(new EntityTypeData<>(EntityType.THROWN_EXP_BOTTLE, ThrownExpBottle.class, CraftThrownExpBottle::new, createAndMoveEmptyRot(EntityTypes.EXPERIENCE_BOTTLE)));
register(new EntityTypeData<>(EntityType.SPECTRAL_ARROW, SpectralArrow.class, CraftSpectralArrow::new, createAndMoveEmptyRot(EntityTypes.SPECTRAL_ARROW)));
register(new EntityTypeData<>(EntityType.ENDER_CRYSTAL, EnderCrystal.class, CraftEnderCrystal::new, createAndMoveEmptyRot(EntityTypes.END_CRYSTAL)));
register(new EntityTypeData<>(EntityType.TRIDENT, Trident.class, CraftTrident::new, createAndMoveEmptyRot(EntityTypes.TRIDENT)));
register(new EntityTypeData<>(EntityType.LIGHTNING, LightningStrike.class, CraftLightningStrike::new, createAndMoveEmptyRot(EntityTypes.LIGHTNING_BOLT)));
// Move
register(new EntityTypeData<>(EntityType.SHULKER_BULLET, ShulkerBullet.class, CraftShulkerBullet::new, createAndMove(EntityTypes.SHULKER_BULLET)));
register(new EntityTypeData<>(EntityType.BOAT, Boat.class, CraftBoat::new, createAndMove(EntityTypes.BOAT)));
register(new EntityTypeData<>(EntityType.LLAMA_SPIT, LlamaSpit.class, CraftLlamaSpit::new, createAndMove(EntityTypes.LLAMA_SPIT)));
register(new EntityTypeData<>(EntityType.CHEST_BOAT, ChestBoat.class, CraftChestBoat::new, createAndMove(EntityTypes.CHEST_BOAT)));
// Set pos
register(new EntityTypeData<>(EntityType.MARKER, Marker.class, CraftMarker::new, createAndSetPos(EntityTypes.MARKER)));
register(new EntityTypeData<>(EntityType.BLOCK_DISPLAY, BlockDisplay.class, CraftBlockDisplay::new, createAndSetPos(EntityTypes.BLOCK_DISPLAY)));
register(new EntityTypeData<>(EntityType.INTERACTION, Interaction.class, CraftInteraction::new, createAndSetPos(EntityTypes.INTERACTION)));
register(new EntityTypeData<>(EntityType.ITEM_DISPLAY, ItemDisplay.class, CraftItemDisplay::new, createAndSetPos(EntityTypes.ITEM_DISPLAY)));
register(new EntityTypeData<>(EntityType.TEXT_DISPLAY, TextDisplay.class, CraftTextDisplay::new, createAndSetPos(EntityTypes.TEXT_DISPLAY)));
// MISC
register(new EntityTypeData<>(EntityType.DROPPED_ITEM, Item.class, CraftItem::new, spawnData -> {
// We use stone instead of empty, to give the plugin developer a visual clue, that the spawn method is working,
// and that the item stack should probably be changed.
net.minecraft.world.item.ItemStack itemStack = new net.minecraft.world.item.ItemStack(Items.STONE);
EntityItem item = new EntityItem(spawnData.minecraftWorld(), spawnData.x(), spawnData.z(), spawnData.z(), itemStack);
item.setPickUpDelay(10);
return item;
}));
register(new EntityTypeData<>(EntityType.EXPERIENCE_ORB, ExperienceOrb.class, CraftExperienceOrb::new,
spawnData -> new EntityExperienceOrb(spawnData.minecraftWorld(), spawnData.x(), spawnData.z(), spawnData.z(), 0)
));
register(new EntityTypeData<>(EntityType.AREA_EFFECT_CLOUD, AreaEffectCloud.class, CraftAreaEffectCloud::new, spawnData -> new EntityAreaEffectCloud(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
register(new EntityTypeData<>(EntityType.EGG, Egg.class, CraftEgg::new, spawnData -> new EntityEgg(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
register(new EntityTypeData<>(EntityType.LEASH_HITCH, LeashHitch.class, CraftLeash::new, spawnData -> new EntityLeash(spawnData.minecraftWorld(), BlockPosition.containing(spawnData.x(), spawnData.y(), spawnData.z())))); // SPIGOT-5732: LeashHitch has no direction and is always centered at a block
register(new EntityTypeData<>(EntityType.SNOWBALL, Snowball.class, CraftSnowball::new, spawnData -> new EntitySnowball(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
register(new EntityTypeData<>(EntityType.ENDER_SIGNAL, EnderSignal.class, CraftEnderSignal::new, spawnData -> new EntityEnderSignal(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
register(new EntityTypeData<>(EntityType.SPLASH_POTION, ThrownPotion.class, CraftThrownPotion::new, spawnData -> {
EntityPotion entity = new EntityPotion(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z());
entity.setItem(CraftItemStack.asNMSCopy(new ItemStack(Material.SPLASH_POTION, 1)));
return entity;
}));
register(new EntityTypeData<>(EntityType.PRIMED_TNT, TNTPrimed.class, CraftTNTPrimed::new, spawnData -> new EntityTNTPrimed(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), null)));
register(new EntityTypeData<>(EntityType.FALLING_BLOCK, FallingBlock.class, CraftFallingBlock::new, spawnData -> {
BlockPosition pos = BlockPosition.containing(spawnData.x(), spawnData.y(), spawnData.z());
return EntityFallingBlock.fall(spawnData.minecraftWorld(), pos, spawnData.world().getBlockState(pos));
}));
register(new EntityTypeData<>(EntityType.FIREWORK, Firework.class, CraftFirework::new, spawnData -> new EntityFireworks(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), net.minecraft.world.item.ItemStack.EMPTY)));
register(new EntityTypeData<>(EntityType.EVOKER_FANGS, EvokerFangs.class, CraftEvokerFangs::new, spawnData -> new EntityEvokerFangs(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z(), (float) Math.toRadians(spawnData.yaw()), 0, null)));
register(new EntityTypeData<>(EntityType.MINECART_COMMAND, CommandMinecart.class, CraftMinecartCommand::new, spawnData -> new EntityMinecartCommandBlock(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
register(new EntityTypeData<>(EntityType.MINECART, RideableMinecart.class, CraftMinecartRideable::new, spawnData -> new EntityMinecartRideable(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
register(new EntityTypeData<>(EntityType.MINECART_CHEST, StorageMinecart.class, CraftMinecartChest::new, spawnData -> new EntityMinecartChest(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
register(new EntityTypeData<>(EntityType.MINECART_FURNACE, PoweredMinecart.class, CraftMinecartFurnace::new, spawnData -> new EntityMinecartFurnace(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
register(new EntityTypeData<>(EntityType.MINECART_TNT, ExplosiveMinecart.class, CraftMinecartTNT::new, spawnData -> new EntityMinecartTNT(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
register(new EntityTypeData<>(EntityType.MINECART_HOPPER, HopperMinecart.class, CraftMinecartHopper::new, spawnData -> new EntityMinecartHopper(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
register(new EntityTypeData<>(EntityType.MINECART_MOB_SPAWNER, SpawnerMinecart.class, CraftMinecartMobSpawner::new, spawnData -> new EntityMinecartMobSpawner(spawnData.minecraftWorld(), spawnData.x(), spawnData.y(), spawnData.z())));
// None spawn able
register(new EntityTypeData<>(EntityType.FISHING_HOOK, FishHook.class, CraftFishHook::new, null)); // Cannot spawn a fish hook
register(new EntityTypeData<>(EntityType.PLAYER, Player.class, CraftPlayer::new, null)); // Cannot spawn a player
}
private static void register(EntityTypeData<?, ?> typeData) {
EntityTypeData<?, ?> other = CLASS_TYPE_DATA.put(typeData.entityClass(), typeData);
if (other != null) {
Bukkit.getLogger().warning(String.format("Found multiple entity type data for class %s, replacing '%s' with new value '%s'", typeData.entityClass().getName(), other, typeData));
}
other = ENTITY_TYPE_DATA.put(typeData.entityType(), typeData);
if (other != null) {
Bukkit.getLogger().warning(String.format("Found multiple entity type data for entity type %s, replacing '%s' with new value '%s'", typeData.entityType().getKey(), other, typeData));
}
}
private static <R extends net.minecraft.world.entity.Entity> Function<SpawnData, R> fromEntityType(EntityTypes<R> entityTypes) {
return spawnData -> entityTypes.create(spawnData.minecraftWorld());
}
private static <R extends net.minecraft.world.entity.EntityLiving> Function<SpawnData, R> createLiving(EntityTypes<R> entityTypes) {
return combine(fromEntityType(entityTypes), ABS_MOVE);
}
private static <R extends EntityFireball> Function<SpawnData, R> createFireball(EntityTypes<R> entityTypes) {
return combine(createAndMove(entityTypes), DIRECTION);
}
private static <R extends net.minecraft.world.entity.Entity> Function<SpawnData, R> createAndMove(EntityTypes<R> entityTypes) {
return combine(fromEntityType(entityTypes), MOVE);
}
private static <R extends net.minecraft.world.entity.Entity> Function<SpawnData, R> createAndMoveEmptyRot(EntityTypes<R> entityTypes) {
return combine(fromEntityType(entityTypes), MOVE_EMPTY_ROT);
}
private static <R extends net.minecraft.world.entity.Entity> Function<SpawnData, R> createAndSetPos(EntityTypes<R> entityTypes) {
return combine(fromEntityType(entityTypes), POS);
}
private record HangingData(boolean randomize, BlockPosition position, EnumDirection direction) {
}
private static <E extends Hanging, R extends EntityHanging> Function<SpawnData, R> createHanging(Class<E> clazz, BiFunction<SpawnData, HangingData, R> spawnFunction) {
return spawnData -> {
boolean randomizeData = spawnData.randomizeData();
BlockFace face = BlockFace.SELF;
BlockFace[] faces = new BlockFace[]{BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH};
int width = 16; // 1 full block, also painting smallest size.
int height = 16; // 1 full block, also painting smallest size.
if (ItemFrame.class.isAssignableFrom(clazz)) {
width = 12;
height = 12;
faces = new BlockFace[]{BlockFace.EAST, BlockFace.NORTH, BlockFace.WEST, BlockFace.SOUTH, BlockFace.UP, BlockFace.DOWN};
}
final BlockPosition pos = BlockPosition.containing(spawnData.x(), spawnData.y(), spawnData.z());
for (BlockFace dir : faces) {
IBlockData nmsBlock = spawnData.world().getBlockState(pos.relative(CraftBlock.blockFaceToNotch(dir)));
if (nmsBlock.isSolid() || BlockDiodeAbstract.isDiode(nmsBlock)) {
boolean taken = false;
AxisAlignedBB bb = (ItemFrame.class.isAssignableFrom(clazz))
? EntityItemFrame.calculateBoundingBox(null, pos, CraftBlock.blockFaceToNotch(dir).getOpposite(), width, height)
: EntityHanging.calculateBoundingBox(null, pos, CraftBlock.blockFaceToNotch(dir).getOpposite(), width, height);
List<net.minecraft.world.entity.Entity> list = spawnData.world().getEntities(null, bb);
for (Iterator<net.minecraft.world.entity.Entity> it = list.iterator(); !taken && it.hasNext(); ) {
net.minecraft.world.entity.Entity e = it.next();
if (e instanceof EntityHanging) {
taken = true; // Hanging entities do not like hanging entities which intersect them.
}
}
if (!taken) {
face = dir;
break;
}
}
}
// No valid face found
if (face == BlockFace.SELF) {
// SPIGOT-6387: Allow hanging entities to be placed in midair
face = BlockFace.SOUTH;
randomizeData = false; // Don't randomize if no valid face is found, prevents null painting
}
EnumDirection dir = CraftBlock.blockFaceToNotch(face).getOpposite();
return spawnFunction.apply(spawnData, new HangingData(randomizeData, pos, dir));
};
}
private static <T, R> Function<T, R> combine(Function<T, R> before, BiConsumer<T, ? super R> after) {
return (t) -> {
R r = before.apply(t);
after.accept(t, r);
return r;
};
}
public static <E extends Entity, M extends net.minecraft.world.entity.Entity> EntityTypeData<E, M> getEntityTypeData(EntityType entityType) {
return (EntityTypeData<E, M>) ENTITY_TYPE_DATA.get(entityType);
}
public static <E extends Entity, M extends net.minecraft.world.entity.Entity> EntityTypeData<E, M> getEntityTypeData(Class<E> entityClass) {
return (EntityTypeData<E, M>) CLASS_TYPE_DATA.get(entityClass);
}
private CraftEntityTypes() {
}
}

View File

@ -0,0 +1,183 @@
package org.bukkit.craftbukkit.entity;
import static org.junit.jupiter.api.Assertions.*;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.List;
import java.util.jar.JarFile;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import org.bukkit.entity.AbstractArrow;
import org.bukkit.entity.AbstractHorse;
import org.bukkit.entity.AbstractSkeleton;
import org.bukkit.entity.AbstractVillager;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Ambient;
import org.bukkit.entity.Animals;
import org.bukkit.entity.Boss;
import org.bukkit.entity.Breedable;
import org.bukkit.entity.ChestedHorse;
import org.bukkit.entity.ComplexEntityPart;
import org.bukkit.entity.ComplexLivingEntity;
import org.bukkit.entity.Creature;
import org.bukkit.entity.Damageable;
import org.bukkit.entity.Display;
import org.bukkit.entity.EnderDragonPart;
import org.bukkit.entity.Enemy;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Explosive;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.Fish;
import org.bukkit.entity.Flying;
import org.bukkit.entity.Golem;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Illager;
import org.bukkit.entity.LingeringPotion;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Minecart;
import org.bukkit.entity.Mob;
import org.bukkit.entity.Monster;
import org.bukkit.entity.NPC;
import org.bukkit.entity.PiglinAbstract;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.Raider;
import org.bukkit.entity.SizedFireball;
import org.bukkit.entity.Spellcaster;
import org.bukkit.entity.SplashPotion;
import org.bukkit.entity.Steerable;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.ThrowableProjectile;
import org.bukkit.entity.TippedArrow;
import org.bukkit.entity.Vehicle;
import org.bukkit.entity.WaterMob;
import org.bukkit.support.AbstractTestingBase;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
public class EntityTypesTest extends AbstractTestingBase {
private static final URI BUKKIT_CLASSES;
// Entity classes, which do not have any entity type / entity type data
private static final List<Class<? extends Entity>> EXCLUDE = Arrays.asList(
AbstractArrow.class,
AbstractHorse.class,
AbstractSkeleton.class,
AbstractVillager.class,
Ageable.class,
Ambient.class,
Animals.class,
Breedable.class,
Boss.class,
ChestedHorse.class,
ComplexEntityPart.class,
ComplexLivingEntity.class,
Creature.class,
Damageable.class,
Display.class,
EnderDragonPart.class,
Enemy.class,
Entity.class,
Explosive.class,
Fireball.class,
Fish.class,
Flying.class,
Golem.class,
Hanging.class,
HumanEntity.class,
Illager.class,
LingeringPotion.class,
LivingEntity.class,
Minecart.class,
Mob.class,
Monster.class,
NPC.class,
PiglinAbstract.class,
Projectile.class,
Raider.class,
SizedFireball.class,
Spellcaster.class,
SplashPotion.class,
Steerable.class,
Tameable.class,
ThrowableProjectile.class,
TippedArrow.class,
Vehicle.class,
WaterMob.class
);
static {
try {
BUKKIT_CLASSES = Entity.class.getProtectionDomain().getCodeSource().getLocation().toURI();
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
private static JarFile jarFile = null;
public static Stream<Arguments> excludedData() {
return EXCLUDE.stream().map(Arguments::arguments);
}
public static Stream<Arguments> data() {
return jarFile
.stream()
.map(ZipEntry::getName)
.filter(name -> name.endsWith(".class"))
.filter(name -> name.startsWith("org/bukkit/entity"))
.map(name -> name.substring(0, name.length() - ".class".length()))
.map(name -> name.replace('/', '.'))
.map(name -> {
try {
return Class.forName(name);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
})
.filter(Entity.class::isAssignableFrom)
.filter(clazz -> !EXCLUDE.contains(clazz))
.map(Arguments::arguments);
}
@BeforeAll
public static void beforeAll() throws IOException {
jarFile = new JarFile(new File(BUKKIT_CLASSES));
}
@ParameterizedTest
@MethodSource("excludedData")
public <T extends Entity> void testExcludedClass(Class<T> clazz) {
CraftEntityTypes.EntityTypeData<?, ?> entityTypeData = CraftEntityTypes.getEntityTypeData(clazz);
assertNull(entityTypeData, String.format("Class %s is marked as excluded, because it does not have an entity type data, but we found one entity type data, something is not adding up.", clazz));
}
@ParameterizedTest
@MethodSource("data")
public <T extends Entity> void testEntityClass(Class<T> clazz) {
CraftEntityTypes.EntityTypeData<?, ?> entityTypeData = CraftEntityTypes.getEntityTypeData(clazz);
assertNotNull(entityTypeData, String.format("Class %s does not have an entity type data, please add on to CraftEntityTypes or mark the class as excluded in EntityTypesTest, if the class does not have an entity type.", clazz));
}
@ParameterizedTest
@EnumSource(value = EntityType.class, names = "UNKNOWN", mode = EnumSource.Mode.EXCLUDE)
public void testEntityType(EntityType entityType) {
CraftEntityTypes.EntityTypeData<?, ?> entityTypeData = CraftEntityTypes.getEntityTypeData(entityType);
assertNotNull(entityTypeData, String.format("Entity type %s does not have an entity type data, please add on to CraftEntityTypes.", entityType));
}
@AfterAll
public static void clear() throws IOException {
if (jarFile != null) {
jarFile.close();
}
}
}