Merged with master

This commit is contained in:
Konstantin Shandurenko 2021-02-26 06:58:12 +03:00
commit 20f581cc11
217 changed files with 6335 additions and 772 deletions

View File

@ -1,7 +1,118 @@
package net.minestom.server.entity;
import java.util.function.BiFunction;
import net.minestom.server.entity.metadata.EntityMeta;
import net.minestom.server.entity.metadata.PlayerMeta;
import net.minestom.server.entity.metadata.ambient.BatMeta;
import net.minestom.server.entity.metadata.animal.BeeMeta;
import net.minestom.server.entity.metadata.animal.ChickenMeta;
import net.minestom.server.entity.metadata.animal.CowMeta;
import net.minestom.server.entity.metadata.animal.DonkeyMeta;
import net.minestom.server.entity.metadata.animal.FoxMeta;
import net.minestom.server.entity.metadata.animal.HoglinMeta;
import net.minestom.server.entity.metadata.animal.HorseMeta;
import net.minestom.server.entity.metadata.animal.LlamaMeta;
import net.minestom.server.entity.metadata.animal.MooshroomMeta;
import net.minestom.server.entity.metadata.animal.MuleMeta;
import net.minestom.server.entity.metadata.animal.OcelotMeta;
import net.minestom.server.entity.metadata.animal.PandaMeta;
import net.minestom.server.entity.metadata.animal.PigMeta;
import net.minestom.server.entity.metadata.animal.PolarBearMeta;
import net.minestom.server.entity.metadata.animal.RabbitMeta;
import net.minestom.server.entity.metadata.animal.SheepMeta;
import net.minestom.server.entity.metadata.animal.SkeletonHorseMeta;
import net.minestom.server.entity.metadata.animal.StriderMeta;
import net.minestom.server.entity.metadata.animal.TurtleMeta;
import net.minestom.server.entity.metadata.animal.ZombieHorseMeta;
import net.minestom.server.entity.metadata.animal.tameable.CatMeta;
import net.minestom.server.entity.metadata.animal.tameable.ParrotMeta;
import net.minestom.server.entity.metadata.animal.tameable.WolfMeta;
import net.minestom.server.entity.metadata.arrow.ArrowMeta;
import net.minestom.server.entity.metadata.arrow.SpectralArrowMeta;
import net.minestom.server.entity.metadata.arrow.ThrownTridentMeta;
import net.minestom.server.entity.metadata.flying.GhastMeta;
import net.minestom.server.entity.metadata.flying.PhantomMeta;
import net.minestom.server.entity.metadata.golem.IronGolemMeta;
import net.minestom.server.entity.metadata.golem.ShulkerMeta;
import net.minestom.server.entity.metadata.golem.SnowGolemMeta;
import net.minestom.server.entity.metadata.item.EyeOfEnderMeta;
import net.minestom.server.entity.metadata.item.FireballMeta;
import net.minestom.server.entity.metadata.item.ItemEntityMeta;
import net.minestom.server.entity.metadata.item.SmallFireballMeta;
import net.minestom.server.entity.metadata.item.SnowballMeta;
import net.minestom.server.entity.metadata.item.ThrownEggMeta;
import net.minestom.server.entity.metadata.item.ThrownEnderPearlMeta;
import net.minestom.server.entity.metadata.item.ThrownExperienceBottleMeta;
import net.minestom.server.entity.metadata.item.ThrownPotionMeta;
import net.minestom.server.entity.metadata.minecart.ChestMinecartMeta;
import net.minestom.server.entity.metadata.minecart.CommandBlockMinecartMeta;
import net.minestom.server.entity.metadata.minecart.FurnaceMinecartMeta;
import net.minestom.server.entity.metadata.minecart.HopperMinecartMeta;
import net.minestom.server.entity.metadata.minecart.MinecartMeta;
import net.minestom.server.entity.metadata.minecart.SpawnerMinecartMeta;
import net.minestom.server.entity.metadata.minecart.TntMinecartMeta;
import net.minestom.server.entity.metadata.monster.BlazeMeta;
import net.minestom.server.entity.metadata.monster.CaveSpiderMeta;
import net.minestom.server.entity.metadata.monster.CreeperMeta;
import net.minestom.server.entity.metadata.monster.ElderGuardianMeta;
import net.minestom.server.entity.metadata.monster.EndermanMeta;
import net.minestom.server.entity.metadata.monster.EndermiteMeta;
import net.minestom.server.entity.metadata.monster.GiantMeta;
import net.minestom.server.entity.metadata.monster.GuardianMeta;
import net.minestom.server.entity.metadata.monster.PiglinBruteMeta;
import net.minestom.server.entity.metadata.monster.PiglinMeta;
import net.minestom.server.entity.metadata.monster.SilverfishMeta;
import net.minestom.server.entity.metadata.monster.SpiderMeta;
import net.minestom.server.entity.metadata.monster.VexMeta;
import net.minestom.server.entity.metadata.monster.WitherMeta;
import net.minestom.server.entity.metadata.monster.ZoglinMeta;
import net.minestom.server.entity.metadata.monster.raider.EvokerMeta;
import net.minestom.server.entity.metadata.monster.raider.IllusionerMeta;
import net.minestom.server.entity.metadata.monster.raider.PillagerMeta;
import net.minestom.server.entity.metadata.monster.raider.RavagerMeta;
import net.minestom.server.entity.metadata.monster.raider.VindicatorMeta;
import net.minestom.server.entity.metadata.monster.raider.WitchMeta;
import net.minestom.server.entity.metadata.monster.skeleton.SkeletonMeta;
import net.minestom.server.entity.metadata.monster.skeleton.StrayMeta;
import net.minestom.server.entity.metadata.monster.skeleton.WitherSkeletonMeta;
import net.minestom.server.entity.metadata.monster.zombie.DrownedMeta;
import net.minestom.server.entity.metadata.monster.zombie.HuskMeta;
import net.minestom.server.entity.metadata.monster.zombie.ZombieMeta;
import net.minestom.server.entity.metadata.monster.zombie.ZombieVillagerMeta;
import net.minestom.server.entity.metadata.monster.zombie.ZombifiedPiglinMeta;
import net.minestom.server.entity.metadata.other.AreaEffectCloudMeta;
import net.minestom.server.entity.metadata.other.ArmorStandMeta;
import net.minestom.server.entity.metadata.other.BoatMeta;
import net.minestom.server.entity.metadata.other.DragonFireballMeta;
import net.minestom.server.entity.metadata.other.EndCrystalMeta;
import net.minestom.server.entity.metadata.other.EnderDragonMeta;
import net.minestom.server.entity.metadata.other.EvokerFangsMeta;
import net.minestom.server.entity.metadata.other.ExperienceOrbMeta;
import net.minestom.server.entity.metadata.other.FallingBlockMeta;
import net.minestom.server.entity.metadata.other.FireworkRocketMeta;
import net.minestom.server.entity.metadata.other.FishingHookMeta;
import net.minestom.server.entity.metadata.other.ItemFrameMeta;
import net.minestom.server.entity.metadata.other.LeashKnotMeta;
import net.minestom.server.entity.metadata.other.LightningBoltMeta;
import net.minestom.server.entity.metadata.other.LlamaSpitMeta;
import net.minestom.server.entity.metadata.other.MagmaCubeMeta;
import net.minestom.server.entity.metadata.other.PaintingMeta;
import net.minestom.server.entity.metadata.other.PrimedTntMeta;
import net.minestom.server.entity.metadata.other.ShulkerBulletMeta;
import net.minestom.server.entity.metadata.other.SlimeMeta;
import net.minestom.server.entity.metadata.other.TraderLlamaMeta;
import net.minestom.server.entity.metadata.other.WitherSkullMeta;
import net.minestom.server.entity.metadata.villager.VillagerMeta;
import net.minestom.server.entity.metadata.villager.WanderingTraderMeta;
import net.minestom.server.entity.metadata.water.DolphinMeta;
import net.minestom.server.entity.metadata.water.SquidMeta;
import net.minestom.server.entity.metadata.water.fish.CodMeta;
import net.minestom.server.entity.metadata.water.fish.PufferfishMeta;
import net.minestom.server.entity.metadata.water.fish.SalmonMeta;
import net.minestom.server.entity.metadata.water.fish.TropicalFishMeta;
import net.minestom.server.registry.Registries;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
/**
* //==============================
@ -10,241 +121,276 @@ import net.minestom.server.utils.NamespaceID;
*/
@SuppressWarnings({"deprecation"})
public enum EntityType {
AREA_EFFECT_CLOUD("minecraft:area_effect_cloud"),
AREA_EFFECT_CLOUD("minecraft:area_effect_cloud", 6.0, 0.5, AreaEffectCloudMeta::new, EntitySpawnType.BASE),
ARMOR_STAND("minecraft:armor_stand"),
ARMOR_STAND("minecraft:armor_stand", 0.5, 1.975, ArmorStandMeta::new, EntitySpawnType.LIVING),
ARROW("minecraft:arrow"),
ARROW("minecraft:arrow", 0.5, 0.5, ArrowMeta::new, EntitySpawnType.BASE),
BAT("minecraft:bat"),
BAT("minecraft:bat", 0.5, 0.9, BatMeta::new, EntitySpawnType.LIVING),
BEE("minecraft:bee"),
BEE("minecraft:bee", 0.7, 0.6, BeeMeta::new, EntitySpawnType.LIVING),
BLAZE("minecraft:blaze"),
BLAZE("minecraft:blaze", 0.6, 1.8, BlazeMeta::new, EntitySpawnType.LIVING),
BOAT("minecraft:boat"),
BOAT("minecraft:boat", 1.375, 0.5625, BoatMeta::new, EntitySpawnType.BASE),
CAT("minecraft:cat"),
CAT("minecraft:cat", 0.6, 0.7, CatMeta::new, EntitySpawnType.LIVING),
CAVE_SPIDER("minecraft:cave_spider"),
CAVE_SPIDER("minecraft:cave_spider", 0.7, 0.5, CaveSpiderMeta::new, EntitySpawnType.LIVING),
CHICKEN("minecraft:chicken"),
CHICKEN("minecraft:chicken", 0.4, 0.7, ChickenMeta::new, EntitySpawnType.LIVING),
COD("minecraft:cod"),
COD("minecraft:cod", 0.5, 0.3, CodMeta::new, EntitySpawnType.LIVING),
COW("minecraft:cow"),
COW("minecraft:cow", 0.9, 1.4, CowMeta::new, EntitySpawnType.LIVING),
CREEPER("minecraft:creeper"),
CREEPER("minecraft:creeper", 0.6, 1.7, CreeperMeta::new, EntitySpawnType.LIVING),
DOLPHIN("minecraft:dolphin"),
DOLPHIN("minecraft:dolphin", 0.9, 0.6, DolphinMeta::new, EntitySpawnType.LIVING),
DONKEY("minecraft:donkey"),
DONKEY("minecraft:donkey", 1.39648, 1.5, DonkeyMeta::new, EntitySpawnType.LIVING),
DRAGON_FIREBALL("minecraft:dragon_fireball"),
DRAGON_FIREBALL("minecraft:dragon_fireball", 1.0, 1.0, DragonFireballMeta::new, EntitySpawnType.BASE),
DROWNED("minecraft:drowned"),
DROWNED("minecraft:drowned", 0.6, 1.95, DrownedMeta::new, EntitySpawnType.LIVING),
ELDER_GUARDIAN("minecraft:elder_guardian"),
ELDER_GUARDIAN("minecraft:elder_guardian", 1.9975, 1.9975, ElderGuardianMeta::new, EntitySpawnType.LIVING),
END_CRYSTAL("minecraft:end_crystal"),
END_CRYSTAL("minecraft:end_crystal", 2.0, 2.0, EndCrystalMeta::new, EntitySpawnType.BASE),
ENDER_DRAGON("minecraft:ender_dragon"),
ENDER_DRAGON("minecraft:ender_dragon", 16.0, 8.0, EnderDragonMeta::new, EntitySpawnType.LIVING),
ENDERMAN("minecraft:enderman"),
ENDERMAN("minecraft:enderman", 0.6, 2.9, EndermanMeta::new, EntitySpawnType.LIVING),
ENDERMITE("minecraft:endermite"),
ENDERMITE("minecraft:endermite", 0.4, 0.3, EndermiteMeta::new, EntitySpawnType.LIVING),
EVOKER("minecraft:evoker"),
EVOKER("minecraft:evoker", 0.6, 1.95, EvokerMeta::new, EntitySpawnType.LIVING),
EVOKER_FANGS("minecraft:evoker_fangs"),
EVOKER_FANGS("minecraft:evoker_fangs", 0.5, 0.8, EvokerFangsMeta::new, EntitySpawnType.BASE),
EXPERIENCE_ORB("minecraft:experience_orb"),
EXPERIENCE_ORB("minecraft:experience_orb", 0.5, 0.5, ExperienceOrbMeta::new, EntitySpawnType.EXPERIENCE_ORB),
EYE_OF_ENDER("minecraft:eye_of_ender"),
EYE_OF_ENDER("minecraft:eye_of_ender", 0.25, 0.25, EyeOfEnderMeta::new, EntitySpawnType.BASE),
FALLING_BLOCK("minecraft:falling_block"),
FALLING_BLOCK("minecraft:falling_block", 0.98, 0.98, FallingBlockMeta::new, EntitySpawnType.BASE),
FIREWORK_ROCKET("minecraft:firework_rocket"),
FIREWORK_ROCKET("minecraft:firework_rocket", 0.25, 0.25, FireworkRocketMeta::new, EntitySpawnType.BASE),
FOX("minecraft:fox"),
FOX("minecraft:fox", 0.6, 0.7, FoxMeta::new, EntitySpawnType.LIVING),
GHAST("minecraft:ghast"),
GHAST("minecraft:ghast", 4.0, 4.0, GhastMeta::new, EntitySpawnType.LIVING),
GIANT("minecraft:giant"),
GIANT("minecraft:giant", 3.6, 12.0, GiantMeta::new, EntitySpawnType.LIVING),
GUARDIAN("minecraft:guardian"),
GUARDIAN("minecraft:guardian", 0.85, 0.85, GuardianMeta::new, EntitySpawnType.LIVING),
HOGLIN("minecraft:hoglin"),
HOGLIN("minecraft:hoglin", 1.39648, 1.4, HoglinMeta::new, EntitySpawnType.LIVING),
HORSE("minecraft:horse"),
HORSE("minecraft:horse", 1.39648, 1.6, HorseMeta::new, EntitySpawnType.LIVING),
HUSK("minecraft:husk"),
HUSK("minecraft:husk", 0.6, 1.95, HuskMeta::new, EntitySpawnType.LIVING),
ILLUSIONER("minecraft:illusioner"),
ILLUSIONER("minecraft:illusioner", 0.6, 1.95, IllusionerMeta::new, EntitySpawnType.LIVING),
IRON_GOLEM("minecraft:iron_golem"),
IRON_GOLEM("minecraft:iron_golem", 1.4, 2.7, IronGolemMeta::new, EntitySpawnType.LIVING),
ITEM("minecraft:item"),
ITEM("minecraft:item", 0.25, 0.25, ItemEntityMeta::new, EntitySpawnType.BASE),
ITEM_FRAME("minecraft:item_frame"),
ITEM_FRAME("minecraft:item_frame", 0.5, 0.5, ItemFrameMeta::new, EntitySpawnType.BASE),
FIREBALL("minecraft:fireball"),
FIREBALL("minecraft:fireball", 1.0, 1.0, FireballMeta::new, EntitySpawnType.BASE),
LEASH_KNOT("minecraft:leash_knot"),
LEASH_KNOT("minecraft:leash_knot", 0.5, 0.5, LeashKnotMeta::new, EntitySpawnType.BASE),
LIGHTNING_BOLT("minecraft:lightning_bolt"),
LIGHTNING_BOLT("minecraft:lightning_bolt", 0.0, 0.0, LightningBoltMeta::new, EntitySpawnType.BASE),
LLAMA("minecraft:llama"),
LLAMA("minecraft:llama", 0.9, 1.87, LlamaMeta::new, EntitySpawnType.LIVING),
LLAMA_SPIT("minecraft:llama_spit"),
LLAMA_SPIT("minecraft:llama_spit", 0.25, 0.25, LlamaSpitMeta::new, EntitySpawnType.BASE),
MAGMA_CUBE("minecraft:magma_cube"),
MAGMA_CUBE("minecraft:magma_cube", 2.04, 2.04, MagmaCubeMeta::new, EntitySpawnType.LIVING),
MINECART("minecraft:minecart"),
MINECART("minecraft:minecart", 0.98, 0.7, MinecartMeta::new, EntitySpawnType.BASE),
CHEST_MINECART("minecraft:chest_minecart"),
CHEST_MINECART("minecraft:chest_minecart", 0.98, 0.7, ChestMinecartMeta::new, EntitySpawnType.BASE),
COMMAND_BLOCK_MINECART("minecraft:command_block_minecart"),
COMMAND_BLOCK_MINECART("minecraft:command_block_minecart", 0.98, 0.7, CommandBlockMinecartMeta::new, EntitySpawnType.BASE),
FURNACE_MINECART("minecraft:furnace_minecart"),
FURNACE_MINECART("minecraft:furnace_minecart", 0.98, 0.7, FurnaceMinecartMeta::new, EntitySpawnType.BASE),
HOPPER_MINECART("minecraft:hopper_minecart"),
HOPPER_MINECART("minecraft:hopper_minecart", 0.98, 0.7, HopperMinecartMeta::new, EntitySpawnType.BASE),
SPAWNER_MINECART("minecraft:spawner_minecart"),
SPAWNER_MINECART("minecraft:spawner_minecart", 0.98, 0.7, SpawnerMinecartMeta::new, EntitySpawnType.BASE),
TNT_MINECART("minecraft:tnt_minecart"),
TNT_MINECART("minecraft:tnt_minecart", 0.98, 0.7, TntMinecartMeta::new, EntitySpawnType.BASE),
MULE("minecraft:mule"),
MULE("minecraft:mule", 1.39648, 1.6, MuleMeta::new, EntitySpawnType.LIVING),
MOOSHROOM("minecraft:mooshroom"),
MOOSHROOM("minecraft:mooshroom", 0.9, 1.4, MooshroomMeta::new, EntitySpawnType.LIVING),
OCELOT("minecraft:ocelot"),
OCELOT("minecraft:ocelot", 0.6, 0.7, OcelotMeta::new, EntitySpawnType.LIVING),
PAINTING("minecraft:painting"),
PAINTING("minecraft:painting", 0.5, 0.5, PaintingMeta::new, EntitySpawnType.PAINTING),
PANDA("minecraft:panda"),
PANDA("minecraft:panda", 1.3, 1.25, PandaMeta::new, EntitySpawnType.LIVING),
PARROT("minecraft:parrot"),
PARROT("minecraft:parrot", 0.5, 0.9, ParrotMeta::new, EntitySpawnType.LIVING),
PHANTOM("minecraft:phantom"),
PHANTOM("minecraft:phantom", 0.9, 0.5, PhantomMeta::new, EntitySpawnType.LIVING),
PIG("minecraft:pig"),
PIG("minecraft:pig", 0.9, 0.9, PigMeta::new, EntitySpawnType.LIVING),
PIGLIN("minecraft:piglin"),
PIGLIN("minecraft:piglin", 0.6, 1.95, PiglinMeta::new, EntitySpawnType.LIVING),
PIGLIN_BRUTE("minecraft:piglin_brute"),
PIGLIN_BRUTE("minecraft:piglin_brute", 0.6, 1.95, PiglinBruteMeta::new, EntitySpawnType.LIVING),
PILLAGER("minecraft:pillager"),
PILLAGER("minecraft:pillager", 0.6, 1.95, PillagerMeta::new, EntitySpawnType.LIVING),
POLAR_BEAR("minecraft:polar_bear"),
POLAR_BEAR("minecraft:polar_bear", 1.4, 1.4, PolarBearMeta::new, EntitySpawnType.LIVING),
TNT("minecraft:tnt"),
TNT("minecraft:tnt", 0.98, 0.98, PrimedTntMeta::new, EntitySpawnType.BASE),
PUFFERFISH("minecraft:pufferfish"),
PUFFERFISH("minecraft:pufferfish", 0.7, 0.7, PufferfishMeta::new, EntitySpawnType.LIVING),
RABBIT("minecraft:rabbit"),
RABBIT("minecraft:rabbit", 0.4, 0.5, RabbitMeta::new, EntitySpawnType.LIVING),
RAVAGER("minecraft:ravager"),
RAVAGER("minecraft:ravager", 1.95, 2.2, RavagerMeta::new, EntitySpawnType.LIVING),
SALMON("minecraft:salmon"),
SALMON("minecraft:salmon", 0.7, 0.4, SalmonMeta::new, EntitySpawnType.LIVING),
SHEEP("minecraft:sheep"),
SHEEP("minecraft:sheep", 0.9, 1.3, SheepMeta::new, EntitySpawnType.LIVING),
SHULKER("minecraft:shulker"),
SHULKER("minecraft:shulker", 1.0, 1.0, ShulkerMeta::new, EntitySpawnType.LIVING),
SHULKER_BULLET("minecraft:shulker_bullet"),
SHULKER_BULLET("minecraft:shulker_bullet", 0.3125, 0.3125, ShulkerBulletMeta::new, EntitySpawnType.BASE),
SILVERFISH("minecraft:silverfish"),
SILVERFISH("minecraft:silverfish", 0.4, 0.3, SilverfishMeta::new, EntitySpawnType.LIVING),
SKELETON("minecraft:skeleton"),
SKELETON("minecraft:skeleton", 0.6, 1.99, SkeletonMeta::new, EntitySpawnType.LIVING),
SKELETON_HORSE("minecraft:skeleton_horse"),
SKELETON_HORSE("minecraft:skeleton_horse", 1.39648, 1.6, SkeletonHorseMeta::new, EntitySpawnType.LIVING),
SLIME("minecraft:slime"),
SLIME("minecraft:slime", 2.04, 2.04, SlimeMeta::new, EntitySpawnType.LIVING),
SMALL_FIREBALL("minecraft:small_fireball"),
SMALL_FIREBALL("minecraft:small_fireball", 0.3125, 0.3125, SmallFireballMeta::new, EntitySpawnType.BASE),
SNOW_GOLEM("minecraft:snow_golem"),
SNOW_GOLEM("minecraft:snow_golem", 0.7, 1.9, SnowGolemMeta::new, EntitySpawnType.LIVING),
SNOWBALL("minecraft:snowball"),
SNOWBALL("minecraft:snowball", 0.25, 0.25, SnowballMeta::new, EntitySpawnType.BASE),
SPECTRAL_ARROW("minecraft:spectral_arrow"),
SPECTRAL_ARROW("minecraft:spectral_arrow", 0.5, 0.5, SpectralArrowMeta::new, EntitySpawnType.BASE),
SPIDER("minecraft:spider"),
SPIDER("minecraft:spider", 1.4, 0.9, SpiderMeta::new, EntitySpawnType.LIVING),
SQUID("minecraft:squid"),
SQUID("minecraft:squid", 0.8, 0.8, SquidMeta::new, EntitySpawnType.LIVING),
STRAY("minecraft:stray"),
STRAY("minecraft:stray", 0.6, 1.99, StrayMeta::new, EntitySpawnType.LIVING),
STRIDER("minecraft:strider"),
STRIDER("minecraft:strider", 0.9, 1.7, StriderMeta::new, EntitySpawnType.LIVING),
EGG("minecraft:egg"),
EGG("minecraft:egg", 0.25, 0.25, ThrownEggMeta::new, EntitySpawnType.BASE),
ENDER_PEARL("minecraft:ender_pearl"),
ENDER_PEARL("minecraft:ender_pearl", 0.25, 0.25, ThrownEnderPearlMeta::new, EntitySpawnType.BASE),
EXPERIENCE_BOTTLE("minecraft:experience_bottle"),
EXPERIENCE_BOTTLE("minecraft:experience_bottle", 0.25, 0.25, ThrownExperienceBottleMeta::new, EntitySpawnType.BASE),
POTION("minecraft:potion"),
POTION("minecraft:potion", 0.25, 0.25, ThrownPotionMeta::new, EntitySpawnType.BASE),
TRIDENT("minecraft:trident"),
TRIDENT("minecraft:trident", 0.5, 0.5, ThrownTridentMeta::new, EntitySpawnType.BASE),
TRADER_LLAMA("minecraft:trader_llama"),
TRADER_LLAMA("minecraft:trader_llama", 0.9, 1.87, TraderLlamaMeta::new, EntitySpawnType.BASE),
TROPICAL_FISH("minecraft:tropical_fish"),
TROPICAL_FISH("minecraft:tropical_fish", 0.5, 0.4, TropicalFishMeta::new, EntitySpawnType.LIVING),
TURTLE("minecraft:turtle"),
TURTLE("minecraft:turtle", 1.2, 0.4, TurtleMeta::new, EntitySpawnType.LIVING),
VEX("minecraft:vex"),
VEX("minecraft:vex", 0.4, 0.8, VexMeta::new, EntitySpawnType.LIVING),
VILLAGER("minecraft:villager"),
VILLAGER("minecraft:villager", 0.6, 1.95, VillagerMeta::new, EntitySpawnType.LIVING),
VINDICATOR("minecraft:vindicator"),
VINDICATOR("minecraft:vindicator", 0.6, 1.95, VindicatorMeta::new, EntitySpawnType.LIVING),
WANDERING_TRADER("minecraft:wandering_trader"),
WANDERING_TRADER("minecraft:wandering_trader", 0.6, 1.95, WanderingTraderMeta::new, EntitySpawnType.LIVING),
WITCH("minecraft:witch"),
WITCH("minecraft:witch", 0.6, 1.95, WitchMeta::new, EntitySpawnType.LIVING),
WITHER("minecraft:wither"),
WITHER("minecraft:wither", 0.9, 3.5, WitherMeta::new, EntitySpawnType.LIVING),
WITHER_SKELETON("minecraft:wither_skeleton"),
WITHER_SKELETON("minecraft:wither_skeleton", 0.7, 2.4, WitherSkeletonMeta::new, EntitySpawnType.LIVING),
WITHER_SKULL("minecraft:wither_skull"),
WITHER_SKULL("minecraft:wither_skull", 0.3125, 0.3125, WitherSkullMeta::new, EntitySpawnType.BASE),
WOLF("minecraft:wolf"),
WOLF("minecraft:wolf", 0.6, 0.85, WolfMeta::new, EntitySpawnType.LIVING),
ZOGLIN("minecraft:zoglin"),
ZOGLIN("minecraft:zoglin", 1.39648, 1.4, ZoglinMeta::new, EntitySpawnType.LIVING),
ZOMBIE("minecraft:zombie"),
ZOMBIE("minecraft:zombie", 0.6, 1.95, ZombieMeta::new, EntitySpawnType.LIVING),
ZOMBIE_HORSE("minecraft:zombie_horse"),
ZOMBIE_HORSE("minecraft:zombie_horse", 1.39648, 1.6, ZombieHorseMeta::new, EntitySpawnType.LIVING),
ZOMBIE_VILLAGER("minecraft:zombie_villager"),
ZOMBIE_VILLAGER("minecraft:zombie_villager", 0.6, 1.95, ZombieVillagerMeta::new, EntitySpawnType.LIVING),
ZOMBIFIED_PIGLIN("minecraft:zombified_piglin"),
ZOMBIFIED_PIGLIN("minecraft:zombified_piglin", 0.6, 1.95, ZombifiedPiglinMeta::new, EntitySpawnType.LIVING),
PLAYER("minecraft:player"),
PLAYER("minecraft:player", 0.6, 1.8, PlayerMeta::new, EntitySpawnType.PLAYER),
FISHING_BOBBER("minecraft:fishing_bobber");
FISHING_BOBBER("minecraft:fishing_bobber", 0.25, 0.25, FishingHookMeta::new, EntitySpawnType.BASE);
private String namespaceID;
private static final EntityType[] VALUES = values();
EntityType(String namespaceID) {
@NotNull
private final String namespaceID;
private final double width;
private final double height;
@NotNull
private final BiFunction<Entity, Metadata, EntityMeta> metaConstructor;
@NotNull
private final EntitySpawnType spawnType;
EntityType(@NotNull String namespaceID, double width, double height,
@NotNull BiFunction<Entity, Metadata, EntityMeta> metaConstructor,
@NotNull EntitySpawnType spawnType) {
this.namespaceID = namespaceID;
this.width = width;
this.height = height;
this.metaConstructor = metaConstructor;
this.spawnType = spawnType;
Registries.entityTypes.put(NamespaceID.from(namespaceID), this);
}
public int getId() {
return ordinal();
public short getId() {
return (short) ordinal();
}
public String getNamespaceID() {
return namespaceID;
return this.namespaceID;
}
public static EntityType fromId(int id) {
if (id >= 0 && id < values().length) {
return values()[id];
public double getWidth() {
return this.width;
}
public double getHeight() {
return this.height;
}
public BiFunction<Entity, Metadata, EntityMeta> getMetaConstructor() {
return this.metaConstructor;
}
public EntitySpawnType getSpawnType() {
return this.spawnType;
}
public static EntityType fromId(short id) {
if(id >= 0 && id < VALUES.length) {
return VALUES[id];
}
return PIG;
return null;
}
}

View File

@ -1,6 +1,7 @@
// AUTOGENERATED by net.minestom.codegen.RegistriesGenerator
package net.minestom.server.registry;
import java.util.HashMap;
import net.minestom.server.entity.EntityType;
import net.minestom.server.fluids.Fluid;
import net.minestom.server.instance.block.Block;
@ -15,8 +16,6 @@ import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
/**
* AUTOGENERATED
*/

View File

@ -0,0 +1,16 @@
package net.minestom.codegen;
import com.squareup.javapoet.ClassName;
public class ConstructorLambda {
private final ClassName className;
public ConstructorLambda(ClassName className) {
this.className = className;
}
public ClassName getClassName() {
return className;
}
}

View File

@ -21,6 +21,7 @@ public class EnumGenerator implements CodeGenerator {
private final String enumName;
private ParameterSpec[] parameters;
private List<Method> methods = new LinkedList<>();
private List<Field> fields = new LinkedList<>();
private List<Instance> instances = new LinkedList<>();
private List<Field> hardcodedFields = new LinkedList<>();
private List<AnnotationSpec> annotations = new LinkedList<>();
@ -50,6 +51,10 @@ public class EnumGenerator implements CodeGenerator {
methods.add(new Method(true, name, signature, returnType, code, false));
}
public void addStaticField(TypeName type, String name, String value) {
fields.add(new Field(type, name, value));
}
public void addInstance(String name, Object... parameters) {
instances.add(new Instance(name, parameters));
}
@ -58,17 +63,22 @@ public class EnumGenerator implements CodeGenerator {
TypeSpec.Builder enumClass = TypeSpec.enumBuilder(ClassName.get(enumPackage, enumName)).addModifiers(Modifier.PUBLIC);
enumClass.addJavadoc(COMMENT);
for(AnnotationSpec annotation : annotations) {
for (AnnotationSpec annotation : annotations) {
enumClass.addAnnotation(annotation);
}
for(Instance instance : instances) {
for (Instance instance : instances) {
StringBuilder format = new StringBuilder();
for (int i = 0; i < instance.parameters.length; i++) {
if (i != 0) {
format.append(", ");
}
format.append("$L");
if (instance.parameters[i] instanceof ConstructorLambda) {
instance.parameters[i] = ((ConstructorLambda) instance.parameters[i]).getClassName();
format.append("$T::new");
} else {
format.append("$L");
}
}
// generate instances
@ -76,7 +86,7 @@ public class EnumGenerator implements CodeGenerator {
enumClass.addEnumConstant(instance.name, arguments);
}
if(staticBlock != null) {
if (staticBlock != null) {
enumClass.addStaticBlock(staticBlock);
}
@ -85,11 +95,18 @@ public class EnumGenerator implements CodeGenerator {
// properties
for (ParameterSpec property : parameters) {
enumClass.addField(FieldSpec.builder(property.type, property.name)
.addModifiers(Modifier.PRIVATE)
.addModifiers(Modifier.PRIVATE, Modifier.FINAL)
.addAnnotations(property.annotations)
.build());
}
for (Field field : fields) {
enumClass.addField(FieldSpec.builder(field.type, field.name)
.initializer("$L", field.value)
.addModifiers(Modifier.PRIVATE, Modifier.FINAL, Modifier.STATIC)
.build());
}
// hard coded fields
for (Field hardcoded : hardcodedFields) {
enumClass.addField(FieldSpec.builder(hardcoded.type, hardcoded.name)
@ -121,10 +138,10 @@ public class EnumGenerator implements CodeGenerator {
}
methodBuilder.addModifiers(Modifier.PUBLIC);
methodBuilder.returns(m.returnType);
if(m.vararg) {
if (m.vararg) {
methodBuilder.varargs(true);
}
for(ParameterSpec parameter : m.signature) {
for (ParameterSpec parameter : m.signature) {
methodBuilder.addParameter(parameter);
}
@ -134,7 +151,6 @@ public class EnumGenerator implements CodeGenerator {
enumClass.addMethod(methodBuilder.build());
}
JavaFile file = JavaFile.builder(enumPackage, enumClass.build())
.skipJavaLangImports(true)
.indent(" ")

View File

@ -20,7 +20,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.lang.model.element.Modifier;
import java.io.*;
import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.Collections;
import java.util.HashMap;
@ -39,7 +40,7 @@ public class RegistriesGenerator implements CodeGenerator {
new ImmutablePair<>(Block.class.getCanonicalName(), "AIR"),
new ImmutablePair<>(Material.class.getCanonicalName(), "AIR"),
new ImmutablePair<>(Enchantment.class.getCanonicalName(), null),
new ImmutablePair<>(EntityType.class.getCanonicalName(), "PIG"),
new ImmutablePair<>(EntityType.class.getCanonicalName(), null),
new ImmutablePair<>(Particle.class.getCanonicalName(), null),
new ImmutablePair<>(PotionType.class.getCanonicalName(), null),
new ImmutablePair<>(PotionEffect.class.getCanonicalName(), null),
@ -61,7 +62,7 @@ public class RegistriesGenerator implements CodeGenerator {
ClassName type = ClassName.bestGuess(registries[i].left);
String simpleType = type.simpleName();
FieldSpec field = FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(HashMap.class), ClassName.get(NamespaceID.class), type), CodeGenerator.decapitalize(simpleType)+"s")
FieldSpec field = FieldSpec.builder(ParameterizedTypeName.get(ClassName.get(HashMap.class), ClassName.get(NamespaceID.class), type), CodeGenerator.decapitalize(simpleType) + "s")
.addModifiers(Modifier.FINAL, Modifier.STATIC, Modifier.PUBLIC)
.addJavadoc("Should only be used for internal code, please use the get* methods.")
.addAnnotation(Deprecated.class)
@ -103,7 +104,7 @@ public class RegistriesGenerator implements CodeGenerator {
CodeBlock.Builder code = CodeBlock.builder();
Class<? extends Annotation> annotation;
if(defaultValue != null) {
if (defaultValue != null) {
annotation = NotNull.class;
code.addStatement("return $N.getOrDefault($N, $T.$N)", fields[i], namespaceIDParam, type, defaultValue);
} else {
@ -114,7 +115,7 @@ public class RegistriesGenerator implements CodeGenerator {
// string variant
ParameterSpec idParam = ParameterSpec.builder(ClassName.get(String.class), "id")
.build();
MethodSpec idMethod = MethodSpec.methodBuilder("get"+simpleType)
MethodSpec idMethod = MethodSpec.methodBuilder("get" + simpleType)
.returns(type)
.addAnnotation(annotation)
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
@ -125,7 +126,7 @@ public class RegistriesGenerator implements CodeGenerator {
registriesClass.addMethod(idMethod);
// NamespaceID variant
registriesClass.addMethod(MethodSpec.methodBuilder("get"+simpleType)
registriesClass.addMethod(MethodSpec.methodBuilder("get" + simpleType)
.returns(type)
.addAnnotation(annotation)
.addModifiers(Modifier.STATIC, Modifier.PUBLIC)
@ -136,7 +137,7 @@ public class RegistriesGenerator implements CodeGenerator {
}
JavaFile file = JavaFile.builder("net.minestom.server.registry", registriesClass.build())
.addFileComment("AUTOGENERATED by "+getClass().getCanonicalName())
.addFileComment("AUTOGENERATED by " + getClass().getCanonicalName())
.indent(" ")
.skipJavaLangImports(true)
.build();

View File

@ -0,0 +1,8 @@
package net.minestom.codegen.entitytypes;
public class BurgerEntity {
int id;
String name;
double width;
double height;
}

View File

@ -0,0 +1,153 @@
package net.minestom.codegen.entitytypes;
import com.google.common.base.CaseFormat;
import net.minestom.server.entity.EntitySpawnType;
import net.minestom.server.entity.metadata.LivingEntityMeta;
import net.minestom.server.entity.metadata.PlayerMeta;
import net.minestom.server.entity.metadata.other.ExperienceOrbMeta;
import net.minestom.server.entity.metadata.other.PaintingMeta;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
public class EntityTypeContainer implements Comparable<EntityTypeContainer> {
private int id;
private NamespaceID name;
private double width;
private double height;
private Class<?> metaClass;
private EntitySpawnType spawnType;
public EntityTypeContainer(int id, NamespaceID name, double width, double height) {
this.id = id;
this.name = name;
this.width = width;
this.height = height;
String metaClassName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name.getPath());
// special cases
switch (metaClassName) {
case "Item":
metaClassName = "ItemEntity";
break;
case "Tnt":
metaClassName = "PrimedTnt";
break;
case "FishingBobber":
metaClassName = "FishingHook";
break;
case "Egg":
case "EnderPearl":
case "ExperienceBottle":
case "Potion":
case "Trident":
metaClassName = "Thrown" + metaClassName;
break;
default:
break;
}
metaClassName += "Meta";
this.metaClass = findClassIn("net.minestom.server.entity.metadata", metaClassName);
if (this.metaClass == PlayerMeta.class) {
this.spawnType = EntitySpawnType.PLAYER;
} else if (this.metaClass == PaintingMeta.class) {
this.spawnType = EntitySpawnType.PAINTING;
} else if (this.metaClass == ExperienceOrbMeta.class) {
this.spawnType = EntitySpawnType.EXPERIENCE_ORB;
} else if (LivingEntityMeta.class.isAssignableFrom(this.metaClass)) {
this.spawnType = EntitySpawnType.LIVING;
} else {
this.spawnType = EntitySpawnType.BASE;
}
}
public int getId() {
return id;
}
public NamespaceID getName() {
return name;
}
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
public Class<?> getMetaClass() {
return metaClass;
}
public EntitySpawnType getSpawnType() {
return spawnType;
}
@Override
public int compareTo(@NotNull EntityTypeContainer o) {
return Integer.compare(id, o.id);
}
private static Class<?> findClassIn(String pkg, String className) {
try {
return getClasses(pkg).stream()
.filter(clazz -> clazz.getSimpleName().equals(className))
.findAny()
.orElseThrow();
} catch (Throwable t) {
throw new IllegalStateException("Could not find class " + className + " in " + pkg, t);
}
}
private static List<Class<?>> getClasses(String packageName)
throws ClassNotFoundException, IOException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
assert classLoader != null;
String path = packageName.replace('.', '/');
Enumeration<URL> resources = classLoader.getResources(path);
List<File> dirs = new ArrayList<>();
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
dirs.add(new File(resource.getFile()));
}
List<Class<?>> classes = new ArrayList<>();
for (File directory : dirs) {
classes.addAll(findClasses(directory, packageName));
}
return classes;
}
/**
* Recursive method used to find all classes in a given directory and subdirs.
*
* @param directory The base directory
* @param packageName The package name for classes found inside the base directory
* @return The classes
* @throws ClassNotFoundException
*/
private static List<Class<?>> findClasses(File directory, String packageName) throws ClassNotFoundException {
List<Class<?>> classes = new ArrayList<>();
if (!directory.exists()) {
return classes;
}
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
assert !file.getName().contains(".");
classes.addAll(findClasses(file, packageName + "." + file.getName()));
} else if (file.getName().endsWith(".class")) {
classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
}
}
return classes;
}
}

View File

@ -1,21 +1,45 @@
package net.minestom.codegen.entitytypes;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.codegen.stats.StatsEnumGenerator;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.squareup.javapoet.*;
import net.minestom.codegen.ConstructorLambda;
import net.minestom.codegen.EnumGenerator;
import net.minestom.codegen.MinestomEnumGenerator;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntitySpawnType;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.EntityMeta;
import net.minestom.server.registry.Registries;
import net.minestom.server.registry.ResourceGatherer;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.*;
import java.util.function.BiFunction;
public class EntityTypeEnumGenerator extends BasicEnumGenerator {
/**
* Generates an EntityType enum containing all data about entity types
*/
public class EntityTypeEnumGenerator extends MinestomEnumGenerator<EntityTypeContainer> {
private static final Logger LOGGER = LoggerFactory.getLogger(EntityTypeEnumGenerator.class);
private final String targetVersion;
private final File targetFolder;
public static void main(String[] args) throws IOException {
String targetVersion;
if(args.length < 1) {
if (args.length < 1) {
System.err.println("Usage: <MC version> [target folder]");
return;
}
@ -29,25 +53,44 @@ public class EntityTypeEnumGenerator extends BasicEnumGenerator {
}
String targetPart = DEFAULT_TARGET_PATH;
if(args.length >= 2) {
if (args.length >= 2) {
targetPart = args[1];
}
File targetFolder = new File(targetPart);
if(!targetFolder.exists()) {
if (!targetFolder.exists()) {
targetFolder.mkdirs();
}
new EntityTypeEnumGenerator(targetFolder);
new EntityTypeEnumGenerator(targetVersion, targetFolder);
}
private EntityTypeEnumGenerator(File targetFolder) throws IOException {
super(targetFolder);
private EntityTypeEnumGenerator(String targetVersion, File targetFolder) throws IOException {
this.targetVersion = targetVersion;
this.targetFolder = targetFolder;
generateTo(targetFolder);
}
@Override
protected String getCategoryID() {
return "minecraft:entity_type";
/**
* Extract entity information from Burger (submodule of Minestom)
*
* @param gson
* @param url
* @return
* @throws IOException
*/
private List<BurgerEntity> parseEntitiesFromBurger(Gson gson, String url) throws IOException {
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new URL(url).openStream()))) {
LOGGER.debug("\tConnection established, reading file");
JsonObject dictionary = gson.fromJson(bufferedReader, JsonArray.class).get(0).getAsJsonObject();
JsonObject entitiesMap = dictionary.getAsJsonObject("entities").getAsJsonObject("entity");
List<BurgerEntity> entities = new LinkedList<>();
for (var entry : entitiesMap.entrySet()) {
BurgerEntity entity = gson.fromJson(entry.getValue(), BurgerEntity.class);
entities.add(entity);
}
return entities;
}
}
@Override
@ -60,6 +103,103 @@ public class EntityTypeEnumGenerator extends BasicEnumGenerator {
return "EntityType";
}
@Override
protected Collection<EntityTypeContainer> compile() throws IOException {
Gson gson = new Gson();
LOGGER.debug("Loading PrismarineJS entity types data");
List<BurgerEntity> burgerEntities = parseEntitiesFromBurger(gson, BURGER_URL_BASE_URL + targetVersion + ".json");
TreeSet<EntityTypeContainer> types = new TreeSet<>(EntityTypeContainer::compareTo);
for (var burgerEntity : burgerEntities) {
if (burgerEntity.name.contains("~")) {
continue;
}
types.add(new EntityTypeContainer(
burgerEntity.id,
NamespaceID.from("minecraft:" + burgerEntity.name),
burgerEntity.width,
burgerEntity.height
));
}
return types;
}
@Override
protected void prepare(EnumGenerator generator) {
ClassName className = ClassName.get(getPackageName(), getClassName());
generator.addClassAnnotation(AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "{$S}", "deprecation").build());
generator.setParams(
ParameterSpec.builder(String.class, "namespaceID").addAnnotation(NotNull.class).build(),
ParameterSpec.builder(TypeName.DOUBLE, "width").build(),
ParameterSpec.builder(TypeName.DOUBLE, "height").build(),
ParameterSpec.builder(ParameterizedTypeName.get(
BiFunction.class,
Entity.class,
Metadata.class,
EntityMeta.class
), "metaConstructor").addAnnotation(NotNull.class).build(),
ParameterSpec.builder(EntitySpawnType.class, "spawnType").addAnnotation(NotNull.class).build()
);
generator.appendToConstructor(code -> {
code.addStatement("$T.$N.put($T.from(namespaceID), this)", Registries.class, "entityTypes", NamespaceID.class);
});
generator.addMethod("getId", new ParameterSpec[0], TypeName.SHORT, code -> {
code.addStatement("return (short) ordinal()");
});
generator.addMethod("getNamespaceID", new ParameterSpec[0], ClassName.get(String.class), code -> {
code.addStatement("return this.namespaceID");
});
generator.addMethod("getWidth", new ParameterSpec[0], TypeName.DOUBLE, code -> {
code.addStatement("return this.width");
});
generator.addMethod("getHeight", new ParameterSpec[0], TypeName.DOUBLE, code -> {
code.addStatement("return this.height");
});
generator.addMethod("getMetaConstructor", new ParameterSpec[0],
ParameterizedTypeName.get(
BiFunction.class,
Entity.class,
Metadata.class,
EntityMeta.class
),
code -> code.addStatement("return this.metaConstructor")
);
generator.addMethod("getSpawnType", new ParameterSpec[0], ClassName.get(EntitySpawnType.class), code -> {
code.addStatement("return this.spawnType");
});
generator.addStaticField(ArrayTypeName.of(ClassName.get(EntityType.class)), "VALUES", "values()");
generator.addStaticMethod("fromId", new ParameterSpec[]{ParameterSpec.builder(TypeName.SHORT, "id").build()}, className, code -> {
code.beginControlFlow("if(id >= 0 && id < VALUES.length)")
.addStatement("return VALUES[id]")
.endControlFlow()
.addStatement("return null");
});
}
@Override
protected void writeSingle(EnumGenerator generator, EntityTypeContainer type) {
String instanceName = type.getName().getPath().toUpperCase();
generator.addInstance(instanceName,
"\"" + type.getName().toString() + "\"",
type.getWidth(),
type.getHeight(),
new ConstructorLambda(ClassName.get(type.getMetaClass())),
"EntitySpawnType." + type.getSpawnType().name()
);
}
@Override
protected List<JavaFile> postGeneration(Collection<EntityTypeContainer> types) {
return Collections.emptyList();
}
@Override
protected void postWrite(EnumGenerator generator) {
}
@Override
public Logger getLogger() {
return LOGGER;

View File

@ -1,7 +1,6 @@
package net.minestom.codegen.particles;
import net.minestom.codegen.BasicEnumGenerator;
import net.minestom.codegen.stats.StatsEnumGenerator;
import net.minestom.server.registry.ResourceGatherer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

View File

@ -2,6 +2,7 @@ package net.minestom.server.chat;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.jetbrains.annotations.NotNull;
import java.util.Objects;
@ -109,6 +110,10 @@ public abstract class JsonMessage {
this.jsonObject = jsonObject;
}
public RawJsonMessage(@NotNull String jsonObject) {
this.jsonObject = JsonParser.parseString(jsonObject).getAsJsonObject();
}
@NotNull
@Override
public JsonObject getJsonObject() {

View File

@ -0,0 +1,70 @@
package net.minestom.server.command.builder.arguments;
import net.minestom.server.command.builder.NodeMaker;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.network.packet.server.play.DeclareCommandsPacket;
import org.jetbrains.annotations.NotNull;
import java.util.Locale;
import java.util.function.Function;
@SuppressWarnings("rawtypes")
public class ArgumentEnum<E extends Enum> extends Argument<E> {
public final static int NOT_ENUM_VALUE_ERROR = 1;
private final Class<E> enumClass;
private final E[] values;
private Format format = Format.DEFAULT;
public ArgumentEnum(@NotNull String id, Class<E> enumClass) {
super(id);
this.enumClass = enumClass;
this.values = enumClass.getEnumConstants();
}
public void setFormat(@NotNull Format format) {
this.format = format;
}
@NotNull
@Override
public E parse(@NotNull String input) throws ArgumentSyntaxException {
for (E value : this.values) {
if (this.format.formatter.apply(value.name()).equals(input)) {
return value;
}
}
throw new ArgumentSyntaxException("Not a " + this.enumClass.getSimpleName() + " value", input, NOT_ENUM_VALUE_ERROR);
}
@Override
public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) {
// Create a primitive array for mapping
DeclareCommandsPacket.Node[] nodes = new DeclareCommandsPacket.Node[this.values.length];
// Create a node for each restrictions as literal
for (int i = 0; i < nodes.length; i++) {
DeclareCommandsPacket.Node argumentNode = new DeclareCommandsPacket.Node();
argumentNode.flags = DeclareCommandsPacket.getFlag(DeclareCommandsPacket.NodeType.LITERAL,
executable, false, false);
argumentNode.name = this.format.formatter.apply(this.values[i].name());
nodes[i] = argumentNode;
}
nodeMaker.addNodes(nodes);
}
public enum Format {
DEFAULT(name -> name),
LOWER_CASED(name -> name.toLowerCase(Locale.ROOT)),
UPPER_CASED(name -> name.toUpperCase(Locale.ROOT));
private final Function<String, String> formatter;
Format(Function<String, String> formatter) {
this.formatter = formatter;
}
}
}

View File

@ -79,6 +79,11 @@ public class ArgumentType {
return new ArgumentCommand(id);
}
@SuppressWarnings("rawtypes")
public static <E extends Enum> ArgumentEnum<E> Enum(@NotNull String id, @NotNull Class<E> enumClass) {
return new ArgumentEnum<>(id, enumClass);
}
// Minecraft specific arguments
public static ArgumentColor Color(@NotNull String id) {

View File

@ -8,8 +8,6 @@ import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer;
/**
* Represents a single word in the command.
* <p>
@ -72,20 +70,10 @@ public class ArgumentWord extends Argument<String> {
@Override
public void processNodes(@NotNull NodeMaker nodeMaker, boolean executable) {
// Add the single word properties + parser
final Consumer<DeclareCommandsPacket.Node> wordConsumer = node -> {
node.parser = "brigadier:string";
node.properties = packetWriter -> {
packetWriter.writeVarInt(0); // Single word
};
};
final boolean hasRestriction = this.hasRestrictions();
if (hasRestriction) {
if (restrictions != null) {
// Create a primitive array for mapping
DeclareCommandsPacket.Node[] nodes = new DeclareCommandsPacket.Node[this.getRestrictions().length];
DeclareCommandsPacket.Node[] nodes = new DeclareCommandsPacket.Node[this.restrictions.length];
// Create a node for each restrictions as literal
for (int i = 0; i < nodes.length; i++) {
@ -93,8 +81,7 @@ public class ArgumentWord extends Argument<String> {
argumentNode.flags = DeclareCommandsPacket.getFlag(DeclareCommandsPacket.NodeType.LITERAL,
executable, false, false);
argumentNode.name = this.getRestrictions()[i];
wordConsumer.accept(argumentNode);
argumentNode.name = this.restrictions[i];
nodes[i] = argumentNode;
}
@ -102,7 +89,10 @@ public class ArgumentWord extends Argument<String> {
} else {
// Can be any word, add only one argument node
DeclareCommandsPacket.Node argumentNode = simpleArgumentNode(this, executable, false, false);
wordConsumer.accept(argumentNode);
argumentNode.parser = "brigadier:string";
argumentNode.properties = packetWriter -> {
packetWriter.writeVarInt(0); // Single word
};
nodeMaker.addNodes(new DeclareCommandsPacket.Node[]{argumentNode});
}
}

View File

@ -8,15 +8,20 @@ import net.minestom.server.collision.BoundingBox;
import net.minestom.server.collision.CollisionUtils;
import net.minestom.server.data.Data;
import net.minestom.server.data.DataContainer;
import net.minestom.server.entity.metadata.EntityMeta;
import net.minestom.server.event.Event;
import net.minestom.server.event.EventCallback;
import net.minestom.server.event.entity.*;
import net.minestom.server.event.handler.EventHandler;
import net.minestom.server.event.item.ArmorEquipEvent;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.InstanceManager;
import net.minestom.server.instance.block.CustomBlock;
import net.minestom.server.inventory.EquipmentHandler;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.packet.server.play.*;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.permission.Permission;
import net.minestom.server.permission.PermissionHandler;
import net.minestom.server.potion.Potion;
@ -26,7 +31,6 @@ import net.minestom.server.thread.ThreadProvider;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Vector;
import net.minestom.server.utils.binary.BitmaskUtil;
import net.minestom.server.utils.callback.OptionalCallback;
import net.minestom.server.utils.chunk.ChunkCallback;
import net.minestom.server.utils.chunk.ChunkUtils;
@ -39,6 +43,7 @@ import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.time.Year;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
@ -51,33 +56,12 @@ import java.util.function.Consumer;
* <p>
* To create your own entity you probably want to extends {@link ObjectEntity} or {@link EntityCreature} instead.
*/
public abstract class Entity implements Viewable, EventHandler, DataContainer, PermissionHandler {
public class Entity implements Viewable, EventHandler, DataContainer, PermissionHandler {
private static final Map<Integer, Entity> entityById = new ConcurrentHashMap<>();
private static final Map<UUID, Entity> entityByUuid = new ConcurrentHashMap<>();
private static final AtomicInteger lastEntityId = new AtomicInteger();
// Metadata
protected static final byte METADATA_BYTE = 0;
protected static final byte METADATA_VARINT = 1;
protected static final byte METADATA_FLOAT = 2;
protected static final byte METADATA_STRING = 3;
protected static final byte METADATA_CHAT = 4;
protected static final byte METADATA_OPTCHAT = 5;
protected static final byte METADATA_SLOT = 6;
protected static final byte METADATA_BOOLEAN = 7;
protected static final byte METADATA_ROTATION = 8;
protected static final byte METADATA_POSITION = 9;
protected static final byte METADATA_OPTPOSITION = 10;
protected static final byte METADATA_DIRECTION = 11;
protected static final byte METADATA_OPTUUID = 12;
protected static final byte METADATA_OPTBLOCKID = 13;
protected static final byte METADATA_NBT = 14;
protected static final byte METADATA_PARTICLE = 15;
protected static final byte METADATA_VILLAGERDATA = 16;
protected static final byte METADATA_OPTVARINT = 17;
protected static final byte METADATA_POSE = 18;
protected Instance instance;
protected final Position position;
protected double lastX, lastY, lastZ;
@ -91,7 +75,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
protected Entity vehicle;
// Velocity
protected Vector velocity = new Vector(); // Movement in block per second
protected Vector velocity = new Vector(); // Movement in block per second
protected boolean hasPhysics = true;
protected double gravityDragPerTick;
@ -123,6 +107,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
private final Map<Class<? extends Event>, Collection<EventCallback>> eventCallbacks = new ConcurrentHashMap<>();
protected Metadata metadata = new Metadata(this);
protected EntityMeta entityMeta;
private final List<TimedPotion> effects = new CopyOnWriteArrayList<>();
@ -133,16 +118,20 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
private long ticks;
private final EntityTickEvent tickEvent = new EntityTickEvent(this);
public Entity(@NotNull EntityType entityType, @NotNull UUID uuid, @NotNull Position spawnPosition) {
/**
* Lock used to support #switchEntityType
*/
private final Object entityTypeLock = new Object();
public Entity(@NotNull EntityType entityType, @NotNull UUID uuid) {
this.id = generateId();
this.entityType = entityType;
this.uuid = uuid;
this.position = spawnPosition.clone();
this.lastX = spawnPosition.getX();
this.lastY = spawnPosition.getY();
this.lastZ = spawnPosition.getZ();
this.position = new Position();
setBoundingBox(0, 0, 0);
setBoundingBox(entityType.getWidth(), entityType.getHeight(), entityType.getWidth());
this.entityMeta = entityType.getMetaConstructor().apply(this, this.metadata);
setAutoViewable(true);
@ -150,12 +139,22 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
Entity.entityByUuid.put(uuid, this);
}
public Entity(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
this(entityType, UUID.randomUUID(), spawnPosition);
public Entity(@NotNull EntityType entityType) {
this(entityType, UUID.randomUUID());
}
public Entity(@NotNull EntityType entityType) {
this(entityType, new Position());
@Deprecated
public Entity(@NotNull EntityType entityType, @NotNull UUID uuid, @NotNull Position spawnPosition) {
this(entityType, uuid);
this.position.set(spawnPosition);
this.lastX = spawnPosition.getX();
this.lastY = spawnPosition.getY();
this.lastZ = spawnPosition.getZ();
}
@Deprecated
public Entity(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
this(entityType, UUID.randomUUID(), spawnPosition);
}
/**
@ -209,17 +208,32 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
*
* @param time time of the update in milliseconds
*/
public abstract void update(long time);
public void update(long time) {
}
/**
* Called when a new instance is set.
*/
public abstract void spawn();
public void spawn() {
}
public boolean isOnGround() {
return onGround || EntityUtils.isOnGround(this) /* backup for levitating entities */;
}
/**
* Gets metadata of this entity.
* You may want to cast it to specific implementation.
*
* @return metadata of this entity.
*/
@NotNull
public EntityMeta getEntityMeta() {
return this.entityMeta;
}
/**
* Teleports the entity only if the chunk at {@code position} is loaded or if
* {@link Instance#hasEnabledAutoChunkLoad()} returns true.
@ -319,18 +333,41 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
}
@Override
public boolean addViewer(@NotNull Player player) {
boolean result = this.viewers.add(player);
if (!result)
public final boolean addViewer(@NotNull Player player) {
synchronized (this.entityTypeLock) {
return addViewer0(player);
}
}
public boolean addViewer0(@NotNull Player player) {
if (!this.viewers.add(player)) {
return false;
}
player.viewableEntities.add(this);
PlayerConnection playerConnection = player.getPlayerConnection();
playerConnection.sendPacket(getEntityType().getSpawnType().getSpawnPacket(this));
playerConnection.sendPacket(getVelocityPacket());
playerConnection.sendPacket(getMetadataPacket());
if (hasPassenger()) {
playerConnection.sendPacket(getPassengersPacket());
}
return true;
}
@Override
public boolean removeViewer(@NotNull Player player) {
if (!viewers.remove(player))
public final boolean removeViewer(@NotNull Player player) {
synchronized (this.entityTypeLock) {
return removeViewer0(player);
}
}
public boolean removeViewer0(@NotNull Player player) {
if (!viewers.remove(player)) {
return false;
}
DestroyEntitiesPacket destroyEntitiesPacket = new DestroyEntitiesPacket();
destroyEntitiesPacket.entityIds = new int[]{getEntityId()};
@ -345,6 +382,29 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
return unmodifiableViewers;
}
/**
* Changes the entity type of this entity.
* <p>
* Works by changing the internal entity type field and by calling {@link #removeViewer(Player)}
* followed by {@link #addViewer(Player)} to all current viewers.
* <p>
* Be aware that this only change the visual of the entity, the {@link net.minestom.server.collision.BoundingBox}
* will not be modified.
*
* @param entityType the new entity type
*/
public final void switchEntityType(@NotNull EntityType entityType) {
synchronized (entityTypeLock) {
this.entityType = entityType;
this.metadata = new Metadata(this);
this.entityMeta = entityType.getMetaConstructor().apply(this, this.metadata);
Set<Player> viewers = new HashSet<>(getViewers());
getViewers().forEach(this::removeViewer0);
viewers.forEach(this::addViewer0);
}
}
@Override
public Data getData() {
return data;
@ -660,6 +720,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
*
* @return the entity type
*/
@NotNull
public EntityType getEntityType() {
return entityType;
}
@ -751,13 +812,13 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
}
/**
* Changes the entity instance.
* Changes the entity instance, i.e. spawns it.
*
* @param instance the new instance of the entity
* @throws NullPointerException if {@code instance} is null
* @param instance the new instance of the entity
* @param spawnPosition the spawn position for the entity.
* @throws IllegalStateException if {@code instance} has not been registered in {@link InstanceManager}
*/
public void setInstance(@NotNull Instance instance) {
public void setInstance(@NotNull Instance instance, @NotNull Position spawnPosition) {
Check.stateCondition(!instance.isRegistered(),
"Instances need to be registered, please use InstanceManager#registerInstance or InstanceManager#registerSharedInstance");
@ -765,6 +826,11 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
this.instance.UNSAFE_removeEntity(this);
}
this.position.set(spawnPosition);
this.lastX = this.position.getX();
this.lastY = this.position.getY();
this.lastZ = this.position.getZ();
this.isActive = true;
this.instance = instance;
instance.UNSAFE_addEntity(this);
@ -773,6 +839,19 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
callEvent(EntitySpawnEvent.class, entitySpawnEvent);
}
/**
* Changes the entity instance.
*
* @param instance the new instance of the entity
* @throws NullPointerException if {@code instance} is null
* @throws IllegalStateException if {@code instance} has not been registered in {@link InstanceManager}
* @deprecated Use {@link Entity#setInstance(Instance, Position)} instead.
*/
@Deprecated
public void setInstance(@NotNull Instance instance) {
setInstance(instance, this.position);
}
/**
* Gets the entity current velocity.
*
@ -975,7 +1054,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
* @return true if the entity is in fire, false otherwise
*/
public boolean isOnFire() {
return (getStateMeta() & 0x01) != 0;
return this.entityMeta.isOnFire();
}
/**
@ -987,8 +1066,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
* @param fire should the entity be set in fire
*/
public void setOnFire(boolean fire) {
final byte state = BitmaskUtil.changeBit(getStateMeta(), (byte) 0x01, (byte) (fire ? 1 : 0), (byte) 0);
this.metadata.setIndex((byte) 0, Metadata.Byte(state));
this.entityMeta.setOnFire(fire);
}
/**
@ -999,7 +1077,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
* @return true if the player is sneaking
*/
public boolean isSneaking() {
return (getStateMeta() & 0x02) != 0;
return this.entityMeta.isSneaking();
}
/**
@ -1011,9 +1089,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
*/
public void setSneaking(boolean sneaking) {
setPose(sneaking ? Pose.SNEAKING : Pose.STANDING);
// update the crouched metadata
final byte state = BitmaskUtil.changeBit(getStateMeta(), (byte) 0x02, (byte) (sneaking ? 1 : 0), (byte) 1);
this.metadata.setIndex((byte) 0, Metadata.Byte(state));
this.entityMeta.setSneaking(sneaking);
}
/**
@ -1024,7 +1100,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
* @return true if the player is sprinting
*/
public boolean isSprinting() {
return (getStateMeta() & 0x08) != 0;
return this.entityMeta.isSprinting();
}
/**
@ -1035,8 +1111,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
* @param sprinting true to make the entity sprint
*/
public void setSprinting(boolean sprinting) {
final byte state = BitmaskUtil.changeBit(getStateMeta(), (byte) 0x08, (byte) (sprinting ? 1 : 0), (byte) 3);
this.metadata.setIndex((byte) 0, Metadata.Byte(state));
this.entityMeta.setSprinting(sprinting);
}
/**
@ -1045,7 +1120,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
* @return true if the entity is invisible, false otherwise
*/
public boolean isInvisible() {
return (getStateMeta() & 0x20) != 0;
return this.entityMeta.isInvisible();
}
/**
@ -1055,8 +1130,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
* @param invisible true to set the entity invisible, false otherwise
*/
public void setInvisible(boolean invisible) {
final byte state = BitmaskUtil.changeBit(getStateMeta(), (byte) 0x20, (byte) (invisible ? 1 : 0), (byte) 5);
this.metadata.setIndex((byte) 0, Metadata.Byte(state));
this.entityMeta.setInvisible(invisible);
}
/**
@ -1065,7 +1139,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
* @return true if the entity is glowing, false otherwise
*/
public boolean isGlowing() {
return (getStateMeta() & 0x40) != 0;
return this.entityMeta.isHasGlowingEffect();
}
/**
@ -1074,8 +1148,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
* @param glowing true to make the entity glows, false otherwise
*/
public void setGlowing(boolean glowing) {
final byte state = BitmaskUtil.changeBit(getStateMeta(), (byte) 0x40, (byte) (glowing ? 1 : 0), (byte) 6);
this.metadata.setIndex((byte) 0, Metadata.Byte(state));
this.entityMeta.setHasGlowingEffect(glowing);
}
/**
@ -1085,7 +1158,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
*/
@NotNull
public Pose getPose() {
return metadata.getIndex((byte) 6, Pose.STANDING);
return this.entityMeta.getPose();
}
/**
@ -1098,7 +1171,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
*/
@NotNull
public void setPose(@NotNull Pose pose) {
this.metadata.setIndex((byte) 6, Metadata.Pose(pose));
this.entityMeta.setPose(pose);
}
/**
@ -1108,7 +1181,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
*/
@Nullable
public JsonMessage getCustomName() {
return metadata.getIndex((byte) 2, null);
return this.entityMeta.getCustomName();
}
/**
@ -1117,7 +1190,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
* @param customName the custom name of the entity, null to remove it
*/
public void setCustomName(@Nullable JsonMessage customName) {
this.metadata.setIndex((byte) 2, Metadata.OptChat(customName));
this.entityMeta.setCustomName(customName);
}
/**
@ -1126,7 +1199,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
* @return true if the custom name is visible, false otherwise
*/
public boolean isCustomNameVisible() {
return metadata.getIndex((byte) 3, false);
return this.entityMeta.isCustomNameVisible();
}
/**
@ -1136,15 +1209,15 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
* @param customNameVisible true to make the custom name visible, false otherwise
*/
public void setCustomNameVisible(boolean customNameVisible) {
this.metadata.setIndex((byte) 3, Metadata.Boolean(customNameVisible));
this.entityMeta.setCustomNameVisible(customNameVisible);
}
public boolean isSilent() {
return metadata.getIndex((byte) 4, false);
return this.entityMeta.isSilent();
}
public void setSilent(boolean silent) {
this.metadata.setIndex((byte) 4, Metadata.Boolean(silent));
this.entityMeta.setSilent(silent);
}
/**
@ -1153,7 +1226,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
* @return true if the entity ignore gravity, false otherwise
*/
public boolean hasNoGravity() {
return metadata.getIndex((byte) 5, false);
return this.entityMeta.isHasNoGravity();
}
/**
@ -1162,7 +1235,7 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
* @param noGravity should the entity ignore gravity
*/
public void setNoGravity(boolean noGravity) {
this.metadata.setIndex((byte) 5, Metadata.Boolean(noGravity));
this.entityMeta.setHasNoGravity(noGravity);
}
/**
@ -1368,14 +1441,19 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
return scheduledRemoveTime != 0;
}
@NotNull
protected Vector getVelocityForPacket() {
return this.velocity.clone().multiply(8000f / MinecraftServer.TICK_PER_SECOND);
}
@NotNull
protected EntityVelocityPacket getVelocityPacket() {
final float strength = 8000f / MinecraftServer.TICK_PER_SECOND;
EntityVelocityPacket velocityPacket = new EntityVelocityPacket();
velocityPacket.entityId = getEntityId();
velocityPacket.velocityX = (short) (velocity.getX() * strength);
velocityPacket.velocityY = (short) (velocity.getY() * strength);
velocityPacket.velocityZ = (short) (velocity.getZ() * strength);
Vector velocity = getVelocityForPacket();
velocityPacket.velocityX = (short) velocity.getX();
velocityPacket.velocityY = (short) velocity.getY();
velocityPacket.velocityZ = (short) velocity.getZ();
return velocityPacket;
}
@ -1392,10 +1470,6 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer, P
return metaDataPacket;
}
private byte getStateMeta() {
return metadata.getIndex((byte) 0, (byte) 0);
}
protected void sendSynchronization() {
EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket();
entityTeleportPacket.entityId = getEntityId();

View File

@ -9,12 +9,7 @@ import net.minestom.server.entity.ai.TargetSelector;
import net.minestom.server.entity.pathfinding.NavigableEntity;
import net.minestom.server.entity.pathfinding.Navigator;
import net.minestom.server.event.entity.EntityAttackEvent;
import net.minestom.server.event.item.ArmorEquipEvent;
import net.minestom.server.instance.Instance;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.packet.server.play.EntityEquipmentPacket;
import net.minestom.server.network.packet.server.play.SpawnLivingEntityPacket;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.time.TimeUnit;
import org.jetbrains.annotations.NotNull;
@ -22,7 +17,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
public abstract class EntityCreature extends LivingEntity implements NavigableEntity, EntityAI {
public class EntityCreature extends LivingEntity implements NavigableEntity, EntityAI {
private int removalAnimationDelay = 1000;
@ -33,36 +28,26 @@ public abstract class EntityCreature extends LivingEntity implements NavigableEn
private Entity target;
/**
* Lock used to support #switchEntityType
* Constructor which allows to specify an UUID. Only use if you know what you are doing!
*/
private final Object entityTypeLock = new Object();
// Equipments
private ItemStack mainHandItem;
private ItemStack offHandItem;
private ItemStack helmet;
private ItemStack chestplate;
private ItemStack leggings;
private ItemStack boots;
public EntityCreature(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
super(entityType, spawnPosition);
this.mainHandItem = ItemStack.getAirItem();
this.offHandItem = ItemStack.getAirItem();
this.helmet = ItemStack.getAirItem();
this.chestplate = ItemStack.getAirItem();
this.leggings = ItemStack.getAirItem();
this.boots = ItemStack.getAirItem();
public EntityCreature(@NotNull EntityType entityType, @NotNull UUID uuid) {
super(entityType, uuid);
heal();
}
public EntityCreature(@NotNull EntityType entityType) {
this(entityType, UUID.randomUUID());
}
@Deprecated
public EntityCreature(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
super(entityType, spawnPosition);
heal();
}
@Deprecated
public EntityCreature(@NotNull EntityType entityType, @NotNull Position spawnPosition, @Nullable Instance instance) {
this(entityType, spawnPosition);
if (instance != null) {
setInstance(instance);
}
@ -81,15 +66,10 @@ public abstract class EntityCreature extends LivingEntity implements NavigableEn
}
@Override
public void setInstance(@NotNull Instance instance) {
public void setInstance(@NotNull Instance instance, @NotNull Position spawnPosition) {
this.navigator.setPathFinder(new HydrazinePathFinder(navigator.getPathingEntity(), instance.getInstanceSpace()));
super.setInstance(instance);
}
@Override
public void spawn() {
super.setInstance(instance, spawnPosition);
}
@Override
@ -105,63 +85,6 @@ public abstract class EntityCreature extends LivingEntity implements NavigableEn
}
}
@Override
public boolean addViewer(@NotNull Player player) {
synchronized (entityTypeLock) {
final boolean result = super.addViewer(player);
final PlayerConnection playerConnection = player.getPlayerConnection();
SpawnLivingEntityPacket spawnLivingEntityPacket = new SpawnLivingEntityPacket();
spawnLivingEntityPacket.entityId = getEntityId();
spawnLivingEntityPacket.entityUuid = getUuid();
spawnLivingEntityPacket.entityType = getEntityType().getId();
spawnLivingEntityPacket.position = getPosition();
spawnLivingEntityPacket.headPitch = getPosition().getYaw();
playerConnection.sendPacket(spawnLivingEntityPacket);
playerConnection.sendPacket(getVelocityPacket());
playerConnection.sendPacket(getMetadataPacket());
// Equipments synchronization
syncEquipments(playerConnection);
if (hasPassenger()) {
playerConnection.sendPacket(getPassengersPacket());
}
return result;
}
}
@Override
public boolean removeViewer(@NotNull Player player) {
synchronized (entityTypeLock) {
return super.removeViewer(player);
}
}
/**
* Changes the entity type of this entity.
* <p>
* Works by changing the internal entity type field and by calling {@link #removeViewer(Player)}
* followed by {@link #addViewer(Player)} to all current viewers.
* <p>
* Be aware that this only change the visual of the entity, the {@link net.minestom.server.collision.BoundingBox}
* will not be modified.
*
* @param entityType the new entity type
*/
public void switchEntityType(@NotNull EntityType entityType) {
synchronized (entityTypeLock) {
this.entityType = entityType;
Set<Player> viewers = new HashSet<>(getViewers());
getViewers().forEach(this::removeViewer);
viewers.forEach(this::addViewer);
}
}
/**
* Gets the kill animation delay before vanishing the entity.
*
@ -171,7 +94,6 @@ public abstract class EntityCreature extends LivingEntity implements NavigableEn
return removalAnimationDelay;
}
/**
* Changes the removal animation delay of the entity.
* <p>
@ -207,78 +129,6 @@ public abstract class EntityCreature extends LivingEntity implements NavigableEn
this.target = target;
}
@NotNull
@Override
public ItemStack getItemInMainHand() {
return mainHandItem;
}
@Override
public void setItemInMainHand(@NotNull ItemStack itemStack) {
this.mainHandItem = itemStack;
syncEquipment(EntityEquipmentPacket.Slot.MAIN_HAND);
}
@NotNull
@Override
public ItemStack getItemInOffHand() {
return offHandItem;
}
@Override
public void setItemInOffHand(@NotNull ItemStack itemStack) {
this.offHandItem = itemStack;
syncEquipment(EntityEquipmentPacket.Slot.OFF_HAND);
}
@NotNull
@Override
public ItemStack getHelmet() {
return helmet;
}
@Override
public void setHelmet(@NotNull ItemStack itemStack) {
this.helmet = getEquipmentItem(itemStack, ArmorEquipEvent.ArmorSlot.HELMET);
syncEquipment(EntityEquipmentPacket.Slot.HELMET);
}
@NotNull
@Override
public ItemStack getChestplate() {
return chestplate;
}
@Override
public void setChestplate(@NotNull ItemStack itemStack) {
this.chestplate = getEquipmentItem(itemStack, ArmorEquipEvent.ArmorSlot.CHESTPLATE);
syncEquipment(EntityEquipmentPacket.Slot.CHESTPLATE);
}
@NotNull
@Override
public ItemStack getLeggings() {
return leggings;
}
@Override
public void setLeggings(@NotNull ItemStack itemStack) {
this.leggings = getEquipmentItem(itemStack, ArmorEquipEvent.ArmorSlot.LEGGINGS);
syncEquipment(EntityEquipmentPacket.Slot.LEGGINGS);
}
@NotNull
@Override
public ItemStack getBoots() {
return boots;
}
@Override
public void setBoots(@NotNull ItemStack itemStack) {
this.boots = getEquipmentItem(itemStack, ArmorEquipEvent.ArmorSlot.BOOTS);
syncEquipment(EntityEquipmentPacket.Slot.BOOTS);
}
@NotNull
@Override
public Navigator getNavigator() {
@ -309,9 +159,4 @@ public abstract class EntityCreature extends LivingEntity implements NavigableEn
attack(target, false);
}
private ItemStack getEquipmentItem(@NotNull ItemStack itemStack, @NotNull ArmorEquipEvent.ArmorSlot armorSlot) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(this, itemStack, armorSlot);
callEvent(ArmorEquipEvent.class, armorEquipEvent);
return armorEquipEvent.getArmorItem();
}
}

View File

@ -0,0 +1,109 @@
package net.minestom.server.entity;
import net.minestom.server.entity.metadata.ObjectDataProvider;
import net.minestom.server.entity.metadata.other.ExperienceOrbMeta;
import net.minestom.server.entity.metadata.other.PaintingMeta;
import net.minestom.server.network.packet.server.ServerPacket;
import net.minestom.server.network.packet.server.play.*;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Vector;
public enum EntitySpawnType {
BASE {
@Override
public ServerPacket getSpawnPacket(Entity entity) {
SpawnEntityPacket packet = new SpawnEntityPacket();
packet.entityId = entity.getEntityId();
packet.uuid = entity.getUuid();
packet.type = entity.getEntityType().ordinal();
packet.position = entity.getPosition();
if (entity.getEntityMeta() instanceof ObjectDataProvider) {
ObjectDataProvider objectDataProvider = (ObjectDataProvider) entity.getEntityMeta();
packet.data = objectDataProvider.getObjectData();
if (objectDataProvider.requiresVelocityPacketAtSpawn()) {
Vector velocity = entity.getVelocityForPacket();
packet.velocityX = (short) velocity.getX();
packet.velocityY = (short) velocity.getY();
packet.velocityZ = (short) velocity.getZ();
}
}
return packet;
}
},
LIVING {
@Override
public ServerPacket getSpawnPacket(Entity entity) {
SpawnLivingEntityPacket packet = new SpawnLivingEntityPacket();
packet.entityId = entity.getEntityId();
packet.entityUuid = entity.getUuid();
packet.entityType = entity.getEntityType().ordinal();
packet.position = entity.getPosition();
packet.headPitch = entity.getPosition().getPitch();
Vector velocity = entity.getVelocityForPacket();
packet.velocityX = (short) velocity.getX();
packet.velocityY = (short) velocity.getY();
packet.velocityZ = (short) velocity.getZ();
return packet;
}
},
PLAYER {
@Override
public ServerPacket getSpawnPacket(Entity entity) {
SpawnPlayerPacket packet = new SpawnPlayerPacket();
packet.entityId = entity.getEntityId();
packet.playerUuid = entity.getUuid();
packet.position = entity.getPosition();
return packet;
}
},
EXPERIENCE_ORB {
@Override
public ServerPacket getSpawnPacket(Entity entity) {
SpawnExperienceOrbPacket packet = new SpawnExperienceOrbPacket();
packet.entityId = entity.getEntityId();
packet.position = entity.getPosition();
if (entity.getEntityMeta() instanceof ExperienceOrbMeta) {
ExperienceOrbMeta experienceOrbMeta = (ExperienceOrbMeta) entity.getEntityMeta();
packet.expCount = (short) experienceOrbMeta.getCount();
}
return packet;
}
},
PAINTING {
@Override
public ServerPacket getSpawnPacket(Entity entity) {
SpawnPaintingPacket packet = new SpawnPaintingPacket();
packet.entityId = entity.getEntityId();
packet.entityUuid = entity.getUuid();
if (entity.getEntityMeta() instanceof PaintingMeta) {
PaintingMeta paintingMeta = (PaintingMeta) entity.getEntityMeta();
packet.motive = paintingMeta.getMotive().ordinal();
packet.position = new BlockPosition(
Math.max(0, (paintingMeta.getMotive().getWidth() >> 1) - 1),
paintingMeta.getMotive().getHeight() >> 1,
0
);
switch (paintingMeta.getDirection()) {
case SOUTH:
packet.direction = 0;
break;
case WEST:
packet.direction = 1;
break;
case NORTH:
packet.direction = 2;
break;
case EAST:
packet.direction = 3;
break;
}
} else {
packet.position = new BlockPosition(0, 0, 0);
}
return packet;
}
};
public abstract ServerPacket getSpawnPacket(Entity entity);
}

View File

@ -1,8 +1,6 @@
package net.minestom.server.entity;
import net.minestom.server.instance.Instance;
import net.minestom.server.network.packet.server.play.SpawnExperienceOrbPacket;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.Position;
import net.minestom.server.utils.Vector;
import org.jetbrains.annotations.NotNull;
@ -87,25 +85,6 @@ public class ExperienceOrb extends Entity {
}
@Override
public boolean addViewer(@NotNull Player player) {
final boolean result = super.addViewer(player); // Add player to viewers list
if (!result)
return false;
final PlayerConnection playerConnection = player.getPlayerConnection();
SpawnExperienceOrbPacket experienceOrbPacket = new SpawnExperienceOrbPacket();
experienceOrbPacket.entityId = getEntityId();
experienceOrbPacket.position = getPosition();
experienceOrbPacket.expCount = experienceCount;
playerConnection.sendPacket(experienceOrbPacket);
playerConnection.sendPacket(getVelocityPacket());
return true;
}
/**
* Gets the experience count.
*

View File

@ -5,18 +5,17 @@ import net.minestom.server.attribute.AttributeInstance;
import net.minestom.server.attribute.Attributes;
import net.minestom.server.collision.BoundingBox;
import net.minestom.server.entity.damage.DamageType;
import net.minestom.server.entity.metadata.LivingEntityMeta;
import net.minestom.server.event.entity.EntityDamageEvent;
import net.minestom.server.event.entity.EntityDeathEvent;
import net.minestom.server.event.entity.EntityFireEvent;
import net.minestom.server.event.item.ArmorEquipEvent;
import net.minestom.server.event.item.PickupItemEvent;
import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.block.Block;
import net.minestom.server.inventory.EquipmentHandler;
import net.minestom.server.item.ItemStack;
import net.minestom.server.network.packet.server.play.CollectItemPacket;
import net.minestom.server.network.packet.server.play.EntityAnimationPacket;
import net.minestom.server.network.packet.server.play.EntityPropertiesPacket;
import net.minestom.server.network.packet.server.play.SoundEffectPacket;
import net.minestom.server.network.packet.server.play.*;
import net.minestom.server.scoreboard.Team;
import net.minestom.server.sound.Sound;
import net.minestom.server.sound.SoundCategory;
@ -34,7 +33,7 @@ import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
//TODO: Default attributes registration (and limitation ?)
public abstract class LivingEntity extends Entity implements EquipmentHandler {
public class LivingEntity extends Entity implements EquipmentHandler {
// Item pickup
protected boolean canPickupItem;
@ -70,30 +69,134 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
private Team team;
public LivingEntity(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
super(entityType, spawnPosition);
setupAttributes();
setGravity(0.02f, 0.08f, 3.92f);
}
private int arrowCount;
private float health = 1F;
/**
* Constructor which allows to specify an UUID. Only use if you know what you are doing!
*/
public LivingEntity(@NotNull EntityType entityType, @NotNull UUID uuid, @NotNull Position spawnPosition) {
super(entityType, uuid, spawnPosition);
setupAttributes();
setGravity(0.02f, 0.08f, 3.92f);
}
// Equipments
private ItemStack mainHandItem;
private ItemStack offHandItem;
public LivingEntity(@NotNull EntityType entityType) {
this(entityType, new Position());
}
private ItemStack helmet;
private ItemStack chestplate;
private ItemStack leggings;
private ItemStack boots;
/**
* Constructor which allows to specify an UUID. Only use if you know what you are doing!
*/
public LivingEntity(@NotNull EntityType entityType, @NotNull UUID uuid) {
this(entityType, uuid, new Position());
setupAttributes();
setGravity(0.02f, 0.08f, 3.92f);
initEquipments();
}
public LivingEntity(@NotNull EntityType entityType) {
this(entityType, UUID.randomUUID());
}
/**
* Constructor which allows to specify an UUID. Only use if you know what you are doing!
*/
@Deprecated
public LivingEntity(@NotNull EntityType entityType, @NotNull UUID uuid, @NotNull Position spawnPosition) {
super(entityType, uuid, spawnPosition);
setupAttributes();
setGravity(0.02f, 0.08f, 3.92f);
initEquipments();
}
@Deprecated
public LivingEntity(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
this(entityType, UUID.randomUUID(), spawnPosition);
}
private void initEquipments() {
this.mainHandItem = ItemStack.getAirItem();
this.offHandItem = ItemStack.getAirItem();
this.helmet = ItemStack.getAirItem();
this.chestplate = ItemStack.getAirItem();
this.leggings = ItemStack.getAirItem();
this.boots = ItemStack.getAirItem();
}
@NotNull
@Override
public ItemStack getItemInMainHand() {
return mainHandItem;
}
@Override
public void setItemInMainHand(@NotNull ItemStack itemStack) {
this.mainHandItem = itemStack;
syncEquipment(EntityEquipmentPacket.Slot.MAIN_HAND);
}
@NotNull
@Override
public ItemStack getItemInOffHand() {
return offHandItem;
}
@Override
public void setItemInOffHand(@NotNull ItemStack itemStack) {
this.offHandItem = itemStack;
syncEquipment(EntityEquipmentPacket.Slot.OFF_HAND);
}
@NotNull
@Override
public ItemStack getHelmet() {
return helmet;
}
@Override
public void setHelmet(@NotNull ItemStack itemStack) {
this.helmet = getEquipmentItem(itemStack, ArmorEquipEvent.ArmorSlot.HELMET);
syncEquipment(EntityEquipmentPacket.Slot.HELMET);
}
@NotNull
@Override
public ItemStack getChestplate() {
return chestplate;
}
@Override
public void setChestplate(@NotNull ItemStack itemStack) {
this.chestplate = getEquipmentItem(itemStack, ArmorEquipEvent.ArmorSlot.CHESTPLATE);
syncEquipment(EntityEquipmentPacket.Slot.CHESTPLATE);
}
@NotNull
@Override
public ItemStack getLeggings() {
return leggings;
}
@Override
public void setLeggings(@NotNull ItemStack itemStack) {
this.leggings = getEquipmentItem(itemStack, ArmorEquipEvent.ArmorSlot.LEGGINGS);
syncEquipment(EntityEquipmentPacket.Slot.LEGGINGS);
}
@NotNull
@Override
public ItemStack getBoots() {
return boots;
}
@Override
public void setBoots(@NotNull ItemStack itemStack) {
this.boots = getEquipmentItem(itemStack, ArmorEquipEvent.ArmorSlot.BOOTS);
syncEquipment(EntityEquipmentPacket.Slot.BOOTS);
}
private ItemStack getEquipmentItem(@NotNull ItemStack itemStack, @NotNull ArmorEquipEvent.ArmorSlot armorSlot) {
ArmorEquipEvent armorEquipEvent = new ArmorEquipEvent(this, itemStack, armorSlot);
callEvent(ArmorEquipEvent.class, armorEquipEvent);
return armorEquipEvent.getArmorItem();
}
@Override
@ -152,7 +255,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
* @return the arrow count
*/
public int getArrowCount() {
return metadata.getIndex((byte) 11, 0);
return this.arrowCount;
}
/**
@ -161,7 +264,11 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
* @param arrowCount the arrow count
*/
public void setArrowCount(int arrowCount) {
this.metadata.setIndex((byte) 11, Metadata.VarInt(arrowCount));
this.arrowCount = arrowCount;
LivingEntityMeta meta = getLivingEntityMeta();
if (meta != null) {
meta.setArrowCount(arrowCount);
}
}
/**
@ -315,7 +422,7 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
* @return the entity health
*/
public float getHealth() {
return metadata.getIndex((byte) 8, 1f);
return this.health;
}
/**
@ -324,12 +431,14 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
* @param health the new entity health
*/
public void setHealth(float health) {
health = Math.min(health, getMaxHealth());
if (health <= 0 && !isDead) {
this.health = Math.min(health, getMaxHealth());
if (this.health <= 0 && !isDead) {
kill();
}
this.metadata.setIndex((byte) 8, Metadata.Float(health));
LivingEntityMeta meta = getLivingEntityMeta();
if (meta != null) {
meta.setHealth(this.health);
}
}
/**
@ -418,6 +527,15 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
this.canPickupItem = canPickupItem;
}
@Override
public boolean addViewer0(@NotNull Player player) {
if (!super.addViewer0(player)) {
return false;
}
syncEquipments(player.getPlayerConnection());
return true;
}
@Override
public void setBoundingBox(double x, double y, double z) {
super.setBoundingBox(x, y, z);
@ -447,15 +565,14 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
}
public void refreshActiveHand(boolean isHandActive, boolean offHand, boolean riptideSpinAttack) {
byte handState = 0;
if (isHandActive)
handState |= 0x01;
if (offHand)
handState |= 0x02;
if (riptideSpinAttack)
handState |= 0x04;
this.metadata.setIndex((byte) 7, Metadata.Byte(handState));
LivingEntityMeta meta = getLivingEntityMeta();
if (meta != null) {
meta.setNotifyAboutChanges(false);
meta.setHandActive(isHandActive);
meta.setActiveHand(offHand ? Player.Hand.OFF : Player.Hand.MAIN);
meta.setInRiptideSpinAttack(riptideSpinAttack);
meta.setNotifyAboutChanges(true);
}
}
/**
@ -600,10 +717,10 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
* @return if the current entity has line of sight to the given one.
*/
public boolean hasLineOfSight(Entity entity) {
Vector start = getPosition().toVector().add(0D, getEyeHeight(), 0D);
Vector end = entity.getPosition().toVector().add(0D, getEyeHeight(), 0D);
Vector direction = end.subtract(start);
int maxDistance = (int) Math.ceil(direction.length());
Vector start = getPosition().toVector().add(0D, getEyeHeight(), 0D);
Vector end = entity.getPosition().toVector().add(0D, getEyeHeight(), 0D);
Vector direction = end.subtract(start);
int maxDistance = (int) Math.ceil(direction.length());
Iterator<BlockPosition> it = new BlockIterator(start, direction.normalize(), 0D, maxDistance);
while (it.hasNext()) {
@ -630,4 +747,16 @@ public abstract class LivingEntity extends Entity implements EquipmentHandler {
return null;
}
/**
* Gets {@link net.minestom.server.entity.metadata.EntityMeta} of this entity casted to {@link LivingEntityMeta}.
*
* @return null if meta of this entity does not inherit {@link LivingEntityMeta}, casted value otherwise.
*/
public LivingEntityMeta getLivingEntityMeta() {
if (this.entityMeta instanceof LivingEntityMeta) {
return (LivingEntityMeta) this.entityMeta;
}
return null;
}
}

View File

@ -12,10 +12,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jglrxavpok.hephaistos.nbt.NBT;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.UUID;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Consumer;
@ -105,9 +102,7 @@ public class Metadata {
}
public static Value<NBT> NBT(@NotNull NBT nbt) {
return new Value<>(TYPE_NBT, nbt, writer -> {
writer.writeNBT("", nbt);
});
return new Value<>(TYPE_NBT, nbt, writer -> writer.writeNBT("", nbt));
}
public static Value<int[]> VillagerData(int villagerType,
@ -153,14 +148,18 @@ public class Metadata {
private final Entity entity;
private Map<Byte, Entry<?>> metadataMap = new ConcurrentHashMap<>();
private final Map<Byte, Entry<?>> metadataMap = new ConcurrentHashMap<>();
private volatile boolean notifyAboutChanges = true;
private final Map<Byte, Entry<?>> notNotifiedChanges = new HashMap<>();
public Metadata(@Nullable Entity entity) {
this.entity = entity;
}
@SuppressWarnings("unchecked")
public <T> T getIndex(byte index, @Nullable T defaultValue) {
Entry<?> value = metadataMap.get(index);
Entry<?> value = this.metadataMap.get(index);
return value != null ? (T) value.getMetaValue().value : defaultValue;
}
@ -169,15 +168,49 @@ public class Metadata {
this.metadataMap.put(index, entry);
// Send metadata packet to update viewers and self
if (entity != null && entity.isActive()) {
if (this.entity != null && this.entity.isActive()) {
if (!this.notifyAboutChanges) {
synchronized (this.notNotifiedChanges) {
this.notNotifiedChanges.put(index, entry);
}
return;
}
EntityMetaDataPacket metaDataPacket = new EntityMetaDataPacket();
metaDataPacket.entityId = entity.getEntityId();
metaDataPacket.entityId = this.entity.getEntityId();
metaDataPacket.entries = Collections.singleton(entry);
this.entity.sendPacketToViewersAndSelf(metaDataPacket);
}
}
public void setNotifyAboutChanges(boolean notifyAboutChanges) {
if (this.notifyAboutChanges == notifyAboutChanges) {
return;
}
Collection<Entry<?>> entries = null;
synchronized (this.notNotifiedChanges) {
this.notifyAboutChanges = notifyAboutChanges;
if (notifyAboutChanges) {
entries = this.notNotifiedChanges.values();
if (entries.isEmpty()) {
return;
}
this.notNotifiedChanges.clear();
}
}
if (entries == null || this.entity == null || !this.entity.isActive()) {
return;
}
EntityMetaDataPacket metaDataPacket = new EntityMetaDataPacket();
metaDataPacket.entityId = this.entity.getEntityId();
metaDataPacket.entries = entries;
this.entity.sendPacketToViewersAndSelf(metaDataPacket);
}
@NotNull
public Collection<Entry<?>> getEntries() {
return metadataMap.values();

View File

@ -1,10 +1,13 @@
package net.minestom.server.entity;
import net.minestom.server.network.packet.server.play.SpawnEntityPacket;
import net.minestom.server.network.player.PlayerConnection;
import net.minestom.server.utils.Position;
import org.jetbrains.annotations.NotNull;
/**
* @deprecated Use {@link net.minestom.server.entity.metadata.EntityMeta} that inherits
* {@link net.minestom.server.entity.metadata.ObjectDataProvider} instead.
*/
@Deprecated
public abstract class ObjectEntity extends Entity {
public ObjectEntity(@NotNull EntityType entityType, @NotNull Position spawnPosition) {
@ -30,29 +33,4 @@ public abstract class ObjectEntity extends Entity {
}
@Override
public boolean addViewer(@NotNull Player player) {
final boolean result = super.addViewer(player);
if (!result)
return false;
final PlayerConnection playerConnection = player.getPlayerConnection();
SpawnEntityPacket spawnEntityPacket = new SpawnEntityPacket();
spawnEntityPacket.entityId = getEntityId();
spawnEntityPacket.uuid = getUuid();
spawnEntityPacket.type = getEntityType().getId();
spawnEntityPacket.position = getPosition();
spawnEntityPacket.data = getObjectData();
playerConnection.sendPacket(spawnEntityPacket);
playerConnection.sendPacket(getVelocityPacket());
playerConnection.sendPacket(getMetadataPacket());
if (hasPassenger()) {
playerConnection.sendPacket(getPassengersPacket());
}
return true;
}
}

View File

@ -626,13 +626,10 @@ public class Player extends LivingEntity implements CommandSender {
}
@Override
public boolean addViewer(@NotNull Player player) {
if (player == this)
return false;
final boolean result = super.addViewer(player);
if (!result)
public boolean addViewer0(@NotNull Player player) {
if (player == this || !super.addViewer0(player)) {
return false;
}
PlayerConnection viewerConnection = player.getPlayerConnection();
showPlayer(viewerConnection);
@ -640,18 +637,19 @@ public class Player extends LivingEntity implements CommandSender {
}
@Override
public boolean removeViewer(@NotNull Player player) {
if (player == this)
public boolean removeViewer0(@NotNull Player player) {
if (player == this || !super.removeViewer0(player)) {
return false;
}
boolean result = super.removeViewer(player);
PlayerConnection viewerConnection = player.getPlayerConnection();
viewerConnection.sendPacket(getRemovePlayerToList());
// Team
if (this.getTeam() != null && this.getTeam().getMembers().size() == 1) // If team only contains "this" player
if (this.getTeam() != null && this.getTeam().getMembers().size() == 1) {// If team only contains "this" player
viewerConnection.sendPacket(this.getTeam().createTeamDestructionPacket());
return result;
}
return true;
}
/**
@ -663,6 +661,7 @@ public class Player extends LivingEntity implements CommandSender {
* @param instance the new player instance
* @param spawnPosition the new position of the player
*/
@Override
public void setInstance(@NotNull Instance instance, @NotNull Position spawnPosition) {
Check.argCondition(this.instance == instance, "Instance should be different than the current one");
@ -734,7 +733,7 @@ public class Player extends LivingEntity implements CommandSender {
* @param spawnPosition the position to teleport the player
* @param firstSpawn true if this is the player first spawn
*/
private void spawnPlayer(@NotNull Instance instance, @Nullable Position spawnPosition,
private void spawnPlayer(@NotNull Instance instance, @NotNull Position spawnPosition,
boolean firstSpawn, boolean updateChunks) {
// Clear previous instance elements
if (!firstSpawn) {
@ -742,9 +741,9 @@ public class Player extends LivingEntity implements CommandSender {
this.viewableEntities.forEach(entity -> entity.removeViewer(this));
}
super.setInstance(instance);
super.setInstance(instance, spawnPosition);
if (spawnPosition != null && !position.isSimilar(spawnPosition)) {
if (!position.isSimilar(spawnPosition)) {
teleport(spawnPosition);
} else if (updateChunks) {
// Send newly visible chunks to player once spawned in the instance
@ -860,6 +859,15 @@ public class Player extends LivingEntity implements CommandSender {
playerConnection.sendPacket(soundEffectPacket);
}
/**
* Plays a sound from the {@link Sound} enum.
*
* @see #playSound(Sound, SoundCategory, int, int, int, float, float)
*/
public void playSound(@NotNull Sound sound, @NotNull SoundCategory soundCategory, BlockPosition position, float volume, float pitch) {
playSound(sound, soundCategory, position.getX(), position.getY(), position.getZ(), volume, pitch);
}
/**
* Plays a sound from an identifier (represents a custom sound in a resource pack).
*
@ -883,6 +891,15 @@ public class Player extends LivingEntity implements CommandSender {
playerConnection.sendPacket(namedSoundEffectPacket);
}
/**
* Plays a sound from an identifier (represents a custom sound in a resource pack).
*
* @see #playSound(String, SoundCategory, int, int, int, float, float)
*/
public void playSound(@NotNull String identifier, @NotNull SoundCategory soundCategory, BlockPosition position, float volume, float pitch) {
playSound(identifier, soundCategory, position.getX(), position.getY(), position.getZ(), volume, pitch);
}
/**
* Plays a sound directly to the player (constant volume).
*
@ -1417,11 +1434,7 @@ public class Player extends LivingEntity implements CommandSender {
protected void refreshAfterTeleport() {
getInventory().update();
SpawnPlayerPacket spawnPlayerPacket = new SpawnPlayerPacket();
spawnPlayerPacket.entityId = getEntityId();
spawnPlayerPacket.playerUuid = getUuid();
spawnPlayerPacket.position = getPosition();
sendPacketToViewers(spawnPlayerPacket);
sendPacketsToViewers(getEntityType().getSpawnType().getSpawnPacket(this));
// Update for viewers
sendPacketToViewersAndSelf(getVelocityPacket());
@ -2400,14 +2413,9 @@ public class Player extends LivingEntity implements CommandSender {
* @param connection the connection to show the player to
*/
protected void showPlayer(@NotNull PlayerConnection connection) {
SpawnPlayerPacket spawnPlayerPacket = new SpawnPlayerPacket();
spawnPlayerPacket.entityId = getEntityId();
spawnPlayerPacket.playerUuid = getUuid();
spawnPlayerPacket.position = getPosition();
connection.sendPacket(getAddPlayerToList());
connection.sendPacket(spawnPlayerPacket);
connection.sendPacket(getEntityType().getSpawnType().getSpawnPacket(this));
connection.sendPacket(getVelocityPacket());
connection.sendPacket(getMetadataPacket());

View File

@ -0,0 +1,31 @@
package net.minestom.server.entity.metadata;
import net.minestom.server.collision.BoundingBox;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class AgeableMobMeta extends PathfinderMobMeta {
protected AgeableMobMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isBaby() {
return super.metadata.getIndex((byte) 15, false);
}
public void setBaby(boolean value) {
if (isBaby() == value) {
return;
}
BoundingBox bb = this.entity.getBoundingBox();
if (value) {
setBoundingBox(bb.getWidth() / 2, bb.getHeight() / 2);
} else {
setBoundingBox(bb.getWidth() * 2, bb.getHeight() * 2);
}
super.metadata.setIndex((byte) 15, Metadata.Boolean(value));
}
}

View File

@ -0,0 +1,183 @@
package net.minestom.server.entity.metadata;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class EntityMeta {
private final static byte MASK_INDEX = 0;
private final static byte ON_FIRE_BIT = 0x01;
private final static byte CROUNCHING_BIT = 0x02;
private final static byte SPRINTING_BIT = 0x08;
private final static byte SWIMMING_BIT = 0x10;
private final static byte INVISIBLE_BIT = 0x20;
private final static byte HAS_GLOWING_EFFECT_BIT = 0x40;
private final static byte FLYING_WITH_ELYTRA_BIT = (byte) 0x80;
protected final Entity entity;
protected final Metadata metadata;
protected EntityMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
this.entity = entity;
this.metadata = metadata;
}
/**
* Sets whether any changes to this meta must result in a metadata packet being sent to entity viewers.
* By default it's set to true.
* <p>
* It's usable if you want to change multiple values of this meta at the same time and want just a
* single packet being sent: if so, disable notification before your first change and enable it
* right after the last one: once notification is set to false, we collect all the updates
* that are being performed, and when it's returned to true we send them all together.
* An example usage could be found at
* {@link net.minestom.server.entity.LivingEntity#refreshActiveHand(boolean, boolean, boolean)}.
*
* @param notifyAboutChanges if to notify entity viewers about this meta changes.
*/
public void setNotifyAboutChanges(boolean notifyAboutChanges) {
this.metadata.setNotifyAboutChanges(notifyAboutChanges);
}
public boolean isOnFire() {
return getMaskBit(MASK_INDEX, ON_FIRE_BIT);
}
public void setOnFire(boolean value) {
setMaskBit(MASK_INDEX, ON_FIRE_BIT, value);
}
public boolean isSneaking() {
return getMaskBit(MASK_INDEX, CROUNCHING_BIT);
}
public void setSneaking(boolean value) {
setMaskBit(MASK_INDEX, CROUNCHING_BIT, value);
}
public boolean isSprinting() {
return getMaskBit(MASK_INDEX, SPRINTING_BIT);
}
public void setSprinting(boolean value) {
setMaskBit(MASK_INDEX, SPRINTING_BIT, value);
}
public boolean isSwimming() {
return getMaskBit(MASK_INDEX, SWIMMING_BIT);
}
public void setSwimming(boolean value) {
setMaskBit(MASK_INDEX, SWIMMING_BIT, value);
}
public boolean isInvisible() {
return getMaskBit(MASK_INDEX, INVISIBLE_BIT);
}
public void setInvisible(boolean value) {
setMaskBit(MASK_INDEX, INVISIBLE_BIT, value);
}
public boolean isHasGlowingEffect() {
return getMaskBit(MASK_INDEX, HAS_GLOWING_EFFECT_BIT);
}
public void setHasGlowingEffect(boolean value) {
setMaskBit(MASK_INDEX, HAS_GLOWING_EFFECT_BIT, value);
}
public boolean isFlyingWithElytra() {
return getMaskBit(MASK_INDEX, FLYING_WITH_ELYTRA_BIT);
}
public void setFlyingWithElytra(boolean value) {
setMaskBit(MASK_INDEX, FLYING_WITH_ELYTRA_BIT, value);
}
public int getAirTicks() {
return this.metadata.getIndex((byte) 1, 300);
}
public void setAirTicks(int value) {
this.metadata.setIndex((byte) 1, Metadata.VarInt(value));
}
public JsonMessage getCustomName() {
return this.metadata.getIndex((byte) 2, null);
}
public void setCustomName(JsonMessage value) {
this.metadata.setIndex((byte) 2, Metadata.OptChat(value));
}
public boolean isCustomNameVisible() {
return this.metadata.getIndex((byte) 3, false);
}
public void setCustomNameVisible(boolean value) {
this.metadata.setIndex((byte) 3, Metadata.Boolean(value));
}
public boolean isSilent() {
return this.metadata.getIndex((byte) 4, false);
}
public void setSilent(boolean value) {
this.metadata.setIndex((byte) 4, Metadata.Boolean(value));
}
public boolean isHasNoGravity() {
return this.metadata.getIndex((byte) 5, false);
}
public void setHasNoGravity(boolean value) {
this.metadata.setIndex((byte) 5, Metadata.Boolean(value));
}
public Entity.Pose getPose() {
return this.metadata.getIndex((byte) 6, Entity.Pose.STANDING);
}
public void setPose(Entity.Pose value) {
this.metadata.setIndex((byte) 6, Metadata.Pose(value));
}
protected byte getMask(byte index) {
return this.metadata.getIndex(index, (byte) 0);
}
protected void setMask(byte index, byte mask) {
this.metadata.setIndex(index, Metadata.Byte(mask));
}
protected boolean getMaskBit(byte index, byte bit) {
return (getMask(index) & bit) == bit;
}
protected void setMaskBit(byte index, byte bit, boolean value) {
byte mask = getMask(index);
boolean currentValue = (mask & bit) == bit;
if (currentValue == value) {
return;
}
if (value) {
mask |= bit;
} else {
mask &= ~bit;
}
setMask(index, mask);
}
protected void setBoundingBox(double x, double y, double z) {
this.entity.setBoundingBox(x, y, z);
}
protected void setBoundingBox(double width, double height) {
setBoundingBox(width, height, width);
}
}

View File

@ -0,0 +1,96 @@
package net.minestom.server.entity.metadata;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.Player;
import net.minestom.server.utils.BlockPosition;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class LivingEntityMeta extends EntityMeta {
private final static byte MASK_INDEX = 7;
private final static byte IS_HAND_ACTIVE_BIT = 0x01;
private final static byte ACTIVE_HAND_BIT = 0x02;
private final static byte IS_IN_SPIN_ATTACK_BIT = 0x04;
protected LivingEntityMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isHandActive() {
return getMaskBit(MASK_INDEX, IS_HAND_ACTIVE_BIT);
}
public void setHandActive(boolean value) {
setMaskBit(MASK_INDEX, IS_HAND_ACTIVE_BIT, value);
}
@NotNull
public Player.Hand getActiveHand() {
return getMaskBit(MASK_INDEX, ACTIVE_HAND_BIT) ? Player.Hand.OFF : Player.Hand.MAIN;
}
public void setActiveHand(@NotNull Player.Hand hand) {
setMaskBit(MASK_INDEX, ACTIVE_HAND_BIT, hand == Player.Hand.OFF);
}
public boolean isInRiptideSpinAttack() {
return getMaskBit(MASK_INDEX, IS_IN_SPIN_ATTACK_BIT);
}
public void setInRiptideSpinAttack(boolean value) {
setMaskBit(MASK_INDEX, IS_IN_SPIN_ATTACK_BIT, value);
}
public float getHealth() {
return super.metadata.getIndex((byte) 8, 1F);
}
public void setHealth(float value) {
super.metadata.setIndex((byte) 8, Metadata.Float(value));
}
public int getPotionEffectColor() {
return super.metadata.getIndex((byte) 9, 0);
}
public void setPotionEffectColor(int value) {
super.metadata.setIndex((byte) 9, Metadata.VarInt(value));
}
public boolean isPotionEffectAmbient() {
return super.metadata.getIndex((byte) 10, false);
}
public void setPotionEffectAmbient(boolean value) {
super.metadata.setIndex((byte) 10, Metadata.Boolean(value));
}
public int getArrowCount() {
return super.metadata.getIndex((byte) 11, 0);
}
public void setArrowCount(int value) {
super.metadata.getIndex((byte) 11, Metadata.VarInt(value));
}
public int getHealthAddedByAbsorption() {
return super.metadata.getIndex((byte) 12, 0);
}
public void setHealthAddedByAbsorption(int value) {
super.metadata.getIndex((byte) 12, Metadata.VarInt(value));
}
@Nullable
public BlockPosition getBedInWhichSleepingPosition() {
return super.metadata.getIndex((byte) 13, null);
}
public void setBedInWhichSleepingPosition(@Nullable BlockPosition value) {
super.metadata.setIndex((byte) 13, Metadata.OptPosition(value));
}
}

View File

@ -0,0 +1,43 @@
package net.minestom.server.entity.metadata;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class MobMeta extends LivingEntityMeta {
private final static byte MASK_INDEX = 14;
private final static byte NO_AI_BIT = 0x01;
private final static byte IS_LEFT_HANDED_BIT = 0x02;
private final static byte IS_AGGRESSIVE_BIT = 0x04;
protected MobMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isNoAi() {
return getMaskBit(MASK_INDEX, NO_AI_BIT);
}
public void setNoAi(boolean value) {
setMaskBit(MASK_INDEX, NO_AI_BIT, value);
}
public boolean isLeftHanded() {
return getMaskBit(MASK_INDEX, IS_LEFT_HANDED_BIT);
}
public void setLeftHanded(boolean value) {
setMaskBit(MASK_INDEX, IS_LEFT_HANDED_BIT, value);
}
public boolean isAggressive() {
return getMaskBit(MASK_INDEX, IS_AGGRESSIVE_BIT);
}
public void setAggressive(boolean value) {
setMaskBit(MASK_INDEX, IS_AGGRESSIVE_BIT, value);
}
}

View File

@ -0,0 +1,10 @@
package net.minestom.server.entity.metadata;
// https://wiki.vg/Object_Data
public interface ObjectDataProvider {
int getObjectData();
boolean requiresVelocityPacketAtSpawn();
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.entity.metadata;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class PathfinderMobMeta extends MobMeta {
protected PathfinderMobMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,123 @@
package net.minestom.server.entity.metadata;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jglrxavpok.hephaistos.nbt.NBT;
public class PlayerMeta extends LivingEntityMeta {
private final static byte MASK_INDEX = 16;
private final static byte CAPE_BIT = 0x01;
private final static byte JACKET_BIT = 0x02;
private final static byte LEFT_SLEEVE_BIT = 0x04;
private final static byte RIGHT_SLEEVE_BIT = 0x08;
private final static byte LEFT_LEG_BIT = 0x10;
private final static byte RIGHT_LEG_BIT = 0x20;
private final static byte HAT_BIT = 0x40;
public PlayerMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public float getAdditionalHearts() {
return super.metadata.getIndex((byte) 14, 0F);
}
public void setAdditionalHearts(float value) {
super.metadata.setIndex((byte) 14, Metadata.Float(value));
}
public int getScore() {
return super.metadata.getIndex((byte) 15, 0);
}
public void setScore(int value) {
super.metadata.setIndex((byte) 15, Metadata.VarInt(value));
}
public boolean isCapeEnabled() {
return getMaskBit(MASK_INDEX, CAPE_BIT);
}
public void setCapeEnabled(boolean value) {
setMaskBit(MASK_INDEX, CAPE_BIT, value);
}
public boolean isJacketEnabled() {
return getMaskBit(MASK_INDEX, JACKET_BIT);
}
public void setJacketEnabled(boolean value) {
setMaskBit(MASK_INDEX, JACKET_BIT, value);
}
public boolean isLeftSleeveEnabled() {
return getMaskBit(MASK_INDEX, LEFT_SLEEVE_BIT);
}
public void setLeftSleeveEnabled(boolean value) {
setMaskBit(MASK_INDEX, LEFT_SLEEVE_BIT, value);
}
public boolean isRightSleeveEnabled() {
return getMaskBit(MASK_INDEX, RIGHT_SLEEVE_BIT);
}
public void setRightSleeveEnabled(boolean value) {
setMaskBit(MASK_INDEX, RIGHT_SLEEVE_BIT, value);
}
public boolean isLeftLegEnabled() {
return getMaskBit(MASK_INDEX, LEFT_LEG_BIT);
}
public void setLeftLegEnabled(boolean value) {
setMaskBit(MASK_INDEX, LEFT_LEG_BIT, value);
}
public boolean isRightLegEnabled() {
return getMaskBit(MASK_INDEX, RIGHT_LEG_BIT);
}
public void setRightLegEnabled(boolean value) {
setMaskBit(MASK_INDEX, RIGHT_LEG_BIT, value);
}
public boolean isHatEnabled() {
return getMaskBit(MASK_INDEX, HAT_BIT);
}
public void setHatEnabled(boolean value) {
setMaskBit(MASK_INDEX, HAT_BIT, value);
}
public boolean isRightMainHand() {
return super.metadata.getIndex((byte) 17, (byte) 1) == (byte) 1;
}
public void setRightMainHand(boolean value) {
super.metadata.setIndex((byte) 17, Metadata.Byte(value ? (byte) 1 : (byte) 0));
}
@Nullable
public NBT getLeftShoulderEntityData() {
return super.metadata.getIndex((byte) 18, null);
}
public void setLeftShoulderEntityData(@Nullable NBT value) {
super.metadata.setIndex((byte) 18, Metadata.NBT(value));
}
@Nullable
public NBT getRightShoulderEntityData() {
return super.metadata.getIndex((byte) 19, null);
}
public void setRightShoulderEntityData(@Nullable NBT value) {
super.metadata.setIndex((byte) 19, Metadata.NBT(value));
}
}

View File

@ -0,0 +1,14 @@
package net.minestom.server.entity.metadata.ambient;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.MobMeta;
import org.jetbrains.annotations.NotNull;
public class AmbientCreatureMeta extends MobMeta {
protected AmbientCreatureMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,25 @@
package net.minestom.server.entity.metadata.ambient;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class BatMeta extends AmbientCreatureMeta {
private final static byte MASK_INDEX = 15;
private final static byte IS_HANGING_BIT = 0x01;
public BatMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isHanging() {
return getMaskBit(MASK_INDEX, IS_HANGING_BIT);
}
public void setHanging(boolean value) {
setMaskBit(MASK_INDEX, IS_HANGING_BIT, value);
}
}

View File

@ -0,0 +1,80 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
public class AbstractHorseMeta extends AnimalMeta {
private final static byte MASK_INDEX = 16;
private final static byte TAMED_BIT = 0x02;
private final static byte SADDLED_BIT = 0x04;
private final static byte HAS_BRED_BIT = 0x08;
private final static byte EATING_BIT = 0x10;
private final static byte REARING_BIT = 0x20;
private final static byte MOUTH_OPEN_BIT = 0x40;
protected AbstractHorseMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isTamed() {
return getMaskBit(MASK_INDEX, TAMED_BIT);
}
public void setTamed(boolean value) {
setMaskBit(MASK_INDEX, TAMED_BIT, value);
}
public boolean isSaddled() {
return getMaskBit(MASK_INDEX, SADDLED_BIT);
}
public void setSaddled(boolean value) {
setMaskBit(MASK_INDEX, SADDLED_BIT, value);
}
public boolean isHasBred() {
return getMaskBit(MASK_INDEX, HAS_BRED_BIT);
}
public void setHasBred(boolean value) {
setMaskBit(MASK_INDEX, HAS_BRED_BIT, value);
}
public boolean isEating() {
return getMaskBit(MASK_INDEX, EATING_BIT);
}
public void setEating(boolean value) {
setMaskBit(MASK_INDEX, EATING_BIT, value);
}
public boolean isRearing() {
return getMaskBit(MASK_INDEX, REARING_BIT);
}
public void setRearing(boolean value) {
setMaskBit(MASK_INDEX, REARING_BIT, value);
}
public boolean isMouthOpen() {
return getMaskBit(MASK_INDEX, MOUTH_OPEN_BIT);
}
public void setMouthOpen(boolean value) {
setMaskBit(MASK_INDEX, MOUTH_OPEN_BIT, value);
}
public UUID getOwner() {
return super.metadata.getIndex((byte) 17, null);
}
public void setOwner(UUID value) {
super.metadata.setIndex((byte) 17, Metadata.OptUUID(value));
}
}

View File

@ -0,0 +1,14 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.AgeableMobMeta;
import org.jetbrains.annotations.NotNull;
public class AnimalMeta extends AgeableMobMeta {
protected AnimalMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,51 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class BeeMeta extends AnimalMeta {
private final static byte MASK_INDEX = 16;
private final static byte ANGRY_BIT = 0x02;
private final static byte HAS_STUNG_BIT = 0x04;
private final static byte HAS_NECTAR_BIT = 0x08;
public BeeMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isAngry() {
return getMaskBit(MASK_INDEX, ANGRY_BIT);
}
public void setAngry(boolean value) {
setMaskBit(MASK_INDEX, ANGRY_BIT, value);
}
public boolean isHasStung() {
return getMaskBit(MASK_INDEX, HAS_STUNG_BIT);
}
public void setHasStung(boolean value) {
setMaskBit(MASK_INDEX, HAS_STUNG_BIT, value);
}
public boolean isHasNectar() {
return getMaskBit(MASK_INDEX, HAS_NECTAR_BIT);
}
public void setHasNectar(boolean value) {
setMaskBit(MASK_INDEX, HAS_NECTAR_BIT, value);
}
public int getAngerTicks() {
return super.metadata.getIndex((byte) 17, 0);
}
public void setAngerTicks(int value) {
super.metadata.setIndex((byte) 17, Metadata.VarInt(value));
}
}

View File

@ -0,0 +1,21 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class ChestedHorseMeta extends AbstractHorseMeta {
protected ChestedHorseMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isHasChest() {
return super.metadata.getIndex((byte) 18, false);
}
public void setHasChest(boolean value) {
super.metadata.setIndex((byte) 18, Metadata.Boolean(value));
}
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class ChickenMeta extends AnimalMeta {
public ChickenMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class CowMeta extends AnimalMeta {
public CowMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class DonkeyMeta extends ChestedHorseMeta {
public DonkeyMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,116 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.UUID;
public class FoxMeta extends AnimalMeta {
private final static byte MASK_INDEX = 17;
private final static byte SITTING_BIT = 0x01;
private final static byte CROUCHING_BIT = 0x04;
private final static byte INTERESTED_BIT = 0x08;
private final static byte POUNCING_BIT = 0x10;
private final static byte SLEEPING_BIT = 0x20;
private final static byte FACEPLANTED_BIT = 0x40;
private final static byte DEFENDING_BIT = (byte) 0x80;
public FoxMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
@NotNull
public Type getType() {
return Type.VALUES[super.metadata.getIndex((byte) 16, 0)];
}
public void setType(@NotNull Type type) {
super.metadata.setIndex((byte) 16, Metadata.VarInt(type.ordinal()));
}
public boolean isSitting() {
return getMaskBit(MASK_INDEX, SITTING_BIT);
}
public void setSitting(boolean value) {
setMaskBit(MASK_INDEX, SITTING_BIT, value);
}
public boolean isFoxSneaking() {
return getMaskBit(MASK_INDEX, CROUCHING_BIT);
}
public void setFoxSneaking(boolean value) {
setMaskBit(MASK_INDEX, CROUCHING_BIT, value);
}
public boolean isInterested() {
return getMaskBit(MASK_INDEX, INTERESTED_BIT);
}
public void setInterested(boolean value) {
setMaskBit(MASK_INDEX, INTERESTED_BIT, value);
}
public boolean isPouncing() {
return getMaskBit(MASK_INDEX, POUNCING_BIT);
}
public void setPouncing(boolean value) {
setMaskBit(MASK_INDEX, POUNCING_BIT, value);
}
public boolean isSleeping() {
return getMaskBit(MASK_INDEX, SLEEPING_BIT);
}
public void setSleeping(boolean value) {
setMaskBit(MASK_INDEX, SLEEPING_BIT, value);
}
public boolean isFaceplanted() {
return getMaskBit(MASK_INDEX, FACEPLANTED_BIT);
}
public void setFaceplanted(boolean value) {
setMaskBit(MASK_INDEX, FACEPLANTED_BIT, value);
}
public boolean isDefending() {
return getMaskBit(MASK_INDEX, DEFENDING_BIT);
}
public void setDefending(boolean value) {
setMaskBit(MASK_INDEX, DEFENDING_BIT, value);
}
@Nullable
public UUID getFirstUUID() {
return super.metadata.getIndex((byte) 18, null);
}
public void setFirstUUID(@Nullable UUID value) {
super.metadata.setIndex((byte) 18, Metadata.OptUUID(value));
}
@Nullable
public UUID getSecondUUID() {
return super.metadata.getIndex((byte) 19, null);
}
public void setSecondUUID(@Nullable UUID value) {
super.metadata.setIndex((byte) 19, Metadata.OptUUID(value));
}
public enum Type {
RED,
SNOW;
private final static Type[] VALUES = values();
}
}

View File

@ -0,0 +1,21 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class HoglinMeta extends AnimalMeta {
public HoglinMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isImmuneToZombification() {
return super.metadata.getIndex((byte) 16, false);
}
public void setImmuneToZombification(boolean value) {
super.metadata.setIndex((byte) 16, Metadata.Boolean(value));
}
}

View File

@ -0,0 +1,84 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class HorseMeta extends AbstractHorseMeta {
public HorseMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public Variant getVariant() {
return getVariantFromID(super.metadata.getIndex((byte) 18, 0));
}
public void setVariant(Variant variant) {
super.metadata.setIndex((byte) 18, Metadata.VarInt(getVariantID(variant.marking, variant.color)));
}
public static int getVariantID(@NotNull Marking marking, @NotNull Color color) {
return (marking.ordinal() << 8) + color.ordinal();
}
public static Variant getVariantFromID(int variantID) {
return new Variant(
Marking.VALUES[variantID >> 8],
Color.VALUES[variantID & 0xFF]
);
}
public static class Variant {
private Marking marking;
private Color color;
public Variant(@NotNull Marking marking, @NotNull Color color) {
this.marking = marking;
this.color = color;
}
@NotNull
public Marking getMarking() {
return this.marking;
}
public void setMarking(@NotNull Marking marking) {
this.marking = marking;
}
@NotNull
public Color getColor() {
return this.color;
}
public void setColor(@NotNull Color color) {
this.color = color;
}
}
public enum Marking {
NONE,
WHITE,
WHITE_FIELD,
WHITE_DOTS,
BLACK_DOTS;
private final static Marking[] VALUES = values();
}
public enum Color {
WHITE,
CREAMY,
CHESTNUT,
BROWN,
BLACK,
GRAY,
DARK_BROWN;
private final static Color[] VALUES = values();
}
}

View File

@ -0,0 +1,46 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class LlamaMeta extends ChestedHorseMeta {
public LlamaMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public int getStrength() {
return super.metadata.getIndex((byte) 19, 0);
}
public void setStrength(int value) {
super.metadata.setIndex((byte) 19, Metadata.VarInt(value));
}
public int getCarpetColor() {
return super.metadata.getIndex((byte) 20, -1);
}
public void setCarpetColor(int value) {
super.metadata.setIndex((byte) 20, Metadata.VarInt(value));
}
public Variant getVariant() {
return Variant.VALUES[super.metadata.getIndex((byte) 21, 0)];
}
public void setVariant(Variant value) {
super.metadata.setIndex((byte) 21, Metadata.VarInt(value.ordinal()));
}
public enum Variant {
CREAMY,
WHITE,
BROWN,
GRAY;
private final static Variant[] VALUES = values();
}
}

View File

@ -0,0 +1,29 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
import java.util.Locale;
public class MooshroomMeta extends CowMeta {
public MooshroomMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
@NotNull
public Variant getVariant() {
return Variant.valueOf(super.metadata.getIndex((byte) 16, "red").toUpperCase(Locale.ROOT));
}
public void setVariant(@NotNull Variant value) {
super.metadata.setIndex((byte) 16, Metadata.String(value.name().toLowerCase(Locale.ROOT)));
}
public enum Variant {
RED,
BROWN;
}
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class MuleMeta extends ChestedHorseMeta {
public MuleMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,21 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class OcelotMeta extends AnimalMeta {
public OcelotMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isTrusting() {
return super.metadata.getIndex((byte) 16, false);
}
public void setTrusting(boolean value) {
super.metadata.setIndex((byte) 16, Metadata.Boolean(value));
}
}

View File

@ -0,0 +1,106 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class PandaMeta extends AnimalMeta {
private final static byte MASK_INDEX = 21;
private final static byte SNEEZING_BIT = 0x02;
private final static byte ROLLING_BIT = 0x04;
private final static byte SITTING_BIT = 0x08;
private final static byte ON_BACK_BIT = 0x10;
public PandaMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public int getBreedTimer() {
return super.metadata.getIndex((byte) 16, 0);
}
public void setBreedTimer(int value) {
super.metadata.setIndex((byte) 16, Metadata.VarInt(value));
}
public int getSneezeTimer() {
return super.metadata.getIndex((byte) 17, 0);
}
public void setSneezeTimer(int value) {
super.metadata.setIndex((byte) 17, Metadata.VarInt(value));
}
public int getEatTimer() {
return super.metadata.getIndex((byte) 18, 0);
}
public void setEatTimer(int value) {
super.metadata.setIndex((byte) 18, Metadata.VarInt(value));
}
@NotNull
public Gene getMainGene() {
return Gene.VALUES[super.metadata.getIndex((byte) 19, (byte) 0)];
}
public void setMainGene(@NotNull Gene value) {
super.metadata.setIndex((byte) 19, Metadata.Byte((byte) value.ordinal()));
}
@NotNull
public Gene getHiddenGene() {
return Gene.VALUES[super.metadata.getIndex((byte) 20, (byte) 0)];
}
public void setHiddenGene(@NotNull Gene value) {
super.metadata.setIndex((byte) 20, Metadata.Byte((byte) value.ordinal()));
}
public boolean isSneezing() {
return getMaskBit(MASK_INDEX, SNEEZING_BIT);
}
public void setSneezing(boolean value) {
setMaskBit(MASK_INDEX, SNEEZING_BIT, value);
}
public boolean isRolling() {
return getMaskBit(MASK_INDEX, ROLLING_BIT);
}
public void setRolling(boolean value) {
setMaskBit(MASK_INDEX, ROLLING_BIT, value);
}
public boolean isSitting() {
return getMaskBit(MASK_INDEX, SITTING_BIT);
}
public void setSitting(boolean value) {
setMaskBit(MASK_INDEX, SITTING_BIT, value);
}
public boolean isOnBack() {
return getMaskBit(MASK_INDEX, ON_BACK_BIT);
}
public void setOnBack(boolean value) {
setMaskBit(MASK_INDEX, ON_BACK_BIT, value);
}
public enum Gene {
NORMAL,
AGGRESSIVE,
LAZY,
WORRIED,
PLAYFUL,
WEAK,
BROWN;
private final static Gene[] VALUES = values();
}
}

View File

@ -0,0 +1,29 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class PigMeta extends AnimalMeta {
public PigMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isHasSaddle() {
return super.metadata.getIndex((byte) 16, false);
}
public void setHasSaddle(boolean value) {
super.metadata.setIndex((byte) 16, Metadata.Boolean(value));
}
public int getTimeToBoost() {
return super.metadata.getIndex((byte) 17, 0);
}
public void setTimeToBoost(int value) {
super.metadata.getIndex((byte) 17, Metadata.VarInt(value));
}
}

View File

@ -0,0 +1,21 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class PolarBearMeta extends AnimalMeta {
public PolarBearMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isStandingUp() {
return super.metadata.getIndex((byte) 16, false);
}
public void setStandingUp(boolean value) {
super.metadata.setIndex((byte) 16, Metadata.Boolean(value));
}
}

View File

@ -0,0 +1,39 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class RabbitMeta extends AnimalMeta {
public RabbitMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
@NotNull
public Type getType() {
int id = super.metadata.getIndex((byte) 16, 0);
if (id == 99) {
return Type.KILLER_BUNNY;
}
return Type.VALUES[id];
}
public void setType(@NotNull Type value) {
int id = value == Type.KILLER_BUNNY ? 99 : value.ordinal();
super.metadata.setIndex((byte) 16, Metadata.VarInt(id));
}
public enum Type {
BROWN,
WHITE,
BLACK,
BLACK_AND_WHITE,
GOLD,
SALT_AND_PEPPER,
KILLER_BUNNY;
private final static Type[] VALUES = values();
}
}

View File

@ -0,0 +1,40 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class SheepMeta extends AnimalMeta {
private final static byte MASK_INDEX = 16;
private final static byte COLOR_BITS = 0x0F;
private final static byte SHEARED_BIT = 0x10;
public SheepMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public int getColor() {
return getMask(MASK_INDEX) & COLOR_BITS;
}
public void setColor(byte color) {
byte before = getMask(MASK_INDEX);
byte mask = before;
mask &= ~COLOR_BITS;
mask |= (color & COLOR_BITS);
if (mask != before) {
setMask(MASK_INDEX, mask);
}
}
public boolean isSheared() {
return getMaskBit(MASK_INDEX, SHEARED_BIT);
}
public void setSheared(boolean value) {
setMaskBit(MASK_INDEX, SHEARED_BIT, value);
}
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class SkeletonHorseMeta extends AbstractHorseMeta {
public SkeletonHorseMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,37 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class StriderMeta extends AnimalMeta {
public StriderMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public int getTimeToBoost() {
return super.metadata.getIndex((byte) 16, 0);
}
public void setTimeToBoost(int value) {
super.metadata.setIndex((byte) 16, Metadata.VarInt(value));
}
public boolean isShaking() {
return super.metadata.getIndex((byte) 17, false);
}
public void setShaking(boolean value) {
super.metadata.setIndex((byte) 17, Metadata.Boolean(value));
}
public boolean isHasSaddle() {
return super.metadata.getIndex((byte) 18, false);
}
public void setHasSaddle(boolean value) {
super.metadata.setIndex((byte) 18, Metadata.Boolean(value));
}
}

View File

@ -0,0 +1,64 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.utils.BlockPosition;
import org.jetbrains.annotations.NotNull;
public class TurtleMeta extends AnimalMeta {
public TurtleMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
@NotNull
public BlockPosition getHomePosition() {
return super.metadata.getIndex((byte) 16, new BlockPosition(0, 0, 0));
}
public void setBlockPosition(@NotNull BlockPosition value) {
super.metadata.setIndex((byte) 16, Metadata.Position(value));
}
public boolean isHasEgg() {
return super.metadata.getIndex((byte) 17, false);
}
public void setHasEgg(boolean value) {
super.metadata.setIndex((byte) 17, Metadata.Boolean(value));
}
public boolean isLayingEgg() {
return super.metadata.getIndex((byte) 18, false);
}
public void setLayingEgg(boolean value) {
super.metadata.setIndex((byte) 18, Metadata.Boolean(value));
}
@NotNull
public BlockPosition getTravelPosition() {
return super.metadata.getIndex((byte) 19, new BlockPosition(0, 0, 0));
}
public void setTravelPosition(@NotNull BlockPosition value) {
super.metadata.setIndex((byte) 19, Metadata.Position(value));
}
public boolean isGoingHome() {
return super.metadata.getIndex((byte) 20, false);
}
public void setGoingHome(boolean value) {
super.metadata.setIndex((byte) 20, Metadata.Boolean(value));
}
public boolean isTravelling() {
return super.metadata.getIndex((byte) 21, false);
}
public void setTravelling(boolean value) {
super.metadata.setIndex((byte) 21, Metadata.Boolean(value));
}
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.entity.metadata.animal;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class ZombieHorseMeta extends AbstractHorseMeta {
public ZombieHorseMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,62 @@
package net.minestom.server.entity.metadata.animal.tameable;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class CatMeta extends TameableAnimalMeta {
public CatMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
@NotNull
public Color getColor() {
return Color.VALUES[super.metadata.getIndex((byte) 18, 1)];
}
public void setColor(@NotNull Color value) {
super.metadata.setIndex((byte) 18, Metadata.VarInt(value.ordinal()));
}
public boolean isLying() {
return super.metadata.getIndex((byte) 19, false);
}
public void setLying(boolean value) {
super.metadata.setIndex((byte) 19, Metadata.Boolean(value));
}
public boolean isRelaxed() {
return super.metadata.getIndex((byte) 20, false);
}
public void setRelaxed(boolean value) {
super.metadata.setIndex((byte) 20, Metadata.Boolean(value));
}
public int getCollarColor() {
return super.metadata.getIndex((byte) 21, 14);
}
public void setCollarColor(int value) {
super.metadata.setIndex((byte) 21, Metadata.VarInt(value));
}
public enum Color {
TABBY,
BLACK,
RED,
SIAMESE,
BRITISH_SHORTHAIR,
CALICO,
PERSIAN,
RAGDOLL,
WHITE,
JELLIE,
ALL_BLACK;
private final static Color[] VALUES = values();
}
}

View File

@ -0,0 +1,32 @@
package net.minestom.server.entity.metadata.animal.tameable;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class ParrotMeta extends TameableAnimalMeta {
public ParrotMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
@NotNull
public Color getColor() {
return Color.VALUES[super.metadata.getIndex((byte) 18, 0)];
}
public void setColor(@NotNull Color value) {
super.metadata.setIndex((byte) 18, Metadata.VarInt(value.ordinal()));
}
public enum Color {
RED_BLUE,
BLUE,
GREEN,
YELLOW_BLUE,
GREY;
private final static Color[] VALUES = values();
}
}

View File

@ -0,0 +1,46 @@
package net.minestom.server.entity.metadata.animal.tameable;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.animal.AnimalMeta;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
public class TameableAnimalMeta extends AnimalMeta {
private final static byte MASK_INDEX = 16;
private final static byte SITTING_BIT = 0x01;
private final static byte TAMED_BIT = 0x04;
protected TameableAnimalMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isSitting() {
return getMaskBit(MASK_INDEX, SITTING_BIT);
}
public void setSitting(boolean value) {
setMaskBit(MASK_INDEX, SITTING_BIT, value);
}
public boolean isTamed() {
return getMaskBit(MASK_INDEX, TAMED_BIT);
}
public void setTamed(boolean value) {
setMaskBit(MASK_INDEX, TAMED_BIT, value);
}
@NotNull
public UUID getOwner() {
return super.metadata.getIndex((byte) 17, null);
}
public void setOwner(@NotNull UUID value) {
super.metadata.setIndex((byte) 17, Metadata.OptUUID(value));
}
}

View File

@ -0,0 +1,37 @@
package net.minestom.server.entity.metadata.animal.tameable;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class WolfMeta extends TameableAnimalMeta {
public WolfMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isBegging() {
return super.metadata.getIndex((byte) 18, false);
}
public void setBegging(boolean value) {
super.metadata.setIndex((byte) 18, Metadata.Boolean(value));
}
public int getCollarColor() {
return super.metadata.getIndex((byte) 19, 14);
}
public void setCollarColor(int value) {
super.metadata.setIndex((byte) 19, Metadata.VarInt(value));
}
public int getAngerTime() {
return super.metadata.getIndex((byte) 20, 0);
}
public void setAngerTime(int value) {
super.metadata.setIndex((byte) 20, Metadata.VarInt(value));
}
}

View File

@ -0,0 +1,43 @@
package net.minestom.server.entity.metadata.arrow;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.EntityMeta;
import org.jetbrains.annotations.NotNull;
public class AbstractArrowMeta extends EntityMeta {
private final static byte MASK_INDEX = 7;
private final static byte CRITICAL_BIT = 0x01;
private final static byte NO_CLIP_BIT = 0x01;
protected AbstractArrowMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isCritical() {
return getMaskBit(MASK_INDEX, CRITICAL_BIT);
}
public void setCritical(boolean value) {
setMaskBit(MASK_INDEX, CRITICAL_BIT, value);
}
public boolean isNoClip() {
return getMaskBit(MASK_INDEX, NO_CLIP_BIT);
}
public void setNoClip(boolean value) {
setMaskBit(MASK_INDEX, NO_CLIP_BIT, value);
}
public byte getPiercingLevel() {
return super.metadata.getIndex((byte) 8, (byte) 0);
}
public void setPiercingLevel(byte value) {
super.metadata.setIndex((byte) 8, Metadata.Byte(value));
}
}

View File

@ -0,0 +1,44 @@
package net.minestom.server.entity.metadata.arrow;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.ObjectDataProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ArrowMeta extends AbstractArrowMeta implements ObjectDataProvider {
private Entity shooter;
public ArrowMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public int getColor() {
return super.metadata.getIndex((byte) 9, -1);
}
public void setColor(int value) {
super.metadata.setIndex((byte) 9, Metadata.VarInt(value));
}
@Nullable
public Entity getShooter() {
return this.shooter;
}
public void setShooter(@Nullable Entity shooter) {
this.shooter = shooter;
}
@Override
public int getObjectData() {
return this.shooter == null ? 0 : this.shooter.getEntityId() + 1;
}
@Override
public boolean requiresVelocityPacketAtSpawn() {
return true;
}
}

View File

@ -0,0 +1,36 @@
package net.minestom.server.entity.metadata.arrow;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.ObjectDataProvider;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class SpectralArrowMeta extends AbstractArrowMeta implements ObjectDataProvider {
private Entity shooter;
public SpectralArrowMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
@Nullable
public Entity getShooter() {
return this.shooter;
}
public void setShooter(@Nullable Entity shooter) {
this.shooter = shooter;
}
@Override
public int getObjectData() {
return this.shooter == null ? 0 : this.shooter.getEntityId() + 1;
}
@Override
public boolean requiresVelocityPacketAtSpawn() {
return true;
}
}

View File

@ -0,0 +1,29 @@
package net.minestom.server.entity.metadata.arrow;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class ThrownTridentMeta extends AbstractArrowMeta {
public ThrownTridentMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public int getLoyaltyLevel() {
return super.metadata.getIndex((byte) 9, 0);
}
public void setLoyaltyLevel(int value) {
super.metadata.setIndex((byte) 9, Metadata.VarInt(value));
}
public boolean isHasEnchantmentGlint() {
return super.metadata.getIndex((byte) 10, false);
}
public void setHasEnchantmentGlint(boolean value) {
super.metadata.setIndex((byte) 10, Metadata.Boolean(value));
}
}

View File

@ -0,0 +1,14 @@
package net.minestom.server.entity.metadata.flying;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.MobMeta;
import org.jetbrains.annotations.NotNull;
public class FlyingMeta extends MobMeta {
protected FlyingMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,21 @@
package net.minestom.server.entity.metadata.flying;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class GhastMeta extends FlyingMeta {
public GhastMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isAttacking() {
return super.metadata.getIndex((byte) 15, false);
}
public void setAttacking(boolean value) {
super.metadata.setIndex((byte) 15, Metadata.Boolean(value));
}
}

View File

@ -0,0 +1,21 @@
package net.minestom.server.entity.metadata.flying;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class PhantomMeta extends FlyingMeta {
public PhantomMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public int getSize() {
return super.metadata.getIndex((byte) 15, 0);
}
public void setSize(int value) {
super.metadata.setIndex((byte) 15, Metadata.VarInt(value));
}
}

View File

@ -0,0 +1,14 @@
package net.minestom.server.entity.metadata.golem;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.PathfinderMobMeta;
import org.jetbrains.annotations.NotNull;
public class AbstractGolemMeta extends PathfinderMobMeta {
protected AbstractGolemMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,25 @@
package net.minestom.server.entity.metadata.golem;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class IronGolemMeta extends AbstractGolemMeta {
private final static byte MASK_INDEX = 15;
private final static byte PLAYER_CREATED_BIT = 0x01;
public IronGolemMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isPlayerCreated() {
return getMaskBit(MASK_INDEX, PLAYER_CREATED_BIT);
}
public void setPlayerCreated(boolean value) {
setMaskBit(MASK_INDEX, PLAYER_CREATED_BIT, value);
}
}

View File

@ -0,0 +1,47 @@
package net.minestom.server.entity.metadata.golem;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.Direction;
import org.jetbrains.annotations.NotNull;
public class ShulkerMeta extends AbstractGolemMeta {
public ShulkerMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public Direction getAttachFace() {
return super.metadata.getIndex((byte) 15, Direction.DOWN);
}
public void setAttachFace(Direction value) {
super.metadata.setIndex((byte) 15, Metadata.Direction(value));
}
public BlockPosition getAttachmentPosition() {
return super.metadata.getIndex((byte) 16, null);
}
public void setAttachmentPosition(BlockPosition value) {
super.metadata.setIndex((byte) 16, Metadata.OptPosition(value));
}
public byte getShieldHeight() {
return super.metadata.getIndex((byte) 17, (byte) 0);
}
public void setShieldHeight(byte value) {
super.metadata.setIndex((byte) 17, Metadata.Byte(value));
}
public byte getColor() {
return super.metadata.getIndex((byte) 18, (byte) 10);
}
public void setColor(byte value) {
super.metadata.setIndex((byte) 18, Metadata.Byte(value));
}
}

View File

@ -0,0 +1,21 @@
package net.minestom.server.entity.metadata.golem;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class SnowGolemMeta extends AbstractGolemMeta {
public SnowGolemMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isHasPumpkinHat() {
return super.metadata.getIndex((byte) 15, (byte) 0x10) == (byte) 0x10;
}
public void setHasPumpkinHat(boolean value) {
super.metadata.setIndex((byte) 15, Metadata.Byte(value ? (byte) 0x10 : (byte) 0x00));
}
}

View File

@ -0,0 +1,14 @@
package net.minestom.server.entity.metadata.item;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
public class EyeOfEnderMeta extends ItemContainingMeta {
public EyeOfEnderMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata, Material.ENDER_EYE);
}
}

View File

@ -0,0 +1,37 @@
package net.minestom.server.entity.metadata.item;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.ObjectDataProvider;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class FireballMeta extends ItemContainingMeta implements ObjectDataProvider {
private Entity shooter;
public FireballMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata, Material.AIR);
}
@Nullable
public Entity getShooter() {
return shooter;
}
public void setShooter(@Nullable Entity shooter) {
this.shooter = shooter;
}
@Override
public int getObjectData() {
return this.shooter == null ? 0 : this.shooter.getEntityId();
}
@Override
public boolean requiresVelocityPacketAtSpawn() {
return true;
}
}

View File

@ -0,0 +1,28 @@
package net.minestom.server.entity.metadata.item;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.EntityMeta;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
class ItemContainingMeta extends EntityMeta {
private final ItemStack defaultItem;
protected ItemContainingMeta(@NotNull Entity entity, @NotNull Metadata metadata, @NotNull Material defaultItemMaterial) {
super(entity, metadata);
this.defaultItem = new ItemStack(defaultItemMaterial, (byte) 1);
}
@NotNull
public ItemStack getItem() {
return super.metadata.getIndex((byte) 7, this.defaultItem);
}
public void setItem(@NotNull ItemStack item) {
super.metadata.setIndex((byte) 7, Metadata.Slot(item));
}
}

View File

@ -0,0 +1,25 @@
package net.minestom.server.entity.metadata.item;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.ObjectDataProvider;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
public class ItemEntityMeta extends ItemContainingMeta implements ObjectDataProvider {
public ItemEntityMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata, Material.AIR);
}
@Override
public int getObjectData() {
return 1;
}
@Override
public boolean requiresVelocityPacketAtSpawn() {
return true;
}
}

View File

@ -0,0 +1,37 @@
package net.minestom.server.entity.metadata.item;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.ObjectDataProvider;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class SmallFireballMeta extends ItemContainingMeta implements ObjectDataProvider {
private Entity shooter;
public SmallFireballMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata, Material.FIRE_CHARGE);
}
@Nullable
public Entity getShooter() {
return shooter;
}
public void setShooter(@Nullable Entity shooter) {
this.shooter = shooter;
}
@Override
public int getObjectData() {
return this.shooter == null ? 0 : this.shooter.getEntityId();
}
@Override
public boolean requiresVelocityPacketAtSpawn() {
return true;
}
}

View File

@ -0,0 +1,14 @@
package net.minestom.server.entity.metadata.item;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
public class SnowballMeta extends ItemContainingMeta {
public SnowballMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata, Material.SNOWBALL);
}
}

View File

@ -0,0 +1,14 @@
package net.minestom.server.entity.metadata.item;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
public class ThrownEggMeta extends ItemContainingMeta {
public ThrownEggMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata, Material.EGG);
}
}

View File

@ -0,0 +1,14 @@
package net.minestom.server.entity.metadata.item;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
public class ThrownEnderPearlMeta extends ItemContainingMeta {
public ThrownEnderPearlMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata, Material.ENDER_PEARL);
}
}

View File

@ -0,0 +1,14 @@
package net.minestom.server.entity.metadata.item;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
public class ThrownExperienceBottleMeta extends ItemContainingMeta {
public ThrownExperienceBottleMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata, Material.EXPERIENCE_BOTTLE);
}
}

View File

@ -0,0 +1,14 @@
package net.minestom.server.entity.metadata.item;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
public class ThrownPotionMeta extends ItemContainingMeta {
public ThrownPotionMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata, Material.AIR);
}
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.entity.metadata.minecart;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public abstract class AbstractMinecartContainerMeta extends AbstractMinecartMeta {
protected AbstractMinecartContainerMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,61 @@
package net.minestom.server.entity.metadata.minecart;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.EntityMeta;
import net.minestom.server.entity.metadata.ObjectDataProvider;
import org.jetbrains.annotations.NotNull;
public abstract class AbstractMinecartMeta extends EntityMeta implements ObjectDataProvider {
protected AbstractMinecartMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public int getShakingPower() {
return super.metadata.getIndex((byte) 7, 0);
}
public void setShakingPower(int value) {
super.metadata.setIndex((byte) 7, Metadata.VarInt(value));
}
public int getShakingDirection() {
return super.metadata.getIndex((byte) 8, 1);
}
public void setShakingDirection(int value) {
super.metadata.setIndex((byte) 8, Metadata.VarInt(value));
}
public float getShakingMultiplier() {
return super.metadata.getIndex((byte) 9, 0F);
}
public void setShakingMultiplier(float value) {
super.metadata.setIndex((byte) 9, Metadata.Float(value));
}
public int getCustomBlockIdAndDamage() {
return super.metadata.getIndex((byte) 10, 0);
}
public void setCustomBlockIdAndDamage(int value) {
super.metadata.setIndex((byte) 10, Metadata.VarInt(value));
}
// in 16th of a block
public int getCustomBlockYPosition() {
return super.metadata.getIndex((byte) 11, 6);
}
public void setCustomBlockYPosition(int value) {
super.metadata.setIndex((byte) 11, Metadata.VarInt(value));
}
@Override
public boolean requiresVelocityPacketAtSpawn() {
return true;
}
}

View File

@ -0,0 +1,18 @@
package net.minestom.server.entity.metadata.minecart;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class ChestMinecartMeta extends AbstractMinecartContainerMeta {
public ChestMinecartMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
@Override
public int getObjectData() {
return 1;
}
}

View File

@ -0,0 +1,38 @@
package net.minestom.server.entity.metadata.minecart;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class CommandBlockMinecartMeta extends AbstractMinecartMeta {
public CommandBlockMinecartMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
@NotNull
public String getCommand() {
return super.metadata.getIndex((byte) 13, "");
}
public void setCommand(@NotNull String value) {
super.metadata.setIndex((byte) 13, Metadata.String(value));
}
@NotNull
public JsonMessage getLastOutput() {
return super.metadata.getIndex((byte) 14, ColoredText.of(""));
}
public void setLastOutput(@NotNull JsonMessage value) {
super.metadata.setIndex((byte) 14, Metadata.Chat(value));
}
@Override
public int getObjectData() {
return 6;
}
}

View File

@ -0,0 +1,26 @@
package net.minestom.server.entity.metadata.minecart;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class FurnaceMinecartMeta extends AbstractMinecartMeta {
public FurnaceMinecartMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isHasFuel() {
return super.metadata.getIndex((byte) 13, false);
}
public void setHasFuel(boolean value) {
super.metadata.setIndex((byte) 13, Metadata.Boolean(value));
}
@Override
public int getObjectData() {
return 2;
}
}

View File

@ -0,0 +1,18 @@
package net.minestom.server.entity.metadata.minecart;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class HopperMinecartMeta extends AbstractMinecartContainerMeta {
public HopperMinecartMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
@Override
public int getObjectData() {
return 5;
}
}

View File

@ -0,0 +1,18 @@
package net.minestom.server.entity.metadata.minecart;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class MinecartMeta extends AbstractMinecartMeta {
public MinecartMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
@Override
public int getObjectData() {
return 0;
}
}

View File

@ -0,0 +1,18 @@
package net.minestom.server.entity.metadata.minecart;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class SpawnerMinecartMeta extends AbstractMinecartMeta {
public SpawnerMinecartMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
@Override
public int getObjectData() {
return 4;
}
}

View File

@ -0,0 +1,18 @@
package net.minestom.server.entity.metadata.minecart;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class TntMinecartMeta extends AbstractMinecartMeta {
public TntMinecartMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
@Override
public int getObjectData() {
return 3;
}
}

View File

@ -0,0 +1,21 @@
package net.minestom.server.entity.metadata.monster;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class BasePiglinMeta extends MonsterMeta {
protected BasePiglinMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isImmuneToZombification() {
return super.metadata.getIndex((byte) 15, false);
}
public void setImmuneToZombification(boolean value) {
super.metadata.setIndex((byte) 15, Metadata.Boolean(value));
}
}

View File

@ -0,0 +1,25 @@
package net.minestom.server.entity.metadata.monster;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class BlazeMeta extends MonsterMeta {
private final static byte MASK_INDEX = 15;
private final static byte ON_FIRE_BIT = 0x01;
public BlazeMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isOnFire() {
return getMaskBit(MASK_INDEX, ON_FIRE_BIT);
}
public void setOnFire(boolean value) {
setMaskBit(MASK_INDEX, ON_FIRE_BIT, value);
}
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.entity.metadata.monster;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class CaveSpiderMeta extends SpiderMeta {
public CaveSpiderMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,44 @@
package net.minestom.server.entity.metadata.monster;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class CreeperMeta extends MonsterMeta {
public CreeperMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
@NotNull
public State getState() {
int id = super.metadata.getIndex((byte) 15, -1);
return id == -1 ? State.IDLE : State.FUSE;
}
public void setState(@NotNull State value) {
super.metadata.setIndex((byte) 15, Metadata.VarInt(value == State.IDLE ? -1 : 1));
}
public boolean isCharged() {
return super.metadata.getIndex((byte) 16, false);
}
public void setCharged(boolean value) {
super.metadata.setIndex((byte) 16, Metadata.Boolean(value));
}
public boolean isIgnited() {
return super.metadata.getIndex((byte) 17, false);
}
public void setIgnited(boolean value) {
super.metadata.setIndex((byte) 17, Metadata.Boolean(value));
}
public enum State {
IDLE,
FUSE
}
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.entity.metadata.monster;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class ElderGuardianMeta extends GuardianMeta {
public ElderGuardianMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,38 @@
package net.minestom.server.entity.metadata.monster;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class EndermanMeta extends MonsterMeta {
public EndermanMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public Integer getCarriedBlockID() {
return super.metadata.getIndex((byte) 15, null);
}
public void setCarriedBlockID(@Nullable Integer value) {
super.metadata.setIndex((byte) 15, Metadata.OptBlockID(value));
}
public boolean isScreaming() {
return super.metadata.getIndex((byte) 16, false);
}
public void setScreaming(boolean value) {
super.metadata.setIndex((byte) 16, Metadata.Boolean(value));
}
public boolean isStaring() {
return super.metadata.getIndex((byte) 17, false);
}
public void setStaring(boolean value) {
super.metadata.setIndex((byte) 17, Metadata.Boolean(value));
}
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.entity.metadata.monster;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class EndermiteMeta extends MonsterMeta {
public EndermiteMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.entity.metadata.monster;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class GiantMeta extends MonsterMeta {
public GiantMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,32 @@
package net.minestom.server.entity.metadata.monster;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class GuardianMeta extends MonsterMeta {
private Entity target;
public GuardianMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isRetractingSpikes() {
return super.metadata.getIndex((byte) 15, false);
}
public void setRetractingSpikes(boolean retractingSpikes) {
super.metadata.setIndex((byte) 15, Metadata.Boolean(retractingSpikes));
}
public Entity getTarget() {
return this.target;
}
public void setTarget(@NotNull Entity target) {
this.target = target;
super.metadata.setIndex((byte) 16, Metadata.VarInt(target.getEntityId()));
}
}

View File

@ -0,0 +1,14 @@
package net.minestom.server.entity.metadata.monster;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import net.minestom.server.entity.metadata.PathfinderMobMeta;
import org.jetbrains.annotations.NotNull;
public class MonsterMeta extends PathfinderMobMeta {
protected MonsterMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.entity.metadata.monster;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class PiglinBruteMeta extends BasePiglinMeta {
public PiglinBruteMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

View File

@ -0,0 +1,47 @@
package net.minestom.server.entity.metadata.monster;
import net.minestom.server.collision.BoundingBox;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class PiglinMeta extends BasePiglinMeta {
public PiglinMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
public boolean isBaby() {
return super.metadata.getIndex((byte) 16, false);
}
public void setBaby(boolean value) {
if (isBaby() == value) {
return;
}
BoundingBox bb = this.entity.getBoundingBox();
if (value) {
setBoundingBox(bb.getWidth() / 2, bb.getHeight() / 2);
} else {
setBoundingBox(bb.getWidth() * 2, bb.getHeight() * 2);
}
super.metadata.setIndex((byte) 16, Metadata.Boolean(value));
}
public boolean isChargingCrossbow() {
return super.metadata.getIndex((byte) 17, false);
}
public void setChargingCrossbow(boolean value) {
super.metadata.setIndex((byte) 17, Metadata.Boolean(value));
}
public boolean isDancing() {
return super.metadata.getIndex((byte) 18, false);
}
public void setDancing(boolean value) {
super.metadata.setIndex((byte) 18, Metadata.Boolean(value));
}
}

View File

@ -0,0 +1,13 @@
package net.minestom.server.entity.metadata.monster;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Metadata;
import org.jetbrains.annotations.NotNull;
public class SilverfishMeta extends MonsterMeta {
public SilverfishMeta(@NotNull Entity entity, @NotNull Metadata metadata) {
super(entity, metadata);
}
}

Some files were not shown because too many files have changed in this diff Show More