Add mob goal generator (#9980)

This commit is contained in:
Owen1212055 2024-01-15 14:36:10 -05:00
parent 64b98ef110
commit 73b42e843e
16 changed files with 1915 additions and 536 deletions

View file

@ -21,6 +21,7 @@ minecraft {
dependencies { dependencies {
implementation("com.squareup:javapoet:1.13.0") implementation("com.squareup:javapoet:1.13.0")
implementation(project(":paper-api")) implementation(project(":paper-api"))
implementation("io.github.classgraph:classgraph:4.8.47")
} }
group = "io.papermc.paper" group = "io.papermc.paper"

File diff suppressed because it is too large Load diff

View file

@ -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);
}
}

View file

@ -48,31 +48,24 @@ public final class Main {
REGISTRY_ACCESS = layers.compositeAccess().freeze(); 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() { private Main() {
} }
public static void main(final String[] args) { 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 { try {
if (Files.exists(output)) { if (Files.exists(output)) {
PathUtils.deleteDirectory(output); PathUtils.deleteDirectory(output);
} }
Files.createDirectories(output); Files.createDirectories(output);
for (final SourceGenerator generator : GENERATORS) { for (final SourceGenerator generator : generators) {
generator.writeToFile(output); generator.writeToFile(output);
} }
@ -81,6 +74,4 @@ public final class Main {
throw new RuntimeException(ex); throw new RuntimeException(ex);
} }
} }
} }

View file

@ -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() {
}
}

View file

@ -1,6 +1,5 @@
package io.papermc.generator.types; package io.papermc.generator.types;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.FieldSpec; import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile; import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.MethodSpec;
@ -9,16 +8,13 @@ import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName; import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec; import com.squareup.javapoet.TypeSpec;
import io.papermc.generator.Main; import io.papermc.generator.Main;
import io.papermc.generator.utils.Annotations;
import io.papermc.generator.utils.CollectingContext; 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.RegistryKey;
import io.papermc.paper.registry.TypedKey; import io.papermc.paper.registry.TypedKey;
import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; 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.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@ -27,7 +23,6 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import net.kyori.adventure.key.Key; import net.kyori.adventure.key.Key;
import net.minecraft.SharedConstants;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.core.RegistrySetBuilder; import net.minecraft.core.RegistrySetBuilder;
import net.minecraft.data.registries.UpdateOneTwentyOneRegistries; import net.minecraft.data.registries.UpdateOneTwentyOneRegistries;
@ -37,9 +32,9 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.qual.DefaultQualifier; import org.checkerframework.framework.qual.DefaultQualifier;
import static com.squareup.javapoet.TypeSpec.classBuilder; import static com.squareup.javapoet.TypeSpec.classBuilder;
import static io.papermc.generator.types.Annotations.EXPERIMENTAL_API_ANNOTATION; import static io.papermc.generator.utils.Annotations.EXPERIMENTAL_API_ANNOTATION;
import static io.papermc.generator.types.Annotations.NOT_NULL; import static io.papermc.generator.utils.Annotations.NOT_NULL;
import static io.papermc.generator.types.Annotations.experimentalAnnotations; import static io.papermc.generator.utils.Annotations.experimentalAnnotations;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static javax.lang.model.element.Modifier.FINAL; import static javax.lang.model.element.Modifier.FINAL;
import static javax.lang.model.element.Modifier.PRIVATE; 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; import static javax.lang.model.element.Modifier.STATIC;
@DefaultQualifier(NonNull.class) @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() 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)); .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 = """ private static final String CREATE_JAVADOC = """
Creates a key for {@link $T} in a registry. 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 @return a new typed key
"""; """;
private final String keysClassName;
private final Class<A> apiType; private final Class<A> apiType;
private final String pkg;
private final ResourceKey<? extends Registry<T>> registryKey; private final ResourceKey<? extends Registry<T>> registryKey;
private final RegistryKey<A> apiRegistryKey; private final RegistryKey<A> apiRegistryKey;
private final boolean publicCreateKeyMethod; 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) { 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.apiType = apiType;
this.pkg = pkg;
this.registryKey = registryKey; this.registryKey = registryKey;
this.apiRegistryKey = apiRegistryKey; this.apiRegistryKey = apiRegistryKey;
this.publicCreateKeyMethod = publicCreateKeyMethod; this.publicCreateKeyMethod = publicCreateKeyMethod;
@ -129,17 +100,18 @@ public class GeneratedKeyType<T, A> implements SourceGenerator {
} }
private TypeSpec.Builder keyHolderType() { private TypeSpec.Builder keyHolderType() {
return classBuilder(this.keysClassName) return classBuilder(this.className)
.addModifiers(PUBLIC, FINAL) .addModifiers(PUBLIC, FINAL)
.addJavadoc(TYPE_JAVADOC, RegistryKey.class, REGISTRY_KEY_FIELD_NAMES.get(this.apiRegistryKey)) .addJavadoc(Javadocs.getVersionDependentClassHeader("{@link $T#$L}"), RegistryKey.class, REGISTRY_KEY_FIELD_NAMES.get(this.apiRegistryKey))
.addAnnotation(SUPPRESS_WARNINGS).addAnnotation(GENERATED_FROM) .addAnnotations(Annotations.CLASS_HEADER)
.addMethod(MethodSpec.constructorBuilder() .addMethod(MethodSpec.constructorBuilder()
.addModifiers(PRIVATE) .addModifiers(PRIVATE)
.build() .build()
); );
} }
protected TypeSpec createTypeSpec() { @Override
protected TypeSpec getTypeSpec() {
final TypeName typedKey = ParameterizedTypeName.get(TypedKey.class, this.apiType); final TypeName typedKey = ParameterizedTypeName.get(TypedKey.class, this.apiType);
final TypeSpec.Builder typeBuilder = this.keyHolderType(); 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 String fieldName = keyPath.toUpperCase(Locale.ENGLISH).replaceAll("[.-/]", "_"); // replace invalid field name chars
final FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, PUBLIC, STATIC, FINAL) final FieldSpec.Builder fieldBuilder = FieldSpec.builder(typedKey, fieldName, PUBLIC, STATIC, FINAL)
.initializer("$N(key($S))", createMethod.build(), keyPath) .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)) { if (experimental.contains(key)) {
fieldBuilder.addAnnotations(experimentalAnnotations("update 1.21")); fieldBuilder.addAnnotations(experimentalAnnotations("update 1.21"));
} else { } else {
@ -183,23 +155,11 @@ public class GeneratedKeyType<T, A> implements SourceGenerator {
return experimental; return experimental;
} }
protected JavaFile createFile() { @Override
return JavaFile.builder(this.pkg, this.createTypeSpec()) protected JavaFile.Builder file(JavaFile.Builder builder) {
return builder
.skipJavaLangImports(true) .skipJavaLangImports(true)
.addStaticImport(Key.class, "key") .addStaticImport(Key.class, "key")
.indent(" ") .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);
} }
} }

