From bbd0f84e68471a1b61c16663aa203a0c8529e925 Mon Sep 17 00:00:00 2001 From: NK Date: Fri, 23 Dec 2022 01:40:54 +0000 Subject: [PATCH] Custom entity zombie pet --- .../nullvalkyrie/commands/BetaCommand.java | 8 +-- .../entities/pets/PathFinderGoalPet.java | 60 +++++++++++++++++++ .../nullvalkyrie/entities/pets/ZombiePet.java | 31 ++++++++++ 3 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 src/main/java/me/night/nullvalkyrie/entities/pets/PathFinderGoalPet.java create mode 100644 src/main/java/me/night/nullvalkyrie/entities/pets/ZombiePet.java diff --git a/src/main/java/me/night/nullvalkyrie/commands/BetaCommand.java b/src/main/java/me/night/nullvalkyrie/commands/BetaCommand.java index 632626e..7aa589d 100644 --- a/src/main/java/me/night/nullvalkyrie/commands/BetaCommand.java +++ b/src/main/java/me/night/nullvalkyrie/commands/BetaCommand.java @@ -1,8 +1,8 @@ package me.night.nullvalkyrie.commands; -//import me.night.nullvalkyrie.entities.pets.ZombiePet; +import me.night.nullvalkyrie.entities.pets.ZombiePet; import org.bukkit.command.CommandSender; -import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_19_R2.CraftWorld; import org.bukkit.entity.Player; import java.util.List; @@ -16,8 +16,8 @@ public class BetaCommand extends Command { @Override public void onCommand(CommandSender sender, String[] args) { if (sender instanceof Player player) { - //ZombiePet a = new ZombiePet(player.getLocation(), player); - //((CraftWorld) player.getWorld()).getHandle().b(a); + ZombiePet a = new ZombiePet(player.getLocation(), player); + ((CraftWorld) player.getWorld()).getHandle().addFreshEntity(a); } } diff --git a/src/main/java/me/night/nullvalkyrie/entities/pets/PathFinderGoalPet.java b/src/main/java/me/night/nullvalkyrie/entities/pets/PathFinderGoalPet.java new file mode 100644 index 0000000..111deac --- /dev/null +++ b/src/main/java/me/night/nullvalkyrie/entities/pets/PathFinderGoalPet.java @@ -0,0 +1,60 @@ +package me.night.nullvalkyrie.entities.pets; + +import java.util.EnumSet; + +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.goal.Goal; + +public class PathFinderGoalPet extends Goal { + + private final Mob pet; // our pet + private LivingEntity owner; // owner + + private final double f; // pet's speed + private final float g; // distance between owner & pet + + private double c; // x + private double d; // y + private double e; // z + + + public PathFinderGoalPet(Mob mob, double speed, float distance) { + this.pet = mob; + this.f = speed; + this.g = distance; + this.setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK, Flag.TARGET, Flag.JUMP)); + } + + @Override + public boolean canUse() { + this.owner = this.pet.getTarget(); + if (this.owner == null) return false; + else if (this.pet.getDisplayName() == null) return false; + else if (!this.pet.getDisplayName().getString().contains(this.owner.getName().getString())) return false; + else if (this.owner.distanceToSqr(this.pet) > (double) (this.g * this.g)) { + pet.getBukkitEntity().teleport(this.owner.getBukkitEntity().getLocation()); + return false; + } else { + this.c = this.owner.getX(); + this.d = this.owner.getY(); + this.e = this.owner.getZ(); + return true; + } + } + + @Override + public void start() { + this.pet.getNavigation().moveTo(this.c, this.d, this.e, this.f); + } + + @Override + public boolean canContinueToUse() { + return !this.pet.getNavigation().isDone() && this.owner.distanceToSqr(this.pet) < (double) (this.g * this.g); + } + + @Override + public void stop() { + this.owner = null; + } + +} \ No newline at end of file diff --git a/src/main/java/me/night/nullvalkyrie/entities/pets/ZombiePet.java b/src/main/java/me/night/nullvalkyrie/entities/pets/ZombiePet.java new file mode 100644 index 0000000..c2fb0de --- /dev/null +++ b/src/main/java/me/night/nullvalkyrie/entities/pets/ZombiePet.java @@ -0,0 +1,31 @@ +package me.night.nullvalkyrie.entities.pets; + +import net.md_5.bungee.api.ChatColor; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.ai.goal.FloatGoal; +import net.minecraft.world.entity.ai.goal.LookAtPlayerGoal; +import net.minecraft.world.entity.monster.Zombie; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_19_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_19_R2.entity.CraftPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityTargetEvent; + +public class ZombiePet extends Zombie { + public ZombiePet(Location location, Player player) { + super(EntityType.ZOMBIE, ((CraftWorld) location.getWorld()).getHandle()); + this.setBaby(true); // https://nms.screamingsandals.org/1.19.2/net/minecraft/world/entity/monster/Zombie.html setBaby + this.setInvulnerable(true); + this.setPos(location.getX(), location.getY(), location.getZ()); // https://nms.screamingsandals.org/1.19.2/net/minecraft/world/entity/Entity.html setPos + this.setCustomName(Component.nullToEmpty(ChatColor.DARK_PURPLE + player.getName() + "'s Zombie")); //https://nms.screamingsandals.org/1.19.2/net/minecraft/world/entity/Entity.html setCustomName + this.setCustomNameVisible(true); // https://nms.screamingsandals.org/1.19.2/net/minecraft/world/entity/Entity.html setCustomNameVisible + this.setTarget(((CraftPlayer) player).getHandle(), EntityTargetEvent.TargetReason.CUSTOM, true); // https://nms.screamingsandals.org/1.19.2/net/minecraft/world/entity/monster/Zombie.html setGoalTarget + } + @Override + public void registerGoals() { + this.goalSelector.addGoal(0, new PathFinderGoalPet(this, 1.0D, 15F)); + this.goalSelector.addGoal(1, new FloatGoal(this)); + this.goalSelector.addGoal(2, new LookAtPlayerGoal(this, net.minecraft.world.entity.player.Player.class, 8.0F)); + } +}