From b739a95b1ef6a5a44671827e6046991e47337cf8 Mon Sep 17 00:00:00 2001 From: granny Date: Sat, 4 Jan 2025 01:27:30 -0800 Subject: [PATCH] port Ridables patches --- .gitignore | 1 - build-data/purpur.at | 3 + patches/api/0006-Ridables.patch | 196 - patches/generated-api/0001-Ridables.patch | 23 - .../paper/entity/ai/VanillaGoal.java.patch | 15 + .../java/org/bukkit/entity/Entity.java.patch | 38 + .../purpur/event/entity/RidableMoveEvent.java | 100 + .../event/entity/RidableSpacebarEvent.java | 38 + .../util/permissions/PurpurPermissions.java | 16 + .../features/0001-Ridables.patch | 3487 +++++------------ .../net/minecraft/core/BlockPos.java.patch | 15 + .../features/0002-Ridables.patch | 66 + .../org/purpurmc/purpur/PurpurConfig.java | 5 + .../purpurmc/purpur/PurpurWorldConfig.java | 749 ++++ .../controller/FlyingMoveControllerWASD.java | 74 + .../FlyingWithSpacebarMoveControllerWASD.java | 66 + .../purpur/controller/LookControllerWASD.java | 79 + .../purpur/controller/MoveControllerWASD.java | 92 + .../controller/WaterMoveControllerWASD.java | 53 + .../purpurmc/purpur/entity/ai/HasRider.java | 20 + .../purpur/entity/ai/HorseHasRider.java | 17 + .../purpur/entity/ai/LlamaHasRider.java | 17 + .../purpur/entity/projectile/DolphinSpit.java | 100 + .../entity/projectile/PhantomFlames.java | 122 + 24 files changed, 2633 insertions(+), 2759 deletions(-) create mode 100644 build-data/purpur.at delete mode 100644 patches/api/0006-Ridables.patch delete mode 100644 patches/generated-api/0001-Ridables.patch create mode 100644 purpur-api-generator/paper-patches/files/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java.patch create mode 100644 purpur-api/paper-patches/files/src/main/java/org/bukkit/entity/Entity.java.patch create mode 100644 purpur-api/src/main/java/org/purpurmc/purpur/event/entity/RidableMoveEvent.java create mode 100644 purpur-api/src/main/java/org/purpurmc/purpur/event/entity/RidableSpacebarEvent.java rename patches/server/0007-Ridables.patch => purpur-server/minecraft-patches/features/0001-Ridables.patch (57%) create mode 100644 purpur-server/minecraft-patches/sources/net/minecraft/core/BlockPos.java.patch create mode 100644 purpur-server/paper-patches/features/0002-Ridables.patch create mode 100644 purpur-server/src/main/java/org/purpurmc/purpur/controller/FlyingMoveControllerWASD.java create mode 100644 purpur-server/src/main/java/org/purpurmc/purpur/controller/FlyingWithSpacebarMoveControllerWASD.java create mode 100644 purpur-server/src/main/java/org/purpurmc/purpur/controller/LookControllerWASD.java create mode 100644 purpur-server/src/main/java/org/purpurmc/purpur/controller/MoveControllerWASD.java create mode 100644 purpur-server/src/main/java/org/purpurmc/purpur/controller/WaterMoveControllerWASD.java create mode 100644 purpur-server/src/main/java/org/purpurmc/purpur/entity/ai/HasRider.java create mode 100644 purpur-server/src/main/java/org/purpurmc/purpur/entity/ai/HorseHasRider.java create mode 100644 purpur-server/src/main/java/org/purpurmc/purpur/entity/ai/LlamaHasRider.java create mode 100644 purpur-server/src/main/java/org/purpurmc/purpur/entity/projectile/DolphinSpit.java create mode 100644 purpur-server/src/main/java/org/purpurmc/purpur/entity/projectile/PhantomFlames.java diff --git a/.gitignore b/.gitignore index 1eca5d0cc..230f52dce 100644 --- a/.gitignore +++ b/.gitignore @@ -52,7 +52,6 @@ manifest.mf # other stuff /run -build-data/ /purpur-server/build.gradle.kts /purpur-server/src/minecraft /paper-server diff --git a/build-data/purpur.at b/build-data/purpur.at new file mode 100644 index 000000000..da5a42839 --- /dev/null +++ b/build-data/purpur.at @@ -0,0 +1,3 @@ +# This file is auto generated, any changes may be overridden! +# See CONTRIBUTING.md on how to add access transformers. +protected net.minecraft.world.entity.Entity dimensions diff --git a/patches/api/0006-Ridables.patch b/patches/api/0006-Ridables.patch deleted file mode 100644 index 7ecc992d5..000000000 --- a/patches/api/0006-Ridables.patch +++ /dev/null @@ -1,196 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 4 May 2019 00:57:16 -0500 -Subject: [PATCH] Ridables - - -diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java -index 19272cff8d6d040e95b2644d70acdac606e06c16..5603ecc5d8f6ccf29333e1c47db3af36379a27d6 100644 ---- a/src/main/java/org/bukkit/entity/Entity.java -+++ b/src/main/java/org/bukkit/entity/Entity.java -@@ -1172,4 +1172,35 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent - */ - void broadcastHurtAnimation(@NotNull java.util.Collection players); - // Paper end - broadcast hurt animation -+ -+ // Purpur start -+ /** -+ * Get the riding player -+ * -+ * @return Riding player -+ */ -+ @Nullable -+ Player getRider(); -+ -+ /** -+ * Check if entity is being ridden -+ * -+ * @return True if being ridden -+ */ -+ boolean hasRider(); -+ -+ /** -+ * Check if entity is ridable -+ * -+ * @return True if ridable -+ */ -+ boolean isRidable(); -+ -+ /** -+ * Check if entity is ridable in water -+ * -+ * @return True if ridable in water -+ */ -+ boolean isRidableInWater(); -+ // Purpur end - } -diff --git a/src/main/java/org/purpurmc/purpur/event/entity/RidableMoveEvent.java b/src/main/java/org/purpurmc/purpur/event/entity/RidableMoveEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..c31a656daa3df1ab87302d8f14110a828c920102 ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/event/entity/RidableMoveEvent.java -@@ -0,0 +1,100 @@ -+package org.purpurmc.purpur.event.entity; -+ -+import com.google.common.base.Preconditions; -+import org.bukkit.Location; -+import org.bukkit.entity.Mob; -+import org.bukkit.entity.Player; -+import org.bukkit.event.Cancellable; -+import org.bukkit.event.HandlerList; -+import org.bukkit.event.entity.EntityEvent; -+import org.jetbrains.annotations.ApiStatus; -+import org.jspecify.annotations.NullMarked; -+ -+/** -+ * Triggered when a ridable mob moves with a rider -+ */ -+@NullMarked -+public class RidableMoveEvent extends EntityEvent implements Cancellable { -+ private static final HandlerList handlers = new HandlerList(); -+ private boolean canceled; -+ private final Player rider; -+ private Location from; -+ private Location to; -+ -+ @ApiStatus.Internal -+ public RidableMoveEvent(Mob entity, Player rider, Location from, Location to) { -+ super(entity); -+ this.rider = rider; -+ this.from = from; -+ this.to = to; -+ } -+ -+ @Override -+ public Mob getEntity() { -+ return (Mob) entity; -+ } -+ -+ public Player getRider() { -+ return rider; -+ } -+ -+ public boolean isCancelled() { -+ return canceled; -+ } -+ -+ public void setCancelled(boolean cancel) { -+ canceled = cancel; -+ } -+ -+ /** -+ * Gets the location this entity moved from -+ * -+ * @return Location the entity moved from -+ */ -+ public Location getFrom() { -+ return from; -+ } -+ -+ /** -+ * Sets the location to mark as where the entity moved from -+ * -+ * @param from New location to mark as the entity's previous location -+ */ -+ public void setFrom(Location from) { -+ validateLocation(from); -+ this.from = from; -+ } -+ -+ /** -+ * Gets the location this entity moved to -+ * -+ * @return Location the entity moved to -+ */ -+ public Location getTo() { -+ return to; -+ } -+ -+ /** -+ * Sets the location that this entity will move to -+ * -+ * @param to New Location this entity will move to -+ */ -+ public void setTo(Location to) { -+ validateLocation(to); -+ this.to = to; -+ } -+ -+ private void validateLocation(Location loc) { -+ Preconditions.checkArgument(loc != null, "Cannot use null location!"); -+ Preconditions.checkArgument(loc.getWorld() != null, "Cannot use null location with null world!"); -+ } -+ -+ @Override -+ public HandlerList getHandlers() { -+ return handlers; -+ } -+ -+ public static HandlerList getHandlerList() { -+ return handlers; -+ } -+} -diff --git a/src/main/java/org/purpurmc/purpur/event/entity/RidableSpacebarEvent.java b/src/main/java/org/purpurmc/purpur/event/entity/RidableSpacebarEvent.java -new file mode 100644 -index 0000000000000000000000000000000000000000..02de629f066ef7d4898b3053efa957edeea16a3f ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/event/entity/RidableSpacebarEvent.java -@@ -0,0 +1,38 @@ -+package org.purpurmc.purpur.event.entity; -+ -+import org.bukkit.entity.Entity; -+import org.bukkit.event.Cancellable; -+import org.bukkit.event.HandlerList; -+import org.bukkit.event.entity.EntityEvent; -+import org.jetbrains.annotations.ApiStatus; -+import org.jspecify.annotations.NullMarked; -+ -+@NullMarked -+public class RidableSpacebarEvent extends EntityEvent implements Cancellable { -+ private static final HandlerList handlers = new HandlerList(); -+ private boolean cancelled; -+ -+ @ApiStatus.Internal -+ public RidableSpacebarEvent(Entity entity) { -+ super(entity); -+ } -+ -+ @Override -+ public boolean isCancelled() { -+ return cancelled; -+ } -+ -+ @Override -+ public void setCancelled(boolean cancel) { -+ cancelled = cancel; -+ } -+ -+ @Override -+ public HandlerList getHandlers() { -+ return handlers; -+ } -+ -+ public static HandlerList getHandlerList() { -+ return handlers; -+ } -+} diff --git a/patches/generated-api/0001-Ridables.patch b/patches/generated-api/0001-Ridables.patch deleted file mode 100644 index 4552c2066..000000000 --- a/patches/generated-api/0001-Ridables.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: William Blake Galbreath -Date: Sat, 4 May 2019 00:57:16 -0500 -Subject: [PATCH] Ridables - - -diff --git a/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/com/destroystokyo/paper/entity/ai/VanillaGoal.java -index f15a7b4471cd31a487467ec7ecf7a186fa887a51..9b9eb256c4f17693e717e87e62a2e61b928f073a 100644 ---- a/com/destroystokyo/paper/entity/ai/VanillaGoal.java -+++ b/com/destroystokyo/paper/entity/ai/VanillaGoal.java -@@ -441,6 +441,12 @@ public interface VanillaGoal extends Goal { - - GoalKey ZOMBIE_ATTACK_TURTLE_EGG = create("zombie_attack_turtle_egg", Zombie.class); - -+ // Purpur start -+ GoalKey MOB_HAS_RIDER = GoalKey.of(Mob.class, NamespacedKey.minecraft("has_rider")); -+ GoalKey HORSE_HAS_RIDER = GoalKey.of(AbstractHorse.class, NamespacedKey.minecraft("horse_has_rider")); -+ GoalKey LLAMA_HAS_RIDER = GoalKey.of(Llama.class, NamespacedKey.minecraft("llama_has_rider")); -+ // Purpur end -+ - private static GoalKey create(final String key, final Class type) { - return GoalKey.of(type, NamespacedKey.minecraft(key)); - } diff --git a/purpur-api-generator/paper-patches/files/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java.patch b/purpur-api-generator/paper-patches/files/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java.patch new file mode 100644 index 000000000..3cdd63c72 --- /dev/null +++ b/purpur-api-generator/paper-patches/files/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java.patch @@ -0,0 +1,15 @@ +--- a/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java ++++ b/generated/com/destroystokyo/paper/entity/ai/VanillaGoal.java +@@ -441,6 +_,12 @@ + + GoalKey ZOMBIE_ATTACK_TURTLE_EGG = create("zombie_attack_turtle_egg", Zombie.class); + ++ // Purpur start - Ridables ++ GoalKey MOB_HAS_RIDER = GoalKey.of(Mob.class, NamespacedKey.minecraft("has_rider")); ++ GoalKey HORSE_HAS_RIDER = GoalKey.of(AbstractHorse.class, NamespacedKey.minecraft("horse_has_rider")); ++ GoalKey LLAMA_HAS_RIDER = GoalKey.of(Llama.class, NamespacedKey.minecraft("llama_has_rider")); ++ // Purpur end - Ridables ++ + private static GoalKey create(final String key, final Class type) { + return GoalKey.of(type, NamespacedKey.minecraft(key)); + } diff --git a/purpur-api/paper-patches/files/src/main/java/org/bukkit/entity/Entity.java.patch b/purpur-api/paper-patches/files/src/main/java/org/bukkit/entity/Entity.java.patch new file mode 100644 index 000000000..2fb28b23c --- /dev/null +++ b/purpur-api/paper-patches/files/src/main/java/org/bukkit/entity/Entity.java.patch @@ -0,0 +1,38 @@ +--- a/src/main/java/org/bukkit/entity/Entity.java ++++ b/src/main/java/org/bukkit/entity/Entity.java +@@ -1172,4 +_,35 @@ + */ + void broadcastHurtAnimation(@NotNull java.util.Collection players); + // Paper end - broadcast hurt animation ++ ++ // Purpur start - Ridables ++ /** ++ * Get the riding player ++ * ++ * @return Riding player ++ */ ++ @Nullable ++ Player getRider(); ++ ++ /** ++ * Check if entity is being ridden ++ * ++ * @return True if being ridden ++ */ ++ boolean hasRider(); ++ ++ /** ++ * Check if entity is ridable ++ * ++ * @return True if ridable ++ */ ++ boolean isRidable(); ++ ++ /** ++ * Check if entity is ridable in water ++ * ++ * @return True if ridable in water ++ */ ++ boolean isRidableInWater(); ++ // Purpur end - Ridables + } diff --git a/purpur-api/src/main/java/org/purpurmc/purpur/event/entity/RidableMoveEvent.java b/purpur-api/src/main/java/org/purpurmc/purpur/event/entity/RidableMoveEvent.java new file mode 100644 index 000000000..c31a656da --- /dev/null +++ b/purpur-api/src/main/java/org/purpurmc/purpur/event/entity/RidableMoveEvent.java @@ -0,0 +1,100 @@ +package org.purpurmc.purpur.event.entity; + +import com.google.common.base.Preconditions; +import org.bukkit.Location; +import org.bukkit.entity.Mob; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +/** + * Triggered when a ridable mob moves with a rider + */ +@NullMarked +public class RidableMoveEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean canceled; + private final Player rider; + private Location from; + private Location to; + + @ApiStatus.Internal + public RidableMoveEvent(Mob entity, Player rider, Location from, Location to) { + super(entity); + this.rider = rider; + this.from = from; + this.to = to; + } + + @Override + public Mob getEntity() { + return (Mob) entity; + } + + public Player getRider() { + return rider; + } + + public boolean isCancelled() { + return canceled; + } + + public void setCancelled(boolean cancel) { + canceled = cancel; + } + + /** + * Gets the location this entity moved from + * + * @return Location the entity moved from + */ + public Location getFrom() { + return from; + } + + /** + * Sets the location to mark as where the entity moved from + * + * @param from New location to mark as the entity's previous location + */ + public void setFrom(Location from) { + validateLocation(from); + this.from = from; + } + + /** + * Gets the location this entity moved to + * + * @return Location the entity moved to + */ + public Location getTo() { + return to; + } + + /** + * Sets the location that this entity will move to + * + * @param to New Location this entity will move to + */ + public void setTo(Location to) { + validateLocation(to); + this.to = to; + } + + private void validateLocation(Location loc) { + Preconditions.checkArgument(loc != null, "Cannot use null location!"); + Preconditions.checkArgument(loc.getWorld() != null, "Cannot use null location with null world!"); + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/purpur-api/src/main/java/org/purpurmc/purpur/event/entity/RidableSpacebarEvent.java b/purpur-api/src/main/java/org/purpurmc/purpur/event/entity/RidableSpacebarEvent.java new file mode 100644 index 000000000..02de629f0 --- /dev/null +++ b/purpur-api/src/main/java/org/purpurmc/purpur/event/entity/RidableSpacebarEvent.java @@ -0,0 +1,38 @@ +package org.purpurmc.purpur.event.entity; + +import org.bukkit.entity.Entity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.entity.EntityEvent; +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; + +@NullMarked +public class RidableSpacebarEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private boolean cancelled; + + @ApiStatus.Internal + public RidableSpacebarEvent(Entity entity) { + super(entity); + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/purpur-api/src/main/java/org/purpurmc/purpur/util/permissions/PurpurPermissions.java b/purpur-api/src/main/java/org/purpurmc/purpur/util/permissions/PurpurPermissions.java index a04ce450d..47ccd1786 100644 --- a/purpur-api/src/main/java/org/purpurmc/purpur/util/permissions/PurpurPermissions.java +++ b/purpur-api/src/main/java/org/purpurmc/purpur/util/permissions/PurpurPermissions.java @@ -29,6 +29,22 @@ public final class PurpurPermissions { public static Permission registerPermissions() { Permission purpur = DefaultPermissions.registerPermission(ROOT, "Gives the user the ability to use all Purpur utilities and commands", PermissionDefault.FALSE); + Permission ride = DefaultPermissions.registerPermission("allow.ride", "Allows the user to ride all mobs", PermissionDefault.FALSE, purpur); + for (String mob : mobs) { + DefaultPermissions.registerPermission("allow.ride." + mob, "Allows the user to ride " + mob, PermissionDefault.FALSE, ride); + } + ride.recalculatePermissibles(); + + Permission special = DefaultPermissions.registerPermission("allow.special", "Allows the user to use all mobs special abilities", PermissionDefault.FALSE, purpur); + for (String mob : mobs) { + DefaultPermissions.registerPermission("allow.special." + mob, "Allows the user to use " + mob + " special ability", PermissionDefault.FALSE, special); + } + special.recalculatePermissibles(); + + Permission powered = DefaultPermissions.registerPermission("allow.powered", "Allows the user to toggle all mobs powered state", PermissionDefault.FALSE, purpur); + DefaultPermissions.registerPermission("allow.powered.creeper", "Allows the user to toggle creeper powered state", PermissionDefault.FALSE, powered); + powered.recalculatePermissibles(); + purpur.recalculatePermissibles(); return purpur; } diff --git a/patches/server/0007-Ridables.patch b/purpur-server/minecraft-patches/features/0001-Ridables.patch similarity index 57% rename from patches/server/0007-Ridables.patch rename to purpur-server/minecraft-patches/features/0001-Ridables.patch index 8c0ddf9c4..0f58c76ef 100644 --- a/patches/server/0007-Ridables.patch +++ b/purpur-server/minecraft-patches/features/0001-Ridables.patch @@ -4,40 +4,36 @@ Date: Sun, 5 Jul 2020 22:19:49 -0500 Subject: [PATCH] Ridables -diff --git a/net/minecraft/core/BlockPos.java b/net/minecraft/core/BlockPos.java -index faffd87c357511ef00646971a16acf1009362c59..6714b4a39180affd101f1cab0d587cf2d3e6886a 100644 ---- a/net/minecraft/core/BlockPos.java -+++ b/net/minecraft/core/BlockPos.java -@@ -63,6 +63,12 @@ public class BlockPos extends Vec3i { - public static final int MAX_HORIZONTAL_COORDINATE = 33554431; - // Paper end - Optimize Bit Operations by inlining +diff --git a/net/minecraft/gametest/framework/GameTestHelper.java b/net/minecraft/gametest/framework/GameTestHelper.java +index fe4ae6bcdcbb55c47e9f9a4d63ead4c39e6d63cf..bf368ba3eecb6131dd23c1fcabf61f439ee6fdb5 100644 +--- a/net/minecraft/gametest/framework/GameTestHelper.java ++++ b/net/minecraft/gametest/framework/GameTestHelper.java +@@ -279,6 +279,8 @@ public class GameTestHelper { + return gameType.isCreative(); + } -+ // Purpur start - Ridables -+ public BlockPos(net.minecraft.world.entity.Entity entity) { -+ super(entity.getBlockX(), entity.getBlockY(), entity.getBlockZ()); -+ } -+ // Purpur end - Ridables ++ public void resetLastActionTime() {} // Purpur - Ridables + - public BlockPos(int x, int y, int z) { - super(x, y, z); - } + @Override + public boolean isLocalPlayer() { + return true; diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index ae4ebf509837e8d44255781c61d02873f8b74be8..ce4ce361061932162ace58070d44d1aa70189dbd 100644 +index 9c859025302ddb2c20cf6457fa4e4eaf7fbafdd7..6194203bb7a99af4257bed25af98ef870b2ff066 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -1857,6 +1857,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - Add EntityMoveEvent - net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers - worldserver.updateLagCompensationTick(); // Paper - lag compensation -+ worldserver.hasRidableMoveEvent = org.purpurmc.purpur.event.entity.RidableMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Purpur - Ridables - - gameprofilerfiller.push(() -> { - String s = String.valueOf(worldserver); +@@ -1708,6 +1708,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - Add EntityMoveEvent + serverLevel.updateLagCompensationTick(); // Paper - lag compensation + net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = serverLevel.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers ++ serverLevel.hasRidableMoveEvent = org.purpurmc.purpur.event.entity.RidableMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Purpur - Ridables + profilerFiller.push(() -> serverLevel + " " + serverLevel.dimension().location()); + /* Drop global time updates + if (this.tickCount % 20 == 0) { diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 1f898500d0e9b18a880645ceb0a8ff0fe75f4e48..4b9434b2d03cd24f5dac7098d2f1318fd12baddb 100644 +index ebeeb63c3dca505a3ce8b88feaa5d2ca20ec24a2..0029717fbd4f2475b07abf4f7036cebbe68949db 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -232,6 +232,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -215,6 +215,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current) @@ -46,10 +42,10 @@ index 1f898500d0e9b18a880645ceb0a8ff0fe75f4e48..4b9434b2d03cd24f5dac7098d2f1318f public LevelChunk getChunkIfLoaded(int x, int z) { return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper - Use getChunkIfLoadedImmediately diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 09a7809b89a4f302a1149850d4daeb471365d189..8207208d6fb3f982e9909add9e74a0dda69e8120 100644 +index dc146170def1b349291916f13164a5f4c43ee6f2..544b87f020ad2177b6ec86ce2d1e49a14be8c2b4 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -1030,6 +1030,15 @@ public class ServerPlayer extends net.minecraft.world.entity.player.Player imple +@@ -838,6 +838,15 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc this.trackEnteredOrExitedLavaOnVehicle(); this.updatePlayerAttributes(); this.advancements.flushDirty(this); @@ -66,32 +62,23 @@ index 09a7809b89a4f302a1149850d4daeb471365d189..8207208d6fb3f982e9909add9e74a0dd private void updatePlayerAttributes() { diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 84fa24880d02dc7ba1ec8bda3575be38447fd4b2..fbc59503316d566e88b037851afd74e5469c281b 100644 +index d248671b2e1c6256fc4d74320bdb29ca078bad0b..e2d30d0daae4ad088c723a2d85760c340fe83e9d 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -2887,6 +2887,8 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl +@@ -2746,6 +2746,8 @@ public class ServerGamePacketListenerImpl - ServerGamePacketListenerImpl.this.cserver.getPluginManager().callEvent(event); + ServerGamePacketListenerImpl.this.cserver.getPluginManager().callEvent(event); -+ player.processClick(enumhand); // Purpur - Ridables ++ player.processClick(hand); // Purpur - Ridables + - // Entity in bucket - SPIGOT-4048 and SPIGOT-6859a - if ((entity instanceof Bucketable && entity instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem)) { - entity.resendPossiblyDesyncedEntityData(ServerGamePacketListenerImpl.this.player); // Paper - The entire mob gets deleted, so resend it + // Entity in bucket - SPIGOT-4048 and SPIGOT-6859a + if ((target instanceof Bucketable && target instanceof LivingEntity && origItem != null && origItem.asItem() == Items.WATER_BUCKET) && (event.isCancelled() || ServerGamePacketListenerImpl.this.player.getInventory().getSelected() == null || ServerGamePacketListenerImpl.this.player.getInventory().getSelected().getItem() != origItem)) { + target.resendPossiblyDesyncedEntityData(ServerGamePacketListenerImpl.this.player); // Paper - The entire mob gets deleted, so resend it diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index 7ac7d0729705cb02f22277be3c467aed4f69ec0e..5c14180d92e1baebe59b08311746418e7d9f6a24 100644 +index 717540737a98ff54e61f0c3e15174d2f77ffe553..52465a528ad0bf0509b128e40779bbef843648a6 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -340,7 +340,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - private final Set tags; - private final double[] pistonDeltas; - private long pistonDeltasGameTime; -- private EntityDimensions dimensions; -+ protected EntityDimensions dimensions; // Purpur - private -> protected - Ridables - private float eyeHeight; - public boolean isInPowderSnow; - public boolean wasInPowderSnow; -@@ -3324,6 +3324,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3128,6 +3128,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.passengers = ImmutableList.copyOf(list); } @@ -105,7 +92,7 @@ index 7ac7d0729705cb02f22277be3c467aed4f69ec0e..5c14180d92e1baebe59b08311746418e this.gameEvent(GameEvent.ENTITY_MOUNT, passenger); } } -@@ -3363,6 +3370,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -3169,6 +3176,14 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return false; } // CraftBukkit end @@ -117,11 +104,11 @@ index 7ac7d0729705cb02f22277be3c467aed4f69ec0e..5c14180d92e1baebe59b08311746418e + } + // Purpur end - Ridables + - if (this.passengers.size() == 1 && this.passengers.get(0) == entity) { + if (this.passengers.size() == 1 && this.passengers.get(0) == passenger) { this.passengers = ImmutableList.of(); } else { -@@ -5355,4 +5370,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - return ((net.minecraft.server.level.ServerLevel) this.level).isPositionEntityTicking(this.blockPosition()); +@@ -5083,4 +5098,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + return ((ServerLevel) this.level).isPositionEntityTicking(this.blockPosition()); } // Paper end - Expose entity id counter + // Purpur start - Ridables @@ -166,11 +153,11 @@ index 7ac7d0729705cb02f22277be3c467aed4f69ec0e..5c14180d92e1baebe59b08311746418e + // Purpur end - Ridables } diff --git a/net/minecraft/world/entity/GlowSquid.java b/net/minecraft/world/entity/GlowSquid.java -index 397765b1547ae47b64963b3807b206c50a6650e1..293ffe990de70f4f8872f063388a3a50c60b68e6 100644 +index efee812785240c1ab1fd47514cfb236a3548f9cf..666455fff2b391b637cf1c07091e88100c5e1308 100644 --- a/net/minecraft/world/entity/GlowSquid.java +++ b/net/minecraft/world/entity/GlowSquid.java @@ -25,6 +25,19 @@ public class GlowSquid extends Squid { - super(type, world); + super(entityType, level); } + // Purpur start - Ridables @@ -190,10 +177,10 @@ index 397765b1547ae47b64963b3807b206c50a6650e1..293ffe990de70f4f8872f063388a3a50 protected ParticleOptions getInkParticle() { return ParticleTypes.GLOW_SQUID_INK; diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 96b4fbe4a4655777ff10b32e3257e2fac2aba12a..715b76bd0ccc0c29583a55f82a8ecd889ab49b56 100644 +index 195e1151f7b2a32d6c4eb67edd1952e38f58b266..67c99e33642964a1756d48e029e00f2676f07fbb 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -246,9 +246,9 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -250,9 +250,9 @@ public abstract class LivingEntity extends Entity implements Attackable { protected float rotOffs; public float lastHurt; public boolean jumping; @@ -206,37 +193,37 @@ index 96b4fbe4a4655777ff10b32e3257e2fac2aba12a..715b76bd0ccc0c29583a55f82a8ecd88 protected int lerpSteps; protected double lerpX; protected double lerpY; -@@ -323,7 +323,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - this.lastClimbablePos = Optional.empty(); - this.activeLocationDependentEnchantments = new EnumMap(EquipmentSlot.class); - this.appliedScale = 1.0F; -- this.attributes = new AttributeMap(DefaultAttributes.getSupplier(type)); -+ this.attributes = new AttributeMap(DefaultAttributes.getSupplier(type), this); // Purpur - Ridables +@@ -310,7 +310,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + + protected LivingEntity(EntityType entityType, Level level) { + super(entityType, level); +- this.attributes = new AttributeMap(DefaultAttributes.getSupplier(entityType)); ++ this.attributes = new AttributeMap(DefaultAttributes.getSupplier(entityType), this); // Purpur - Ridables this.craftAttributes = new CraftAttributeMap(this.attributes); // CraftBukkit - // CraftBukkit - setHealth(getMaxHealth()) inlined and simplified to skip the instanceof check for EntityPlayer, as getBukkitEntity() is not initialized in constructor - this.entityData.set(LivingEntity.DATA_HEALTH_ID, (float) this.getAttribute(Attributes.MAX_HEALTH).getValue()); -@@ -373,6 +373,7 @@ public abstract class LivingEntity extends Entity implements Attackable { - public static AttributeSupplier.Builder createLivingAttributes() { - return AttributeSupplier.builder().add(Attributes.MAX_HEALTH).add(Attributes.KNOCKBACK_RESISTANCE).add(Attributes.MOVEMENT_SPEED).add(Attributes.ARMOR).add(Attributes.ARMOR_TOUGHNESS).add(Attributes.MAX_ABSORPTION).add(Attributes.STEP_HEIGHT).add(Attributes.SCALE).add(Attributes.GRAVITY).add(Attributes.SAFE_FALL_DISTANCE).add(Attributes.FALL_DAMAGE_MULTIPLIER).add(Attributes.JUMP_STRENGTH).add(Attributes.OXYGEN_BONUS).add(Attributes.BURNING_TIME).add(Attributes.EXPLOSION_KNOCKBACK_RESISTANCE).add(Attributes.WATER_MOVEMENT_EFFICIENCY).add(Attributes.MOVEMENT_EFFICIENCY).add(Attributes.ATTACK_KNOCKBACK); + // CraftBukkit - this.setHealth(this.getMaxHealth()) inlined and simplified to skip the instanceof check for Player, as getBukkitEntity() is not initialized in constructor + this.entityData.set(LivingEntity.DATA_HEALTH_ID, this.getMaxHealth()); +@@ -377,6 +377,7 @@ public abstract class LivingEntity extends Entity implements Attackable { + .add(Attributes.MOVEMENT_EFFICIENCY) + .add(Attributes.ATTACK_KNOCKBACK); } + public boolean shouldSendAttribute(Attribute attribute) { return true; } // Purpur - Ridables @Override - protected void checkFallDamage(double heightDifference, boolean onGround, BlockState state, BlockPos landedPosition) { -@@ -3703,8 +3704,10 @@ public abstract class LivingEntity extends Entity implements Attackable { + protected void checkFallDamage(double y, boolean onGround, BlockState state, BlockPos pos) { +@@ -3477,8 +3478,10 @@ public abstract class LivingEntity extends Entity implements Attackable { this.pushEntities(); - gameprofilerfiller.pop(); + profilerFiller.pop(); // Paper start - Add EntityMoveEvent -- if (((ServerLevel) this.level()).hasEntityMoveEvent && !(this instanceof net.minecraft.world.entity.player.Player)) { +- if (((ServerLevel) this.level()).hasEntityMoveEvent && !(this instanceof Player)) { - if (this.xo != this.getX() || this.yo != this.getY() || this.zo != this.getZ() || this.yRotO != this.getYRot() || this.xRotO != this.getXRot()) { + // Purpur start - Ridables + if (this.xo != this.getX() || this.yo != this.getY() || this.zo != this.getZ() || this.yRotO != this.getYRot() || this.xRotO != this.getXRot()) { -+ if (((ServerLevel) this.level()).hasEntityMoveEvent && !(this instanceof net.minecraft.world.entity.player.Player)) { ++ if (((ServerLevel) this.level()).hasEntityMoveEvent && !(this instanceof Player)) { + // Purpur end - Ridables Location from = new Location(this.level().getWorld(), this.xo, this.yo, this.zo, this.yRotO, this.xRotO); Location to = new Location(this.level().getWorld(), this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot()); io.papermc.paper.event.entity.EntityMoveEvent event = new io.papermc.paper.event.entity.EntityMoveEvent(this.getBukkitLivingEntity(), from, to.clone()); -@@ -3714,6 +3717,21 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3488,6 +3491,21 @@ public abstract class LivingEntity extends Entity implements Attackable { this.absMoveTo(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ(), event.getTo().getYaw(), event.getTo().getPitch()); } } @@ -246,7 +233,7 @@ index 96b4fbe4a4655777ff10b32e3257e2fac2aba12a..715b76bd0ccc0c29583a55f82a8ecd88 + if (((ServerLevel) level()).hasRidableMoveEvent && this instanceof Mob) { + Location from = new Location(level().getWorld(), xo, yo, zo, this.yRotO, this.xRotO); + Location to = new Location(level().getWorld(), getX(), getY(), getZ(), this.getYRot(), this.getXRot()); -+ org.purpurmc.purpur.event.entity.RidableMoveEvent event = new org.purpurmc.purpur.event.entity.RidableMoveEvent((org.bukkit.entity.Mob) getBukkitLivingEntity(), (Player) getRider().getBukkitEntity(), from, to.clone()); ++ org.purpurmc.purpur.event.entity.RidableMoveEvent event = new org.purpurmc.purpur.event.entity.RidableMoveEvent((org.bukkit.entity.Mob) getBukkitLivingEntity(), (org.bukkit.entity.Player) getRider().getBukkitEntity(), from, to.clone()); + if (!event.callEvent()) { + absMoveTo(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch()); + } else if (!to.equals(event.getTo())) { @@ -257,13 +244,13 @@ index 96b4fbe4a4655777ff10b32e3257e2fac2aba12a..715b76bd0ccc0c29583a55f82a8ecd88 + // Purpur end - Ridables } // Paper end - Add EntityMoveEvent - world = this.level(); + if (this.level() instanceof ServerLevel serverLevel && this.isSensitiveToWater() && this.isInWaterRainOrBubble()) { diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java -index 5a0b51342f4a646101f4588697bcae7d1ca8a010..261288f51ed47b0eac80cc965c76683f3e13687f 100644 +index 1ed07fd23985a6bf8cf8300f74c92b7531a79fc6..e8f86c69f122d94d707eebd41b1e1c26edb3700a 100644 --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java -@@ -159,8 +159,8 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab - this.restrictRadius = -1.0F; +@@ -150,8 +150,8 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + super(entityType, level); this.goalSelector = new GoalSelector(); this.targetSelector = new GoalSelector(); - this.lookControl = new LookControl(this); @@ -272,9 +259,9 @@ index 5a0b51342f4a646101f4588697bcae7d1ca8a010..261288f51ed47b0eac80cc965c76683f + this.moveControl = new org.purpurmc.purpur.controller.MoveControllerWASD(this); // Purpur - Ridables this.jumpControl = new JumpControl(this); this.bodyRotationControl = this.createBodyControl(); - this.navigation = this.createNavigation(world); -@@ -1496,7 +1496,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab - protected void onOffspringSpawnedFromEgg(Player player, Mob child) {} + this.navigation = this.createNavigation(level); +@@ -1377,7 +1377,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab + } protected InteractionResult mobInteract(Player player, InteractionHand hand) { - return InteractionResult.PASS; @@ -282,7 +269,7 @@ index 5a0b51342f4a646101f4588697bcae7d1ca8a010..261288f51ed47b0eac80cc965c76683f } public boolean isWithinRestriction() { -@@ -1816,4 +1816,58 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -1694,4 +1694,58 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab public float[] getArmorDropChances() { return this.armorDropChances; } @@ -342,7 +329,7 @@ index 5a0b51342f4a646101f4588697bcae7d1ca8a010..261288f51ed47b0eac80cc965c76683f + // Purpur end - Ridables } diff --git a/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/net/minecraft/world/entity/ai/attributes/AttributeMap.java -index fb967ac7b3e7828301f08a7fe9b039441cf7da30..d6c98612ca15e506657d85f6872c1278e0b73652 100644 +index 4c808c7ef336de74048f40bd1cc8b14131a9325d..a25d74592e89e3d6339479c6dc2b6f45d1932cfc 100644 --- a/net/minecraft/world/entity/ai/attributes/AttributeMap.java +++ b/net/minecraft/world/entity/ai/attributes/AttributeMap.java @@ -23,14 +23,21 @@ public class AttributeMap { @@ -351,14 +338,15 @@ index fb967ac7b3e7828301f08a7fe9b039441cf7da30..d6c98612ca15e506657d85f6872c1278 private final AttributeSupplier supplier; + private final net.minecraft.world.entity.LivingEntity entity; // Purpur - Ridables - public AttributeMap(AttributeSupplier defaultAttributes) { + public AttributeMap(AttributeSupplier supplier) { +- this.supplier = supplier; + // Purpur start - Ridables -+ this(defaultAttributes, null); ++ this(supplier, null); + } + public AttributeMap(AttributeSupplier defaultAttributes, net.minecraft.world.entity.LivingEntity entity) { + this.entity = entity; + // Purpur end - Ridables - this.supplier = defaultAttributes; ++ this.supplier = defaultAttributes; } private void onAttributeModified(AttributeInstance instance) { @@ -372,13 +360,13 @@ index fb967ac7b3e7828301f08a7fe9b039441cf7da30..d6c98612ca15e506657d85f6872c1278 } public Collection getSyncableAttributes() { -- return this.attributes.values().stream().filter(attribute -> attribute.getAttribute().value().isClientSyncable()).collect(Collectors.toList()); -+ return this.attributes.values().stream().filter(attribute -> attribute.getAttribute().value().isClientSyncable() && (entity == null || entity.shouldSendAttribute(attribute.getAttribute().value()))).collect(Collectors.toList()); // Purpur - Ridables +- return this.attributes.values().stream().filter(instance -> instance.getAttribute().value().isClientSyncable()).collect(Collectors.toList()); ++ return this.attributes.values().stream().filter(instance -> instance.getAttribute().value().isClientSyncable() && (entity == null || entity.shouldSendAttribute(instance.getAttribute().value()))).collect(Collectors.toList()); // Purpur - Ridables } @Nullable diff --git a/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java b/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java -index c76438d5ce2330eca16dc0b381f97e9506f84aef..8ccbf0386aa453e82fc0f82d2aefd1e08b6c3345 100644 +index 33527a1825119f3667fb3c7ccec318f2c7328ec9..61ed4d687120fcbb7b91863e400f3657ebcde687 100644 --- a/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java +++ b/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java @@ -131,7 +131,7 @@ public class DefaultAttributes { @@ -391,11 +379,11 @@ index c76438d5ce2330eca16dc0b381f97e9506f84aef..8ccbf0386aa453e82fc0f82d2aefd1e0 .put(EntityType.PIGLIN, Piglin.createAttributes().build()) .put(EntityType.PIGLIN_BRUTE, PiglinBrute.createAttributes().build()) diff --git a/net/minecraft/world/entity/ai/control/MoveControl.java b/net/minecraft/world/entity/ai/control/MoveControl.java -index c8fd5696de7c3623cdb4f498190a5c2708cf843e..2a6e5a9b35102ef540b561ec7ef5a5f119c564fe 100644 +index 0f9bf0cb0655a6ed449a86e99b17f89b4e3264df..1860b4ab2314f5da017313977c6423e735a4f96b 100644 --- a/net/minecraft/world/entity/ai/control/MoveControl.java +++ b/net/minecraft/world/entity/ai/control/MoveControl.java @@ -29,6 +29,20 @@ public class MoveControl implements Control { - this.mob = entity; + this.mob = mob; } + // Purpur start - Ridables @@ -416,7 +404,7 @@ index c8fd5696de7c3623cdb4f498190a5c2708cf843e..2a6e5a9b35102ef540b561ec7ef5a5f1 return this.operation == MoveControl.Operation.MOVE_TO; } diff --git a/net/minecraft/world/entity/ai/control/SmoothSwimmingLookControl.java b/net/minecraft/world/entity/ai/control/SmoothSwimmingLookControl.java -index fbfc2f2515ad709b2c1212aef9521e795547d66b..ebe941aeb959fc34372bfc59bc3a13421167b4cf 100644 +index d7f9b3b2b1077ea10e8f64b87c8f4c4354e90858..713f62b34a91fa76f40e49a5e390145f70755e58 100644 --- a/net/minecraft/world/entity/ai/control/SmoothSwimmingLookControl.java +++ b/net/minecraft/world/entity/ai/control/SmoothSwimmingLookControl.java @@ -3,7 +3,7 @@ package net.minecraft.world.entity.ai.control; @@ -436,20 +424,19 @@ index fbfc2f2515ad709b2c1212aef9521e795547d66b..ebe941aeb959fc34372bfc59bc3a1342 + public void vanillaTick() { // Purpur - Ridables if (this.lookAtCooldown > 0) { this.lookAtCooldown--; - this.getYRotD().ifPresent(yaw -> this.mob.yHeadRot = this.rotateTowards(this.mob.yHeadRot, yaw + 20.0F, this.yMaxRotSpeed)); + this.getYRotD().ifPresent(rotationWanted -> this.mob.yHeadRot = this.rotateTowards(this.mob.yHeadRot, rotationWanted + 20.0F, this.yMaxRotSpeed)); diff --git a/net/minecraft/world/entity/ambient/Bat.java b/net/minecraft/world/entity/ambient/Bat.java -index 60c2868f255d372226e0c1389caaa5477bbef41e..add1c146cd7428547d9ef8810841b4cf39a6a05e 100644 +index 5ebe7b1dce367d5c5e1136b97b2b9f6737595201..f01ddd493d38e2e231c59841649a2e5bf3b87c49 100644 --- a/net/minecraft/world/entity/ambient/Bat.java +++ b/net/minecraft/world/entity/ambient/Bat.java -@@ -47,12 +47,59 @@ public class Bat extends AmbientCreature { +@@ -42,11 +42,58 @@ public class Bat extends AmbientCreature { - public Bat(EntityType type, Level world) { - super(type, world); + public Bat(EntityType entityType, Level level) { + super(entityType, level); + this.moveControl = new org.purpurmc.purpur.controller.FlyingWithSpacebarMoveControllerWASD(this, 0.075F); // Purpur - Ridables - if (!world.isClientSide) { + if (!level.isClientSide) { this.setResting(true); } - } + // Purpur start - Ridables @@ -477,7 +464,7 @@ index 60c2868f255d372226e0c1389caaa5477bbef41e..add1c146cd7428547d9ef8810841b4cf + } + + @Override -+ public void onMount(Player rider) { ++ public void onMount(net.minecraft.world.entity.player.Player rider) { + super.onMount(rider); + if (isResting()) { + setResting(false); @@ -500,20 +487,20 @@ index 60c2868f255d372226e0c1389caaa5477bbef41e..add1c146cd7428547d9ef8810841b4cf + @Override public boolean isFlapping() { - return !this.isResting() && (float) this.tickCount % 10.0F == 0.0F; -@@ -102,7 +149,7 @@ public class Bat extends AmbientCreature { - protected void pushEntities() {} + return !this.isResting() && this.tickCount % 10.0F == 0.0F; +@@ -98,7 +145,7 @@ public class Bat extends AmbientCreature { + } public static AttributeSupplier.Builder createAttributes() { -- return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 6.0D); -+ return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 6.0D).add(Attributes.FLYING_SPEED, 0.6D); // Purpur - Ridables +- return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 6.0); ++ return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 6.0).add(Attributes.FLYING_SPEED, 0.6D); // Purpur - Ridables } public boolean isResting() { -@@ -135,6 +182,14 @@ public class Bat extends AmbientCreature { +@@ -129,6 +176,14 @@ public class Bat extends AmbientCreature { @Override - protected void customServerAiStep(ServerLevel world) { + protected void customServerAiStep(ServerLevel level) { + // Purpur start - Ridables + if (getRider() != null && this.isControllable()) { + Vec3 mot = getDeltaMovement(); @@ -522,11 +509,11 @@ index 60c2868f255d372226e0c1389caaa5477bbef41e..add1c146cd7428547d9ef8810841b4cf + } + // Purpur end - Ridables + - super.customServerAiStep(world); - BlockPos blockposition = this.blockPosition(); - BlockPos blockposition1 = blockposition.above(); + super.customServerAiStep(level); + BlockPos blockPos = this.blockPosition(); + BlockPos blockPos1 = blockPos.above(); diff --git a/net/minecraft/world/entity/animal/AbstractFish.java b/net/minecraft/world/entity/animal/AbstractFish.java -index 9aedc62b1766f6a7db4da7eba55167d21d698791..d1fa6b6a18bd7a44e398eed17f2ff127b09f222a 100644 +index c0997c8c0f8ee4474d3acdd5938b1879c4e589a2..28ae152125ed83d8917674b6068f227f87890f30 100644 --- a/net/minecraft/world/entity/animal/AbstractFish.java +++ b/net/minecraft/world/entity/animal/AbstractFish.java @@ -87,6 +87,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { @@ -539,24 +526,24 @@ index 9aedc62b1766f6a7db4da7eba55167d21d698791..d1fa6b6a18bd7a44e398eed17f2ff127 this.goalSelector.addGoal(4, new AbstractFish.FishSwimGoal(this)); @@ -100,7 +101,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { @Override - public void travel(Vec3 movementInput) { + public void travel(Vec3 travelVector) { if (this.isControlledByLocalInstance() && this.isInWater()) { -- this.moveRelative(0.01F, movementInput); -+ this.moveRelative(getRider() != null ? getSpeed() : 0.01F, movementInput); // Purpur - Ridables +- this.moveRelative(0.01F, travelVector); ++ this.moveRelative(getRider() != null ? getSpeed() : 0.01F, travelVector); // Purpur - Ridables this.move(MoverType.SELF, this.getDeltaMovement()); this.setDeltaMovement(this.getDeltaMovement().scale(0.9)); if (this.getTarget() == null) { -@@ -161,7 +162,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { - protected void playStepSound(BlockPos pos, BlockState state) { +@@ -160,7 +161,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { + protected void playStepSound(BlockPos pos, BlockState block) { } - static class FishMoveControl extends MoveControl { + static class FishMoveControl extends org.purpurmc.purpur.controller.WaterMoveControllerWASD { // Purpur - Ridables private final AbstractFish fish; - FishMoveControl(AbstractFish owner) { -@@ -169,14 +170,22 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { - this.fish = owner; + FishMoveControl(AbstractFish mob) { +@@ -168,14 +169,22 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable { + this.fish = mob; } + // Purpur start - Ridables @@ -579,20 +566,20 @@ index 9aedc62b1766f6a7db4da7eba55167d21d698791..d1fa6b6a18bd7a44e398eed17f2ff127 + float f = (float)(this.getSpeedModifier() * this.fish.getAttributeValue(Attributes.MOVEMENT_SPEED)); // Purpur - Ridables this.fish.setSpeed(Mth.lerp(0.125F, this.fish.getSpeed(), f)); double d = this.wantedX - this.fish.getX(); - double e = this.wantedY - this.fish.getY(); + double d1 = this.wantedY - this.fish.getY(); diff --git a/net/minecraft/world/entity/animal/Bee.java b/net/minecraft/world/entity/animal/Bee.java -index 0bafe14342c1acce131ad34717c18aed3718deed..13f6e4c83e1775daadb13e3532d7dfe6eef15aac 100644 +index 94244b148533ef026bf5c56abbc2bb5cfa83c938..474240c0fd68dbfe18b8fce7ae6e7634eea65956 100644 --- a/net/minecraft/world/entity/animal/Bee.java +++ b/net/minecraft/world/entity/animal/Bee.java -@@ -154,6 +154,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { - public Bee(EntityType type, Level world) { - super(type, world); - this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(this.random, 20, 60); +@@ -145,6 +145,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { + + public Bee(EntityType entityType, Level level) { + super(entityType, level); + final org.purpurmc.purpur.controller.FlyingMoveControllerWASD flyingController = new org.purpurmc.purpur.controller.FlyingMoveControllerWASD(this, 0.25F, 1.0F, false); // Purpur - Ridables // Paper start - Fix MC-167279 class BeeFlyingMoveControl extends FlyingMoveControl { public BeeFlyingMoveControl(final Mob entity, final int maxPitchChange, final boolean noGravity) { -@@ -162,11 +163,24 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -153,11 +154,24 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @Override public void tick() { @@ -617,7 +604,7 @@ index 0bafe14342c1acce131ad34717c18aed3718deed..13f6e4c83e1775daadb13e3532d7dfe6 } this.moveControl = new BeeFlyingMoveControl(this, 20, true); // Paper end - Fix MC-167279 -@@ -178,6 +192,40 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -169,6 +183,40 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.setPathfindingMalus(PathType.FENCE, -1.0F); } @@ -658,31 +645,30 @@ index 0bafe14342c1acce131ad34717c18aed3718deed..13f6e4c83e1775daadb13e3532d7dfe6 @Override protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); -@@ -192,6 +240,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { +@@ -183,6 +231,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @Override protected void registerGoals() { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.goalSelector.addGoal(0, new Bee.BeeAttackGoal(this, 1.399999976158142D, true)); + this.goalSelector.addGoal(0, new Bee.BeeAttackGoal(this, 1.4F, true)); this.goalSelector.addGoal(1, new Bee.BeeEnterHiveGoal()); - this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D)); -@@ -211,6 +260,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { + this.goalSelector.addGoal(2, new BreedGoal(this, 1.0)); +@@ -200,6 +249,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { this.goalSelector.addGoal(7, new Bee.BeeGrowCropGoal()); this.goalSelector.addGoal(8, new Bee.BeeWanderGoal()); this.goalSelector.addGoal(9, new FloatGoal(this)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, (new Bee.BeeHurtByOtherGoal(this)).setAlertOthers(new Class[0])); + this.targetSelector.addGoal(1, new Bee.BeeHurtByOtherGoal(this).setAlertOthers(new Class[0])); this.targetSelector.addGoal(2, new Bee.BeeBecomeAngryTargetGoal(this)); this.targetSelector.addGoal(3, new ResetUniversalAngerTargetGoal<>(this, true)); -@@ -738,16 +788,16 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { - return state.is(BlockTags.BEE_ATTRACTIVE) ? ((Boolean) state.getValueOrElse(BlockStateProperties.WATERLOGGED, false) ? false : (state.is(Blocks.SUNFLOWER) ? state.getValue(DoublePlantBlock.HALF) == DoubleBlockHalf.UPPER : true)) : false; +@@ -1083,15 +1133,15 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { + } } -- private class BeeLookControl extends LookControl { -+ private class BeeLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - Ridables - - BeeLookControl(final Mob entity) { - super(entity); +- class BeeLookControl extends LookControl { ++ class BeeLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - Ridables + BeeLookControl(final Mob mob) { + super(mob); } @Override @@ -695,10 +681,10 @@ index 0bafe14342c1acce131ad34717c18aed3718deed..13f6e4c83e1775daadb13e3532d7dfe6 } diff --git a/net/minecraft/world/entity/animal/Cat.java b/net/minecraft/world/entity/animal/Cat.java -index 989b7be74eaeba7f40eac87c7ee7f252cb0c05c9..472bbf4c3f932e2b1c7d7fa3c74b41f5be11431f 100644 +index 1a7a5c81a260cc740994d1a63c4775c41c238dea..b4cb2312a1948781cf087fa6d2eb8bb96667605e 100644 --- a/net/minecraft/world/entity/animal/Cat.java +++ b/net/minecraft/world/entity/animal/Cat.java -@@ -100,12 +100,38 @@ public class Cat extends TamableAnimal implements VariantHolder { - return itemstack.is(ItemTags.CAT_FOOD); - }, true); + this.temptGoal = new Cat.CatTemptGoal(this, 0.6, itemStack -> itemStack.is(ItemTags.CAT_FOOD), true); this.goalSelector.addGoal(1, new FloatGoal(this)); + this.goalSelector.addGoal(1, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.goalSelector.addGoal(1, new TamableAnimal.TamableAnimalPanicGoal(1.5D)); + this.goalSelector.addGoal(1, new TamableAnimal.TamableAnimalPanicGoal(1.5)); this.goalSelector.addGoal(2, new SitWhenOrderedToGoal(this)); this.goalSelector.addGoal(3, new Cat.CatRelaxOnOwnerGoal(this)); -@@ -118,6 +144,7 @@ public class Cat extends TamableAnimal implements VariantHolder(this, Rabbit.class, false, (TargetingConditions.Selector) null)); + this.targetSelector.addGoal(1, new NonTameRandomTargetGoal<>(this, Rabbit.class, false, null)); this.targetSelector.addGoal(1, new NonTameRandomTargetGoal<>(this, Turtle.class, false, Turtle.BABY_ON_LAND_SELECTOR)); } -@@ -375,6 +402,7 @@ public class Cat extends TamableAnimal implements VariantHolder { + this.goalSelector.addGoal(1, new PanicGoal(this, 1.4)); + this.goalSelector.addGoal(2, new BreedGoal(this, 1.0)); + this.goalSelector.addGoal(3, new TemptGoal(this, 1.0, itemStack -> itemStack.is(ItemTags.CHICKEN_FOOD), false)); diff --git a/net/minecraft/world/entity/animal/Cod.java b/net/minecraft/world/entity/animal/Cod.java -index 824e5e4fe7619ae46061c3c978c9a044db8c84ab..fcf7073dd2d79f1483bdc6e7fdc37c8c260ae418 100644 +index 708bcc39e7242292d5d5bfcaf599e3738628df9b..6a19086e272363701260801f3c6db9b5c91b8ef5 100644 --- a/net/minecraft/world/entity/animal/Cod.java +++ b/net/minecraft/world/entity/animal/Cod.java @@ -13,6 +13,18 @@ public class Cod extends AbstractSchoolingFish { - super(type, world); + super(entityType, level); } + // Purpur start - Ridables @@ -809,11 +793,11 @@ index 824e5e4fe7619ae46061c3c978c9a044db8c84ab..fcf7073dd2d79f1483bdc6e7fdc37c8c public ItemStack getBucketItemStack() { return new ItemStack(Items.COD_BUCKET); diff --git a/net/minecraft/world/entity/animal/Cow.java b/net/minecraft/world/entity/animal/Cow.java -index 3e00bbff266fc71b07014e7e047d77b7f809239f..dc7ccfe90a82892d65098a325fd71fbbc734da86 100644 +index befb99f0a96cb23f139061f92497737e9203a8fd..b2bf4276952fa1c984bf0571b041be4141fbdf3a 100644 --- a/net/minecraft/world/entity/animal/Cow.java +++ b/net/minecraft/world/entity/animal/Cow.java -@@ -44,9 +44,27 @@ public class Cow extends Animal { - super(type, world); +@@ -38,9 +38,27 @@ public class Cow extends Animal { + super(entityType, level); } + // Purpur start - Ridables @@ -837,38 +821,37 @@ index 3e00bbff266fc71b07014e7e047d77b7f809239f..dc7ccfe90a82892d65098a325fd71fbb protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.goalSelector.addGoal(1, new PanicGoal(this, 2.0D)); - this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D)); - this.goalSelector.addGoal(3, new TemptGoal(this, 1.25D, (itemstack) -> { -@@ -94,6 +112,7 @@ public class Cow extends Animal { + this.goalSelector.addGoal(1, new PanicGoal(this, 2.0)); + this.goalSelector.addGoal(2, new BreedGoal(this, 1.0)); + this.goalSelector.addGoal(3, new TemptGoal(this, 1.25, itemStack -> itemStack.is(ItemTags.COW_FOOD), false)); +@@ -86,13 +104,14 @@ public class Cow extends Animal { @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { + if (getRider() != null) return InteractionResult.PASS; // Purpur - Ridables - ItemStack itemstack = player.getItemInHand(hand); - - if (itemstack.is(Items.BUCKET) && !this.isBaby()) { -@@ -102,7 +121,7 @@ public class Cow extends Animal { - + ItemStack itemInHand = player.getItemInHand(hand); + if (itemInHand.is(Items.BUCKET) && !this.isBaby()) { + // CraftBukkit start - Got milk? + org.bukkit.event.player.PlayerBucketFillEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) player.level(), player, this.blockPosition(), this.blockPosition(), null, itemInHand, Items.MILK_BUCKET, hand); if (event.isCancelled()) { player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync - return InteractionResult.PASS; + return tryRide(player, hand); // Purpur - Ridables } // CraftBukkit end - + player.playSound(SoundEvents.COW_MILK, 1.0F, 1.0F); diff --git a/net/minecraft/world/entity/animal/Dolphin.java b/net/minecraft/world/entity/animal/Dolphin.java -index 5af4d590a9b0f17ba53c6959d9c18bd1269878a4..af677b6581514a07e6455977ffc591538d43bbc6 100644 +index 4141052dfd635804195a5cfa24dbd0394355a7da..0e4112793dddc0d75f4bed35bb880c03b2d1318f 100644 --- a/net/minecraft/world/entity/animal/Dolphin.java +++ b/net/minecraft/world/entity/animal/Dolphin.java -@@ -85,14 +85,82 @@ public class Dolphin extends AgeableWaterCreature { - return !entityitem.hasPickUpDelay() && entityitem.isAlive() && entityitem.isInWater(); - }; +@@ -71,14 +71,82 @@ public class Dolphin extends AgeableWaterCreature { + private static final int TOTAL_MOISTNESS_LEVEL = 2400; + public static final Predicate ALLOWED_ITEMS = itemEntity -> !itemEntity.hasPickUpDelay() && itemEntity.isAlive() && itemEntity.isInWater(); public static final float BABY_SCALE = 0.65F; + private int spitCooldown; // Purpur - Ridables - public Dolphin(EntityType type, Level world) { - super(type, world); + public Dolphin(EntityType entityType, Level level) { + super(entityType, level); - this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true); + // Purpur start - Ridables + class DolphinMoveControl extends SmoothSwimmingMoveControl { @@ -931,7 +914,7 @@ index 5af4d590a9b0f17ba53c6959d9c18bd1269878a4..af677b6581514a07e6455977ffc59153 + loc.setPitch(loc.getPitch() - 10); + org.bukkit.util.Vector target = loc.getDirection().normalize().multiply(10).add(loc.toVector()); + -+ org.purpurmc.purpur.entity.DolphinSpit spit = new org.purpurmc.purpur.entity.DolphinSpit(level(), this); ++ org.purpurmc.purpur.entity.projectile.DolphinSpit spit = new org.purpurmc.purpur.entity.projectile.DolphinSpit(level(), this); + spit.shoot(target.getX() - getX(), target.getY() - getY(), target.getZ() - getZ(), level().purpurConfig.dolphinSpitSpeed, 5.0F); + + level().addFreshEntity(spit); @@ -944,24 +927,24 @@ index 5af4d590a9b0f17ba53c6959d9c18bd1269878a4..af677b6581514a07e6455977ffc59153 + @Nullable @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, EntitySpawnReason spawnReason, @Nullable SpawnGroupData entityData) { -@@ -177,6 +245,7 @@ public class Dolphin extends AgeableWaterCreature { + public SpawnGroupData finalizeSpawn( +@@ -169,6 +237,7 @@ public class Dolphin extends AgeableWaterCreature { protected void registerGoals() { this.goalSelector.addGoal(0, new BreathAirGoal(this)); this.goalSelector.addGoal(0, new TryFindWaterGoal(this)); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.goalSelector.addGoal(1, new Dolphin.DolphinSwimToTreasureGoal(this)); - this.goalSelector.addGoal(2, new Dolphin.DolphinSwimWithPlayerGoal(this, 4.0D)); - this.goalSelector.addGoal(4, new RandomSwimmingGoal(this, 1.0D, 10)); -@@ -187,6 +256,7 @@ public class Dolphin extends AgeableWaterCreature { + this.goalSelector.addGoal(2, new Dolphin.DolphinSwimWithPlayerGoal(this, 4.0)); + this.goalSelector.addGoal(4, new RandomSwimmingGoal(this, 1.0, 10)); +@@ -179,6 +248,7 @@ public class Dolphin extends AgeableWaterCreature { this.goalSelector.addGoal(8, new Dolphin.PlayWithItemsGoal()); this.goalSelector.addGoal(8, new FollowBoatGoal(this)); - this.goalSelector.addGoal(9, new AvoidEntityGoal<>(this, Guardian.class, 8.0F, 1.0D, 1.0D)); + this.goalSelector.addGoal(9, new AvoidEntityGoal<>(this, Guardian.class, 8.0F, 1.0, 1.0)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[]{Guardian.class})).setAlertOthers()); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Guardian.class).setAlertOthers()); } -@@ -231,7 +301,7 @@ public class Dolphin extends AgeableWaterCreature { +@@ -223,7 +293,7 @@ public class Dolphin extends AgeableWaterCreature { @Override protected boolean canRide(Entity entity) { @@ -970,7 +953,7 @@ index 5af4d590a9b0f17ba53c6959d9c18bd1269878a4..af677b6581514a07e6455977ffc59153 } @Override -@@ -264,6 +334,11 @@ public class Dolphin extends AgeableWaterCreature { +@@ -252,6 +322,11 @@ public class Dolphin extends AgeableWaterCreature { @Override public void tick() { super.tick(); @@ -983,10 +966,10 @@ index 5af4d590a9b0f17ba53c6959d9c18bd1269878a4..af677b6581514a07e6455977ffc59153 this.setAirSupply(this.getMaxAirSupply()); } else { diff --git a/net/minecraft/world/entity/animal/Fox.java b/net/minecraft/world/entity/animal/Fox.java -index d48c2bdb004c86e9e08680138fe51dc3b2975a64..ce5ac300582f61d0f3eeb1e94340cfefbdff1ba9 100644 +index 44bb04cc9796a16f5477d8f2ad22af62c9af1fc3..ff22b9bd7eb2b60fac58cae0a2be1d93a6eef7b7 100644 --- a/net/minecraft/world/entity/animal/Fox.java +++ b/net/minecraft/world/entity/animal/Fox.java -@@ -144,6 +144,44 @@ public class Fox extends Animal implements VariantHolder { +@@ -129,6 +129,44 @@ public class Fox extends Animal implements VariantHolder { this.getNavigation().setRequiredPathLength(32.0F); } @@ -1031,29 +1014,28 @@ index d48c2bdb004c86e9e08680138fe51dc3b2975a64..ce5ac300582f61d0f3eeb1e94340cfef @Override protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); -@@ -163,6 +201,7 @@ public class Fox extends Animal implements VariantHolder { - return entityliving instanceof AbstractSchoolingFish; - }); +@@ -148,6 +186,7 @@ public class Fox extends Animal implements VariantHolder { + this, AbstractFish.class, 20, false, false, (entity, level) -> entity instanceof AbstractSchoolingFish + ); this.goalSelector.addGoal(0, new Fox.FoxFloatGoal()); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.goalSelector.addGoal(0, new ClimbOnTopOfPowderSnowGoal(this, this.level())); this.goalSelector.addGoal(1, new Fox.FaceplantGoal()); - this.goalSelector.addGoal(2, new Fox.FoxPanicGoal(2.2D)); -@@ -189,6 +228,7 @@ public class Fox extends Animal implements VariantHolder { + this.goalSelector.addGoal(2, new Fox.FoxPanicGoal(2.2)); +@@ -175,6 +214,7 @@ public class Fox extends Animal implements VariantHolder { this.goalSelector.addGoal(11, new Fox.FoxSearchForItemsGoal()); this.goalSelector.addGoal(12, new Fox.FoxLookAtPlayerGoal(this, Player.class, 24.0F)); this.goalSelector.addGoal(13, new Fox.PerchAndSearchGoal()); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(3, new Fox.DefendTrustedTargetGoal(LivingEntity.class, false, false, (entityliving, worldserver) -> { - return Fox.TRUSTED_TARGET_SELECTOR.test(entityliving) && !this.trusts(entityliving.getUUID()); - })); -@@ -754,16 +794,16 @@ public class Fox extends Animal implements VariantHolder { - return new Vec3(0.0D, (double) (0.55F * this.getEyeHeight()), (double) (this.getBbWidth() * 0.4F)); + this.targetSelector + .addGoal( + 3, +@@ -1066,15 +1106,15 @@ public class Fox extends Animal implements VariantHolder { + } } - public class FoxLookControl extends LookControl { + public class FoxLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - Ridables - public FoxLookControl() { super(Fox.this); } @@ -1065,15 +1047,14 @@ index d48c2bdb004c86e9e08680138fe51dc3b2975a64..ce5ac300582f61d0f3eeb1e94340cfef - super.tick(); + super.vanillaTick(); // Purpur - Ridables } - } -@@ -774,16 +814,16 @@ public class Fox extends Animal implements VariantHolder { + +@@ -1110,15 +1150,15 @@ public class Fox extends Animal implements VariantHolder { } } -- private class FoxMoveControl extends MoveControl { -+ private class FoxMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables - +- class FoxMoveControl extends MoveControl { ++ class FoxMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables public FoxMoveControl() { super(Fox.this); } @@ -1085,14 +1066,14 @@ index d48c2bdb004c86e9e08680138fe51dc3b2975a64..ce5ac300582f61d0f3eeb1e94340cfef - super.tick(); + super.vanillaTick(); // Purpur - Ridables } - } + } diff --git a/net/minecraft/world/entity/animal/IronGolem.java b/net/minecraft/world/entity/animal/IronGolem.java -index e07b79ef172095c1800c88342b3ac8dc7703aea2..938a0c6f7cfbb6cd459d5a2ec46f912d45fd2226 100644 +index 8e9ba307a0528eb1aef56bdc0f4ded0e71621253..654f5855e1b69f05205e6a132d79ac94b929eeb4 100644 --- a/net/minecraft/world/entity/animal/IronGolem.java +++ b/net/minecraft/world/entity/animal/IronGolem.java -@@ -62,8 +62,27 @@ public class IronGolem extends AbstractGolem implements NeutralMob { - super(type, world); +@@ -61,8 +61,27 @@ public class IronGolem extends AbstractGolem implements NeutralMob { + super(entityType, level); } + // Purpur start - Ridables @@ -1116,39 +1097,38 @@ index e07b79ef172095c1800c88342b3ac8dc7703aea2..938a0c6f7cfbb6cd459d5a2ec46f912d protected void registerGoals() { + if (level().purpurConfig.ironGolemCanSwim) this.goalSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.FloatGoal(this)); // Purpur - Ridables + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.0D, true)); - this.goalSelector.addGoal(2, new MoveTowardsTargetGoal(this, 0.9D, 32.0F)); - this.goalSelector.addGoal(2, new MoveBackToVillageGoal(this, 0.6D, false)); -@@ -71,6 +90,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { + this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.0, true)); + this.goalSelector.addGoal(2, new MoveTowardsTargetGoal(this, 0.9, 32.0F)); + this.goalSelector.addGoal(2, new MoveBackToVillageGoal(this, 0.6, false)); +@@ -70,6 +89,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob { this.goalSelector.addGoal(5, new OfferFlowerGoal(this)); this.goalSelector.addGoal(7, new LookAtPlayerGoal(this, Player.class, 6.0F)); this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.targetSelector.addGoal(1, new DefendVillageTargetGoal(this)); - this.targetSelector.addGoal(2, new HurtByTargetGoal(this, new Class[0])); + this.targetSelector.addGoal(2, new HurtByTargetGoal(this)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt)); -@@ -267,13 +287,13 @@ public class IronGolem extends AbstractGolem implements NeutralMob { - ItemStack itemstack = player.getItemInHand(hand); - - if (!itemstack.is(Items.IRON_INGOT)) { +@@ -256,12 +276,12 @@ public class IronGolem extends AbstractGolem implements NeutralMob { + protected InteractionResult mobInteract(Player player, InteractionHand hand) { + ItemStack itemInHand = player.getItemInHand(hand); + if (!itemInHand.is(Items.IRON_INGOT)) { - return InteractionResult.PASS; + return tryRide(player, hand); // Purpur - Ridables } else { - float f = this.getHealth(); - + float health = this.getHealth(); this.heal(25.0F); - if (this.getHealth() == f) { + if (this.getHealth() == health) { - return InteractionResult.PASS; + return tryRide(player, hand); // Purpur - Ridables } else { - float f1 = 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F; - + float f = 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F; + this.playSound(SoundEvents.IRON_GOLEM_REPAIR, 1.0F, f); diff --git a/net/minecraft/world/entity/animal/MushroomCow.java b/net/minecraft/world/entity/animal/MushroomCow.java -index b04532aa04aec6ebbff74d64abb73189c2e12016..f37c8efa34efcb289bbeed06ea2d3860ff2662ac 100644 +index 12099a5eb45ee21520d3ba68ef26909d5949206d..696b0eb93f8c8fe30f4c2cabadc50de730f93c22 100644 --- a/net/minecraft/world/entity/animal/MushroomCow.java +++ b/net/minecraft/world/entity/animal/MushroomCow.java -@@ -64,6 +64,23 @@ public class MushroomCow extends Cow implements Shearable, VariantHolder drops = this.generateDefaultDrops(serverLevel, itemInHand); + org.bukkit.event.player.PlayerShearEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemInHand, hand, drops); if (event != null) { - if (event.isCancelled()) { -- return InteractionResult.PASS; -+ return tryRide(player, hand); // Purpur - Ridables - } +- if (event.isCancelled()) return InteractionResult.PASS; ++ if (event.isCancelled()) return tryRide(player, hand); // Purpur - Ridables drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); - // Paper end - custom shear drops + // Paper end - custom shear drops + } diff --git a/net/minecraft/world/entity/animal/Ocelot.java b/net/minecraft/world/entity/animal/Ocelot.java -index 0554ee499c452db6c1e6852f5022b1f197adb024..5b045751c7302ef5c8b2b730677d02840441efa6 100644 +index 5b59f68141c2ceeaf7907bbf5e7b9e08cbe2239e..ce042556d41836ad5fa7eca6d019176f6207d5cb 100644 --- a/net/minecraft/world/entity/animal/Ocelot.java +++ b/net/minecraft/world/entity/animal/Ocelot.java -@@ -65,6 +65,23 @@ public class Ocelot extends Animal { +@@ -62,6 +62,23 @@ public class Ocelot extends Animal { this.reassessTrustingGoals(); } @@ -1206,29 +1186,29 @@ index 0554ee499c452db6c1e6852f5022b1f197adb024..5b045751c7302ef5c8b2b730677d0284 + // Purpur end - Ridables + public boolean isTrusting() { - return (Boolean) this.entityData.get(Ocelot.DATA_TRUSTING); + return this.entityData.get(DATA_TRUSTING); } -@@ -98,12 +115,14 @@ public class Ocelot extends Animal { - return itemstack.is(ItemTags.OCELOT_FOOD); - }, true); +@@ -93,12 +110,14 @@ public class Ocelot extends Animal { + protected void registerGoals() { + this.temptGoal = new Ocelot.OcelotTemptGoal(this, 0.6, itemStack -> itemStack.is(ItemTags.OCELOT_FOOD), true); this.goalSelector.addGoal(1, new FloatGoal(this)); + this.goalSelector.addGoal(1, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.goalSelector.addGoal(3, this.temptGoal); this.goalSelector.addGoal(7, new LeapAtTargetGoal(this, 0.3F)); this.goalSelector.addGoal(8, new OcelotAttackGoal(this)); - this.goalSelector.addGoal(9, new BreedGoal(this, 0.8D)); - this.goalSelector.addGoal(10, new WaterAvoidingRandomStrollGoal(this, 0.8D, 1.0000001E-5F)); + this.goalSelector.addGoal(9, new BreedGoal(this, 0.8)); + this.goalSelector.addGoal(10, new WaterAvoidingRandomStrollGoal(this, 0.8, 1.0000001E-5F)); this.goalSelector.addGoal(11, new LookAtPlayerGoal(this, Player.class, 10.0F)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Chicken.class, false)); this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, false, false, Turtle.BABY_ON_LAND_SELECTOR)); } diff --git a/net/minecraft/world/entity/animal/Panda.java b/net/minecraft/world/entity/animal/Panda.java -index be753557d7ebd6f1e82b1bdb6d60ecc450f72eec..20d18f7bd8e9c1b3e3a6d06a11c9072456cd742f 100644 +index 283ddf7d13a17c0a6df5a52b7fd26ed7b7a4826b..19aa39af6685a03eb584820853239a3f4fa1a515 100644 --- a/net/minecraft/world/entity/animal/Panda.java +++ b/net/minecraft/world/entity/animal/Panda.java -@@ -112,6 +112,32 @@ public class Panda extends Animal { - +@@ -105,6 +105,32 @@ public class Panda extends Animal { + } } + // Purpur start - Ridables @@ -1260,38 +1240,32 @@ index be753557d7ebd6f1e82b1bdb6d60ecc450f72eec..20d18f7bd8e9c1b3e3a6d06a11c90724 @Override protected boolean canDispenserEquipIntoSlot(EquipmentSlot slot) { return slot == EquipmentSlot.MAINHAND && this.canPickUpLoot(); -@@ -271,6 +297,7 @@ public class Panda extends Animal { +@@ -258,6 +284,7 @@ public class Panda extends Animal { @Override protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.goalSelector.addGoal(2, new Panda.PandaPanicGoal(this, 2.0D)); - this.goalSelector.addGoal(2, new Panda.PandaBreedGoal(this, 1.0D)); - this.goalSelector.addGoal(3, new Panda.PandaAttackGoal(this, 1.2000000476837158D, true)); -@@ -288,6 +315,7 @@ public class Panda extends Animal { + this.goalSelector.addGoal(2, new Panda.PandaPanicGoal(this, 2.0)); + this.goalSelector.addGoal(2, new Panda.PandaBreedGoal(this, 1.0)); + this.goalSelector.addGoal(3, new Panda.PandaAttackGoal(this, 1.2F, true)); +@@ -273,6 +300,7 @@ public class Panda extends Animal { this.goalSelector.addGoal(12, new Panda.PandaRollGoal(this)); - this.goalSelector.addGoal(13, new FollowParentGoal(this, 1.25D)); - this.goalSelector.addGoal(14, new WaterAvoidingRandomStrollGoal(this, 1.0D)); + this.goalSelector.addGoal(13, new FollowParentGoal(this, 1.25)); + this.goalSelector.addGoal(14, new WaterAvoidingRandomStrollGoal(this, 1.0)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, (new Panda.PandaHurtByTargetGoal(this, new Class[0])).setAlertOthers(new Class[0])); + this.targetSelector.addGoal(1, new Panda.PandaHurtByTargetGoal(this).setAlertOthers(new Class[0])); } -@@ -640,7 +668,7 @@ public class Panda extends Animal { - ItemStack itemstack = player.getItemInHand(hand); - +@@ -616,7 +644,7 @@ public class Panda extends Animal { + public InteractionResult mobInteract(Player player, InteractionHand hand) { + ItemStack itemInHand = player.getItemInHand(hand); if (this.isScared()) { - return InteractionResult.PASS; + return tryRide(player, hand); // Purpur - Ridables } else if (this.isOnBack()) { this.setOnBack(false); return InteractionResult.SUCCESS; -@@ -679,12 +707,12 @@ public class Panda extends Animal { - } - } - -- return InteractionResult.PASS; -+ return tryRide(player, hand); // Purpur - Ridables - } +@@ -652,7 +680,7 @@ public class Panda extends Animal { return InteractionResult.SUCCESS_SERVER; } else { @@ -1300,16 +1274,16 @@ index be753557d7ebd6f1e82b1bdb6d60ecc450f72eec..20d18f7bd8e9c1b3e3a6d06a11c90724 } } -@@ -729,7 +757,7 @@ public class Panda extends Animal { - return itemEntity.getItem().is(ItemTags.PANDA_EATS_FROM_GROUND) && itemEntity.isAlive() && !itemEntity.hasPickUpDelay(); +@@ -964,7 +992,7 @@ public class Panda extends Animal { + } } -- private static class PandaMoveControl extends MoveControl { -+ private static class PandaMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables - +- static class PandaMoveControl extends MoveControl { ++ static class PandaMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables private final Panda panda; -@@ -739,9 +767,9 @@ public class Panda extends Animal { + public PandaMoveControl(Panda mob) { +@@ -973,9 +1001,9 @@ public class Panda extends Animal { } @Override @@ -1322,13 +1296,13 @@ index be753557d7ebd6f1e82b1bdb6d60ecc450f72eec..20d18f7bd8e9c1b3e3a6d06a11c90724 } } diff --git a/net/minecraft/world/entity/animal/Parrot.java b/net/minecraft/world/entity/animal/Parrot.java -index a2f0b79599799ad2aa85aff821d8ac76a8e650bd..872f2406531bf71f378325441b7215c085f1a70d 100644 +index 16cc69b14fba16a5a5dfc05d63a40a5112314031..0cd22002a1af6075be4818a4b351ee716f228cb2 100644 --- a/net/minecraft/world/entity/animal/Parrot.java +++ b/net/minecraft/world/entity/animal/Parrot.java -@@ -125,12 +125,68 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder type, Level world) { - super(type, world); + public Parrot(EntityType entityType, Level level) { + super(entityType, level); - this.moveControl = new FlyingMoveControl(this, 10, false); + // Purpur start - Ridables + final org.purpurmc.purpur.controller.FlyingWithSpacebarMoveControllerWASD flyingController = new org.purpurmc.purpur.controller.FlyingWithSpacebarMoveControllerWASD(this, 0.3F); @@ -1394,25 +1368,25 @@ index a2f0b79599799ad2aa85aff821d8ac76a8e650bd..872f2406531bf71f378325441b7215c0 + @Nullable @Override - public SpawnGroupData finalizeSpawn(ServerLevelAccessor world, DifficultyInstance difficulty, EntitySpawnReason spawnReason, @Nullable SpawnGroupData entityData) { -@@ -149,8 +205,10 @@ public class Parrot extends ShoulderRidingEntity implements VariantHolder { + this.goalSelector.addGoal(1, new PanicGoal(this, 1.25)); + this.goalSelector.addGoal(3, new BreedGoal(this, 1.0)); + this.goalSelector.addGoal(4, new TemptGoal(this, 1.2, itemStack -> itemStack.is(Items.CARROT_ON_A_STICK), false)); diff --git a/net/minecraft/world/entity/animal/PolarBear.java b/net/minecraft/world/entity/animal/PolarBear.java -index cd72d8f766069796ce1fe4a83b8646692005ff8c..6f30cdc26054a4ed7c577cd4e9aa29ade1d2ede5 100644 +index f568c385e1427e183aefb5819013838aca95407b..c0356a2e1e4a5dbefb5f1546869f449e00b76b99 100644 --- a/net/minecraft/world/entity/animal/PolarBear.java +++ b/net/minecraft/world/entity/animal/PolarBear.java @@ -59,11 +59,40 @@ public class PolarBear extends Animal implements NeutralMob { @@ -1449,8 +1423,8 @@ index cd72d8f766069796ce1fe4a83b8646692005ff8c..6f30cdc26054a4ed7c577cd4e9aa29ad private UUID persistentAngerTarget; + private int standTimer = 0; // Purpur - Ridables - public PolarBear(EntityType type, Level world) { - super(type, world); + public PolarBear(EntityType entityType, Level level) { + super(entityType, level); } + // Purpur start - Ridables @@ -1483,16 +1457,15 @@ index cd72d8f766069796ce1fe4a83b8646692005ff8c..6f30cdc26054a4ed7c577cd4e9aa29ad + @Nullable @Override - public AgeableMob getBreedOffspring(ServerLevel world, AgeableMob entity) { -@@ -79,6 +108,7 @@ public class PolarBear extends Animal implements NeutralMob { + public AgeableMob getBreedOffspring(ServerLevel level, AgeableMob otherParent) { +@@ -79,12 +108,14 @@ public class PolarBear extends Animal implements NeutralMob { protected void registerGoals() { super.registerGoals(); this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.goalSelector.addGoal(1, new PolarBear.PolarBearMeleeAttackGoal()); - this.goalSelector - .addGoal(1, new PanicGoal(this, 2.0, polarBear -> polarBear.isBaby() ? DamageTypeTags.PANIC_CAUSES : DamageTypeTags.PANIC_ENVIRONMENTAL_CAUSES)); -@@ -86,6 +116,7 @@ public class PolarBear extends Animal implements NeutralMob { + this.goalSelector.addGoal(1, new PanicGoal(this, 2.0, mob -> mob.isBaby() ? DamageTypeTags.PANIC_CAUSES : DamageTypeTags.PANIC_ENVIRONMENTAL_CAUSES)); + this.goalSelector.addGoal(4, new FollowParentGoal(this, 1.25)); this.goalSelector.addGoal(5, new RandomStrollGoal(this, 1.0)); this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F)); this.goalSelector.addGoal(7, new RandomLookAroundGoal(this)); @@ -1500,7 +1473,7 @@ index cd72d8f766069796ce1fe4a83b8646692005ff8c..6f30cdc26054a4ed7c577cd4e9aa29ad this.targetSelector.addGoal(1, new PolarBear.PolarBearHurtByTargetGoal()); this.targetSelector.addGoal(2, new PolarBear.PolarBearAttackPlayersGoal()); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt)); -@@ -204,6 +235,12 @@ public class PolarBear extends Animal implements NeutralMob { +@@ -203,6 +234,12 @@ public class PolarBear extends Animal implements NeutralMob { if (!this.level().isClientSide) { this.updatePersistentAnger((ServerLevel)this.level(), true); } @@ -1513,19 +1486,19 @@ index cd72d8f766069796ce1fe4a83b8646692005ff8c..6f30cdc26054a4ed7c577cd4e9aa29ad } @Override -@@ -223,6 +260,7 @@ public class PolarBear extends Animal implements NeutralMob { +@@ -222,6 +259,7 @@ public class PolarBear extends Animal implements NeutralMob { - public void setStanding(boolean warning) { - this.entityData.set(DATA_STANDING_ID, warning); -+ standTimer = warning ? 20 : -1; // Purpur - Ridables + public void setStanding(boolean standing) { + this.entityData.set(DATA_STANDING_ID, standing); ++ standTimer = standing ? 20 : -1; // Purpur - Ridables } - public float getStandingAnimationScale(float tickDelta) { + public float getStandingAnimationScale(float partialTick) { diff --git a/net/minecraft/world/entity/animal/Pufferfish.java b/net/minecraft/world/entity/animal/Pufferfish.java -index cdb74f86ee92ee143af29962a85d45ca585cee44..93c1b945672a769ef6ee285efdcebd3717caf9f1 100644 +index d94a7cfcd0f7a15ce97d3b12daa8b2c71acf997a..f7e9abf778186ad1c78dbe411980a83c5e68792e 100644 --- a/net/minecraft/world/entity/animal/Pufferfish.java +++ b/net/minecraft/world/entity/animal/Pufferfish.java -@@ -52,6 +52,18 @@ public class Pufferfish extends AbstractFish { +@@ -45,6 +45,18 @@ public class Pufferfish extends AbstractFish { this.refreshDimensions(); } @@ -1545,19 +1518,19 @@ index cdb74f86ee92ee143af29962a85d45ca585cee44..93c1b945672a769ef6ee285efdcebd37 protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); diff --git a/net/minecraft/world/entity/animal/Rabbit.java b/net/minecraft/world/entity/animal/Rabbit.java -index 53d60d62686f9b6bc98b6b25e4315b848600a99d..b5601b99401f2c3cf4ce0fef4497b09667083412 100644 +index c5346b6e4ffe09ca1ec4b85e612c9ee52ae77329..9342662abf74b921573aba2bbacb43e6ad5683f5 100644 --- a/net/minecraft/world/entity/animal/Rabbit.java +++ b/net/minecraft/world/entity/animal/Rabbit.java -@@ -88,6 +88,7 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -83,6 +83,7 @@ public class Rabbit extends Animal implements VariantHolder { private boolean wasOnGround; private int jumpDelayTicks; public int moreCarrotTicks; + private boolean actualJump; // Purpur - Ridables - public Rabbit(EntityType type, Level world) { - super(type, world); -@@ -95,9 +96,55 @@ public class Rabbit extends Animal implements VariantHolder { - this.moveControl = new Rabbit.RabbitMoveControl(this); + public Rabbit(EntityType entityType, Level level) { + super(entityType, level); +@@ -91,9 +92,55 @@ public class Rabbit extends Animal implements VariantHolder { + //this.setSpeedModifier(0.0); // CraftBukkit } + // Purpur start - Ridables @@ -1610,9 +1583,9 @@ index 53d60d62686f9b6bc98b6b25e4315b848600a99d..b5601b99401f2c3cf4ce0fef4497b096 this.goalSelector.addGoal(1, new FloatGoal(this)); + this.goalSelector.addGoal(1, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.goalSelector.addGoal(1, new ClimbOnTopOfPowderSnowGoal(this, this.level())); - this.goalSelector.addGoal(1, new Rabbit.RabbitPanicGoal(this, 2.2D)); - this.goalSelector.addGoal(2, new BreedGoal(this, 0.8D)); -@@ -114,6 +161,14 @@ public class Rabbit extends Animal implements VariantHolder { + this.goalSelector.addGoal(1, new Rabbit.RabbitPanicGoal(this, 2.2)); + this.goalSelector.addGoal(2, new BreedGoal(this, 0.8)); +@@ -108,6 +155,14 @@ public class Rabbit extends Animal implements VariantHolder { @Override protected float getJumpPower() { @@ -1625,12 +1598,12 @@ index 53d60d62686f9b6bc98b6b25e4315b848600a99d..b5601b99401f2c3cf4ce0fef4497b096 + } + // Purpur end - Ridables float f = 0.3F; - - if (this.moveControl.getSpeedModifier() <= 0.6D) { -@@ -188,6 +243,12 @@ public class Rabbit extends Animal implements VariantHolder { + if (this.moveControl.getSpeedModifier() <= 0.6) { + f = 0.2F; +@@ -175,6 +230,12 @@ public class Rabbit extends Animal implements VariantHolder { @Override - public void customServerAiStep(ServerLevel world) { + public void customServerAiStep(ServerLevel level) { + // Purpur start - Ridables + if (getRider() != null && this.isControllable()) { + handleJumping(); @@ -1638,25 +1611,25 @@ index 53d60d62686f9b6bc98b6b25e4315b848600a99d..b5601b99401f2c3cf4ce0fef4497b096 + } + // Purpur end - Ridables if (this.jumpDelayTicks > 0) { - --this.jumpDelayTicks; + this.jumpDelayTicks--; } -@@ -469,7 +530,7 @@ public class Rabbit extends Animal implements VariantHolder { +@@ -470,7 +531,7 @@ public class Rabbit extends Animal implements VariantHolder { } } -- private static class RabbitMoveControl extends MoveControl { -+ private static class RabbitMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables - +- static class RabbitMoveControl extends MoveControl { ++ static class RabbitMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables private final Rabbit rabbit; private double nextJumpSpeed; + @@ -480,14 +541,14 @@ public class Rabbit extends Animal implements VariantHolder { } @Override - public void tick() { + public void vanillaTick() { // Purpur - Ridables - if (this.rabbit.onGround() && !this.rabbit.jumping && !((Rabbit.RabbitJumpControl) this.rabbit.jumpControl).wantJump()) { - this.rabbit.setSpeedModifier(0.0D); + if (this.rabbit.onGround() && !this.rabbit.jumping && !((Rabbit.RabbitJumpControl)this.rabbit.jumpControl).wantJump()) { + this.rabbit.setSpeedModifier(0.0); } else if (this.hasWanted() || this.operation == MoveControl.Operation.JUMPING) { this.rabbit.setSpeedModifier(this.nextJumpSpeed); } @@ -1667,7 +1640,7 @@ index 53d60d62686f9b6bc98b6b25e4315b848600a99d..b5601b99401f2c3cf4ce0fef4497b096 @Override diff --git a/net/minecraft/world/entity/animal/Salmon.java b/net/minecraft/world/entity/animal/Salmon.java -index 500259e6f297276fb3d6943c2bf88c844d4ec7e4..9bc58ca4556baf6f6bc494ae249c11c5c627f86c 100644 +index 41366f7b9af176a33b20ea26dd53d50994d2c600..ebbd6d39c3f5d6c66445c2c743785ed369408389 100644 --- a/net/minecraft/world/entity/animal/Salmon.java +++ b/net/minecraft/world/entity/animal/Salmon.java @@ -35,6 +35,18 @@ public class Salmon extends AbstractSchoolingFish implements VariantHolder { + this.goalSelector.addGoal(1, new PanicGoal(this, 1.25)); + this.goalSelector.addGoal(2, new BreedGoal(this, 1.0)); + this.goalSelector.addGoal(3, new TemptGoal(this, 1.1, stack -> stack.is(ItemTags.SHEEP_FOOD), false)); diff --git a/net/minecraft/world/entity/animal/SnowGolem.java b/net/minecraft/world/entity/animal/SnowGolem.java -index fd9f6c17448a4d87f940eb8f544ecb9669068582..0ba9aa45902cbad16ee0356cb3051b12923cfe10 100644 +index 8871964fd735178804b95182db1fd6bc1088f69d..320035fd5e7120d58cb7d4432b8e85d92a243d8b 100644 --- a/net/minecraft/world/entity/animal/SnowGolem.java +++ b/net/minecraft/world/entity/animal/SnowGolem.java -@@ -55,12 +55,31 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM - super(type, world); +@@ -49,12 +49,31 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM + super(entityType, level); } + // Purpur start - Ridables @@ -1750,32 +1723,32 @@ index fd9f6c17448a4d87f940eb8f544ecb9669068582..0ba9aa45902cbad16ee0356cb3051b12 @Override protected void registerGoals() { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.goalSelector.addGoal(1, new RangedAttackGoal(this, 1.25D, 20, 10.0F)); - this.goalSelector.addGoal(2, new WaterAvoidingRandomStrollGoal(this, 1.0D, 1.0000001E-5F)); + this.goalSelector.addGoal(1, new RangedAttackGoal(this, 1.25, 20, 10.0F)); + this.goalSelector.addGoal(2, new WaterAvoidingRandomStrollGoal(this, 1.0, 1.0000001E-5F)); this.goalSelector.addGoal(3, new LookAtPlayerGoal(this, Player.class, 6.0F)); this.goalSelector.addGoal(4, new RandomLookAroundGoal(this)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Mob.class, 10, true, false, (entityliving, worldserver) -> { - return entityliving instanceof Enemy; - })); -@@ -110,6 +129,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM + this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Mob.class, 10, true, false, (entity, level) -> entity instanceof Enemy)); + } + +@@ -99,6 +118,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM return; } + if (getRider() != null && this.isControllable() && !level().purpurConfig.snowGolemLeaveTrailWhenRidden) return; // Purpur - don't leave snow trail when being ridden - BlockState iblockdata = Blocks.SNOW.defaultBlockState(); + BlockState blockState = Blocks.SNOW.defaultBlockState(); - for (int i = 0; i < 4; ++i) { -@@ -166,7 +186,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM - org.bukkit.event.player.PlayerShearEntityEvent event = CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemstack, hand, drops); + for (int i = 0; i < 4; i++) { +@@ -141,7 +161,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM + org.bukkit.event.player.PlayerShearEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerShearEntityEvent(player, this, itemInHand, hand, drops); if (event != null) { if (event.isCancelled()) { - return InteractionResult.PASS; + return tryRide(player, hand); // Purpur - Ridables } drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops()); - // Paper end - custom shear drops -@@ -179,7 +199,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM + // Paper end - custom shear drops +@@ -154,7 +174,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM return InteractionResult.SUCCESS; } else { @@ -1785,7 +1758,7 @@ index fd9f6c17448a4d87f940eb8f544ecb9669068582..0ba9aa45902cbad16ee0356cb3051b12 } diff --git a/net/minecraft/world/entity/animal/Squid.java b/net/minecraft/world/entity/animal/Squid.java -index 97a3f0ab3dfca24991051395229dd4c601a66fa0..2d0ecae9625e08ecf5028ec62f71a5432c462712 100644 +index 687ac3f50ed517a0b4df70c0c0a01215691ac718..28d67a8e3cbc668badc76bd68ea851654bebcb76 100644 --- a/net/minecraft/world/entity/animal/Squid.java +++ b/net/minecraft/world/entity/animal/Squid.java @@ -50,9 +50,32 @@ public class Squid extends AgeableWaterCreature { @@ -1821,7 +1794,7 @@ index 97a3f0ab3dfca24991051395229dd4c601a66fa0..2d0ecae9625e08ecf5028ec62f71a543 this.goalSelector.addGoal(1, new Squid.SquidFleeGoal()); } -@@ -305,6 +328,37 @@ public class Squid extends AgeableWaterCreature { +@@ -307,6 +330,37 @@ public class Squid extends AgeableWaterCreature { @Override public void tick() { @@ -1856,15 +1829,15 @@ index 97a3f0ab3dfca24991051395229dd4c601a66fa0..2d0ecae9625e08ecf5028ec62f71a543 + return; + } + // Purpur end - Ridables - int i = this.squid.getNoActionTime(); - if (i > 100) { + int noActionTime = this.squid.getNoActionTime(); + if (noActionTime > 100) { this.squid.movementVector = Vec3.ZERO; diff --git a/net/minecraft/world/entity/animal/TropicalFish.java b/net/minecraft/world/entity/animal/TropicalFish.java -index 8d59d606bdaaea7c64389572b2810b65414a1533..df9d2d4d285f51d6e8e5bc781699c20fe1c2d00d 100644 +index fa5f7f7d54083f9ea2095dd44362069d00e0b9a5..1e31a39b276e1c5ae767da7af0b536007c87189e 100644 --- a/net/minecraft/world/entity/animal/TropicalFish.java +++ b/net/minecraft/world/entity/animal/TropicalFish.java @@ -67,6 +67,18 @@ public class TropicalFish extends AbstractSchoolingFish implements VariantHolder - super(type, world); + super(entityType, level); } + // Purpur start - Ridables @@ -1879,14 +1852,14 @@ index 8d59d606bdaaea7c64389572b2810b65414a1533..df9d2d4d285f51d6e8e5bc781699c20f + } + // Purpur end - Ridables + - public static String getPredefinedName(int variant) { - return "entity.minecraft.tropical_fish.predefined." + variant; + public static String getPredefinedName(int variantId) { + return "entity.minecraft.tropical_fish.predefined." + variantId; } diff --git a/net/minecraft/world/entity/animal/Turtle.java b/net/minecraft/world/entity/animal/Turtle.java -index d6605c15111dbdb6ee61a24822bc0a9aed7198d6..0fc805540305dd8d34b903d5b7769816578c19c3 100644 +index 354ec2b987882d8f40ef4ac5257183d2fda73bb8..98cb91574c8d2bdb6d180256f657ecc67987a6fe 100644 --- a/net/minecraft/world/entity/animal/Turtle.java +++ b/net/minecraft/world/entity/animal/Turtle.java -@@ -86,6 +86,23 @@ public class Turtle extends Animal { +@@ -84,6 +84,23 @@ public class Turtle extends Animal { this.moveControl = new Turtle.TurtleMoveControl(this); } @@ -1907,35 +1880,34 @@ index d6605c15111dbdb6ee61a24822bc0a9aed7198d6..0fc805540305dd8d34b903d5b7769816 + } + // Purpur end - Ridables + - public void setHomePos(BlockPos pos) { - this.entityData.set(Turtle.HOME_POS, pos); + public void setHomePos(BlockPos homePos) { + this.entityData.set(HOME_POS, homePos); } @@ -188,6 +205,7 @@ public class Turtle extends Animal { @Override protected void registerGoals() { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.goalSelector.addGoal(0, new Turtle.TurtlePanicGoal(this, 1.2D)); - this.goalSelector.addGoal(1, new Turtle.TurtleBreedGoal(this, 1.0D)); - this.goalSelector.addGoal(1, new Turtle.TurtleLayEggGoal(this, 1.0D)); -@@ -349,13 +367,15 @@ public class Turtle extends Animal { - return this.isBaby() ? Turtle.BABY_DIMENSIONS : super.getDefaultDimensions(pose); + this.goalSelector.addGoal(0, new Turtle.TurtlePanicGoal(this, 1.2)); + this.goalSelector.addGoal(1, new Turtle.TurtleBreedGoal(this, 1.0)); + this.goalSelector.addGoal(1, new Turtle.TurtleLayEggGoal(this, 1.0)); +@@ -539,12 +557,14 @@ public class Turtle extends Animal { + } } -- private static class TurtleMoveControl extends MoveControl { -+ private static class TurtleMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables - +- static class TurtleMoveControl extends MoveControl { ++ static class TurtleMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables private final Turtle turtle; + private final org.purpurmc.purpur.controller.WaterMoveControllerWASD waterController; // Purpur - Ridables - TurtleMoveControl(Turtle turtle) { - super(turtle); - this.turtle = turtle; + TurtleMoveControl(Turtle mob) { + super(mob); + this.turtle = mob; + waterController = new org.purpurmc.purpur.controller.WaterMoveControllerWASD(turtle, 0.25D); // Purpur - Ridables } private void updateSpeed() { -@@ -375,7 +395,7 @@ public class Turtle extends Animal { +@@ -563,7 +583,7 @@ public class Turtle extends Animal { } @Override @@ -1943,21 +1915,21 @@ index d6605c15111dbdb6ee61a24822bc0a9aed7198d6..0fc805540305dd8d34b903d5b7769816 + public void vanillaTick() { // Purpur - Ridables this.updateSpeed(); if (this.operation == MoveControl.Operation.MOVE_TO && !this.turtle.getNavigation().isDone()) { - double d0 = this.wantedX - this.turtle.getX(); -@@ -391,7 +411,7 @@ public class Turtle extends Animal { - + double d = this.wantedX - this.turtle.getX(); +@@ -577,7 +597,7 @@ public class Turtle extends Animal { + float f = (float)(Mth.atan2(d2, d) * 180.0F / (float)Math.PI) - 90.0F; this.turtle.setYRot(this.rotlerp(this.turtle.getYRot(), f, 90.0F)); this.turtle.yBodyRot = this.turtle.getYRot(); -- float f1 = (float) (this.speedModifier * this.turtle.getAttributeValue(Attributes.MOVEMENT_SPEED)); -+ float f1 = (float) (this.getSpeedModifier() * this.turtle.getAttributeValue(Attributes.MOVEMENT_SPEED)); - +- float f1 = (float)(this.speedModifier * this.turtle.getAttributeValue(Attributes.MOVEMENT_SPEED)); ++ float f1 = (float)(this.getSpeedModifier() * this.turtle.getAttributeValue(Attributes.MOVEMENT_SPEED)); // Purpur - Ridables this.turtle.setSpeed(Mth.lerp(0.125F, this.turtle.getSpeed(), f1)); - this.turtle.setDeltaMovement(this.turtle.getDeltaMovement().add(0.0D, (double) this.turtle.getSpeed() * d1 * 0.1D, 0.0D)); + this.turtle.setDeltaMovement(this.turtle.getDeltaMovement().add(0.0, this.turtle.getSpeed() * d1 * 0.1, 0.0)); + } diff --git a/net/minecraft/world/entity/animal/Wolf.java b/net/minecraft/world/entity/animal/Wolf.java -index c57fac6b5a17f39699298a58d9d25c12da929e64..5ac51a56c451a8fde4b98cec165143b2128fd9eb 100644 +index 362b2d049080ffa1b0763146c31fc2ce6d337e51..32efe3af5f4f046f2935686eeba8cf0a40f23bfc 100644 --- a/net/minecraft/world/entity/animal/Wolf.java +++ b/net/minecraft/world/entity/animal/Wolf.java -@@ -124,9 +124,32 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder(this, Llama.class, 24.0F, 1.5D, 1.5D)); -@@ -138,6 +161,7 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder(this, Llama.class, 24.0F, 1.5, 1.5)); +@@ -129,6 +152,7 @@ public class Wolf extends TamableAnimal implements NeutralMob, VariantHolder type, Level world) { - super(type, world); + public Allay(EntityType entityType, Level level) { + super(entityType, level); - this.moveControl = new FlyingMoveControl(this, 20, true); + // Purpur start - Ridables + this.purpurController = new org.purpurmc.purpur.controller.FlyingMoveControllerWASD(this, 0.1F, 0.5F); @@ -2027,7 +1999,7 @@ index b86f638390d386c838318a4d9b6571ac5514df8f..76779074ceea0d79b01c6744e6cc0a50 this.setCanPickUpLoot(this.canPickUpLoot()); this.vibrationUser = new Allay.VibrationUser(); this.vibrationData = new VibrationSystem.Data(); -@@ -121,6 +134,28 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS +@@ -138,6 +151,28 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS } // CraftBukkit end @@ -2055,21 +2027,21 @@ index b86f638390d386c838318a4d9b6571ac5514df8f..76779074ceea0d79b01c6744e6cc0a50 + @Override protected Brain.Provider brainProvider() { - return Brain.provider(Allay.MEMORY_TYPES, Allay.SENSOR_TYPES); -@@ -228,6 +263,7 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS - ProfilerFiller gameprofilerfiller = Profiler.get(); - - gameprofilerfiller.push("allayBrain"); + return Brain.provider(MEMORY_TYPES, SENSOR_TYPES); +@@ -247,6 +282,7 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS + protected void customServerAiStep(ServerLevel level) { + ProfilerFiller profilerFiller = Profiler.get(); + profilerFiller.push("allayBrain"); + //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider - this.getBrain().tick(world, this); - gameprofilerfiller.pop(); - gameprofilerfiller.push("allayActivityUpdate"); + this.getBrain().tick(level, this); + profilerFiller.pop(); + profilerFiller.push("allayActivityUpdate"); diff --git a/net/minecraft/world/entity/animal/armadillo/Armadillo.java b/net/minecraft/world/entity/animal/armadillo/Armadillo.java -index c1ef714096159608752d744b98f615cd45fe459a..4c9771725f9567790841094dae72c2bbf0d5ba62 100644 +index dfdbcb31458095a71c187efc2774ecc4945dd11b..87a190d8646d8bbed8c182f9f0f7d8c398e63d26 100644 --- a/net/minecraft/world/entity/animal/armadillo/Armadillo.java +++ b/net/minecraft/world/entity/animal/armadillo/Armadillo.java -@@ -82,6 +82,23 @@ public class Armadillo extends Animal { - return Animal.createAnimalAttributes().add(Attributes.MAX_HEALTH, 12.0D).add(Attributes.MOVEMENT_SPEED, 0.14D); +@@ -80,6 +80,23 @@ public class Armadillo extends Animal { + return Animal.createAnimalAttributes().add(Attributes.MAX_HEALTH, 12.0).add(Attributes.MOVEMENT_SPEED, 0.14); } + // Purpur start - Ridables @@ -2093,10 +2065,10 @@ index c1ef714096159608752d744b98f615cd45fe459a..4c9771725f9567790841094dae72c2bb protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); diff --git a/net/minecraft/world/entity/animal/axolotl/Axolotl.java b/net/minecraft/world/entity/animal/axolotl/Axolotl.java -index 31b10cd404b672d7ce21c2107d8f83e32de26ef4..b414edf515890066bd970f65c073964839851840 100644 +index 9faa929734035c167e54569ce34d841291856589..2054e4624da0c9b04ea69b9bf39443c4574d48be 100644 --- a/net/minecraft/world/entity/animal/axolotl/Axolotl.java +++ b/net/minecraft/world/entity/animal/axolotl/Axolotl.java -@@ -100,6 +100,23 @@ public class Axolotl extends Animal implements VariantHolder, B +@@ -115,6 +115,23 @@ public class Axolotl extends Animal implements VariantHolder, B this.lookControl = new Axolotl.AxolotlLookControl(this, 20); } @@ -2118,19 +2090,30 @@ index 31b10cd404b672d7ce21c2107d8f83e32de26ef4..b414edf515890066bd970f65c0739648 + // Purpur end - Ridables + @Override - public float getWalkTargetValue(BlockPos pos, LevelReader world) { + public float getWalkTargetValue(BlockPos pos, LevelReader level) { return 0.0F; -@@ -297,6 +314,7 @@ public class Axolotl extends Animal implements VariantHolder, B - ProfilerFiller gameprofilerfiller = Profiler.get(); - - gameprofilerfiller.push("axolotlBrain"); +@@ -304,6 +321,7 @@ public class Axolotl extends Animal implements VariantHolder, B + protected void customServerAiStep(ServerLevel level) { + ProfilerFiller profilerFiller = Profiler.get(); + profilerFiller.push("axolotlBrain"); + //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider - this.getBrain().tick(world, this); - gameprofilerfiller.pop(); - gameprofilerfiller.push("axolotlActivityUpdate"); -@@ -520,14 +538,22 @@ public class Axolotl extends Animal implements VariantHolder, B - private static class AxolotlMoveControl extends SmoothSwimmingMoveControl { + this.getBrain().tick(level, this); + profilerFiller.pop(); + profilerFiller.push("axolotlActivityUpdate"); +@@ -555,23 +573,31 @@ public class Axolotl extends Animal implements VariantHolder, B + } + @Override +- public void tick() { ++ public void vanillaTick() { // Purpur - Ridables + if (!Axolotl.this.isPlayingDead()) { +- super.tick(); ++ super.vanillaTick(); // Purpur - Ridables + } + } + } + + static class AxolotlMoveControl extends SmoothSwimmingMoveControl { private final Axolotl axolotl; + private final org.purpurmc.purpur.controller.WaterMoveControllerWASD waterController; // Purpur - Ridables @@ -2151,24 +2134,12 @@ index 31b10cd404b672d7ce21c2107d8f83e32de26ef4..b414edf515890066bd970f65c0739648 if (!this.axolotl.isPlayingDead()) { super.tick(); } -@@ -542,9 +568,9 @@ public class Axolotl extends Animal implements VariantHolder, B - } - - @Override -- public void tick() { -+ public void vanillaTick() { // Purpur - Ridables - if (!Axolotl.this.isPlayingDead()) { -- super.tick(); -+ super.vanillaTick(); // Purpur - Ridables - } - - } diff --git a/net/minecraft/world/entity/animal/camel/Camel.java b/net/minecraft/world/entity/animal/camel/Camel.java -index f3c884ab9c09f04dd01cabf2ee9de3b5b620563d..f794ac7af227d413ed030457cbe4cd68e6eca969 100644 +index 3ac169f83c5619b5c00c866354a2e066a0a738cc..11311d2ec37d825e73e2218e60e2606dd3a25a1d 100644 --- a/net/minecraft/world/entity/animal/camel/Camel.java +++ b/net/minecraft/world/entity/animal/camel/Camel.java -@@ -87,6 +87,13 @@ public class Camel extends AbstractHorse { - navigation.setCanWalkOverFences(true); +@@ -83,6 +83,13 @@ public class Camel extends AbstractHorse { + groundPathNavigation.setCanWalkOverFences(true); } + // Purpur start - Ridables @@ -2179,10 +2150,10 @@ index f3c884ab9c09f04dd01cabf2ee9de3b5b620563d..f794ac7af227d413ed030457cbe4cd68 + // Purpur end - Ridables + @Override - public void addAdditionalSaveData(CompoundTag nbt) { - super.addAdditionalSaveData(nbt); + public void addAdditionalSaveData(CompoundTag compound) { + super.addAdditionalSaveData(compound); diff --git a/net/minecraft/world/entity/animal/frog/Frog.java b/net/minecraft/world/entity/animal/frog/Frog.java -index ca04e5d829331551a2c2f44e223ff05c6ce04e76..b42e1e1749c9f18b3bf842517522e90ba60330ff 100644 +index 12c655b60087a2f6122ffa508b3224159d8777b0..9a400c8bf2b54aa5fbcbe65b61670cac5fbebf05 100644 --- a/net/minecraft/world/entity/animal/frog/Frog.java +++ b/net/minecraft/world/entity/animal/frog/Frog.java @@ -106,6 +106,8 @@ public class Frog extends Animal implements VariantHolder> { @@ -2192,8 +2163,8 @@ index ca04e5d829331551a2c2f44e223ff05c6ce04e76..b42e1e1749c9f18b3bf842517522e90b + private org.purpurmc.purpur.controller.MoveControllerWASD purpurLandController; // Purpur - Ridables + private org.purpurmc.purpur.controller.WaterMoveControllerWASD purpurWaterController; // Purpur - Ridables - public Frog(EntityType type, Level world) { - super(type, world); + public Frog(EntityType entityType, Level level) { + super(entityType, level); @@ -113,7 +115,55 @@ public class Frog extends Animal implements VariantHolder> { this.setPathfindingMalus(PathType.WATER, 4.0F); this.setPathfindingMalus(PathType.TRAPDOOR, -1.0F); @@ -2251,34 +2222,34 @@ index ca04e5d829331551a2c2f44e223ff05c6ce04e76..b42e1e1749c9f18b3bf842517522e90b @Override protected Brain.Provider brainProvider() { @@ -188,6 +238,7 @@ public class Frog extends Animal implements VariantHolder> { - protected void customServerAiStep(ServerLevel world) { + protected void customServerAiStep(ServerLevel level) { ProfilerFiller profilerFiller = Profiler.get(); profilerFiller.push("frogBrain"); + //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider - this.getBrain().tick(world, this); + this.getBrain().tick(level, this); profilerFiller.pop(); profilerFiller.push("frogActivityUpdate"); -@@ -384,7 +435,7 @@ public class Frog extends Animal implements VariantHolder> { - return world.getBlockState(pos.below()).is(BlockTags.FROGS_SPAWNABLE_ON) && isBrightEnoughToSpawn(world, pos); +@@ -380,7 +431,7 @@ public class Frog extends Animal implements VariantHolder> { + return level.getBlockState(pos.below()).is(BlockTags.FROGS_SPAWNABLE_ON) && isBrightEnoughToSpawn(level, pos); } - class FrogLookControl extends LookControl { + class FrogLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - Ridables - FrogLookControl(final Mob entity) { - super(entity); + FrogLookControl(final Mob mob) { + super(mob); } diff --git a/net/minecraft/world/entity/animal/frog/Tadpole.java b/net/minecraft/world/entity/animal/frog/Tadpole.java -index 48ac8c3f6e00c3c2dc67b6c994be7c0ac6dfcf81..87a2825d4e198e152a601f20105596a793695885 100644 +index 97adf8142cdd322c4873c420ed760e9dee34da23..e888e606b4b14fa6485de7426bc146b6005962af 100644 --- a/net/minecraft/world/entity/animal/frog/Tadpole.java +++ b/net/minecraft/world/entity/animal/frog/Tadpole.java -@@ -51,13 +51,50 @@ public class Tadpole extends AbstractFish { - protected static final ImmutableList>> SENSOR_TYPES = ImmutableList.of(SensorType.NEAREST_LIVING_ENTITIES, SensorType.NEAREST_PLAYERS, SensorType.HURT_BY, SensorType.FROG_TEMPTATIONS); - protected static final ImmutableList> MEMORY_TYPES = ImmutableList.of(MemoryModuleType.LOOK_TARGET, MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.NEAREST_VISIBLE_ADULT, MemoryModuleType.TEMPTATION_COOLDOWN_TICKS, MemoryModuleType.IS_TEMPTED, MemoryModuleType.TEMPTING_PLAYER, MemoryModuleType.BREED_TARGET, MemoryModuleType.IS_PANICKING); +@@ -63,13 +63,50 @@ public class Tadpole extends AbstractFish { + MemoryModuleType.IS_PANICKING + ); public boolean ageLocked; // Paper + private org.purpurmc.purpur.controller.WaterMoveControllerWASD purpurController; // Purpur - Ridables - public Tadpole(EntityType type, Level world) { - super(type, world); + public Tadpole(EntityType entityType, Level level) { + super(entityType, level); - this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true); + // Purpur start - Ridables + this.purpurController = new org.purpurmc.purpur.controller.WaterMoveControllerWASD(this, 0.5F); @@ -2321,22 +2292,22 @@ index 48ac8c3f6e00c3c2dc67b6c994be7c0ac6dfcf81..87a2825d4e198e152a601f20105596a7 + // Purpur end - Ridables + @Override - protected PathNavigation createNavigation(Level world) { - return new WaterBoundPathNavigation(this, world); -@@ -88,6 +125,7 @@ public class Tadpole extends AbstractFish { - ProfilerFiller gameprofilerfiller = Profiler.get(); - - gameprofilerfiller.push("tadpoleBrain"); + protected PathNavigation createNavigation(Level level) { + return new WaterBoundPathNavigation(this, level); +@@ -99,6 +136,7 @@ public class Tadpole extends AbstractFish { + protected void customServerAiStep(ServerLevel level) { + ProfilerFiller profilerFiller = Profiler.get(); + profilerFiller.push("tadpoleBrain"); + //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider - this.getBrain().tick(world, this); - gameprofilerfiller.pop(); - gameprofilerfiller.push("tadpoleActivityUpdate"); + this.getBrain().tick(level, this); + profilerFiller.pop(); + profilerFiller.push("tadpoleActivityUpdate"); diff --git a/net/minecraft/world/entity/animal/goat/Goat.java b/net/minecraft/world/entity/animal/goat/Goat.java -index 76aca47d8638d5c37c57d3a59fa7f8ceaa5a53b4..307d11e5ad6d0b47af36b1469a73ae1caa100232 100644 +index 504a30ead8d2bb13d559acbde62f9d44a5dda1cb..9924a39953fb49954d02c771ae1a51411226ceac 100644 --- a/net/minecraft/world/entity/animal/goat/Goat.java +++ b/net/minecraft/world/entity/animal/goat/Goat.java -@@ -93,6 +93,23 @@ public class Goat extends Animal { - }); +@@ -111,6 +111,23 @@ public class Goat extends Animal { + .orElseGet(() -> new ItemStack(Items.GOAT_HORN)); } + // Purpur start - Ridables @@ -2358,23 +2329,23 @@ index 76aca47d8638d5c37c57d3a59fa7f8ceaa5a53b4..307d11e5ad6d0b47af36b1469a73ae1c + @Override protected Brain.Provider brainProvider() { - return Brain.provider(Goat.MEMORY_TYPES, Goat.SENSOR_TYPES); -@@ -197,6 +214,7 @@ public class Goat extends Animal { - ProfilerFiller gameprofilerfiller = Profiler.get(); - - gameprofilerfiller.push("goatBrain"); + return Brain.provider(MEMORY_TYPES, SENSOR_TYPES); +@@ -188,6 +205,7 @@ public class Goat extends Animal { + protected void customServerAiStep(ServerLevel level) { + ProfilerFiller profilerFiller = Profiler.get(); + profilerFiller.push("goatBrain"); + //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider - this.getBrain().tick(world, this); - gameprofilerfiller.pop(); - gameprofilerfiller.push("goatActivityUpdate"); + this.getBrain().tick(level, this); + profilerFiller.pop(); + profilerFiller.push("goatActivityUpdate"); diff --git a/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/net/minecraft/world/entity/animal/horse/AbstractHorse.java -index 8aed30cdbbfdd42c20dcd4c8773c8a0ee21a980d..d9e4eb76209abffd0079ccdbbd2fc3f29bd67052 100644 +index d52a8315f1e6876c26c732f4c4caa47bc6bebf6e..828406060e50ff62586929371aafb46ef7d81f92 100644 --- a/net/minecraft/world/entity/animal/horse/AbstractHorse.java +++ b/net/minecraft/world/entity/animal/horse/AbstractHorse.java -@@ -228,11 +228,21 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, +@@ -206,11 +206,21 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, - protected AbstractHorse(EntityType type, Level world) { - super(type, world); + protected AbstractHorse(EntityType entityType, Level level) { + super(entityType, level); + this.moveControl = new net.minecraft.world.entity.ai.control.MoveControl(this); // Purpur - use vanilla controller + this.lookControl = new net.minecraft.world.entity.ai.control.LookControl(this); // Purpur - use vanilla controller this.createInventory(); @@ -2390,10 +2361,10 @@ index 8aed30cdbbfdd42c20dcd4c8773c8a0ee21a980d..d9e4eb76209abffd0079ccdbbd2fc3f2 @Override protected void registerGoals() { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HorseHasRider(this)); // Purpur - Ridables - this.goalSelector.addGoal(1, new PanicGoal(this, 1.2D)); - this.goalSelector.addGoal(1, new RunAroundLikeCrazyGoal(this, 1.2D)); - this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D, AbstractHorse.class)); -@@ -243,6 +253,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, + this.goalSelector.addGoal(1, new PanicGoal(this, 1.2)); + this.goalSelector.addGoal(1, new RunAroundLikeCrazyGoal(this, 1.2)); + this.goalSelector.addGoal(2, new BreedGoal(this, 1.0, AbstractHorse.class)); +@@ -221,6 +231,7 @@ public abstract class AbstractHorse extends Animal implements ContainerListener, if (this.canPerformRearing()) { this.goalSelector.addGoal(9, new RandomStandGoal(this)); } @@ -2402,11 +2373,11 @@ index 8aed30cdbbfdd42c20dcd4c8773c8a0ee21a980d..d9e4eb76209abffd0079ccdbbd2fc3f2 this.addBehaviourGoals(); } diff --git a/net/minecraft/world/entity/animal/horse/Donkey.java b/net/minecraft/world/entity/animal/horse/Donkey.java -index 5cafdde956d7a5b00cd5aec5c44849639307363d..f4ef46c6cf40993b878ee965a0af397894231ba6 100644 +index 9b97f3d3675f5051b18a68ff7fa056d859a283e9..ee3fa710e95f2e84f7f9bdce1159d1136815172d 100644 --- a/net/minecraft/world/entity/animal/horse/Donkey.java +++ b/net/minecraft/world/entity/animal/horse/Donkey.java @@ -16,6 +16,13 @@ public class Donkey extends AbstractChestedHorse { - super(type, world); + super(entityType, level); } + // Purpur start - Ridables @@ -2420,11 +2391,11 @@ index 5cafdde956d7a5b00cd5aec5c44849639307363d..f4ef46c6cf40993b878ee965a0af3978 protected SoundEvent getAmbientSound() { return SoundEvents.DONKEY_AMBIENT; diff --git a/net/minecraft/world/entity/animal/horse/Horse.java b/net/minecraft/world/entity/animal/horse/Horse.java -index b5ec7c8ad0e482930d1a54b590b26093f4e477ea..4505bcc6ab70ee2bc969ecfaecf7cff072f48ca1 100644 +index c6d0700f29d6c8123e96efe225faf2d99202ac81..361bf346153912bcbfcf962d7f716dfe12ae2a7b 100644 --- a/net/minecraft/world/entity/animal/horse/Horse.java +++ b/net/minecraft/world/entity/animal/horse/Horse.java @@ -43,6 +43,13 @@ public class Horse extends AbstractHorse implements VariantHolder { - super(type, world); + super(entityType, level); } + // Purpur start - Ridables @@ -2436,13 +2407,13 @@ index b5ec7c8ad0e482930d1a54b590b26093f4e477ea..4505bcc6ab70ee2bc969ecfaecf7cff0 + @Override protected void randomizeAttributes(RandomSource random) { - this.getAttribute(Attributes.MAX_HEALTH).setBaseValue((double)generateMaxHealth(random::nextInt)); + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(generateMaxHealth(random::nextInt)); diff --git a/net/minecraft/world/entity/animal/horse/Llama.java b/net/minecraft/world/entity/animal/horse/Llama.java -index 18bd483fe46de3d9dc129bffbccfba9d4cab9550..0e15cb99cab5ed664dc265f3754b9da7fef8958f 100644 +index 58bb056ce934c793b16e63e44a4029be955c7caa..81a72b5ddbf7644d65dea972821d19e8fccd9b48 100644 --- a/net/minecraft/world/entity/animal/horse/Llama.java +++ b/net/minecraft/world/entity/animal/horse/Llama.java @@ -77,7 +77,51 @@ public class Llama extends AbstractChestedHorse implements VariantHolder entitytypes, Level world) { - super(EntityType.ENDER_DRAGON, world); -@@ -129,6 +130,37 @@ public class EnderDragon extends Mob implements Enemy { + public EnderDragon(EntityType entityType, Level level) { + super(EntityType.ENDER_DRAGON, level); +@@ -106,6 +107,37 @@ public class EnderDragon extends Mob implements Enemy { this.noPhysics = true; this.phaseManager = new EnderDragonPhaseManager(this); - this.explosionSource = new ServerExplosion(world.getMinecraftWorld(), this, null, null, new Vec3(Double.NaN, Double.NaN, Double.NaN), Float.NaN, true, Explosion.BlockInteraction.DESTROY); // CraftBukkit + this.explosionSource = new net.minecraft.world.level.ServerExplosion(level.getMinecraftWorld(), this, null, null, new Vec3(Double.NaN, Double.NaN, Double.NaN), Float.NaN, true, net.minecraft.world.level.Explosion.BlockInteraction.DESTROY); // Paper + + // Purpur start - Ridables + this.moveControl = new org.purpurmc.purpur.controller.FlyingMoveControllerWASD(this) { @@ -2715,8 +2683,8 @@ index d5fc74dbc2c5f6b65fee46e7797b151144c8fd41..d51675bb8660eb9d5e4d1263c28ada32 + return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.enderDragonRidableInWater; } - public void setDragonFight(EndDragonFight fight) { -@@ -143,6 +175,17 @@ public class EnderDragon extends Mob implements Enemy { + public void setDragonFight(EndDragonFight dragonFight) { +@@ -120,6 +152,17 @@ public class EnderDragon extends Mob implements Enemy { return this.fightOrigin; } @@ -2732,9 +2700,9 @@ index d5fc74dbc2c5f6b65fee46e7797b151144c8fd41..d51675bb8660eb9d5e4d1263c28ada32 + // Purpur end - Ridables + public static AttributeSupplier.Builder createAttributes() { - return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 200.0D); + return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 200.0); } -@@ -184,6 +227,37 @@ public class EnderDragon extends Mob implements Enemy { +@@ -169,6 +212,37 @@ public class EnderDragon extends Mob implements Enemy { @Override public void aiStep() { @@ -2772,74 +2740,77 @@ index d5fc74dbc2c5f6b65fee46e7797b151144c8fd41..d51675bb8660eb9d5e4d1263c28ada32 this.processFlappingMovement(); if (this.level().isClientSide) { this.setHealth(this.getHealth()); -@@ -210,6 +284,8 @@ public class EnderDragon extends Mob implements Enemy { - float f; +@@ -197,6 +271,8 @@ public class EnderDragon extends Mob implements Enemy { + this.oFlapTime = this.flapTime; if (this.isDeadOrDying()) { + if (hasRider) ejectPassengers(); // Purpur - Ridables + - float f1 = (this.random.nextFloat() - 0.5F) * 8.0F; - - f = (this.random.nextFloat() - 0.5F) * 4.0F; -@@ -222,9 +298,9 @@ public class EnderDragon extends Mob implements Enemy { - - f = 0.2F / ((float) vec3d.horizontalDistance() * 10.0F + 1.0F); - f *= (float) Math.pow(2.0D, vec3d.y); + float f = (this.random.nextFloat() - 0.5F) * 8.0F; + float f1 = (this.random.nextFloat() - 0.5F) * 4.0F; + float f2 = (this.random.nextFloat() - 0.5F) * 8.0F; +@@ -206,9 +282,9 @@ public class EnderDragon extends Mob implements Enemy { + Vec3 deltaMovement = this.getDeltaMovement(); + float f1 = 0.2F / ((float)deltaMovement.horizontalDistance() * 10.0F + 1.0F); + f1 *= (float)Math.pow(2.0, deltaMovement.y); - if (this.phaseManager.getCurrentPhase().isSitting()) { + if (!hasRider && this.phaseManager.getCurrentPhase().isSitting()) { // Purpur - Ridables this.flapTime += 0.1F; - } else if (this.inWall) { + } else if (!hasRider && this.inWall) { // Purpur - Ridables - this.flapTime += f * 0.5F; + this.flapTime += f1 * 0.5F; } else { - this.flapTime += f; -@@ -240,7 +316,7 @@ public class EnderDragon extends Mob implements Enemy { - float f4; - float f5; + this.flapTime += f1; +@@ -219,7 +295,7 @@ public class EnderDragon extends Mob implements Enemy { + this.flapTime = 0.5F; + } else { + this.flightHistory.record(this.getY(), this.getYRot()); +- if (this.level() instanceof ServerLevel serverLevel1) { ++ if (this.level() instanceof ServerLevel serverLevel1 && !hasRider) { // Purpur - Ridables + DragonPhaseInstance currentPhase = this.phaseManager.getCurrentPhase(); + currentPhase.doServerTick(serverLevel1); + if (this.phaseManager.getCurrentPhase() != currentPhase) { +@@ -298,7 +374,7 @@ public class EnderDragon extends Mob implements Enemy { + this.tickPart(this.body, sin1 * 0.5F, 0.0, -cos1 * 0.5F); + this.tickPart(this.wing1, cos1 * 4.5F, 2.0, sin1 * 4.5F); + this.tickPart(this.wing2, cos1 * -4.5F, 2.0, sin1 * -4.5F); +- if (this.level() instanceof ServerLevel serverLevel2 && this.hurtTime == 0) { ++ if (this.level() instanceof ServerLevel serverLevel2 && this.hurtTime == 0 && !hasRider) { // Purpur - Ridables + this.knockBack( + serverLevel2, + serverLevel2.getEntities( +@@ -348,9 +424,9 @@ public class EnderDragon extends Mob implements Enemy { + } -- if (world1 instanceof ServerLevel) { -+ if (world1 instanceof ServerLevel && !hasRider) { // Purpur - Ridables - ServerLevel worldserver1 = (ServerLevel) world1; - DragonPhaseInstance idragoncontroller = this.phaseManager.getCurrentPhase(); - -@@ -326,7 +402,7 @@ public class EnderDragon extends Mob implements Enemy { - if (world2 instanceof ServerLevel) { - ServerLevel worldserver2 = (ServerLevel) world2; - -- if (this.hurtTime == 0) { -+ if (!hasRider && this.hurtTime == 0) { // Purpur - Ridables - this.knockBack(worldserver2, worldserver2.getEntities((Entity) this, this.wing1.getBoundingBox().inflate(4.0D, 2.0D, 4.0D).move(0.0D, -2.0D, 0.0D), EntitySelector.NO_CREATIVE_OR_SPECTATOR)); - this.knockBack(worldserver2, worldserver2.getEntities((Entity) this, this.wing2.getBoundingBox().inflate(4.0D, 2.0D, 4.0D).move(0.0D, -2.0D, 0.0D), EntitySelector.NO_CREATIVE_OR_SPECTATOR)); - this.hurt(worldserver2, worldserver2.getEntities((Entity) this, this.head.getBoundingBox().inflate(1.0D), EntitySelector.NO_CREATIVE_OR_SPECTATOR)); -@@ -374,7 +450,7 @@ public class EnderDragon extends Mob implements Enemy { - if (world3 instanceof ServerLevel) { - ServerLevel worldserver3 = (ServerLevel) world3; - -- this.inWall = this.checkWalls(worldserver3, this.head.getBoundingBox()) | this.checkWalls(worldserver3, this.neck.getBoundingBox()) | this.checkWalls(worldserver3, this.body.getBoundingBox()); -+ this.inWall = !hasRider && this.checkWalls(worldserver3, this.head.getBoundingBox()) | this.checkWalls(worldserver3, this.neck.getBoundingBox()) | this.checkWalls(worldserver3, this.body.getBoundingBox()); // Purpur - Ridables + if (this.level() instanceof ServerLevel serverLevel3) { +- this.inWall = this.checkWalls(serverLevel3, this.head.getBoundingBox()) ++ this.inWall = !hasRider && this.checkWalls(serverLevel3, this.head.getBoundingBox()) + | this.checkWalls(serverLevel3, this.neck.getBoundingBox()) +- | this.checkWalls(serverLevel3, this.body.getBoundingBox()); ++ | this.checkWalls(serverLevel3, this.body.getBoundingBox()); // Purpur - Ridables if (this.dragonFight != null) { this.dragonFight.updateDragon(this); } diff --git a/net/minecraft/world/entity/boss/wither/WitherBoss.java b/net/minecraft/world/entity/boss/wither/WitherBoss.java -index bd9e10f79eaf0d23908229b3ebc2227946a14843..236e8ea79119dcf21c066b7c250fe20e6752df9e 100644 +index afe43600c4976e01e61d716034a2823d50fb55cb..452fb5473094b713ac456202c3f2f390f8fb7f27 100644 --- a/net/minecraft/world/entity/boss/wither/WitherBoss.java +++ b/net/minecraft/world/entity/boss/wither/WitherBoss.java -@@ -86,16 +86,30 @@ public class WitherBoss extends Monster implements RangedAttackMob { - return !entityliving.getType().is(EntityTypeTags.WITHER_FRIENDS) && entityliving.attackable(); - }; - private static final TargetingConditions TARGETING_CONDITIONS = TargetingConditions.forCombat().range(20.0D).selector(WitherBoss.LIVING_ENTITY_SELECTOR); +@@ -69,6 +69,7 @@ public class WitherBoss extends Monster implements RangedAttackMob { + private final int[] nextHeadUpdate = new int[2]; + private final int[] idleHeadUpdates = new int[2]; + private int destroyBlocksTick; + private int shootCooldown = 0; // Purpur - Ridables - // Paper start - private boolean canPortal = false; - - public void setCanTravelThroughPortals(boolean canPortal) { this.canPortal = canPortal; } - // Paper end + private boolean canPortal = false; // Paper + public final ServerBossEvent bossEvent = (ServerBossEvent)new ServerBossEvent( + this.getDisplayName(), BossEvent.BossBarColor.PURPLE, BossEvent.BossBarOverlay.PROGRESS +@@ -77,9 +78,23 @@ public class WitherBoss extends Monster implements RangedAttackMob { + private static final TargetingConditions.Selector LIVING_ENTITY_SELECTOR = (entity, level) -> !entity.getType().is(EntityTypeTags.WITHER_FRIENDS) + && entity.attackable(); + private static final TargetingConditions TARGETING_CONDITIONS = TargetingConditions.forCombat().range(20.0).selector(LIVING_ENTITY_SELECTOR); + private org.purpurmc.purpur.controller.FlyingWithSpacebarMoveControllerWASD purpurController; // Purpur - Ridables - public WitherBoss(EntityType type, Level world) { - super(type, world); - this.bossEvent = (ServerBossEvent) (new ServerBossEvent(this.getDisplayName(), BossEvent.BossBarColor.PURPLE, BossEvent.BossBarOverlay.PROGRESS)).setDarkenScreen(true); -- this.moveControl = new FlyingMoveControl(this, 10, false); + public WitherBoss(EntityType entityType, Level level) { + super(entityType, level); + // Purpur start - Ridables + this.purpurController = new org.purpurmc.purpur.controller.FlyingWithSpacebarMoveControllerWASD(this, 0.1F); + this.moveControl = new FlyingMoveControl(this, 10, false) { @@ -2853,11 +2824,11 @@ index bd9e10f79eaf0d23908229b3ebc2227946a14843..236e8ea79119dcf21c066b7c250fe20e + } + }; + // Purpur end - Ridables + this.moveControl = new FlyingMoveControl(this, 10, false); this.setHealth(this.getMaxHealth()); this.xpReward = 50; - } -@@ -109,13 +123,114 @@ public class WitherBoss extends Monster implements RangedAttackMob { - return navigationflying; +@@ -93,13 +108,114 @@ public class WitherBoss extends Monster implements RangedAttackMob { + return flyingPathNavigation; } + // Purpur start - Ridables @@ -2963,18 +2934,18 @@ index bd9e10f79eaf0d23908229b3ebc2227946a14843..236e8ea79119dcf21c066b7c250fe20e protected void registerGoals() { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.goalSelector.addGoal(0, new WitherBoss.WitherDoNothingGoal()); - this.goalSelector.addGoal(2, new RangedAttackGoal(this, 1.0D, 40, 20.0F)); - this.goalSelector.addGoal(5, new WaterAvoidingRandomFlyingGoal(this, 1.0D)); + this.goalSelector.addGoal(2, new RangedAttackGoal(this, 1.0, 40, 20.0F)); + this.goalSelector.addGoal(5, new WaterAvoidingRandomFlyingGoal(this, 1.0)); this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 8.0F)); this.goalSelector.addGoal(7, new RandomLookAroundGoal(this)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[0])); - this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, LivingEntity.class, 0, false, false, WitherBoss.LIVING_ENTITY_SELECTOR)); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this)); + this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, LivingEntity.class, 0, false, false, LIVING_ENTITY_SELECTOR)); } -@@ -260,6 +375,15 @@ public class WitherBoss extends Monster implements RangedAttackMob { +@@ -257,6 +373,15 @@ public class WitherBoss extends Monster implements RangedAttackMob { @Override - protected void customServerAiStep(ServerLevel world) { + protected void customServerAiStep(ServerLevel level) { + // Purpur start - Ridables + if (getRider() != null && this.isControllable()) { + Vec3 mot = getDeltaMovement(); @@ -2984,50 +2955,50 @@ index bd9e10f79eaf0d23908229b3ebc2227946a14843..236e8ea79119dcf21c066b7c250fe20e + shootCooldown--; + } + // Purpur end - Ridables - int i; - if (this.getInvulnerableTicks() > 0) { -@@ -578,11 +702,11 @@ public class WitherBoss extends Monster implements RangedAttackMob { + int i = this.getInvulnerableTicks() - 1; + this.bossEvent.setProgress(1.0F - i / 220.0F); +@@ -561,11 +686,11 @@ public class WitherBoss extends Monster implements RangedAttackMob { } - public int getAlternativeTarget(int headIndex) { -- return (Integer) this.entityData.get((EntityDataAccessor) WitherBoss.DATA_TARGETS.get(headIndex)); -+ return getRider() != null && this.isControllable() ? 0 : this.entityData.get(WitherBoss.DATA_TARGETS.get(headIndex)); // Purpur - Ridables + public int getAlternativeTarget(int head) { +- return this.entityData.get(DATA_TARGETS.get(head)); ++ return getRider() != null && this.isControllable() ? 0 : this.entityData.get(DATA_TARGETS.get(head)); // Purpur - Ridables } - public void setAlternativeTarget(int headIndex, int id) { -- this.entityData.set((EntityDataAccessor) WitherBoss.DATA_TARGETS.get(headIndex), id); -+ if (getRider() == null || !this.isControllable()) this.entityData.set(WitherBoss.DATA_TARGETS.get(headIndex), id); // Purpur - Ridables + public void setAlternativeTarget(int targetOffset, int newId) { +- this.entityData.set(DATA_TARGETS.get(targetOffset), newId); ++ if (getRider() == null || !this.isControllable()) this.entityData.set(DATA_TARGETS.get(targetOffset), newId); // Purpur - Ridables } public boolean isPowered() { diff --git a/net/minecraft/world/entity/monster/AbstractSkeleton.java b/net/minecraft/world/entity/monster/AbstractSkeleton.java -index 90b6ed81dcfd4021c7e9509da5e8725034fa07e5..22b003a23b519bedc50bbcad0706aa2d7d7f4b3a 100644 +index 37abc7769573e3cdda380166dd086551d5e7bd88..6c78780166822755a89e7021733ccb7641c62ffe 100644 --- a/net/minecraft/world/entity/monster/AbstractSkeleton.java +++ b/net/minecraft/world/entity/monster/AbstractSkeleton.java -@@ -74,12 +74,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo +@@ -73,12 +73,14 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo @Override protected void registerGoals() { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.goalSelector.addGoal(2, new RestrictSunGoal(this)); - this.goalSelector.addGoal(3, new FleeSunGoal(this, 1.0D)); - this.goalSelector.addGoal(3, new AvoidEntityGoal<>(this, Wolf.class, 6.0F, 1.0D, 1.2D)); - this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 1.0D)); + this.goalSelector.addGoal(3, new FleeSunGoal(this, 1.0)); + this.goalSelector.addGoal(3, new AvoidEntityGoal<>(this, Wolf.class, 6.0F, 1.0, 1.2)); + this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 1.0)); this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 8.0F)); this.goalSelector.addGoal(6, new RandomLookAroundGoal(this)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[0])); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this)); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true)); diff --git a/net/minecraft/world/entity/monster/Blaze.java b/net/minecraft/world/entity/monster/Blaze.java -index e33fa82ca1332b95bb067fd621212d3026eee1b7..968af87ceeb1862738c5270c2aad85c7974cfdb3 100644 +index 419c729502ee708bba9e750f1b951450eca82695..201b08a75c42d90e657c3d56fc6691839e87199c 100644 --- a/net/minecraft/world/entity/monster/Blaze.java +++ b/net/minecraft/world/entity/monster/Blaze.java @@ -33,6 +33,7 @@ public class Blaze extends Monster { - public Blaze(EntityType type, Level world) { - super(type, world); + public Blaze(EntityType entityType, Level level) { + super(entityType, level); + this.moveControl = new org.purpurmc.purpur.controller.FlyingWithSpacebarMoveControllerWASD(this, 0.3F); // Purpur - Ridables this.setPathfindingMalus(PathType.WATER, -1.0F); this.setPathfindingMalus(PathType.LAVA, 8.0F); @@ -3092,7 +3063,7 @@ index e33fa82ca1332b95bb067fd621212d3026eee1b7..968af87ceeb1862738c5270c2aad85c7 @@ -117,6 +154,13 @@ public class Blaze extends Monster { @Override - protected void customServerAiStep(ServerLevel world) { + protected void customServerAiStep(ServerLevel level) { + // Purpur start - Ridables + if (getRider() != null && this.isControllable()) { + Vec3 mot = getDeltaMovement(); @@ -3104,11 +3075,11 @@ index e33fa82ca1332b95bb067fd621212d3026eee1b7..968af87ceeb1862738c5270c2aad85c7 if (this.nextHeightOffsetChangeTick <= 0) { this.nextHeightOffsetChangeTick = 100; diff --git a/net/minecraft/world/entity/monster/Bogged.java b/net/minecraft/world/entity/monster/Bogged.java -index 975477663b6d76a69c006a89e440e21471b39b89..05848ad509461f3fd40d820098cf7cbfe6866b0c 100644 +index f01670f7106a39957c9b37839fcca0d9f29208f0..2b603c1242aac307f28bae5a85bcaad309f929f5 100644 --- a/net/minecraft/world/entity/monster/Bogged.java +++ b/net/minecraft/world/entity/monster/Bogged.java -@@ -44,6 +44,23 @@ public class Bogged extends AbstractSkeleton implements Shearable { - super(type, world); +@@ -41,6 +41,23 @@ public class Bogged extends AbstractSkeleton implements Shearable { + super(entityType, level); } + // Purpur start - Ridables @@ -3132,11 +3103,11 @@ index 975477663b6d76a69c006a89e440e21471b39b89..05848ad509461f3fd40d820098cf7cbf protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); diff --git a/net/minecraft/world/entity/monster/CaveSpider.java b/net/minecraft/world/entity/monster/CaveSpider.java -index 4e621a7f36b3d718695434a2a4e3060283667bb2..a21a18e249dbfa0f1d3d6995b6810961ed5e084b 100644 +index 2e32567fca7a2a4cd87bc078a6eeb30e3ffabfce..4873a3d8dd9c160ecdbda594ee546c35ec03a1e7 100644 --- a/net/minecraft/world/entity/monster/CaveSpider.java +++ b/net/minecraft/world/entity/monster/CaveSpider.java -@@ -27,6 +27,23 @@ public class CaveSpider extends Spider { - return Spider.createAttributes().add(Attributes.MAX_HEALTH, 12.0D); +@@ -26,6 +26,23 @@ public class CaveSpider extends Spider { + return Spider.createAttributes().add(Attributes.MAX_HEALTH, 12.0); } + // Purpur start - Ridables @@ -3157,13 +3128,13 @@ index 4e621a7f36b3d718695434a2a4e3060283667bb2..a21a18e249dbfa0f1d3d6995b6810961 + // Purpur end - Ridables + @Override - public boolean doHurtTarget(ServerLevel world, Entity target) { - if (super.doHurtTarget(world, target)) { + public boolean doHurtTarget(ServerLevel level, Entity source) { + if (super.doHurtTarget(level, source)) { diff --git a/net/minecraft/world/entity/monster/Creeper.java b/net/minecraft/world/entity/monster/Creeper.java -index 1906dfc22af208d6e801ad4a8f2f9e9702432691..ff7ee3a07f0c84aaa36be3a324274b4ccb04fb0b 100644 +index e832612a7ed3f25d087c4f8f85f5d737ade5d645..9adf407bde97e607af915123a999fde2728ad7a4 100644 --- a/net/minecraft/world/entity/monster/Creeper.java +++ b/net/minecraft/world/entity/monster/Creeper.java -@@ -60,21 +60,98 @@ public class Creeper extends Monster { +@@ -50,21 +50,98 @@ public class Creeper extends Monster { public int explosionRadius = 3; private int droppedSkulls; public Entity entityIgniter; // CraftBukkit @@ -3173,8 +3144,8 @@ index 1906dfc22af208d6e801ad4a8f2f9e9702432691..ff7ee3a07f0c84aaa36be3a324274b4c + private int powerToggleDelay = 0; + // Purpur end - Ridables - public Creeper(EntityType type, Level world) { - super(type, world); + public Creeper(EntityType entityType, Level level) { + super(entityType, level); } + // Purpur start - Ridables @@ -3252,26 +3223,26 @@ index 1906dfc22af208d6e801ad4a8f2f9e9702432691..ff7ee3a07f0c84aaa36be3a324274b4c this.goalSelector.addGoal(1, new FloatGoal(this)); this.goalSelector.addGoal(2, new SwellGoal(this)); + this.goalSelector.addGoal(3, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.goalSelector.addGoal(3, new AvoidEntityGoal<>(this, Ocelot.class, 6.0F, 1.0D, 1.2D)); - this.goalSelector.addGoal(3, new AvoidEntityGoal<>(this, Cat.class, 6.0F, 1.0D, 1.2D)); - this.goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0D, false)); - this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 0.8D)); + this.goalSelector.addGoal(3, new AvoidEntityGoal<>(this, Ocelot.class, 6.0F, 1.0, 1.2)); + this.goalSelector.addGoal(3, new AvoidEntityGoal<>(this, Cat.class, 6.0F, 1.0, 1.2)); + this.goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0, false)); + this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 0.8)); this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 8.0F)); this.goalSelector.addGoal(6, new RandomLookAroundGoal(this)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, true)); - this.targetSelector.addGoal(2, new HurtByTargetGoal(this, new Class[0])); + this.targetSelector.addGoal(2, new HurtByTargetGoal(this)); } -@@ -324,6 +401,7 @@ public class Creeper extends Monster { +@@ -288,6 +365,7 @@ public class Creeper extends Monster { com.destroystokyo.paper.event.entity.CreeperIgniteEvent event = new com.destroystokyo.paper.event.entity.CreeperIgniteEvent((org.bukkit.entity.Creeper) getBukkitEntity(), ignited); if (event.callEvent()) { - this.entityData.set(Creeper.DATA_IS_IGNITED, event.isIgnited()); + this.entityData.set(DATA_IS_IGNITED, event.isIgnited()); + if (!event.isIgnited()) setSwellDir(-1); // Purpur - Ridables } } - // Paper end - CreeperIgniteEvent + } diff --git a/net/minecraft/world/entity/monster/Drowned.java b/net/minecraft/world/entity/monster/Drowned.java -index c6c86913c0a48501a9109a3838a3e56685d16d79..025133dff77df06e147defb70f920ee140b9881f 100644 +index c23c4e44ece85fb746a497cbb8a7cd14b2f9768a..87dacd6ddf2f237ebfa4fd98d1d95f2de572b814 100644 --- a/net/minecraft/world/entity/monster/Drowned.java +++ b/net/minecraft/world/entity/monster/Drowned.java @@ -75,6 +75,23 @@ public class Drowned extends Zombie implements RangedAttackMob { @@ -3298,7 +3269,7 @@ index c6c86913c0a48501a9109a3838a3e56685d16d79..025133dff77df06e147defb70f920ee1 @Override protected void addBehaviourGoals() { this.goalSelector.addGoal(1, new Drowned.DrownedGoToWaterGoal(this, 1.0)); -@@ -398,7 +415,7 @@ public class Drowned extends Zombie implements RangedAttackMob { +@@ -395,7 +412,7 @@ public class Drowned extends Zombie implements RangedAttackMob { } } @@ -3306,26 +3277,26 @@ index c6c86913c0a48501a9109a3838a3e56685d16d79..025133dff77df06e147defb70f920ee1 + static class DrownedMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables private final Drowned drowned; - public DrownedMoveControl(Drowned drowned) { -@@ -407,7 +424,7 @@ public class Drowned extends Zombie implements RangedAttackMob { + public DrownedMoveControl(Drowned mob) { +@@ -404,7 +421,7 @@ public class Drowned extends Zombie implements RangedAttackMob { } @Override - public void tick() { + public void vanillaTick() { // Purpur - Ridables - LivingEntity livingEntity = this.drowned.getTarget(); + LivingEntity target = this.drowned.getTarget(); if (this.drowned.wantsToSwim() && this.drowned.isInWater()) { - if (livingEntity != null && livingEntity.getY() > this.drowned.getY() || this.drowned.searchingForLand) { -@@ -427,7 +444,7 @@ public class Drowned extends Zombie implements RangedAttackMob { - float h = (float)(Mth.atan2(f, d) * 180.0F / (float)Math.PI) - 90.0F; - this.drowned.setYRot(this.rotlerp(this.drowned.getYRot(), h, 90.0F)); + if (target != null && target.getY() > this.drowned.getY() || this.drowned.searchingForLand) { +@@ -424,7 +441,7 @@ public class Drowned extends Zombie implements RangedAttackMob { + float f = (float)(Mth.atan2(d2, d) * 180.0F / (float)Math.PI) - 90.0F; + this.drowned.setYRot(this.rotlerp(this.drowned.getYRot(), f, 90.0F)); this.drowned.yBodyRot = this.drowned.getYRot(); -- float i = (float)(this.speedModifier * this.drowned.getAttributeValue(Attributes.MOVEMENT_SPEED)); -+ float i = (float)(this.getSpeedModifier() * this.drowned.getAttributeValue(Attributes.MOVEMENT_SPEED)); // Purpur - Ridables - float j = Mth.lerp(0.125F, this.drowned.getSpeed(), i); - this.drowned.setSpeed(j); - this.drowned.setDeltaMovement(this.drowned.getDeltaMovement().add((double)j * d * 0.005, (double)j * e * 0.1, (double)j * f * 0.005)); -@@ -436,7 +453,7 @@ public class Drowned extends Zombie implements RangedAttackMob { +- float f1 = (float)(this.speedModifier * this.drowned.getAttributeValue(Attributes.MOVEMENT_SPEED)); ++ float f1 = (float)(this.getSpeedModifier() * this.drowned.getAttributeValue(Attributes.MOVEMENT_SPEED)); // Purpur - Ridables + float f2 = Mth.lerp(0.125F, this.drowned.getSpeed(), f1); + this.drowned.setSpeed(f2); + this.drowned.setDeltaMovement(this.drowned.getDeltaMovement().add(f2 * d * 0.005, f2 * d1 * 0.1, f2 * d2 * 0.005)); +@@ -433,7 +450,7 @@ public class Drowned extends Zombie implements RangedAttackMob { this.drowned.setDeltaMovement(this.drowned.getDeltaMovement().add(0.0, -0.008, 0.0)); } @@ -3335,11 +3306,11 @@ index c6c86913c0a48501a9109a3838a3e56685d16d79..025133dff77df06e147defb70f920ee1 } } diff --git a/net/minecraft/world/entity/monster/ElderGuardian.java b/net/minecraft/world/entity/monster/ElderGuardian.java -index 378694a38115c012978e1fea59d049d1ebd04110..bff963a1a0d89b57a686ed06aa630e789a602d82 100644 +index 4585b7c867685f8419c4d2b5b90af5946d337f90..c6eeaf7b460408acfdf89d988b47b08eab7df4c5 100644 --- a/net/minecraft/world/entity/monster/ElderGuardian.java +++ b/net/minecraft/world/entity/monster/ElderGuardian.java -@@ -33,6 +33,18 @@ public class ElderGuardian extends Guardian { - +@@ -31,6 +31,18 @@ public class ElderGuardian extends Guardian { + } } + // Purpur start - Ridables @@ -3355,13 +3326,13 @@ index 378694a38115c012978e1fea59d049d1ebd04110..bff963a1a0d89b57a686ed06aa630e78 + // Purpur end - Ridables + public static AttributeSupplier.Builder createAttributes() { - return Guardian.createAttributes().add(Attributes.MOVEMENT_SPEED, 0.30000001192092896D).add(Attributes.ATTACK_DAMAGE, 8.0D).add(Attributes.MAX_HEALTH, 80.0D); + return Guardian.createAttributes().add(Attributes.MOVEMENT_SPEED, 0.3F).add(Attributes.ATTACK_DAMAGE, 8.0).add(Attributes.MAX_HEALTH, 80.0); } diff --git a/net/minecraft/world/entity/monster/EnderMan.java b/net/minecraft/world/entity/monster/EnderMan.java -index 2a394381a4ad46359359ba402b65c62b331480b4..f3013664d21f70c2650306f2406e93b21de8f9e0 100644 +index 4b5ffd278e0e9d47100e5452949e8d757bbfece4..7330a73c4ed3065a999a984864087f60d091bd3b 100644 --- a/net/minecraft/world/entity/monster/EnderMan.java +++ b/net/minecraft/world/entity/monster/EnderMan.java -@@ -94,9 +94,27 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -90,9 +90,27 @@ public class EnderMan extends Monster implements NeutralMob { this.setPathfindingMalus(PathType.WATER, -1.0F); } @@ -3387,38 +3358,38 @@ index 2a394381a4ad46359359ba402b65c62b331480b4..f3013664d21f70c2650306f2406e93b2 this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.goalSelector.addGoal(1, new EnderMan.EndermanFreezeWhenLookedAt(this)); - this.goalSelector.addGoal(2, new MeleeAttackGoal(this, 1.0D, false)); - this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0D, 0.0F)); -@@ -104,6 +122,7 @@ public class EnderMan extends Monster implements NeutralMob { + this.goalSelector.addGoal(2, new MeleeAttackGoal(this, 1.0, false)); + this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0, 0.0F)); +@@ -100,6 +118,7 @@ public class EnderMan extends Monster implements NeutralMob { this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); this.goalSelector.addGoal(10, new EnderMan.EndermanLeaveBlockGoal(this)); this.goalSelector.addGoal(11, new EnderMan.EndermanTakeBlockGoal(this)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.targetSelector.addGoal(1, new EnderMan.EndermanLookForPlayerGoal(this, this::isAngryAt)); - this.targetSelector.addGoal(2, new HurtByTargetGoal(this, new Class[0])); + this.targetSelector.addGoal(2, new HurtByTargetGoal(this)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Endermite.class, true, false)); -@@ -267,7 +286,7 @@ public class EnderMan extends Monster implements NeutralMob { +@@ -272,7 +291,7 @@ public class EnderMan extends Monster implements NeutralMob { @Override - protected void customServerAiStep(ServerLevel world) { -- if (world.isDay() && this.tickCount >= this.targetChangeTime + 600) { -+ if ((getRider() == null || !this.isControllable()) && world.isDay() && this.tickCount >= this.targetChangeTime + 600) { // Purpur - no random teleporting - float f = this.getLightLevelDependentMagicValue(); - - if (f > 0.5F && world.canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper - EndermanEscapeEvent -@@ -382,6 +401,7 @@ public class EnderMan extends Monster implements NeutralMob { - public boolean hurtServer(ServerLevel world, DamageSource source, float amount) { - if (this.isInvulnerableTo(world, source)) { + protected void customServerAiStep(ServerLevel level) { +- if (level.isDay() && this.tickCount >= this.targetChangeTime + 600) { ++ if ((getRider() == null || !this.isControllable()) && level.isDay() && this.tickCount >= this.targetChangeTime + 600) { // Purpur - Ridables - no random teleporting + float lightLevelDependentMagicValue = this.getLightLevelDependentMagicValue(); + if (lightLevelDependentMagicValue > 0.5F + && level.canSeeSky(this.blockPosition()) +@@ -385,6 +404,7 @@ public class EnderMan extends Monster implements NeutralMob { + public boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) { + if (this.isInvulnerableTo(level, damageSource)) { return false; -+ } else if (getRider() != null && this.isControllable()) { return super.hurtServer(world, source, amount); // Purpur - no teleporting on damage ++ } else if (getRider() != null && this.isControllable()) { return super.hurtServer(level, damageSource, amount); // Purpur - no teleporting on damage } else { - boolean flag = source.getDirectEntity() instanceof ThrownPotion; - boolean flag1; + boolean flag = damageSource.getDirectEntity() instanceof ThrownPotion; + if (!damageSource.is(DamageTypeTags.IS_PROJECTILE) && !flag) { diff --git a/net/minecraft/world/entity/monster/Endermite.java b/net/minecraft/world/entity/monster/Endermite.java -index 534e98dd7291e09dee1d0f77cbf221b15708590f..ac9116735d8ee4713fab8d90ef12e781b77b26c8 100644 +index 2a219c9ae39d7cbee8484b2a93bd278d913afe95..f412cebb5c350bf16f0bee710a4ae1df7c72c384 100644 --- a/net/minecraft/world/entity/monster/Endermite.java +++ b/net/minecraft/world/entity/monster/Endermite.java -@@ -38,14 +38,33 @@ public class Endermite extends Monster { +@@ -34,14 +34,33 @@ public class Endermite extends Monster { this.xpReward = 3; } @@ -3444,19 +3415,19 @@ index 534e98dd7291e09dee1d0f77cbf221b15708590f..ac9116735d8ee4713fab8d90ef12e781 this.goalSelector.addGoal(1, new FloatGoal(this)); + this.goalSelector.addGoal(1, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.goalSelector.addGoal(1, new ClimbOnTopOfPowderSnowGoal(this, this.level())); - this.goalSelector.addGoal(2, new MeleeAttackGoal(this, 1.0D, false)); - this.goalSelector.addGoal(3, new WaterAvoidingRandomStrollGoal(this, 1.0D)); + this.goalSelector.addGoal(2, new MeleeAttackGoal(this, 1.0, false)); + this.goalSelector.addGoal(3, new WaterAvoidingRandomStrollGoal(this, 1.0)); this.goalSelector.addGoal(7, new LookAtPlayerGoal(this, Player.class, 8.0F)); this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[0])).setAlertOthers()); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this).setAlertOthers()); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); } diff --git a/net/minecraft/world/entity/monster/Evoker.java b/net/minecraft/world/entity/monster/Evoker.java -index 14f23c9a248760a57b3d6fe4f2824a4a456a6d37..69a37f88c7f05084007cc2f895c31650da6566f8 100644 +index b70ea1af39cada6bb17001c6b65502510e34c4b2..2eaeb0c0c0cb917506443ed1380b81f317961d53 100644 --- a/net/minecraft/world/entity/monster/Evoker.java +++ b/net/minecraft/world/entity/monster/Evoker.java -@@ -53,10 +53,28 @@ public class Evoker extends SpellcasterIllager { +@@ -50,10 +50,28 @@ public class Evoker extends SpellcasterIllager { this.xpReward = 10; } @@ -3483,21 +3454,21 @@ index 14f23c9a248760a57b3d6fe4f2824a4a456a6d37..69a37f88c7f05084007cc2f895c31650 this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.goalSelector.addGoal(1, new Evoker.EvokerCastingSpellGoal()); - this.goalSelector.addGoal(2, new AvoidEntityGoal<>(this, Player.class, 8.0F, 0.6D, 1.0D)); - this.goalSelector.addGoal(3, new AvoidEntityGoal<>(this, Creaking.class, 8.0F, 0.6D, 1.0D)); -@@ -66,6 +84,7 @@ public class Evoker extends SpellcasterIllager { - this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.6D)); + this.goalSelector.addGoal(2, new AvoidEntityGoal<>(this, Player.class, 8.0F, 0.6, 1.0)); + this.goalSelector.addGoal(3, new AvoidEntityGoal<>(this, Creaking.class, 8.0F, 0.6, 1.0)); +@@ -63,6 +81,7 @@ public class Evoker extends SpellcasterIllager { + this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.6)); this.goalSelector.addGoal(9, new LookAtPlayerGoal(this, Player.class, 3.0F, 1.0F)); this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 8.0F)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[]{Raider.class})).setAlertOthers()); - this.targetSelector.addGoal(2, (new NearestAttackableTargetGoal<>(this, Player.class, true)).setUnseenMemoryTicks(300)); - this.targetSelector.addGoal(3, (new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)).setUnseenMemoryTicks(300)); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Raider.class).setAlertOthers()); + this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true).setUnseenMemoryTicks(300)); + this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false).setUnseenMemoryTicks(300)); diff --git a/net/minecraft/world/entity/monster/Ghast.java b/net/minecraft/world/entity/monster/Ghast.java -index a8c8c03e972aa6352843cf4c3e4aebfb8f493125..8cb7bdd96f9780ee5e2fa0876bc80d092e06b5f5 100644 +index b97bbfbbc8c1a4f38b4b858ef4915b637cc8a627..00c05fb5736c90c94f6fe51793acf8b65b1d0505 100644 --- a/net/minecraft/world/entity/monster/Ghast.java +++ b/net/minecraft/world/entity/monster/Ghast.java -@@ -44,11 +44,47 @@ public class Ghast extends FlyingMob implements Enemy { +@@ -42,11 +42,47 @@ public class Ghast extends FlyingMob implements Enemy { this.moveControl = new Ghast.GhastMoveControl(this); } @@ -3542,28 +3513,28 @@ index a8c8c03e972aa6352843cf4c3e4aebfb8f493125..8cb7bdd96f9780ee5e2fa0876bc80d09 this.goalSelector.addGoal(7, new Ghast.GhastLookGoal(this)); this.goalSelector.addGoal(7, new Ghast.GhastShootFireballGoal(this)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entityliving, worldserver) -> { - return Math.abs(entityliving.getY() - this.getY()) <= 4.0D; - })); -@@ -103,7 +139,7 @@ public class Ghast extends FlyingMob implements Enemy { + this.targetSelector + .addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entity, level) -> Math.abs(entity.getY() - this.getY()) <= 4.0)); + } +@@ -101,7 +137,7 @@ public class Ghast extends FlyingMob implements Enemy { } public static AttributeSupplier.Builder createAttributes() { -- return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 10.0D).add(Attributes.FOLLOW_RANGE, 100.0D); -+ return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 10.0D).add(Attributes.FOLLOW_RANGE, 100.0D).add(Attributes.FLYING_SPEED, 0.6D); // Purpur - Ridables +- return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 10.0).add(Attributes.FOLLOW_RANGE, 100.0); ++ return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 10.0).add(Attributes.FOLLOW_RANGE, 100.0).add(Attributes.FLYING_SPEED, 0.6D); // Purpur - Ridables } @Override -@@ -155,7 +191,7 @@ public class Ghast extends FlyingMob implements Enemy { - +@@ -191,7 +227,7 @@ public class Ghast extends FlyingMob implements Enemy { + } } -- private static class GhastMoveControl extends MoveControl { -+ private static class GhastMoveControl extends org.purpurmc.purpur.controller.FlyingMoveControllerWASD { // Purpur - Ridables - +- static class GhastMoveControl extends MoveControl { ++ static class GhastMoveControl extends org.purpurmc.purpur.controller.FlyingMoveControllerWASD { // Purpur - Ridables private final Ghast ghast; private int floatDuration; -@@ -166,7 +202,7 @@ public class Ghast extends FlyingMob implements Enemy { + +@@ -201,7 +237,7 @@ public class Ghast extends FlyingMob implements Enemy { } @Override @@ -3571,13 +3542,13 @@ index a8c8c03e972aa6352843cf4c3e4aebfb8f493125..8cb7bdd96f9780ee5e2fa0876bc80d09 + public void vanillaTick() { // Purpur - Ridables if (this.operation == MoveControl.Operation.MOVE_TO) { if (this.floatDuration-- <= 0) { - this.floatDuration += this.ghast.getRandom().nextInt(5) + 2; + this.floatDuration = this.floatDuration + this.ghast.getRandom().nextInt(5) + 2; diff --git a/net/minecraft/world/entity/monster/Giant.java b/net/minecraft/world/entity/monster/Giant.java -index 118521ae54254b0a73bb7cba7b2871c9c26f89fc..64e4f78fd626c59e2957140af22993aa8e5c4f15 100644 +index 969eb604851d1cce50f0f99ed479189061d5de0c..135f83484ac31db7dcc225ba6f94e2e4ca27eea8 100644 --- a/net/minecraft/world/entity/monster/Giant.java +++ b/net/minecraft/world/entity/monster/Giant.java @@ -12,6 +12,29 @@ public class Giant extends Monster { - super(type, world); + super(entityType, level); } + // Purpur start - Ridables @@ -3607,10 +3578,10 @@ index 118521ae54254b0a73bb7cba7b2871c9c26f89fc..64e4f78fd626c59e2957140af22993aa return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 100.0).add(Attributes.MOVEMENT_SPEED, 0.5).add(Attributes.ATTACK_DAMAGE, 50.0); } diff --git a/net/minecraft/world/entity/monster/Guardian.java b/net/minecraft/world/entity/monster/Guardian.java -index 951f46684623582980901c1ebc1870aa5bcf25a1..bde5d88dcdb4f2305e2786842551c36da5ed9778 100644 +index c8e249b8f7ee8e9c075169ec988f5a0d459a3767..c20c744522459d938c772077e542ba433bc4c80e 100644 --- a/net/minecraft/world/entity/monster/Guardian.java +++ b/net/minecraft/world/entity/monster/Guardian.java -@@ -67,15 +67,36 @@ public class Guardian extends Monster { +@@ -66,14 +66,35 @@ public class Guardian extends Monster { this.xpReward = 10; this.setPathfindingMalus(PathType.WATER, 0.0F); this.moveControl = new Guardian.GuardianMoveControl(this); @@ -3640,41 +3611,40 @@ index 951f46684623582980901c1ebc1870aa5bcf25a1..bde5d88dcdb4f2305e2786842551c36d + @Override protected void registerGoals() { - MoveTowardsRestrictionGoal pathfindergoalmovetowardsrestriction = new MoveTowardsRestrictionGoal(this, 1.0D); - - this.randomStrollGoal = new RandomStrollGoal(this, 1.0D, 80); + MoveTowardsRestrictionGoal moveTowardsRestrictionGoal = new MoveTowardsRestrictionGoal(this, 1.0); + this.randomStrollGoal = new RandomStrollGoal(this, 1.0, 80); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.goalSelector.addGoal(4, this.guardianAttackGoal = new Guardian.GuardianAttackGoal(this)); // CraftBukkit - assign field - this.goalSelector.addGoal(5, pathfindergoalmovetowardsrestriction); + this.goalSelector.addGoal(5, moveTowardsRestrictionGoal); this.goalSelector.addGoal(7, this.randomStrollGoal); -@@ -84,6 +105,7 @@ public class Guardian extends Monster { +@@ -82,6 +103,7 @@ public class Guardian extends Monster { this.goalSelector.addGoal(9, new RandomLookAroundGoal(this)); this.randomStrollGoal.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK)); - pathfindergoalmovetowardsrestriction.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK)); + moveTowardsRestrictionGoal.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, LivingEntity.class, 10, true, false, new Guardian.GuardianAttackSelector(this))); } -@@ -330,7 +352,7 @@ public class Guardian extends Monster { +@@ -344,7 +366,7 @@ public class Guardian extends Monster { @Override - public void travel(Vec3 movementInput) { + public void travel(Vec3 travelVector) { if (this.isControlledByLocalInstance() && this.isInWater()) { -- this.moveRelative(0.1F, movementInput); -+ this.moveRelative(getRider() != null && this.isControllable() ? getSpeed() : 0.1F, movementInput); // Purpur - Ridables +- this.moveRelative(0.1F, travelVector); ++ this.moveRelative(getRider() != null && this.isControllable() ? getSpeed() : 0.1F, travelVector); // Purpur - Ridables this.move(MoverType.SELF, this.getDeltaMovement()); - this.setDeltaMovement(this.getDeltaMovement().scale(0.9D)); + this.setDeltaMovement(this.getDeltaMovement().scale(0.9)); if (!this.isMoving() && this.getTarget() == null) { -@@ -342,7 +364,7 @@ public class Guardian extends Monster { - +@@ -452,7 +474,7 @@ public class Guardian extends Monster { + } } -- private static class GuardianMoveControl extends MoveControl { -+ private static class GuardianMoveControl extends org.purpurmc.purpur.controller.WaterMoveControllerWASD { // Purpur - Ridables - +- static class GuardianMoveControl extends MoveControl { ++ static class GuardianMoveControl extends org.purpurmc.purpur.controller.WaterMoveControllerWASD { // Purpur - Ridables private final Guardian guardian; -@@ -351,8 +373,17 @@ public class Guardian extends Monster { - this.guardian = guardian; + public GuardianMoveControl(Guardian mob) { +@@ -460,8 +482,17 @@ public class Guardian extends Monster { + this.guardian = mob; } + // Purpur start - Ridables @@ -3690,23 +3660,23 @@ index 951f46684623582980901c1ebc1870aa5bcf25a1..bde5d88dcdb4f2305e2786842551c36d + @Override + public void vanillaTick() { // Purpur - Ridables if (this.operation == MoveControl.Operation.MOVE_TO && !this.guardian.getNavigation().isDone()) { - Vec3 vec3d = new Vec3(this.wantedX - this.guardian.getX(), this.wantedY - this.guardian.getY(), this.wantedZ - this.guardian.getZ()); - double d0 = vec3d.length(); -@@ -363,7 +394,7 @@ public class Guardian extends Monster { - + Vec3 vec3 = new Vec3(this.wantedX - this.guardian.getX(), this.wantedY - this.guardian.getY(), this.wantedZ - this.guardian.getZ()); + double len = vec3.length(); +@@ -471,7 +502,7 @@ public class Guardian extends Monster { + float f = (float)(Mth.atan2(vec3.z, vec3.x) * 180.0F / (float)Math.PI) - 90.0F; this.guardian.setYRot(this.rotlerp(this.guardian.getYRot(), f, 90.0F)); this.guardian.yBodyRot = this.guardian.getYRot(); -- float f1 = (float) (this.speedModifier * this.guardian.getAttributeValue(Attributes.MOVEMENT_SPEED)); -+ float f1 = (float) (this.getSpeedModifier() * this.guardian.getAttributeValue(Attributes.MOVEMENT_SPEED)); // Purpur - Ridables +- float f1 = (float)(this.speedModifier * this.guardian.getAttributeValue(Attributes.MOVEMENT_SPEED)); ++ float f1 = (float)(this.getSpeedModifier() * this.guardian.getAttributeValue(Attributes.MOVEMENT_SPEED)); // Purpur - Ridables float f2 = Mth.lerp(0.125F, this.guardian.getSpeed(), f1); - this.guardian.setSpeed(f2); + double d3 = Math.sin((this.guardian.tickCount + this.guardian.getId()) * 0.5) * 0.05; diff --git a/net/minecraft/world/entity/monster/Husk.java b/net/minecraft/world/entity/monster/Husk.java -index 184fa759db065fb345f3623752229430816d8ad3..f396652fdc30ec5638b30a8b4189f05fb0eee12d 100644 +index 6155c544ad2722a49c5e41dd7d7b02fedc56474e..23936305045299352561e866b6a28aa515cd614a 100644 --- a/net/minecraft/world/entity/monster/Husk.java +++ b/net/minecraft/world/entity/monster/Husk.java -@@ -23,6 +23,23 @@ public class Husk extends Zombie { - super(type, world); +@@ -21,6 +21,23 @@ public class Husk extends Zombie { + super(entityType, level); } + // Purpur start - Ridables @@ -3726,15 +3696,15 @@ index 184fa759db065fb345f3623752229430816d8ad3..f396652fdc30ec5638b30a8b4189f05f + } + // Purpur end - Ridables + - public static boolean checkHuskSpawnRules(EntityType type, ServerLevelAccessor world, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random) { - return checkMonsterSpawnRules(type, world, spawnReason, pos, random) && (EntitySpawnReason.isSpawner(spawnReason) || world.canSeeSky(pos)); - } + public static boolean checkHuskSpawnRules( + EntityType entityType, ServerLevelAccessor level, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random + ) { diff --git a/net/minecraft/world/entity/monster/Illusioner.java b/net/minecraft/world/entity/monster/Illusioner.java -index db3aac9ba711dcd18ffc35c4a745ecaec89d0166..8ff616fe05071bd2a197a465c7e17f35a3e72d44 100644 +index 40ca12e391b2adac6b132f1832b1427acb3748bc..bd0f4d77260f5b123856fc7e72d5f8e74bb45321 100644 --- a/net/minecraft/world/entity/monster/Illusioner.java +++ b/net/minecraft/world/entity/monster/Illusioner.java -@@ -59,10 +59,28 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { - +@@ -57,10 +57,28 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { + } } + // Purpur start - Ridables @@ -3760,22 +3730,22 @@ index db3aac9ba711dcd18ffc35c4a745ecaec89d0166..8ff616fe05071bd2a197a465c7e17f35 this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables this.goalSelector.addGoal(1, new SpellcasterIllager.SpellcasterCastingSpellGoal()); - this.goalSelector.addGoal(3, new AvoidEntityGoal<>(this, Creaking.class, 8.0F, 1.0D, 1.2D)); + this.goalSelector.addGoal(3, new AvoidEntityGoal<>(this, Creaking.class, 8.0F, 1.0, 1.2)); this.goalSelector.addGoal(4, new Illusioner.IllusionerMirrorSpellGoal()); -@@ -71,6 +89,7 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { - this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.6D)); +@@ -69,6 +87,7 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob { + this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.6)); this.goalSelector.addGoal(9, new LookAtPlayerGoal(this, Player.class, 3.0F, 1.0F)); this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 8.0F)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[]{Raider.class})).setAlertOthers()); - this.targetSelector.addGoal(2, (new NearestAttackableTargetGoal<>(this, Player.class, true)).setUnseenMemoryTicks(300)); - this.targetSelector.addGoal(3, (new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)).setUnseenMemoryTicks(300)); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Raider.class).setAlertOthers()); + this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true).setUnseenMemoryTicks(300)); + this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false).setUnseenMemoryTicks(300)); diff --git a/net/minecraft/world/entity/monster/MagmaCube.java b/net/minecraft/world/entity/monster/MagmaCube.java -index ae710c3fffc7840a9ff2cbc5cdacef8a2e248253..4f7d99fadfa1ba31439ec02bfb107288a722e828 100644 +index 905ecbd8b22c785ee4ea18004ac50eb1b7005d3f..f10b204c18b88e9110cebf050b60c23367ea3aa0 100644 --- a/net/minecraft/world/entity/monster/MagmaCube.java +++ b/net/minecraft/world/entity/monster/MagmaCube.java @@ -24,6 +24,28 @@ public class MagmaCube extends Slime { - super(type, world); + super(entityType, level); } + // Purpur start - Ridables @@ -3804,15 +3774,15 @@ index ae710c3fffc7840a9ff2cbc5cdacef8a2e248253..4f7d99fadfa1ba31439ec02bfb107288 return Monster.createMonsterAttributes().add(Attributes.MOVEMENT_SPEED, 0.2F); } @@ -71,6 +93,7 @@ public class MagmaCube extends Slime { - float f = (float)this.getSize() * 0.1F; - this.setDeltaMovement(vec3.x, (double)(this.getJumpPower() + f), vec3.z); + float f = this.getSize() * 0.1F; + this.setDeltaMovement(deltaMovement.x, this.getJumpPower() + f, deltaMovement.z); this.hasImpulse = true; + this.actualJump = false; // Purpur - Ridables } @Override diff --git a/net/minecraft/world/entity/monster/Phantom.java b/net/minecraft/world/entity/monster/Phantom.java -index 4ff75412452649ebf106ef591cb97dc7ac8175e7..afd00fd83e6c246afecf7042435ae119057b9e93 100644 +index a91aba11ecda561d117c9d8db85c92cdcd81887e..f78976646ea03fbddabdc7ed56229e9d05f90027 100644 --- a/net/minecraft/world/entity/monster/Phantom.java +++ b/net/minecraft/world/entity/monster/Phantom.java @@ -60,6 +60,64 @@ public class Phantom extends FlyingMob implements Enemy { @@ -3869,7 +3839,7 @@ index 4ff75412452649ebf106ef591cb97dc7ac8175e7..afd00fd83e6c246afecf7042435ae119 + loc.setPitch(-loc.getPitch()); + org.bukkit.util.Vector target = loc.getDirection().normalize().multiply(100).add(loc.toVector()); + -+ org.purpurmc.purpur.entity.PhantomFlames flames = new org.purpurmc.purpur.entity.PhantomFlames(level(), this); ++ org.purpurmc.purpur.entity.projectile.PhantomFlames flames = new org.purpurmc.purpur.entity.projectile.PhantomFlames(level(), this); + flames.canGrief = level().purpurConfig.phantomAllowGriefing; + flames.shoot(target.getX() - getX(), target.getY() - getY(), target.getZ() - getZ(), 1.0F, 5.0F); + level().addFreshEntity(flames); @@ -3879,7 +3849,7 @@ index 4ff75412452649ebf106ef591cb97dc7ac8175e7..afd00fd83e6c246afecf7042435ae119 + @Override public boolean isFlapping() { - return (this.getUniqueFlapTickOffset() + this.tickCount) % Phantom.TICKS_PER_FLAP == 0; + return (this.getUniqueFlapTickOffset() + this.tickCount) % TICKS_PER_FLAP == 0; @@ -72,9 +130,11 @@ public class Phantom extends FlyingMob implements Enemy { @Override @@ -3892,7 +3862,7 @@ index 4ff75412452649ebf106ef591cb97dc7ac8175e7..afd00fd83e6c246afecf7042435ae119 this.targetSelector.addGoal(1, new Phantom.PhantomAttackPlayerTargetGoal()); } -@@ -140,6 +200,7 @@ public class Phantom extends FlyingMob implements Enemy { +@@ -147,6 +207,7 @@ public class Phantom extends FlyingMob implements Enemy { @Override public void aiStep() { if (this.isAlive() && this.shouldBurnInDay && this.isSunBurnTick()) { // Paper - shouldBurnInDay API @@ -3900,17 +3870,34 @@ index 4ff75412452649ebf106ef591cb97dc7ac8175e7..afd00fd83e6c246afecf7042435ae119 this.igniteForSeconds(8.0F); } -@@ -254,7 +315,7 @@ public class Phantom extends FlyingMob implements Enemy { - private AttackPhase() {} +@@ -407,25 +468,42 @@ public class Phantom extends FlyingMob implements Enemy { + } } -- private class PhantomMoveControl extends MoveControl { -+ private class PhantomMoveControl extends org.purpurmc.purpur.controller.FlyingMoveControllerWASD { // Purpur - Ridables +- static class PhantomLookControl extends LookControl { ++ static class PhantomLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - Ridables + public PhantomLookControl(Mob mob) { + super(mob); + } ++ // Purpur start - Ridables ++ public void purpurTick(Player rider) { ++ setYawPitch(rider.getYRot(), -rider.xRotO * 0.75F); ++ } ++ // Purpur end - Ridables ++ + @Override +- public void tick() { ++ public void vanillaTick() { // Purpur - Ridables + } + } + +- class PhantomMoveControl extends MoveControl { ++ class PhantomMoveControl extends org.purpurmc.purpur.controller.FlyingMoveControllerWASD { // Purpur - Ridables private float speed = 0.1F; -@@ -262,8 +323,19 @@ public class Phantom extends FlyingMob implements Enemy { - super(entity); + public PhantomMoveControl(final Mob mob) { + super(mob); } + // Purpur start - Ridables @@ -3930,35 +3917,12 @@ index 4ff75412452649ebf106ef591cb97dc7ac8175e7..afd00fd83e6c246afecf7042435ae119 if (Phantom.this.horizontalCollision) { Phantom.this.setYRot(Phantom.this.getYRot() + 180.0F); this.speed = 0.1F; -@@ -309,14 +381,20 @@ public class Phantom extends FlyingMob implements Enemy { - } - } - -- private static class PhantomLookControl extends LookControl { -+ private static class PhantomLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - Ridables - - public PhantomLookControl(Mob entity) { - super(entity); - } - -+ // Purpur start - Ridables -+ public void purpurTick(Player rider) { -+ setYawPitch(rider.getYRot(), -rider.xRotO * 0.75F); -+ } -+ // Purpur end - Ridables -+ - @Override -- public void tick() {} -+ public void vanillaTick() {} // Purpur - Ridables - } - - private class PhantomBodyRotationControl extends BodyRotationControl { diff --git a/net/minecraft/world/entity/monster/Pillager.java b/net/minecraft/world/entity/monster/Pillager.java -index 91edf8767541982b8cd1be83c33a7b287ffb62fe..a629e31e6ea0f49f88746856382fcec96918c490 100644 +index e855ebc5be2cef3b96e2c01a8c1d388e433c0d52..4e799981f04cd17a34f043dda82869adcf16ea98 100644 --- a/net/minecraft/world/entity/monster/Pillager.java +++ b/net/minecraft/world/entity/monster/Pillager.java -@@ -67,16 +67,35 @@ public class Pillager extends AbstractIllager implements CrossbowAttackMob, Inve - super(type, world); +@@ -63,16 +63,35 @@ public class Pillager extends AbstractIllager implements CrossbowAttackMob, Inve + super(entityType, level); } + // Purpur start - Ridables @@ -3983,21 +3947,21 @@ index 91edf8767541982b8cd1be83c33a7b287ffb62fe..a629e31e6ea0f49f88746856382fcec9 super.registerGoals(); this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.goalSelector.addGoal(1, new AvoidEntityGoal<>(this, Creaking.class, 8.0F, 1.0D, 1.2D)); + this.goalSelector.addGoal(1, new AvoidEntityGoal<>(this, Creaking.class, 8.0F, 1.0, 1.2)); this.goalSelector.addGoal(2, new Raider.HoldGroundAttackGoal(this, 10.0F)); - this.goalSelector.addGoal(3, new RangedCrossbowAttackGoal<>(this, 1.0D, 8.0F)); - this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.6D)); + this.goalSelector.addGoal(3, new RangedCrossbowAttackGoal<>(this, 1.0, 8.0F)); + this.goalSelector.addGoal(8, new RandomStrollGoal(this, 0.6)); this.goalSelector.addGoal(9, new LookAtPlayerGoal(this, Player.class, 15.0F, 1.0F)); this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 15.0F)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[]{Raider.class})).setAlertOthers()); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Raider.class).setAlertOthers()); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); diff --git a/net/minecraft/world/entity/monster/Ravager.java b/net/minecraft/world/entity/monster/Ravager.java -index cfc28828a5b81563a826ae6045553e7350f67986..6222ed8408096e0bb8e9572c07c0db6971fc8308 100644 +index 129479cedda20e77719f4f7237ec5b9acc5b00c8..a58a0d5d3872a57c8c5e464bd0f6d2fd7a054990 100644 --- a/net/minecraft/world/entity/monster/Ravager.java +++ b/net/minecraft/world/entity/monster/Ravager.java -@@ -75,14 +75,39 @@ public class Ravager extends Raider { +@@ -66,14 +66,39 @@ public class Ravager extends Raider { this.setPathfindingMalus(PathType.LEAVES, 0.0F); } @@ -4029,28 +3993,28 @@ index cfc28828a5b81563a826ae6045553e7350f67986..6222ed8408096e0bb8e9572c07c0db69 super.registerGoals(); this.goalSelector.addGoal(0, new FloatGoal(this)); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0D, true)); - this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 0.4D)); + this.goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0, true)); + this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 0.4)); this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 6.0F)); this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 8.0F)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(2, (new HurtByTargetGoal(this, new Class[]{Raider.class})).setAlertOthers()); + this.targetSelector.addGoal(2, new HurtByTargetGoal(this, Raider.class).setAlertOthers()); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, true)); - this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, true, (entityliving, worldserver) -> { -@@ -135,7 +160,7 @@ public class Ravager extends Raider { + this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, true, (entity, level) -> !entity.isBaby())); +@@ -130,7 +155,7 @@ public class Ravager extends Raider { @Override public void aiStep() { super.aiStep(); - if (this.isAlive()) { + if (this.isAlive() && (getRider() == null || !this.isControllable())) { // Purpur - Ridables if (this.isImmobile()) { - this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.0D); + this.getAttribute(Attributes.MOVEMENT_SPEED).setBaseValue(0.0); } else { diff --git a/net/minecraft/world/entity/monster/Shulker.java b/net/minecraft/world/entity/monster/Shulker.java -index 64d99b8b576212f754bd316343562b1ba7f604fa..6541e1059ca16cfd01bf01aae2c56400cbe78132 100644 +index 9df62e2ae02c680501cc9284e44c1672315a9cbf..87507f5fad41e7339b02e8a425d41d6213656fbb 100644 --- a/net/minecraft/world/entity/monster/Shulker.java +++ b/net/minecraft/world/entity/monster/Shulker.java -@@ -98,12 +98,31 @@ public class Shulker extends AbstractGolem implements VariantHolder(this, Player.class, true)); } diff --git a/net/minecraft/world/entity/monster/Skeleton.java b/net/minecraft/world/entity/monster/Skeleton.java -index 3972e2ed0554e2550519e994888e068df0a151e5..78c8483da3c0ac7f93e236dd723fc6051427a50e 100644 +index 72468b903a9bbebca817d8a1c6796dc05342a29d..4fa5495893ddaa3e4df1b44c16476948b7419370 100644 --- a/net/minecraft/world/entity/monster/Skeleton.java +++ b/net/minecraft/world/entity/monster/Skeleton.java -@@ -29,6 +29,23 @@ public class Skeleton extends AbstractSkeleton { - super(type, world); +@@ -25,6 +25,23 @@ public class Skeleton extends AbstractSkeleton { + super(entityType, level); } + // Purpur start - Ridables @@ -4158,18 +4122,18 @@ index 3972e2ed0554e2550519e994888e068df0a151e5..78c8483da3c0ac7f93e236dd723fc605 protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); diff --git a/net/minecraft/world/entity/monster/Slime.java b/net/minecraft/world/entity/monster/Slime.java -index 72346a7e5269c91e3143933ac37e65ad9639b791..b7941230b082d4de9ab77c981bd396fa1184d78e 100644 +index 8db4cba1be6d7a5538295ba8da1fdaf7a77a16d0..7d31d68ac0fce102af480a47db73409926611428 100644 --- a/net/minecraft/world/entity/monster/Slime.java +++ b/net/minecraft/world/entity/monster/Slime.java -@@ -65,6 +65,7 @@ public class Slime extends Mob implements Enemy { - public float squish; +@@ -57,6 +57,7 @@ public class Slime extends Mob implements Enemy { public float oSquish; private boolean wasOnGround; + private boolean canWander = true; // Paper - Slime pathfinder events + protected boolean actualJump; // Purpur - Ridables - public Slime(EntityType type, Level world) { - super(type, world); -@@ -72,12 +73,48 @@ public class Slime extends Mob implements Enemy { + public Slime(EntityType entityType, Level level) { + super(entityType, level); +@@ -64,12 +65,48 @@ public class Slime extends Mob implements Enemy { this.moveControl = new Slime.SlimeMoveControl(this); } @@ -4215,27 +4179,27 @@ index 72346a7e5269c91e3143933ac37e65ad9639b791..b7941230b082d4de9ab77c981bd396fa this.goalSelector.addGoal(3, new Slime.SlimeRandomDirectionGoal(this)); this.goalSelector.addGoal(5, new Slime.SlimeKeepOnJumpingGoal(this)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entityliving, worldserver) -> { - return Math.abs(entityliving.getY() - this.getY()) <= 4.0D; - })); -@@ -386,6 +423,7 @@ public class Slime extends Mob implements Enemy { - - this.setDeltaMovement(vec3d.x, (double) this.getJumpPower(), vec3d.z); + this.targetSelector + .addGoal(1, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entity, level) -> Math.abs(entity.getY() - this.getY()) <= 4.0)); + this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true)); +@@ -371,6 +408,7 @@ public class Slime extends Mob implements Enemy { + Vec3 deltaMovement = this.getDeltaMovement(); + this.setDeltaMovement(deltaMovement.x, this.getJumpPower(), deltaMovement.z); this.hasImpulse = true; + this.actualJump = false; // Purpur - Ridables } @Nullable -@@ -419,7 +457,7 @@ public class Slime extends Mob implements Enemy { - return super.getDefaultDimensions(pose).scale((float) this.getSize()); +@@ -535,7 +573,7 @@ public class Slime extends Mob implements Enemy { + } } -- private static class SlimeMoveControl extends MoveControl { -+ private static class SlimeMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables - +- static class SlimeMoveControl extends MoveControl { ++ static class SlimeMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables private float yRot; private int jumpDelay; -@@ -438,21 +476,33 @@ public class Slime extends Mob implements Enemy { + private final Slime slime; +@@ -553,21 +591,33 @@ public class Slime extends Mob implements Enemy { } public void setWantedMovement(double speed) { @@ -4267,26 +4231,26 @@ index 72346a7e5269c91e3143933ac37e65ad9639b791..b7941230b082d4de9ab77c981bd396fa } else { this.operation = MoveControl.Operation.WAIT; if (this.mob.onGround()) { -- this.mob.setSpeed((float) (this.speedModifier * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED))); -+ this.mob.setSpeed((float) (this.getSpeedModifier() * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED) * (slime.getRider() != null && slime.isControllable() && (slime.getRider().getForwardMot() != 0 || slime.getRider().getStrafeMot() != 0) ? 2.0D : 1.0D))); // Purpur - Ridables +- this.mob.setSpeed((float)(this.speedModifier * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED))); ++ this.mob.setSpeed((float)(this.getSpeedModifier() * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED) * (slime.getRider() != null && slime.isControllable() && (slime.getRider().getForwardMot() != 0 || slime.getRider().getStrafeMot() != 0) ? 2.0D : 1.0D))); // Purpur - Ridables if (this.jumpDelay-- <= 0) { this.jumpDelay = this.slime.getJumpDelay(); if (this.isAggressive) { -@@ -469,7 +519,7 @@ public class Slime extends Mob implements Enemy { +@@ -584,7 +634,7 @@ public class Slime extends Mob implements Enemy { this.mob.setSpeed(0.0F); } } else { -- this.mob.setSpeed((float) (this.speedModifier * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED))); -+ this.mob.setSpeed((float) (this.getSpeedModifier() * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED) * (slime.getRider() != null && slime.isControllable() && (slime.getRider().getForwardMot() != 0 || slime.getRider().getStrafeMot() != 0) ? 2.0D : 1.0D))); // Purpur - Ridables +- this.mob.setSpeed((float)(this.speedModifier * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED))); ++ this.mob.setSpeed((float)(this.getSpeedModifier() * this.mob.getAttributeValue(Attributes.MOVEMENT_SPEED) * (slime.getRider() != null && slime.isControllable() && (slime.getRider().getForwardMot() != 0 || slime.getRider().getStrafeMot() != 0) ? 2.0D : 1.0D))); // Purpur - Ridables } - } + } diff --git a/net/minecraft/world/entity/monster/Spider.java b/net/minecraft/world/entity/monster/Spider.java -index 91e521414c3ea5722aac7506b7589fbb399e9636..d3eabdde9e9bf010cae7fc81165f0123adfcf958 100644 +index af0305079a367899708ee2bbac82aefaa9129d2f..ea83335dd0d128b32d2fe513eab82e642b533b4c 100644 --- a/net/minecraft/world/entity/monster/Spider.java +++ b/net/minecraft/world/entity/monster/Spider.java -@@ -51,9 +51,27 @@ public class Spider extends Monster { - super(type, world); +@@ -50,15 +50,34 @@ public class Spider extends Monster { + super(entityType, level); } + // Purpur start - Ridables @@ -4310,23 +4274,22 @@ index 91e521414c3ea5722aac7506b7589fbb399e9636..d3eabdde9e9bf010cae7fc81165f0123 protected void registerGoals() { this.goalSelector.addGoal(1, new FloatGoal(this)); + this.goalSelector.addGoal(1, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.goalSelector.addGoal(2, new AvoidEntityGoal<>(this, Armadillo.class, 6.0F, 1.0D, 1.2D, (entityliving) -> { - return !((Armadillo) entityliving).isScared(); - })); -@@ -62,6 +80,7 @@ public class Spider extends Monster { - this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 0.8D)); + this.goalSelector.addGoal(2, new AvoidEntityGoal<>(this, Armadillo.class, 6.0F, 1.0, 1.2, livingEntity -> !((Armadillo)livingEntity).isScared())); + this.goalSelector.addGoal(3, new LeapAtTargetGoal(this, 0.4F)); + this.goalSelector.addGoal(4, new Spider.SpiderAttackGoal(this)); + this.goalSelector.addGoal(5, new WaterAvoidingRandomStrollGoal(this, 0.8)); this.goalSelector.addGoal(6, new LookAtPlayerGoal(this, Player.class, 8.0F)); this.goalSelector.addGoal(6, new RandomLookAroundGoal(this)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[0])); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this)); this.targetSelector.addGoal(2, new Spider.SpiderTargetGoal<>(this, Player.class)); this.targetSelector.addGoal(3, new Spider.SpiderTargetGoal<>(this, IronGolem.class)); diff --git a/net/minecraft/world/entity/monster/Stray.java b/net/minecraft/world/entity/monster/Stray.java -index baaf17107584b253d7e268749849bf5b0d0c88ab..879748708e3fc8c0a3f126d265e99a7c054d2a10 100644 +index 5fa2b7920a233afb3659b02cbd7ab82307ea9aaf..ed7ba19870a09ac78c1f069040a25e47c4b19d3a 100644 --- a/net/minecraft/world/entity/monster/Stray.java +++ b/net/minecraft/world/entity/monster/Stray.java @@ -22,6 +22,23 @@ public class Stray extends AbstractSkeleton { - super(type, world); + super(entityType, level); } + // Purpur start - Ridables @@ -4347,13 +4310,13 @@ index baaf17107584b253d7e268749849bf5b0d0c88ab..879748708e3fc8c0a3f126d265e99a7c + // Purpur end - Ridables + public static boolean checkStraySpawnRules( - EntityType type, ServerLevelAccessor world, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random + EntityType entityType, ServerLevelAccessor level, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random ) { diff --git a/net/minecraft/world/entity/monster/Strider.java b/net/minecraft/world/entity/monster/Strider.java -index 0a9246241985d2d97beb865b7163f1d2198f03b8..7b1525c6bc46d65660588d90c3121ad3d12cf077 100644 +index cbae85171a1bb64ee3be40ba211d88e68bf672e4..15c1608b1a8f4d59b1d2cbc9c113ac3198119fb2 100644 --- a/net/minecraft/world/entity/monster/Strider.java +++ b/net/minecraft/world/entity/monster/Strider.java -@@ -97,6 +97,23 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { +@@ -94,6 +94,23 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { this.setPathfindingMalus(PathType.DAMAGE_FIRE, 0.0F); } @@ -4374,31 +4337,31 @@ index 0a9246241985d2d97beb865b7163f1d2198f03b8..7b1525c6bc46d65660588d90c3121ad3 + } + // Purpur end - Ridables + - public static boolean checkStriderSpawnRules(EntityType type, LevelAccessor world, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random) { - BlockPos.MutableBlockPos blockposition_mutableblockposition = pos.mutable(); - -@@ -158,6 +175,7 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { + public static boolean checkStriderSpawnRules( + EntityType entityType, LevelAccessor level, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random + ) { +@@ -156,6 +173,7 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { @Override protected void registerGoals() { - this.goalSelector.addGoal(1, new PanicGoal(this, 1.65D)); + this.goalSelector.addGoal(1, new PanicGoal(this, 1.65)); + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.goalSelector.addGoal(2, new BreedGoal(this, 1.0D)); - this.temptGoal = new TemptGoal(this, 1.4D, (itemstack) -> { - return itemstack.is(ItemTags.STRIDER_TEMPT_ITEMS); -@@ -466,7 +484,7 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { - if (!enuminteractionresult.consumesAction()) { - ItemStack itemstack = player.getItemInHand(hand); - -- return (InteractionResult) (itemstack.is(Items.SADDLE) ? itemstack.interactLivingEntity(player, this, hand) : InteractionResult.PASS); -+ return (InteractionResult) (itemstack.is(Items.SADDLE) ? itemstack.interactLivingEntity(player, this, hand) : tryRide(player, hand)); // Purpur - Ridables + this.goalSelector.addGoal(2, new BreedGoal(this, 1.0)); + this.temptGoal = new TemptGoal(this, 1.4, itemStack -> itemStack.is(ItemTags.STRIDER_TEMPT_ITEMS), false); + this.goalSelector.addGoal(3, this.temptGoal); +@@ -424,7 +442,7 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { + InteractionResult interactionResult = super.mobInteract(player, hand); + if (!interactionResult.consumesAction()) { + ItemStack itemInHand = player.getItemInHand(hand); +- return (InteractionResult)(itemInHand.is(Items.SADDLE) ? itemInHand.interactLivingEntity(player, this, hand) : InteractionResult.PASS); ++ return (InteractionResult)(itemInHand.is(Items.SADDLE) ? itemInHand.interactLivingEntity(player, this, hand) : tryRide(player, hand)); // Purpur - Ridables } else { - if (flag && !this.isSilent()) { - this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.STRIDER_EAT, this.getSoundSource(), 1.0F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F); + if (isFood && !this.isSilent()) { + this.level() diff --git a/net/minecraft/world/entity/monster/Vex.java b/net/minecraft/world/entity/monster/Vex.java -index 183a33b7d666d652b455baa7e8339e9c4a870a58..fba52457f85573f5918aeeb5f3b69b3f113cc9d5 100644 +index 7f1cdea810db24182f8f87076c42a19b1b43e98a..26528bc9a9cffb68f82917a3e70900cfb65304d7 100644 --- a/net/minecraft/world/entity/monster/Vex.java +++ b/net/minecraft/world/entity/monster/Vex.java -@@ -59,6 +59,50 @@ public class Vex extends Monster implements TraceableEntity { +@@ -58,6 +58,50 @@ public class Vex extends Monster implements TraceableEntity { this.xpReward = 3; } @@ -4448,8 +4411,8 @@ index 183a33b7d666d652b455baa7e8339e9c4a870a58..fba52457f85573f5918aeeb5f3b69b3f + @Override public boolean isFlapping() { - return this.tickCount % Vex.TICKS_PER_FLAP == 0; -@@ -71,7 +115,7 @@ public class Vex extends Monster implements TraceableEntity { + return this.tickCount % TICKS_PER_FLAP == 0; +@@ -70,7 +114,7 @@ public class Vex extends Monster implements TraceableEntity { @Override public void tick() { @@ -4458,7 +4421,7 @@ index 183a33b7d666d652b455baa7e8339e9c4a870a58..fba52457f85573f5918aeeb5f3b69b3f super.tick(); this.noPhysics = false; this.setNoGravity(true); -@@ -86,17 +130,19 @@ public class Vex extends Monster implements TraceableEntity { +@@ -84,17 +128,19 @@ public class Vex extends Monster implements TraceableEntity { protected void registerGoals() { super.registerGoals(); this.goalSelector.addGoal(0, new FloatGoal(this)); @@ -4468,49 +4431,48 @@ index 183a33b7d666d652b455baa7e8339e9c4a870a58..fba52457f85573f5918aeeb5f3b69b3f this.goalSelector.addGoal(9, new LookAtPlayerGoal(this, Player.class, 3.0F, 1.0F)); this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Mob.class, 8.0F)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[]{Raider.class})).setAlertOthers()); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Raider.class).setAlertOthers()); this.targetSelector.addGoal(2, new Vex.VexCopyOwnerTargetGoal(this)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, true)); } public static AttributeSupplier.Builder createAttributes() { -- return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 14.0D).add(Attributes.ATTACK_DAMAGE, 4.0D); -+ return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 14.0D).add(Attributes.ATTACK_DAMAGE, 4.0D).add(Attributes.FLYING_SPEED, 0.6D); // Purpur; +- return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 14.0).add(Attributes.ATTACK_DAMAGE, 4.0); ++ return Monster.createMonsterAttributes().add(Attributes.MAX_HEALTH, 14.0).add(Attributes.ATTACK_DAMAGE, 4.0).add(Attributes.FLYING_SPEED, 0.6D); // Purpur; } @Override -@@ -228,14 +274,14 @@ public class Vex extends Monster implements TraceableEntity { - this.setDropChance(EquipmentSlot.MAINHAND, 0.0F); +@@ -301,13 +347,13 @@ public class Vex extends Monster implements TraceableEntity { + } } -- private class VexMoveControl extends MoveControl { -+ private class VexMoveControl extends org.purpurmc.purpur.controller.FlyingMoveControllerWASD { // Purpur - Ridables - - public VexMoveControl(final Vex entityvex) { - super(entityvex); +- class VexMoveControl extends MoveControl { ++ class VexMoveControl extends org.purpurmc.purpur.controller.FlyingMoveControllerWASD { // Purpur - Ridables + public VexMoveControl(final Vex mob) { + super(mob); } @Override - public void tick() { + public void vanillaTick() { // Purpur - Ridables if (this.operation == MoveControl.Operation.MOVE_TO) { - Vec3 vec3d = new Vec3(this.wantedX - Vex.this.getX(), this.wantedY - Vex.this.getY(), this.wantedZ - Vex.this.getZ()); - double d0 = vec3d.length(); -@@ -244,7 +290,7 @@ public class Vex extends Monster implements TraceableEntity { + Vec3 vec3 = new Vec3(this.wantedX - Vex.this.getX(), this.wantedY - Vex.this.getY(), this.wantedZ - Vex.this.getZ()); + double len = vec3.length(); +@@ -315,7 +361,7 @@ public class Vex extends Monster implements TraceableEntity { this.operation = MoveControl.Operation.WAIT; - Vex.this.setDeltaMovement(Vex.this.getDeltaMovement().scale(0.5D)); + Vex.this.setDeltaMovement(Vex.this.getDeltaMovement().scale(0.5)); } else { -- Vex.this.setDeltaMovement(Vex.this.getDeltaMovement().add(vec3d.scale(this.speedModifier * 0.05D / d0))); -+ Vex.this.setDeltaMovement(Vex.this.getDeltaMovement().add(vec3d.scale(this.getSpeedModifier() * 0.05D / d0))); // Purpur - Ridables +- Vex.this.setDeltaMovement(Vex.this.getDeltaMovement().add(vec3.scale(this.speedModifier * 0.05 / len))); ++ Vex.this.setDeltaMovement(Vex.this.getDeltaMovement().add(vec3.scale(this.getSpeedModifier() * 0.05 / len))); // Purpur - Ridables if (Vex.this.getTarget() == null) { - Vec3 vec3d1 = Vex.this.getDeltaMovement(); - + Vec3 deltaMovement = Vex.this.getDeltaMovement(); + Vex.this.setYRot(-((float)Mth.atan2(deltaMovement.x, deltaMovement.z)) * (180.0F / (float)Math.PI)); diff --git a/net/minecraft/world/entity/monster/Vindicator.java b/net/minecraft/world/entity/monster/Vindicator.java -index 96b105697c91314148fd1b783501389214b1a3f0..5bf2aad976be5d6149b8252c84cd870551a2aa8e 100644 +index 5f649d1e69d2be8d8e6963544e3aab6848616893..637d7a78dd92851afb8a68bfdbbf84019d21599c 100644 --- a/net/minecraft/world/entity/monster/Vindicator.java +++ b/net/minecraft/world/entity/monster/Vindicator.java @@ -55,15 +55,34 @@ public class Vindicator extends AbstractIllager { - super(type, world); + super(entityType, level); } + // Purpur start - Ridables @@ -4545,11 +4507,11 @@ index 96b105697c91314148fd1b783501389214b1a3f0..5bf2aad976be5d6149b8252c84cd8705 this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, true)); diff --git a/net/minecraft/world/entity/monster/Witch.java b/net/minecraft/world/entity/monster/Witch.java -index a03fa8a3e648532a7ffaaf523ca87c13e8af4c0a..5cba860f9ce81d90eec4c6bf45699d28cf8d93e6 100644 +index 9f5676b5fa0f369adb8643391738c5ae33911df7..0b3c78e646d68ef57a7cf5d7eb77a07c497bd216 100644 --- a/net/minecraft/world/entity/monster/Witch.java +++ b/net/minecraft/world/entity/monster/Witch.java -@@ -57,6 +57,23 @@ public class Witch extends Raider implements RangedAttackMob { - super(type, world); +@@ -56,6 +56,23 @@ public class Witch extends Raider implements RangedAttackMob { + super(entityType, level); } + // Purpur start - Ridables @@ -4572,24 +4534,24 @@ index a03fa8a3e648532a7ffaaf523ca87c13e8af4c0a..5cba860f9ce81d90eec4c6bf45699d28 @Override protected void registerGoals() { super.registerGoals(); -@@ -65,10 +82,12 @@ public class Witch extends Raider implements RangedAttackMob { - }); - this.attackPlayersGoal = new NearestAttackableWitchTargetGoal<>(this, Player.class, 10, true, false, (TargetingConditions.Selector) null); +@@ -64,10 +81,12 @@ public class Witch extends Raider implements RangedAttackMob { + ); + this.attackPlayersGoal = new NearestAttackableWitchTargetGoal<>(this, Player.class, 10, true, false, null); this.goalSelector.addGoal(1, new FloatGoal(this)); + this.goalSelector.addGoal(1, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.goalSelector.addGoal(2, new RangedAttackGoal(this, 1.0D, 60, 10.0F)); - this.goalSelector.addGoal(2, new WaterAvoidingRandomStrollGoal(this, 1.0D)); + this.goalSelector.addGoal(2, new RangedAttackGoal(this, 1.0, 60, 10.0F)); + this.goalSelector.addGoal(2, new WaterAvoidingRandomStrollGoal(this, 1.0)); this.goalSelector.addGoal(3, new LookAtPlayerGoal(this, Player.class, 8.0F)); this.goalSelector.addGoal(3, new RandomLookAroundGoal(this)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[]{Raider.class})); + this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Raider.class)); this.targetSelector.addGoal(2, this.healRaidersGoal); this.targetSelector.addGoal(3, this.attackPlayersGoal); diff --git a/net/minecraft/world/entity/monster/WitherSkeleton.java b/net/minecraft/world/entity/monster/WitherSkeleton.java -index 557b4e225688416132281e9b1759d46a9b775ff9..626cab5a974d2c8736123cc23e535b5cf0e5349e 100644 +index eed8dbefd4d04082dc4e091c858e50309ed5c49b..b0f155564b11ff5fd2430694b937b7826df104ea 100644 --- a/net/minecraft/world/entity/monster/WitherSkeleton.java +++ b/net/minecraft/world/entity/monster/WitherSkeleton.java -@@ -36,6 +36,23 @@ public class WitherSkeleton extends AbstractSkeleton { +@@ -34,6 +34,23 @@ public class WitherSkeleton extends AbstractSkeleton { this.setPathfindingMalus(PathType.LAVA, 8.0F); } @@ -4614,7 +4576,7 @@ index 557b4e225688416132281e9b1759d46a9b775ff9..626cab5a974d2c8736123cc23e535b5c protected void registerGoals() { this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractPiglin.class, true)); diff --git a/net/minecraft/world/entity/monster/Zoglin.java b/net/minecraft/world/entity/monster/Zoglin.java -index 35b0c5c322864e2f5ae5a412296072f268adcd05..2ac14783e7b5739a13c487d5028ecba38480980d 100644 +index 9b94e74f6317f835500225b087fe93487a7a0b22..b279e33bb14dfea4813bba770daf950f5343419d 100644 --- a/net/minecraft/world/entity/monster/Zoglin.java +++ b/net/minecraft/world/entity/monster/Zoglin.java @@ -85,6 +85,23 @@ public class Zoglin extends Monster implements HoglinBase { @@ -4642,19 +4604,19 @@ index 35b0c5c322864e2f5ae5a412296072f268adcd05..2ac14783e7b5739a13c487d5028ecba3 protected Brain.Provider brainProvider() { return Brain.provider(MEMORY_TYPES, SENSOR_TYPES); @@ -250,6 +267,7 @@ public class Zoglin extends Monster implements HoglinBase { - protected void customServerAiStep(ServerLevel world) { + protected void customServerAiStep(ServerLevel level) { ProfilerFiller profilerFiller = Profiler.get(); profilerFiller.push("zoglinBrain"); + if (getRider() == null || !this.isControllable()) // Purpur - only use brain if no rider - this.getBrain().tick(world, this); + this.getBrain().tick(level, this); profilerFiller.pop(); this.updateActivity(); diff --git a/net/minecraft/world/entity/monster/Zombie.java b/net/minecraft/world/entity/monster/Zombie.java -index a12461907278cfbfa3b1c0aa74b9f07a31768b8a..9b4b923117a7025bdbb6d222c6388aeae9bef8a2 100644 +index 637790ff833abaa0c52fdee204abba7077d12ccc..c84de9ba38d365ae93ea4ba047f6812b1161a9ba 100644 --- a/net/minecraft/world/entity/monster/Zombie.java +++ b/net/minecraft/world/entity/monster/Zombie.java -@@ -110,11 +110,30 @@ public class Zombie extends Monster { - this(EntityType.ZOMBIE, world); +@@ -100,11 +100,30 @@ public class Zombie extends Monster { + this(EntityType.ZOMBIE, level); } + // Purpur start - Ridables @@ -4677,7 +4639,7 @@ index a12461907278cfbfa3b1c0aa74b9f07a31768b8a..9b4b923117a7025bdbb6d222c6388aea @Override protected void registerGoals() { + this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables - if (this.level().paperConfig().entities.behavior.zombiesTargetTurtleEggs) this.goalSelector.addGoal(4, new Zombie.ZombieAttackTurtleEggGoal(this, 1.0D, 3)); // Paper - Add zombie targets turtle egg config + if (this.level().paperConfig().entities.behavior.zombiesTargetTurtleEggs) this.goalSelector.addGoal(4, new Zombie.ZombieAttackTurtleEggGoal(this, 1.0, 3)); // Paper - Add zombie targets turtle egg config this.goalSelector.addGoal(8, new LookAtPlayerGoal(this, Player.class, 8.0F)); this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); + this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables @@ -4685,11 +4647,11 @@ index a12461907278cfbfa3b1c0aa74b9f07a31768b8a..9b4b923117a7025bdbb6d222c6388aea } diff --git a/net/minecraft/world/entity/monster/ZombieVillager.java b/net/minecraft/world/entity/monster/ZombieVillager.java -index 30bce56a70f923b0ec77c8e3f29e435a71c71510..9fafe05ef0ffc1120873727082290a8ea177d62f 100644 +index 9061e0b6544d6a31a4dc5b51037f608031a00553..c79e03267b0030e844746945f947616c1b6e4726 100644 --- a/net/minecraft/world/entity/monster/ZombieVillager.java +++ b/net/minecraft/world/entity/monster/ZombieVillager.java -@@ -85,6 +85,23 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { - }); +@@ -78,6 +78,23 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder { + .ifPresent(profession -> this.setVillagerData(this.getVillagerData().setProfession(profession.value()))); } + // Purpur start - Ridables @@ -4713,7 +4675,7 @@ index 30bce56a70f923b0ec77c8e3f29e435a71c71510..9fafe05ef0ffc1120873727082290a8e protected void defineSynchedData(SynchedEntityData.Builder builder) { super.defineSynchedData(builder); diff --git a/net/minecraft/world/entity/monster/ZombifiedPiglin.java b/net/minecraft/world/entity/monster/ZombifiedPiglin.java -index 03e3cbe73119ca76417d4dd192e1560bdfc373ec..69c291c3347a3e3f454ecb8f418a310bbd688a43 100644 +index c7eab22fe4a0541ebdba96961521271ee5619cd4..f2d5866c10e82098d0276320cb3aa3f652b27477 100644 --- a/net/minecraft/world/entity/monster/ZombifiedPiglin.java +++ b/net/minecraft/world/entity/monster/ZombifiedPiglin.java @@ -63,6 +63,23 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob { @@ -4738,13 +4700,13 @@ index 03e3cbe73119ca76417d4dd192e1560bdfc373ec..69c291c3347a3e3f454ecb8f418a310b + // Purpur end - Ridables + @Override - public void setPersistentAngerTarget(@Nullable UUID angryAt) { - this.persistentAngerTarget = angryAt; + public void setPersistentAngerTarget(@Nullable UUID target) { + this.persistentAngerTarget = target; diff --git a/net/minecraft/world/entity/monster/creaking/Creaking.java b/net/minecraft/world/entity/monster/creaking/Creaking.java -index 6a7e725edece3043c8523d387e2929d5ba8932cb..6716bfa903be5ab34b80c963cc9d6a8a26272621 100644 +index eba1e78352f956618b2796ce7cbe5d6f7e6591b6..57ac66c2de97c9b5940c1f0af663a1a26d2c8b73 100644 --- a/net/minecraft/world/entity/monster/creaking/Creaking.java +++ b/net/minecraft/world/entity/monster/creaking/Creaking.java -@@ -106,6 +106,29 @@ public class Creaking extends Monster { +@@ -102,6 +102,29 @@ public class Creaking extends Monster { return this.getHomePos() != null; } @@ -4774,15 +4736,14 @@ index 6a7e725edece3043c8523d387e2929d5ba8932cb..6716bfa903be5ab34b80c963cc9d6a8a @Override protected BodyRotationControl createBodyControl() { return new Creaking.CreakingBodyRotationControl(this); -@@ -575,31 +598,31 @@ public class Creaking extends Monster { - return 0.0F; +@@ -580,28 +603,28 @@ public class Creaking extends Monster { + } } -- private class CreakingLookControl extends LookControl { -+ private class CreakingLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - Ridables - - public CreakingLookControl(final Creaking creaking) { - super(creaking); +- class CreakingLookControl extends LookControl { ++ class CreakingLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - Ridables { + public CreakingLookControl(final Creaking mob) { + super(mob); } @Override @@ -4792,15 +4753,13 @@ index 6a7e725edece3043c8523d387e2929d5ba8932cb..6716bfa903be5ab34b80c963cc9d6a8a - super.tick(); + super.vanillaTick(); // Purpur - Ridables } - } } -- private class CreakingMoveControl extends MoveControl { -+ private class CreakingMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables - - public CreakingMoveControl(final Creaking creaking) { - super(creaking); +- class CreakingMoveControl extends MoveControl { ++ class CreakingMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables + public CreakingMoveControl(final Creaking mob) { + super(mob); } @Override @@ -4810,13 +4769,13 @@ index 6a7e725edece3043c8523d387e2929d5ba8932cb..6716bfa903be5ab34b80c963cc9d6a8a - super.tick(); + super.vanillaTick(); // Purpur - Ridables } - } + } diff --git a/net/minecraft/world/entity/monster/hoglin/Hoglin.java b/net/minecraft/world/entity/monster/hoglin/Hoglin.java -index 92270912ef26924f611a1df7cb3d5b485b0a262d..4ab971e86b48ce3010928fe9046e8f68224719ca 100644 +index 0ddc0fe06a1b701f88ed8f8041ecd68f7da6c86d..028e09e1d8a14d989b2c19ca62e6544a93e1f1c4 100644 --- a/net/minecraft/world/entity/monster/hoglin/Hoglin.java +++ b/net/minecraft/world/entity/monster/hoglin/Hoglin.java -@@ -71,6 +71,23 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { +@@ -92,6 +92,23 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { this.xpReward = 5; } @@ -4840,19 +4799,19 @@ index 92270912ef26924f611a1df7cb3d5b485b0a262d..4ab971e86b48ce3010928fe9046e8f68 @VisibleForTesting public void setTimeInOverworld(int timeInOverworld) { this.timeInOverworld = timeInOverworld; -@@ -143,6 +160,7 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { - ProfilerFiller gameprofilerfiller = Profiler.get(); - - gameprofilerfiller.push("hoglinBrain"); +@@ -160,6 +177,7 @@ public class Hoglin extends Animal implements Enemy, HoglinBase { + protected void customServerAiStep(ServerLevel level) { + ProfilerFiller profilerFiller = Profiler.get(); + profilerFiller.push("hoglinBrain"); + //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider - this.getBrain().tick(world, this); - gameprofilerfiller.pop(); + this.getBrain().tick(level, this); + profilerFiller.pop(); HoglinAi.updateActivity(this); diff --git a/net/minecraft/world/entity/monster/piglin/Piglin.java b/net/minecraft/world/entity/monster/piglin/Piglin.java -index 2121d2a2e1aa1d0f0390cc515317096431f6dcb0..b19e3b442a650f773df462e32088648a2b7eafd4 100644 +index 0257eada48b35ea024520afe30596beae8a7ef1e..02d748ecb10c3e20aafc0c449b99ca5b6cd80e04 100644 --- a/net/minecraft/world/entity/monster/piglin/Piglin.java +++ b/net/minecraft/world/entity/monster/piglin/Piglin.java -@@ -99,6 +99,23 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento +@@ -151,6 +151,23 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento this.xpReward = 5; } @@ -4874,18 +4833,18 @@ index 2121d2a2e1aa1d0f0390cc515317096431f6dcb0..b19e3b442a650f773df462e32088648a + // Purpur end - Ridables + @Override - public void addAdditionalSaveData(CompoundTag nbt) { - super.addAdditionalSaveData(nbt); -@@ -312,6 +329,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento - ProfilerFiller gameprofilerfiller = Profiler.get(); - - gameprofilerfiller.push("piglinBrain"); + public void addAdditionalSaveData(CompoundTag compound) { + super.addAdditionalSaveData(compound); +@@ -346,6 +363,7 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento + protected void customServerAiStep(ServerLevel level) { + ProfilerFiller profilerFiller = Profiler.get(); + profilerFiller.push("piglinBrain"); + //if ((getRider() == null || !this.isControllable()) && this.behaviorTick++ % this.activatedPriority == 0) // Pufferfish // Purpur - only use brain if no rider - this.getBrain().tick(world, this); - gameprofilerfiller.pop(); + this.getBrain().tick(level, this); + profilerFiller.pop(); PiglinAi.updateActivity(this); diff --git a/net/minecraft/world/entity/monster/piglin/PiglinBrute.java b/net/minecraft/world/entity/monster/piglin/PiglinBrute.java -index 24eaeb93284fe1a573026b85818a93a34fd9e1ec..3dc234f8cea8769f715a4913ae4ecf7d47433577 100644 +index 0964b138e87357b7601ddfe937a2b9132afd5478..97241682311797faa93927e0477a7646ce53b2c8 100644 --- a/net/minecraft/world/entity/monster/piglin/PiglinBrute.java +++ b/net/minecraft/world/entity/monster/piglin/PiglinBrute.java @@ -65,6 +65,23 @@ public class PiglinBrute extends AbstractPiglin { @@ -4913,18 +4872,18 @@ index 24eaeb93284fe1a573026b85818a93a34fd9e1ec..3dc234f8cea8769f715a4913ae4ecf7d return Monster.createMonsterAttributes() .add(Attributes.MAX_HEALTH, 50.0) @@ -117,6 +134,7 @@ public class PiglinBrute extends AbstractPiglin { - protected void customServerAiStep(ServerLevel world) { + protected void customServerAiStep(ServerLevel level) { ProfilerFiller profilerFiller = Profiler.get(); profilerFiller.push("piglinBruteBrain"); + if (getRider() == null || this.isControllable()) // Purpur - only use brain if no rider - this.getBrain().tick(world, this); + this.getBrain().tick(level, this); profilerFiller.pop(); PiglinBruteAi.updateActivity(this); diff --git a/net/minecraft/world/entity/monster/warden/Warden.java b/net/minecraft/world/entity/monster/warden/Warden.java -index c47ed605f0822effd58df4f875297ed015e1e57e..19f7a6d55144adb5217fbea590d8f23d79ed05e0 100644 +index 9f476e587d7df797129e49738f101cccca7e10b7..f968e5c99bdb23b268bc34ea1ba5d54ae9ad0ff9 100644 --- a/net/minecraft/world/entity/monster/warden/Warden.java +++ b/net/minecraft/world/entity/monster/warden/Warden.java -@@ -127,8 +127,32 @@ public class Warden extends Monster implements VibrationSystem { +@@ -129,8 +129,32 @@ public class Warden extends Monster implements VibrationSystem { this.setPathfindingMalus(PathType.LAVA, 8.0F); this.setPathfindingMalus(PathType.DAMAGE_FIRE, 0.0F); this.setPathfindingMalus(PathType.DANGER_FIRE, 0.0F); @@ -4955,35 +4914,22 @@ index c47ed605f0822effd58df4f875297ed015e1e57e..19f7a6d55144adb5217fbea590d8f23d + // Purpur end - Ridables + @Override - public Packet getAddEntityPacket(ServerEntity entityTrackerEntry) { - return new ClientboundAddEntityPacket(this, entityTrackerEntry, this.hasPose(Pose.EMERGING) ? 1 : 0); -@@ -396,17 +420,14 @@ public class Warden extends Monster implements VibrationSystem { + public Packet getAddEntityPacket(ServerEntity entity) { + return new ClientboundAddEntityPacket(this, entity, this.hasPose(Pose.EMERGING) ? 1 : 0); +@@ -394,6 +418,7 @@ public class Warden extends Monster implements VibrationSystem { @Contract("null->false") public boolean canTargetEntity(@Nullable Entity entity) { -- boolean flag; -- + if (getRider() != null && isControllable()) return false; // Purpur - Ridables - if (entity instanceof LivingEntity entityliving) { - if (this.level() == entity.level() && EntitySelector.NO_CREATIVE_OR_SPECTATOR.test(entity) && !this.isAlliedTo(entity) && entityliving.getType() != EntityType.ARMOR_STAND && entityliving.getType() != EntityType.WARDEN && !entityliving.isInvulnerable() && !entityliving.isDeadOrDying() && this.level().getWorldBorder().isWithinBounds(entityliving.getBoundingBox())) { -- flag = true; -- return flag; -+ return true; // Purpur - wtf - } - } - -- flag = false; -- return flag; -+ return false; // Purpur - wtf - } - - public static void applyDarknessAround(ServerLevel world, Vec3 pos, @Nullable Entity entity, int range) { + return entity instanceof LivingEntity livingEntity + && this.level() == entity.level() + && EntitySelector.NO_CREATIVE_OR_SPECTATOR.test(entity) diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java -index 2d8ba55906c8da16fde850e3412f4a6bda3d56e7..066836e450ca8d104990c3c5fba5fe3dad2e136e 100644 +index 2b83262e4a13eae86df82913ce4f3121e3631a43..fbb12688470ac4dea129ee171c9fc001bdc8812b 100644 --- a/net/minecraft/world/entity/npc/Villager.java +++ b/net/minecraft/world/entity/npc/Villager.java -@@ -156,6 +156,28 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - this.setVillagerData(this.getVillagerData().setType(type).setProfession(VillagerProfession.NONE)); +@@ -193,6 +193,28 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + this.setVillagerData(this.getVillagerData().setType(villagerType).setProfession(VillagerProfession.NONE)); } + // Purpur start - Ridables @@ -5010,47 +4956,44 @@ index 2d8ba55906c8da16fde850e3412f4a6bda3d56e7..066836e450ca8d104990c3c5fba5fe3d + @Override public Brain getBrain() { - return (Brain) super.getBrain(); // CraftBukkit - decompile error -@@ -255,7 +277,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - ProfilerFiller gameprofilerfiller = Profiler.get(); - - gameprofilerfiller.push("villagerBrain"); -- if (!inactive) this.getBrain().tick(world, this); -+ // Pufferfish start -+ if (!inactive && (getRider() == null || !this.isControllable()) /*&& this.behaviorTick++ % this.activatedPriority == 0*/) { -+ this.getBrain().tick(world, this); // Paper // Purpur - Ridables -+ } -+ // Pufferfish end - gameprofilerfiller.pop(); + return (Brain)super.getBrain(); +@@ -293,7 +315,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + // Paper end - EAR 2 + ProfilerFiller profilerFiller = Profiler.get(); + profilerFiller.push("villagerBrain"); +- if (!inactive) this.getBrain().tick(level, this); // Paper - EAR 2 ++ if (!inactive && (getRider() == null || !this.isControllable()) /*&& this.behaviorTick++ % this.activatedPriority == 0*/) this.getBrain().tick(level, this); // Paper - EAR 2 // Purpur - Ridables + profilerFiller.pop(); if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; -@@ -312,7 +338,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - if (!itemstack.is(Items.VILLAGER_SPAWN_EGG) && this.isAlive() && !this.isTrading() && !this.isSleeping()) { - if (this.isBaby()) { - this.setUnhappy(); -- return InteractionResult.SUCCESS; -+ return tryRide(player, hand, InteractionResult.SUCCESS); // Purpur - Ridables - } else { - if (!this.level().isClientSide) { - boolean flag = this.getOffers().isEmpty(); -@@ -326,9 +352,10 @@ public class Villager extends AbstractVillager implements ReputationEventHandler - } - - if (flag) { -- return InteractionResult.CONSUME; -+ return tryRide(player, hand, InteractionResult.CONSUME); // Purpur - Ridables - } - -+ if (level().purpurConfig.villagerRidable && itemstack.isEmpty()) return tryRide(player, hand); // Purpur - Ridables - this.startTrading(player); +@@ -349,7 +371,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler + return super.mobInteract(player, hand); + } else if (this.isBaby()) { + this.setUnhappy(); +- return InteractionResult.SUCCESS; ++ return tryRide(player, hand, InteractionResult.SUCCESS); // Purpur - Ridables + } else { + if (!this.level().isClientSide) { + boolean isEmpty = this.getOffers().isEmpty(); +@@ -362,9 +384,11 @@ public class Villager extends AbstractVillager implements ReputationEventHandler } + if (isEmpty) { +- return InteractionResult.CONSUME; ++ return tryRide(player, hand, InteractionResult.CONSUME); // Purpur - Ridables + } + ++ if (level().purpurConfig.villagerRidable && itemInHand.isEmpty()) return tryRide(player, hand); // Purpur - Ridables ++ + this.startTrading(player); + } + diff --git a/net/minecraft/world/entity/npc/WanderingTrader.java b/net/minecraft/world/entity/npc/WanderingTrader.java -index 1e77cce428d9e53142aaa2cf780b7f862d536eca..c5bef9f0ad2a0f57d8c37ea0833e899dc588d30f 100644 +index 6655d06e2011e20e7346dfe57527795269094d8a..6c14537c8376bd392524aefde8dfe76b159c3655 100644 --- a/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/net/minecraft/world/entity/npc/WanderingTrader.java -@@ -72,6 +72,23 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill - //this.setDespawnDelay(48000); // CraftBukkit - set default from MobSpawnerTrader // Paper - move back to MobSpawnerTrader - Vanilla behavior is that only traders spawned by it have this value set. +@@ -69,6 +69,23 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill + super(entityType, level); } + // Purpur - start @@ -5073,7 +5016,7 @@ index 1e77cce428d9e53142aaa2cf780b7f862d536eca..c5bef9f0ad2a0f57d8c37ea0833e899d @Override protected void registerGoals() { this.goalSelector.addGoal(0, new FloatGoal(this)); -@@ -120,9 +137,9 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill +@@ -130,9 +147,9 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill if (!this.level().isClientSide) { if (this.getOffers().isEmpty()) { @@ -5081,12 +5024,12 @@ index 1e77cce428d9e53142aaa2cf780b7f862d536eca..c5bef9f0ad2a0f57d8c37ea0833e899d + return tryRide(player, hand, InteractionResult.CONSUME); // Purpur - Ridables } - -+ if (level().purpurConfig.wanderingTraderRidable && itemstack.isEmpty()) return tryRide(player, hand); // Purpur - Ridables ++ if (level().purpurConfig.wanderingTraderRidable && itemInHand.isEmpty()) return tryRide(player, hand); // Purpur - Ridables this.setTradingPlayer(player); this.openTradingScreen(player, this.getDisplayName(), 1); } diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java -index 5b8b85a295a08ae495f729c595b3a78778965342..28a4cf814ec4b34dce883ba4f24ca55008c8f6c1 100644 +index 58932bc9256e9e2ff054ac007971c03187851b53..dda02ceae600f2909aad60bfef0ce29f83ca5a77 100644 --- a/net/minecraft/world/entity/player/Player.java +++ b/net/minecraft/world/entity/player/Player.java @@ -211,6 +211,19 @@ public abstract class Player extends LivingEntity { @@ -5106,32 +5049,32 @@ index 5b8b85a295a08ae495f729c595b3a78778965342..28a4cf814ec4b34dce883ba4f24ca550 + } + // Purpur end - Ridables + - public Player(Level world, BlockPos pos, float yaw, GameProfile gameProfile) { - super(EntityType.PLAYER, world); - this.lastItemInMainHand = ItemStack.EMPTY; + public Player(Level level, BlockPos pos, float yRot, GameProfile gameProfile) { + super(EntityType.PLAYER, level); + this.setUUID(gameProfile.getId()); diff --git a/net/minecraft/world/entity/projectile/LlamaSpit.java b/net/minecraft/world/entity/projectile/LlamaSpit.java -index 958ea103cc80da7366cc33dc385b76d4f5c809f2..f8ff53488d886bfd67ca3bfe4431b42010052d87 100644 +index 4880db97135d54fa72f64c108b2bd4ded096438b..bc102b049047d6e2a1d29e10f92cdf5ae2c140bd 100644 --- a/net/minecraft/world/entity/projectile/LlamaSpit.java +++ b/net/minecraft/world/entity/projectile/LlamaSpit.java @@ -33,6 +33,12 @@ public class LlamaSpit extends Projectile { - this.setPos(owner.getX() - (double) (owner.getBbWidth() + 1.0F) * 0.5D * (double) Mth.sin(owner.yBodyRot * 0.017453292F), owner.getEyeY() - 0.10000000149011612D, owner.getZ() + (double) (owner.getBbWidth() + 1.0F) * 0.5D * (double) Mth.cos(owner.yBodyRot * 0.017453292F)); + ); } + // Purpur start - Ridables -+ public void super_tick() { ++ public void projectileTick() { + super.tick(); + } + // Purpur end - Ridables + @Override protected double getDefaultGravity() { - return 0.06D; + return 0.06; diff --git a/net/minecraft/world/entity/projectile/WitherSkull.java b/net/minecraft/world/entity/projectile/WitherSkull.java -index 4c47b30867e30d84908abf93dbefc252bc8c3453..8296765d8f63f1a9fd207b27d495d7c04646f134 100644 +index a83839fce264429e2a8fd3b19cd2d0a6d88585e0..93aa35ed53e84d06245613b0d64d3fbb158354fe 100644 --- a/net/minecraft/world/entity/projectile/WitherSkull.java +++ b/net/minecraft/world/entity/projectile/WitherSkull.java -@@ -115,6 +115,14 @@ public class WitherSkull extends AbstractHurtingProjectile { - +@@ -103,6 +103,14 @@ public class WitherSkull extends AbstractHurtingProjectile { + } } + // Purpur start - Ridables @@ -5144,1538 +5087,4 @@ index 4c47b30867e30d84908abf93dbefc252bc8c3453..8296765d8f63f1a9fd207b27d495d7c0 + @Override protected void defineSynchedData(SynchedEntityData.Builder builder) { - builder.define(WitherSkull.DATA_DANGEROUS, false); -diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -index b25b10c24a379097233e61bcc10add841b6a7115..c105d0cce462df46e106eb502355225b83be32b7 100644 ---- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java -@@ -1306,4 +1306,27 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { - } - } - // Paper end - broadcast hurt animation -+ -+ // Purpur start - Ridables -+ @Override -+ public org.bukkit.entity.Player getRider() { -+ net.minecraft.world.entity.player.Player rider = getHandle().getRider(); -+ return rider != null ? (org.bukkit.entity.Player) rider.getBukkitEntity() : null; -+ } -+ -+ @Override -+ public boolean hasRider() { -+ return getHandle().getRider() != null; -+ } -+ -+ @Override -+ public boolean isRidable() { -+ return getHandle().isRidable(); -+ } -+ -+ @Override -+ public boolean isRidableInWater() { -+ return !getHandle().dismountsUnderwater(); -+ } -+ // Purpur end - Ridables - } -diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -index e37aaf77f94b97b736cc20ef070cefdff0400188..eb2f9bfdaf3ed8a684337a15365e70174d1533b3 100644 ---- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java -@@ -602,6 +602,15 @@ public class CraftEventFactory { - // Paper end - craftServer.getPluginManager().callEvent(event); - -+ // Purpur start - Ridables -+ if (who != null) { -+ switch (action) { -+ case LEFT_CLICK_BLOCK, LEFT_CLICK_AIR -> who.processClick(InteractionHand.MAIN_HAND); -+ case RIGHT_CLICK_BLOCK, RIGHT_CLICK_AIR -> who.processClick(InteractionHand.OFF_HAND); -+ } -+ } -+ // Purpur end - Ridables -+ - return event; - } - -@@ -1191,6 +1200,7 @@ public class CraftEventFactory { - EntityDamageEvent event; - if (damager != null) { - event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions, critical); -+ damager.processClick(InteractionHand.MAIN_HAND); // Purpur - Ridables - } else { - event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions); - } -diff --git a/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -index c2991c34fd4306fae79fca2c1349c826b3247c49..e8c9393760108f2549b52a61d973ea2b4a64a312 100644 ---- a/src/main/java/org/purpurmc/purpur/PurpurConfig.java -+++ b/src/main/java/org/purpurmc/purpur/PurpurConfig.java -@@ -175,4 +175,9 @@ public class PurpurConfig { - } - return builder.build(); - } -+ -+ public static String cannotRideMob = "You cannot mount that mob"; -+ private static void messages() { -+ cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob); -+ } - } -diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -index 42e502cfcb8d2e775cbf738773caf1a087d2f3f4..5004e86747306cc8d4bbed6f10d3a6e9047cb5f4 100644 ---- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java -@@ -90,4 +90,753 @@ public class PurpurWorldConfig { - final Map value = PurpurConfig.getMap("world-settings." + worldName + "." + path, null); - return value.isEmpty() ? fallback : value; - } -+ -+ public boolean babiesAreRidable = true; -+ public boolean untamedTamablesAreRidable = true; -+ public boolean useNightVisionWhenRiding = false; -+ public boolean useDismountsUnderwaterTag = true; -+ private void ridableSettings() { -+ babiesAreRidable = getBoolean("ridable-settings.babies-are-ridable", babiesAreRidable); -+ untamedTamablesAreRidable = getBoolean("ridable-settings.untamed-tamables-are-ridable", untamedTamablesAreRidable); -+ useNightVisionWhenRiding = getBoolean("ridable-settings.use-night-vision", useNightVisionWhenRiding); -+ useDismountsUnderwaterTag = getBoolean("ridable-settings.use-dismounts-underwater-tag", useDismountsUnderwaterTag); -+ } -+ -+ public boolean allayRidable = false; -+ public boolean allayRidableInWater = true; -+ public boolean allayControllable = true; -+ private void allaySettings() { -+ allayRidable = getBoolean("mobs.allay.ridable", allayRidable); -+ allayRidableInWater = getBoolean("mobs.allay.ridable-in-water", allayRidableInWater); -+ allayControllable = getBoolean("mobs.allay.controllable", allayControllable); -+ } -+ -+ public boolean armadilloRidable = false; -+ public boolean armadilloRidableInWater = true; -+ public boolean armadilloControllable = true; -+ private void armadilloSettings() { -+ armadilloRidable = getBoolean("mobs.armadillo.ridable", armadilloRidable); -+ armadilloRidableInWater = getBoolean("mobs.armadillo.ridable-in-water", armadilloRidableInWater); -+ armadilloControllable = getBoolean("mobs.armadillo.controllable", armadilloControllable); -+ } -+ -+ public boolean axolotlRidable = false; -+ public boolean axolotlControllable = true; -+ private void axolotlSettings() { -+ axolotlRidable = getBoolean("mobs.axolotl.ridable", axolotlRidable); -+ axolotlControllable = getBoolean("mobs.axolotl.controllable", axolotlControllable); -+ } -+ -+ public boolean batRidable = false; -+ public boolean batRidableInWater = true; -+ public boolean batControllable = true; -+ public double batMaxY = 320D; -+ private void batSettings() { -+ batRidable = getBoolean("mobs.bat.ridable", batRidable); -+ batRidableInWater = getBoolean("mobs.bat.ridable-in-water", batRidableInWater); -+ batControllable = getBoolean("mobs.bat.controllable", batControllable); -+ batMaxY = getDouble("mobs.bat.ridable-max-y", batMaxY); -+ } -+ -+ public boolean beeRidable = false; -+ public boolean beeRidableInWater = true; -+ public boolean beeControllable = true; -+ public double beeMaxY = 320D; -+ private void beeSettings() { -+ beeRidable = getBoolean("mobs.bee.ridable", beeRidable); -+ beeRidableInWater = getBoolean("mobs.bee.ridable-in-water", beeRidableInWater); -+ beeControllable = getBoolean("mobs.bee.controllable", beeControllable); -+ beeMaxY = getDouble("mobs.bee.ridable-max-y", beeMaxY); -+ } -+ -+ public boolean blazeRidable = false; -+ public boolean blazeRidableInWater = true; -+ public boolean blazeControllable = true; -+ public double blazeMaxY = 320D; -+ private void blazeSettings() { -+ blazeRidable = getBoolean("mobs.blaze.ridable", blazeRidable); -+ blazeRidableInWater = getBoolean("mobs.blaze.ridable-in-water", blazeRidableInWater); -+ blazeControllable = getBoolean("mobs.blaze.controllable", blazeControllable); -+ blazeMaxY = getDouble("mobs.blaze.ridable-max-y", blazeMaxY); -+ } -+ -+ public boolean boggedRidable = false; -+ public boolean boggedRidableInWater = true; -+ public boolean boggedControllable = true; -+ private void boggedSettings() { -+ boggedRidable = getBoolean("mobs.bogged.ridable", boggedRidable); -+ boggedRidableInWater = getBoolean("mobs.bogged.ridable-in-water", boggedRidableInWater); -+ boggedControllable = getBoolean("mobs.bogged.controllable", boggedControllable); -+ } -+ -+ public boolean camelRidableInWater = false; -+ private void camelSettings() { -+ camelRidableInWater = getBoolean("mobs.camel.ridable-in-water", camelRidableInWater); -+ } -+ -+ public boolean catRidable = false; -+ public boolean catRidableInWater = true; -+ public boolean catControllable = true; -+ private void catSettings() { -+ catRidable = getBoolean("mobs.cat.ridable", catRidable); -+ catRidableInWater = getBoolean("mobs.cat.ridable-in-water", catRidableInWater); -+ catControllable = getBoolean("mobs.cat.controllable", catControllable); -+ } -+ -+ public boolean caveSpiderRidable = false; -+ public boolean caveSpiderRidableInWater = true; -+ public boolean caveSpiderControllable = true; -+ private void caveSpiderSettings() { -+ caveSpiderRidable = getBoolean("mobs.cave_spider.ridable", caveSpiderRidable); -+ caveSpiderRidableInWater = getBoolean("mobs.cave_spider.ridable-in-water", caveSpiderRidableInWater); -+ caveSpiderControllable = getBoolean("mobs.cave_spider.controllable", caveSpiderControllable); -+ } -+ -+ public boolean chickenRidable = false; -+ public boolean chickenRidableInWater = false; -+ public boolean chickenControllable = true; -+ private void chickenSettings() { -+ chickenRidable = getBoolean("mobs.chicken.ridable", chickenRidable); -+ chickenRidableInWater = getBoolean("mobs.chicken.ridable-in-water", chickenRidableInWater); -+ chickenControllable = getBoolean("mobs.chicken.controllable", chickenControllable); -+ } -+ -+ public boolean codRidable = false; -+ public boolean codControllable = true; -+ private void codSettings() { -+ codRidable = getBoolean("mobs.cod.ridable", codRidable); -+ codControllable = getBoolean("mobs.cod.controllable", codControllable); -+ } -+ -+ public boolean cowRidable = false; -+ public boolean cowRidableInWater = true; -+ public boolean cowControllable = true; -+ private void cowSettings() { -+ cowRidable = getBoolean("mobs.cow.ridable", cowRidable); -+ cowRidableInWater = getBoolean("mobs.cow.ridable-in-water", cowRidableInWater); -+ cowControllable = getBoolean("mobs.cow.controllable", cowControllable); -+ } -+ -+ public boolean creakingRidable = false; -+ public boolean creakingRidableInWater = true; -+ public boolean creakingControllable = true; -+ private void creakingSettings() { -+ creakingRidable = getBoolean("mobs.creaking.ridable", creakingRidable); -+ creakingRidableInWater = getBoolean("mobs.creaking.ridable-in-water", creakingRidableInWater); -+ creakingControllable = getBoolean("mobs.creaking.controllable", creakingControllable); -+ } -+ -+ public boolean creeperRidable = false; -+ public boolean creeperRidableInWater = true; -+ public boolean creeperControllable = true; -+ private void creeperSettings() { -+ creeperRidable = getBoolean("mobs.creeper.ridable", creeperRidable); -+ creeperRidableInWater = getBoolean("mobs.creeper.ridable-in-water", creeperRidableInWater); -+ creeperControllable = getBoolean("mobs.creeper.controllable", creeperControllable); -+ } -+ -+ public boolean dolphinRidable = false; -+ public boolean dolphinControllable = true; -+ public int dolphinSpitCooldown = 20; -+ public float dolphinSpitSpeed = 1.0F; -+ public float dolphinSpitDamage = 2.0F; -+ private void dolphinSettings() { -+ dolphinRidable = getBoolean("mobs.dolphin.ridable", dolphinRidable); -+ dolphinControllable = getBoolean("mobs.dolphin.controllable", dolphinControllable); -+ dolphinSpitCooldown = getInt("mobs.dolphin.spit.cooldown", dolphinSpitCooldown); -+ dolphinSpitSpeed = (float) getDouble("mobs.dolphin.spit.speed", dolphinSpitSpeed); -+ dolphinSpitDamage = (float) getDouble("mobs.dolphin.spit.damage", dolphinSpitDamage); -+ } -+ -+ public boolean donkeyRidableInWater = false; -+ private void donkeySettings() { -+ donkeyRidableInWater = getBoolean("mobs.donkey.ridable-in-water", donkeyRidableInWater); -+ } -+ -+ public boolean drownedRidable = false; -+ public boolean drownedRidableInWater = true; -+ public boolean drownedControllable = true; -+ private void drownedSettings() { -+ drownedRidable = getBoolean("mobs.drowned.ridable", drownedRidable); -+ drownedRidableInWater = getBoolean("mobs.drowned.ridable-in-water", drownedRidableInWater); -+ drownedControllable = getBoolean("mobs.drowned.controllable", drownedControllable); -+ } -+ -+ public boolean elderGuardianRidable = false; -+ public boolean elderGuardianControllable = true; -+ private void elderGuardianSettings() { -+ elderGuardianRidable = getBoolean("mobs.elder_guardian.ridable", elderGuardianRidable); -+ elderGuardianControllable = getBoolean("mobs.elder_guardian.controllable", elderGuardianControllable); -+ } -+ -+ public boolean enderDragonRidable = false; -+ public boolean enderDragonRidableInWater = true; -+ public boolean enderDragonControllable = true; -+ public double enderDragonMaxY = 320D; -+ private void enderDragonSettings() { -+ enderDragonRidable = getBoolean("mobs.ender_dragon.ridable", enderDragonRidable); -+ enderDragonRidableInWater = getBoolean("mobs.ender_dragon.ridable-in-water", enderDragonRidableInWater); -+ enderDragonControllable = getBoolean("mobs.ender_dragon.controllable", enderDragonControllable); -+ enderDragonMaxY = getDouble("mobs.ender_dragon.ridable-max-y", enderDragonMaxY); -+ } -+ -+ public boolean endermanRidable = false; -+ public boolean endermanRidableInWater = true; -+ public boolean endermanControllable = true; -+ private void endermanSettings() { -+ endermanRidable = getBoolean("mobs.enderman.ridable", endermanRidable); -+ endermanRidableInWater = getBoolean("mobs.enderman.ridable-in-water", endermanRidableInWater); -+ endermanControllable = getBoolean("mobs.enderman.controllable", endermanControllable); -+ } -+ -+ public boolean endermiteRidable = false; -+ public boolean endermiteRidableInWater = true; -+ public boolean endermiteControllable = true; -+ private void endermiteSettings() { -+ endermiteRidable = getBoolean("mobs.endermite.ridable", endermiteRidable); -+ endermiteRidableInWater = getBoolean("mobs.endermite.ridable-in-water", endermiteRidableInWater); -+ endermiteControllable = getBoolean("mobs.endermite.controllable", endermiteControllable); -+ } -+ -+ public boolean evokerRidable = false; -+ public boolean evokerRidableInWater = true; -+ public boolean evokerControllable = true; -+ private void evokerSettings() { -+ evokerRidable = getBoolean("mobs.evoker.ridable", evokerRidable); -+ evokerRidableInWater = getBoolean("mobs.evoker.ridable-in-water", evokerRidableInWater); -+ evokerControllable = getBoolean("mobs.evoker.controllable", evokerControllable); -+ } -+ -+ public boolean foxRidable = false; -+ public boolean foxRidableInWater = true; -+ public boolean foxControllable = true; -+ private void foxSettings() { -+ foxRidable = getBoolean("mobs.fox.ridable", foxRidable); -+ foxRidableInWater = getBoolean("mobs.fox.ridable-in-water", foxRidableInWater); -+ foxControllable = getBoolean("mobs.fox.controllable", foxControllable); -+ } -+ -+ public boolean frogRidable = false; -+ public boolean frogRidableInWater = true; -+ public boolean frogControllable = true; -+ public float frogRidableJumpHeight = 0.65F; -+ private void frogSettings() { -+ frogRidable = getBoolean("mobs.frog.ridable", frogRidable); -+ frogRidableInWater = getBoolean("mobs.frog.ridable-in-water", frogRidableInWater); -+ frogControllable = getBoolean("mobs.frog.controllable", frogControllable); -+ frogRidableJumpHeight = (float) getDouble("mobs.frog.ridable-jump-height", frogRidableJumpHeight); -+ } -+ -+ public boolean ghastRidable = false; -+ public boolean ghastRidableInWater = true; -+ public boolean ghastControllable = true; -+ public double ghastMaxY = 320D; -+ private void ghastSettings() { -+ ghastRidable = getBoolean("mobs.ghast.ridable", ghastRidable); -+ ghastRidableInWater = getBoolean("mobs.ghast.ridable-in-water", ghastRidableInWater); -+ ghastControllable = getBoolean("mobs.ghast.controllable", ghastControllable); -+ ghastMaxY = getDouble("mobs.ghast.ridable-max-y", ghastMaxY); -+ } -+ -+ public boolean giantRidable = false; -+ public boolean giantRidableInWater = true; -+ public boolean giantControllable = true; -+ private void giantSettings() { -+ giantRidable = getBoolean("mobs.giant.ridable", giantRidable); -+ giantRidableInWater = getBoolean("mobs.giant.ridable-in-water", giantRidableInWater); -+ giantControllable = getBoolean("mobs.giant.controllable", giantControllable); -+ } -+ -+ public boolean glowSquidRidable = false; -+ public boolean glowSquidControllable = true; -+ private void glowSquidSettings() { -+ glowSquidRidable = getBoolean("mobs.glow_squid.ridable", glowSquidRidable); -+ glowSquidControllable = getBoolean("mobs.glow_squid.controllable", glowSquidControllable); -+ } -+ -+ public boolean goatRidable = false; -+ public boolean goatRidableInWater = true; -+ public boolean goatControllable = true; -+ private void goatSettings() { -+ goatRidable = getBoolean("mobs.goat.ridable", goatRidable); -+ goatRidableInWater = getBoolean("mobs.goat.ridable-in-water", goatRidableInWater); -+ goatControllable = getBoolean("mobs.goat.controllable", goatControllable); -+ } -+ -+ public boolean guardianRidable = false; -+ public boolean guardianControllable = true; -+ private void guardianSettings() { -+ guardianRidable = getBoolean("mobs.guardian.ridable", guardianRidable); -+ guardianControllable = getBoolean("mobs.guardian.controllable", guardianControllable); -+ } -+ -+ public boolean hoglinRidable = false; -+ public boolean hoglinRidableInWater = true; -+ public boolean hoglinControllable = true; -+ private void hoglinSettings() { -+ hoglinRidable = getBoolean("mobs.hoglin.ridable", hoglinRidable); -+ hoglinRidableInWater = getBoolean("mobs.hoglin.ridable-in-water", hoglinRidableInWater); -+ hoglinControllable = getBoolean("mobs.hoglin.controllable", hoglinControllable); -+ } -+ -+ public boolean horseRidableInWater = false; -+ private void horseSettings() { -+ horseRidableInWater = getBoolean("mobs.horse.ridable-in-water", horseRidableInWater); -+ } -+ -+ public boolean huskRidable = false; -+ public boolean huskRidableInWater = true; -+ public boolean huskControllable = true; -+ private void huskSettings() { -+ huskRidable = getBoolean("mobs.husk.ridable", huskRidable); -+ huskRidableInWater = getBoolean("mobs.husk.ridable-in-water", huskRidableInWater); -+ huskControllable = getBoolean("mobs.husk.controllable", huskControllable); -+ } -+ -+ public boolean illusionerRidable = false; -+ public boolean illusionerRidableInWater = true; -+ public boolean illusionerControllable = true; -+ private void illusionerSettings() { -+ illusionerRidable = getBoolean("mobs.illusioner.ridable", illusionerRidable); -+ illusionerRidableInWater = getBoolean("mobs.illusioner.ridable-in-water", illusionerRidableInWater); -+ illusionerControllable = getBoolean("mobs.illusioner.controllable", illusionerControllable); -+ } -+ -+ public boolean ironGolemRidable = false; -+ public boolean ironGolemRidableInWater = true; -+ public boolean ironGolemControllable = true; -+ public boolean ironGolemCanSwim = false; -+ private void ironGolemSettings() { -+ ironGolemRidable = getBoolean("mobs.iron_golem.ridable", ironGolemRidable); -+ ironGolemRidableInWater = getBoolean("mobs.iron_golem.ridable-in-water", ironGolemRidableInWater); -+ ironGolemControllable = getBoolean("mobs.iron_golem.controllable", ironGolemControllable); -+ ironGolemCanSwim = getBoolean("mobs.iron_golem.can-swim", ironGolemCanSwim); -+ } -+ -+ public boolean llamaRidable = false; -+ public boolean llamaRidableInWater = false; -+ public boolean llamaControllable = true; -+ private void llamaSettings() { -+ llamaRidable = getBoolean("mobs.llama.ridable", llamaRidable); -+ llamaRidableInWater = getBoolean("mobs.llama.ridable-in-water", llamaRidableInWater); -+ llamaControllable = getBoolean("mobs.llama.controllable", llamaControllable); -+ } -+ -+ public boolean magmaCubeRidable = false; -+ public boolean magmaCubeRidableInWater = true; -+ public boolean magmaCubeControllable = true; -+ private void magmaCubeSettings() { -+ magmaCubeRidable = getBoolean("mobs.magma_cube.ridable", magmaCubeRidable); -+ magmaCubeRidableInWater = getBoolean("mobs.magma_cube.ridable-in-water", magmaCubeRidableInWater); -+ magmaCubeControllable = getBoolean("mobs.magma_cube.controllable", magmaCubeControllable); -+ } -+ -+ public boolean mooshroomRidable = false; -+ public boolean mooshroomRidableInWater = true; -+ public boolean mooshroomControllable = true; -+ private void mooshroomSettings() { -+ mooshroomRidable = getBoolean("mobs.mooshroom.ridable", mooshroomRidable); -+ mooshroomRidableInWater = getBoolean("mobs.mooshroom.ridable-in-water", mooshroomRidableInWater); -+ mooshroomControllable = getBoolean("mobs.mooshroom.controllable", mooshroomControllable); -+ } -+ -+ public boolean muleRidableInWater = false; -+ private void muleSettings() { -+ muleRidableInWater = getBoolean("mobs.mule.ridable-in-water", muleRidableInWater); -+ } -+ -+ public boolean ocelotRidable = false; -+ public boolean ocelotRidableInWater = true; -+ public boolean ocelotControllable = true; -+ private void ocelotSettings() { -+ ocelotRidable = getBoolean("mobs.ocelot.ridable", ocelotRidable); -+ ocelotRidableInWater = getBoolean("mobs.ocelot.ridable-in-water", ocelotRidableInWater); -+ ocelotControllable = getBoolean("mobs.ocelot.controllable", ocelotControllable); -+ } -+ -+ public boolean pandaRidable = false; -+ public boolean pandaRidableInWater = true; -+ public boolean pandaControllable = true; -+ private void pandaSettings() { -+ pandaRidable = getBoolean("mobs.panda.ridable", pandaRidable); -+ pandaRidableInWater = getBoolean("mobs.panda.ridable-in-water", pandaRidableInWater); -+ pandaControllable = getBoolean("mobs.panda.controllable", pandaControllable); -+ } -+ -+ public boolean parrotRidable = false; -+ public boolean parrotRidableInWater = true; -+ public boolean parrotControllable = true; -+ public double parrotMaxY = 320D; -+ private void parrotSettings() { -+ parrotRidable = getBoolean("mobs.parrot.ridable", parrotRidable); -+ parrotRidableInWater = getBoolean("mobs.parrot.ridable-in-water", parrotRidableInWater); -+ parrotControllable = getBoolean("mobs.parrot.controllable", parrotControllable); -+ parrotMaxY = getDouble("mobs.parrot.ridable-max-y", parrotMaxY); -+ } -+ -+ public boolean phantomRidable = false; -+ public boolean phantomRidableInWater = true; -+ public boolean phantomControllable = true; -+ public double phantomMaxY = 320D; -+ public float phantomFlameDamage = 1.0F; -+ public int phantomFlameFireTime = 8; -+ public boolean phantomAllowGriefing = false; -+ private void phantomSettings() { -+ phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable); -+ phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater); -+ phantomControllable = getBoolean("mobs.phantom.controllable", phantomControllable); -+ phantomMaxY = getDouble("mobs.phantom.ridable-max-y", phantomMaxY); -+ phantomFlameDamage = (float) getDouble("mobs.phantom.flames.damage", phantomFlameDamage); -+ phantomFlameFireTime = getInt("mobs.phantom.flames.fire-time", phantomFlameFireTime); -+ phantomAllowGriefing = getBoolean("mobs.phantom.allow-griefing", phantomAllowGriefing); -+ } -+ -+ public boolean pigRidable = false; -+ public boolean pigRidableInWater = false; -+ public boolean pigControllable = true; -+ private void pigSettings() { -+ pigRidable = getBoolean("mobs.pig.ridable", pigRidable); -+ pigRidableInWater = getBoolean("mobs.pig.ridable-in-water", pigRidableInWater); -+ pigControllable = getBoolean("mobs.pig.controllable", pigControllable); -+ } -+ -+ public boolean piglinRidable = false; -+ public boolean piglinRidableInWater = true; -+ public boolean piglinControllable = true; -+ private void piglinSettings() { -+ piglinRidable = getBoolean("mobs.piglin.ridable", piglinRidable); -+ piglinRidableInWater = getBoolean("mobs.piglin.ridable-in-water", piglinRidableInWater); -+ piglinControllable = getBoolean("mobs.piglin.controllable", piglinControllable); -+ } -+ -+ public boolean piglinBruteRidable = false; -+ public boolean piglinBruteRidableInWater = true; -+ public boolean piglinBruteControllable = true; -+ private void piglinBruteSettings() { -+ piglinBruteRidable = getBoolean("mobs.piglin_brute.ridable", piglinBruteRidable); -+ piglinBruteRidableInWater = getBoolean("mobs.piglin_brute.ridable-in-water", piglinBruteRidableInWater); -+ piglinBruteControllable = getBoolean("mobs.piglin_brute.controllable", piglinBruteControllable); -+ } -+ -+ public boolean pillagerRidable = false; -+ public boolean pillagerRidableInWater = true; -+ public boolean pillagerControllable = true; -+ private void pillagerSettings() { -+ pillagerRidable = getBoolean("mobs.pillager.ridable", pillagerRidable); -+ pillagerRidableInWater = getBoolean("mobs.pillager.ridable-in-water", pillagerRidableInWater); -+ pillagerControllable = getBoolean("mobs.pillager.controllable", pillagerControllable); -+ } -+ -+ public boolean polarBearRidable = false; -+ public boolean polarBearRidableInWater = true; -+ public boolean polarBearControllable = true; -+ private void polarBearSettings() { -+ polarBearRidable = getBoolean("mobs.polar_bear.ridable", polarBearRidable); -+ polarBearRidableInWater = getBoolean("mobs.polar_bear.ridable-in-water", polarBearRidableInWater); -+ polarBearControllable = getBoolean("mobs.polar_bear.controllable", polarBearControllable); -+ } -+ -+ public boolean pufferfishRidable = false; -+ public boolean pufferfishControllable = true; -+ private void pufferfishSettings() { -+ pufferfishRidable = getBoolean("mobs.pufferfish.ridable", pufferfishRidable); -+ pufferfishControllable = getBoolean("mobs.pufferfish.controllable", pufferfishControllable); -+ } -+ -+ public boolean rabbitRidable = false; -+ public boolean rabbitRidableInWater = true; -+ public boolean rabbitControllable = true; -+ private void rabbitSettings() { -+ rabbitRidable = getBoolean("mobs.rabbit.ridable", rabbitRidable); -+ rabbitRidableInWater = getBoolean("mobs.rabbit.ridable-in-water", rabbitRidableInWater); -+ rabbitControllable = getBoolean("mobs.rabbit.controllable", rabbitControllable); -+ } -+ -+ public boolean ravagerRidable = false; -+ public boolean ravagerRidableInWater = false; -+ public boolean ravagerControllable = true; -+ private void ravagerSettings() { -+ ravagerRidable = getBoolean("mobs.ravager.ridable", ravagerRidable); -+ ravagerRidableInWater = getBoolean("mobs.ravager.ridable-in-water", ravagerRidableInWater); -+ ravagerControllable = getBoolean("mobs.ravager.controllable", ravagerControllable); -+ } -+ -+ public boolean salmonRidable = false; -+ public boolean salmonControllable = true; -+ private void salmonSettings() { -+ salmonRidable = getBoolean("mobs.salmon.ridable", salmonRidable); -+ salmonControllable = getBoolean("mobs.salmon.controllable", salmonControllable); -+ } -+ -+ public boolean sheepRidable = false; -+ public boolean sheepRidableInWater = true; -+ public boolean sheepControllable = true; -+ private void sheepSettings() { -+ sheepRidable = getBoolean("mobs.sheep.ridable", sheepRidable); -+ sheepRidableInWater = getBoolean("mobs.sheep.ridable-in-water", sheepRidableInWater); -+ sheepControllable = getBoolean("mobs.sheep.controllable", sheepControllable); -+ } -+ -+ public boolean shulkerRidable = false; -+ public boolean shulkerRidableInWater = true; -+ public boolean shulkerControllable = true; -+ private void shulkerSettings() { -+ shulkerRidable = getBoolean("mobs.shulker.ridable", shulkerRidable); -+ shulkerRidableInWater = getBoolean("mobs.shulker.ridable-in-water", shulkerRidableInWater); -+ shulkerControllable = getBoolean("mobs.shulker.controllable", shulkerControllable); -+ } -+ -+ public boolean silverfishRidable = false; -+ public boolean silverfishRidableInWater = true; -+ public boolean silverfishControllable = true; -+ private void silverfishSettings() { -+ silverfishRidable = getBoolean("mobs.silverfish.ridable", silverfishRidable); -+ silverfishRidableInWater = getBoolean("mobs.silverfish.ridable-in-water", silverfishRidableInWater); -+ silverfishControllable = getBoolean("mobs.silverfish.controllable", silverfishControllable); -+ } -+ -+ public boolean skeletonRidable = false; -+ public boolean skeletonRidableInWater = true; -+ public boolean skeletonControllable = true; -+ private void skeletonSettings() { -+ skeletonRidable = getBoolean("mobs.skeleton.ridable", skeletonRidable); -+ skeletonRidableInWater = getBoolean("mobs.skeleton.ridable-in-water", skeletonRidableInWater); -+ skeletonControllable = getBoolean("mobs.skeleton.controllable", skeletonControllable); -+ } -+ -+ public boolean skeletonHorseRidable = false; -+ public boolean skeletonHorseRidableInWater = true; -+ public boolean skeletonHorseCanSwim = false; -+ private void skeletonHorseSettings() { -+ skeletonHorseRidable = getBoolean("mobs.skeleton_horse.ridable", skeletonHorseRidable); -+ skeletonHorseRidableInWater = getBoolean("mobs.skeleton_horse.ridable-in-water", skeletonHorseRidableInWater); -+ skeletonHorseCanSwim = getBoolean("mobs.skeleton_horse.can-swim", skeletonHorseCanSwim); -+ } -+ -+ public boolean slimeRidable = false; -+ public boolean slimeRidableInWater = true; -+ public boolean slimeControllable = true; -+ private void slimeSettings() { -+ slimeRidable = getBoolean("mobs.slime.ridable", slimeRidable); -+ slimeRidableInWater = getBoolean("mobs.slime.ridable-in-water", slimeRidableInWater); -+ slimeControllable = getBoolean("mobs.slime.controllable", slimeControllable); -+ } -+ -+ public boolean snowGolemRidable = false; -+ public boolean snowGolemRidableInWater = true; -+ public boolean snowGolemControllable = true; -+ public boolean snowGolemLeaveTrailWhenRidden = false; -+ private void snowGolemSettings() { -+ snowGolemRidable = getBoolean("mobs.snow_golem.ridable", snowGolemRidable); -+ snowGolemRidableInWater = getBoolean("mobs.snow_golem.ridable-in-water", snowGolemRidableInWater); -+ snowGolemControllable = getBoolean("mobs.snow_golem.controllable", snowGolemControllable); -+ snowGolemLeaveTrailWhenRidden = getBoolean("mobs.snow_golem.leave-trail-when-ridden", snowGolemLeaveTrailWhenRidden); -+ } -+ -+ public boolean snifferRidable = false; -+ public boolean snifferRidableInWater = true; -+ public boolean snifferControllable = true; -+ private void snifferSettings() { -+ snifferRidable = getBoolean("mobs.sniffer.ridable", snifferRidable); -+ snifferRidableInWater = getBoolean("mobs.sniffer.ridable-in-water", snifferRidableInWater); -+ snifferControllable = getBoolean("mobs.sniffer.controllable", snifferControllable); -+ } -+ -+ public boolean squidRidable = false; -+ public boolean squidControllable = true; -+ private void squidSettings() { -+ squidRidable = getBoolean("mobs.squid.ridable", squidRidable); -+ squidControllable = getBoolean("mobs.squid.controllable", squidControllable); -+ } -+ -+ public boolean spiderRidable = false; -+ public boolean spiderRidableInWater = false; -+ public boolean spiderControllable = true; -+ private void spiderSettings() { -+ spiderRidable = getBoolean("mobs.spider.ridable", spiderRidable); -+ spiderRidableInWater = getBoolean("mobs.spider.ridable-in-water", spiderRidableInWater); -+ spiderControllable = getBoolean("mobs.spider.controllable", spiderControllable); -+ } -+ -+ public boolean strayRidable = false; -+ public boolean strayRidableInWater = true; -+ public boolean strayControllable = true; -+ private void straySettings() { -+ strayRidable = getBoolean("mobs.stray.ridable", strayRidable); -+ strayRidableInWater = getBoolean("mobs.stray.ridable-in-water", strayRidableInWater); -+ strayControllable = getBoolean("mobs.stray.controllable", strayControllable); -+ } -+ -+ public boolean striderRidable = false; -+ public boolean striderRidableInWater = false; -+ public boolean striderControllable = true; -+ private void striderSettings() { -+ striderRidable = getBoolean("mobs.strider.ridable", striderRidable); -+ striderRidableInWater = getBoolean("mobs.strider.ridable-in-water", striderRidableInWater); -+ striderControllable = getBoolean("mobs.strider.controllable", striderControllable); -+ } -+ -+ public boolean tadpoleRidable = false; -+ public boolean tadpoleRidableInWater = true; -+ public boolean tadpoleControllable = true; -+ private void tadpoleSettings() { -+ tadpoleRidable = getBoolean("mobs.tadpole.ridable", tadpoleRidable); -+ tadpoleRidableInWater = getBoolean("mobs.tadpole.ridable-in-water", tadpoleRidableInWater); -+ tadpoleControllable = getBoolean("mobs.tadpole.controllable", tadpoleControllable); -+ } -+ -+ public boolean traderLlamaRidable = false; -+ public boolean traderLlamaRidableInWater = false; -+ public boolean traderLlamaControllable = true; -+ private void traderLlamaSettings() { -+ traderLlamaRidable = getBoolean("mobs.trader_llama.ridable", traderLlamaRidable); -+ traderLlamaRidableInWater = getBoolean("mobs.trader_llama.ridable-in-water", traderLlamaRidableInWater); -+ traderLlamaControllable = getBoolean("mobs.trader_llama.controllable", traderLlamaControllable); -+ } -+ -+ public boolean tropicalFishRidable = false; -+ public boolean tropicalFishControllable = true; -+ private void tropicalFishSettings() { -+ tropicalFishRidable = getBoolean("mobs.tropical_fish.ridable", tropicalFishRidable); -+ tropicalFishControllable = getBoolean("mobs.tropical_fish.controllable", tropicalFishControllable); -+ } -+ -+ public boolean turtleRidable = false; -+ public boolean turtleRidableInWater = true; -+ public boolean turtleControllable = true; -+ private void turtleSettings() { -+ turtleRidable = getBoolean("mobs.turtle.ridable", turtleRidable); -+ turtleRidableInWater = getBoolean("mobs.turtle.ridable-in-water", turtleRidableInWater); -+ turtleControllable = getBoolean("mobs.turtle.controllable", turtleControllable); -+ } -+ -+ public boolean vexRidable = false; -+ public boolean vexRidableInWater = true; -+ public boolean vexControllable = true; -+ public double vexMaxY = 320D; -+ private void vexSettings() { -+ vexRidable = getBoolean("mobs.vex.ridable", vexRidable); -+ vexRidableInWater = getBoolean("mobs.vex.ridable-in-water", vexRidableInWater); -+ vexControllable = getBoolean("mobs.vex.controllable", vexControllable); -+ vexMaxY = getDouble("mobs.vex.ridable-max-y", vexMaxY); -+ } -+ -+ public boolean villagerRidable = false; -+ public boolean villagerRidableInWater = true; -+ public boolean villagerControllable = true; -+ private void villagerSettings() { -+ villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); -+ villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); -+ villagerControllable = getBoolean("mobs.villager.controllable", villagerControllable); -+ } -+ -+ public boolean vindicatorRidable = false; -+ public boolean vindicatorRidableInWater = true; -+ public boolean vindicatorControllable = true; -+ private void vindicatorSettings() { -+ vindicatorRidable = getBoolean("mobs.vindicator.ridable", vindicatorRidable); -+ vindicatorRidableInWater = getBoolean("mobs.vindicator.ridable-in-water", vindicatorRidableInWater); -+ vindicatorControllable = getBoolean("mobs.vindicator.controllable", vindicatorControllable); -+ } -+ -+ public boolean wanderingTraderRidable = false; -+ public boolean wanderingTraderRidableInWater = true; -+ public boolean wanderingTraderControllable = true; -+ private void wanderingTraderSettings() { -+ wanderingTraderRidable = getBoolean("mobs.wandering_trader.ridable", wanderingTraderRidable); -+ wanderingTraderRidableInWater = getBoolean("mobs.wandering_trader.ridable-in-water", wanderingTraderRidableInWater); -+ wanderingTraderControllable = getBoolean("mobs.wandering_trader.controllable", wanderingTraderControllable); -+ } -+ -+ public boolean wardenRidable = false; -+ public boolean wardenRidableInWater = true; -+ public boolean wardenControllable = true; -+ private void wardenSettings() { -+ wardenRidable = getBoolean("mobs.warden.ridable", wardenRidable); -+ wardenRidableInWater = getBoolean("mobs.warden.ridable-in-water", wardenRidableInWater); -+ wardenControllable = getBoolean("mobs.warden.controllable", wardenControllable); -+ } -+ -+ public boolean witchRidable = false; -+ public boolean witchRidableInWater = true; -+ public boolean witchControllable = true; -+ private void witchSettings() { -+ witchRidable = getBoolean("mobs.witch.ridable", witchRidable); -+ witchRidableInWater = getBoolean("mobs.witch.ridable-in-water", witchRidableInWater); -+ witchControllable = getBoolean("mobs.witch.controllable", witchControllable); -+ } -+ -+ public boolean witherRidable = false; -+ public boolean witherRidableInWater = true; -+ public boolean witherControllable = true; -+ public double witherMaxY = 320D; -+ private void witherSettings() { -+ witherRidable = getBoolean("mobs.wither.ridable", witherRidable); -+ witherRidableInWater = getBoolean("mobs.wither.ridable-in-water", witherRidableInWater); -+ witherControllable = getBoolean("mobs.wither.controllable", witherControllable); -+ witherMaxY = getDouble("mobs.wither.ridable-max-y", witherMaxY); -+ } -+ -+ public boolean witherSkeletonRidable = false; -+ public boolean witherSkeletonRidableInWater = true; -+ public boolean witherSkeletonControllable = true; -+ private void witherSkeletonSettings() { -+ witherSkeletonRidable = getBoolean("mobs.wither_skeleton.ridable", witherSkeletonRidable); -+ witherSkeletonRidableInWater = getBoolean("mobs.wither_skeleton.ridable-in-water", witherSkeletonRidableInWater); -+ witherSkeletonControllable = getBoolean("mobs.wither_skeleton.controllable", witherSkeletonControllable); -+ } -+ -+ public boolean wolfRidable = false; -+ public boolean wolfRidableInWater = true; -+ public boolean wolfControllable = true; -+ private void wolfSettings() { -+ wolfRidable = getBoolean("mobs.wolf.ridable", wolfRidable); -+ wolfRidableInWater = getBoolean("mobs.wolf.ridable-in-water", wolfRidableInWater); -+ wolfControllable = getBoolean("mobs.wolf.controllable", wolfControllable); -+ } -+ -+ public boolean zoglinRidable = false; -+ public boolean zoglinRidableInWater = true; -+ public boolean zoglinControllable = true; -+ private void zoglinSettings() { -+ zoglinRidable = getBoolean("mobs.zoglin.ridable", zoglinRidable); -+ zoglinRidableInWater = getBoolean("mobs.zoglin.ridable-in-water", zoglinRidableInWater); -+ zoglinControllable = getBoolean("mobs.zoglin.controllable", zoglinControllable); -+ } -+ -+ public boolean zombieRidable = false; -+ public boolean zombieRidableInWater = true; -+ public boolean zombieControllable = true; -+ private void zombieSettings() { -+ zombieRidable = getBoolean("mobs.zombie.ridable", zombieRidable); -+ zombieRidableInWater = getBoolean("mobs.zombie.ridable-in-water", zombieRidableInWater); -+ zombieControllable = getBoolean("mobs.zombie.controllable", zombieControllable); -+ } -+ -+ public boolean zombieHorseRidable = false; -+ public boolean zombieHorseRidableInWater = false; -+ public boolean zombieHorseCanSwim = false; -+ private void zombieHorseSettings() { -+ zombieHorseRidable = getBoolean("mobs.zombie_horse.ridable", zombieHorseRidable); -+ zombieHorseRidableInWater = getBoolean("mobs.zombie_horse.ridable-in-water", zombieHorseRidableInWater); -+ zombieHorseCanSwim = getBoolean("mobs.zombie_horse.can-swim", zombieHorseCanSwim); -+ } -+ -+ public boolean zombieVillagerRidable = false; -+ public boolean zombieVillagerRidableInWater = true; -+ public boolean zombieVillagerControllable = true; -+ private void zombieVillagerSettings() { -+ zombieVillagerRidable = getBoolean("mobs.zombie_villager.ridable", zombieVillagerRidable); -+ zombieVillagerRidableInWater = getBoolean("mobs.zombie_villager.ridable-in-water", zombieVillagerRidableInWater); -+ zombieVillagerControllable = getBoolean("mobs.zombie_villager.controllable", zombieVillagerControllable); -+ } -+ -+ public boolean zombifiedPiglinRidable = false; -+ public boolean zombifiedPiglinRidableInWater = true; -+ public boolean zombifiedPiglinControllable = true; -+ private void zombifiedPiglinSettings() { -+ zombifiedPiglinRidable = getBoolean("mobs.zombified_piglin.ridable", zombifiedPiglinRidable); -+ zombifiedPiglinRidableInWater = getBoolean("mobs.zombified_piglin.ridable-in-water", zombifiedPiglinRidableInWater); -+ zombifiedPiglinControllable = getBoolean("mobs.zombified_piglin.controllable", zombifiedPiglinControllable); -+ } - } -diff --git a/src/main/java/org/purpurmc/purpur/controller/FlyingMoveControllerWASD.java b/src/main/java/org/purpurmc/purpur/controller/FlyingMoveControllerWASD.java -new file mode 100644 -index 0000000000000000000000000000000000000000..940bcc6f79b59cb3cce578912eb789efd394f456 ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/controller/FlyingMoveControllerWASD.java -@@ -0,0 +1,74 @@ -+package org.purpurmc.purpur.controller; -+ -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.world.entity.Mob; -+import net.minecraft.world.entity.ai.attributes.Attributes; -+import net.minecraft.world.entity.player.Input; -+import net.minecraft.world.entity.player.Player; -+ -+public class FlyingMoveControllerWASD extends MoveControllerWASD { -+ protected final float groundSpeedModifier; -+ protected final float flyingSpeedModifier; -+ protected int tooHighCooldown = 0; -+ protected boolean setNoGravityFlag; -+ -+ public FlyingMoveControllerWASD(Mob entity) { -+ this(entity, 1.0F); -+ } -+ -+ public FlyingMoveControllerWASD(Mob entity, float groundSpeedModifier) { -+ this(entity, groundSpeedModifier, 1.0F, true); -+ } -+ -+ public FlyingMoveControllerWASD(Mob entity, float groundSpeedModifier, float flyingSpeedModifier) { -+ this(entity, groundSpeedModifier, flyingSpeedModifier, true); -+ } -+ -+ public FlyingMoveControllerWASD(Mob entity, float groundSpeedModifier, float flyingSpeedModifier, boolean setNoGravityFlag) { -+ super(entity); -+ this.groundSpeedModifier = groundSpeedModifier; -+ this.flyingSpeedModifier = flyingSpeedModifier; -+ this.setNoGravityFlag = setNoGravityFlag; -+ } -+ -+ @Override -+ public void purpurTick(Player rider) { -+ Input lastClientInput = ((ServerPlayer) rider).getLastClientInput(); -+ float forward = lastClientInput.forward() == lastClientInput.backward() ? 0.0F : lastClientInput.forward() ? 1.0F : 0.0F; -+ float vertical = forward == 0.0F ? 0.0F : -(rider.xRotO / 45.0F); -+ float strafe = (lastClientInput.left() == lastClientInput.right() ? 0.0F : lastClientInput.left() ? 1.0F : -1.0F); -+ -+ if (lastClientInput.jump() && spacebarEvent(entity)) { -+ entity.onSpacebar(); -+ } -+ -+ if (entity.getY() >= entity.getMaxY() || --tooHighCooldown > 0) { -+ if (tooHighCooldown <= 0) { -+ tooHighCooldown = 20; -+ } -+ entity.setDeltaMovement(entity.getDeltaMovement().add(0.0D, -0.05D, 0.0D)); -+ vertical = 0.0F; -+ } -+ -+ setSpeedModifier(entity.getAttributeValue(Attributes.MOVEMENT_SPEED)); -+ float speed = (float) getSpeedModifier(); -+ -+ if (entity.onGround) { -+ speed *= groundSpeedModifier; // TODO = fix this! -+ } else { -+ speed *= flyingSpeedModifier; -+ } -+ -+ if (setNoGravityFlag) { -+ entity.setNoGravity(forward > 0); -+ } -+ -+ entity.setSpeed(speed); -+ entity.setVerticalMot(vertical); -+ entity.setStrafeMot(strafe); -+ entity.setForwardMot(forward); -+ -+ setForward(entity.getForwardMot()); -+ setStrafe(entity.getStrafeMot()); -+ } -+} -diff --git a/src/main/java/org/purpurmc/purpur/controller/FlyingWithSpacebarMoveControllerWASD.java b/src/main/java/org/purpurmc/purpur/controller/FlyingWithSpacebarMoveControllerWASD.java -new file mode 100644 -index 0000000000000000000000000000000000000000..e0bbaec05afa0ae67ed486b14ea1fbadbbe90d9b ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/controller/FlyingWithSpacebarMoveControllerWASD.java -@@ -0,0 +1,66 @@ -+package org.purpurmc.purpur.controller; -+ -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.world.entity.Mob; -+import net.minecraft.world.entity.ai.attributes.Attributes; -+import net.minecraft.world.entity.player.Input; -+import net.minecraft.world.entity.player.Player; -+import net.minecraft.world.phys.Vec3; -+ -+public class FlyingWithSpacebarMoveControllerWASD extends FlyingMoveControllerWASD { -+ public FlyingWithSpacebarMoveControllerWASD(Mob entity) { -+ super(entity); -+ } -+ -+ public FlyingWithSpacebarMoveControllerWASD(Mob entity, float groundSpeedModifier) { -+ super(entity, groundSpeedModifier); -+ } -+ -+ @Override -+ public void purpurTick(Player rider) { -+ Input lastClientInput = ((ServerPlayer) rider).getLastClientInput(); -+ float forward = (lastClientInput.forward() == lastClientInput.backward() ? 0.0F : lastClientInput.forward() ? 1.0F : -1.0F); -+ float strafe = (lastClientInput.left() == lastClientInput.right() ? 0.0F : lastClientInput.left() ? 1.0F : -1.0F) * 0.5F; -+ float vertical = 0; -+ -+ if (forward < 0.0F) { -+ forward *= 0.5F; -+ strafe *= 0.5F; -+ } -+ -+ float speed = (float) entity.getAttributeValue(Attributes.MOVEMENT_SPEED); -+ -+ if (entity.onGround) { -+ speed *= groundSpeedModifier; -+ } -+ -+ if (lastClientInput.jump() && spacebarEvent(entity) && !entity.onSpacebar()) { -+ entity.setNoGravity(true); -+ vertical = 1.0F; -+ } else { -+ entity.setNoGravity(false); -+ } -+ -+ if (entity.getY() >= entity.getMaxY() || --tooHighCooldown > 0) { -+ if (tooHighCooldown <= 0) { -+ tooHighCooldown = 20; -+ } -+ entity.setDeltaMovement(entity.getDeltaMovement().add(0.0D, -0.2D, 0.0D)); -+ vertical = 0.0F; -+ } -+ -+ setSpeedModifier(speed); -+ entity.setSpeed((float) getSpeedModifier()); -+ entity.setVerticalMot(vertical); -+ entity.setStrafeMot(strafe); -+ entity.setForwardMot(forward); -+ -+ setForward(entity.getForwardMot()); -+ setStrafe(entity.getStrafeMot()); -+ -+ Vec3 mot = entity.getDeltaMovement(); -+ if (mot.y > 0.2D) { -+ entity.setDeltaMovement(mot.x, 0.2D, mot.z); -+ } -+ } -+} -diff --git a/src/main/java/org/purpurmc/purpur/controller/LookControllerWASD.java b/src/main/java/org/purpurmc/purpur/controller/LookControllerWASD.java -new file mode 100644 -index 0000000000000000000000000000000000000000..dd219518150ca90f89ad238904fd4095efe032d8 ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/controller/LookControllerWASD.java -@@ -0,0 +1,79 @@ -+package org.purpurmc.purpur.controller; -+ -+ -+import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.util.Mth; -+import net.minecraft.world.entity.Mob; -+import net.minecraft.world.entity.ai.control.LookControl; -+import net.minecraft.world.entity.player.Player; -+ -+public class LookControllerWASD extends LookControl { -+ protected final Mob entity; -+ private float yOffset = 0; -+ private float xOffset = 0; -+ -+ public LookControllerWASD(Mob entity) { -+ super(entity); -+ this.entity = entity; -+ } -+ -+ // tick -+ @Override -+ public void tick() { -+ if (entity.getRider() != null && entity.isControllable()) { -+ purpurTick(entity.getRider()); -+ } else { -+ vanillaTick(); -+ } -+ } -+ -+ protected void purpurTick(Player rider) { -+ setYawPitch(rider.getYRot(), rider.getXRot()); -+ } -+ -+ public void vanillaTick() { -+ super.tick(); -+ } -+ -+ public void setYawPitch(float yRot, float xRot) { -+ entity.setXRot(normalizePitch(xRot + xOffset)); -+ entity.setYRot(normalizeYaw(yRot + yOffset)); -+ entity.setYHeadRot(entity.getYRot()); -+ entity.xRotO = entity.getXRot(); -+ entity.yRotO = entity.getYRot(); -+ -+ ClientboundMoveEntityPacket.PosRot entityPacket = new ClientboundMoveEntityPacket.PosRot( -+ entity.getId(), -+ (short) 0, (short) 0, (short) 0, -+ (byte) Mth.floor(entity.getYRot() * 256.0F / 360.0F), -+ (byte) Mth.floor(entity.getXRot() * 256.0F / 360.0F), -+ entity.onGround -+ ); -+ ((ServerLevel) entity.level()).getChunkSource().broadcast(entity, entityPacket); -+ } -+ -+ public void setOffsets(float yaw, float pitch) { -+ yOffset = yaw; -+ xOffset = pitch; -+ } -+ -+ public float normalizeYaw(float yaw) { -+ yaw %= 360.0f; -+ if (yaw >= 180.0f) { -+ yaw -= 360.0f; -+ } else if (yaw < -180.0f) { -+ yaw += 360.0f; -+ } -+ return yaw; -+ } -+ -+ public float normalizePitch(float pitch) { -+ if (pitch > 90.0f) { -+ pitch = 90.0f; -+ } else if (pitch < -90.0f) { -+ pitch = -90.0f; -+ } -+ return pitch; -+ } -+} -diff --git a/src/main/java/org/purpurmc/purpur/controller/MoveControllerWASD.java b/src/main/java/org/purpurmc/purpur/controller/MoveControllerWASD.java -new file mode 100644 -index 0000000000000000000000000000000000000000..34f3c43fa16e950326ac5e3d93faee0466ffedc6 ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/controller/MoveControllerWASD.java -@@ -0,0 +1,92 @@ -+package org.purpurmc.purpur.controller; -+ -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.world.entity.Mob; -+import net.minecraft.world.entity.ai.attributes.Attributes; -+import net.minecraft.world.entity.ai.control.MoveControl; -+import net.minecraft.world.entity.player.Input; -+import net.minecraft.world.entity.player.Player; -+import org.purpurmc.purpur.event.entity.RidableSpacebarEvent; -+ -+public class MoveControllerWASD extends MoveControl { -+ protected final Mob entity; -+ private final double speedModifier; -+ -+ public MoveControllerWASD(Mob entity) { -+ this(entity, 1.0D); -+ } -+ -+ public MoveControllerWASD(Mob entity, double speedModifier) { -+ super(entity); -+ this.entity = entity; -+ this.speedModifier = speedModifier; -+ } -+ -+ @Override -+ public boolean hasWanted() { -+ return entity.getRider() != null ? strafeForwards != 0 || strafeRight != 0 : super.hasWanted(); -+ } -+ -+ @Override -+ public void tick() { -+ if (entity.getRider() != null && entity.isControllable()) { -+ purpurTick(entity.getRider()); -+ } else { -+ vanillaTick(); -+ } -+ } -+ -+ public void vanillaTick() { -+ super.tick(); -+ } -+ -+ public void purpurTick(Player rider) { -+ Input lastClientInput = ((ServerPlayer) rider).getLastClientInput(); -+ float forward = (lastClientInput.forward() == lastClientInput.backward() ? 0.0F : lastClientInput.forward() ? 1.0F : -1.0F) * 0.5F; -+ float strafe = (lastClientInput.left() == lastClientInput.right() ? 0.0F : lastClientInput.left() ? 1.0F : -1.0F) * 0.25F; -+ -+ if (forward <= 0.0F) { -+ forward *= 0.5F; -+ } -+ -+ float yawOffset = 0; -+ if (strafe != 0) { -+ if (forward == 0) { -+ yawOffset += strafe > 0 ? -90 : 90; -+ forward = Math.abs(strafe * 2); -+ } else { -+ yawOffset += strafe > 0 ? -30 : 30; -+ strafe /= 2; -+ if (forward < 0) { -+ yawOffset += strafe > 0 ? -110 : 110; -+ forward *= -1; -+ } -+ } -+ } else if (forward < 0) { -+ yawOffset -= 180; -+ forward *= -1; -+ } -+ -+ ((LookControllerWASD) entity.getLookControl()).setOffsets(yawOffset, 0); -+ -+ if (lastClientInput.jump() && spacebarEvent(entity) && !entity.onSpacebar() && entity.onGround) { -+ entity.jumpFromGround(); -+ } -+ -+ setSpeedModifier(entity.getAttributeValue(Attributes.MOVEMENT_SPEED) * speedModifier); -+ -+ entity.setSpeed((float) getSpeedModifier()); -+ entity.setForwardMot(forward); -+ -+ setForward(entity.getForwardMot()); -+ setStrafe(entity.getStrafeMot()); -+ } -+ -+ public static boolean spacebarEvent(Mob entity) { -+ if (RidableSpacebarEvent.getHandlerList().getRegisteredListeners().length > 0) { -+ return new RidableSpacebarEvent(entity.getBukkitEntity()).callEvent(); -+ } else { -+ return true; -+ } -+ } -+} -diff --git a/src/main/java/org/purpurmc/purpur/controller/WaterMoveControllerWASD.java b/src/main/java/org/purpurmc/purpur/controller/WaterMoveControllerWASD.java -new file mode 100644 -index 0000000000000000000000000000000000000000..922e48799c43ca322a8f550c98a26e1e2959439c ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/controller/WaterMoveControllerWASD.java -@@ -0,0 +1,53 @@ -+package org.purpurmc.purpur.controller; -+ -+import net.minecraft.server.level.ServerPlayer; -+import net.minecraft.world.entity.Mob; -+import net.minecraft.world.entity.ai.attributes.Attributes; -+import net.minecraft.world.entity.player.Input; -+import net.minecraft.world.entity.player.Player; -+ -+public class WaterMoveControllerWASD extends MoveControllerWASD { -+ private final double speedModifier; -+ -+ public WaterMoveControllerWASD(Mob entity) { -+ this(entity, 1.0D); -+ } -+ -+ public WaterMoveControllerWASD(Mob entity, double speedModifier) { -+ super(entity); -+ this.speedModifier = speedModifier; -+ } -+ -+ @Override -+ public void purpurTick(Player rider) { -+ Input lastClientInput = ((ServerPlayer) rider).getLastClientInput(); -+ float forward = (lastClientInput.forward() == lastClientInput.backward() ? 0.0F : lastClientInput.forward() ? 1.0F : -1.0F); -+ float strafe = (lastClientInput.left() == lastClientInput.right() ? 0.0F : lastClientInput.left() ? 1.0F : -1.0F) * 0.5F; // strafe slower by default -+ float vertical = -(rider.xRotO / 90); -+ -+ if (forward == 0.0F) { -+ // strafe slower if not moving forward -+ strafe *= 0.5F; -+ // do not move vertically if not moving forward -+ vertical = 0.0F; -+ } else if (forward < 0.0F) { -+ // water animals can't swim backwards -+ forward = 0.0F; -+ vertical = 0.0F; -+ } -+ -+ if (rider.jumping && spacebarEvent(entity)) { -+ entity.onSpacebar(); -+ } -+ -+ setSpeedModifier(entity.getAttributeValue(Attributes.MOVEMENT_SPEED) * speedModifier); -+ entity.setSpeed((float) getSpeedModifier() * 0.1F); -+ -+ entity.setForwardMot(forward * (float) speedModifier); -+ entity.setStrafeMot(strafe * (float) speedModifier); -+ entity.setVerticalMot(vertical * (float) speedModifier); -+ -+ setForward(entity.getForwardMot()); -+ setStrafe(entity.getStrafeMot()); -+ } -+} -diff --git a/src/main/java/org/purpurmc/purpur/entity/DolphinSpit.java b/src/main/java/org/purpurmc/purpur/entity/DolphinSpit.java -new file mode 100644 -index 0000000000000000000000000000000000000000..e33e54fc31ab7dcff054d0ab245d6c3391d06449 ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/entity/DolphinSpit.java -@@ -0,0 +1,101 @@ -+package org.purpurmc.purpur.entity; -+ -+import net.minecraft.core.particles.ParticleTypes; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.util.Mth; -+import net.minecraft.world.damagesource.DamageSource; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.entity.EntityType; -+import net.minecraft.world.entity.LivingEntity; -+import net.minecraft.world.entity.animal.Dolphin; -+import net.minecraft.world.entity.projectile.LlamaSpit; -+import net.minecraft.world.entity.projectile.ProjectileUtil; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.phys.BlockHitResult; -+import net.minecraft.world.phys.EntityHitResult; -+import net.minecraft.world.phys.HitResult; -+import net.minecraft.world.phys.Vec3; -+import org.bukkit.event.entity.EntityRemoveEvent; -+ -+public class DolphinSpit extends LlamaSpit { -+ public LivingEntity dolphin; -+ public int ticksLived; -+ -+ public DolphinSpit(EntityType type, Level world) { -+ super(type, world); -+ } -+ -+ public DolphinSpit(Level world, Dolphin dolphin) { -+ this(EntityType.LLAMA_SPIT, world); -+ setOwner(dolphin.getRider() != null ? dolphin.getRider() : dolphin); -+ this.dolphin = dolphin; -+ this.setPos( -+ dolphin.getX() - (double) (dolphin.getBbWidth() + 1.0F) * 0.5D * (double) Mth.sin(dolphin.yBodyRot * 0.017453292F), -+ dolphin.getEyeY() - 0.10000000149011612D, -+ dolphin.getZ() + (double) (dolphin.getBbWidth() + 1.0F) * 0.5D * (double) Mth.cos(dolphin.yBodyRot * 0.017453292F)); -+ } -+ -+ public void tick() { -+ super_tick(); -+ -+ Vec3 mot = this.getDeltaMovement(); -+ HitResult hitResult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); -+ -+ this.preHitTargetOrDeflectSelf(hitResult); -+ -+ double x = this.getX() + mot.x; -+ double y = this.getY() + mot.y; -+ double z = this.getZ() + mot.z; -+ -+ this.updateRotation(); -+ -+ Vec3 motDouble = mot.scale(2.0); -+ for (int i = 0; i < 5; i++) { -+ ((ServerLevel) level()).sendParticlesSource(null, ParticleTypes.BUBBLE, -+ false, true, -+ getX() + random.nextFloat() / 2 - 0.25F, -+ getY() + random.nextFloat() / 2 - 0.25F, -+ getZ() + random.nextFloat() / 2 - 0.25F, -+ 0, motDouble.x(), motDouble.y(), motDouble.z(), 0.1D); -+ } -+ -+ if (++ticksLived > 20) { -+ this.discard(EntityRemoveEvent.Cause.DISCARD); -+ } else { -+ this.setDeltaMovement(mot.scale(0.99D)); -+ if (!this.isNoGravity()) { -+ this.setDeltaMovement(this.getDeltaMovement().add(0.0D, -0.06D, 0.0D)); -+ } -+ -+ this.setPos(x, y, z); -+ } -+ } -+ -+ @Override -+ public void shoot(double x, double y, double z, float speed, float inaccuracy) { -+ setDeltaMovement(new Vec3(x, y, z).normalize().add( -+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, -+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, -+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy) -+ .scale(speed)); -+ } -+ -+ @Override -+ protected void onHitEntity(EntityHitResult entityHitResult) { -+ Entity shooter = this.getOwner(); -+ if (shooter instanceof LivingEntity) { -+ entityHitResult.getEntity().hurt(entityHitResult.getEntity().damageSources().mobProjectile(this, (LivingEntity) shooter), level().purpurConfig.dolphinSpitDamage); -+ } -+ } -+ -+ @Override -+ protected void onHitBlock(BlockHitResult blockHitResult) { -+ if (this.hitCancelled) { -+ return; -+ } -+ BlockState state = this.level().getBlockState(blockHitResult.getBlockPos()); -+ state.onProjectileHit(this.level(), state, blockHitResult, this); -+ this.discard(EntityRemoveEvent.Cause.DISCARD); -+ } -+} -diff --git a/src/main/java/org/purpurmc/purpur/entity/PhantomFlames.java b/src/main/java/org/purpurmc/purpur/entity/PhantomFlames.java -new file mode 100644 -index 0000000000000000000000000000000000000000..3759e45afe16bf1d8a37b78d3526ee446e63cfe5 ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/entity/PhantomFlames.java -@@ -0,0 +1,123 @@ -+package org.purpurmc.purpur.entity; -+ -+import net.minecraft.core.particles.ParticleTypes; -+import net.minecraft.server.level.ServerLevel; -+import net.minecraft.util.Mth; -+import net.minecraft.world.damagesource.DamageSource; -+import net.minecraft.world.entity.Entity; -+import net.minecraft.world.entity.EntityType; -+import net.minecraft.world.entity.LivingEntity; -+import net.minecraft.world.entity.decoration.ArmorStand; -+import net.minecraft.world.entity.monster.Phantom; -+import net.minecraft.world.entity.projectile.LlamaSpit; -+import net.minecraft.world.entity.projectile.ProjectileUtil; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.block.state.BlockBehaviour; -+import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.phys.BlockHitResult; -+import net.minecraft.world.phys.EntityHitResult; -+import net.minecraft.world.phys.HitResult; -+import net.minecraft.world.phys.Vec3; -+ -+public class PhantomFlames extends LlamaSpit { -+ public Phantom phantom; -+ public int ticksLived; -+ public boolean canGrief = false; -+ -+ public PhantomFlames(EntityType type, Level world) { -+ super(type, world); -+ } -+ -+ public PhantomFlames(Level world, Phantom phantom) { -+ this(EntityType.LLAMA_SPIT, world); -+ setOwner(phantom.getRider() != null ? phantom.getRider() : phantom); -+ this.phantom = phantom; -+ this.setPos( -+ phantom.getX() - (double) (phantom.getBbWidth() + 1.0F) * 0.5D * (double) Mth.sin(phantom.yBodyRot * 0.017453292F), -+ phantom.getEyeY() - 0.10000000149011612D, -+ phantom.getZ() + (double) (phantom.getBbWidth() + 1.0F) * 0.5D * (double) Mth.cos(phantom.yBodyRot * 0.017453292F)); -+ } -+ -+ public void tick() { -+ super_tick(); -+ -+ Vec3 mot = this.getDeltaMovement(); -+ HitResult hitResult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); -+ -+ this.preHitTargetOrDeflectSelf(hitResult); -+ -+ double x = this.getX() + mot.x; -+ double y = this.getY() + mot.y; -+ double z = this.getZ() + mot.z; -+ -+ this.updateRotation(); -+ -+ Vec3 motDouble = mot.scale(2.0); -+ for (int i = 0; i < 5; i++) { -+ ((ServerLevel) level()).sendParticlesSource(null, ParticleTypes.FLAME, -+ false, true, -+ getX() + random.nextFloat() / 2 - 0.25F, -+ getY() + random.nextFloat() / 2 - 0.25F, -+ getZ() + random.nextFloat() / 2 - 0.25F, -+ 0, motDouble.x(), motDouble.y(), motDouble.z(), 0.1D); -+ } -+ -+ if (++ticksLived > 20) { -+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); -+ } else if (this.level().getBlockStates(this.getBoundingBox()).noneMatch(BlockBehaviour.BlockStateBase::isAir)) { -+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); -+ } else if (this.isInWaterOrBubble()) { -+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); -+ } else { -+ this.setDeltaMovement(mot.scale(0.99D)); -+ if (!this.isNoGravity()) { -+ this.setDeltaMovement(this.getDeltaMovement().add(0.0D, -0.06D, 0.0D)); -+ } -+ -+ this.setPos(x, y, z); -+ } -+ } -+ -+ @Override -+ public void shoot(double x, double y, double z, float speed, float inaccuracy) { -+ setDeltaMovement(new Vec3(x, y, z).normalize().add( -+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, -+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, -+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy) -+ .scale(speed)); -+ } -+ -+ @Override -+ protected void onHitEntity(EntityHitResult entityHitResult) { -+ Level world = this.level(); -+ -+ if (world instanceof ServerLevel worldserver) { -+ Entity shooter = this.getOwner(); -+ if (shooter instanceof LivingEntity) { -+ Entity target = entityHitResult.getEntity(); -+ if (canGrief || (target instanceof LivingEntity && !(target instanceof ArmorStand))) { -+ boolean hurt = target.hurtServer(worldserver, target.damageSources().mobProjectile(this, (LivingEntity) shooter), worldserver.purpurConfig.phantomFlameDamage); -+ if (hurt && worldserver.purpurConfig.phantomFlameFireTime > 0) { -+ target.igniteForSeconds(worldserver.purpurConfig.phantomFlameFireTime); -+ } -+ } -+ } -+ } -+ } -+ -+ @Override -+ protected void onHitBlock(BlockHitResult blockHitResult) { -+ Level world = this.level(); -+ -+ if (world instanceof ServerLevel worldserver) { -+ if (this.hitCancelled) { -+ return; -+ } -+ if (this.canGrief) { -+ BlockState state = worldserver.getBlockState(blockHitResult.getBlockPos()); -+ state.onProjectileHit(worldserver, state, blockHitResult, this); -+ } -+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); -+ } -+ } -+} -diff --git a/src/main/java/org/purpurmc/purpur/entity/ai/HasRider.java b/src/main/java/org/purpurmc/purpur/entity/ai/HasRider.java -new file mode 100644 -index 0000000000000000000000000000000000000000..8babdaddd8b33278aea0369dbbeeb445abe45016 ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/entity/ai/HasRider.java -@@ -0,0 +1,20 @@ -+package org.purpurmc.purpur.entity.ai; -+ -+import net.minecraft.world.entity.Mob; -+import net.minecraft.world.entity.ai.goal.Goal; -+ -+import java.util.EnumSet; -+ -+public class HasRider extends Goal { -+ public final Mob entity; -+ -+ public HasRider(Mob entity) { -+ this.entity = entity; -+ setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK, Flag.TARGET, Flag.UNKNOWN_BEHAVIOR)); -+ } -+ -+ @Override -+ public boolean canUse() { -+ return entity.getRider() != null && entity.isControllable(); -+ } -+} -diff --git a/src/main/java/org/purpurmc/purpur/entity/ai/HorseHasRider.java b/src/main/java/org/purpurmc/purpur/entity/ai/HorseHasRider.java -new file mode 100644 -index 0000000000000000000000000000000000000000..432f4f3d82af2f19820890b68d33189a9f2c69f9 ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/entity/ai/HorseHasRider.java -@@ -0,0 +1,17 @@ -+package org.purpurmc.purpur.entity.ai; -+ -+import net.minecraft.world.entity.animal.horse.AbstractHorse; -+ -+public class HorseHasRider extends HasRider { -+ public final AbstractHorse horse; -+ -+ public HorseHasRider(AbstractHorse entity) { -+ super(entity); -+ this.horse = entity; -+ } -+ -+ @Override -+ public boolean canUse() { -+ return super.canUse() && horse.isSaddled(); -+ } -+} -diff --git a/src/main/java/org/purpurmc/purpur/entity/ai/LlamaHasRider.java b/src/main/java/org/purpurmc/purpur/entity/ai/LlamaHasRider.java -new file mode 100644 -index 0000000000000000000000000000000000000000..18a95e043cbffa65eeaaf65ff7695e5dc939820c ---- /dev/null -+++ b/src/main/java/org/purpurmc/purpur/entity/ai/LlamaHasRider.java -@@ -0,0 +1,17 @@ -+package org.purpurmc.purpur.entity.ai; -+ -+import net.minecraft.world.entity.animal.horse.Llama; -+ -+public class LlamaHasRider extends HasRider { -+ public final Llama llama; -+ -+ public LlamaHasRider(Llama entity) { -+ super(entity); -+ this.llama = entity; -+ } -+ -+ @Override -+ public boolean canUse() { -+ return super.canUse() && llama.isSaddled() && llama.isControllable(); -+ } -+} + builder.define(DATA_DANGEROUS, false); diff --git a/purpur-server/minecraft-patches/sources/net/minecraft/core/BlockPos.java.patch b/purpur-server/minecraft-patches/sources/net/minecraft/core/BlockPos.java.patch new file mode 100644 index 000000000..8b669b1d6 --- /dev/null +++ b/purpur-server/minecraft-patches/sources/net/minecraft/core/BlockPos.java.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/core/BlockPos.java ++++ b/net/minecraft/core/BlockPos.java +@@ -63,6 +_,12 @@ + public static final int MAX_HORIZONTAL_COORDINATE = 33554431; + // Paper end - Optimize Bit Operations by inlining + ++ // Purpur start - Ridables ++ public BlockPos(net.minecraft.world.entity.Entity entity) { ++ super(entity.getBlockX(), entity.getBlockY(), entity.getBlockZ()); ++ } ++ // Purpur end - Ridables ++ + public BlockPos(int x, int y, int z) { + super(x, y, z); + } diff --git a/purpur-server/paper-patches/features/0002-Ridables.patch b/purpur-server/paper-patches/features/0002-Ridables.patch new file mode 100644 index 000000000..d8d965323 --- /dev/null +++ b/purpur-server/paper-patches/features/0002-Ridables.patch @@ -0,0 +1,66 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: William Blake Galbreath +Date: Sun, 5 Jul 2020 22:19:49 -0500 +Subject: [PATCH] Ridables + + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +index 91b78711ec06f51e3bc25109129cc164a98bcf87..0d69e89c1ade115b868cb13f08f75cf256734d88 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +@@ -1306,4 +1306,27 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { + } + } + // Paper end - broadcast hurt animation ++ ++ // Purpur start - Ridables ++ @Override ++ public org.bukkit.entity.Player getRider() { ++ net.minecraft.world.entity.player.Player rider = getHandle().getRider(); ++ return rider != null ? (org.bukkit.entity.Player) rider.getBukkitEntity() : null; ++ } ++ ++ @Override ++ public boolean hasRider() { ++ return getHandle().getRider() != null; ++ } ++ ++ @Override ++ public boolean isRidable() { ++ return getHandle().isRidable(); ++ } ++ ++ @Override ++ public boolean isRidableInWater() { ++ return !getHandle().dismountsUnderwater(); ++ } ++ // Purpur end - Ridables + } +diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +index e37aaf77f94b97b736cc20ef070cefdff0400188..eb2f9bfdaf3ed8a684337a15365e70174d1533b3 100644 +--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java ++++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +@@ -602,6 +602,15 @@ public class CraftEventFactory { + // Paper end + craftServer.getPluginManager().callEvent(event); + ++ // Purpur start - Ridables ++ if (who != null) { ++ switch (action) { ++ case LEFT_CLICK_BLOCK, LEFT_CLICK_AIR -> who.processClick(InteractionHand.MAIN_HAND); ++ case RIGHT_CLICK_BLOCK, RIGHT_CLICK_AIR -> who.processClick(InteractionHand.OFF_HAND); ++ } ++ } ++ // Purpur end - Ridables ++ + return event; + } + +@@ -1191,6 +1200,7 @@ public class CraftEventFactory { + EntityDamageEvent event; + if (damager != null) { + event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions, critical); ++ damager.processClick(InteractionHand.MAIN_HAND); // Purpur - Ridables + } else { + event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, bukkitDamageSource, modifiers, modifierFunctions); + } diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java index e395eccc4..2cec1edf5 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurConfig.java @@ -155,4 +155,9 @@ public class PurpurConfig { } return builder.build(); } + + public static String cannotRideMob = "You cannot mount that mob"; + private static void messages() { + cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob); + } } diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java index a370bbb69..74e1d7474 100644 --- a/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java +++ b/purpur-server/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java @@ -67,4 +67,753 @@ public class PurpurWorldConfig { final Map value = PurpurConfig.getMap("world-settings." + worldName + "." + path, null); return value.isEmpty() ? fallback : value; } + + public boolean babiesAreRidable = true; + public boolean untamedTamablesAreRidable = true; + public boolean useNightVisionWhenRiding = false; + public boolean useDismountsUnderwaterTag = true; + private void ridableSettings() { + babiesAreRidable = getBoolean("ridable-settings.babies-are-ridable", babiesAreRidable); + untamedTamablesAreRidable = getBoolean("ridable-settings.untamed-tamables-are-ridable", untamedTamablesAreRidable); + useNightVisionWhenRiding = getBoolean("ridable-settings.use-night-vision", useNightVisionWhenRiding); + useDismountsUnderwaterTag = getBoolean("ridable-settings.use-dismounts-underwater-tag", useDismountsUnderwaterTag); + } + + public boolean allayRidable = false; + public boolean allayRidableInWater = true; + public boolean allayControllable = true; + private void allaySettings() { + allayRidable = getBoolean("mobs.allay.ridable", allayRidable); + allayRidableInWater = getBoolean("mobs.allay.ridable-in-water", allayRidableInWater); + allayControllable = getBoolean("mobs.allay.controllable", allayControllable); + } + + public boolean armadilloRidable = false; + public boolean armadilloRidableInWater = true; + public boolean armadilloControllable = true; + private void armadilloSettings() { + armadilloRidable = getBoolean("mobs.armadillo.ridable", armadilloRidable); + armadilloRidableInWater = getBoolean("mobs.armadillo.ridable-in-water", armadilloRidableInWater); + armadilloControllable = getBoolean("mobs.armadillo.controllable", armadilloControllable); + } + + public boolean axolotlRidable = false; + public boolean axolotlControllable = true; + private void axolotlSettings() { + axolotlRidable = getBoolean("mobs.axolotl.ridable", axolotlRidable); + axolotlControllable = getBoolean("mobs.axolotl.controllable", axolotlControllable); + } + + public boolean batRidable = false; + public boolean batRidableInWater = true; + public boolean batControllable = true; + public double batMaxY = 320D; + private void batSettings() { + batRidable = getBoolean("mobs.bat.ridable", batRidable); + batRidableInWater = getBoolean("mobs.bat.ridable-in-water", batRidableInWater); + batControllable = getBoolean("mobs.bat.controllable", batControllable); + batMaxY = getDouble("mobs.bat.ridable-max-y", batMaxY); + } + + public boolean beeRidable = false; + public boolean beeRidableInWater = true; + public boolean beeControllable = true; + public double beeMaxY = 320D; + private void beeSettings() { + beeRidable = getBoolean("mobs.bee.ridable", beeRidable); + beeRidableInWater = getBoolean("mobs.bee.ridable-in-water", beeRidableInWater); + beeControllable = getBoolean("mobs.bee.controllable", beeControllable); + beeMaxY = getDouble("mobs.bee.ridable-max-y", beeMaxY); + } + + public boolean blazeRidable = false; + public boolean blazeRidableInWater = true; + public boolean blazeControllable = true; + public double blazeMaxY = 320D; + private void blazeSettings() { + blazeRidable = getBoolean("mobs.blaze.ridable", blazeRidable); + blazeRidableInWater = getBoolean("mobs.blaze.ridable-in-water", blazeRidableInWater); + blazeControllable = getBoolean("mobs.blaze.controllable", blazeControllable); + blazeMaxY = getDouble("mobs.blaze.ridable-max-y", blazeMaxY); + } + + public boolean boggedRidable = false; + public boolean boggedRidableInWater = true; + public boolean boggedControllable = true; + private void boggedSettings() { + boggedRidable = getBoolean("mobs.bogged.ridable", boggedRidable); + boggedRidableInWater = getBoolean("mobs.bogged.ridable-in-water", boggedRidableInWater); + boggedControllable = getBoolean("mobs.bogged.controllable", boggedControllable); + } + + public boolean camelRidableInWater = false; + private void camelSettings() { + camelRidableInWater = getBoolean("mobs.camel.ridable-in-water", camelRidableInWater); + } + + public boolean catRidable = false; + public boolean catRidableInWater = true; + public boolean catControllable = true; + private void catSettings() { + catRidable = getBoolean("mobs.cat.ridable", catRidable); + catRidableInWater = getBoolean("mobs.cat.ridable-in-water", catRidableInWater); + catControllable = getBoolean("mobs.cat.controllable", catControllable); + } + + public boolean caveSpiderRidable = false; + public boolean caveSpiderRidableInWater = true; + public boolean caveSpiderControllable = true; + private void caveSpiderSettings() { + caveSpiderRidable = getBoolean("mobs.cave_spider.ridable", caveSpiderRidable); + caveSpiderRidableInWater = getBoolean("mobs.cave_spider.ridable-in-water", caveSpiderRidableInWater); + caveSpiderControllable = getBoolean("mobs.cave_spider.controllable", caveSpiderControllable); + } + + public boolean chickenRidable = false; + public boolean chickenRidableInWater = false; + public boolean chickenControllable = true; + private void chickenSettings() { + chickenRidable = getBoolean("mobs.chicken.ridable", chickenRidable); + chickenRidableInWater = getBoolean("mobs.chicken.ridable-in-water", chickenRidableInWater); + chickenControllable = getBoolean("mobs.chicken.controllable", chickenControllable); + } + + public boolean codRidable = false; + public boolean codControllable = true; + private void codSettings() { + codRidable = getBoolean("mobs.cod.ridable", codRidable); + codControllable = getBoolean("mobs.cod.controllable", codControllable); + } + + public boolean cowRidable = false; + public boolean cowRidableInWater = true; + public boolean cowControllable = true; + private void cowSettings() { + cowRidable = getBoolean("mobs.cow.ridable", cowRidable); + cowRidableInWater = getBoolean("mobs.cow.ridable-in-water", cowRidableInWater); + cowControllable = getBoolean("mobs.cow.controllable", cowControllable); + } + + public boolean creakingRidable = false; + public boolean creakingRidableInWater = true; + public boolean creakingControllable = true; + private void creakingSettings() { + creakingRidable = getBoolean("mobs.creaking.ridable", creakingRidable); + creakingRidableInWater = getBoolean("mobs.creaking.ridable-in-water", creakingRidableInWater); + creakingControllable = getBoolean("mobs.creaking.controllable", creakingControllable); + } + + public boolean creeperRidable = false; + public boolean creeperRidableInWater = true; + public boolean creeperControllable = true; + private void creeperSettings() { + creeperRidable = getBoolean("mobs.creeper.ridable", creeperRidable); + creeperRidableInWater = getBoolean("mobs.creeper.ridable-in-water", creeperRidableInWater); + creeperControllable = getBoolean("mobs.creeper.controllable", creeperControllable); + } + + public boolean dolphinRidable = false; + public boolean dolphinControllable = true; + public int dolphinSpitCooldown = 20; + public float dolphinSpitSpeed = 1.0F; + public float dolphinSpitDamage = 2.0F; + private void dolphinSettings() { + dolphinRidable = getBoolean("mobs.dolphin.ridable", dolphinRidable); + dolphinControllable = getBoolean("mobs.dolphin.controllable", dolphinControllable); + dolphinSpitCooldown = getInt("mobs.dolphin.spit.cooldown", dolphinSpitCooldown); + dolphinSpitSpeed = (float) getDouble("mobs.dolphin.spit.speed", dolphinSpitSpeed); + dolphinSpitDamage = (float) getDouble("mobs.dolphin.spit.damage", dolphinSpitDamage); + } + + public boolean donkeyRidableInWater = false; + private void donkeySettings() { + donkeyRidableInWater = getBoolean("mobs.donkey.ridable-in-water", donkeyRidableInWater); + } + + public boolean drownedRidable = false; + public boolean drownedRidableInWater = true; + public boolean drownedControllable = true; + private void drownedSettings() { + drownedRidable = getBoolean("mobs.drowned.ridable", drownedRidable); + drownedRidableInWater = getBoolean("mobs.drowned.ridable-in-water", drownedRidableInWater); + drownedControllable = getBoolean("mobs.drowned.controllable", drownedControllable); + } + + public boolean elderGuardianRidable = false; + public boolean elderGuardianControllable = true; + private void elderGuardianSettings() { + elderGuardianRidable = getBoolean("mobs.elder_guardian.ridable", elderGuardianRidable); + elderGuardianControllable = getBoolean("mobs.elder_guardian.controllable", elderGuardianControllable); + } + + public boolean enderDragonRidable = false; + public boolean enderDragonRidableInWater = true; + public boolean enderDragonControllable = true; + public double enderDragonMaxY = 320D; + private void enderDragonSettings() { + enderDragonRidable = getBoolean("mobs.ender_dragon.ridable", enderDragonRidable); + enderDragonRidableInWater = getBoolean("mobs.ender_dragon.ridable-in-water", enderDragonRidableInWater); + enderDragonControllable = getBoolean("mobs.ender_dragon.controllable", enderDragonControllable); + enderDragonMaxY = getDouble("mobs.ender_dragon.ridable-max-y", enderDragonMaxY); + } + + public boolean endermanRidable = false; + public boolean endermanRidableInWater = true; + public boolean endermanControllable = true; + private void endermanSettings() { + endermanRidable = getBoolean("mobs.enderman.ridable", endermanRidable); + endermanRidableInWater = getBoolean("mobs.enderman.ridable-in-water", endermanRidableInWater); + endermanControllable = getBoolean("mobs.enderman.controllable", endermanControllable); + } + + public boolean endermiteRidable = false; + public boolean endermiteRidableInWater = true; + public boolean endermiteControllable = true; + private void endermiteSettings() { + endermiteRidable = getBoolean("mobs.endermite.ridable", endermiteRidable); + endermiteRidableInWater = getBoolean("mobs.endermite.ridable-in-water", endermiteRidableInWater); + endermiteControllable = getBoolean("mobs.endermite.controllable", endermiteControllable); + } + + public boolean evokerRidable = false; + public boolean evokerRidableInWater = true; + public boolean evokerControllable = true; + private void evokerSettings() { + evokerRidable = getBoolean("mobs.evoker.ridable", evokerRidable); + evokerRidableInWater = getBoolean("mobs.evoker.ridable-in-water", evokerRidableInWater); + evokerControllable = getBoolean("mobs.evoker.controllable", evokerControllable); + } + + public boolean foxRidable = false; + public boolean foxRidableInWater = true; + public boolean foxControllable = true; + private void foxSettings() { + foxRidable = getBoolean("mobs.fox.ridable", foxRidable); + foxRidableInWater = getBoolean("mobs.fox.ridable-in-water", foxRidableInWater); + foxControllable = getBoolean("mobs.fox.controllable", foxControllable); + } + + public boolean frogRidable = false; + public boolean frogRidableInWater = true; + public boolean frogControllable = true; + public float frogRidableJumpHeight = 0.65F; + private void frogSettings() { + frogRidable = getBoolean("mobs.frog.ridable", frogRidable); + frogRidableInWater = getBoolean("mobs.frog.ridable-in-water", frogRidableInWater); + frogControllable = getBoolean("mobs.frog.controllable", frogControllable); + frogRidableJumpHeight = (float) getDouble("mobs.frog.ridable-jump-height", frogRidableJumpHeight); + } + + public boolean ghastRidable = false; + public boolean ghastRidableInWater = true; + public boolean ghastControllable = true; + public double ghastMaxY = 320D; + private void ghastSettings() { + ghastRidable = getBoolean("mobs.ghast.ridable", ghastRidable); + ghastRidableInWater = getBoolean("mobs.ghast.ridable-in-water", ghastRidableInWater); + ghastControllable = getBoolean("mobs.ghast.controllable", ghastControllable); + ghastMaxY = getDouble("mobs.ghast.ridable-max-y", ghastMaxY); + } + + public boolean giantRidable = false; + public boolean giantRidableInWater = true; + public boolean giantControllable = true; + private void giantSettings() { + giantRidable = getBoolean("mobs.giant.ridable", giantRidable); + giantRidableInWater = getBoolean("mobs.giant.ridable-in-water", giantRidableInWater); + giantControllable = getBoolean("mobs.giant.controllable", giantControllable); + } + + public boolean glowSquidRidable = false; + public boolean glowSquidControllable = true; + private void glowSquidSettings() { + glowSquidRidable = getBoolean("mobs.glow_squid.ridable", glowSquidRidable); + glowSquidControllable = getBoolean("mobs.glow_squid.controllable", glowSquidControllable); + } + + public boolean goatRidable = false; + public boolean goatRidableInWater = true; + public boolean goatControllable = true; + private void goatSettings() { + goatRidable = getBoolean("mobs.goat.ridable", goatRidable); + goatRidableInWater = getBoolean("mobs.goat.ridable-in-water", goatRidableInWater); + goatControllable = getBoolean("mobs.goat.controllable", goatControllable); + } + + public boolean guardianRidable = false; + public boolean guardianControllable = true; + private void guardianSettings() { + guardianRidable = getBoolean("mobs.guardian.ridable", guardianRidable); + guardianControllable = getBoolean("mobs.guardian.controllable", guardianControllable); + } + + public boolean hoglinRidable = false; + public boolean hoglinRidableInWater = true; + public boolean hoglinControllable = true; + private void hoglinSettings() { + hoglinRidable = getBoolean("mobs.hoglin.ridable", hoglinRidable); + hoglinRidableInWater = getBoolean("mobs.hoglin.ridable-in-water", hoglinRidableInWater); + hoglinControllable = getBoolean("mobs.hoglin.controllable", hoglinControllable); + } + + public boolean horseRidableInWater = false; + private void horseSettings() { + horseRidableInWater = getBoolean("mobs.horse.ridable-in-water", horseRidableInWater); + } + + public boolean huskRidable = false; + public boolean huskRidableInWater = true; + public boolean huskControllable = true; + private void huskSettings() { + huskRidable = getBoolean("mobs.husk.ridable", huskRidable); + huskRidableInWater = getBoolean("mobs.husk.ridable-in-water", huskRidableInWater); + huskControllable = getBoolean("mobs.husk.controllable", huskControllable); + } + + public boolean illusionerRidable = false; + public boolean illusionerRidableInWater = true; + public boolean illusionerControllable = true; + private void illusionerSettings() { + illusionerRidable = getBoolean("mobs.illusioner.ridable", illusionerRidable); + illusionerRidableInWater = getBoolean("mobs.illusioner.ridable-in-water", illusionerRidableInWater); + illusionerControllable = getBoolean("mobs.illusioner.controllable", illusionerControllable); + } + + public boolean ironGolemRidable = false; + public boolean ironGolemRidableInWater = true; + public boolean ironGolemControllable = true; + public boolean ironGolemCanSwim = false; + private void ironGolemSettings() { + ironGolemRidable = getBoolean("mobs.iron_golem.ridable", ironGolemRidable); + ironGolemRidableInWater = getBoolean("mobs.iron_golem.ridable-in-water", ironGolemRidableInWater); + ironGolemControllable = getBoolean("mobs.iron_golem.controllable", ironGolemControllable); + ironGolemCanSwim = getBoolean("mobs.iron_golem.can-swim", ironGolemCanSwim); + } + + public boolean llamaRidable = false; + public boolean llamaRidableInWater = false; + public boolean llamaControllable = true; + private void llamaSettings() { + llamaRidable = getBoolean("mobs.llama.ridable", llamaRidable); + llamaRidableInWater = getBoolean("mobs.llama.ridable-in-water", llamaRidableInWater); + llamaControllable = getBoolean("mobs.llama.controllable", llamaControllable); + } + + public boolean magmaCubeRidable = false; + public boolean magmaCubeRidableInWater = true; + public boolean magmaCubeControllable = true; + private void magmaCubeSettings() { + magmaCubeRidable = getBoolean("mobs.magma_cube.ridable", magmaCubeRidable); + magmaCubeRidableInWater = getBoolean("mobs.magma_cube.ridable-in-water", magmaCubeRidableInWater); + magmaCubeControllable = getBoolean("mobs.magma_cube.controllable", magmaCubeControllable); + } + + public boolean mooshroomRidable = false; + public boolean mooshroomRidableInWater = true; + public boolean mooshroomControllable = true; + private void mooshroomSettings() { + mooshroomRidable = getBoolean("mobs.mooshroom.ridable", mooshroomRidable); + mooshroomRidableInWater = getBoolean("mobs.mooshroom.ridable-in-water", mooshroomRidableInWater); + mooshroomControllable = getBoolean("mobs.mooshroom.controllable", mooshroomControllable); + } + + public boolean muleRidableInWater = false; + private void muleSettings() { + muleRidableInWater = getBoolean("mobs.mule.ridable-in-water", muleRidableInWater); + } + + public boolean ocelotRidable = false; + public boolean ocelotRidableInWater = true; + public boolean ocelotControllable = true; + private void ocelotSettings() { + ocelotRidable = getBoolean("mobs.ocelot.ridable", ocelotRidable); + ocelotRidableInWater = getBoolean("mobs.ocelot.ridable-in-water", ocelotRidableInWater); + ocelotControllable = getBoolean("mobs.ocelot.controllable", ocelotControllable); + } + + public boolean pandaRidable = false; + public boolean pandaRidableInWater = true; + public boolean pandaControllable = true; + private void pandaSettings() { + pandaRidable = getBoolean("mobs.panda.ridable", pandaRidable); + pandaRidableInWater = getBoolean("mobs.panda.ridable-in-water", pandaRidableInWater); + pandaControllable = getBoolean("mobs.panda.controllable", pandaControllable); + } + + public boolean parrotRidable = false; + public boolean parrotRidableInWater = true; + public boolean parrotControllable = true; + public double parrotMaxY = 320D; + private void parrotSettings() { + parrotRidable = getBoolean("mobs.parrot.ridable", parrotRidable); + parrotRidableInWater = getBoolean("mobs.parrot.ridable-in-water", parrotRidableInWater); + parrotControllable = getBoolean("mobs.parrot.controllable", parrotControllable); + parrotMaxY = getDouble("mobs.parrot.ridable-max-y", parrotMaxY); + } + + public boolean phantomRidable = false; + public boolean phantomRidableInWater = true; + public boolean phantomControllable = true; + public double phantomMaxY = 320D; + public float phantomFlameDamage = 1.0F; + public int phantomFlameFireTime = 8; + public boolean phantomAllowGriefing = false; + private void phantomSettings() { + phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable); + phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater); + phantomControllable = getBoolean("mobs.phantom.controllable", phantomControllable); + phantomMaxY = getDouble("mobs.phantom.ridable-max-y", phantomMaxY); + phantomFlameDamage = (float) getDouble("mobs.phantom.flames.damage", phantomFlameDamage); + phantomFlameFireTime = getInt("mobs.phantom.flames.fire-time", phantomFlameFireTime); + phantomAllowGriefing = getBoolean("mobs.phantom.allow-griefing", phantomAllowGriefing); + } + + public boolean pigRidable = false; + public boolean pigRidableInWater = false; + public boolean pigControllable = true; + private void pigSettings() { + pigRidable = getBoolean("mobs.pig.ridable", pigRidable); + pigRidableInWater = getBoolean("mobs.pig.ridable-in-water", pigRidableInWater); + pigControllable = getBoolean("mobs.pig.controllable", pigControllable); + } + + public boolean piglinRidable = false; + public boolean piglinRidableInWater = true; + public boolean piglinControllable = true; + private void piglinSettings() { + piglinRidable = getBoolean("mobs.piglin.ridable", piglinRidable); + piglinRidableInWater = getBoolean("mobs.piglin.ridable-in-water", piglinRidableInWater); + piglinControllable = getBoolean("mobs.piglin.controllable", piglinControllable); + } + + public boolean piglinBruteRidable = false; + public boolean piglinBruteRidableInWater = true; + public boolean piglinBruteControllable = true; + private void piglinBruteSettings() { + piglinBruteRidable = getBoolean("mobs.piglin_brute.ridable", piglinBruteRidable); + piglinBruteRidableInWater = getBoolean("mobs.piglin_brute.ridable-in-water", piglinBruteRidableInWater); + piglinBruteControllable = getBoolean("mobs.piglin_brute.controllable", piglinBruteControllable); + } + + public boolean pillagerRidable = false; + public boolean pillagerRidableInWater = true; + public boolean pillagerControllable = true; + private void pillagerSettings() { + pillagerRidable = getBoolean("mobs.pillager.ridable", pillagerRidable); + pillagerRidableInWater = getBoolean("mobs.pillager.ridable-in-water", pillagerRidableInWater); + pillagerControllable = getBoolean("mobs.pillager.controllable", pillagerControllable); + } + + public boolean polarBearRidable = false; + public boolean polarBearRidableInWater = true; + public boolean polarBearControllable = true; + private void polarBearSettings() { + polarBearRidable = getBoolean("mobs.polar_bear.ridable", polarBearRidable); + polarBearRidableInWater = getBoolean("mobs.polar_bear.ridable-in-water", polarBearRidableInWater); + polarBearControllable = getBoolean("mobs.polar_bear.controllable", polarBearControllable); + } + + public boolean pufferfishRidable = false; + public boolean pufferfishControllable = true; + private void pufferfishSettings() { + pufferfishRidable = getBoolean("mobs.pufferfish.ridable", pufferfishRidable); + pufferfishControllable = getBoolean("mobs.pufferfish.controllable", pufferfishControllable); + } + + public boolean rabbitRidable = false; + public boolean rabbitRidableInWater = true; + public boolean rabbitControllable = true; + private void rabbitSettings() { + rabbitRidable = getBoolean("mobs.rabbit.ridable", rabbitRidable); + rabbitRidableInWater = getBoolean("mobs.rabbit.ridable-in-water", rabbitRidableInWater); + rabbitControllable = getBoolean("mobs.rabbit.controllable", rabbitControllable); + } + + public boolean ravagerRidable = false; + public boolean ravagerRidableInWater = false; + public boolean ravagerControllable = true; + private void ravagerSettings() { + ravagerRidable = getBoolean("mobs.ravager.ridable", ravagerRidable); + ravagerRidableInWater = getBoolean("mobs.ravager.ridable-in-water", ravagerRidableInWater); + ravagerControllable = getBoolean("mobs.ravager.controllable", ravagerControllable); + } + + public boolean salmonRidable = false; + public boolean salmonControllable = true; + private void salmonSettings() { + salmonRidable = getBoolean("mobs.salmon.ridable", salmonRidable); + salmonControllable = getBoolean("mobs.salmon.controllable", salmonControllable); + } + + public boolean sheepRidable = false; + public boolean sheepRidableInWater = true; + public boolean sheepControllable = true; + private void sheepSettings() { + sheepRidable = getBoolean("mobs.sheep.ridable", sheepRidable); + sheepRidableInWater = getBoolean("mobs.sheep.ridable-in-water", sheepRidableInWater); + sheepControllable = getBoolean("mobs.sheep.controllable", sheepControllable); + } + + public boolean shulkerRidable = false; + public boolean shulkerRidableInWater = true; + public boolean shulkerControllable = true; + private void shulkerSettings() { + shulkerRidable = getBoolean("mobs.shulker.ridable", shulkerRidable); + shulkerRidableInWater = getBoolean("mobs.shulker.ridable-in-water", shulkerRidableInWater); + shulkerControllable = getBoolean("mobs.shulker.controllable", shulkerControllable); + } + + public boolean silverfishRidable = false; + public boolean silverfishRidableInWater = true; + public boolean silverfishControllable = true; + private void silverfishSettings() { + silverfishRidable = getBoolean("mobs.silverfish.ridable", silverfishRidable); + silverfishRidableInWater = getBoolean("mobs.silverfish.ridable-in-water", silverfishRidableInWater); + silverfishControllable = getBoolean("mobs.silverfish.controllable", silverfishControllable); + } + + public boolean skeletonRidable = false; + public boolean skeletonRidableInWater = true; + public boolean skeletonControllable = true; + private void skeletonSettings() { + skeletonRidable = getBoolean("mobs.skeleton.ridable", skeletonRidable); + skeletonRidableInWater = getBoolean("mobs.skeleton.ridable-in-water", skeletonRidableInWater); + skeletonControllable = getBoolean("mobs.skeleton.controllable", skeletonControllable); + } + + public boolean skeletonHorseRidable = false; + public boolean skeletonHorseRidableInWater = true; + public boolean skeletonHorseCanSwim = false; + private void skeletonHorseSettings() { + skeletonHorseRidable = getBoolean("mobs.skeleton_horse.ridable", skeletonHorseRidable); + skeletonHorseRidableInWater = getBoolean("mobs.skeleton_horse.ridable-in-water", skeletonHorseRidableInWater); + skeletonHorseCanSwim = getBoolean("mobs.skeleton_horse.can-swim", skeletonHorseCanSwim); + } + + public boolean slimeRidable = false; + public boolean slimeRidableInWater = true; + public boolean slimeControllable = true; + private void slimeSettings() { + slimeRidable = getBoolean("mobs.slime.ridable", slimeRidable); + slimeRidableInWater = getBoolean("mobs.slime.ridable-in-water", slimeRidableInWater); + slimeControllable = getBoolean("mobs.slime.controllable", slimeControllable); + } + + public boolean snowGolemRidable = false; + public boolean snowGolemRidableInWater = true; + public boolean snowGolemControllable = true; + public boolean snowGolemLeaveTrailWhenRidden = false; + private void snowGolemSettings() { + snowGolemRidable = getBoolean("mobs.snow_golem.ridable", snowGolemRidable); + snowGolemRidableInWater = getBoolean("mobs.snow_golem.ridable-in-water", snowGolemRidableInWater); + snowGolemControllable = getBoolean("mobs.snow_golem.controllable", snowGolemControllable); + snowGolemLeaveTrailWhenRidden = getBoolean("mobs.snow_golem.leave-trail-when-ridden", snowGolemLeaveTrailWhenRidden); + } + + public boolean snifferRidable = false; + public boolean snifferRidableInWater = true; + public boolean snifferControllable = true; + private void snifferSettings() { + snifferRidable = getBoolean("mobs.sniffer.ridable", snifferRidable); + snifferRidableInWater = getBoolean("mobs.sniffer.ridable-in-water", snifferRidableInWater); + snifferControllable = getBoolean("mobs.sniffer.controllable", snifferControllable); + } + + public boolean squidRidable = false; + public boolean squidControllable = true; + private void squidSettings() { + squidRidable = getBoolean("mobs.squid.ridable", squidRidable); + squidControllable = getBoolean("mobs.squid.controllable", squidControllable); + } + + public boolean spiderRidable = false; + public boolean spiderRidableInWater = false; + public boolean spiderControllable = true; + private void spiderSettings() { + spiderRidable = getBoolean("mobs.spider.ridable", spiderRidable); + spiderRidableInWater = getBoolean("mobs.spider.ridable-in-water", spiderRidableInWater); + spiderControllable = getBoolean("mobs.spider.controllable", spiderControllable); + } + + public boolean strayRidable = false; + public boolean strayRidableInWater = true; + public boolean strayControllable = true; + private void straySettings() { + strayRidable = getBoolean("mobs.stray.ridable", strayRidable); + strayRidableInWater = getBoolean("mobs.stray.ridable-in-water", strayRidableInWater); + strayControllable = getBoolean("mobs.stray.controllable", strayControllable); + } + + public boolean striderRidable = false; + public boolean striderRidableInWater = false; + public boolean striderControllable = true; + private void striderSettings() { + striderRidable = getBoolean("mobs.strider.ridable", striderRidable); + striderRidableInWater = getBoolean("mobs.strider.ridable-in-water", striderRidableInWater); + striderControllable = getBoolean("mobs.strider.controllable", striderControllable); + } + + public boolean tadpoleRidable = false; + public boolean tadpoleRidableInWater = true; + public boolean tadpoleControllable = true; + private void tadpoleSettings() { + tadpoleRidable = getBoolean("mobs.tadpole.ridable", tadpoleRidable); + tadpoleRidableInWater = getBoolean("mobs.tadpole.ridable-in-water", tadpoleRidableInWater); + tadpoleControllable = getBoolean("mobs.tadpole.controllable", tadpoleControllable); + } + + public boolean traderLlamaRidable = false; + public boolean traderLlamaRidableInWater = false; + public boolean traderLlamaControllable = true; + private void traderLlamaSettings() { + traderLlamaRidable = getBoolean("mobs.trader_llama.ridable", traderLlamaRidable); + traderLlamaRidableInWater = getBoolean("mobs.trader_llama.ridable-in-water", traderLlamaRidableInWater); + traderLlamaControllable = getBoolean("mobs.trader_llama.controllable", traderLlamaControllable); + } + + public boolean tropicalFishRidable = false; + public boolean tropicalFishControllable = true; + private void tropicalFishSettings() { + tropicalFishRidable = getBoolean("mobs.tropical_fish.ridable", tropicalFishRidable); + tropicalFishControllable = getBoolean("mobs.tropical_fish.controllable", tropicalFishControllable); + } + + public boolean turtleRidable = false; + public boolean turtleRidableInWater = true; + public boolean turtleControllable = true; + private void turtleSettings() { + turtleRidable = getBoolean("mobs.turtle.ridable", turtleRidable); + turtleRidableInWater = getBoolean("mobs.turtle.ridable-in-water", turtleRidableInWater); + turtleControllable = getBoolean("mobs.turtle.controllable", turtleControllable); + } + + public boolean vexRidable = false; + public boolean vexRidableInWater = true; + public boolean vexControllable = true; + public double vexMaxY = 320D; + private void vexSettings() { + vexRidable = getBoolean("mobs.vex.ridable", vexRidable); + vexRidableInWater = getBoolean("mobs.vex.ridable-in-water", vexRidableInWater); + vexControllable = getBoolean("mobs.vex.controllable", vexControllable); + vexMaxY = getDouble("mobs.vex.ridable-max-y", vexMaxY); + } + + public boolean villagerRidable = false; + public boolean villagerRidableInWater = true; + public boolean villagerControllable = true; + private void villagerSettings() { + villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); + villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); + villagerControllable = getBoolean("mobs.villager.controllable", villagerControllable); + } + + public boolean vindicatorRidable = false; + public boolean vindicatorRidableInWater = true; + public boolean vindicatorControllable = true; + private void vindicatorSettings() { + vindicatorRidable = getBoolean("mobs.vindicator.ridable", vindicatorRidable); + vindicatorRidableInWater = getBoolean("mobs.vindicator.ridable-in-water", vindicatorRidableInWater); + vindicatorControllable = getBoolean("mobs.vindicator.controllable", vindicatorControllable); + } + + public boolean wanderingTraderRidable = false; + public boolean wanderingTraderRidableInWater = true; + public boolean wanderingTraderControllable = true; + private void wanderingTraderSettings() { + wanderingTraderRidable = getBoolean("mobs.wandering_trader.ridable", wanderingTraderRidable); + wanderingTraderRidableInWater = getBoolean("mobs.wandering_trader.ridable-in-water", wanderingTraderRidableInWater); + wanderingTraderControllable = getBoolean("mobs.wandering_trader.controllable", wanderingTraderControllable); + } + + public boolean wardenRidable = false; + public boolean wardenRidableInWater = true; + public boolean wardenControllable = true; + private void wardenSettings() { + wardenRidable = getBoolean("mobs.warden.ridable", wardenRidable); + wardenRidableInWater = getBoolean("mobs.warden.ridable-in-water", wardenRidableInWater); + wardenControllable = getBoolean("mobs.warden.controllable", wardenControllable); + } + + public boolean witchRidable = false; + public boolean witchRidableInWater = true; + public boolean witchControllable = true; + private void witchSettings() { + witchRidable = getBoolean("mobs.witch.ridable", witchRidable); + witchRidableInWater = getBoolean("mobs.witch.ridable-in-water", witchRidableInWater); + witchControllable = getBoolean("mobs.witch.controllable", witchControllable); + } + + public boolean witherRidable = false; + public boolean witherRidableInWater = true; + public boolean witherControllable = true; + public double witherMaxY = 320D; + private void witherSettings() { + witherRidable = getBoolean("mobs.wither.ridable", witherRidable); + witherRidableInWater = getBoolean("mobs.wither.ridable-in-water", witherRidableInWater); + witherControllable = getBoolean("mobs.wither.controllable", witherControllable); + witherMaxY = getDouble("mobs.wither.ridable-max-y", witherMaxY); + } + + public boolean witherSkeletonRidable = false; + public boolean witherSkeletonRidableInWater = true; + public boolean witherSkeletonControllable = true; + private void witherSkeletonSettings() { + witherSkeletonRidable = getBoolean("mobs.wither_skeleton.ridable", witherSkeletonRidable); + witherSkeletonRidableInWater = getBoolean("mobs.wither_skeleton.ridable-in-water", witherSkeletonRidableInWater); + witherSkeletonControllable = getBoolean("mobs.wither_skeleton.controllable", witherSkeletonControllable); + } + + public boolean wolfRidable = false; + public boolean wolfRidableInWater = true; + public boolean wolfControllable = true; + private void wolfSettings() { + wolfRidable = getBoolean("mobs.wolf.ridable", wolfRidable); + wolfRidableInWater = getBoolean("mobs.wolf.ridable-in-water", wolfRidableInWater); + wolfControllable = getBoolean("mobs.wolf.controllable", wolfControllable); + } + + public boolean zoglinRidable = false; + public boolean zoglinRidableInWater = true; + public boolean zoglinControllable = true; + private void zoglinSettings() { + zoglinRidable = getBoolean("mobs.zoglin.ridable", zoglinRidable); + zoglinRidableInWater = getBoolean("mobs.zoglin.ridable-in-water", zoglinRidableInWater); + zoglinControllable = getBoolean("mobs.zoglin.controllable", zoglinControllable); + } + + public boolean zombieRidable = false; + public boolean zombieRidableInWater = true; + public boolean zombieControllable = true; + private void zombieSettings() { + zombieRidable = getBoolean("mobs.zombie.ridable", zombieRidable); + zombieRidableInWater = getBoolean("mobs.zombie.ridable-in-water", zombieRidableInWater); + zombieControllable = getBoolean("mobs.zombie.controllable", zombieControllable); + } + + public boolean zombieHorseRidable = false; + public boolean zombieHorseRidableInWater = false; + public boolean zombieHorseCanSwim = false; + private void zombieHorseSettings() { + zombieHorseRidable = getBoolean("mobs.zombie_horse.ridable", zombieHorseRidable); + zombieHorseRidableInWater = getBoolean("mobs.zombie_horse.ridable-in-water", zombieHorseRidableInWater); + zombieHorseCanSwim = getBoolean("mobs.zombie_horse.can-swim", zombieHorseCanSwim); + } + + public boolean zombieVillagerRidable = false; + public boolean zombieVillagerRidableInWater = true; + public boolean zombieVillagerControllable = true; + private void zombieVillagerSettings() { + zombieVillagerRidable = getBoolean("mobs.zombie_villager.ridable", zombieVillagerRidable); + zombieVillagerRidableInWater = getBoolean("mobs.zombie_villager.ridable-in-water", zombieVillagerRidableInWater); + zombieVillagerControllable = getBoolean("mobs.zombie_villager.controllable", zombieVillagerControllable); + } + + public boolean zombifiedPiglinRidable = false; + public boolean zombifiedPiglinRidableInWater = true; + public boolean zombifiedPiglinControllable = true; + private void zombifiedPiglinSettings() { + zombifiedPiglinRidable = getBoolean("mobs.zombified_piglin.ridable", zombifiedPiglinRidable); + zombifiedPiglinRidableInWater = getBoolean("mobs.zombified_piglin.ridable-in-water", zombifiedPiglinRidableInWater); + zombifiedPiglinControllable = getBoolean("mobs.zombified_piglin.controllable", zombifiedPiglinControllable); + } } diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/controller/FlyingMoveControllerWASD.java b/purpur-server/src/main/java/org/purpurmc/purpur/controller/FlyingMoveControllerWASD.java new file mode 100644 index 000000000..940bcc6f7 --- /dev/null +++ b/purpur-server/src/main/java/org/purpurmc/purpur/controller/FlyingMoveControllerWASD.java @@ -0,0 +1,74 @@ +package org.purpurmc.purpur.controller; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.player.Input; +import net.minecraft.world.entity.player.Player; + +public class FlyingMoveControllerWASD extends MoveControllerWASD { + protected final float groundSpeedModifier; + protected final float flyingSpeedModifier; + protected int tooHighCooldown = 0; + protected boolean setNoGravityFlag; + + public FlyingMoveControllerWASD(Mob entity) { + this(entity, 1.0F); + } + + public FlyingMoveControllerWASD(Mob entity, float groundSpeedModifier) { + this(entity, groundSpeedModifier, 1.0F, true); + } + + public FlyingMoveControllerWASD(Mob entity, float groundSpeedModifier, float flyingSpeedModifier) { + this(entity, groundSpeedModifier, flyingSpeedModifier, true); + } + + public FlyingMoveControllerWASD(Mob entity, float groundSpeedModifier, float flyingSpeedModifier, boolean setNoGravityFlag) { + super(entity); + this.groundSpeedModifier = groundSpeedModifier; + this.flyingSpeedModifier = flyingSpeedModifier; + this.setNoGravityFlag = setNoGravityFlag; + } + + @Override + public void purpurTick(Player rider) { + Input lastClientInput = ((ServerPlayer) rider).getLastClientInput(); + float forward = lastClientInput.forward() == lastClientInput.backward() ? 0.0F : lastClientInput.forward() ? 1.0F : 0.0F; + float vertical = forward == 0.0F ? 0.0F : -(rider.xRotO / 45.0F); + float strafe = (lastClientInput.left() == lastClientInput.right() ? 0.0F : lastClientInput.left() ? 1.0F : -1.0F); + + if (lastClientInput.jump() && spacebarEvent(entity)) { + entity.onSpacebar(); + } + + if (entity.getY() >= entity.getMaxY() || --tooHighCooldown > 0) { + if (tooHighCooldown <= 0) { + tooHighCooldown = 20; + } + entity.setDeltaMovement(entity.getDeltaMovement().add(0.0D, -0.05D, 0.0D)); + vertical = 0.0F; + } + + setSpeedModifier(entity.getAttributeValue(Attributes.MOVEMENT_SPEED)); + float speed = (float) getSpeedModifier(); + + if (entity.onGround) { + speed *= groundSpeedModifier; // TODO = fix this! + } else { + speed *= flyingSpeedModifier; + } + + if (setNoGravityFlag) { + entity.setNoGravity(forward > 0); + } + + entity.setSpeed(speed); + entity.setVerticalMot(vertical); + entity.setStrafeMot(strafe); + entity.setForwardMot(forward); + + setForward(entity.getForwardMot()); + setStrafe(entity.getStrafeMot()); + } +} diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/controller/FlyingWithSpacebarMoveControllerWASD.java b/purpur-server/src/main/java/org/purpurmc/purpur/controller/FlyingWithSpacebarMoveControllerWASD.java new file mode 100644 index 000000000..e0bbaec05 --- /dev/null +++ b/purpur-server/src/main/java/org/purpurmc/purpur/controller/FlyingWithSpacebarMoveControllerWASD.java @@ -0,0 +1,66 @@ +package org.purpurmc.purpur.controller; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.player.Input; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.Vec3; + +public class FlyingWithSpacebarMoveControllerWASD extends FlyingMoveControllerWASD { + public FlyingWithSpacebarMoveControllerWASD(Mob entity) { + super(entity); + } + + public FlyingWithSpacebarMoveControllerWASD(Mob entity, float groundSpeedModifier) { + super(entity, groundSpeedModifier); + } + + @Override + public void purpurTick(Player rider) { + Input lastClientInput = ((ServerPlayer) rider).getLastClientInput(); + float forward = (lastClientInput.forward() == lastClientInput.backward() ? 0.0F : lastClientInput.forward() ? 1.0F : -1.0F); + float strafe = (lastClientInput.left() == lastClientInput.right() ? 0.0F : lastClientInput.left() ? 1.0F : -1.0F) * 0.5F; + float vertical = 0; + + if (forward < 0.0F) { + forward *= 0.5F; + strafe *= 0.5F; + } + + float speed = (float) entity.getAttributeValue(Attributes.MOVEMENT_SPEED); + + if (entity.onGround) { + speed *= groundSpeedModifier; + } + + if (lastClientInput.jump() && spacebarEvent(entity) && !entity.onSpacebar()) { + entity.setNoGravity(true); + vertical = 1.0F; + } else { + entity.setNoGravity(false); + } + + if (entity.getY() >= entity.getMaxY() || --tooHighCooldown > 0) { + if (tooHighCooldown <= 0) { + tooHighCooldown = 20; + } + entity.setDeltaMovement(entity.getDeltaMovement().add(0.0D, -0.2D, 0.0D)); + vertical = 0.0F; + } + + setSpeedModifier(speed); + entity.setSpeed((float) getSpeedModifier()); + entity.setVerticalMot(vertical); + entity.setStrafeMot(strafe); + entity.setForwardMot(forward); + + setForward(entity.getForwardMot()); + setStrafe(entity.getStrafeMot()); + + Vec3 mot = entity.getDeltaMovement(); + if (mot.y > 0.2D) { + entity.setDeltaMovement(mot.x, 0.2D, mot.z); + } + } +} diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/controller/LookControllerWASD.java b/purpur-server/src/main/java/org/purpurmc/purpur/controller/LookControllerWASD.java new file mode 100644 index 000000000..dd2195181 --- /dev/null +++ b/purpur-server/src/main/java/org/purpurmc/purpur/controller/LookControllerWASD.java @@ -0,0 +1,79 @@ +package org.purpurmc.purpur.controller; + + +import net.minecraft.network.protocol.game.ClientboundMoveEntityPacket; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.control.LookControl; +import net.minecraft.world.entity.player.Player; + +public class LookControllerWASD extends LookControl { + protected final Mob entity; + private float yOffset = 0; + private float xOffset = 0; + + public LookControllerWASD(Mob entity) { + super(entity); + this.entity = entity; + } + + // tick + @Override + public void tick() { + if (entity.getRider() != null && entity.isControllable()) { + purpurTick(entity.getRider()); + } else { + vanillaTick(); + } + } + + protected void purpurTick(Player rider) { + setYawPitch(rider.getYRot(), rider.getXRot()); + } + + public void vanillaTick() { + super.tick(); + } + + public void setYawPitch(float yRot, float xRot) { + entity.setXRot(normalizePitch(xRot + xOffset)); + entity.setYRot(normalizeYaw(yRot + yOffset)); + entity.setYHeadRot(entity.getYRot()); + entity.xRotO = entity.getXRot(); + entity.yRotO = entity.getYRot(); + + ClientboundMoveEntityPacket.PosRot entityPacket = new ClientboundMoveEntityPacket.PosRot( + entity.getId(), + (short) 0, (short) 0, (short) 0, + (byte) Mth.floor(entity.getYRot() * 256.0F / 360.0F), + (byte) Mth.floor(entity.getXRot() * 256.0F / 360.0F), + entity.onGround + ); + ((ServerLevel) entity.level()).getChunkSource().broadcast(entity, entityPacket); + } + + public void setOffsets(float yaw, float pitch) { + yOffset = yaw; + xOffset = pitch; + } + + public float normalizeYaw(float yaw) { + yaw %= 360.0f; + if (yaw >= 180.0f) { + yaw -= 360.0f; + } else if (yaw < -180.0f) { + yaw += 360.0f; + } + return yaw; + } + + public float normalizePitch(float pitch) { + if (pitch > 90.0f) { + pitch = 90.0f; + } else if (pitch < -90.0f) { + pitch = -90.0f; + } + return pitch; + } +} diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/controller/MoveControllerWASD.java b/purpur-server/src/main/java/org/purpurmc/purpur/controller/MoveControllerWASD.java new file mode 100644 index 000000000..34f3c43fa --- /dev/null +++ b/purpur-server/src/main/java/org/purpurmc/purpur/controller/MoveControllerWASD.java @@ -0,0 +1,92 @@ +package org.purpurmc.purpur.controller; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.ai.control.MoveControl; +import net.minecraft.world.entity.player.Input; +import net.minecraft.world.entity.player.Player; +import org.purpurmc.purpur.event.entity.RidableSpacebarEvent; + +public class MoveControllerWASD extends MoveControl { + protected final Mob entity; + private final double speedModifier; + + public MoveControllerWASD(Mob entity) { + this(entity, 1.0D); + } + + public MoveControllerWASD(Mob entity, double speedModifier) { + super(entity); + this.entity = entity; + this.speedModifier = speedModifier; + } + + @Override + public boolean hasWanted() { + return entity.getRider() != null ? strafeForwards != 0 || strafeRight != 0 : super.hasWanted(); + } + + @Override + public void tick() { + if (entity.getRider() != null && entity.isControllable()) { + purpurTick(entity.getRider()); + } else { + vanillaTick(); + } + } + + public void vanillaTick() { + super.tick(); + } + + public void purpurTick(Player rider) { + Input lastClientInput = ((ServerPlayer) rider).getLastClientInput(); + float forward = (lastClientInput.forward() == lastClientInput.backward() ? 0.0F : lastClientInput.forward() ? 1.0F : -1.0F) * 0.5F; + float strafe = (lastClientInput.left() == lastClientInput.right() ? 0.0F : lastClientInput.left() ? 1.0F : -1.0F) * 0.25F; + + if (forward <= 0.0F) { + forward *= 0.5F; + } + + float yawOffset = 0; + if (strafe != 0) { + if (forward == 0) { + yawOffset += strafe > 0 ? -90 : 90; + forward = Math.abs(strafe * 2); + } else { + yawOffset += strafe > 0 ? -30 : 30; + strafe /= 2; + if (forward < 0) { + yawOffset += strafe > 0 ? -110 : 110; + forward *= -1; + } + } + } else if (forward < 0) { + yawOffset -= 180; + forward *= -1; + } + + ((LookControllerWASD) entity.getLookControl()).setOffsets(yawOffset, 0); + + if (lastClientInput.jump() && spacebarEvent(entity) && !entity.onSpacebar() && entity.onGround) { + entity.jumpFromGround(); + } + + setSpeedModifier(entity.getAttributeValue(Attributes.MOVEMENT_SPEED) * speedModifier); + + entity.setSpeed((float) getSpeedModifier()); + entity.setForwardMot(forward); + + setForward(entity.getForwardMot()); + setStrafe(entity.getStrafeMot()); + } + + public static boolean spacebarEvent(Mob entity) { + if (RidableSpacebarEvent.getHandlerList().getRegisteredListeners().length > 0) { + return new RidableSpacebarEvent(entity.getBukkitEntity()).callEvent(); + } else { + return true; + } + } +} diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/controller/WaterMoveControllerWASD.java b/purpur-server/src/main/java/org/purpurmc/purpur/controller/WaterMoveControllerWASD.java new file mode 100644 index 000000000..922e48799 --- /dev/null +++ b/purpur-server/src/main/java/org/purpurmc/purpur/controller/WaterMoveControllerWASD.java @@ -0,0 +1,53 @@ +package org.purpurmc.purpur.controller; + +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.attributes.Attributes; +import net.minecraft.world.entity.player.Input; +import net.minecraft.world.entity.player.Player; + +public class WaterMoveControllerWASD extends MoveControllerWASD { + private final double speedModifier; + + public WaterMoveControllerWASD(Mob entity) { + this(entity, 1.0D); + } + + public WaterMoveControllerWASD(Mob entity, double speedModifier) { + super(entity); + this.speedModifier = speedModifier; + } + + @Override + public void purpurTick(Player rider) { + Input lastClientInput = ((ServerPlayer) rider).getLastClientInput(); + float forward = (lastClientInput.forward() == lastClientInput.backward() ? 0.0F : lastClientInput.forward() ? 1.0F : -1.0F); + float strafe = (lastClientInput.left() == lastClientInput.right() ? 0.0F : lastClientInput.left() ? 1.0F : -1.0F) * 0.5F; // strafe slower by default + float vertical = -(rider.xRotO / 90); + + if (forward == 0.0F) { + // strafe slower if not moving forward + strafe *= 0.5F; + // do not move vertically if not moving forward + vertical = 0.0F; + } else if (forward < 0.0F) { + // water animals can't swim backwards + forward = 0.0F; + vertical = 0.0F; + } + + if (rider.jumping && spacebarEvent(entity)) { + entity.onSpacebar(); + } + + setSpeedModifier(entity.getAttributeValue(Attributes.MOVEMENT_SPEED) * speedModifier); + entity.setSpeed((float) getSpeedModifier() * 0.1F); + + entity.setForwardMot(forward * (float) speedModifier); + entity.setStrafeMot(strafe * (float) speedModifier); + entity.setVerticalMot(vertical * (float) speedModifier); + + setForward(entity.getForwardMot()); + setStrafe(entity.getStrafeMot()); + } +} diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/entity/ai/HasRider.java b/purpur-server/src/main/java/org/purpurmc/purpur/entity/ai/HasRider.java new file mode 100644 index 000000000..8babdaddd --- /dev/null +++ b/purpur-server/src/main/java/org/purpurmc/purpur/entity/ai/HasRider.java @@ -0,0 +1,20 @@ +package org.purpurmc.purpur.entity.ai; + +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.goal.Goal; + +import java.util.EnumSet; + +public class HasRider extends Goal { + public final Mob entity; + + public HasRider(Mob entity) { + this.entity = entity; + setFlags(EnumSet.of(Flag.MOVE, Flag.LOOK, Flag.TARGET, Flag.UNKNOWN_BEHAVIOR)); + } + + @Override + public boolean canUse() { + return entity.getRider() != null && entity.isControllable(); + } +} diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/entity/ai/HorseHasRider.java b/purpur-server/src/main/java/org/purpurmc/purpur/entity/ai/HorseHasRider.java new file mode 100644 index 000000000..432f4f3d8 --- /dev/null +++ b/purpur-server/src/main/java/org/purpurmc/purpur/entity/ai/HorseHasRider.java @@ -0,0 +1,17 @@ +package org.purpurmc.purpur.entity.ai; + +import net.minecraft.world.entity.animal.horse.AbstractHorse; + +public class HorseHasRider extends HasRider { + public final AbstractHorse horse; + + public HorseHasRider(AbstractHorse entity) { + super(entity); + this.horse = entity; + } + + @Override + public boolean canUse() { + return super.canUse() && horse.isSaddled(); + } +} diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/entity/ai/LlamaHasRider.java b/purpur-server/src/main/java/org/purpurmc/purpur/entity/ai/LlamaHasRider.java new file mode 100644 index 000000000..18a95e043 --- /dev/null +++ b/purpur-server/src/main/java/org/purpurmc/purpur/entity/ai/LlamaHasRider.java @@ -0,0 +1,17 @@ +package org.purpurmc.purpur.entity.ai; + +import net.minecraft.world.entity.animal.horse.Llama; + +public class LlamaHasRider extends HasRider { + public final Llama llama; + + public LlamaHasRider(Llama entity) { + super(entity); + this.llama = entity; + } + + @Override + public boolean canUse() { + return super.canUse() && llama.isSaddled() && llama.isControllable(); + } +} diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/entity/projectile/DolphinSpit.java b/purpur-server/src/main/java/org/purpurmc/purpur/entity/projectile/DolphinSpit.java new file mode 100644 index 000000000..510f0f1b2 --- /dev/null +++ b/purpur-server/src/main/java/org/purpurmc/purpur/entity/projectile/DolphinSpit.java @@ -0,0 +1,100 @@ +package org.purpurmc.purpur.entity.projectile; + +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.animal.Dolphin; +import net.minecraft.world.entity.projectile.LlamaSpit; +import net.minecraft.world.entity.projectile.ProjectileUtil; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.EntityHitResult; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; +import org.bukkit.event.entity.EntityRemoveEvent; + +public class DolphinSpit extends LlamaSpit { + public LivingEntity dolphin; + public int ticksLived; + + public DolphinSpit(EntityType type, Level world) { + super(type, world); + } + + public DolphinSpit(Level world, Dolphin dolphin) { + this(EntityType.LLAMA_SPIT, world); + this.setOwner(dolphin.getRider() != null ? dolphin.getRider() : dolphin); + this.dolphin = dolphin; + this.setPos( + dolphin.getX() - (double) (dolphin.getBbWidth() + 1.0F) * 0.5 * (double) Mth.sin(dolphin.yBodyRot * (float) (Math.PI / 180.0)), + dolphin.getEyeY() - 0.1F, + dolphin.getZ() + (double) (dolphin.getBbWidth() + 1.0F) * 0.5 * (double) Mth.cos(dolphin.yBodyRot * (float) (Math.PI / 180.0))); + } + + public void tick() { + projectileTick(); + + Vec3 mot = this.getDeltaMovement(); + HitResult hitResult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); + + this.preHitTargetOrDeflectSelf(hitResult); + + double x = this.getX() + mot.x; + double y = this.getY() + mot.y; + double z = this.getZ() + mot.z; + + this.updateRotation(); + + Vec3 motDouble = mot.scale(2.0); + for (int i = 0; i < 5; i++) { + ((ServerLevel) level()).sendParticlesSource(null, ParticleTypes.BUBBLE, + false, true, + getX() + random.nextFloat() / 2 - 0.25F, + getY() + random.nextFloat() / 2 - 0.25F, + getZ() + random.nextFloat() / 2 - 0.25F, + 0, motDouble.x(), motDouble.y(), motDouble.z(), 0.1D); + } + + if (++ticksLived > 20) { + this.discard(EntityRemoveEvent.Cause.DISCARD); + } else { + this.setDeltaMovement(mot.scale(0.99D)); + if (!this.isNoGravity()) { + this.setDeltaMovement(this.getDeltaMovement().add(0.0D, -0.06D, 0.0D)); + } + + this.setPos(x, y, z); + } + } + + @Override + public void shoot(double x, double y, double z, float speed, float inaccuracy) { + setDeltaMovement(new Vec3(x, y, z).normalize().add( + random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, + random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, + random.nextGaussian() * (double) 0.0075F * (double) inaccuracy) + .scale(speed)); + } + + @Override + protected void onHitEntity(EntityHitResult entityHitResult) { + Entity shooter = this.getOwner(); + if (shooter instanceof LivingEntity) { + entityHitResult.getEntity().hurt(entityHitResult.getEntity().damageSources().mobProjectile(this, (LivingEntity) shooter), level().purpurConfig.dolphinSpitDamage); + } + } + + @Override + protected void onHitBlock(BlockHitResult blockHitResult) { + if (this.hitCancelled) { + return; + } + BlockState state = this.level().getBlockState(blockHitResult.getBlockPos()); + state.onProjectileHit(this.level(), state, blockHitResult, this); + this.discard(EntityRemoveEvent.Cause.DISCARD); + } +} diff --git a/purpur-server/src/main/java/org/purpurmc/purpur/entity/projectile/PhantomFlames.java b/purpur-server/src/main/java/org/purpurmc/purpur/entity/projectile/PhantomFlames.java new file mode 100644 index 000000000..f1b79647b --- /dev/null +++ b/purpur-server/src/main/java/org/purpurmc/purpur/entity/projectile/PhantomFlames.java @@ -0,0 +1,122 @@ +package org.purpurmc.purpur.entity.projectile; + +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.decoration.ArmorStand; +import net.minecraft.world.entity.monster.Phantom; +import net.minecraft.world.entity.projectile.LlamaSpit; +import net.minecraft.world.entity.projectile.ProjectileUtil; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.EntityHitResult; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; + +public class PhantomFlames extends LlamaSpit { + public Phantom phantom; + public int ticksLived; + public boolean canGrief = false; + + public PhantomFlames(EntityType type, Level world) { + super(type, world); + } + + public PhantomFlames(Level world, Phantom phantom) { + this(EntityType.LLAMA_SPIT, world); + setOwner(phantom.getRider() != null ? phantom.getRider() : phantom); + this.phantom = phantom; + this.setPos( + phantom.getX() - (double) (phantom.getBbWidth() + 1.0F) * 0.5D * (double) Mth.sin(phantom.yBodyRot * (float) (Math.PI / 180.0)), + phantom.getEyeY() - 0.10000000149011612D, + phantom.getZ() + (double) (phantom.getBbWidth() + 1.0F) * 0.5D * (double) Mth.cos(phantom.yBodyRot * (float) (Math.PI / 180.0))); + } + + public void tick() { + projectileTick(); + + Vec3 mot = this.getDeltaMovement(); + HitResult hitResult = ProjectileUtil.getHitResultOnMoveVector(this, this::canHitEntity); + + this.preHitTargetOrDeflectSelf(hitResult); + + double x = this.getX() + mot.x; + double y = this.getY() + mot.y; + double z = this.getZ() + mot.z; + + this.updateRotation(); + + Vec3 motDouble = mot.scale(2.0); + for (int i = 0; i < 5; i++) { + ((ServerLevel) level()).sendParticlesSource(null, ParticleTypes.FLAME, + false, true, + getX() + random.nextFloat() / 2 - 0.25F, + getY() + random.nextFloat() / 2 - 0.25F, + getZ() + random.nextFloat() / 2 - 0.25F, + 0, motDouble.x(), motDouble.y(), motDouble.z(), 0.1D); + } + + if (++ticksLived > 20) { + this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); + } else if (this.level().getBlockStates(this.getBoundingBox()).noneMatch(BlockBehaviour.BlockStateBase::isAir)) { + this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); + } else if (this.isInWaterOrBubble()) { + this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); + } else { + this.setDeltaMovement(mot.scale(0.99D)); + if (!this.isNoGravity()) { + this.setDeltaMovement(this.getDeltaMovement().add(0.0D, -0.06D, 0.0D)); + } + + this.setPos(x, y, z); + } + } + + @Override + public void shoot(double x, double y, double z, float speed, float inaccuracy) { + setDeltaMovement(new Vec3(x, y, z).normalize().add( + random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, + random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, + random.nextGaussian() * (double) 0.0075F * (double) inaccuracy) + .scale(speed)); + } + + @Override + protected void onHitEntity(EntityHitResult entityHitResult) { + Level world = this.level(); + + if (world instanceof ServerLevel worldserver) { + Entity shooter = this.getOwner(); + if (shooter instanceof LivingEntity) { + Entity target = entityHitResult.getEntity(); + if (canGrief || (target instanceof LivingEntity && !(target instanceof ArmorStand))) { + boolean hurt = target.hurtServer(worldserver, target.damageSources().mobProjectile(this, (LivingEntity) shooter), worldserver.purpurConfig.phantomFlameDamage); + if (hurt && worldserver.purpurConfig.phantomFlameFireTime > 0) { + target.igniteForSeconds(worldserver.purpurConfig.phantomFlameFireTime); + } + } + } + } + } + + @Override + protected void onHitBlock(BlockHitResult blockHitResult) { + Level world = this.level(); + + if (world instanceof ServerLevel worldserver) { + if (this.hitCancelled) { + return; + } + if (this.canGrief) { + BlockState state = worldserver.getBlockState(blockHitResult.getBlockPos()); + state.onProjectileHit(worldserver, state, blockHitResult, this); + } + this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD); + } + } +}