View file

@ -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);
}
}

View file

@ -5,7 +5,5 @@ import java.nio.file.Path;
public interface SourceGenerator { public interface SourceGenerator {
String outputString();
void writeToFile(Path parent) throws IOException; void writeToFile(Path parent) throws IOException;
} }

View file

@ -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) {
}
}

View file

@ -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;
}
}

View file

@ -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() {
}
}

View file

@ -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() {
}
}

View file

@ -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() {
}
}

View file

@ -225,315 +225,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ @NotNull + @NotNull
+ <T extends Mob> Collection<Goal<T>> getRunningGoalsWithout(@NotNull T mob, @NotNull GoalType type); + <T extends Mob> Collection<Goal<T>> 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.<br>
+ * Generated by VanillaPathfinderTest in paper-server
+ */
+public interface VanillaGoal<T extends Mob> extends Goal<T> {
+
+ GoalKey<Creature> AVOID_ENTITY = GoalKey.of(Creature.class, NamespacedKey.minecraft("avoid_entity"));
+ GoalKey<Wolf> BEG = GoalKey.of(Wolf.class, NamespacedKey.minecraft("beg"));
+ GoalKey<Mob> BREAK_DOOR = GoalKey.of(Mob.class, NamespacedKey.minecraft("break_door"));
+ GoalKey<Creature> BREATH_AIR = GoalKey.of(Creature.class, NamespacedKey.minecraft("breath_air"));
+ GoalKey<Animals> BREED = GoalKey.of(Animals.class, NamespacedKey.minecraft("breed"));
+ GoalKey<Cat> CAT_LIE_ON_BED = GoalKey.of(Cat.class, NamespacedKey.minecraft("cat_lie_on_bed"));
+ GoalKey<Cat> CAT_SIT_ON_BLOCK = GoalKey.of(Cat.class, NamespacedKey.minecraft("cat_sit_on_block"));
+ GoalKey<Dolphin> DOLPHIN_JUMP = GoalKey.of(Dolphin.class, NamespacedKey.minecraft("dolphin_jump"));
+ GoalKey<Mob> EAT_BLOCK = GoalKey.of(Mob.class, NamespacedKey.minecraft("eat_block"));
+ GoalKey<Creature> FLEE_SUN = GoalKey.of(Creature.class, NamespacedKey.minecraft("flee_sun"));
+ GoalKey<Mob> FLOAT = GoalKey.of(Mob.class, NamespacedKey.minecraft("float"));
+ GoalKey<Creature> FOLLOW_BOAT = GoalKey.of(Creature.class, NamespacedKey.minecraft("follow_boat"));
+ GoalKey<Fish> FOLLOW_FLOCK_LEADER = GoalKey.of(Fish.class, NamespacedKey.minecraft("follow_flock_leader"));
+ GoalKey<Mob> FOLLOW_MOB = GoalKey.of(Mob.class, NamespacedKey.minecraft("follow_mob"));
+ GoalKey<Tameable> FOLLOW_OWNER = GoalKey.of(Tameable.class, NamespacedKey.minecraft("follow_owner"));
+ GoalKey<Animals> FOLLOW_PARENT = GoalKey.of(Animals.class, NamespacedKey.minecraft("follow_parent"));
+ GoalKey<Creature> GOLEM_RANDOM_STROLL_IN_VILLAGE = GoalKey.of(Creature.class, NamespacedKey.minecraft("golem_random_stroll_in_village"));
+ GoalKey<Mob> INTERACT = GoalKey.of(Mob.class, NamespacedKey.minecraft("interact"));
+ GoalKey<Parrot> LAND_ON_OWNERS_SHOULDER = GoalKey.of(Parrot.class, NamespacedKey.minecraft("land_on_owners_shoulder"));
+ GoalKey<Mob> LEAP_AT = GoalKey.of(Mob.class, NamespacedKey.minecraft("leap_at"));
+ GoalKey<Llama> LLAMA_FOLLOW_CARAVAN = GoalKey.of(Llama.class, NamespacedKey.minecraft("llama_follow_caravan"));
+ GoalKey<Mob> LOOK_AT_PLAYER = GoalKey.of(Mob.class, NamespacedKey.minecraft("look_at_player"));
+ GoalKey<AbstractVillager> LOOK_AT_TRADING_PLAYER = GoalKey.of(AbstractVillager.class, NamespacedKey.minecraft("look_at_trading_player"));
+ GoalKey<Creature> MELEE_ATTACK = GoalKey.of(Creature.class, NamespacedKey.minecraft("melee_attack"));
+ GoalKey<Creature> MOVE_BACK_TO_VILLAGE = GoalKey.of(Creature.class, NamespacedKey.minecraft("move_back_to_village"));
+ GoalKey<Creature> MOVE_THROUGH_VILLAGE = GoalKey.of(Creature.class, NamespacedKey.minecraft("move_through_village"));
+ GoalKey<Creature> MOVE_TOWARDS_RESTRICTION = GoalKey.of(Creature.class, NamespacedKey.minecraft("move_towards_restriction"));
+ GoalKey<Creature> MOVE_TOWARDS = GoalKey.of(Creature.class, NamespacedKey.minecraft("move_towards"));
+ GoalKey<Mob> OCELOT_ATTACK = GoalKey.of(Mob.class, NamespacedKey.minecraft("ocelot_attack"));
+ GoalKey<IronGolem> OFFER_FLOWER = GoalKey.of(IronGolem.class, NamespacedKey.minecraft("offer_flower"));
+ GoalKey<Mob> OPEN_DOOR = GoalKey.of(Mob.class, NamespacedKey.minecraft("open_door"));
+ GoalKey<Creature> PANIC = GoalKey.of(Creature.class, NamespacedKey.minecraft("panic"));
+ GoalKey<Raider> PATHFIND_TO_RAID = GoalKey.of(Raider.class, NamespacedKey.minecraft("pathfind_to_raid"));
+ GoalKey<Mob> RANDOM_LOOK_AROUND = GoalKey.of(Mob.class, NamespacedKey.minecraft("random_look_around"));
+ GoalKey<AbstractHorse> RANDOM_STAND = GoalKey.of(AbstractHorse.class, NamespacedKey.minecraft("random_stand"));
+ GoalKey<Creature> RANDOM_STROLL = GoalKey.of(Creature.class, NamespacedKey.minecraft("random_stroll"));
+ GoalKey<Creature> RANDOM_SWIMMING = GoalKey.of(Creature.class, NamespacedKey.minecraft("random_swimming"));
+ GoalKey<RangedEntity> RANGED_ATTACK = GoalKey.of(RangedEntity.class, NamespacedKey.minecraft("ranged_attack"));
+ GoalKey<Monster> RANGED_BOW_ATTACK = GoalKey.of(Monster.class, NamespacedKey.minecraft("ranged_bow_attack"));
+ GoalKey<Monster> RANGED_CROSSBOW_ATTACK = GoalKey.of(Monster.class, NamespacedKey.minecraft("ranged_crossbow_attack"));
+ GoalKey<Creature> REMOVE_BLOCK = GoalKey.of(Creature.class, NamespacedKey.minecraft("remove_block"));
+ GoalKey<Creature> RESTRICT_SUN = GoalKey.of(Creature.class, NamespacedKey.minecraft("restrict_sun"));
+ GoalKey<AbstractHorse> RUN_AROUND_LIKE_CRAZY = GoalKey.of(AbstractHorse.class, NamespacedKey.minecraft("run_around_like_crazy"));
+ GoalKey<Tameable> SIT_WHEN_ORDERED_TO = GoalKey.of(Tameable.class, NamespacedKey.minecraft("sit_when_ordered_to"));
+ GoalKey<Creature> STROLL_THROUGH_VILLAGE = GoalKey.of(Creature.class, NamespacedKey.minecraft("stroll_through_village"));
+ GoalKey<Creeper> SWELL = GoalKey.of(Creeper.class, NamespacedKey.minecraft("swell"));
+ GoalKey<Creature> TEMPT = GoalKey.of(Creature.class, NamespacedKey.minecraft("tempt"));
+ GoalKey<AbstractVillager> TRADE_WITH_PLAYER = GoalKey.of(AbstractVillager.class, NamespacedKey.minecraft("trade_with_player"));
+ GoalKey<Creature> TRY_FIND_WATER = GoalKey.of(Creature.class, NamespacedKey.minecraft("try_find_water"));
+ GoalKey<Mob> USE_ITEM = GoalKey.of(Mob.class, NamespacedKey.minecraft("use_item"));
+ GoalKey<Creature> WATER_AVOIDING_RANDOM_FLYING = GoalKey.of(Creature.class, NamespacedKey.minecraft("water_avoiding_random_flying"));
+ GoalKey<Creature> WATER_AVOIDING_RANDOM_STROLL = GoalKey.of(Creature.class, NamespacedKey.minecraft("water_avoiding_random_stroll"));
+ GoalKey<Zombie> ZOMBIE_ATTACK = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack"));
+ GoalKey<IronGolem> DEFEND_VILLAGE = GoalKey.of(IronGolem.class, NamespacedKey.minecraft("defend_village"));
+ GoalKey<Creature> HURT_BY = GoalKey.of(Creature.class, NamespacedKey.minecraft("hurt_by"));
+ GoalKey<Mob> NEAREST_ATTACKABLE = GoalKey.of(Mob.class, NamespacedKey.minecraft("nearest_attackable"));
+ GoalKey<Raider> NEAREST_ATTACKABLE_WITCH = GoalKey.of(Raider.class, NamespacedKey.minecraft("nearest_attackable_witch"));
+ GoalKey<Raider> NEAREST_HEALABLE_RAIDER = GoalKey.of(Raider.class, NamespacedKey.minecraft("nearest_healable_raider"));
+ GoalKey<Tameable> NON_TAME_RANDOM = GoalKey.of(Tameable.class, NamespacedKey.minecraft("non_tame_random"));
+ GoalKey<Tameable> OWNER_HURT_BY = GoalKey.of(Tameable.class, NamespacedKey.minecraft("owner_hurt_by"));
+ GoalKey<Tameable> OWNER_HURT = GoalKey.of(Tameable.class, NamespacedKey.minecraft("owner_hurt"));
+ GoalKey<Mob> RESET_UNIVERSAL_ANGER = GoalKey.of(Mob.class, NamespacedKey.minecraft("reset_universal_anger"));
+ GoalKey<Fish> FISH_SWIM = GoalKey.of(Fish.class, NamespacedKey.minecraft("fish_swim"));
+ GoalKey<Bee> BEE_ATTACK = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_attack"));
+ GoalKey<Bee> BEE_BECOME_ANGRY = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_become_angry"));
+ GoalKey<Bee> BEE_ENTER_HIVE = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_enter_hive"));
+ GoalKey<Bee> BEE_GO_TO_HIVE = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_go_to_hive"));
+ GoalKey<Bee> BEE_GO_TO_KNOWN_FLOWER = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_go_to_known_flower"));
+ GoalKey<Bee> BEE_GROW_CROP = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_grow_crop"));
+ GoalKey<Bee> BEE_HURT_BY_OTHER = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_hurt_by_other"));
+ GoalKey<Bee> BEE_LOCATE_HIVE = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_locate_hive"));
+ GoalKey<Bee> BEE_POLLINATE = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_pollinate"));
+ GoalKey<Bee> BEE_WANDER = GoalKey.of(Bee.class, NamespacedKey.minecraft("bee_wander"));
+ GoalKey<Cat> CAT_AVOID_ENTITY = GoalKey.of(Cat.class, NamespacedKey.minecraft("cat_avoid_entity"));
+ GoalKey<Cat> CAT_RELAX_ON_OWNER = GoalKey.of(Cat.class, NamespacedKey.minecraft("cat_relax_on_owner"));
+ GoalKey<Cat> CAT_TEMPT = GoalKey.of(Cat.class, NamespacedKey.minecraft("cat_tempt"));
+ GoalKey<Dolphin> DOLPHIN_SWIM_TO_TREASURE = GoalKey.of(Dolphin.class, NamespacedKey.minecraft("dolphin_swim_to_treasure"));
+ GoalKey<Dolphin> DOLPHIN_SWIM_WITH_PLAYER = GoalKey.of(Dolphin.class, NamespacedKey.minecraft("dolphin_swim_with_player"));
+ GoalKey<Dolphin> PLAY_WITH_ITEMS = GoalKey.of(Dolphin.class, NamespacedKey.minecraft("play_with_items"));
+ GoalKey<Fox> DEFEND_TRUSTED = GoalKey.of(Fox.class, NamespacedKey.minecraft("defend_trusted"));
+ GoalKey<Fox> FACEPLANT = GoalKey.of(Fox.class, NamespacedKey.minecraft("faceplant"));
+ GoalKey<Fox> FOX_BREED = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_breed"));
+ GoalKey<Fox> FOX_EAT_BERRIES = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_eat_berries"));
+ GoalKey<Fox> FOX_FLOAT = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_float"));
+ GoalKey<Fox> FOX_FOLLOW_PARENT = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_follow_parent"));
+ GoalKey<Fox> FOX_LOOK_AT_PLAYER = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_look_at_player"));
+ GoalKey<Fox> FOX_MELEE_ATTACK = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_melee_attack"));
+ GoalKey<Fox> FOX_PANIC = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_panic"));
+ GoalKey<Fox> FOX_POUNCE = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_pounce"));
+ GoalKey<Fox> FOX_SEARCH_FOR_ITEMS = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_search_for_items"));
+ GoalKey<Fox> FOX_STROLL_THROUGH_VILLAGE = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_stroll_through_village"));
+ GoalKey<Fox> PERCH_AND_SEARCH = GoalKey.of(Fox.class, NamespacedKey.minecraft("perch_and_search"));
+ GoalKey<Fox> SEEK_SHELTER = GoalKey.of(Fox.class, NamespacedKey.minecraft("seek_shelter"));
+ GoalKey<Fox> SLEEP = GoalKey.of(Fox.class, NamespacedKey.minecraft("sleep"));
+ GoalKey<Fox> STALK_PREY = GoalKey.of(Fox.class, NamespacedKey.minecraft("stalk_prey"));
+ GoalKey<Ocelot> OCELOT_AVOID_ENTITY = GoalKey.of(Ocelot.class, NamespacedKey.minecraft("ocelot_avoid_entity"));
+ GoalKey<Ocelot> OCELOT_TEMPT = GoalKey.of(Ocelot.class, NamespacedKey.minecraft("ocelot_tempt"));
+ GoalKey<Panda> PANDA_ATTACK = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_attack"));
+ GoalKey<Panda> PANDA_AVOID = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_avoid"));
+ GoalKey<Panda> PANDA_BREED = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_breed"));
+ GoalKey<Panda> PANDA_HURT_BY = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_hurt_by"));
+ GoalKey<Panda> PANDA_LIE_ON_BACK = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_lie_on_back"));
+ GoalKey<Panda> PANDA_LOOK_AT_PLAYER = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_look_at_player"));
+ GoalKey<Panda> PANDA_PANIC = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_panic"));
+ GoalKey<Panda> PANDA_ROLL = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_roll"));
+ GoalKey<Panda> PANDA_SIT = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_sit"));
+ GoalKey<Panda> PANDA_SNEEZE = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_sneeze"));
+ GoalKey<PolarBear> POLAR_BEAR_ATTACK_PLAYERS = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polar_bear_attack_players"));
+ GoalKey<PolarBear> POLAR_BEAR_HURT_BY = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polar_bear_hurt_by"));
+ GoalKey<PolarBear> POLAR_BEAR_MELEE_ATTACK = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polar_bear_melee_attack"));
+ GoalKey<PolarBear> POLAR_BEAR_PANIC = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polar_bear_panic"));
+ GoalKey<PufferFish> PUFFERFISH_PUFF = GoalKey.of(PufferFish.class, NamespacedKey.minecraft("pufferfish_puff"));
+ GoalKey<Rabbit> RABBIT_AVOID_ENTITY = GoalKey.of(Rabbit.class, NamespacedKey.minecraft("rabbit_avoid_entity"));
+ GoalKey<Rabbit> RABBIT_PANIC = GoalKey.of(Rabbit.class, NamespacedKey.minecraft("rabbit_panic"));
+ GoalKey<Rabbit> RAID_GARDEN = GoalKey.of(Rabbit.class, NamespacedKey.minecraft("raid_garden"));
+ GoalKey<Squid> SQUID_FLEE = GoalKey.of(Squid.class, NamespacedKey.minecraft("squid_flee"));
+ GoalKey<Squid> SQUID_RANDOM_MOVEMENT = GoalKey.of(Squid.class, NamespacedKey.minecraft("squid_random_movement"));
+ GoalKey<Turtle> TURTLE_BREED = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_breed"));
+ GoalKey<Turtle> TURTLE_GO_HOME = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_go_home"));
+ GoalKey<Turtle> TURTLE_GO_TO_WATER = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_go_to_water"));
+ GoalKey<Turtle> TURTLE_LAY_EGG = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_lay_egg"));
+ GoalKey<Turtle> TURTLE_PANIC = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_panic"));
+ GoalKey<Turtle> TURTLE_RANDOM_STROLL = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_random_stroll"));
+ GoalKey<Turtle> TURTLE_TRAVEL = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_travel"));
+ GoalKey<Wolf> WOLF_AVOID_ENTITY = GoalKey.of(Wolf.class, NamespacedKey.minecraft("wolf_avoid_entity"));
+ GoalKey<Llama> LLAMA_ATTACK_WOLF = GoalKey.of(Llama.class, NamespacedKey.minecraft("llama_attack_wolf"));
+ GoalKey<Llama> LLAMA_HURT_BY = GoalKey.of(Llama.class, NamespacedKey.minecraft("llama_hurt_by"));
+ GoalKey<SkeletonHorse> SKELETON_TRAP = GoalKey.of(SkeletonHorse.class, NamespacedKey.minecraft("skeleton_trap"));
+ GoalKey<Llama> TRADER_LLAMA_DEFEND_WANDERING_TRADER = GoalKey.of(Llama.class, NamespacedKey.minecraft("trader_llama_defend_wandering_trader"));
+ GoalKey<Wither> WITHER_DO_NOTHING = GoalKey.of(Wither.class, NamespacedKey.minecraft("wither_do_nothing"));
+ GoalKey<Illager> RAIDER_OPEN_DOOR = GoalKey.of(Illager.class, NamespacedKey.minecraft("raider_open_door"));
+ GoalKey<AbstractSkeleton> SKELETON_MELEE = GoalKey.of(AbstractSkeleton.class, NamespacedKey.minecraft("abstract_skeleton_melee"));
+ GoalKey<Blaze> BLAZE_ATTACK = GoalKey.of(Blaze.class, NamespacedKey.minecraft("blaze_attack"));
+ GoalKey<Drowned> DROWNED_ATTACK = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_attack"));
+ GoalKey<Drowned> DROWNED_GO_TO_BEACH = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_go_to_beach"));
+ GoalKey<Creature> DROWNED_GO_TO_WATER = GoalKey.of(Creature.class, NamespacedKey.minecraft("drowned_go_to_water"));
+ GoalKey<Drowned> DROWNED_SWIM_UP = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_swim_up"));
+ GoalKey<RangedEntity> DROWNED_TRIDENT_ATTACK = GoalKey.of(RangedEntity.class, NamespacedKey.minecraft("drowned_trident_attack"));
+ GoalKey<Enderman> ENDERMAN_FREEZE_WHEN_LOOKED_AT = GoalKey.of(Enderman.class, NamespacedKey.minecraft("enderman_freeze_when_looked_at"));
+ GoalKey<Enderman> ENDERMAN_LEAVE_BLOCK = GoalKey.of(Enderman.class, NamespacedKey.minecraft("enderman_leave_block"));
+ GoalKey<Enderman> ENDERMAN_LOOK_FOR_PLAYER = GoalKey.of(Enderman.class, NamespacedKey.minecraft("enderman_look_for_player"));
+ GoalKey<Enderman> ENDERMAN_TAKE_BLOCK = GoalKey.of(Enderman.class, NamespacedKey.minecraft("enderman_take_block"));
+ GoalKey<Evoker> EVOKER_ATTACK_SPELL = GoalKey.of(Evoker.class, NamespacedKey.minecraft("evoker_attack_spell"));
+ GoalKey<Evoker> EVOKER_CASTING_SPELL = GoalKey.of(Evoker.class, NamespacedKey.minecraft("evoker_casting_spell"));
+ GoalKey<Evoker> EVOKER_SUMMON_SPELL = GoalKey.of(Evoker.class, NamespacedKey.minecraft("evoker_summon_spell"));
+ GoalKey<Evoker> EVOKER_WOLOLO_SPELL = GoalKey.of(Evoker.class, NamespacedKey.minecraft("evoker_wololo_spell"));
+ GoalKey<Ghast> GHAST_LOOK = GoalKey.of(Ghast.class, NamespacedKey.minecraft("ghast_look"));
+ GoalKey<Ghast> GHAST_SHOOT_FIREBALL = GoalKey.of(Ghast.class, NamespacedKey.minecraft("ghast_shoot_fireball"));
+ GoalKey<Ghast> RANDOM_FLOAT_AROUND = GoalKey.of(Ghast.class, NamespacedKey.minecraft("random_float_around"));
+ GoalKey<Guardian> GUARDIAN_ATTACK = GoalKey.of(Guardian.class, NamespacedKey.minecraft("guardian_attack"));
+ GoalKey<Illusioner> ILLUSIONER_BLINDNESS_SPELL = GoalKey.of(Illusioner.class, NamespacedKey.minecraft("illusioner_blindness_spell"));
+ GoalKey<Illusioner> ILLUSIONER_MIRROR_SPELL = GoalKey.of(Illusioner.class, NamespacedKey.minecraft("illusioner_mirror_spell"));
+ GoalKey<Raider> LONG_DISTANCE_PATROL = GoalKey.of(Raider.class, NamespacedKey.minecraft("long_distance_patrol"));
+ GoalKey<Phantom> PHANTOM_ATTACK_PLAYER = GoalKey.of(Phantom.class, NamespacedKey.minecraft("phantom_attack_player"));
+ GoalKey<Phantom> PHANTOM_ATTACK_STRATEGY = GoalKey.of(Phantom.class, NamespacedKey.minecraft("phantom_attack_strategy"));
+ GoalKey<Phantom> PHANTOM_CIRCLE_AROUND_ANCHOR = GoalKey.of(Phantom.class, NamespacedKey.minecraft("phantom_circle_around_anchor"));
+ GoalKey<Phantom> PHANTOM_SWEEP_ATTACK = GoalKey.of(Phantom.class, NamespacedKey.minecraft("phantom_sweep_attack"));
+ GoalKey<Shulker> SHULKER_ATTACK = GoalKey.of(Shulker.class, NamespacedKey.minecraft("shulker_attack"));
+ GoalKey<Shulker> SHULKER_DEFENSE_ATTACK = GoalKey.of(Shulker.class, NamespacedKey.minecraft("shulker_defense_attack"));
+ GoalKey<Shulker> SHULKER_NEAREST_ATTACK = GoalKey.of(Shulker.class, NamespacedKey.minecraft("shulker_nearest_attack"));
+ GoalKey<Shulker> SHULKER_PEEK = GoalKey.of(Shulker.class, NamespacedKey.minecraft("shulker_peek"));
+ GoalKey<Silverfish> SILVERFISH_MERGE_WITH_STONE = GoalKey.of(Silverfish.class, NamespacedKey.minecraft("silverfish_merge_with_stone"));
+ GoalKey<Silverfish> SILVERFISH_WAKE_UP_FRIENDS = GoalKey.of(Silverfish.class, NamespacedKey.minecraft("silverfish_wake_up_friends"));
+ GoalKey<Slime> SLIME_ATTACK = GoalKey.of(Slime.class, NamespacedKey.minecraft("slime_attack"));
+ GoalKey<Slime> SLIME_FLOAT = GoalKey.of(Slime.class, NamespacedKey.minecraft("slime_float"));
+ GoalKey<Slime> SLIME_KEEP_ON_JUMPING = GoalKey.of(Slime.class, NamespacedKey.minecraft("slime_keep_on_jumping"));
+ GoalKey<Slime> SLIME_RANDOM_DIRECTION = GoalKey.of(Slime.class, NamespacedKey.minecraft("slime_random_direction"));
+ GoalKey<Spellcaster> SPELLCASTER_CASTING_SPELL = GoalKey.of(Spellcaster.class, NamespacedKey.minecraft("spellcaster_casting_spell"));
+ GoalKey<Spider> SPIDER_ATTACK = GoalKey.of(Spider.class, NamespacedKey.minecraft("spider_attack"));
+ GoalKey<Spider> SPIDER = GoalKey.of(Spider.class, NamespacedKey.minecraft("spider"));
+ GoalKey<Strider> STRIDER_GO_TO_LAVA = GoalKey.of(Strider.class, NamespacedKey.minecraft("strider_go_to_lava"));
+ GoalKey<Vex> VEX_CHARGE_ATTACK = GoalKey.of(Vex.class, NamespacedKey.minecraft("vex_charge_attack"));
+ GoalKey<Vex> VEX_COPY_OWNER = GoalKey.of(Vex.class, NamespacedKey.minecraft("vex_copy_owner"));
+ GoalKey<Vex> VEX_RANDOM_MOVE = GoalKey.of(Vex.class, NamespacedKey.minecraft("vex_random_move"));
+ GoalKey<Mob> VINDICATOR_BREAK_DOOR = GoalKey.of(Mob.class, NamespacedKey.minecraft("vindicator_break_door"));
+ GoalKey<Vindicator> VINDICATOR_JOHNNY_ATTACK = GoalKey.of(Vindicator.class, NamespacedKey.minecraft("vindicator_johnny_attack"));
+ GoalKey<Zombie> ZOMBIE_ATTACK_TURTLE_EGG = GoalKey.of(Zombie.class, NamespacedKey.minecraft("zombie_attack_turtle_egg"));
+ GoalKey<WanderingTrader> WANDER_TO_POSITION = GoalKey.of(WanderingTrader.class, NamespacedKey.minecraft("wander_to_position"));
+ GoalKey<Raider> HOLD_GROUND_ATTACK = GoalKey.of(Raider.class, NamespacedKey.minecraft("hold_ground_attack"));
+ GoalKey<Raider> OBTAIN_RAID_LEADER_BANNER = GoalKey.of(Raider.class, NamespacedKey.minecraft("obtain_raid_leader_banner"));
+ GoalKey<Raider> RAIDER_CELEBRATION = GoalKey.of(Raider.class, NamespacedKey.minecraft("raider_celebration"));
+ GoalKey<Raider> RAIDER_MOVE_THROUGH_VILLAGE = GoalKey.of(Raider.class, NamespacedKey.minecraft("raider_move_through_village"));
+ GoalKey<Creature> PARROT_WANDER = GoalKey.of(Creature.class, NamespacedKey.minecraft("parrot_wander"));
+ GoalKey<Mob> CLIMB_ON_TOP_OF_POWDER_SNOW = GoalKey.of(Mob.class, NamespacedKey.minecraft("climb_on_top_of_powder_snow"));
+ GoalKey<Wolf> WOLF_PANIC = GoalKey.of(Wolf.class, NamespacedKey.minecraft("wolf_panic"));
+
+ /**
+ * @deprecated removed in 1.20.2
+ */
+ @Deprecated GoalKey<Vindicator> VINDICATOR_MELEE_ATTACK = GoalKey.of(Vindicator.class, NamespacedKey.minecraft("vindicator_melee_attack"));
+ /**
+ * @deprecated removed in 1.20.2
+ */
+ @Deprecated GoalKey<Ravager> RAVAGER_MELEE_ATTACK = GoalKey.of(Ravager.class, NamespacedKey.minecraft("ravager_melee_attack"));
+ /**
+ * @deprecated removed in 1.20.2
+ */
+ @Deprecated GoalKey<Rabbit> 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<PigZombie> ANGER = GoalKey.of(PigZombie.class, NamespacedKey.minecraft("anger"));
+ /**
+ * @deprecated removed in 1.16
+ */
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<PigZombie> 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> BLAZE_FIREBALL = GoalKey.of(Blaze.class, NamespacedKey.minecraft("blaze_fireball"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Cat> TEMPT_CHANCE = GoalKey.of(Cat.class, NamespacedKey.minecraft("tempt_chance"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Dolphin> DOLPHIN_PLAY_WITH_ITEMS = GoalKey.of(Dolphin.class, NamespacedKey.minecraft("dolphin_play_with_items"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Drowned> DROWNED_GOTO_BEACH = GoalKey.of(Drowned.class, NamespacedKey.minecraft("drowned_goto_beach"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Creature> DROWNED_GOTO_WATER = GoalKey.of(Creature.class, NamespacedKey.minecraft("drowned_goto_water"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Enderman> ENDERMAN_PICKUP_BLOCK = GoalKey.of(Enderman.class, NamespacedKey.minecraft("enderman_pickup_block"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Enderman> ENDERMAN_PLACE_BLOCK = GoalKey.of(Enderman.class, NamespacedKey.minecraft("enderman_place_block"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Enderman> 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> EVOKER_CAST_SPELL = GoalKey.of(Evoker.class, NamespacedKey.minecraft("evoker_cast_spell"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Fox> FOX_DEFEND_TRUSTED = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_defend_trusted"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Fox> FOX_FACEPLANT = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_faceplant"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Fox> FOX_PERCH_AND_SEARCH = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_perch_and_search"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Fox> FOX_SLEEP = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_sleep"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Fox> FOX_SEEK_SHELTER = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_seek_shelter"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Fox> FOX_STALK_PREY = GoalKey.of(Fox.class, NamespacedKey.minecraft("fox_stalk_prey"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Ghast> GHAST_ATTACK_TARGET = GoalKey.of(Ghast.class, NamespacedKey.minecraft("ghast_attack_target"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Ghast> GHAST_IDLE_MOVE = GoalKey.of(Ghast.class, NamespacedKey.minecraft("ghast_idle_move"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Ghast> GHAST_MOVE_TOWARDS_TARGET = GoalKey.of(Ghast.class, NamespacedKey.minecraft("ghast_move_towards_target"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Spellcaster> SPELLCASTER_CAST_SPELL = GoalKey.of(Spellcaster.class, NamespacedKey.minecraft("spellcaster_cast_spell"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<TraderLlama> LLAMATRADER_DEFENDED_WANDERING_TRADER = GoalKey.of(TraderLlama.class, NamespacedKey.minecraft("llamatrader_defended_wandering_trader"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Panda> PANDA_HURT_BY_TARGET = GoalKey.of(Panda.class, NamespacedKey.minecraft("panda_hurt_by_target"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<PolarBear> POLARBEAR_ATTACK_PLAYERS = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polarbear_attack_players"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<PolarBear> POLARBEAR_HURT_BY = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polarbear_hurt_by"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<PolarBear> POLARBEAR_MELEE = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polarbear_melee"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<PolarBear> POLARBEAR_PANIC = GoalKey.of(PolarBear.class, NamespacedKey.minecraft("polarbear_panic"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Rabbit> EAT_CARROTS = GoalKey.of(Rabbit.class, NamespacedKey.minecraft("eat_carrots"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Rabbit> KILLER_RABBIT_MELEE_ATTACK = GoalKey.of(Rabbit.class, NamespacedKey.minecraft("killer_rabbit_melee_attack"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Rabbit> RABBIT_AVOID_TARGET = GoalKey.of(Rabbit.class, NamespacedKey.minecraft("rabbit_avoid_target"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Raider> RAIDER_HOLD_GROUND = GoalKey.of(Raider.class, NamespacedKey.minecraft("raider_hold_ground"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Raider> RAIDER_OBTAIN_BANNER = GoalKey.of(Raider.class, NamespacedKey.minecraft("raider_obtain_banner"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Shulker> SHULKER_DEFENSE = GoalKey.of(Shulker.class, NamespacedKey.minecraft("shulker_defense"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Shulker> SHULKER_NEAREST = GoalKey.of(Shulker.class, NamespacedKey.minecraft("shulker_nearest"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Silverfish> SILVERFISH_HIDE_IN_BLOCK = GoalKey.of(Silverfish.class, NamespacedKey.minecraft("silverfish_hide_in_block"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Silverfish> SILVERFISH_WAKE_OTHERS = GoalKey.of(Silverfish.class, NamespacedKey.minecraft("silverfish_wake_others"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Slime> SLIME_IDLE = GoalKey.of(Slime.class, NamespacedKey.minecraft("slime_idle"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Slime> SLIME_NEAREST_PLAYER = GoalKey.of(Slime.class, NamespacedKey.minecraft("slime_nearest_player"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Slime> SLIME_RANDOM_JUMP = GoalKey.of(Slime.class, NamespacedKey.minecraft("slime_random_jump"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Spider> SPIDER_MELEE_ATTACK = GoalKey.of(Spider.class, NamespacedKey.minecraft("spider_melee_attack"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Spider> SPIDER_NEAREST_ATTACKABLE_TARGET = GoalKey.of(Spider.class, NamespacedKey.minecraft("spider_nearest_attackable_target"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Squid> SQUID = GoalKey.of(Squid.class, NamespacedKey.minecraft("squid"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Turtle> TURTLE_GOTO_WATER = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_goto_water"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Turtle> TURTLE_TEMPT = GoalKey.of(Turtle.class, NamespacedKey.minecraft("turtle_tempt"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Vex> 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<WanderingTrader> VILLAGERTRADER_WANDER_TO_POSITION = GoalKey.of(WanderingTrader.class, NamespacedKey.minecraft("villagertrader_wander_to_position"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<RangedEntity> ARROW_ATTACK = GoalKey.of(RangedEntity.class, NamespacedKey.minecraft("arrow_attack"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Creature> AVOID_TARGET = GoalKey.of(Creature.class, NamespacedKey.minecraft("avoid_target"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Monster> BOW_SHOOT = GoalKey.of(Monster.class, NamespacedKey.minecraft("bow_shoot"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Creature> BREATH = GoalKey.of(Creature.class, NamespacedKey.minecraft("breath"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Cat> CAT_SIT_ON_BED = GoalKey.of(Cat.class, NamespacedKey.minecraft("cat_sit_on_bed"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Monster> CROSSBOW_ATTACK = GoalKey.of(Monster.class, NamespacedKey.minecraft("crossbow_attack"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Mob> DOOR_OPEN = GoalKey.of(Mob.class, NamespacedKey.minecraft("door_open"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Mob> EAT_TILE = GoalKey.of(Mob.class, NamespacedKey.minecraft("eat_tile"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Fish> FISH_SCHOOL = GoalKey.of(Fish.class, NamespacedKey.minecraft("fish_school"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Mob> FOLLOW_ENTITY = GoalKey.of(Mob.class, NamespacedKey.minecraft("follow_entity"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<SkeletonHorse> HORSE_TRAP = GoalKey.of(SkeletonHorse.class, NamespacedKey.minecraft("horse_trap"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Creature> HURT_BY_TARGET = GoalKey.of(Creature.class, NamespacedKey.minecraft("hurt_by_target"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Cat> JUMP_ON_BLOCK = GoalKey.of(Cat.class, NamespacedKey.minecraft("jump_on_block"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Mob> LEAP_AT_TARGET = GoalKey.of(Mob.class, NamespacedKey.minecraft("leap_at_target"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Llama> LLAMA_FOLLOW = GoalKey.of(Llama.class, NamespacedKey.minecraft("llama_follow"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Creature> MOVE_TOWARDS_TARGET = GoalKey.of(Creature.class, NamespacedKey.minecraft("move_towards_target"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Mob> NEAREST_ATTACKABLE_TARGET = GoalKey.of(Mob.class, NamespacedKey.minecraft("nearest_attackable_target"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Raider> NEAREST_ATTACKABLE_TARGET_WITCH = GoalKey.of(Raider.class, NamespacedKey.minecraft("nearest_attackable_target_witch"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Creature> NEAREST_VILLAGE = GoalKey.of(Creature.class, NamespacedKey.minecraft("nearest_village"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Tameable> OWNER_HURT_BY_TARGET = GoalKey.of(Tameable.class, NamespacedKey.minecraft("owner_hurt_by_target"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Tameable> OWNER_HURT_TARGET = GoalKey.of(Tameable.class, NamespacedKey.minecraft("owner_hurt_target"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Parrot> PERCH = GoalKey.of(Parrot.class, NamespacedKey.minecraft("perch"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Raider> RAID = GoalKey.of(Raider.class, NamespacedKey.minecraft("raid"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Creature> RANDOM_FLY = GoalKey.of(Creature.class, NamespacedKey.minecraft("random_fly"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Mob> RANDOM_LOOKAROUND = GoalKey.of(Mob.class, NamespacedKey.minecraft("random_lookaround"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Creature> RANDOM_STROLL_LAND = GoalKey.of(Creature.class, NamespacedKey.minecraft("random_stroll_land"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Creature> RANDOM_SWIM = GoalKey.of(Creature.class, NamespacedKey.minecraft("random_swim"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Tameable> RANDOM_TARGET_NON_TAMED = GoalKey.of(Tameable.class, NamespacedKey.minecraft("random_target_non_tamed"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Tameable> SIT = GoalKey.of(Tameable.class, NamespacedKey.minecraft("sit"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Creature> STROLL_VILLAGE = GoalKey.of(Creature.class, NamespacedKey.minecraft("stroll_village"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<AbstractHorse> TAME = GoalKey.of(AbstractHorse.class, NamespacedKey.minecraft("tame"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Creature> WATER = GoalKey.of(Creature.class, NamespacedKey.minecraft("water"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Dolphin> WATER_JUMP = GoalKey.of(Dolphin.class, NamespacedKey.minecraft("water_jump"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Creature> STROLL_VILLAGE_GOLEM = GoalKey.of(Creature.class, NamespacedKey.minecraft("stroll_village_golem"));
+ @Deprecated(forRemoval = true) @ApiStatus.ScheduledForRemoval(inVersion = "1.21") GoalKey<Mob> 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 diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/Bukkit.java --- a/src/main/java/org/bukkit/Bukkit.java

View file

@ -10,19 +10,6 @@ Co-authored-by: SoSeDiK <mrsosedik@gmail.com>
Co-authored-by: booky10 <boooky10@gmail.com> Co-authored-by: booky10 <boooky10@gmail.com>
Co-authored-by: Amin <amin.haddou@frg.wwschool.de> Co-authored-by: Amin <amin.haddou@frg.wwschool.de>
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<T extends Mob> extends Goal<T> {
GoalKey<Creature> FLEE_SUN = GoalKey.of(Creature.class, NamespacedKey.minecraft("flee_sun"));
GoalKey<Mob> FLOAT = GoalKey.of(Mob.class, NamespacedKey.minecraft("float"));
GoalKey<Creature> FOLLOW_BOAT = GoalKey.of(Creature.class, NamespacedKey.minecraft("follow_boat"));
- GoalKey<Fish> FOLLOW_FLOCK_LEADER = GoalKey.of(Fish.class, NamespacedKey.minecraft("follow_flock_leader"));
+ GoalKey<io.papermc.paper.entity.SchoolableFish> FOLLOW_FLOCK_LEADER = GoalKey.of(io.papermc.paper.entity.SchoolableFish.class, NamespacedKey.minecraft("follow_flock_leader"));
GoalKey<Mob> FOLLOW_MOB = GoalKey.of(Mob.class, NamespacedKey.minecraft("follow_mob"));
GoalKey<Tameable> FOLLOW_OWNER = GoalKey.of(Tameable.class, NamespacedKey.minecraft("follow_owner"));
GoalKey<Animals> 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 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 new file mode 100644
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000

View file

@ -809,115 +809,3 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
// Paper end // 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<GoalKey<?>> deprecated = new ArrayList<>();
+ List<GoalKey<?>> 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<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<GoalKey<?>> 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<? extends net.minecraft.world.entity.ai.goal.Goal>) goalClass))
+ .collect(Collectors.toList());
+
+ List<GoalKey<?>> missingFromAPI = new ArrayList<>(vanillaNames);
+ missingFromAPI.removeAll(keys);
+ missingFromAPI.removeIf(k -> MobGoalHelper.ignored.contains(k.getNamespacedKey().getKey()));
+ List<GoalKey<?>> 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<Class<?>> 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<? extends Mob> bukkitClass = MobGoalHelper.toBukkitClass((Class<? extends net.minecraft.world.entity.Mob>) 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");
+ }
+ }
+}