diff options
author | Owen <[email protected]> | 2024-01-15 14:36:10 -0500 |
---|---|---|
committer | GitHub <[email protected]> | 2024-01-15 14:36:10 -0500 |
commit | 848a3960f6056461b7edfeefa717bc18bbc1172a (patch) | |
tree | 4e23273df7acc58b3ef22880dce7fca9b150f396 /paper-api-generator | |
parent | 0ef59845bf75aac7d8f0d03003a2f4a3c82b918d (diff) | |
download | Paper-848a3960f6056461b7edfeefa717bc18bbc1172a.tar.gz Paper-848a3960f6056461b7edfeefa717bc18bbc1172a.zip |
Add mob goal generator (#9980)
Diffstat (limited to 'paper-api-generator')
13 files changed, 1915 insertions, 102 deletions
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<T extends Mob> extends Goal<T> { + GoalKey<AbstractHorse> RANDOM_STAND = create("random_stand", AbstractHorse.class); + + GoalKey<AbstractHorse> RUN_AROUND_LIKE_CRAZY = create("run_around_like_crazy", AbstractHorse.class); + + GoalKey<AbstractSkeleton> ABSTRACT_SKELETON_MELEE = create("abstract_skeleton_melee", AbstractSkeleton.class); + + GoalKey<AbstractVillager> LOOK_AT_TRADING_PLAYER = create("look_at_trading_player", AbstractVillager.class); + + GoalKey<AbstractVillager> TRADE_WITH_PLAYER = create("trade_with_player", AbstractVillager.class); + + GoalKey<Animals> BREED = create("breed", Animals.class); + + GoalKey<Animals> FOLLOW_PARENT = create("follow_parent", Animals.class); + + GoalKey<Bee> BEE_ATTACK = create("bee_attack", Bee.class); + + GoalKey<Bee> BEE_BECOME_ANGRY = create("bee_become_angry", Bee.class); + + GoalKey<Bee> BEE_ENTER_HIVE = create("bee_enter_hive", Bee.class); + + GoalKey<Bee> BEE_GO_TO_HIVE = create("bee_go_to_hive", Bee.class); + + GoalKey<Bee> BEE_GO_TO_KNOWN_FLOWER = create("bee_go_to_known_flower", Bee.class); + + GoalKey<Bee> BEE_GROW_CROP = create("bee_grow_crop", Bee.class); + + GoalKey<Bee> BEE_HURT_BY_OTHER = create("bee_hurt_by_other", Bee.class); + + GoalKey<Bee> BEE_LOCATE_HIVE = create("bee_locate_hive", Bee.class); + + GoalKey<Bee> BEE_POLLINATE = create("bee_pollinate", Bee.class); + + GoalKey<Bee> BEE_WANDER = create("bee_wander", Bee.class); + + GoalKey<Blaze> BLAZE_ATTACK = create("blaze_attack", Blaze.class); + + GoalKey<Cat> CAT_AVOID_ENTITY = create("cat_avoid_entity", Cat.class); + + GoalKey<Cat> CAT_LIE_ON_BED = create("cat_lie_on_bed", Cat.class); + + GoalKey<Cat> CAT_RELAX_ON_OWNER = create("cat_relax_on_owner", Cat.class); + + GoalKey<Cat> CAT_SIT_ON_BLOCK = create("cat_sit_on_block", Cat.class); + + GoalKey<Cat> CAT_TEMPT = create("cat_tempt", Cat.class); + + GoalKey<Creature> AVOID_ENTITY = create("avoid_entity", Creature.class); + + GoalKey<Creature> BREATH_AIR = create("breath_air", Creature.class); + + GoalKey<Creature> DROWNED_GO_TO_WATER = create("drowned_go_to_water", Creature.class); + + GoalKey<Creature> FLEE_SUN = create("flee_sun", Creature.class); + + GoalKey<Creature> FOLLOW_BOAT = create("follow_boat", Creature.class); + + GoalKey<Creature> GOLEM_RANDOM_STROLL_IN_VILLAGE = create("golem_random_stroll_in_village", Creature.class); + + GoalKey<Creature> HURT_BY = create("hurt_by", Creature.class); + + GoalKey<Creature> MELEE_ATTACK = create("melee_attack", Creature.class); + + GoalKey<Creature> MOVE_BACK_TO_VILLAGE = create("move_back_to_village", Creature.class); + + GoalKey<Creature> MOVE_THROUGH_VILLAGE = create("move_through_village", Creature.class); + + GoalKey<Creature> MOVE_TOWARDS = create("move_towards", Creature.class); + + GoalKey<Creature> MOVE_TOWARDS_RESTRICTION = create("move_towards_restriction", Creature.class); + + GoalKey<Creature> PANIC = create("panic", Creature.class); + + GoalKey<Creature> PARROT_WANDER = create("parrot_wander", Creature.class); + + GoalKey<Creature> RANDOM_STROLL = create("random_stroll", Creature.class); + + GoalKey<Creature> RANDOM_SWIMMING = create("random_swimming", Creature.class); + + GoalKey<Creature> REMOVE_BLOCK = create("remove_block", Creature.class); + + GoalKey<Creature> RESTRICT_SUN = create("restrict_sun", Creature.class); + + GoalKey<Creature> STROLL_THROUGH_VILLAGE = create("stroll_through_village", Creature.class); + + GoalKey<Creature> TEMPT = create("tempt", Creature.class); + + GoalKey<Creature> TRY_FIND_WATER = create("try_find_water", Creature.class); + + GoalKey<Creature> WATER_AVOIDING_RANDOM_FLYING = create("water_avoiding_random_flying", Creature.class); + + GoalKey<Creature> WATER_AVOIDING_RANDOM_STROLL = create("water_avoiding_random_stroll", Creature.class); + + GoalKey<Creeper> SWELL = create("swell", Creeper.class); + + GoalKey<Dolphin> DOLPHIN_JUMP = create("dolphin_jump", Dolphin.class); + + GoalKey<Dolphin> DOLPHIN_SWIM_TO_TREASURE = create("dolphin_swim_to_treasure", Dolphin.class); + + GoalKey<Dolphin> DOLPHIN_SWIM_WITH_PLAYER = create("dolphin_swim_with_player", Dolphin.class); + + GoalKey<Dolphin> PLAY_WITH_ITEMS = create("play_with_items", Dolphin.class); + + GoalKey<Drowned> DROWNED_ATTACK = create("drowned_attack", Drowned.class); + + GoalKey<Drowned> DROWNED_GO_TO_BEACH = create("drowned_go_to_beach", Drowned.class); + + GoalKey<Drowned> DROWNED_SWIM_UP = create("drowned_swim_up", Drowned.class); + + GoalKey<Enderman> ENDERMAN_FREEZE_WHEN_LOOKED_AT = create("enderman_freeze_when_looked_at", Enderman.class); + + GoalKey<Enderman> ENDERMAN_LEAVE_BLOCK = create("enderman_leave_block", Enderman.class); + + GoalKey<Enderman> ENDERMAN_LOOK_FOR_PLAYER = create("enderman_look_for_player", Enderman.class); + + GoalKey<Enderman> ENDERMAN_TAKE_BLOCK = create("enderman_take_block", Enderman.class); + + GoalKey<Evoker> EVOKER_ATTACK_SPELL = create("evoker_attack_spell", Evoker.class); + + GoalKey<Evoker> EVOKER_CASTING_SPELL = create("evoker_casting_spell", Evoker.class); + + GoalKey<Evoker> EVOKER_SUMMON_SPELL = create("evoker_summon_spell", Evoker.class); + + GoalKey<Evoker> EVOKER_WOLOLO_SPELL = create("evoker_wololo_spell", Evoker.class); + + GoalKey<Fish> FISH_SWIM = create("fish_swim", Fish.class); + + GoalKey<Fox> DEFEND_TRUSTED = create("defend_trusted", Fox.class); + + GoalKey<Fox> FACEPLANT = create("faceplant", Fox.class); + + GoalKey<Fox> FOX_BREED = create("fox_breed", Fox.class); + + GoalKey<Fox> FOX_EAT_BERRIES = create("fox_eat_berries", Fox.class); + + GoalKey<Fox> FOX_FLOAT = create("fox_float", Fox.class); + + GoalKey<Fox> FOX_FOLLOW_PARENT = create("fox_follow_parent", Fox.class); + + GoalKey<Fox> FOX_LOOK_AT_PLAYER = create("fox_look_at_player", Fox.class); + + GoalKey<Fox> FOX_MELEE_ATTACK = create("fox_melee_attack", Fox.class); + + GoalKey<Fox> FOX_PANIC = create("fox_panic", Fox.class); + + GoalKey<Fox> FOX_POUNCE = create("fox_pounce", Fox.class); + + GoalKey<Fox> FOX_SEARCH_FOR_ITEMS = create("fox_search_for_items", Fox.class); + + GoalKey<Fox> FOX_STROLL_THROUGH_VILLAGE = create("fox_stroll_through_village", Fox.class); + + GoalKey<Fox> PERCH_AND_SEARCH = create("perch_and_search", Fox.class); + + GoalKey<Fox> SEEK_SHELTER = create("seek_shelter", Fox.class); + + GoalKey<Fox> SLEEP = create("sleep", Fox.class); + + GoalKey<Fox> STALK_PREY = create("stalk_prey", Fox.class); + + GoalKey<Ghast> GHAST_LOOK = create("ghast_look", Ghast.class); + + GoalKey<Ghast> GHAST_SHOOT_FIREBALL = create("ghast_shoot_fireball", Ghast.class); + + GoalKey<Ghast> RANDOM_FLOAT_AROUND = create("random_float_around", Ghast.class); + + GoalKey<Guardian> GUARDIAN_ATTACK = create("guardian_attack", Guardian.class); + + GoalKey<Illager> RAIDER_OPEN_DOOR = create("raider_open_door", Illager.class); + + GoalKey<Illusioner> ILLUSIONER_BLINDNESS_SPELL = create("illusioner_blindness_spell", Illusioner.class); + + GoalKey<Illusioner> ILLUSIONER_MIRROR_SPELL = create("illusioner_mirror_spell", Illusioner.class); + + GoalKey<IronGolem> DEFEND_VILLAGE = create("defend_village", IronGolem.class); + + GoalKey<IronGolem> OFFER_FLOWER = create("offer_flower", IronGolem.class); + + GoalKey<Llama> LLAMA_ATTACK_WOLF = create("llama_attack_wolf", Llama.class); + + GoalKey<Llama> LLAMA_FOLLOW_CARAVAN = create("llama_follow_caravan", Llama.class); + + GoalKey<Llama> LLAMA_HURT_BY = create("llama_hurt_by", Llama.class); + + GoalKey<Llama> TRADER_LLAMA_DEFEND_WANDERING_TRADER = create("trader_llama_defend_wandering_trader", Llama.class); + + GoalKey<Mob> BREAK_DOOR = create("break_door", Mob.class); + + GoalKey<Mob> CLIMB_ON_TOP_OF_POWDER_SNOW = create("climb_on_top_of_powder_snow", Mob.class); + + GoalKey<Mob> EAT_BLOCK = create("eat_block", Mob.class); + + GoalKey<Mob> FLOAT = create("float", Mob.class); + + GoalKey<Mob> FOLLOW_MOB = create("follow_mob", Mob.class); + + GoalKey<Mob> INTERACT = create("interact", Mob.class); + + GoalKey<Mob> LEAP_AT = create("leap_at", Mob.class); + + GoalKey<Mob> LOOK_AT_PLAYER = create("look_at_player", Mob.class); + + GoalKey<Mob> NEAREST_ATTACKABLE = create("nearest_attackable", Mob.class); + + GoalKey<Mob> OCELOT_ATTACK = create("ocelot_attack", Mob.class); + + GoalKey<Mob> OPEN_DOOR = create("open_door", Mob.class); + + GoalKey<Mob> RANDOM_LOOK_AROUND = create("random_look_around", Mob.class); + + GoalKey<Mob> RESET_UNIVERSAL_ANGER = create("reset_universal_anger", Mob.class); + + GoalKey<Mob> USE_ITEM = create("use_item", Mob.class); + + GoalKey<Mob> VINDICATOR_BREAK_DOOR = create("vindicator_break_door", Mob.class); + + GoalKey<Monster> RANGED_BOW_ATTACK = create("ranged_bow_attack", Monster.class); + + GoalKey<Monster> RANGED_CROSSBOW_ATTACK = create("ranged_crossbow_attack", Monster.class); + + GoalKey<Ocelot> OCELOT_AVOID_ENTITY = create("ocelot_avoid_entity", Ocelot.class); + + GoalKey<Ocelot> OCELOT_TEMPT = create("ocelot_tempt", Ocelot.class); + + GoalKey<Panda> PANDA_ATTACK = create("panda_attack", Panda.class); + + GoalKey<Panda> PANDA_AVOID = create("panda_avoid", Panda.class); + + GoalKey<Panda> PANDA_BREED = create("panda_breed", Panda.class); + + GoalKey<Panda> PANDA_HURT_BY = create("panda_hurt_by", Panda.class); + + GoalKey<Panda> PANDA_LIE_ON_BACK = create("panda_lie_on_back", Panda.class); + + GoalKey<Panda> PANDA_LOOK_AT_PLAYER = create("panda_look_at_player", Panda.class); + + GoalKey<Panda> PANDA_PANIC = create("panda_panic", Panda.class); + + GoalKey<Panda> PANDA_ROLL = create("panda_roll", Panda.class); + + GoalKey<Panda> PANDA_SIT = create("panda_sit", Panda.class); + + GoalKey<Panda> PANDA_SNEEZE = create("panda_sneeze", Panda.class); + + GoalKey<Parrot> LAND_ON_OWNERS_SHOULDER = create("land_on_owners_shoulder", Parrot.class); + + GoalKey<Phantom> PHANTOM_ATTACK_PLAYER = create("phantom_attack_player", Phantom.class); + + GoalKey<Phantom> PHANTOM_ATTACK_STRATEGY = create("phantom_attack_strategy", Phantom.class); + + GoalKey<Phantom> PHANTOM_CIRCLE_AROUND_ANCHOR = create("phantom_circle_around_anchor", Phantom.class); + + GoalKey<Phantom> PHANTOM_SWEEP_ATTACK = create("phantom_sweep_attack", Phantom.class); + + GoalKey<PolarBear> POLAR_BEAR_ATTACK_PLAYERS = create("polar_bear_attack_players", PolarBear.class); + + GoalKey<PolarBear> POLAR_BEAR_HURT_BY = create("polar_bear_hurt_by", PolarBear.class); + + GoalKey<PolarBear> POLAR_BEAR_MELEE_ATTACK = create("polar_bear_melee_attack", PolarBear.class); + + GoalKey<PolarBear> POLAR_BEAR_PANIC = create("polar_bear_panic", PolarBear.class); + + GoalKey<PufferFish> PUFFERFISH_PUFF = create("pufferfish_puff", PufferFish.class); + + GoalKey<Rabbit> RABBIT_AVOID_ENTITY = create("rabbit_avoid_entity", Rabbit.class); + + GoalKey<Rabbit> RABBIT_PANIC = create("rabbit_panic", Rabbit.class); + + GoalKey<Rabbit> RAID_GARDEN = create("raid_garden", Rabbit.class); + + GoalKey<Raider> HOLD_GROUND_ATTACK = create("hold_ground_attack", Raider.class); + + GoalKey<Raider> LONG_DISTANCE_PATROL = create("long_distance_patrol", Raider.class); + + GoalKey<Raider> NEAREST_ATTACKABLE_WITCH = create("nearest_attackable_witch", Raider.class); + + GoalKey<Raider> NEAREST_HEALABLE_RAIDER = create("nearest_healable_raider", Raider.class); + + GoalKey<Raider> OBTAIN_RAID_LEADER_BANNER = create("obtain_raid_leader_banner", Raider.class); + + GoalKey<Raider> PATHFIND_TO_RAID = create("pathfind_to_raid", Raider.class); + + GoalKey<Raider> RAIDER_CELEBRATION = create("raider_celebration", Raider.class); + + GoalKey<Raider> RAIDER_MOVE_THROUGH_VILLAGE = create("raider_move_through_village", Raider.class); + + GoalKey<RangedEntity> DROWNED_TRIDENT_ATTACK = create("drowned_trident_attack", RangedEntity.class); + + GoalKey<RangedEntity> RANGED_ATTACK = create("ranged_attack", RangedEntity.class); + + GoalKey<SchoolableFish> FOLLOW_FLOCK_LEADER = create("follow_flock_leader", SchoolableFish.class); + + GoalKey<Shulker> SHULKER_ATTACK = create("shulker_attack", Shulker.class); + + GoalKey<Shulker> SHULKER_DEFENSE_ATTACK = create("shulker_defense_attack", Shulker.class); + + GoalKey<Shulker> SHULKER_NEAREST_ATTACK = create("shulker_nearest_attack", Shulker.class); + + GoalKey<Shulker> SHULKER_PEEK = create("shulker_peek", Shulker.class); + + GoalKey<Silverfish> SILVERFISH_MERGE_WITH_STONE = create("silverfish_merge_with_stone", Silverfish.class); + + GoalKey<Silverfish> SILVERFISH_WAKE_UP_FRIENDS = create("silverfish_wake_up_friends", Silverfish.class); + + GoalKey<SkeletonHorse> SKELETON_TRAP = create("skeleton_trap", SkeletonHorse.class); + + GoalKey<Slime> SLIME_ATTACK = create("slime_attack", Slime.class); + + GoalKey<Slime> SLIME_FLOAT = create("slime_float", Slime.class); + + GoalKey<Slime> SLIME_KEEP_ON_JUMPING = create("slime_keep_on_jumping", Slime.class); + + GoalKey<Slime> SLIME_RANDOM_DIRECTION = create("slime_random_direction", Slime.class); + + GoalKey<Spellcaster> SPELLCASTER_CASTING_SPELL = create("spellcaster_casting_spell", Spellcaster.class); + + GoalKey<Spider> SPIDER = create("spider", Spider.class); + + GoalKey<Spider> SPIDER_ATTACK = create("spider_attack", Spider.class); + + GoalKey<Squid> SQUID_FLEE = create("squid_flee", Squid.class); + + GoalKey<Squid> SQUID_RANDOM_MOVEMENT = create("squid_random_movement", Squid.class); + + GoalKey<Strider> STRIDER_GO_TO_LAVA = create("strider_go_to_lava", Strider.class); + + GoalKey<Tameable> FOLLOW_OWNER = create("follow_owner", Tameable.class); + + GoalKey<Tameable> NON_TAME_RANDOM = create("non_tame_random", Tameable.class); + + GoalKey<Tameable> OWNER_HURT = create("owner_hurt", Tameable.class); + + GoalKey<Tameable> OWNER_HURT_BY = create("owner_hurt_by", Tameable.class); + + GoalKey<Tameable> SIT_WHEN_ORDERED_TO = create("sit_when_ordered_to", Tameable.class); + + GoalKey<Turtle> TURTLE_BREED = create("turtle_breed", Turtle.class); + + GoalKey<Turtle> TURTLE_GO_HOME = create("turtle_go_home", Turtle.class); + + GoalKey<Turtle> TURTLE_GO_TO_WATER = create("turtle_go_to_water", Turtle.class); + + GoalKey<Turtle> TURTLE_LAY_EGG = create("turtle_lay_egg", Turtle.class); + + GoalKey<Turtle> TURTLE_PANIC = create("turtle_panic", Turtle.class); + + GoalKey<Turtle> TURTLE_RANDOM_STROLL = create("turtle_random_stroll", Turtle.class); + + GoalKey<Turtle> TURTLE_TRAVEL = create("turtle_travel", Turtle.class); + + GoalKey<Vex> VEX_CHARGE_ATTACK = create("vex_charge_attack", Vex.class); + + GoalKey<Vex> VEX_COPY_OWNER = create("vex_copy_owner", Vex.class); + + GoalKey<Vex> VEX_RANDOM_MOVE = create("vex_random_move", Vex.class); + + GoalKey<Vindicator> VINDICATOR_JOHNNY_ATTACK = create("vindicator_johnny_attack", Vindicator.class); + + GoalKey<WanderingTrader> WANDER_TO_POSITION = create("wander_to_position", WanderingTrader.class); + + GoalKey<Wither> WITHER_DO_NOTHING = create("wither_do_nothing", Wither.class); + + GoalKey<Wolf> BEG = create("beg", Wolf.class); + + GoalKey<Wolf> WOLF_AVOID_ENTITY = create("wolf_avoid_entity", Wolf.class); + + GoalKey<Wolf> WOLF_PANIC = create("wolf_panic", Wolf.class); + + GoalKey<Zombie> ZOMBIE_ATTACK = create("zombie_attack", Zombie.class); + + GoalKey<Zombie> ZOMBIE_ATTACK_TURTLE_EGG = create("zombie_attack_turtle_egg", Zombie.class); + + /** + * Removed in 1.20.2 + */ + @Deprecated( + since = "1.20.2" + ) + GoalKey<Vindicator> VINDICATOR_MELEE_ATTACK = create("vindicator_melee_attack", Vindicator.class); + + /** + * Removed in 1.20.2 + */ + @Deprecated( + since = "1.20.2" + ) + GoalKey<Ravager> RAVAGER_MELEE_ATTACK = create("ravager_melee_attack", Ravager.class); + + /** + * Removed in 1.20.2 + */ + @Deprecated( + since = "1.20.2" + ) + GoalKey<Rabbit> 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<PigZombie> ANGER = create("anger", PigZombie.class); + + /** + * Removed in 1.16 + */ + @Deprecated( + forRemoval = true, + since = "1.16" + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<PigZombie> ANGER_OTHER = create("anger_other", PigZombie.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Blaze> BLAZE_FIREBALL = create("blaze_fireball", Blaze.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Cat> TEMPT_CHANCE = create("tempt_chance", Cat.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Dolphin> DOLPHIN_PLAY_WITH_ITEMS = create("dolphin_play_with_items", Dolphin.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Drowned> DROWNED_GOTO_BEACH = create("drowned_goto_beach", Drowned.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Creature> DROWNED_GOTO_WATER = create("drowned_goto_water", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Enderman> ENDERMAN_PICKUP_BLOCK = create("enderman_pickup_block", Enderman.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Enderman> ENDERMAN_PLACE_BLOCK = create("enderman_place_block", Enderman.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Enderman> PLAYER_WHO_LOOKED_AT_TARGET = create("player_who_looked_at_target", Enderman.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Evoker> EVOKER_CAST_SPELL = create("evoker_cast_spell", Evoker.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Fox> FOX_DEFEND_TRUSTED = create("fox_defend_trusted", Fox.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Fox> FOX_FACEPLANT = create("fox_faceplant", Fox.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Fox> FOX_PERCH_AND_SEARCH = create("fox_perch_and_search", Fox.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Fox> FOX_SLEEP = create("fox_sleep", Fox.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Fox> FOX_SEEK_SHELTER = create("fox_seek_shelter", Fox.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Fox> FOX_STALK_PREY = create("fox_stalk_prey", Fox.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Ghast> GHAST_ATTACK_TARGET = create("ghast_attack_target", Ghast.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Ghast> GHAST_IDLE_MOVE = create("ghast_idle_move", Ghast.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Ghast> GHAST_MOVE_TOWARDS_TARGET = create("ghast_move_towards_target", Ghast.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Spellcaster> SPELLCASTER_CAST_SPELL = create("spellcaster_cast_spell", Spellcaster.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<TraderLlama> LLAMATRADER_DEFENDED_WANDERING_TRADER = create("llamatrader_defended_wandering_trader", TraderLlama.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Panda> PANDA_HURT_BY_TARGET = create("panda_hurt_by_target", Panda.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<PolarBear> POLARBEAR_ATTACK_PLAYERS = create("polarbear_attack_players", PolarBear.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<PolarBear> POLARBEAR_HURT_BY = create("polarbear_hurt_by", PolarBear.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<PolarBear> POLARBEAR_MELEE = create("polarbear_melee", PolarBear.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<PolarBear> POLARBEAR_PANIC = create("polarbear_panic", PolarBear.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Rabbit> EAT_CARROTS = create("eat_carrots", Rabbit.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Rabbit> KILLER_RABBIT_MELEE_ATTACK = create("killer_rabbit_melee_attack", Rabbit.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Rabbit> RABBIT_AVOID_TARGET = create("rabbit_avoid_target", Rabbit.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Raider> RAIDER_HOLD_GROUND = create("raider_hold_ground", Raider.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Raider> RAIDER_OBTAIN_BANNER = create("raider_obtain_banner", Raider.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Shulker> SHULKER_DEFENSE = create("shulker_defense", Shulker.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Shulker> SHULKER_NEAREST = create("shulker_nearest", Shulker.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Silverfish> SILVERFISH_HIDE_IN_BLOCK = create("silverfish_hide_in_block", Silverfish.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Silverfish> SILVERFISH_WAKE_OTHERS = create("silverfish_wake_others", Silverfish.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Slime> SLIME_IDLE = create("slime_idle", Slime.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Slime> SLIME_NEAREST_PLAYER = create("slime_nearest_player", Slime.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Slime> SLIME_RANDOM_JUMP = create("slime_random_jump", Slime.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Spider> SPIDER_MELEE_ATTACK = create("spider_melee_attack", Spider.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Spider> SPIDER_NEAREST_ATTACKABLE_TARGET = create("spider_nearest_attackable_target", Spider.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Squid> SQUID = create("squid", Squid.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Turtle> TURTLE_GOTO_WATER = create("turtle_goto_water", Turtle.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Turtle> TURTLE_TEMPT = create("turtle_tempt", Turtle.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Vex> VEX_COPY_TARGET_OF_OWNER = create("vex_copy_target_of_owner", Vex.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<WanderingTrader> VILLAGERTRADER_WANDER_TO_POSITION = create("villagertrader_wander_to_position", WanderingTrader.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<RangedEntity> ARROW_ATTACK = create("arrow_attack", RangedEntity.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Creature> AVOID_TARGET = create("avoid_target", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Monster> BOW_SHOOT = create("bow_shoot", Monster.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Creature> BREATH = create("breath", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Cat> CAT_SIT_ON_BED = create("cat_sit_on_bed", Cat.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Monster> CROSSBOW_ATTACK = create("crossbow_attack", Monster.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Mob> DOOR_OPEN = create("door_open", Mob.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Mob> EAT_TILE = create("eat_tile", Mob.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Fish> FISH_SCHOOL = create("fish_school", Fish.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Mob> FOLLOW_ENTITY = create("follow_entity", Mob.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<SkeletonHorse> HORSE_TRAP = create("horse_trap", SkeletonHorse.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Creature> HURT_BY_TARGET = create("hurt_by_target", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Cat> JUMP_ON_BLOCK = create("jump_on_block", Cat.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Mob> LEAP_AT_TARGET = create("leap_at_target", Mob.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Llama> LLAMA_FOLLOW = create("llama_follow", Llama.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Creature> MOVE_TOWARDS_TARGET = create("move_towards_target", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Mob> NEAREST_ATTACKABLE_TARGET = create("nearest_attackable_target", Mob.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Raider> NEAREST_ATTACKABLE_TARGET_WITCH = create("nearest_attackable_target_witch", Raider.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Creature> NEAREST_VILLAGE = create("nearest_village", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Tameable> OWNER_HURT_BY_TARGET = create("owner_hurt_by_target", Tameable.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Tameable> OWNER_HURT_TARGET = create("owner_hurt_target", Tameable.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Parrot> PERCH = create("perch", Parrot.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Raider> RAID = create("raid", Raider.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Creature> RANDOM_FLY = create("random_fly", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Mob> RANDOM_LOOKAROUND = create("random_lookaround", Mob.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Creature> RANDOM_STROLL_LAND = create("random_stroll_land", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Creature> RANDOM_SWIM = create("random_swim", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Tameable> RANDOM_TARGET_NON_TAMED = create("random_target_non_tamed", Tameable.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Tameable> SIT = create("sit", Tameable.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Creature> STROLL_VILLAGE = create("stroll_village", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<AbstractHorse> TAME = create("tame", AbstractHorse.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Creature> WATER = create("water", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Dolphin> WATER_JUMP = create("water_jump", Dolphin.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Creature> STROLL_VILLAGE_GOLEM = create("stroll_village_golem", Creature.class); + + @Deprecated( + forRemoval = true + ) + @ApiStatus.ScheduledForRemoval( + inVersion = "1.21" + ) + GoalKey<Mob> 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 <T, A> SourceGenerator simpleKey(final String className, final Class<A> apiType, final ResourceKey<? extends Registry<T>> registryKey, final RegistryKey<A> 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<SourceGenerator> 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 <T, A> SourceGenerator simpleKey(final String className, final Class<A> apiType, final ResourceKey<? extends Registry<T>> registryKey, final RegistryKey<A> 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<AnnotationSpec> 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<T, A> implements SourceGenerator { +public class GeneratedKeyType<T, A> extends SimpleGenerator { private static final Map<ResourceKey<? extends Registry<?>>, 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<T, A> 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<T, A> implements SourceGenerator { @return a new typed key """; - private final String keysClassName; private final Class<A> apiType; - private final String pkg; private final ResourceKey<? extends Registry<T>> registryKey; private final RegistryKey<A> apiRegistryKey; private final boolean publicCreateKeyMethod; public GeneratedKeyType(final String keysClassName, final Class<A> apiType, final String pkg, final ResourceKey<? extends Registry<T>> registryKey, final RegistryKey<A> 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<T, A> 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<T, A> 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<T, A> 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 = { + //<editor-fold defaultstate="collapsed" desc="legacy 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) + //</editor-fold> + }; + + 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<Class<?>> 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<VanillaGoalKey> 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<? extends Goal>) goalClass))) + .filter((key) -> !MobGoalNames.isIgnored(key.key().getNamespacedKey().getKey())) + .sorted(Comparator.<VanillaGoalKey, String>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<? extends Goal>, Class<? extends Mob>> entityClassCache = new HashMap<>(); + private static final Map<Class<? extends net.minecraft.world.entity.Mob>, Class<? extends Mob>> bukkitMap = new HashMap<>(); + + + static { + //<editor-fold defaultstate="collapsed" desc="bukkitMap Entities"> + 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); + //</editor-fold> + } + + private static final BiMap<String, String> deobfuscationMap = HashBiMap.create(); + static final Set<String> 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 <T extends Mob> GoalKey<T> getKey(String clazzName, Class<? extends Goal> goalClass) { + String name = getUsableName(clazzName); + if (MobGoalNames.isIgnored(name)) { + //noinspection unchecked + return (GoalKey<T>) GoalKey.of(Mob.class, NamespacedKey.minecraft(name)); + } + return GoalKey.of(getEntity(goalClass), NamespacedKey.minecraft(name)); + } + + public static <T extends Mob> Class<T> getEntity(Class<? extends Goal> goalClass) { + //noinspection unchecked + return (Class<T>) 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<? extends net.minecraft.world.entity.Mob>) 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<? extends Mob> toBukkitClass(Class<? extends net.minecraft.world.entity.Mob> nmsClass) { + Class<? extends Mob> 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<AnnotationSpec> 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<AnnotationSpec> 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() { + } +} |