From 73b42e843e5653ae03ec588e12ca0b6a4182ccdd Mon Sep 17 00:00:00 2001 From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Date: Mon, 15 Jan 2024 14:36:10 -0500 Subject: [PATCH] Add mob goal generator (#9980) --- paper-api-generator/build.gradle.kts | 1 + .../paper/entity/ai/VanillaGoal.java | 1128 +++++++++++++++++ .../java/io/papermc/generator/Generators.java | 32 + .../main/java/io/papermc/generator/Main.java | 25 +- .../papermc/generator/types/Annotations.java | 26 - .../generator/types/GeneratedKeyType.java | 74 +- .../generator/types/SimpleGenerator.java | 37 + .../generator/types/SourceGenerator.java | 2 - .../types/goal/MobGoalGenerator.java | 262 ++++ .../generator/types/goal/MobGoalNames.java | 329 +++++ .../papermc/generator/utils/Annotations.java | 59 + .../papermc/generator/utils/Formatting.java | 15 + .../io/papermc/generator/utils/Javadocs.java | 27 + patches/api/Add-Mob-Goal-API.patch | 309 ----- patches/api/Missing-Entity-API.patch | 13 - patches/server/Implement-Mob-Goal-API.patch | 112 -- 16 files changed, 1915 insertions(+), 536 deletions(-) create mode 100644 paper-api-generator/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java create mode 100644 paper-api-generator/src/main/java/io/papermc/generator/Generators.java delete mode 100644 paper-api-generator/src/main/java/io/papermc/generator/types/Annotations.java create mode 100644 paper-api-generator/src/main/java/io/papermc/generator/types/SimpleGenerator.java create mode 100644 paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalGenerator.java create mode 100644 paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java create mode 100644 paper-api-generator/src/main/java/io/papermc/generator/utils/Annotations.java create mode 100644 paper-api-generator/src/main/java/io/papermc/generator/utils/Formatting.java create mode 100644 paper-api-generator/src/main/java/io/papermc/generator/utils/Javadocs.java diff --git a/paper-api-generator/build.gradle.kts b/paper-api-generator/build.gradle.kts index 50cc3c1e59..3b86451bdc 100644 --- a/paper-api-generator/build.gradle.kts +++ b/paper-api-generator/build.gradle.kts @@ -21,6 +21,7 @@ minecraft { dependencies { implementation("com.squareup:javapoet:1.13.0") implementation(project(":paper-api")) + implementation("io.github.classgraph:classgraph:4.8.47") } group = "io.papermc.paper" diff --git a/paper-api-generator/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/paper-api-generator/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java new file mode 100644 index 0000000000..069f2668f5 --- /dev/null +++ b/paper-api-generator/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java @@ -0,0 +1,1128 @@ +package com.destroystokyo.paper.entity.ai; + +import com.destroystokyo.paper.entity.RangedEntity; +import io.papermc.paper.entity.SchoolableFish; +import io.papermc.paper.generated.GeneratedFrom; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.AbstractHorse; +import org.bukkit.entity.AbstractSkeleton; +import org.bukkit.entity.AbstractVillager; +import org.bukkit.entity.Animals; +import org.bukkit.entity.Bee; +import org.bukkit.entity.Blaze; +import org.bukkit.entity.Cat; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.Dolphin; +import org.bukkit.entity.Drowned; +import org.bukkit.entity.Enderman; +import org.bukkit.entity.Evoker; +import org.bukkit.entity.Fish; +import org.bukkit.entity.Fox; +import org.bukkit.entity.Ghast; +import org.bukkit.entity.Guardian; +import org.bukkit.entity.Illager; +import org.bukkit.entity.Illusioner; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Llama; +import org.bukkit.entity.Mob; +import org.bukkit.entity.Monster; +import org.bukkit.entity.Ocelot; +import org.bukkit.entity.Panda; +import org.bukkit.entity.Parrot; +import org.bukkit.entity.Phantom; +import org.bukkit.entity.PigZombie; +import org.bukkit.entity.PolarBear; +import org.bukkit.entity.PufferFish; +import org.bukkit.entity.Rabbit; +import org.bukkit.entity.Raider; +import org.bukkit.entity.Ravager; +import org.bukkit.entity.Shulker; +import org.bukkit.entity.Silverfish; +import org.bukkit.entity.SkeletonHorse; +import org.bukkit.entity.Slime; +import org.bukkit.entity.Spellcaster; +import org.bukkit.entity.Spider; +import org.bukkit.entity.Squid; +import org.bukkit.entity.Strider; +import org.bukkit.entity.Tameable; +import org.bukkit.entity.TraderLlama; +import org.bukkit.entity.Turtle; +import org.bukkit.entity.Vex; +import org.bukkit.entity.Vindicator; +import org.bukkit.entity.WanderingTrader; +import org.bukkit.entity.Wither; +import org.bukkit.entity.Wolf; +import org.bukkit.entity.Zombie; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +/** + * Vanilla keys for Mob Goals. + * + * @apiNote The fields provided here are a direct representation of + * what is available from the vanilla game source. They may be + * changed (including removals) on any Minecraft version + * bump, so cross-version compatibility is not provided on the + * same level as it is on most of the other API. + */ +@SuppressWarnings({ + "unused", + "SpellCheckingInspection" +}) +@GeneratedFrom("1.20.4") +public interface VanillaGoal extends Goal { + GoalKey RANDOM_STAND = create("random_stand", AbstractHorse.class); + + GoalKey RUN_AROUND_LIKE_CRAZY = create("run_around_like_crazy", AbstractHorse.class); + + GoalKey ABSTRACT_SKELETON_MELEE = create("abstract_skeleton_melee", AbstractSkeleton.class); + + GoalKey LOOK_AT_TRADING_PLAYER = create("look_at_trading_player", AbstractVillager.class); + + GoalKey TRADE_WITH_PLAYER = create("trade_with_player", AbstractVillager.class); + + GoalKey BREED = create("breed", Animals.class); + + GoalKey FOLLOW_PARENT = create("follow_parent", Animals.class); + + GoalKey BEE_ATTACK = create("bee_attack", Bee.class); + + GoalKey BEE_BECOME_ANGRY = create("bee_become_angry", Bee.class); + + GoalKey BEE_ENTER_HIVE = create("bee_enter_hive", Bee.class); + + GoalKey BEE_GO_TO_HIVE = create("bee_go_to_hive", Bee.class); + + GoalKey BEE_GO_TO_KNOWN_FLOWER = create("bee_go_to_known_flower", Bee.class); + + GoalKey BEE_GROW_CROP = create("bee_grow_crop", Bee.class); + + GoalKey BEE_HURT_BY_OTHER = create("bee_hurt_by_other", Bee.class); + + GoalKey BEE_LOCATE_HIVE = create("bee_locate_hive", Bee.class); + + GoalKey BEE_POLLINATE = create("bee_pollinate", Bee.class); + + GoalKey BEE_WANDER = create("bee_wander", Bee.class); + + GoalKey BLAZE_ATTACK = create("blaze_attack", Blaze.class); + + GoalKey CAT_AVOID_ENTITY = create("cat_avoid_entity", Cat.class); + + GoalKey CAT_LIE_ON_BED = create("cat_lie_on_bed", Cat.class); + + GoalKey CAT_RELAX_ON_OWNER = create("cat_relax_on_owner", Cat.class); + + GoalKey CAT_SIT_ON_BLOCK = create("cat_sit_on_block", Cat.class); + + GoalKey CAT_TEMPT = create("cat_tempt", Cat.class); + + GoalKey AVOID_ENTITY = create("avoid_entity", Creature.class); + + GoalKey BREATH_AIR = create("breath_air", Creature.class); + + GoalKey DROWNED_GO_TO_WATER = create("drowned_go_to_water", Creature.class); + + GoalKey FLEE_SUN = create("flee_sun", Creature.class); + + GoalKey FOLLOW_BOAT = create("follow_boat", Creature.class); + + GoalKey GOLEM_RANDOM_STROLL_IN_VILLAGE = create("golem_random_stroll_in_village", Creature.class); + + GoalKey HURT_BY = create("hurt_by", Creature.class); + + GoalKey MELEE_ATTACK = create("melee_attack", Creature.class); + + GoalKey MOVE_BACK_TO_VILLAGE = create("move_back_to_village", Creature.class); + + GoalKey MOVE_THROUGH_VILLAGE = create("move_through_village", Creature.class); + + GoalKey MOVE_TOWARDS = create("move_towards", Creature.class); + + GoalKey MOVE_TOWARDS_RESTRICTION = create("move_towards_restriction", Creature.class); + + GoalKey PANIC = create("panic", Creature.class); + + GoalKey PARROT_WANDER = create("parrot_wander", Creature.class); + + GoalKey RANDOM_STROLL = create("random_stroll", Creature.class); + + GoalKey RANDOM_SWIMMING = create("random_swimming", Creature.class); + + GoalKey REMOVE_BLOCK = create("remove_block", Creature.class); + + GoalKey RESTRICT_SUN = create("restrict_sun", Creature.class); + + GoalKey STROLL_THROUGH_VILLAGE = create("stroll_through_village", Creature.class); + + GoalKey TEMPT = create("tempt", Creature.class); + + GoalKey TRY_FIND_WATER = create("try_find_water", Creature.class); + + GoalKey WATER_AVOIDING_RANDOM_FLYING = create("water_avoiding_random_flying", Creature.class); + + GoalKey WATER_AVOIDING_RANDOM_STROLL = create("water_avoiding_random_stroll", Creature.class); + + GoalKey SWELL = create("swell", Creeper.class); + + GoalKey DOLPHIN_JUMP = create("dolphin_jump", Dolphin.class); + + GoalKey DOLPHIN_SWIM_TO_TREASURE = create("dolphin_swim_to_treasure", Dolphin.class); + + GoalKey DOLPHIN_SWIM_WITH_PLAYER = create("dolphin_swim_with_player", Dolphin.class); + + GoalKey PLAY_WITH_ITEMS = create("play_with_items", Dolphin.class); + + GoalKey DROWNED_ATTACK = create("drowned_attack", Drowned.class); + + GoalKey DROWNED_GO_TO_BEACH = create("drowned_go_to_beach", Drowned.class); + + GoalKey DROWNED_SWIM_UP = create("drowned_swim_up", Drowned.class); + + GoalKey ENDERMAN_FREEZE_WHEN_LOOKED_AT = create("enderman_freeze_when_looked_at", Enderman.class); + + GoalKey ENDERMAN_LEAVE_BLOCK = create("enderman_leave_block", Enderman.class); + + GoalKey ENDERMAN_LOOK_FOR_PLAYER = create("enderman_look_for_player", Enderman.class); + + GoalKey ENDERMAN_TAKE_BLOCK = create("enderman_take_block", Enderman.class); + + GoalKey EVOKER_ATTACK_SPELL = create("evoker_attack_spell", Evoker.class); + + GoalKey EVOKER_CASTING_SPELL = create("evoker_casting_spell", Evoker.class); + + GoalKey EVOKER_SUMMON_SPELL = create("evoker_summon_spell", Evoker.class); + + GoalKey EVOKER_WOLOLO_SPELL = create("evoker_wololo_spell", Evoker.class); + + GoalKey FISH_SWIM = create("fish_swim", Fish.class); + + GoalKey DEFEND_TRUSTED = create("defend_trusted", Fox.class); + + GoalKey FACEPLANT = create("faceplant", Fox.class); + + GoalKey FOX_BREED = create("fox_breed", Fox.class); + + GoalKey FOX_EAT_BERRIES = create("fox_eat_berries", Fox.class); + + GoalKey FOX_FLOAT = create("fox_float", Fox.class); + + GoalKey FOX_FOLLOW_PARENT = create("fox_follow_parent", Fox.class); + + GoalKey FOX_LOOK_AT_PLAYER = create("fox_look_at_player", Fox.class); + + GoalKey FOX_MELEE_ATTACK = create("fox_melee_attack", Fox.class); + + GoalKey FOX_PANIC = create("fox_panic", Fox.class); + + GoalKey FOX_POUNCE = create("fox_pounce", Fox.class); + + GoalKey FOX_SEARCH_FOR_ITEMS = create("fox_search_for_items", Fox.class); + + GoalKey FOX_STROLL_THROUGH_VILLAGE = create("fox_stroll_through_village", Fox.class); + + GoalKey PERCH_AND_SEARCH = create("perch_and_search", Fox.class); + + GoalKey SEEK_SHELTER = create("seek_shelter", Fox.class); + + GoalKey SLEEP = create("sleep", Fox.class); + + GoalKey STALK_PREY = create("stalk_prey", Fox.class); + + GoalKey GHAST_LOOK = create("ghast_look", Ghast.class); + + GoalKey GHAST_SHOOT_FIREBALL = create("ghast_shoot_fireball", Ghast.class); + + GoalKey RANDOM_FLOAT_AROUND = create("random_float_around", Ghast.class); + + GoalKey GUARDIAN_ATTACK = create("guardian_attack", Guardian.class); + + GoalKey RAIDER_OPEN_DOOR = create("raider_open_door", Illager.class); + + GoalKey ILLUSIONER_BLINDNESS_SPELL = create("illusioner_blindness_spell", Illusioner.class); + + GoalKey ILLUSIONER_MIRROR_SPELL = create("illusioner_mirror_spell", Illusioner.class); + + GoalKey DEFEND_VILLAGE = create("defend_village", IronGolem.class); + + GoalKey OFFER_FLOWER = create("offer_flower", IronGolem.class); + + GoalKey LLAMA_ATTACK_WOLF = create("llama_attack_wolf", Llama.class); + + GoalKey LLAMA_FOLLOW_CARAVAN = create("llama_follow_caravan", Llama.class); + + GoalKey LLAMA_HURT_BY = create("llama_hurt_by", Llama.class); + + GoalKey TRADER_LLAMA_DEFEND_WANDERING_TRADER = create("trader_llama_defend_wandering_trader", Llama.class); + + GoalKey BREAK_DOOR = create("break_door", Mob.class); + + GoalKey CLIMB_ON_TOP_OF_POWDER_SNOW = create("climb_on_top_of_powder_snow", Mob.class); + + GoalKey EAT_BLOCK = create("eat_block", Mob.class); + + GoalKey FLOAT = create("float", Mob.class); + + GoalKey FOLLOW_MOB = create("follow_mob", Mob.class); + + GoalKey INTERACT = create("interact", Mob.class); + + GoalKey LEAP_AT = create("leap_at", Mob.class); + + GoalKey LOOK_AT_PLAYER = create("look_at_player", Mob.class); + + GoalKey NEAREST_ATTACKABLE = create("nearest_attackable", Mob.class); + + GoalKey OCELOT_ATTACK = create("ocelot_attack", Mob.class); + + GoalKey OPEN_DOOR = create("open_door", Mob.class); + + GoalKey RANDOM_LOOK_AROUND = create("random_look_around", Mob.class); + + GoalKey RESET_UNIVERSAL_ANGER = create("reset_universal_anger", Mob.class); + + GoalKey USE_ITEM = create("use_item", Mob.class); + + GoalKey VINDICATOR_BREAK_DOOR = create("vindicator_break_door", Mob.class); + + GoalKey RANGED_BOW_ATTACK = create("ranged_bow_attack", Monster.class); + + GoalKey RANGED_CROSSBOW_ATTACK = create("ranged_crossbow_attack", Monster.class); + + GoalKey OCELOT_AVOID_ENTITY = create("ocelot_avoid_entity", Ocelot.class); + + GoalKey OCELOT_TEMPT = create("ocelot_tempt", Ocelot.class); + + GoalKey PANDA_ATTACK = create("panda_attack", Panda.class); + + GoalKey PANDA_AVOID = create("panda_avoid", Panda.class); + + GoalKey PANDA_BREED = create("panda_breed", Panda.class); + + GoalKey PANDA_HURT_BY = create("panda_hurt_by", Panda.class); + + GoalKey PANDA_LIE_ON_BACK = create("panda_lie_on_back", Panda.class); + + GoalKey PANDA_LOOK_AT_PLAYER = create("panda_look_at_player", Panda.class); + + GoalKey PANDA_PANIC = create("panda_panic", Panda.class); + + GoalKey PANDA_ROLL = create("panda_roll", Panda.class); + + GoalKey PANDA_SIT = create("panda_sit", Panda.class); + + GoalKey PANDA_SNEEZE = create("panda_sneeze", Panda.class); + + GoalKey LAND_ON_OWNERS_SHOULDER = create("land_on_owners_shoulder", Parrot.class); + + GoalKey PHANTOM_ATTACK_PLAYER = create("phantom_attack_player", Phantom.class); + + GoalKey PHANTOM_ATTACK_STRATEGY = create("phantom_attack_strategy", Phantom.class); + + GoalKey PHANTOM_CIRCLE_AROUND_ANCHOR = create("phantom_circle_around_anchor", Phantom.class); + + GoalKey PHANTOM_SWEEP_ATTACK = create("phantom_sweep_attack", Phantom.class); + + GoalKey POLAR_BEAR_ATTACK_PLAYERS = create("polar_bear_attack_players", PolarBear.class); + + GoalKey POLAR_BEAR_HURT_BY = create("polar_bear_hurt_by", PolarBear.class); + + GoalKey POLAR_BEAR_MELEE_ATTACK = create("polar_bear_melee_attack", PolarBear.class); + + GoalKey POLAR_BEAR_PANIC = create("polar_bear_panic", PolarBear.class); + + GoalKey PUFFERFISH_PUFF = create("pufferfish_puff", PufferFish.class); + + GoalKey RABBIT_AVOID_ENTITY = create("rabbit_avoid_entity", Rabbit.class); + + GoalKey RABBIT_PANIC = create("rabbit_panic", Rabbit.class); + + GoalKey RAID_GARDEN = create("raid_garden", Rabbit.class); + + GoalKey HOLD_GROUND_ATTACK = create("hold_ground_attack", Raider.class); + + GoalKey LONG_DISTANCE_PATROL = create("long_distance_patrol", Raider.class); + + GoalKey NEAREST_ATTACKABLE_WITCH = create("nearest_attackable_witch", Raider.class); + + GoalKey NEAREST_HEALABLE_RAIDER = create("nearest_healable_raider", Raider.class); + + GoalKey OBTAIN_RAID_LEADER_BANNER = create("obtain_raid_leader_banner", Raider.class); + + GoalKey PATHFIND_TO_RAID = create("pathfind_to_raid", Raider.class); + + GoalKey RAIDER_CELEBRATION = create("raider_celebration", Raider.class); + + GoalKey RAIDER_MOVE_THROUGH_VILLAGE = create("raider_move_through_village", Raider.class); + + GoalKey DROWNED_TRIDENT_ATTACK = create("drowned_trident_attack", RangedEntity.class); + + GoalKey RANGED_ATTACK = create("ranged_attack", RangedEntity.class); + + GoalKey FOLLOW_FLOCK_LEADER = create("follow_flock_leader", SchoolableFish.class); + + GoalKey SHULKER_ATTACK = create("shulker_attack", Shulker.class); + + GoalKey SHULKER_DEFENSE_ATTACK = create("shulker_defense_attack", Shulker.class); + + GoalKey SHULKER_NEAREST_ATTACK = create("shulker_nearest_attack", Shulker.class); + + GoalKey SHULKER_PEEK = create("shulker_peek", Shulker.class); + + GoalKey SILVERFISH_MERGE_WITH_STONE = create("silverfish_merge_with_stone", Silverfish.class); + + GoalKey SILVERFISH_WAKE_UP_FRIENDS = create("silverfish_wake_up_friends", Silverfish.class); + + GoalKey SKELETON_TRAP = create("skeleton_trap", SkeletonHorse.class); + + GoalKey SLIME_ATTACK = create("slime_attack", Slime.class); + + GoalKey SLIME_FLOAT = create("slime_float", Slime.class); + + GoalKey SLIME_KEEP_ON_JUMPING = create("slime_keep_on_jumping", Slime.class); + + GoalKey SLIME_RANDOM_DIRECTION = create("slime_random_direction", Slime.class); + + GoalKey SPELLCASTER_CASTING_SPELL = create("spellcaster_casting_spell", Spellcaster.class); + + GoalKey SPIDER = create("spider", Spider.class); + + GoalKey SPIDER_ATTACK = create("spider_attack", Spider.class); + + GoalKey SQUID_FLEE = create("squid_flee", Squid.class); + + GoalKey SQUID_RANDOM_MOVEMENT = create("squid_random_movement", Squid.class); + + GoalKey STRIDER_GO_TO_LAVA = create("strider_go_to_lava", Strider.class); + + GoalKey FOLLOW_OWNER = create("follow_owner", Tameable.class); + + GoalKey NON_TAME_RANDOM = create("non_tame_random", Tameable.class); + + GoalKey OWNER_HURT = create("owner_hurt", Tameable.class); + + GoalKey OWNER_HURT_BY = create("owner_hurt_by", Tameable.class); + + GoalKey SIT_WHEN_ORDERED_TO = create("sit_when_ordered_to", Tameable.class); + + GoalKey TURTLE_BREED = create("turtle_breed", Turtle.class); + + GoalKey TURTLE_GO_HOME = create("turtle_go_home", Turtle.class); + + GoalKey TURTLE_GO_TO_WATER = create("turtle_go_to_water", Turtle.class); + + GoalKey TURTLE_LAY_EGG = create("turtle_lay_egg", Turtle.class); + + GoalKey TURTLE_PANIC = create("turtle_panic", Turtle.class); + + GoalKey TURTLE_RANDOM_STROLL = create("turtle_random_stroll", Turtle.class); + + GoalKey TURTLE_TRAVEL = create("turtle_travel", Turtle.class); + + GoalKey VEX_CHARGE_ATTACK = create("vex_charge_attack", Vex.class); + + GoalKey VEX_COPY_OWNER = create("vex_copy_owner", Vex.class); + + GoalKey VEX_RANDOM_MOVE = create("vex_random_move", Vex.class); + + GoalKey VINDICATOR_JOHNNY_ATTACK = create("vindicator_johnny_attack", Vindicator.class); + + GoalKey WANDER_TO_POSITION = create("wander_to_position", WanderingTrader.class); + + GoalKey WITHER_DO_NOTHING = create("wither_do_nothing", Wither.class); + + GoalKey BEG = create("beg", Wolf.class); + + GoalKey WOLF_AVOID_ENTITY = create("wolf_avoid_entity", Wolf.class); + + GoalKey WOLF_PANIC = create("wolf_panic", Wolf.class); + + GoalKey ZOMBIE_ATTACK = create("zombie_attack", Zombie.class); + + GoalKey ZOMBIE_ATTACK_TURTLE_EGG = create("zombie_attack_turtle_egg", Zombie.class); + + /** + * Removed in 1.20.2 + */ + @Deprecated( + since = "1.20.2" + ) + GoalKey VINDICATOR_MELEE_ATTACK = create("vindicator_melee_attack", Vindicator.class); + + /** + * Removed in 1.20.2 + */ + @Deprecated( + since = "1.20.2" + ) + GoalKey RAVAGER_MELEE_ATTACK = create("ravager_melee_attack", Ravager.class); + + /** + * Removed in 1.20.2 + */ + @Deprecated( + since = "1.20.2" + ) + GoalKey EVIL_RABBIT_ATTACK = create("evil_rabbit_attack", Rabbit.class); + + /** + * Removed in 1.16 + */ + @Deprecated( + forRemoval = true, + since = "1.16" + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey ANGER = create("anger", PigZombie.class); + + /** + * Removed in 1.16 + */ + @Deprecated( + forRemoval = true, + since = "1.16" + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey ANGER_OTHER = create("anger_other", PigZombie.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey BLAZE_FIREBALL = create("blaze_fireball", Blaze.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey TEMPT_CHANCE = create("tempt_chance", Cat.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey DOLPHIN_PLAY_WITH_ITEMS = create("dolphin_play_with_items", Dolphin.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey DROWNED_GOTO_BEACH = create("drowned_goto_beach", Drowned.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey DROWNED_GOTO_WATER = create("drowned_goto_water", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey ENDERMAN_PICKUP_BLOCK = create("enderman_pickup_block", Enderman.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey ENDERMAN_PLACE_BLOCK = create("enderman_place_block", Enderman.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey PLAYER_WHO_LOOKED_AT_TARGET = create("player_who_looked_at_target", Enderman.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey EVOKER_CAST_SPELL = create("evoker_cast_spell", Evoker.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey FOX_DEFEND_TRUSTED = create("fox_defend_trusted", Fox.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey FOX_FACEPLANT = create("fox_faceplant", Fox.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey FOX_PERCH_AND_SEARCH = create("fox_perch_and_search", Fox.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey FOX_SLEEP = create("fox_sleep", Fox.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey FOX_SEEK_SHELTER = create("fox_seek_shelter", Fox.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey FOX_STALK_PREY = create("fox_stalk_prey", Fox.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey GHAST_ATTACK_TARGET = create("ghast_attack_target", Ghast.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey GHAST_IDLE_MOVE = create("ghast_idle_move", Ghast.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey GHAST_MOVE_TOWARDS_TARGET = create("ghast_move_towards_target", Ghast.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey SPELLCASTER_CAST_SPELL = create("spellcaster_cast_spell", Spellcaster.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey LLAMATRADER_DEFENDED_WANDERING_TRADER = create("llamatrader_defended_wandering_trader", TraderLlama.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey PANDA_HURT_BY_TARGET = create("panda_hurt_by_target", Panda.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey POLARBEAR_ATTACK_PLAYERS = create("polarbear_attack_players", PolarBear.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey POLARBEAR_HURT_BY = create("polarbear_hurt_by", PolarBear.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey POLARBEAR_MELEE = create("polarbear_melee", PolarBear.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey POLARBEAR_PANIC = create("polarbear_panic", PolarBear.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey EAT_CARROTS = create("eat_carrots", Rabbit.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey KILLER_RABBIT_MELEE_ATTACK = create("killer_rabbit_melee_attack", Rabbit.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey RABBIT_AVOID_TARGET = create("rabbit_avoid_target", Rabbit.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey RAIDER_HOLD_GROUND = create("raider_hold_ground", Raider.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey RAIDER_OBTAIN_BANNER = create("raider_obtain_banner", Raider.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey SHULKER_DEFENSE = create("shulker_defense", Shulker.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey SHULKER_NEAREST = create("shulker_nearest", Shulker.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey SILVERFISH_HIDE_IN_BLOCK = create("silverfish_hide_in_block", Silverfish.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey SILVERFISH_WAKE_OTHERS = create("silverfish_wake_others", Silverfish.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey SLIME_IDLE = create("slime_idle", Slime.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey SLIME_NEAREST_PLAYER = create("slime_nearest_player", Slime.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey SLIME_RANDOM_JUMP = create("slime_random_jump", Slime.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey SPIDER_MELEE_ATTACK = create("spider_melee_attack", Spider.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey SPIDER_NEAREST_ATTACKABLE_TARGET = create("spider_nearest_attackable_target", Spider.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey SQUID = create("squid", Squid.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey TURTLE_GOTO_WATER = create("turtle_goto_water", Turtle.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey TURTLE_TEMPT = create("turtle_tempt", Turtle.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey VEX_COPY_TARGET_OF_OWNER = create("vex_copy_target_of_owner", Vex.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey VILLAGERTRADER_WANDER_TO_POSITION = create("villagertrader_wander_to_position", WanderingTrader.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey ARROW_ATTACK = create("arrow_attack", RangedEntity.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey AVOID_TARGET = create("avoid_target", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey BOW_SHOOT = create("bow_shoot", Monster.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey BREATH = create("breath", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey CAT_SIT_ON_BED = create("cat_sit_on_bed", Cat.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey CROSSBOW_ATTACK = create("crossbow_attack", Monster.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey DOOR_OPEN = create("door_open", Mob.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey EAT_TILE = create("eat_tile", Mob.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey FISH_SCHOOL = create("fish_school", Fish.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey FOLLOW_ENTITY = create("follow_entity", Mob.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey HORSE_TRAP = create("horse_trap", SkeletonHorse.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey HURT_BY_TARGET = create("hurt_by_target", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey JUMP_ON_BLOCK = create("jump_on_block", Cat.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey LEAP_AT_TARGET = create("leap_at_target", Mob.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey LLAMA_FOLLOW = create("llama_follow", Llama.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey MOVE_TOWARDS_TARGET = create("move_towards_target", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey NEAREST_ATTACKABLE_TARGET = create("nearest_attackable_target", Mob.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey NEAREST_ATTACKABLE_TARGET_WITCH = create("nearest_attackable_target_witch", Raider.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey NEAREST_VILLAGE = create("nearest_village", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey OWNER_HURT_BY_TARGET = create("owner_hurt_by_target", Tameable.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey OWNER_HURT_TARGET = create("owner_hurt_target", Tameable.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey PERCH = create("perch", Parrot.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey RAID = create("raid", Raider.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey RANDOM_FLY = create("random_fly", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey RANDOM_LOOKAROUND = create("random_lookaround", Mob.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey RANDOM_STROLL_LAND = create("random_stroll_land", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey RANDOM_SWIM = create("random_swim", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey RANDOM_TARGET_NON_TAMED = create("random_target_non_tamed", Tameable.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey SIT = create("sit", Tameable.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey STROLL_VILLAGE = create("stroll_village", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey TAME = create("tame", AbstractHorse.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey WATER = create("water", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey WATER_JUMP = create("water_jump", Dolphin.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey STROLL_VILLAGE_GOLEM = create("stroll_village_golem", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey UNIVERSAL_ANGER_RESET = create("universal_anger_reset", Mob.class); + + private static @NotNull GoalKey create(final @NotNull String key, final @NotNull Class clazz) { + return GoalKey.of(clazz, NamespacedKey.minecraft(key)); + } +} diff --git a/paper-api-generator/src/main/java/io/papermc/generator/Generators.java b/paper-api-generator/src/main/java/io/papermc/generator/Generators.java new file mode 100644 index 0000000000..ac62e26e93 --- /dev/null +++ b/paper-api-generator/src/main/java/io/papermc/generator/Generators.java @@ -0,0 +1,32 @@ +package io.papermc.generator; + +import io.papermc.generator.types.GeneratedKeyType; +import io.papermc.generator.types.SourceGenerator; +import io.papermc.generator.types.goal.MobGoalGenerator; +import io.papermc.paper.registry.RegistryKey; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import org.bukkit.GameEvent; +import org.bukkit.block.Biome; +import org.bukkit.generator.structure.Structure; +import org.bukkit.generator.structure.StructureType; +import org.bukkit.inventory.meta.trim.TrimMaterial; +import org.bukkit.inventory.meta.trim.TrimPattern; + +public interface Generators { + + SourceGenerator[] API = { + simpleKey("GameEventKeys", GameEvent.class, Registries.GAME_EVENT, RegistryKey.GAME_EVENT, true), + simpleKey("BiomeKeys", Biome.class, Registries.BIOME, RegistryKey.BIOME, true), + simpleKey("TrimMaterialKeys", TrimMaterial.class, Registries.TRIM_MATERIAL, RegistryKey.TRIM_MATERIAL, true), + simpleKey("TrimPatternKeys", TrimPattern.class, Registries.TRIM_PATTERN, RegistryKey.TRIM_PATTERN, true), + simpleKey("StructureKeys", Structure.class, Registries.STRUCTURE, RegistryKey.STRUCTURE, true), + simpleKey("StructureTypeKeys", StructureType.class, Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE, false), + new MobGoalGenerator("VanillaGoal", "com.destroystokyo.paper.entity.ai") + }; + + private static SourceGenerator simpleKey(final String className, final Class apiType, final ResourceKey> registryKey, final RegistryKey apiRegistryKey, final boolean publicCreateKeyMethod) { + return new GeneratedKeyType<>(className, apiType, "io.papermc.paper.registry.keys", registryKey, apiRegistryKey, publicCreateKeyMethod); + } +} diff --git a/paper-api-generator/src/main/java/io/papermc/generator/Main.java b/paper-api-generator/src/main/java/io/papermc/generator/Main.java index 4ce510a6d2..e02f55871f 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/Main.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/Main.java @@ -48,31 +48,24 @@ public final class Main { REGISTRY_ACCESS = layers.compositeAccess().freeze(); } - private static final List GENERATORS = List.of( - simpleKey("GameEventKeys", GameEvent.class, Registries.GAME_EVENT, RegistryKey.GAME_EVENT, true), - simpleKey("BiomeKeys", Biome.class, Registries.BIOME, RegistryKey.BIOME, true), - simpleKey("TrimMaterialKeys", TrimMaterial.class, Registries.TRIM_MATERIAL, RegistryKey.TRIM_MATERIAL, true), - simpleKey("TrimPatternKeys", TrimPattern.class, Registries.TRIM_PATTERN, RegistryKey.TRIM_PATTERN, true), - simpleKey("StructureKeys", Structure.class, Registries.STRUCTURE, RegistryKey.STRUCTURE, true), - simpleKey("StructureTypeKeys", StructureType.class, Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE, false) - ); - - private static SourceGenerator simpleKey(final String className, final Class apiType, final ResourceKey> registryKey, final RegistryKey apiRegistryKey, final boolean publicCreateKeyMethod) { - return new GeneratedKeyType<>(className, apiType, "io.papermc.paper.registry.keys", registryKey, apiRegistryKey, publicCreateKeyMethod); - } - private Main() { } public static void main(final String[] args) { - final Path output = Paths.get(args[0]); + LOGGER.info("Running API generators..."); + generate(Paths.get(args[0]), Generators.API); + // LOGGER.info("Running Server generators..."); + // generate(Paths.get(args[1]), Generators.SERVER); + } + + private static void generate(Path output, SourceGenerator[] generators) { try { if (Files.exists(output)) { PathUtils.deleteDirectory(output); } Files.createDirectories(output); - for (final SourceGenerator generator : GENERATORS) { + for (final SourceGenerator generator : generators) { generator.writeToFile(output); } @@ -81,6 +74,4 @@ public final class Main { throw new RuntimeException(ex); } } - - } diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/Annotations.java b/paper-api-generator/src/main/java/io/papermc/generator/types/Annotations.java deleted file mode 100644 index 0886a360a6..0000000000 --- a/paper-api-generator/src/main/java/io/papermc/generator/types/Annotations.java +++ /dev/null @@ -1,26 +0,0 @@ -package io.papermc.generator.types; - -import com.squareup.javapoet.AnnotationSpec; -import java.util.List; -import org.bukkit.MinecraftExperimental; -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; - -public final class Annotations { - - public static List experimentalAnnotations(final String version) { - return List.of( - AnnotationSpec.builder(ApiStatus.Experimental.class).build(), - AnnotationSpec.builder(MinecraftExperimental.class) - .addMember("value", "$S", version) - .build() - ); - } - - @ApiStatus.Experimental - public static final AnnotationSpec EXPERIMENTAL_API_ANNOTATION = AnnotationSpec.builder(ApiStatus.Experimental.class).build(); - public static final AnnotationSpec NOT_NULL = AnnotationSpec.builder(NotNull.class).build(); - - private Annotations() { - } -} diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java b/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java index 4ecb1d102c..2c1a72d715 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/types/GeneratedKeyType.java @@ -1,6 +1,5 @@ package io.papermc.generator.types; -import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.MethodSpec; @@ -9,16 +8,13 @@ import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeSpec; import io.papermc.generator.Main; +import io.papermc.generator.utils.Annotations; import io.papermc.generator.utils.CollectingContext; -import io.papermc.paper.generated.GeneratedFrom; +import io.papermc.generator.utils.Javadocs; import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; -import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Modifier; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -27,7 +23,6 @@ import java.util.Locale; import java.util.Map; import java.util.stream.Collectors; import net.kyori.adventure.key.Key; -import net.minecraft.SharedConstants; import net.minecraft.core.Registry; import net.minecraft.core.RegistrySetBuilder; import net.minecraft.data.registries.UpdateOneTwentyOneRegistries; @@ -37,9 +32,9 @@ import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.framework.qual.DefaultQualifier; import static com.squareup.javapoet.TypeSpec.classBuilder; -import static io.papermc.generator.types.Annotations.EXPERIMENTAL_API_ANNOTATION; -import static io.papermc.generator.types.Annotations.NOT_NULL; -import static io.papermc.generator.types.Annotations.experimentalAnnotations; +import static io.papermc.generator.utils.Annotations.EXPERIMENTAL_API_ANNOTATION; +import static io.papermc.generator.utils.Annotations.NOT_NULL; +import static io.papermc.generator.utils.Annotations.experimentalAnnotations; import static java.util.Objects.requireNonNull; import static javax.lang.model.element.Modifier.FINAL; import static javax.lang.model.element.Modifier.PRIVATE; @@ -47,7 +42,7 @@ import static javax.lang.model.element.Modifier.PUBLIC; import static javax.lang.model.element.Modifier.STATIC; @DefaultQualifier(NonNull.class) -public class GeneratedKeyType implements SourceGenerator { +public class GeneratedKeyType extends SimpleGenerator { private static final Map>, RegistrySetBuilder.RegistryBootstrap> EXPERIMENTAL_REGISTRY_ENTRIES = UpdateOneTwentyOneRegistries.BUILDER.entries.stream() .collect(Collectors.toMap(RegistrySetBuilder.RegistryStub::key, RegistrySetBuilder.RegistryStub::bootstrap)); @@ -68,27 +63,6 @@ public class GeneratedKeyType implements SourceGenerator { } } - private static final AnnotationSpec SUPPRESS_WARNINGS = AnnotationSpec.builder(SuppressWarnings.class) - .addMember("value", "$S", "unused") - .addMember("value", "$S", "SpellCheckingInspection") - .build(); - private static final AnnotationSpec GENERATED_FROM = AnnotationSpec.builder(GeneratedFrom.class) - .addMember("value", "$S", SharedConstants.getCurrentVersion().getName()) - .build(); - private static final String TYPE_JAVADOC = """ - Vanilla keys for {@link $T#$L}. - - @apiNote The fields provided here are a direct representation of - what is available from the vanilla game source. They may be - changed (including removals) on any Minecraft version - bump, so cross-version compatibility is not provided on the - same level as it is on most of the other API. - """; - private static final String FIELD_JAVADOC = """ - {@code $L} - - @apiNote This field is version-dependant and may be removed in future Minecraft versions - """; private static final String CREATE_JAVADOC = """ Creates a key for {@link $T} in a registry. @@ -96,17 +70,14 @@ public class GeneratedKeyType implements SourceGenerator { @return a new typed key """; - private final String keysClassName; private final Class apiType; - private final String pkg; private final ResourceKey> registryKey; private final RegistryKey apiRegistryKey; private final boolean publicCreateKeyMethod; public GeneratedKeyType(final String keysClassName, final Class apiType, final String pkg, final ResourceKey> registryKey, final RegistryKey apiRegistryKey, final boolean publicCreateKeyMethod) { - this.keysClassName = keysClassName; + super(keysClassName, pkg); this.apiType = apiType; - this.pkg = pkg; this.registryKey = registryKey; this.apiRegistryKey = apiRegistryKey; this.publicCreateKeyMethod = publicCreateKeyMethod; @@ -129,17 +100,18 @@ public class GeneratedKeyType implements SourceGenerator { } private TypeSpec.Builder keyHolderType() { - return classBuilder(this.keysClassName) + return classBuilder(this.className) .addModifiers(PUBLIC, FINAL) - .addJavadoc(TYPE_JAVADOC, RegistryKey.class, REGISTRY_KEY_FIELD_NAMES.get(this.apiRegistryKey)) - .addAnnotation(SUPPRESS_WARNINGS).addAnnotation(GENERATED_FROM) + .addJavadoc(Javadocs.getVersionDependentClassHeader("{@link $T#$L}"), RegistryKey.class, REGISTRY_KEY_FIELD_NAMES.get(this.apiRegistryKey)) + .addAnnotations(Annotations.CLASS_HEADER) .addMethod(MethodSpec.constructorBuilder() .addModifiers(PRIVATE) .build() ); } - protected TypeSpec createTypeSpec() { + @Override + protected TypeSpec getTypeSpec() { final TypeName typedKey = ParameterizedTypeName.get(TypedKey.class, this.apiType); final TypeSpec.Builder typeBuilder = this.keyHolderType(); @@ -156,7 +128,7 @@ public class GeneratedKeyType implements SourceGenerator { final String fieldName = keyPath.toUpperCase(Locale.ENGLISH).replaceAll("[.-/]", "_"); // replace invalid field name chars final FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, PUBLIC, STATIC, FINAL) .initializer("$N(key($S))", createMethod.build(), keyPath) - .addJavadoc(FIELD_JAVADOC, key.location().toString()); + .addJavadoc(Javadocs.getVersionDependentField("{@code $L}"), key.location().toString()); if (experimental.contains(key)) { fieldBuilder.addAnnotations(experimentalAnnotations("update 1.21")); } else { @@ -183,23 +155,11 @@ public class GeneratedKeyType implements SourceGenerator { return experimental; } - protected JavaFile createFile() { - return JavaFile.builder(this.pkg, this.createTypeSpec()) + @Override + protected JavaFile.Builder file(JavaFile.Builder builder) { + return builder .skipJavaLangImports(true) .addStaticImport(Key.class, "key") - .indent(" ") - .build(); - } - - @Override - public final String outputString() { - return this.createFile().toString(); - } - - @Override - public void writeToFile(final Path parent) throws IOException { - final Path pkgDir = parent.resolve(this.pkg.replace('.', '/')); - Files.createDirectories(pkgDir); - Files.writeString(pkgDir.resolve(this.keysClassName + ".java"), this.outputString(), StandardCharsets.UTF_8); + .indent(" "); } } diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/SimpleGenerator.java b/paper-api-generator/src/main/java/io/papermc/generator/types/SimpleGenerator.java new file mode 100644 index 0000000000..76edecd9ff --- /dev/null +++ b/paper-api-generator/src/main/java/io/papermc/generator/types/SimpleGenerator.java @@ -0,0 +1,37 @@ +package io.papermc.generator.types; + +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.TypeSpec; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; + +public abstract class SimpleGenerator implements SourceGenerator { + + protected final String className; + protected final String packageName; + + protected SimpleGenerator(String className, String packageName) { + this.className = className; + this.packageName = packageName; + } + + protected abstract TypeSpec getTypeSpec(); + + protected abstract JavaFile.Builder file(JavaFile.Builder builder); + + @Override + public void writeToFile(Path parent) throws IOException { + Path packagePath = parent.resolve(this.packageName.replace('.', '/')); + Files.createDirectories(packagePath); + + JavaFile.Builder builder = JavaFile.builder(this.packageName, this.getTypeSpec()) + .indent(" "); + this.file(builder); + + Files.writeString(packagePath.resolve(this.className + ".java"), this.file(builder).build().toString(), StandardCharsets.UTF_8); + } + +} diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/SourceGenerator.java b/paper-api-generator/src/main/java/io/papermc/generator/types/SourceGenerator.java index 50d176e9ea..2d550fa421 100644 --- a/paper-api-generator/src/main/java/io/papermc/generator/types/SourceGenerator.java +++ b/paper-api-generator/src/main/java/io/papermc/generator/types/SourceGenerator.java @@ -5,7 +5,5 @@ import java.nio.file.Path; public interface SourceGenerator { - String outputString(); - void writeToFile(Path parent) throws IOException; } diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalGenerator.java b/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalGenerator.java new file mode 100644 index 0000000000..649490b5b0 --- /dev/null +++ b/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalGenerator.java @@ -0,0 +1,262 @@ +package io.papermc.generator.types.goal; + +import com.destroystokyo.paper.entity.RangedEntity; +import com.destroystokyo.paper.entity.ai.GoalKey; +import com.squareup.javapoet.AnnotationSpec; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.FieldSpec; +import com.squareup.javapoet.JavaFile; +import com.squareup.javapoet.MethodSpec; +import com.squareup.javapoet.ParameterSpec; +import com.squareup.javapoet.ParameterizedTypeName; +import com.squareup.javapoet.TypeName; +import com.squareup.javapoet.TypeSpec; +import com.squareup.javapoet.TypeVariableName; +import io.github.classgraph.ClassGraph; +import io.github.classgraph.ScanResult; +import io.papermc.generator.types.SimpleGenerator; +import io.papermc.generator.utils.Annotations; +import io.papermc.generator.utils.Formatting; +import io.papermc.generator.utils.Javadocs; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import javax.lang.model.element.Modifier; +import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.entity.ai.goal.WrappedGoal; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.AbstractHorse; +import org.bukkit.entity.Blaze; +import org.bukkit.entity.Cat; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Dolphin; +import org.bukkit.entity.Drowned; +import org.bukkit.entity.Enderman; +import org.bukkit.entity.Evoker; +import org.bukkit.entity.Fish; +import org.bukkit.entity.Fox; +import org.bukkit.entity.Ghast; +import org.bukkit.entity.Llama; +import org.bukkit.entity.Mob; +import org.bukkit.entity.Monster; +import org.bukkit.entity.Panda; +import org.bukkit.entity.Parrot; +import org.bukkit.entity.PigZombie; +import org.bukkit.entity.PolarBear; +import org.bukkit.entity.Rabbit; +import org.bukkit.entity.Raider; +import org.bukkit.entity.Ravager; +import org.bukkit.entity.Shulker; +import org.bukkit.entity.Silverfish; +import org.bukkit.entity.SkeletonHorse; +import org.bukkit.entity.Slime; +import org.bukkit.entity.Spellcaster; +import org.bukkit.entity.Spider; +import org.bukkit.entity.Squid; +import org.bukkit.entity.Tameable; +import org.bukkit.entity.TraderLlama; +import org.bukkit.entity.Turtle; +import org.bukkit.entity.Vex; +import org.bukkit.entity.Vindicator; +import org.bukkit.entity.WanderingTrader; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.framework.qual.DefaultQualifier; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +@DefaultQualifier(NonNull.class) +public class MobGoalGenerator extends SimpleGenerator { + + private static final String CLASS_HEADER = Javadocs.getVersionDependentClassHeader("Mob Goals"); + + private static final DeprecatedEntry[] DEPRECATED_ENTRIES = { + // + new DeprecatedEntry(Vindicator.class, "vindicator_melee_attack", null, "1.20.2"), + new DeprecatedEntry(Ravager.class, "ravager_melee_attack", null, "1.20.2"), + new DeprecatedEntry(Rabbit.class, "evil_rabbit_attack", null, "1.20.2"), + new DeprecatedEntry(PigZombie.class, "anger", "1.21", "1.16"), + new DeprecatedEntry(PigZombie.class, "anger_other", "1.21", "1.16"), + new DeprecatedEntry(Blaze.class, "blaze_fireball", "1.21", null), + new DeprecatedEntry(Cat.class, "tempt_chance", "1.21", null), + new DeprecatedEntry(Dolphin.class, "dolphin_play_with_items", "1.21", null), + new DeprecatedEntry(Drowned.class, "drowned_goto_beach", "1.21", null), + new DeprecatedEntry(Creature.class, "drowned_goto_water", "1.21", null), + new DeprecatedEntry(Enderman.class, "enderman_pickup_block", "1.21", null), + new DeprecatedEntry(Enderman.class, "enderman_place_block", "1.21", null), + new DeprecatedEntry(Enderman.class, "player_who_looked_at_target", "1.21", null), + new DeprecatedEntry(Evoker.class, "evoker_cast_spell", "1.21", null), + new DeprecatedEntry(Fox.class, "fox_defend_trusted", "1.21", null), + new DeprecatedEntry(Fox.class, "fox_faceplant", "1.21", null), + new DeprecatedEntry(Fox.class, "fox_perch_and_search", "1.21", null), + new DeprecatedEntry(Fox.class, "fox_sleep", "1.21", null), + new DeprecatedEntry(Fox.class, "fox_seek_shelter", "1.21", null), + new DeprecatedEntry(Fox.class, "fox_stalk_prey", "1.21", null), + new DeprecatedEntry(Ghast.class, "ghast_attack_target", "1.21", null), + new DeprecatedEntry(Ghast.class, "ghast_idle_move", "1.21", null), + new DeprecatedEntry(Ghast.class, "ghast_move_towards_target", "1.21", null), + new DeprecatedEntry(Spellcaster.class, "spellcaster_cast_spell", "1.21", null), + new DeprecatedEntry(TraderLlama.class, "llamatrader_defended_wandering_trader", "1.21", null), + new DeprecatedEntry(Panda.class, "panda_hurt_by_target", "1.21", null), + new DeprecatedEntry(PolarBear.class, "polarbear_attack_players", "1.21", null), + new DeprecatedEntry(PolarBear.class, "polarbear_hurt_by", "1.21", null), + new DeprecatedEntry(PolarBear.class, "polarbear_melee", "1.21", null), + new DeprecatedEntry(PolarBear.class, "polarbear_panic", "1.21", null), + new DeprecatedEntry(Rabbit.class, "eat_carrots", "1.21", null), + new DeprecatedEntry(Rabbit.class, "killer_rabbit_melee_attack", "1.21", null), + new DeprecatedEntry(Rabbit.class, "rabbit_avoid_target", "1.21", null), + new DeprecatedEntry(Raider.class, "raider_hold_ground", "1.21", null), + new DeprecatedEntry(Raider.class, "raider_obtain_banner", "1.21", null), + new DeprecatedEntry(Shulker.class, "shulker_defense", "1.21", null), + new DeprecatedEntry(Shulker.class, "shulker_nearest", "1.21", null), + new DeprecatedEntry(Silverfish.class, "silverfish_hide_in_block", "1.21", null), + new DeprecatedEntry(Silverfish.class, "silverfish_wake_others", "1.21", null), + new DeprecatedEntry(Slime.class, "slime_idle", "1.21", null), + new DeprecatedEntry(Slime.class, "slime_nearest_player", "1.21", null), + new DeprecatedEntry(Slime.class, "slime_random_jump", "1.21", null), + new DeprecatedEntry(Spider.class, "spider_melee_attack", "1.21", null), + new DeprecatedEntry(Spider.class, "spider_nearest_attackable_target", "1.21", null), + new DeprecatedEntry(Squid.class, "squid", "1.21", null), + new DeprecatedEntry(Turtle.class, "turtle_goto_water", "1.21", null), + new DeprecatedEntry(Turtle.class, "turtle_tempt", "1.21", null), + new DeprecatedEntry(Vex.class, "vex_copy_target_of_owner", "1.21", null), + new DeprecatedEntry(WanderingTrader.class, "villagertrader_wander_to_position", "1.21", null), + new DeprecatedEntry(RangedEntity.class, "arrow_attack", "1.21", null), + new DeprecatedEntry(Creature.class, "avoid_target", "1.21", null), + new DeprecatedEntry(Monster.class, "bow_shoot", "1.21", null), + new DeprecatedEntry(Creature.class, "breath", "1.21", null), + new DeprecatedEntry(Cat.class, "cat_sit_on_bed", "1.21", null), + new DeprecatedEntry(Monster.class, "crossbow_attack", "1.21", null), + new DeprecatedEntry(Mob.class, "door_open", "1.21", null), + new DeprecatedEntry(Mob.class, "eat_tile", "1.21", null), + new DeprecatedEntry(Fish.class, "fish_school", "1.21", null), + new DeprecatedEntry(Mob.class, "follow_entity", "1.21", null), + new DeprecatedEntry(SkeletonHorse.class, "horse_trap", "1.21", null), + new DeprecatedEntry(Creature.class, "hurt_by_target", "1.21", null), + new DeprecatedEntry(Cat.class, "jump_on_block", "1.21", null), + new DeprecatedEntry(Mob.class, "leap_at_target", "1.21", null), + new DeprecatedEntry(Llama.class, "llama_follow", "1.21", null), + new DeprecatedEntry(Creature.class, "move_towards_target", "1.21", null), + new DeprecatedEntry(Mob.class, "nearest_attackable_target", "1.21", null), + new DeprecatedEntry(Raider.class, "nearest_attackable_target_witch", "1.21", null), + new DeprecatedEntry(Creature.class, "nearest_village", "1.21", null), + new DeprecatedEntry(Tameable.class, "owner_hurt_by_target", "1.21", null), + new DeprecatedEntry(Tameable.class, "owner_hurt_target", "1.21", null), + new DeprecatedEntry(Parrot.class, "perch", "1.21", null), + new DeprecatedEntry(Raider.class, "raid", "1.21", null), + new DeprecatedEntry(Creature.class, "random_fly", "1.21", null), + new DeprecatedEntry(Mob.class, "random_lookaround", "1.21", null), + new DeprecatedEntry(Creature.class, "random_stroll_land", "1.21", null), + new DeprecatedEntry(Creature.class, "random_swim", "1.21", null), + new DeprecatedEntry(Tameable.class, "random_target_non_tamed", "1.21", null), + new DeprecatedEntry(Tameable.class, "sit", "1.21", null), + new DeprecatedEntry(Creature.class, "stroll_village", "1.21", null), + new DeprecatedEntry(AbstractHorse.class, "tame", "1.21", null), + new DeprecatedEntry(Creature.class, "water", "1.21", null), + new DeprecatedEntry(Dolphin.class, "water_jump", "1.21", null), + new DeprecatedEntry(Creature.class, "stroll_village_golem", "1.21", null), + new DeprecatedEntry(Mob.class, "universal_anger_reset", "1.21", null) + // + }; + + public MobGoalGenerator(final String keysClassName, final String pkg) { + super(keysClassName, pkg); + } + + @Override + protected TypeSpec getTypeSpec() { + TypeName clazzType = TypeName.get(Class.class) + .annotated(Annotations.NOT_NULL); + TypeName keyType = TypeName.get(String.class) + .annotated(Annotations.NOT_NULL); + + MethodSpec.Builder createMethod = MethodSpec.methodBuilder("create") + .addModifiers(Modifier.PRIVATE, Modifier.STATIC) + .addParameter(ParameterSpec.builder(keyType, "key", Modifier.FINAL) + .build() + ) + .addParameter(ParameterSpec.builder(clazzType, "clazz", Modifier.FINAL) + .build() + ) + .addCode("return $T.of(clazz, $T.minecraft(key));", GoalKey.class, NamespacedKey.class) + .returns(ParameterizedTypeName.get(GoalKey.class).annotated(Annotations.NOT_NULL)); + + + TypeVariableName type = TypeVariableName.get("T", Mob.class); + TypeSpec.Builder typeBuilder = TypeSpec.interfaceBuilder(this.className) + .addSuperinterface(ParameterizedTypeName.get(ClassName.get(com.destroystokyo.paper.entity.ai.Goal.class), type)) + .addModifiers(Modifier.PUBLIC) + .addTypeVariable(type) + .addAnnotations(Annotations.CLASS_HEADER) + .addJavadoc(CLASS_HEADER); + + + List> classes; + try (ScanResult scanResult = new ClassGraph().enableAllInfo().whitelistPackages("net.minecraft").scan()) { + classes = scanResult.getSubclasses(net.minecraft.world.entity.ai.goal.Goal.class.getName()).loadClasses(); + } + + List vanillaNames = classes.stream() + .filter(clazz -> !java.lang.reflect.Modifier.isAbstract(clazz.getModifiers())) + .filter(clazz -> !WrappedGoal.class.equals(clazz)) // TODO - properly fix + .map(goalClass -> new VanillaGoalKey(goalClass, MobGoalNames.getKey(goalClass.getName(), (Class) goalClass))) + .filter((key) -> !MobGoalNames.isIgnored(key.key().getNamespacedKey().getKey())) + .sorted(Comparator.comparing(o -> o.key().getEntityClass().getSimpleName()) + .thenComparing(vanillaGoalKey -> vanillaGoalKey.key.getNamespacedKey().getKey()) + ) + .toList(); + + + for (final VanillaGoalKey vanillaGoalKey : vanillaNames) { + GoalKey value = vanillaGoalKey.key(); + TypeName typedKey = ParameterizedTypeName.get(GoalKey.class, value.getEntityClass()); + NamespacedKey key = value.getNamespacedKey(); + + String keyPath = key.getKey(); + String fieldName = Formatting.formatKeyAsField(key); + FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) + .initializer("$N($S, $T.class)", createMethod.build(), keyPath, value.getEntityClass()); + typeBuilder.addField(fieldBuilder.build()); + } + + for (final DeprecatedEntry value : DEPRECATED_ENTRIES) { + TypeName typedKey = ParameterizedTypeName.get(GoalKey.class, value.entity); + NamespacedKey key = NamespacedKey.minecraft(value.entryName); + + String keyPath = key.getKey(); + String fieldName = Formatting.formatKeyAsField(key); + FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL) + .addAnnotation(Annotations.deprecatedVersioned(value.removedVersion, value.removalVersion != null)) + .initializer("$N($S, $T.class)", createMethod.build(), keyPath, value.entity); + + if (value.removedVersion != null) { + fieldBuilder.addJavadoc("Removed in $L", value.removedVersion); + } + if (value.removalVersion != null) { + fieldBuilder.addAnnotation(Annotations.scheduledRemoval(value.removalVersion)); + } + + typeBuilder.addField(fieldBuilder.build()); + } + + return typeBuilder.addMethod(createMethod.build()).build(); + } + + @Override + protected JavaFile.Builder file(JavaFile.Builder builder) { + return builder + .skipJavaLangImports(true); + } + + record VanillaGoalKey(Class clazz, GoalKey key) { + } + + record DeprecatedEntry(Class entity, String entryName, @Nullable String removalVersion, + @Nullable String removedVersion) { + + } + +} diff --git a/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java b/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java new file mode 100644 index 0000000000..cc7a416166 --- /dev/null +++ b/paper-api-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java @@ -0,0 +1,329 @@ +package io.papermc.generator.types.goal; + +import com.destroystokyo.paper.entity.RangedEntity; +import com.destroystokyo.paper.entity.ai.GoalKey; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import net.minecraft.world.entity.FlyingMob; +import net.minecraft.world.entity.PathfinderMob; +import net.minecraft.world.entity.TamableAnimal; +import net.minecraft.world.entity.ai.goal.Goal; +import net.minecraft.world.entity.ambient.AmbientCreature; +import net.minecraft.world.entity.animal.AbstractFish; +import net.minecraft.world.entity.animal.AbstractGolem; +import net.minecraft.world.entity.animal.AbstractSchoolingFish; +import net.minecraft.world.entity.animal.Animal; +import net.minecraft.world.entity.animal.Pufferfish; +import net.minecraft.world.entity.animal.ShoulderRidingEntity; +import net.minecraft.world.entity.animal.SnowGolem; +import net.minecraft.world.entity.animal.WaterAnimal; +import net.minecraft.world.entity.animal.horse.AbstractChestedHorse; +import net.minecraft.world.entity.boss.wither.WitherBoss; +import net.minecraft.world.entity.monster.AbstractIllager; +import net.minecraft.world.entity.monster.EnderMan; +import net.minecraft.world.entity.monster.PatrollingMonster; +import net.minecraft.world.entity.monster.RangedAttackMob; +import net.minecraft.world.entity.monster.SpellcasterIllager; +import net.minecraft.world.entity.monster.ZombifiedPiglin; +import net.minecraft.world.entity.monster.piglin.AbstractPiglin; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.AbstractHorse; +import org.bukkit.entity.AbstractSkeleton; +import org.bukkit.entity.AbstractVillager; +import org.bukkit.entity.Ageable; +import org.bukkit.entity.Ambient; +import org.bukkit.entity.Animals; +import org.bukkit.entity.Bat; +import org.bukkit.entity.Bee; +import org.bukkit.entity.Blaze; +import org.bukkit.entity.Cat; +import org.bukkit.entity.CaveSpider; +import org.bukkit.entity.ChestedHorse; +import org.bukkit.entity.Chicken; +import org.bukkit.entity.Cod; +import org.bukkit.entity.Cow; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.Dolphin; +import org.bukkit.entity.Donkey; +import org.bukkit.entity.Drowned; +import org.bukkit.entity.ElderGuardian; +import org.bukkit.entity.EnderDragon; +import org.bukkit.entity.Enderman; +import org.bukkit.entity.Endermite; +import org.bukkit.entity.Evoker; +import org.bukkit.entity.Fish; +import org.bukkit.entity.Flying; +import org.bukkit.entity.Fox; +import org.bukkit.entity.Ghast; +import org.bukkit.entity.Giant; +import org.bukkit.entity.Golem; +import org.bukkit.entity.Guardian; +import org.bukkit.entity.Hoglin; +import org.bukkit.entity.Horse; +import org.bukkit.entity.Husk; +import org.bukkit.entity.Illager; +import org.bukkit.entity.Illusioner; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Llama; +import org.bukkit.entity.MagmaCube; +import org.bukkit.entity.Mob; +import org.bukkit.entity.Monster; +import org.bukkit.entity.Mule; +import org.bukkit.entity.MushroomCow; +import org.bukkit.entity.Ocelot; +import org.bukkit.entity.Panda; +import org.bukkit.entity.Parrot; +import org.bukkit.entity.Phantom; +import org.bukkit.entity.Pig; +import org.bukkit.entity.PigZombie; +import org.bukkit.entity.Piglin; +import org.bukkit.entity.PiglinAbstract; +import org.bukkit.entity.PiglinBrute; +import org.bukkit.entity.Pillager; +import org.bukkit.entity.PolarBear; +import org.bukkit.entity.PufferFish; +import org.bukkit.entity.Rabbit; +import org.bukkit.entity.Raider; +import org.bukkit.entity.Ravager; +import org.bukkit.entity.Salmon; +import org.bukkit.entity.Sheep; +import org.bukkit.entity.Shulker; +import org.bukkit.entity.Silverfish; +import org.bukkit.entity.Skeleton; +import org.bukkit.entity.SkeletonHorse; +import org.bukkit.entity.Slime; +import org.bukkit.entity.Snowman; +import org.bukkit.entity.Spellcaster; +import org.bukkit.entity.Spider; +import org.bukkit.entity.Squid; +import org.bukkit.entity.Stray; +import org.bukkit.entity.Strider; +import org.bukkit.entity.Tameable; +import org.bukkit.entity.TraderLlama; +import org.bukkit.entity.TropicalFish; +import org.bukkit.entity.Turtle; +import org.bukkit.entity.Vex; +import org.bukkit.entity.Villager; +import org.bukkit.entity.Vindicator; +import org.bukkit.entity.WanderingTrader; +import org.bukkit.entity.WaterMob; +import org.bukkit.entity.Witch; +import org.bukkit.entity.Wither; +import org.bukkit.entity.WitherSkeleton; +import org.bukkit.entity.Wolf; +import org.bukkit.entity.Zoglin; +import org.bukkit.entity.Zombie; +import org.bukkit.entity.ZombieHorse; +import org.bukkit.entity.ZombieVillager; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class MobGoalNames { + + private static final Map, Class> entityClassCache = new HashMap<>(); + private static final Map, Class> bukkitMap = new HashMap<>(); + + + static { + // + bukkitMap.put(net.minecraft.world.entity.Mob.class, Mob.class); + bukkitMap.put(net.minecraft.world.entity.AgeableMob.class, Ageable.class); + bukkitMap.put(AmbientCreature.class, Ambient.class); + bukkitMap.put(Animal.class, Animals.class); + bukkitMap.put(net.minecraft.world.entity.ambient.Bat.class, Bat.class); + bukkitMap.put(net.minecraft.world.entity.animal.Bee.class, Bee.class); + bukkitMap.put(net.minecraft.world.entity.monster.Blaze.class, Blaze.class); + bukkitMap.put(net.minecraft.world.entity.animal.Cat.class, Cat.class); + bukkitMap.put(net.minecraft.world.entity.monster.CaveSpider.class, CaveSpider.class); + bukkitMap.put(net.minecraft.world.entity.animal.Chicken.class, Chicken.class); + bukkitMap.put(net.minecraft.world.entity.animal.Cod.class, Cod.class); + bukkitMap.put(net.minecraft.world.entity.animal.Cow.class, Cow.class); + bukkitMap.put(PathfinderMob.class, Creature.class); + bukkitMap.put(net.minecraft.world.entity.monster.Creeper.class, Creeper.class); + bukkitMap.put(net.minecraft.world.entity.animal.Dolphin.class, Dolphin.class); + bukkitMap.put(net.minecraft.world.entity.monster.Drowned.class, Drowned.class); + bukkitMap.put(net.minecraft.world.entity.boss.enderdragon.EnderDragon.class, EnderDragon.class); + bukkitMap.put(EnderMan.class, Enderman.class); + bukkitMap.put(net.minecraft.world.entity.monster.Endermite.class, Endermite.class); + bukkitMap.put(net.minecraft.world.entity.monster.Evoker.class, Evoker.class); + bukkitMap.put(AbstractFish.class, Fish.class); + bukkitMap.put(AbstractSchoolingFish.class, io.papermc.paper.entity.SchoolableFish.class); + bukkitMap.put(FlyingMob.class, Flying.class); + bukkitMap.put(net.minecraft.world.entity.animal.Fox.class, Fox.class); + bukkitMap.put(net.minecraft.world.entity.monster.Ghast.class, Ghast.class); + bukkitMap.put(net.minecraft.world.entity.monster.Giant.class, Giant.class); + bukkitMap.put(AbstractGolem.class, Golem.class); + bukkitMap.put(net.minecraft.world.entity.monster.Guardian.class, Guardian.class); + bukkitMap.put(net.minecraft.world.entity.monster.ElderGuardian.class, ElderGuardian.class); + bukkitMap.put(net.minecraft.world.entity.animal.horse.Horse.class, Horse.class); + bukkitMap.put(net.minecraft.world.entity.animal.horse.AbstractHorse.class, AbstractHorse.class); + bukkitMap.put(AbstractChestedHorse.class, ChestedHorse.class); + bukkitMap.put(net.minecraft.world.entity.animal.horse.Donkey.class, Donkey.class); + bukkitMap.put(net.minecraft.world.entity.animal.horse.Mule.class, Mule.class); + bukkitMap.put(net.minecraft.world.entity.animal.horse.SkeletonHorse.class, SkeletonHorse.class); + bukkitMap.put(net.minecraft.world.entity.animal.horse.ZombieHorse.class, ZombieHorse.class); + bukkitMap.put(net.minecraft.world.entity.animal.camel.Camel.class, org.bukkit.entity.Camel.class); + bukkitMap.put(AbstractIllager.class, Illager.class); + bukkitMap.put(net.minecraft.world.entity.monster.Illusioner.class, Illusioner.class); + bukkitMap.put(SpellcasterIllager.class, Spellcaster.class); + bukkitMap.put(net.minecraft.world.entity.animal.IronGolem.class, IronGolem.class); + bukkitMap.put(net.minecraft.world.entity.animal.horse.Llama.class, Llama.class); + bukkitMap.put(net.minecraft.world.entity.animal.horse.TraderLlama.class, TraderLlama.class); + bukkitMap.put(net.minecraft.world.entity.monster.MagmaCube.class, MagmaCube.class); + bukkitMap.put(net.minecraft.world.entity.monster.Monster.class, Monster.class); + bukkitMap.put(PatrollingMonster.class, Raider.class); // close enough + bukkitMap.put(net.minecraft.world.entity.animal.MushroomCow.class, MushroomCow.class); + bukkitMap.put(net.minecraft.world.entity.animal.Ocelot.class, Ocelot.class); + bukkitMap.put(net.minecraft.world.entity.animal.Panda.class, Panda.class); + bukkitMap.put(net.minecraft.world.entity.animal.Parrot.class, Parrot.class); + bukkitMap.put(ShoulderRidingEntity.class, Parrot.class); // close enough + bukkitMap.put(net.minecraft.world.entity.monster.Phantom.class, Phantom.class); + bukkitMap.put(net.minecraft.world.entity.animal.Pig.class, Pig.class); + bukkitMap.put(ZombifiedPiglin.class, PigZombie.class); + bukkitMap.put(net.minecraft.world.entity.monster.Pillager.class, Pillager.class); + bukkitMap.put(net.minecraft.world.entity.animal.PolarBear.class, PolarBear.class); + bukkitMap.put(Pufferfish.class, PufferFish.class); + bukkitMap.put(net.minecraft.world.entity.animal.Rabbit.class, Rabbit.class); + bukkitMap.put(net.minecraft.world.entity.raid.Raider.class, Raider.class); + bukkitMap.put(net.minecraft.world.entity.monster.Ravager.class, Ravager.class); + bukkitMap.put(net.minecraft.world.entity.animal.Salmon.class, Salmon.class); + bukkitMap.put(net.minecraft.world.entity.animal.Sheep.class, Sheep.class); + bukkitMap.put(net.minecraft.world.entity.monster.Shulker.class, Shulker.class); + bukkitMap.put(net.minecraft.world.entity.monster.Silverfish.class, Silverfish.class); + bukkitMap.put(net.minecraft.world.entity.monster.Skeleton.class, Skeleton.class); + bukkitMap.put(net.minecraft.world.entity.monster.AbstractSkeleton.class, AbstractSkeleton.class); + bukkitMap.put(net.minecraft.world.entity.monster.Stray.class, Stray.class); + bukkitMap.put(net.minecraft.world.entity.monster.WitherSkeleton.class, WitherSkeleton.class); + bukkitMap.put(net.minecraft.world.entity.monster.Slime.class, Slime.class); + bukkitMap.put(SnowGolem.class, Snowman.class); + bukkitMap.put(net.minecraft.world.entity.monster.Spider.class, Spider.class); + bukkitMap.put(net.minecraft.world.entity.animal.Squid.class, Squid.class); + bukkitMap.put(TamableAnimal.class, Tameable.class); + bukkitMap.put(net.minecraft.world.entity.animal.TropicalFish.class, TropicalFish.class); + bukkitMap.put(net.minecraft.world.entity.animal.Turtle.class, Turtle.class); + bukkitMap.put(net.minecraft.world.entity.monster.Vex.class, Vex.class); + bukkitMap.put(net.minecraft.world.entity.npc.Villager.class, Villager.class); + bukkitMap.put(net.minecraft.world.entity.npc.AbstractVillager.class, AbstractVillager.class); + bukkitMap.put(net.minecraft.world.entity.npc.WanderingTrader.class, WanderingTrader.class); + bukkitMap.put(net.minecraft.world.entity.monster.Vindicator.class, Vindicator.class); + bukkitMap.put(WaterAnimal.class, WaterMob.class); + bukkitMap.put(net.minecraft.world.entity.monster.Witch.class, Witch.class); + bukkitMap.put(WitherBoss.class, Wither.class); + bukkitMap.put(net.minecraft.world.entity.animal.Wolf.class, Wolf.class); + bukkitMap.put(net.minecraft.world.entity.monster.Zombie.class, Zombie.class); + bukkitMap.put(net.minecraft.world.entity.monster.Husk.class, Husk.class); + bukkitMap.put(net.minecraft.world.entity.monster.ZombieVillager.class, ZombieVillager.class); + bukkitMap.put(net.minecraft.world.entity.monster.hoglin.Hoglin.class, Hoglin.class); + bukkitMap.put(net.minecraft.world.entity.monster.piglin.Piglin.class, Piglin.class); + bukkitMap.put(AbstractPiglin.class, PiglinAbstract.class); + bukkitMap.put(net.minecraft.world.entity.monster.piglin.PiglinBrute.class, PiglinBrute.class); + bukkitMap.put(net.minecraft.world.entity.monster.Strider.class, Strider.class); + bukkitMap.put(net.minecraft.world.entity.monster.Zoglin.class, Zoglin.class); + bukkitMap.put(net.minecraft.world.entity.GlowSquid.class, org.bukkit.entity.GlowSquid.class); + bukkitMap.put(net.minecraft.world.entity.animal.axolotl.Axolotl.class, org.bukkit.entity.Axolotl.class); + bukkitMap.put(net.minecraft.world.entity.animal.goat.Goat.class, org.bukkit.entity.Goat.class); + bukkitMap.put(net.minecraft.world.entity.animal.frog.Frog.class, org.bukkit.entity.Frog.class); + bukkitMap.put(net.minecraft.world.entity.animal.frog.Tadpole.class, org.bukkit.entity.Tadpole.class); + bukkitMap.put(net.minecraft.world.entity.monster.warden.Warden.class, org.bukkit.entity.Warden.class); + bukkitMap.put(net.minecraft.world.entity.animal.allay.Allay.class, org.bukkit.entity.Allay.class); + bukkitMap.put(net.minecraft.world.entity.animal.sniffer.Sniffer.class, org.bukkit.entity.Sniffer.class); + // + } + + private static final BiMap deobfuscationMap = HashBiMap.create(); + static final Set ignored = new HashSet<>(); + + static { + deobfuscationMap.put("abstract_skeleton_1", "abstract_skeleton_melee"); + + ignored.add("goal_selector_1"); + ignored.add("goal_selector_2"); + ignored.add("selector_1"); + ignored.add("selector_2"); + ignored.add("wrapped"); + } + + public static String getUsableName(String name) { + final String original = name; + name = name.substring(name.lastIndexOf(".") + 1); + boolean flag = false; + // inner classes + if (name.contains("$")) { + String cut = name.substring(name.indexOf("$") + 1); + if (cut.length() <= 2) { + name = name.replace("Entity", ""); + name = name.replace("$", "_"); + flag = true; + } else { + // mapped, wooo + name = cut; + } + } + name = name.replace("PathfinderGoal", ""); + name = name.replace("TargetGoal", ""); + name = name.replace("Goal", ""); + StringBuilder sb = new StringBuilder(); + for (char c : name.toCharArray()) { + if (c >= 'A' && c <= 'Z') { + sb.append("_"); + sb.append(Character.toLowerCase(c)); + } else { + sb.append(c); + } + } + name = sb.toString(); + name = name.replaceFirst("_", ""); + + if (flag && !deobfuscationMap.containsKey(name.toLowerCase()) && !ignored.contains(name)) { + System.out.println("need to map " + original + " (" + name.toLowerCase() + ")"); + } + + // did we rename this key? + return deobfuscationMap.getOrDefault(name, name); + } + + public static boolean isIgnored(String name) { + return ignored.contains(name); + } + + + public static GoalKey getKey(String clazzName, Class goalClass) { + String name = getUsableName(clazzName); + if (MobGoalNames.isIgnored(name)) { + //noinspection unchecked + return (GoalKey) GoalKey.of(Mob.class, NamespacedKey.minecraft(name)); + } + return GoalKey.of(getEntity(goalClass), NamespacedKey.minecraft(name)); + } + + public static Class getEntity(Class goalClass) { + //noinspection unchecked + return (Class) entityClassCache.computeIfAbsent(goalClass, key -> { + for (Constructor ctor : key.getDeclaredConstructors()) { + for (int i = 0; i < ctor.getParameterCount(); i++) { + Class param = ctor.getParameterTypes()[i]; + if (net.minecraft.world.entity.Mob.class.isAssignableFrom(param)) { + //noinspection unchecked + return toBukkitClass((Class) param); + } else if (RangedAttackMob.class.isAssignableFrom(param)) { + return RangedEntity.class; + } + } + } + throw new RuntimeException("Can't figure out applicable entity for mob goal " + goalClass); // maybe just return EntityInsentient? + }); + } + + public static Class toBukkitClass(Class nmsClass) { + Class bukkitClass = bukkitMap.get(nmsClass); + if (bukkitClass == null) { + throw new RuntimeException("Can't figure out applicable bukkit entity for nms entity " + nmsClass); // maybe just return Mob? + } + return bukkitClass; + } +} diff --git a/paper-api-generator/src/main/java/io/papermc/generator/utils/Annotations.java b/paper-api-generator/src/main/java/io/papermc/generator/utils/Annotations.java new file mode 100644 index 0000000000..0d897ecfb4 --- /dev/null +++ b/paper-api-generator/src/main/java/io/papermc/generator/utils/Annotations.java @@ -0,0 +1,59 @@ +package io.papermc.generator.utils; + +import com.squareup.javapoet.AnnotationSpec; +import java.util.List; + +import io.papermc.paper.generated.GeneratedFrom; +import net.minecraft.SharedConstants; +import org.bukkit.MinecraftExperimental; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public final class Annotations { + + public static List experimentalAnnotations(final String version) { + return List.of( + AnnotationSpec.builder(ApiStatus.Experimental.class).build(), + AnnotationSpec.builder(MinecraftExperimental.class) + .addMember("value", "$S", version) + .build() + ); + } + + public static AnnotationSpec deprecatedVersioned(final @Nullable String version, boolean forRemoval) { + AnnotationSpec.Builder annotationSpec = AnnotationSpec.builder(Deprecated.class); + if (forRemoval) { + annotationSpec.addMember("forRemoval", "$L", forRemoval); + } + if (version != null) { + annotationSpec.addMember("since", "$S", version); + } + + return annotationSpec.build(); + } + + public static AnnotationSpec scheduledRemoval(final @Nullable String version) { + return AnnotationSpec.builder(ApiStatus.ScheduledForRemoval.class) + .addMember("inVersion", "$S", version) + .build(); + } + + @ApiStatus.Experimental + public static final AnnotationSpec EXPERIMENTAL_API_ANNOTATION = AnnotationSpec.builder(ApiStatus.Experimental.class).build(); + public static final AnnotationSpec NOT_NULL = AnnotationSpec.builder(NotNull.class).build(); + private static final AnnotationSpec SUPPRESS_WARNINGS = AnnotationSpec.builder(SuppressWarnings.class) + .addMember("value", "$S", "unused") + .addMember("value", "$S", "SpellCheckingInspection") + .build(); + private static final AnnotationSpec GENERATED_FROM = AnnotationSpec.builder(GeneratedFrom.class) + .addMember("value", "$S", SharedConstants.getCurrentVersion().getName()) + .build(); + public static final Iterable CLASS_HEADER = List.of( + SUPPRESS_WARNINGS, + GENERATED_FROM + ); + + private Annotations() { + } +} diff --git a/paper-api-generator/src/main/java/io/papermc/generator/utils/Formatting.java b/paper-api-generator/src/main/java/io/papermc/generator/utils/Formatting.java new file mode 100644 index 0000000000..f4b07411a4 --- /dev/null +++ b/paper-api-generator/src/main/java/io/papermc/generator/utils/Formatting.java @@ -0,0 +1,15 @@ +package io.papermc.generator.utils; + +import net.kyori.adventure.key.Key; + +import java.util.Locale; + +public final class Formatting { + + public static String formatKeyAsField(Key key) { + return key.value().toUpperCase(Locale.ENGLISH).replaceAll("[.-/]", "_"); // replace invalid field name chars + } + + private Formatting() { + } +} diff --git a/paper-api-generator/src/main/java/io/papermc/generator/utils/Javadocs.java b/paper-api-generator/src/main/java/io/papermc/generator/utils/Javadocs.java new file mode 100644 index 0000000000..33536c8311 --- /dev/null +++ b/paper-api-generator/src/main/java/io/papermc/generator/utils/Javadocs.java @@ -0,0 +1,27 @@ +package io.papermc.generator.utils; + +public final class Javadocs { + + public static String getVersionDependentClassHeader(String headerIdentifier) { + return """ + Vanilla keys for %s. + + @apiNote The fields provided here are a direct representation of + what is available from the vanilla game source. They may be + changed (including removals) on any Minecraft version + bump, so cross-version compatibility is not provided on the + same level as it is on most of the other API. + """.formatted(headerIdentifier); + } + + public static String getVersionDependentField(String headerIdentifier) { + return """ + %s + + @apiNote This field is version-dependant and may be removed in future Minecraft versions + """.formatted(headerIdentifier); + } + + private Javadocs() { + } +} diff --git a/patches/api/Add-Mob-Goal-API.patch b/patches/api/Add-Mob-Goal-API.patch index a4bde5ed94..a858e42e4c 100644 --- a/patches/api/Add-Mob-Goal-API.patch +++ b/patches/api/Add-Mob-Goal-API.patch @@ -225,315 +225,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @NotNull + Collection> getRunningGoalsWithout(@NotNull T mob, @NotNull GoalType type); +} -diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 ---- /dev/null -+++ b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java -@@ -0,0 +0,0 @@ -+package com.destroystokyo.paper.entity.ai; -+ -+import com.destroystokyo.paper.entity.RangedEntity; -+ -+import org.bukkit.NamespacedKey; -+import org.bukkit.entity.*; -+import org.jetbrains.annotations.ApiStatus; -+ -+/** -+ * Represents a vanilla goal. Plugins should never implement this.
-+ * Generated by VanillaPathfinderTest in paper-server -+ */ -+public interface VanillaGoal extends Goal { -+ -+ GoalKey AVOID_ENTITY = GoalKey.of(Creature.class, NamespacedKey.minecraft("avoid_entity")); -+ GoalKey BEG = GoalKey.of(Wolf.class, NamespacedKey.minecraft("beg")); -+ GoalKey BREAK_DOOR = GoalKey.of(Mob.class, NamespacedKey.minecraft("break_door")); -+ GoalKey BREATH_AIR = GoalKey.of(Creature.class, NamespacedKey.minecraft("breath_air")); -+ GoalKey BREED = GoalKey.of(Animals.class, NamespacedKey.minecraft("breed")); -+ GoalKey CAT_LIE_ON_BED = GoalKey.of(Cat.class, NamespacedKey.minecraft("cat_lie_on_bed")); -+ GoalKey CAT_SIT_ON_BLOCK = GoalKey.of(Cat.class, NamespacedKey.minecraft("cat_sit_on_block")); -+ GoalKey DOLPHIN_JUMP = GoalKey.of(Dolphin.class, NamespacedKey.minecraft("dolphin_jump")); -+ GoalKey EAT_BLOCK = GoalKey.of(Mob.class, NamespacedKey.minecraft("eat_block")); -+ GoalKey FLEE_SUN = GoalKey.of(Creature.class, NamespacedKey.minecraft("flee_sun")); -+ GoalKey FLOAT = GoalKey.of(Mob.class, NamespacedKey.minecraft("float")); -+ GoalKey FOLLOW_BOAT = GoalKey.of(Creature.class, NamespacedKey.minecraft("follow_boat")); -+ GoalKey FOLLOW_FLOCK_LEADER = GoalKey.of(Fish.class, NamespacedKey.minecraft("follow_flock_leader")); -+ GoalKey FOLLOW_MOB = GoalKey.of(Mob.class, NamespacedKey.minecraft("follow_mob")); -+ GoalKey FOLLOW_OWNER = GoalKey.of(Tameable.class, NamespacedKey.minecraft("follow_owner")); -+ GoalKey FOLLOW_PARENT = GoalKey.of(Animals.class, NamespacedKey.minecraft("follow_parent")); -+ GoalKey GOLEM_RANDOM_STROLL_IN_VILLAGE = GoalKey.of(Creature.class, NamespacedKey.minecraft("golem_random_stroll_in_village")); -+ GoalKey INTERACT = GoalKey.of(Mob.class, NamespacedKey.minecraft("interact")); -+ GoalKey LAND_ON_OWNERS_SHOULDER = GoalKey.of(Parrot.class, NamespacedKey.minecraft("land_on_owners_shoulder")); -+ GoalKey LEAP_AT = GoalKey.of(Mob.class, NamespacedKey.minecraft("leap_at")); -+ GoalKey LLAMA_FOLLOW_CARAVAN = GoalKey.of(Llama.class, NamespacedKey.minecraft("llama_follow_caravan")); -+ GoalKey LOOK_AT_PLAYER = GoalKey.of(Mob.class, NamespacedKey.minecraft("look_at_player")); -+ GoalKey LOOK_AT_TRADING_PLAYER = GoalKey.of(AbstractVillager.class, NamespacedKey.minecraft("look_at_trading_player")); -+ GoalKey MELEE_ATTACK = GoalKey.of(Creature.class, NamespacedKey.minecraft("melee_attack")); -+ GoalKey MOVE_BACK_TO_VILLAGE = GoalKey.of(Creature.class, NamespacedKey.minecraft("move_back_to_village")); -+ GoalKey MOVE_THROUGH_VILLAGE = GoalKey.of(Creature.class, NamespacedKey.minecraft("move_through_village")); -+ GoalKey MOVE_TOWARDS_RESTRICTION = GoalKey.of(Creature.class, NamespacedKey.minecraft("move_towards_restriction")); -+ GoalKey MOVE_TOWARDS = GoalKey.of(Creature.class, NamespacedKey.minecraft("move_towards")); -+ GoalKey OCELOT_ATTACK = GoalKey.of(Mob.class, NamespacedKey.minecraft("ocelot_attack")); -+ GoalKey OFFER_FLOWER = GoalKey.of(IronGolem.class, NamespacedKey.minecraft("offer_flower")); -+ GoalKey OPEN_DOOR = GoalKey.of(Mob.class, NamespacedKey.minecraft("open_door")); -+ GoalKey PANIC = GoalKey.of(Creature.class, NamespacedKey.minecraft("panic")); -+ GoalKey PATHFIND_TO_RAID = GoalKey.of(Raider.class, NamespacedKey.minecraft("pathfind_to_raid")); -+ GoalKey RANDOM_LOOK_AROUND = GoalKey.of(Mob.class, NamespacedKey.minecraft("random_look_around")); -+ GoalKey RANDOM_STAND = GoalKey.of(AbstractHorse.class, NamespacedKey.minecraft("random_stand")); -+ GoalKey RANDOM_STROLL = GoalKey.of(Creature.class, NamespacedKey.minecraft("random_stroll")); -+ GoalKey RANDOM_SWIMMING = GoalKey.of(Creature.class, NamespacedKey.minecraft("random_swimming")); -+ GoalKey RANGED_ATTACK = GoalKey.of(RangedEntity.class, NamespacedKey.minecraft("ranged_attack")); -+ GoalKey RANGED_BOW_ATTACK = GoalKey.of(Monster.class, NamespacedKey.minecraft("ranged_bow_attack")); -+ GoalKey RANGED_CROSSBOW_ATTACK = GoalKey.of(Monster.class, NamespacedKey.minecraft("ranged_crossbow_attack")); -+ GoalKey REMOVE_BLOCK = GoalKey.of(Creature.class, NamespacedKey.minecraft("remove_block")); -+ GoalKey RESTRICT_SUN = GoalKey.of(Creature.class, NamespacedKey.minecraft("restrict_sun")); -+ GoalKey RUN_AROUND_LIKE_CRAZY = GoalKey.of(AbstractHorse.class, NamespacedKey.minecraft("run_around_like_crazy")); -+ GoalKey SIT_WHEN_ORDERED_TO = GoalKey.of(Tameable.class, NamespacedKey.minecraft("sit_when_ordered_to")); -+ GoalKey STROLL_THROUGH_VILLAGE = GoalKey.of(Creature.class, NamespacedKey.minecraft("stroll_through_village")); -+ GoalKey SWELL = GoalKey.of(Creeper.class, NamespacedKey.minecraft("swell")); -+ GoalKey TEMPT = GoalKey.of(Creature.class, NamespacedKey.minecraft("tempt")); -+ GoalKey TRADE_WITH_PLAYER = GoalKey.of(AbstractVillager.class, NamespacedKey.minecraft("trade_with_player")); -+ GoalKey TRY_FIND_WATER = GoalKey.of(Creature.class, NamespacedKey.minecraft("try_find_water")); -+ GoalKey USE_ITEM = GoalKey.of(Mob.class, NamespacedKey.minecraft("use_item")); -+ GoalKey WATER_AVOIDING_RANDOM_FLYING = GoalKey.of(Creature.class, NamespacedKey.minecraft("water_avoiding_random_flying")); -+ GoalKey WATER_AVOIDING_RANDOM_STROLL = GoalKey.of(Creature.class, NamespacedKey.minecraft("water_avoiding_random_stroll")); -+ GoalKey ZOMBIE_ATTACK = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack")); -+ GoalKey DEFEND_VILLAGE = GoalKey.of(IronGolem.class, NamespacedKey.minecraft("defend_village")); -+ GoalKey HURT_BY = GoalKey.of(Creature.class, NamespacedKey.minecraft("hurt_by")); -+ GoalKey NEAREST_ATTACKABLE = GoalKey.of(Mob.class, NamespacedKey.minecraft("nearest_attackable")); -+ GoalKey NEAREST_ATTACKABLE_WITCH = GoalKey.of(Raider.class, NamespacedKey.minecraft("nearest_attackable_witch")); -+ GoalKey NEAREST_HEALABLE_RAIDER = GoalKey.of(Raider.class, NamespacedKey.minecraft("nearest_healable_raider")); -+ GoalKey NON_TAME_RANDOM = GoalKey.of(Tameable.class, NamespacedKey.minecraft("non_tame_random")); -+ GoalKey OWNER_HURT_BY = GoalKey.of(Tameable.class, NamespacedKey.minecraft("owner_hurt_by")); -+ GoalKey OWNER_HURT = GoalKey.of(Tameable.class, NamespacedKey.minecraft("owner_hurt")); -+ GoalKey RESET_UNIVERSAL_ANGER = GoalKey.of(Mob.class, NamespacedKey.minecraft("reset_universal_anger")); -+ GoalKey FISH_SWIM = GoalKey.of(Fish.class, NamespacedKey.minecraft("fish_swim")); -+ GoalKey BEE_ATTACK = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_attack")); -+ GoalKey BEE_BECOME_ANGRY = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_become_angry")); -+ GoalKey BEE_ENTER_HIVE = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_enter_hive")); -+ GoalKey BEE_GO_TO_HIVE = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_go_to_hive")); -+ GoalKey BEE_GO_TO_KNOWN_FLOWER = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_go_to_known_flower")); -+ GoalKey BEE_GROW_CROP = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_grow_crop")); -+ GoalKey BEE_HURT_BY_OTHER = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_hurt_by_other")); -+ GoalKey BEE_LOCATE_HIVE = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_locate_hive")); -+ GoalKey BEE_POLLINATE = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_pollinate")); -+ GoalKey BEE_WANDER = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_wander")); -+ GoalKey CAT_AVOID_ENTITY = GoalKey.of(Cat.class, NamespacedKey.minecraft("cat_avoid_entity")); -+ GoalKey CAT_RELAX_ON_OWNER = GoalKey.of(Cat.class, NamespacedKey.minecraft("cat_relax_on_owner")); -+ GoalKey CAT_TEMPT = GoalKey.of(Cat.class, NamespacedKey.minecraft("cat_tempt")); -+ GoalKey DOLPHIN_SWIM_TO_TREASURE = GoalKey.of(Dolphin.class, NamespacedKey.minecraft("dolphin_swim_to_treasure")); -+ GoalKey DOLPHIN_SWIM_WITH_PLAYER = GoalKey.of(Dolphin.class, NamespacedKey.minecraft("dolphin_swim_with_player")); -+ GoalKey PLAY_WITH_ITEMS = GoalKey.of(Dolphin.class, NamespacedKey.minecraft("play_with_items")); -+ GoalKey DEFEND_TRUSTED = GoalKey.of(Fox.class, NamespacedKey.minecraft("defend_trusted")); -+ GoalKey FACEPLANT = GoalKey.of(Fox.class, NamespacedKey.minecraft("faceplant")); -+ GoalKey FOX_BREED = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_breed")); -+ GoalKey FOX_EAT_BERRIES = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_eat_berries")); -+ GoalKey FOX_FLOAT = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_float")); -+ GoalKey FOX_FOLLOW_PARENT = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_follow_parent")); -+ GoalKey FOX_LOOK_AT_PLAYER = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_look_at_player")); -+ GoalKey FOX_MELEE_ATTACK = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_melee_attack")); -+ GoalKey FOX_PANIC = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_panic")); -+ GoalKey FOX_POUNCE = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_pounce")); -+ GoalKey FOX_SEARCH_FOR_ITEMS = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_search_for_items")); -+ GoalKey FOX_STROLL_THROUGH_VILLAGE = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_stroll_through_village")); -+ GoalKey PERCH_AND_SEARCH = GoalKey.of(Fox.class, NamespacedKey.minecraft("perch_and_search")); -+ GoalKey SEEK_SHELTER = GoalKey.of(Fox.class, NamespacedKey.minecraft("seek_shelter")); -+ GoalKey SLEEP = GoalKey.of(Fox.class, NamespacedKey.minecraft("sleep")); -+ GoalKey STALK_PREY = GoalKey.of(Fox.class, NamespacedKey.minecraft("stalk_prey")); -+ GoalKey OCELOT_AVOID_ENTITY = GoalKey.of(Ocelot.class, NamespacedKey.minecraft("ocelot_avoid_entity")); -+ GoalKey OCELOT_TEMPT = GoalKey.of(Ocelot.class, NamespacedKey.minecraft("ocelot_tempt")); -+ GoalKey PANDA_ATTACK = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_attack")); -+ GoalKey PANDA_AVOID = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_avoid")); -+ GoalKey PANDA_BREED = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_breed")); -+ GoalKey PANDA_HURT_BY = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_hurt_by")); -+ GoalKey PANDA_LIE_ON_BACK = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_lie_on_back")); -+ GoalKey PANDA_LOOK_AT_PLAYER = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_look_at_player")); -+ GoalKey PANDA_PANIC = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_panic")); -+ GoalKey PANDA_ROLL = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_roll")); -+ GoalKey PANDA_SIT = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_sit")); -+ GoalKey PANDA_SNEEZE = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_sneeze")); -+ GoalKey POLAR_BEAR_ATTACK_PLAYERS = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polar_bear_attack_players")); -+ GoalKey POLAR_BEAR_HURT_BY = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polar_bear_hurt_by")); -+ GoalKey POLAR_BEAR_MELEE_ATTACK = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polar_bear_melee_attack")); -+ GoalKey POLAR_BEAR_PANIC = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polar_bear_panic")); -+ GoalKey PUFFERFISH_PUFF = GoalKey.of(PufferFish.class, NamespacedKey.minecraft("pufferfish_puff")); -+ GoalKey RABBIT_AVOID_ENTITY = GoalKey.of(Rabbit.class, NamespacedKey.minecraft("rabbit_avoid_entity")); -+ GoalKey RABBIT_PANIC = GoalKey.of(Rabbit.class, NamespacedKey.minecraft("rabbit_panic")); -+ GoalKey RAID_GARDEN = GoalKey.of(Rabbit.class, NamespacedKey.minecraft("raid_garden")); -+ GoalKey SQUID_FLEE = GoalKey.of(Squid.class, NamespacedKey.minecraft("squid_flee")); -+ GoalKey SQUID_RANDOM_MOVEMENT = GoalKey.of(Squid.class, NamespacedKey.minecraft("squid_random_movement")); -+ GoalKey TURTLE_BREED = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_breed")); -+ GoalKey TURTLE_GO_HOME = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_go_home")); -+ GoalKey TURTLE_GO_TO_WATER = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_go_to_water")); -+ GoalKey TURTLE_LAY_EGG = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_lay_egg")); -+ GoalKey TURTLE_PANIC = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_panic")); -+ GoalKey TURTLE_RANDOM_STROLL = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_random_stroll")); -+ GoalKey TURTLE_TRAVEL = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_travel")); -+ GoalKey WOLF_AVOID_ENTITY = GoalKey.of(Wolf.class, NamespacedKey.minecraft("wolf_avoid_entity")); -+ GoalKey LLAMA_ATTACK_WOLF = GoalKey.of(Llama.class, NamespacedKey.minecraft("llama_attack_wolf")); -+ GoalKey LLAMA_HURT_BY = GoalKey.of(Llama.class, NamespacedKey.minecraft("llama_hurt_by")); -+ GoalKey SKELETON_TRAP = GoalKey.of(SkeletonHorse.class, NamespacedKey.minecraft("skeleton_trap")); -+ GoalKey TRADER_LLAMA_DEFEND_WANDERING_TRADER = GoalKey.of(Llama.class, NamespacedKey.minecraft("trader_llama_defend_wandering_trader")); -+ GoalKey WITHER_DO_NOTHING = GoalKey.of(Wither.class, NamespacedKey.minecraft("wither_do_nothing")); -+ GoalKey RAIDER_OPEN_DOOR = GoalKey.of(Illager.class, NamespacedKey.minecraft("raider_open_door")); -+ GoalKey SKELETON_MELEE = GoalKey.of(AbstractSkeleton.class, NamespacedKey.minecraft("abstract_skeleton_melee")); -+ GoalKey BLAZE_ATTACK = GoalKey.of(Blaze.class, NamespacedKey.minecraft("blaze_attack")); -+ GoalKey DROWNED_ATTACK = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_attack")); -+ GoalKey DROWNED_GO_TO_BEACH = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_go_to_beach")); -+ GoalKey DROWNED_GO_TO_WATER = GoalKey.of(Creature.class, NamespacedKey.minecraft("drowned_go_to_water")); -+ GoalKey DROWNED_SWIM_UP = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_swim_up")); -+ GoalKey DROWNED_TRIDENT_ATTACK = GoalKey.of(RangedEntity.class, NamespacedKey.minecraft("drowned_trident_attack")); -+ GoalKey ENDERMAN_FREEZE_WHEN_LOOKED_AT = GoalKey.of(Enderman.class, NamespacedKey.minecraft("enderman_freeze_when_looked_at")); -+ GoalKey ENDERMAN_LEAVE_BLOCK = GoalKey.of(Enderman.class, NamespacedKey.minecraft("enderman_leave_block")); -+ GoalKey ENDERMAN_LOOK_FOR_PLAYER = GoalKey.of(Enderman.class, NamespacedKey.minecraft("enderman_look_for_player")); -+ GoalKey ENDERMAN_TAKE_BLOCK = GoalKey.of(Enderman.class, NamespacedKey.minecraft("enderman_take_block")); -+ GoalKey EVOKER_ATTACK_SPELL = GoalKey.of(Evoker.class, NamespacedKey.minecraft("evoker_attack_spell")); -+ GoalKey EVOKER_CASTING_SPELL = GoalKey.of(Evoker.class, NamespacedKey.minecraft("evoker_casting_spell")); -+ GoalKey EVOKER_SUMMON_SPELL = GoalKey.of(Evoker.class, NamespacedKey.minecraft("evoker_summon_spell")); -+ GoalKey EVOKER_WOLOLO_SPELL = GoalKey.of(Evoker.class, NamespacedKey.minecraft("evoker_wololo_spell")); -+ GoalKey GHAST_LOOK = GoalKey.of(Ghast.class, NamespacedKey.minecraft("ghast_look")); -+ GoalKey GHAST_SHOOT_FIREBALL = GoalKey.of(Ghast.class, NamespacedKey.minecraft("ghast_shoot_fireball")); -+ GoalKey RANDOM_FLOAT_AROUND = GoalKey.of(Ghast.class, NamespacedKey.minecraft("random_float_around")); -+ GoalKey GUARDIAN_ATTACK = GoalKey.of(Guardian.class, NamespacedKey.minecraft("guardian_attack")); -+ GoalKey ILLUSIONER_BLINDNESS_SPELL = GoalKey.of(Illusioner.class, NamespacedKey.minecraft("illusioner_blindness_spell")); -+ GoalKey ILLUSIONER_MIRROR_SPELL = GoalKey.of(Illusioner.class, NamespacedKey.minecraft("illusioner_mirror_spell")); -+ GoalKey LONG_DISTANCE_PATROL = GoalKey.of(Raider.class, NamespacedKey.minecraft("long_distance_patrol")); -+ GoalKey PHANTOM_ATTACK_PLAYER = GoalKey.of(Phantom.class, NamespacedKey.minecraft("phantom_attack_player")); -+ GoalKey PHANTOM_ATTACK_STRATEGY = GoalKey.of(Phantom.class, NamespacedKey.minecraft("phantom_attack_strategy")); -+ GoalKey PHANTOM_CIRCLE_AROUND_ANCHOR = GoalKey.of(Phantom.class, NamespacedKey.minecraft("phantom_circle_around_anchor")); -+ GoalKey PHANTOM_SWEEP_ATTACK = GoalKey.of(Phantom.class, NamespacedKey.minecraft("phantom_sweep_attack")); -+ GoalKey SHULKER_ATTACK = GoalKey.of(Shulker.class, NamespacedKey.minecraft("shulker_attack")); -+ GoalKey SHULKER_DEFENSE_ATTACK = GoalKey.of(Shulker.class, NamespacedKey.minecraft("shulker_defense_attack")); -+ GoalKey SHULKER_NEAREST_ATTACK = GoalKey.of(Shulker.class, NamespacedKey.minecraft("shulker_nearest_attack")); -+ GoalKey SHULKER_PEEK = GoalKey.of(Shulker.class, NamespacedKey.minecraft("shulker_peek")); -+ GoalKey SILVERFISH_MERGE_WITH_STONE = GoalKey.of(Silverfish.class, NamespacedKey.minecraft("silverfish_merge_with_stone")); -+ GoalKey SILVERFISH_WAKE_UP_FRIENDS = GoalKey.of(Silverfish.class, NamespacedKey.minecraft("silverfish_wake_up_friends")); -+ GoalKey SLIME_ATTACK = GoalKey.of(Slime.class, NamespacedKey.minecraft("slime_attack")); -+ GoalKey SLIME_FLOAT = GoalKey.of(Slime.class, NamespacedKey.minecraft("slime_float")); -+ GoalKey SLIME_KEEP_ON_JUMPING = GoalKey.of(Slime.class, NamespacedKey.minecraft("slime_keep_on_jumping")); -+ GoalKey SLIME_RANDOM_DIRECTION = GoalKey.of(Slime.class, NamespacedKey.minecraft("slime_random_direction")); -+ GoalKey SPELLCASTER_CASTING_SPELL = GoalKey.of(Spellcaster.class, NamespacedKey.minecraft("spellcaster_casting_spell")); -+ GoalKey SPIDER_ATTACK = GoalKey.of(Spider.class, NamespacedKey.minecraft("spider_attack")); -+ GoalKey SPIDER = GoalKey.of(Spider.class, NamespacedKey.minecraft("spider")); -+ GoalKey STRIDER_GO_TO_LAVA = GoalKey.of(Strider.class, NamespacedKey.minecraft("strider_go_to_lava")); -+ GoalKey VEX_CHARGE_ATTACK = GoalKey.of(Vex.class, NamespacedKey.minecraft("vex_charge_attack")); -+ GoalKey VEX_COPY_OWNER = GoalKey.of(Vex.class, NamespacedKey.minecraft("vex_copy_owner")); -+ GoalKey VEX_RANDOM_MOVE = GoalKey.of(Vex.class, NamespacedKey.minecraft("vex_random_move")); -+ GoalKey VINDICATOR_BREAK_DOOR = GoalKey.of(Mob.class, NamespacedKey.minecraft("vindicator_break_door")); -+ GoalKey VINDICATOR_JOHNNY_ATTACK = GoalKey.of(Vindicator.class, NamespacedKey.minecraft("vindicator_johnny_attack")); -+ GoalKey ZOMBIE_ATTACK_TURTLE_EGG = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack_turtle_egg")); -+ GoalKey WANDER_TO_POSITION = GoalKey.of(WanderingTrader.class, NamespacedKey.minecraft("wander_to_position")); -+ GoalKey HOLD_GROUND_ATTACK = GoalKey.of(Raider.class, NamespacedKey.minecraft("hold_ground_attack")); -+ GoalKey OBTAIN_RAID_LEADER_BANNER = GoalKey.of(Raider.class, NamespacedKey.minecraft("obtain_raid_leader_banner")); -+ GoalKey RAIDER_CELEBRATION = GoalKey.of(Raider.class, NamespacedKey.minecraft("raider_celebration")); -+ GoalKey RAIDER_MOVE_THROUGH_VILLAGE = GoalKey.of(Raider.class, NamespacedKey.minecraft("raider_move_through_village")); -+ GoalKey PARROT_WANDER = GoalKey.of(Creature.class, NamespacedKey.minecraft("parrot_wander")); -+ GoalKey CLIMB_ON_TOP_OF_POWDER_SNOW = GoalKey.of(Mob.class, NamespacedKey.minecraft("climb_on_top_of_powder_snow")); -+ GoalKey WOLF_PANIC = GoalKey.of(Wolf.class, NamespacedKey.minecraft("wolf_panic")); -+ -+ /** -+ * @deprecated removed in 1.20.2 -+ */ -+ @Deprecated GoalKey VINDICATOR_MELEE_ATTACK = GoalKey.of(Vindicator.class, NamespacedKey.minecraft("vindicator_melee_attack")); -+ /** -+ * @deprecated removed in 1.20.2 -+ */ -+ @Deprecated GoalKey RAVAGER_MELEE_ATTACK = GoalKey.of(Ravager.class, NamespacedKey.minecraft("ravager_melee_attack")); -+ /** -+ * @deprecated removed in 1.20.2 -+ */ -+ @Deprecated GoalKey EVIL_RABBIT_ATTACK = GoalKey.of(Rabbit.class, NamespacedKey.minecraft("evil_rabbit_attack")); -+ -+ /** -+ * @deprecated removed in 1.16 -+ */ -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey ANGER = GoalKey.of(PigZombie.class, NamespacedKey.minecraft("anger")); -+ /** -+ * @deprecated removed in 1.16 -+ */ -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey ANGER_OTHER = GoalKey.of(PigZombie.class, NamespacedKey.minecraft("anger_other")); -+ -+ // the constants below use spigot names, they no longer work -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey BLAZE_FIREBALL = GoalKey.of(Blaze.class, NamespacedKey.minecraft("blaze_fireball")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey TEMPT_CHANCE = GoalKey.of(Cat.class, NamespacedKey.minecraft("tempt_chance")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey DOLPHIN_PLAY_WITH_ITEMS = GoalKey.of(Dolphin.class, NamespacedKey.minecraft("dolphin_play_with_items")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey DROWNED_GOTO_BEACH = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_goto_beach")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey DROWNED_GOTO_WATER = GoalKey.of(Creature.class, NamespacedKey.minecraft("drowned_goto_water")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey ENDERMAN_PICKUP_BLOCK = GoalKey.of(Enderman.class, NamespacedKey.minecraft("enderman_pickup_block")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey ENDERMAN_PLACE_BLOCK = GoalKey.of(Enderman.class, NamespacedKey.minecraft("enderman_place_block")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey PLAYER_WHO_LOOKED_AT_TARGET = GoalKey.of(Enderman.class, NamespacedKey.minecraft("player_who_looked_at_target")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey EVOKER_CAST_SPELL = GoalKey.of(Evoker.class, NamespacedKey.minecraft("evoker_cast_spell")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey FOX_DEFEND_TRUSTED = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_defend_trusted")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey FOX_FACEPLANT = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_faceplant")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey FOX_PERCH_AND_SEARCH = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_perch_and_search")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey FOX_SLEEP = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_sleep")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey FOX_SEEK_SHELTER = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_seek_shelter")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey FOX_STALK_PREY = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_stalk_prey")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey GHAST_ATTACK_TARGET = GoalKey.of(Ghast.class, NamespacedKey.minecraft("ghast_attack_target")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey GHAST_IDLE_MOVE = GoalKey.of(Ghast.class, NamespacedKey.minecraft("ghast_idle_move")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey GHAST_MOVE_TOWARDS_TARGET = GoalKey.of(Ghast.class, NamespacedKey.minecraft("ghast_move_towards_target")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey SPELLCASTER_CAST_SPELL = GoalKey.of(Spellcaster.class, NamespacedKey.minecraft("spellcaster_cast_spell")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey LLAMATRADER_DEFENDED_WANDERING_TRADER = GoalKey.of(TraderLlama.class, NamespacedKey.minecraft("llamatrader_defended_wandering_trader")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey PANDA_HURT_BY_TARGET = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_hurt_by_target")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey POLARBEAR_ATTACK_PLAYERS = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polarbear_attack_players")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey POLARBEAR_HURT_BY = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polarbear_hurt_by")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey POLARBEAR_MELEE = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polarbear_melee")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey POLARBEAR_PANIC = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polarbear_panic")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey EAT_CARROTS = GoalKey.of(Rabbit.class, NamespacedKey.minecraft("eat_carrots")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey KILLER_RABBIT_MELEE_ATTACK = GoalKey.of(Rabbit.class, NamespacedKey.minecraft("killer_rabbit_melee_attack")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey RABBIT_AVOID_TARGET = GoalKey.of(Rabbit.class, NamespacedKey.minecraft("rabbit_avoid_target")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey RAIDER_HOLD_GROUND = GoalKey.of(Raider.class, NamespacedKey.minecraft("raider_hold_ground")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey RAIDER_OBTAIN_BANNER = GoalKey.of(Raider.class, NamespacedKey.minecraft("raider_obtain_banner")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey SHULKER_DEFENSE = GoalKey.of(Shulker.class, NamespacedKey.minecraft("shulker_defense")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey SHULKER_NEAREST = GoalKey.of(Shulker.class, NamespacedKey.minecraft("shulker_nearest")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey SILVERFISH_HIDE_IN_BLOCK = GoalKey.of(Silverfish.class, NamespacedKey.minecraft("silverfish_hide_in_block")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey SILVERFISH_WAKE_OTHERS = GoalKey.of(Silverfish.class, NamespacedKey.minecraft("silverfish_wake_others")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey SLIME_IDLE = GoalKey.of(Slime.class, NamespacedKey.minecraft("slime_idle")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey SLIME_NEAREST_PLAYER = GoalKey.of(Slime.class, NamespacedKey.minecraft("slime_nearest_player")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey SLIME_RANDOM_JUMP = GoalKey.of(Slime.class, NamespacedKey.minecraft("slime_random_jump")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey SPIDER_MELEE_ATTACK = GoalKey.of(Spider.class, NamespacedKey.minecraft("spider_melee_attack")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey SPIDER_NEAREST_ATTACKABLE_TARGET = GoalKey.of(Spider.class, NamespacedKey.minecraft("spider_nearest_attackable_target")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey SQUID = GoalKey.of(Squid.class, NamespacedKey.minecraft("squid")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey TURTLE_GOTO_WATER = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_goto_water")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey TURTLE_TEMPT = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_tempt")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey VEX_COPY_TARGET_OF_OWNER = GoalKey.of(Vex.class, NamespacedKey.minecraft("vex_copy_target_of_owner")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey VILLAGERTRADER_WANDER_TO_POSITION = GoalKey.of(WanderingTrader.class, NamespacedKey.minecraft("villagertrader_wander_to_position")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey ARROW_ATTACK = GoalKey.of(RangedEntity.class, NamespacedKey.minecraft("arrow_attack")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey AVOID_TARGET = GoalKey.of(Creature.class, NamespacedKey.minecraft("avoid_target")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey BOW_SHOOT = GoalKey.of(Monster.class, NamespacedKey.minecraft("bow_shoot")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey BREATH = GoalKey.of(Creature.class, NamespacedKey.minecraft("breath")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey CAT_SIT_ON_BED = GoalKey.of(Cat.class, NamespacedKey.minecraft("cat_sit_on_bed")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey CROSSBOW_ATTACK = GoalKey.of(Monster.class, NamespacedKey.minecraft("crossbow_attack")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey DOOR_OPEN = GoalKey.of(Mob.class, NamespacedKey.minecraft("door_open")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey EAT_TILE = GoalKey.of(Mob.class, NamespacedKey.minecraft("eat_tile")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey FISH_SCHOOL = GoalKey.of(Fish.class, NamespacedKey.minecraft("fish_school")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey FOLLOW_ENTITY = GoalKey.of(Mob.class, NamespacedKey.minecraft("follow_entity")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey HORSE_TRAP = GoalKey.of(SkeletonHorse.class, NamespacedKey.minecraft("horse_trap")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey HURT_BY_TARGET = GoalKey.of(Creature.class, NamespacedKey.minecraft("hurt_by_target")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey JUMP_ON_BLOCK = GoalKey.of(Cat.class, NamespacedKey.minecraft("jump_on_block")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey LEAP_AT_TARGET = GoalKey.of(Mob.class, NamespacedKey.minecraft("leap_at_target")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey LLAMA_FOLLOW = GoalKey.of(Llama.class, NamespacedKey.minecraft("llama_follow")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey MOVE_TOWARDS_TARGET = GoalKey.of(Creature.class, NamespacedKey.minecraft("move_towards_target")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey NEAREST_ATTACKABLE_TARGET = GoalKey.of(Mob.class, NamespacedKey.minecraft("nearest_attackable_target")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey NEAREST_ATTACKABLE_TARGET_WITCH = GoalKey.of(Raider.class, NamespacedKey.minecraft("nearest_attackable_target_witch")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey NEAREST_VILLAGE = GoalKey.of(Creature.class, NamespacedKey.minecraft("nearest_village")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey OWNER_HURT_BY_TARGET = GoalKey.of(Tameable.class, NamespacedKey.minecraft("owner_hurt_by_target")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey OWNER_HURT_TARGET = GoalKey.of(Tameable.class, NamespacedKey.minecraft("owner_hurt_target")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey PERCH = GoalKey.of(Parrot.class, NamespacedKey.minecraft("perch")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey RAID = GoalKey.of(Raider.class, NamespacedKey.minecraft("raid")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey RANDOM_FLY = GoalKey.of(Creature.class, NamespacedKey.minecraft("random_fly")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey RANDOM_LOOKAROUND = GoalKey.of(Mob.class, NamespacedKey.minecraft("random_lookaround")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey RANDOM_STROLL_LAND = GoalKey.of(Creature.class, NamespacedKey.minecraft("random_stroll_land")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey RANDOM_SWIM = GoalKey.of(Creature.class, NamespacedKey.minecraft("random_swim")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey RANDOM_TARGET_NON_TAMED = GoalKey.of(Tameable.class, NamespacedKey.minecraft("random_target_non_tamed")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey SIT = GoalKey.of(Tameable.class, NamespacedKey.minecraft("sit")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey STROLL_VILLAGE = GoalKey.of(Creature.class, NamespacedKey.minecraft("stroll_village")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey TAME = GoalKey.of(AbstractHorse.class, NamespacedKey.minecraft("tame")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey WATER = GoalKey.of(Creature.class, NamespacedKey.minecraft("water")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey WATER_JUMP = GoalKey.of(Dolphin.class, NamespacedKey.minecraft("water_jump")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey STROLL_VILLAGE_GOLEM = GoalKey.of(Creature.class, NamespacedKey.minecraft("stroll_village_golem")); -+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey UNIVERSAL_ANGER_RESET = GoalKey.of(Mob.class, NamespacedKey.minecraft("universal_anger_reset")); -+} diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/Bukkit.java diff --git a/patches/api/Missing-Entity-API.patch b/patches/api/Missing-Entity-API.patch index a117cee3bd..19359c1e51 100644 --- a/patches/api/Missing-Entity-API.patch +++ b/patches/api/Missing-Entity-API.patch @@ -10,19 +10,6 @@ Co-authored-by: SoSeDiK Co-authored-by: booky10 Co-authored-by: Amin -diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 ---- a/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java -+++ b/src/main/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java -@@ -0,0 +0,0 @@ public interface VanillaGoal extends Goal { - GoalKey FLEE_SUN = GoalKey.of(Creature.class, NamespacedKey.minecraft("flee_sun")); - GoalKey FLOAT = GoalKey.of(Mob.class, NamespacedKey.minecraft("float")); - GoalKey FOLLOW_BOAT = GoalKey.of(Creature.class, NamespacedKey.minecraft("follow_boat")); -- GoalKey FOLLOW_FLOCK_LEADER = GoalKey.of(Fish.class, NamespacedKey.minecraft("follow_flock_leader")); -+ GoalKey FOLLOW_FLOCK_LEADER = GoalKey.of(io.papermc.paper.entity.SchoolableFish.class, NamespacedKey.minecraft("follow_flock_leader")); - GoalKey FOLLOW_MOB = GoalKey.of(Mob.class, NamespacedKey.minecraft("follow_mob")); - GoalKey FOLLOW_OWNER = GoalKey.of(Tameable.class, NamespacedKey.minecraft("follow_owner")); - GoalKey FOLLOW_PARENT = GoalKey.of(Animals.class, NamespacedKey.minecraft("follow_parent")); diff --git a/src/main/java/io/papermc/paper/entity/SchoolableFish.java b/src/main/java/io/papermc/paper/entity/SchoolableFish.java new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 diff --git a/patches/server/Implement-Mob-Goal-API.patch b/patches/server/Implement-Mob-Goal-API.patch index 2c45cf35a0..9a86d4fe20 100644 --- a/patches/server/Implement-Mob-Goal-API.patch +++ b/patches/server/Implement-Mob-Goal-API.patch @@ -809,115 +809,3 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } // Paper end } -diff --git a/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java b/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java -new file mode 100644 -index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 ---- /dev/null -+++ b/src/test/java/com/destroystokyo/paper/entity/ai/VanillaMobGoalTest.java -@@ -0,0 +0,0 @@ -+package com.destroystokyo.paper.entity.ai; -+ -+import io.github.classgraph.ClassGraph; -+import io.github.classgraph.ScanResult; -+import java.lang.reflect.Field; -+import java.lang.reflect.Modifier; -+import java.util.ArrayList; -+import java.util.Collections; -+import java.util.List; -+import java.util.stream.Collectors; -+import org.bukkit.entity.Mob; -+import org.junit.jupiter.api.Test; -+ -+import static org.junit.jupiter.api.Assertions.assertNotEquals; -+import static org.junit.jupiter.api.Assertions.fail; -+ -+public class VanillaMobGoalTest { -+ -+ @Test -+ public void testKeys() { -+ List> deprecated = new ArrayList<>(); -+ List> keys = new ArrayList<>(); -+ for (Field field : VanillaGoal.class.getFields()) { -+ if (field.getType().equals(GoalKey.class)) { -+ try { -+ GoalKey goalKey = (GoalKey) field.get(null); -+ if (field.getAnnotation(Deprecated.class) != null) { -+ deprecated.add(goalKey); -+ } else { -+ keys.add(goalKey); -+ } -+ } catch (IllegalAccessException e) { -+ System.out.println("Skipping " + field.getName() + ": " + e.getMessage()); -+ } -+ } -+ } -+ -+ List> classes; -+ try (ScanResult scanResult = new ClassGraph().enableAllInfo().whitelistPackages("net.minecraft").scan()) { -+ classes = scanResult.getSubclasses(net.minecraft.world.entity.ai.goal.Goal.class.getName()).loadClasses(); -+ } -+ -+ List> vanillaNames = classes.stream() -+ .filter(VanillaMobGoalTest::hasNoEnclosingClass) -+ .filter(clazz -> !Modifier.isAbstract(clazz.getModifiers())) -+ .filter(clazz -> !net.minecraft.world.entity.ai.goal.WrappedGoal.class.equals(clazz)) // TODO - properly fix -+ .map(goalClass -> MobGoalHelper.getKey((Class) goalClass)) -+ .collect(Collectors.toList()); -+ -+ List> missingFromAPI = new ArrayList<>(vanillaNames); -+ missingFromAPI.removeAll(keys); -+ missingFromAPI.removeIf(k -> MobGoalHelper.ignored.contains(k.getNamespacedKey().getKey())); -+ List> missingFromVanilla = new ArrayList<>(keys); -+ missingFromVanilla.removeAll(vanillaNames); -+ -+ boolean shouldFail = false; -+ if (missingFromAPI.size() != 0) { -+ System.out.println("Missing from API: "); -+ for (GoalKey key : missingFromAPI) { -+ System.out.println("GoalKey<" + key.getEntityClass().getSimpleName() + "> " + key.getNamespacedKey().getKey().toUpperCase() + -+ " = GoalKey.of(" + key.getEntityClass().getSimpleName() + ".class, NamespacedKey.minecraft(\"" + key.getNamespacedKey().getKey() + "\"));"); -+ } -+ shouldFail = true; -+ } -+ if (missingFromVanilla.size() != 0) { -+ System.out.println("Missing from vanilla: "); -+ missingFromVanilla.forEach(System.out::println); -+ shouldFail = true; -+ } -+ -+ if (deprecated.size() != 0) { -+ System.out.println("Deprecated (might want to remove them at some point): "); -+ deprecated.forEach(System.out::println); -+ } -+ -+ if (shouldFail) { -+ fail("See above"); -+ } -+ } -+ -+ private static boolean hasNoEnclosingClass(Class clazz) { -+ return clazz.getEnclosingClass() == null || hasNoEnclosingClass(clazz.getSuperclass()); -+ } -+ -+ @Test -+ public void testBukkitMap() { -+ List> classes; -+ try (ScanResult scanResult = new ClassGraph().enableAllInfo().whitelistPackages("net.minecraft.world.entity").scan()) { -+ classes = scanResult.getSubclasses("net.minecraft.world.entity.Mob").loadClasses(); -+ } -+ assertNotEquals(Collections.emptyList(), classes, "There are supposed to be more than 0 entity types!"); -+ -+ boolean shouldFail = false; -+ for (Class nmsClass : classes) { -+ Class bukkitClass = MobGoalHelper.toBukkitClass((Class) nmsClass); -+ if (bukkitClass == null) { -+ shouldFail = true; -+ System.out.println("Missing bukkitMap.put(" + nmsClass.getSimpleName() + ".class, " + nmsClass.getSimpleName().replace("Entity", "") + ".class);"); -+ } -+ } -+ -+ if (shouldFail) { -+ fail("See above"); -+ } -+ } -+}