mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-17 16:37:43 +01:00
5249 lines
240 KiB
Diff
5249 lines
240 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
|
Date: Sun, 5 Jul 2020 22:19:49 -0500
|
|
Subject: [PATCH] Ridables
|
|
|
|
|
|
diff --git a/net/minecraft/gametest/framework/GameTestHelper.java b/net/minecraft/gametest/framework/GameTestHelper.java
|
|
index aa87e93ade4c25a575e7861fef45b70c3e4e3aeb..c92ffd8b2fe4945ccd552eb54154b7be0e1b492e 100644
|
|
--- a/net/minecraft/gametest/framework/GameTestHelper.java
|
|
+++ b/net/minecraft/gametest/framework/GameTestHelper.java
|
|
@@ -314,6 +314,8 @@ public class GameTestHelper {
|
|
|
|
public void setAfk(final boolean afk) {} // Purpur - AFK API
|
|
|
|
+ public void resetLastActionTime() {} // Purpur - Ridables
|
|
+
|
|
@Override
|
|
public boolean isClientAuthoritative() {
|
|
return false;
|
|
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
|
|
index 9dffc51f3651169e81e1617bce4562faf35c12f6..5f86c3024a857d5ec3ac39a4ef1d2a77b452c2bb 100644
|
|
--- a/net/minecraft/server/MinecraftServer.java
|
|
+++ b/net/minecraft/server/MinecraftServer.java
|
|
@@ -1683,6 +1683,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
serverLevel.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 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 187fd32cdc6a37974cb9e55997dfdda57f7cbfa5..5fe9976ccd113eddd94e328b37946ef0fb7f0b09 100644
|
|
--- a/net/minecraft/server/level/ServerLevel.java
|
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
|
@@ -224,6 +224,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)
|
|
+ public boolean hasRidableMoveEvent = false; // Purpur - Ridables
|
|
|
|
@Override
|
|
public @Nullable LevelChunk getChunkIfLoaded(int x, int z) {
|
|
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
|
index 5477fd9bc0a30b0d566d982b86b737cb6392b030..8c0cdb6aaf2f546b90d7d6b0d9dfc1c053479de7 100644
|
|
--- a/net/minecraft/server/level/ServerPlayer.java
|
|
+++ b/net/minecraft/server/level/ServerPlayer.java
|
|
@@ -774,6 +774,15 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
|
|
this.trackEnteredOrExitedLavaOnVehicle();
|
|
this.updatePlayerAttributes();
|
|
this.advancements.flushDirty(this, true);
|
|
+
|
|
+ // Purpur start - Ridables
|
|
+ if (this.level().purpurConfig.useNightVisionWhenRiding && this.getVehicle() != null && this.getVehicle().getRider() == this && this.level().getGameTime() % 100 == 0) { // 5 seconds
|
|
+ MobEffectInstance nightVision = this.getEffect(MobEffects.NIGHT_VISION);
|
|
+ if (nightVision == null || nightVision.getDuration() <= 300) { // 15 seconds
|
|
+ this.addEffect(new MobEffectInstance(MobEffects.NIGHT_VISION, 400, 0)); // 20 seconds
|
|
+ }
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
}
|
|
|
|
private void updatePlayerAttributes() {
|
|
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
index 8813b9d09b0ffaf235516cada788df92a7730eaa..c643f0546613e8f4783d1e0830f7267570de7ea7 100644
|
|
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
@@ -2862,6 +2862,8 @@ public class ServerGamePacketListenerImpl
|
|
ServerGamePacketListenerImpl.this.cserver.getPluginManager().callEvent(event);
|
|
final boolean resendData = event.isCancelled() || !ServerGamePacketListenerImpl.this.player.getItemInHand(hand).is(itemType);
|
|
|
|
+ player.processClick(hand); // Purpur - Ridables
|
|
+
|
|
// Entity in bucket - SPIGOT-4048 and SPIGOT-6859
|
|
if (itemType == Items.WATER_BUCKET && target instanceof net.minecraft.world.entity.animal.Bucketable && target instanceof LivingEntity && resendData) {
|
|
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 e7a2d579ab6b2eeacc34da01c8bb9f7c0d224221..ef77be60df1cf44088e684c21dbcaf3032bb3ad6 100644
|
|
--- a/net/minecraft/world/entity/Entity.java
|
|
+++ b/net/minecraft/world/entity/Entity.java
|
|
@@ -3357,6 +3357,13 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
|
|
|
this.passengers = ImmutableList.copyOf(list);
|
|
}
|
|
+
|
|
+ // Purpur start - Ridables
|
|
+ if (isRidable() && this.passengers.get(0) == passenger && passenger instanceof Player player) {
|
|
+ onMount(player);
|
|
+ this.rider = player;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
}
|
|
}
|
|
|
|
@@ -3397,6 +3404,14 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
|
return false;
|
|
}
|
|
// CraftBukkit end
|
|
+
|
|
+ // Purpur start - Ridables
|
|
+ if (this.rider != null && this.passengers.get(0) == this.rider) {
|
|
+ onDismount(this.rider);
|
|
+ this.rider = null;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
if (this.passengers.size() == 1 && this.passengers.get(0) == passenger) {
|
|
this.passengers = ImmutableList.of();
|
|
} else {
|
|
@@ -5474,4 +5489,44 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name
|
|
return ((ServerLevel) this.level()).isPositionEntityTicking(this.blockPosition());
|
|
}
|
|
// Paper end - Expose entity id counter
|
|
+ // Purpur start - Ridables
|
|
+ @Nullable
|
|
+ private Player rider = null;
|
|
+
|
|
+ @Nullable
|
|
+ public Player getRider() {
|
|
+ return rider;
|
|
+ }
|
|
+
|
|
+ public boolean isRidable() {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ public boolean isControllable() {
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ public void onMount(Player rider) {
|
|
+ if (this instanceof Mob) {
|
|
+ ((Mob) this).setTarget(null, null);
|
|
+ ((Mob) this).getNavigation().stop();
|
|
+ }
|
|
+ rider.setJumping(false); // fixes jump on mount
|
|
+ }
|
|
+
|
|
+ public void onDismount(Player player) {
|
|
+ }
|
|
+
|
|
+ public boolean onSpacebar() {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ public boolean onClick(InteractionHand hand) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ public boolean processClick(InteractionHand hand) {
|
|
+ return false;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
}
|
|
diff --git a/net/minecraft/world/entity/GlowSquid.java b/net/minecraft/world/entity/GlowSquid.java
|
|
index f0c452ddc4b299a930de261722cc41a89aa78eeb..8e8ddab59de508c84c4182e105a11554387dcce0 100644
|
|
--- a/net/minecraft/world/entity/GlowSquid.java
|
|
+++ b/net/minecraft/world/entity/GlowSquid.java
|
|
@@ -34,6 +34,19 @@ public class GlowSquid extends Squid {
|
|
}
|
|
// Purpur end - Flying squids! Oh my!
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.glowSquidRidable;
|
|
+ }
|
|
+
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.glowSquidControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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 d6540b82ce0f7c8fde596c6af24212bac1ef54bd..fdf197b040b87468fe89d86f21688c7c07bef853 100644
|
|
--- a/net/minecraft/world/entity/LivingEntity.java
|
|
+++ b/net/minecraft/world/entity/LivingEntity.java
|
|
@@ -239,9 +239,9 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
|
protected int noActionTime;
|
|
public float lastHurt;
|
|
public boolean jumping;
|
|
- public float xxa;
|
|
- public float yya;
|
|
- public float zza;
|
|
+ public float xxa; public float getStrafeMot() { return xxa; } public void setStrafeMot(float strafe) { xxa = strafe; } // Purpur - OBFHELPER
|
|
+ public float yya; public float getVerticalMot() { return yya; } public void setVerticalMot(float vertical) { yya = vertical; } // Purpur - OBFHELPER
|
|
+ public float zza; public float getForwardMot() { return zza; } public void setForwardMot(float forward) { zza = forward; } // Purpur - OBFHELPER
|
|
protected InterpolationHandler interpolation = new InterpolationHandler(this);
|
|
protected double lerpYHeadRot;
|
|
protected int lerpHeadSteps;
|
|
@@ -290,7 +290,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
|
|
|
protected LivingEntity(EntityType<? extends LivingEntity> 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 org.bukkit.craftbukkit.attribute.CraftAttributeMap(this.attributes); // CraftBukkit
|
|
// 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());
|
|
@@ -370,6 +370,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
|
.add(Attributes.CAMERA_DISTANCE)
|
|
.add(Attributes.WAYPOINT_TRANSMIT_RANGE);
|
|
}
|
|
+ public boolean shouldSendAttribute(Attribute attribute) { return true; } // Purpur - Ridables
|
|
|
|
@Override
|
|
protected void checkFallDamage(double y, boolean onGround, BlockState state, BlockPos pos) {
|
|
@@ -3057,6 +3058,20 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
|
this.move(MoverType.SELF, this.getDeltaMovement());
|
|
this.setDeltaMovement(this.getDeltaMovement().scale(0.5));
|
|
} else {
|
|
+ // Purpur start - Ridables
|
|
+ if (this.getRider() != null && this.isControllable()) {
|
|
+ float friction = 0.91F;
|
|
+ if (this.onGround()) {
|
|
+ friction = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getFriction() * 0.91F;
|
|
+ }
|
|
+
|
|
+ float frictionCompensation = 0.16277137F / (friction * friction * friction);
|
|
+ this.moveRelative(this.onGround() ? 0.1F * frictionCompensation : 0.02F, relative);
|
|
+ this.move(MoverType.SELF, this.getDeltaMovement());
|
|
+ this.setDeltaMovement(this.getDeltaMovement().scale(friction));
|
|
+ return;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
this.moveRelative(amount, relative);
|
|
this.move(MoverType.SELF, this.getDeltaMovement());
|
|
this.setDeltaMovement(this.getDeltaMovement().scale(0.91F));
|
|
@@ -3660,8 +3675,10 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
|
this.pushEntities();
|
|
profilerFiller.pop();
|
|
// Paper start - Add EntityMoveEvent
|
|
- 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 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());
|
|
@@ -3671,6 +3688,21 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
|
|
this.absSnapTo(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ(), event.getTo().getYaw(), event.getTo().getPitch());
|
|
}
|
|
}
|
|
+ // Purpur start - Ridables
|
|
+ if (getRider() != null) {
|
|
+ getRider().resetLastActionTime();
|
|
+ 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(), (org.bukkit.entity.Player) getRider().getBukkitEntity(), from, to.clone());
|
|
+ if (!event.callEvent()) {
|
|
+ this.absSnapTo(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch());
|
|
+ } else if (!to.equals(event.getTo())) {
|
|
+ this.absSnapTo(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ(), event.getTo().getYaw(), event.getTo().getPitch());
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
}
|
|
// Paper end - Add EntityMoveEvent
|
|
if (this.level() instanceof ServerLevel serverLevel && this.isSensitiveToWater() && this.isInWaterOrRain()) {
|
|
diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java
|
|
index 73c110a04f17141e6331d5c518780fc5122f2bc3..2bef2cd10447f41d5fc4c37eb574ce32fc2386ab 100644
|
|
--- a/net/minecraft/world/entity/Mob.java
|
|
+++ b/net/minecraft/world/entity/Mob.java
|
|
@@ -156,8 +156,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);
|
|
- this.moveControl = new MoveControl(this);
|
|
+ this.lookControl = new org.purpurmc.purpur.controller.LookControllerWASD(this); // Purpur - Ridables
|
|
+ this.moveControl = new org.purpurmc.purpur.controller.MoveControllerWASD(this); // Purpur - Ridables
|
|
this.jumpControl = new JumpControl(this);
|
|
this.bodyRotationControl = this.createBodyControl();
|
|
this.navigation = this.createNavigation(level);
|
|
@@ -1322,7 +1322,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
|
}
|
|
|
|
protected InteractionResult mobInteract(Player player, InteractionHand hand) {
|
|
- return InteractionResult.PASS;
|
|
+ return tryRide(player, hand); // Purpur - Ridables
|
|
}
|
|
|
|
protected void usePlayerItem(Player player, InteractionHand hand, ItemStack stack) {
|
|
@@ -1673,4 +1673,58 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab
|
|
registration.register(DebugSubscriptions.BRAINS, () -> DebugBrainDump.takeBrainDump(level, this));
|
|
}
|
|
}
|
|
+
|
|
+ // Purpur start - Ridables
|
|
+ public double getMaxY() {
|
|
+ return level().getHeight();
|
|
+ }
|
|
+
|
|
+ public InteractionResult tryRide(Player player, InteractionHand hand) {
|
|
+ return tryRide(player, hand, InteractionResult.PASS);
|
|
+ }
|
|
+
|
|
+ public InteractionResult tryRide(Player player, InteractionHand hand, InteractionResult result) {
|
|
+ if (!isRidable()) {
|
|
+ return result;
|
|
+ }
|
|
+ if (hand != InteractionHand.MAIN_HAND) {
|
|
+ return InteractionResult.PASS;
|
|
+ }
|
|
+ if (player.isShiftKeyDown()) {
|
|
+ return InteractionResult.PASS;
|
|
+ }
|
|
+ if (!player.getItemInHand(hand).isEmpty()) {
|
|
+ return InteractionResult.PASS;
|
|
+ }
|
|
+ if (!passengers.isEmpty() || player.isPassenger()) {
|
|
+ return InteractionResult.PASS;
|
|
+ }
|
|
+ if (this instanceof TamableAnimal tamable) {
|
|
+ if (tamable.isTame() && !tamable.isOwnedBy(player)) {
|
|
+ return InteractionResult.PASS;
|
|
+ }
|
|
+ if (!tamable.isTame() && !level().purpurConfig.untamedTamablesAreRidable) {
|
|
+ return InteractionResult.PASS;
|
|
+ }
|
|
+ }
|
|
+ if (this instanceof AgeableMob ageable) {
|
|
+ if (ageable.isBaby() && !level().purpurConfig.babiesAreRidable) {
|
|
+ return InteractionResult.PASS;
|
|
+ }
|
|
+ }
|
|
+ if (!player.getBukkitEntity().hasPermission("allow.ride." + net.minecraft.core.registries.BuiltInRegistries.ENTITY_TYPE.getKey(getType()).getPath())) {
|
|
+ if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) {
|
|
+ serverPlayer.sendMiniMessage(org.purpurmc.purpur.PurpurConfig.cannotRideMob);
|
|
+ }
|
|
+ return InteractionResult.PASS;
|
|
+ }
|
|
+ player.setYRot(this.getYRot());
|
|
+ player.setXRot(this.getXRot());
|
|
+ if (player.startRiding(this)) {
|
|
+ return InteractionResult.SUCCESS;
|
|
+ } else {
|
|
+ return InteractionResult.PASS;
|
|
+ }
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
}
|
|
diff --git a/net/minecraft/world/entity/ai/attributes/AttributeMap.java b/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
|
index fdb02fc40579866167e8cc9bcefbd961588b53a6..7dd8c1c8e27410854ce1ee90defc607c2710b5a2 100644
|
|
--- a/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
|
+++ b/net/minecraft/world/entity/ai/attributes/AttributeMap.java
|
|
@@ -18,14 +18,21 @@ public class AttributeMap {
|
|
private final Set<AttributeInstance> attributesToSync = new ObjectOpenHashSet<>();
|
|
private final Set<AttributeInstance> attributesToUpdate = new ObjectOpenHashSet<>();
|
|
private final AttributeSupplier supplier;
|
|
+ private final net.minecraft.world.entity.LivingEntity entity; // Purpur - Ridables
|
|
|
|
public AttributeMap(AttributeSupplier supplier) {
|
|
- this.supplier = supplier;
|
|
+ // Purpur start - Ridables
|
|
+ this(supplier, null);
|
|
+ }
|
|
+ public AttributeMap(AttributeSupplier defaultAttributes, net.minecraft.world.entity.LivingEntity entity) {
|
|
+ this.entity = entity;
|
|
+ // Purpur end - Ridables
|
|
+ this.supplier = defaultAttributes;
|
|
}
|
|
|
|
private void onAttributeModified(AttributeInstance instance) {
|
|
this.attributesToUpdate.add(instance);
|
|
- if (instance.getAttribute().value().isClientSyncable()) {
|
|
+ if (instance.getAttribute().value().isClientSyncable() && (entity == null || entity.shouldSendAttribute(instance.getAttribute().value()))) { // Purpur - Ridables
|
|
this.attributesToSync.add(instance);
|
|
}
|
|
}
|
|
@@ -39,7 +46,7 @@ public class AttributeMap {
|
|
}
|
|
|
|
public Collection<AttributeInstance> getSyncableAttributes() {
|
|
- 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 f14358b09785fe78459964c0e25ef8f4c12c8e60..c23d6edeaca324bcfd60c6e96ec4038f6ef595a9 100644
|
|
--- a/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java
|
|
+++ b/net/minecraft/world/entity/ai/attributes/DefaultAttributes.java
|
|
@@ -136,7 +136,7 @@ public class DefaultAttributes {
|
|
.put(EntityType.OCELOT, Ocelot.createAttributes().build())
|
|
.put(EntityType.PANDA, Panda.createAttributes().build())
|
|
.put(EntityType.PARROT, Parrot.createAttributes().build())
|
|
- .put(EntityType.PHANTOM, Monster.createMonsterAttributes().build())
|
|
+ .put(EntityType.PHANTOM, net.minecraft.world.entity.monster.Phantom.createAttributes().build()) // Purpur - Ridables
|
|
.put(EntityType.PIG, Pig.createAttributes().build())
|
|
.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 b6921582adef6f4c48de4dcffd6873ac0f909a08..89ee325b26ec3a647f55e45c9122ff4196433a43 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 = mob;
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ public void setSpeedModifier(double speed) {
|
|
+ this.speedModifier = speed;
|
|
+ }
|
|
+
|
|
+ public void setForward(float forward) {
|
|
+ this.strafeForwards = forward;
|
|
+ }
|
|
+
|
|
+ public void setStrafe(float strafe) {
|
|
+ this.strafeRight = strafe;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public boolean hasWanted() {
|
|
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 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;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.world.entity.Mob;
|
|
|
|
-public class SmoothSwimmingLookControl extends LookControl {
|
|
+public class SmoothSwimmingLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - Ridables
|
|
private final int maxYRotFromCenter;
|
|
private static final int HEAD_TILT_X = 10;
|
|
private static final int HEAD_TILT_Y = 20;
|
|
@@ -14,7 +14,7 @@ public class SmoothSwimmingLookControl extends LookControl {
|
|
}
|
|
|
|
@Override
|
|
- public void tick() {
|
|
+ public void vanillaTick() { // Purpur - Ridables
|
|
if (this.lookAtCooldown > 0) {
|
|
this.lookAtCooldown--;
|
|
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 43978de88c97ef2bd3e57171ea124e53a04171fd..3b4ebfaf2327dd599cd98918418b6efc6d6be9b2 100644
|
|
--- a/net/minecraft/world/entity/ambient/Bat.java
|
|
+++ b/net/minecraft/world/entity/ambient/Bat.java
|
|
@@ -44,11 +44,58 @@ public class Bat extends AmbientCreature {
|
|
|
|
public Bat(EntityType<? extends Bat> entityType, Level level) {
|
|
super(entityType, level);
|
|
+ this.moveControl = new org.purpurmc.purpur.controller.FlyingWithSpacebarMoveControllerWASD(this, 0.075F); // Purpur - Ridables
|
|
if (!level.isClientSide()) {
|
|
this.setResting(true);
|
|
}
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean shouldSendAttribute(net.minecraft.world.entity.ai.attributes.Attribute attribute) { return attribute != Attributes.FLYING_SPEED.value(); } // Fixes log spam on clients
|
|
+
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.batRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.batRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.batControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public double getMaxY() {
|
|
+ return level().purpurConfig.batMaxY;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onMount(net.minecraft.world.entity.player.Player rider) {
|
|
+ super.onMount(rider);
|
|
+ if (isResting()) {
|
|
+ setResting(false);
|
|
+ level().levelEvent(null, 1025, new BlockPos(this).above(), 0);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void travel(Vec3 vec3) {
|
|
+ super.travel(vec3);
|
|
+ if (getRider() != null && this.isControllable() && !onGround) {
|
|
+ float speed = (float) getAttributeValue(Attributes.FLYING_SPEED) * 2;
|
|
+ setSpeed(speed);
|
|
+ Vec3 mot = getDeltaMovement();
|
|
+ move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, 0.25, speed));
|
|
+ setDeltaMovement(mot.scale(0.9D));
|
|
+ }
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
public boolean isFlapping() {
|
|
return !this.isResting() && this.tickCount % 10.0F == 0.0F;
|
|
@@ -100,7 +147,7 @@ public class Bat extends AmbientCreature {
|
|
}
|
|
|
|
public static AttributeSupplier.Builder createAttributes() {
|
|
- 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() {
|
|
@@ -131,6 +178,14 @@ public class Bat extends AmbientCreature {
|
|
|
|
@Override
|
|
protected void customServerAiStep(ServerLevel level) {
|
|
+ // Purpur start - Ridables
|
|
+ if (getRider() != null && this.isControllable()) {
|
|
+ Vec3 mot = getDeltaMovement();
|
|
+ setDeltaMovement(mot.x(), mot.y() + (getVerticalMot() > 0 ? 0.07D : 0.0D), mot.z());
|
|
+ return;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
super.customServerAiStep(level);
|
|
BlockPos blockPos = this.blockPosition();
|
|
BlockPos blockPos1 = blockPos.above();
|
|
diff --git a/net/minecraft/world/entity/animal/AbstractCow.java b/net/minecraft/world/entity/animal/AbstractCow.java
|
|
index 4e81bc7215c845b316bcd46ce29f49af7f986088..61e7300bbf272398b2faebf5e537d9c2ddedc6d6 100644
|
|
--- a/net/minecraft/world/entity/animal/AbstractCow.java
|
|
+++ b/net/minecraft/world/entity/animal/AbstractCow.java
|
|
@@ -37,6 +37,7 @@ public abstract class AbstractCow 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(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 -> level().purpurConfig.cowFeedMushrooms > 0 && (itemStack.is(net.minecraft.world.level.block.Blocks.RED_MUSHROOM.asItem()) || itemStack.is(net.minecraft.world.level.block.Blocks.BROWN_MUSHROOM.asItem())) || itemStack.is(ItemTags.COW_FOOD), false)); // Purpur - Cows eat mushrooms
|
|
@@ -82,13 +83,14 @@ public abstract class AbstractCow extends Animal {
|
|
|
|
@Override
|
|
public InteractionResult mobInteract(Player player, InteractionHand hand) {
|
|
+ if (getRider() != null) return InteractionResult.PASS; // Purpur - Ridables
|
|
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(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/AbstractFish.java b/net/minecraft/world/entity/animal/AbstractFish.java
|
|
index b18765bb91b4015bef326663dbc8966945929996..0002e39e2670ad92849ccc0aada163b174fe1ec2 100644
|
|
--- a/net/minecraft/world/entity/animal/AbstractFish.java
|
|
+++ b/net/minecraft/world/entity/animal/AbstractFish.java
|
|
@@ -90,6 +90,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable {
|
|
@Override
|
|
protected void registerGoals() {
|
|
super.registerGoals();
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
this.goalSelector.addGoal(0, new PanicGoal(this, 1.25));
|
|
this.goalSelector.addGoal(2, new AvoidEntityGoal<>(this, Player.class, 8.0F, 1.6, 1.4, EntitySelector.NO_SPECTATORS::test));
|
|
this.goalSelector.addGoal(4, new AbstractFish.FishSwimGoal(this));
|
|
@@ -103,7 +104,7 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable {
|
|
@Override
|
|
public void travel(Vec3 travelVector) {
|
|
if (this.isInWater()) {
|
|
- 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) {
|
|
@@ -163,7 +164,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 mob) {
|
|
@@ -171,14 +172,22 @@ public abstract class AbstractFish extends WaterAnimal implements Bucketable {
|
|
this.fish = mob;
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
@Override
|
|
- public void tick() {
|
|
+ public void purpurTick(Player rider) {
|
|
+ super.purpurTick(rider);
|
|
+ fish.setDeltaMovement(fish.getDeltaMovement().add(0.0D, 0.005D, 0.0D));
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
+ @Override
|
|
+ public void vanillaTick() { // Purpur - Ridables
|
|
if (this.fish.isEyeInFluid(FluidTags.WATER)) {
|
|
this.fish.setDeltaMovement(this.fish.getDeltaMovement().add(0.0, 0.005, 0.0));
|
|
}
|
|
|
|
if (this.operation == MoveControl.Operation.MOVE_TO && !this.fish.getNavigation().isDone()) {
|
|
- float f = (float)(this.speedModifier * this.fish.getAttributeValue(Attributes.MOVEMENT_SPEED));
|
|
+ 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 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 924dbe3f82224ce4e68b9829c59586c2efda1781..3da697dfaef1880070ef61a3386adbf20d98e1a1 100644
|
|
--- a/net/minecraft/world/entity/animal/Bee.java
|
|
+++ b/net/minecraft/world/entity/animal/Bee.java
|
|
@@ -152,6 +152,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
|
|
|
public Bee(EntityType<? extends Bee> 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) {
|
|
@@ -160,11 +161,24 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
|
|
|
@Override
|
|
public void tick() {
|
|
+ // Purpur start - Ridables
|
|
+ if (mob.getRider() != null && mob.isControllable()) {
|
|
+ flyingController.purpurTick(mob.getRider());
|
|
+ return;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
if (this.mob.getY() <= Bee.this.level().getMinY()) {
|
|
this.mob.setNoGravity(false);
|
|
}
|
|
super.tick();
|
|
}
|
|
+
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean hasWanted() {
|
|
+ return mob.getRider() != null || !mob.isControllable() || super.hasWanted();
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
}
|
|
this.moveControl = new BeeFlyingMoveControl(this, 20, true);
|
|
// Paper end - Fix MC-167279
|
|
@@ -176,6 +190,40 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
|
this.setPathfindingMalus(PathType.FENCE, -1.0F);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.beeRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.beeRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.beeControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public double getMaxY() {
|
|
+ return level().purpurConfig.beeMaxY;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void travel(Vec3 vec3) {
|
|
+ super.travel(vec3);
|
|
+ if (getRider() != null && this.isControllable() && !onGround) {
|
|
+ float speed = (float) getAttributeValue(Attributes.FLYING_SPEED) * 2;
|
|
+ setSpeed(speed);
|
|
+ Vec3 mot = getDeltaMovement();
|
|
+ move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, speed, speed));
|
|
+ setDeltaMovement(mot.scale(0.9D));
|
|
+ }
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void defineSynchedData(SynchedEntityData.Builder builder) {
|
|
super.defineSynchedData(builder);
|
|
@@ -190,6 +238,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.4F, true));
|
|
this.goalSelector.addGoal(1, new Bee.BeeEnterHiveGoal());
|
|
this.goalSelector.addGoal(2, new BreedGoal(this, 1.0));
|
|
@@ -207,6 +256,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(2, new Bee.BeeBecomeAngryTargetGoal(this));
|
|
this.targetSelector.addGoal(3, new ResetUniversalAngerTargetGoal<>(this, true));
|
|
@@ -1088,15 +1138,15 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
|
}
|
|
}
|
|
|
|
- class BeeLookControl extends LookControl {
|
|
+ class BeeLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - Ridables
|
|
BeeLookControl(final Mob mob) {
|
|
super(mob);
|
|
}
|
|
|
|
@Override
|
|
- public void tick() {
|
|
+ public void vanillaTick() { // Purpur - Ridables
|
|
if (!Bee.this.isAngry()) {
|
|
- super.tick();
|
|
+ super.vanillaTick(); // Purpur - Ridables
|
|
}
|
|
}
|
|
|
|
diff --git a/net/minecraft/world/entity/animal/Cat.java b/net/minecraft/world/entity/animal/Cat.java
|
|
index 5b9d8c85f91396287b0deb4deac30e2c136cc461..a960c3a4854f7d2343747d463d1d505b2e39d16b 100644
|
|
--- a/net/minecraft/world/entity/animal/Cat.java
|
|
+++ b/net/minecraft/world/entity/animal/Cat.java
|
|
@@ -92,10 +92,36 @@ public class Cat extends TamableAnimal {
|
|
this.reassessTameGoals();
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.catRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.catRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.catControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onMount(Player rider) {
|
|
+ super.onMount(rider);
|
|
+ setInSittingPose(false);
|
|
+ setLying(false);
|
|
+ setRelaxStateOne(false);
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void registerGoals() {
|
|
this.temptGoal = new Cat.CatTemptGoal(this, 0.6, stack -> stack.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.5));
|
|
this.goalSelector.addGoal(2, new SitWhenOrderedToGoal(this));
|
|
this.goalSelector.addGoal(3, new Cat.CatRelaxOnOwnerGoal(this));
|
|
@@ -108,6 +134,7 @@ public class Cat extends TamableAnimal {
|
|
this.goalSelector.addGoal(10, new BreedGoal(this, 0.8));
|
|
this.goalSelector.addGoal(11, new WaterAvoidingRandomStrollGoal(this, 0.8, 1.0000001E-5F));
|
|
this.goalSelector.addGoal(12, new LookAtPlayerGoal(this, Player.class, 10.0F));
|
|
+ this.targetSelector.addGoal(1, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
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));
|
|
}
|
|
@@ -374,6 +401,7 @@ public class Cat extends TamableAnimal {
|
|
|
|
@Override
|
|
public InteractionResult mobInteract(Player player, InteractionHand hand) {
|
|
+ if (getRider() != null) return InteractionResult.PASS; // Purpur - Ridables
|
|
ItemStack itemInHand = player.getItemInHand(hand);
|
|
Item item = itemInHand.getItem();
|
|
if (this.isTame()) {
|
|
diff --git a/net/minecraft/world/entity/animal/Chicken.java b/net/minecraft/world/entity/animal/Chicken.java
|
|
index da408c313d898413dee928e9c80501ddf56d75e8..26732fde9894816cb83ba1249b2ac9b47e2b639b 100644
|
|
--- a/net/minecraft/world/entity/animal/Chicken.java
|
|
+++ b/net/minecraft/world/entity/animal/Chicken.java
|
|
@@ -72,9 +72,27 @@ public class Chicken extends Animal {
|
|
this.setPathfindingMalus(PathType.WATER, 0.0F);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.chickenRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.chickenRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.chickenControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@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(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 75509be5b9162c1f7f91f2290ef2d80171ae61df..651c9243902e3c48fb438913974e996d67d6f746 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(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.codRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.codControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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 176425cbacea381990386d440059b768a583af98..802c536659d45d0974fe788535ca326b86f90551 100644
|
|
--- a/net/minecraft/world/entity/animal/Cow.java
|
|
+++ b/net/minecraft/world/entity/animal/Cow.java
|
|
@@ -29,6 +29,23 @@ public class Cow extends AbstractCow {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.cowRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.cowRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.cowControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void defineSynchedData(SynchedEntityData.Builder builder) {
|
|
super.defineSynchedData(builder);
|
|
diff --git a/net/minecraft/world/entity/animal/Dolphin.java b/net/minecraft/world/entity/animal/Dolphin.java
|
|
index 1386ba68ae768af5593c066b4a0acc7f62239290..ecd4dbcfc7f568722488c0894a98db68bb07ead9 100644
|
|
--- a/net/minecraft/world/entity/animal/Dolphin.java
|
|
+++ b/net/minecraft/world/entity/animal/Dolphin.java
|
|
@@ -75,14 +75,82 @@ public class Dolphin extends AgeableWaterCreature {
|
|
@Nullable
|
|
public BlockPos treasurePos;
|
|
private boolean isNaturallyAggressiveToPlayers; // Purpur - Dolphins naturally aggressive to players chance
|
|
+ private int spitCooldown; // Purpur - Ridables
|
|
|
|
public Dolphin(EntityType<? extends Dolphin> 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 {
|
|
+ private final org.purpurmc.purpur.controller.WaterMoveControllerWASD waterMoveControllerWASD;
|
|
+ private final Dolphin dolphin;
|
|
+
|
|
+ public DolphinMoveControl(Dolphin dolphin, int pitchChange, int yawChange, float speedInWater, float speedInAir, boolean buoyant) {
|
|
+ super(dolphin, pitchChange, yawChange, speedInWater, speedInAir, buoyant);
|
|
+ this.dolphin = dolphin;
|
|
+ this.waterMoveControllerWASD = new org.purpurmc.purpur.controller.WaterMoveControllerWASD(dolphin);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void tick() {
|
|
+ if (dolphin.getRider() != null && dolphin.isControllable()) {
|
|
+ purpurTick(dolphin.getRider());
|
|
+ } else {
|
|
+ super.tick();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void purpurTick(Player rider) {
|
|
+ if (dolphin.getAirSupply() < 150) {
|
|
+ // if drowning override player WASD controls to find air
|
|
+ super.tick();
|
|
+ } else {
|
|
+ waterMoveControllerWASD.purpurTick(rider);
|
|
+ dolphin.setDeltaMovement(dolphin.getDeltaMovement().add(0.0D, 0.005D, 0.0D));
|
|
+ }
|
|
+ }
|
|
+ };
|
|
+ this.moveControl = new DolphinMoveControl(this, 85, 10, 0.02F, 0.1F, true);
|
|
+ // Purpur end - Ridables
|
|
this.lookControl = new SmoothSwimmingLookControl(this, 10);
|
|
this.setCanPickUpLoot(true);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.dolphinRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.dolphinControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean onSpacebar() {
|
|
+ if (spitCooldown == 0 && getRider() != null) {
|
|
+ spitCooldown = level().purpurConfig.dolphinSpitCooldown;
|
|
+
|
|
+ org.bukkit.craftbukkit.entity.CraftPlayer player = (org.bukkit.craftbukkit.entity.CraftPlayer) getRider().getBukkitEntity();
|
|
+ if (!player.hasPermission("allow.special.dolphin")) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ org.bukkit.Location loc = player.getEyeLocation();
|
|
+ loc.setPitch(loc.getPitch() - 10);
|
|
+ org.bukkit.util.Vector target = loc.getDirection().normalize().multiply(10).add(loc.toVector());
|
|
+
|
|
+ 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);
|
|
+ playSound(SoundEvents.DOLPHIN_ATTACK, 1.0F, 1.0F + (random.nextFloat() - random.nextFloat()) * 0.2F);
|
|
+ return true;
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Nullable
|
|
@Override
|
|
public SpawnGroupData finalizeSpawn(
|
|
@@ -159,6 +227,7 @@ public class Dolphin extends AgeableWaterCreature {
|
|
this.goalSelector.addGoal(0, new BreathAirGoal(this));
|
|
this.goalSelector.addGoal(0, new TryFindWaterGoal(this));
|
|
this.goalSelector.addGoal(1, new MeleeAttackGoal(this, 1.2000000476837158D, true)); // Purpur - Dolphins naturally aggressive to players chance
|
|
+ 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.0));
|
|
this.goalSelector.addGoal(4, new RandomSwimmingGoal(this, 1.0, 10));
|
|
@@ -169,6 +238,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.0, 1.0));
|
|
+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Guardian.class).setAlertOthers());
|
|
this.targetSelector.addGoal(2, new net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (ignored, ignored2) -> isNaturallyAggressiveToPlayers)); // Purpur - Dolphins naturally aggressive to players chance
|
|
}
|
|
@@ -214,7 +284,7 @@ public class Dolphin extends AgeableWaterCreature {
|
|
|
|
@Override
|
|
protected boolean canRide(Entity entity) {
|
|
- return true;
|
|
+ return boardingCooldown <= 0; // Purpur - make dolphin honor ride cooldown like all other non-boss mobs;
|
|
}
|
|
|
|
@Override
|
|
@@ -243,6 +313,11 @@ public class Dolphin extends AgeableWaterCreature {
|
|
@Override
|
|
public void tick() {
|
|
super.tick();
|
|
+ // Purpur start - Ridables
|
|
+ if (spitCooldown > 0) {
|
|
+ spitCooldown--;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
if (this.isNoAi()) {
|
|
this.setAirSupply(this.getMaxAirSupply());
|
|
} else {
|
|
diff --git a/net/minecraft/world/entity/animal/Fox.java b/net/minecraft/world/entity/animal/Fox.java
|
|
index defdacce68e59b038b919b597df17d1aae366b51..4d2b6a34c0c276ef304916b2b84c92a516fe4979 100644
|
|
--- a/net/minecraft/world/entity/animal/Fox.java
|
|
+++ b/net/minecraft/world/entity/animal/Fox.java
|
|
@@ -142,6 +142,44 @@ public class Fox extends Animal {
|
|
this.getNavigation().setRequiredPathLength(32.0F);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.foxRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.foxRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.foxControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public float getJumpPower() {
|
|
+ return getRider() != null && this.isControllable() ? 0.5F : super.getJumpPower();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onMount(Player rider) {
|
|
+ super.onMount(rider);
|
|
+ setCanPickUpLoot(false);
|
|
+ clearStates();
|
|
+ setIsPouncing(false);
|
|
+ spitOutItem(getItemBySlot(EquipmentSlot.MAINHAND));
|
|
+ setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onDismount(Player rider) {
|
|
+ super.onDismount(rider);
|
|
+ setCanPickUpLoot(true);
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void defineSynchedData(SynchedEntityData.Builder builder) {
|
|
super.defineSynchedData(builder);
|
|
@@ -161,6 +199,7 @@ public class Fox extends Animal {
|
|
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.2));
|
|
@@ -186,6 +225,7 @@ public class Fox extends Animal {
|
|
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,
|
|
@@ -1115,15 +1155,15 @@ public class Fox extends Animal {
|
|
}
|
|
}
|
|
|
|
- public class FoxLookControl extends LookControl {
|
|
+ public class FoxLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - Ridables
|
|
public FoxLookControl() {
|
|
super(Fox.this);
|
|
}
|
|
|
|
@Override
|
|
- public void tick() {
|
|
+ public void vanillaTick() { // Purpur - Ridables
|
|
if (!Fox.this.isSleeping()) {
|
|
- super.tick();
|
|
+ super.vanillaTick(); // Purpur - Ridables
|
|
}
|
|
}
|
|
|
|
@@ -1159,15 +1199,15 @@ public class Fox extends Animal {
|
|
}
|
|
}
|
|
|
|
- class FoxMoveControl extends MoveControl {
|
|
+ class FoxMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables
|
|
public FoxMoveControl() {
|
|
super(Fox.this);
|
|
}
|
|
|
|
@Override
|
|
- public void tick() {
|
|
+ public void vanillaTick() { // Purpur - Ridables
|
|
if (Fox.this.canMove()) {
|
|
- super.tick();
|
|
+ super.vanillaTick(); // Purpur - Ridables
|
|
}
|
|
}
|
|
}
|
|
diff --git a/net/minecraft/world/entity/animal/HappyGhast.java b/net/minecraft/world/entity/animal/HappyGhast.java
|
|
index 4d13d33fc40e42fe924f8aeca737e15b9a4ee136..390b929a2d71df840febb081e68f675972db0fa4 100644
|
|
--- a/net/minecraft/world/entity/animal/HappyGhast.java
|
|
+++ b/net/minecraft/world/entity/animal/HappyGhast.java
|
|
@@ -125,6 +125,13 @@ public class HappyGhast extends Animal {
|
|
this.removeAllGoals(goal -> true);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.happyGhastRidableInWater;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void ageBoundaryReached() {
|
|
if (this.isBaby()) {
|
|
diff --git a/net/minecraft/world/entity/animal/IronGolem.java b/net/minecraft/world/entity/animal/IronGolem.java
|
|
index b449c1cf9966fadb58a93c8895cddc16920fbb17..febe8b7b6a29f34fda685d1ab467dbf168d998c3 100644
|
|
--- a/net/minecraft/world/entity/animal/IronGolem.java
|
|
+++ b/net/minecraft/world/entity/animal/IronGolem.java
|
|
@@ -75,9 +75,28 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
|
|
}
|
|
// Purpur end - Summoner API
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.ironGolemRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.ironGolemRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.ironGolemControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void registerGoals() {
|
|
if (this.level().purpurConfig.ironGolemPoppyCalm) this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.ReceiveFlower(this)); // Purpur - Iron golem calm anger options
|
|
+ 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.0, true));
|
|
this.goalSelector.addGoal(2, new MoveTowardsTargetGoal(this, 0.9, 32.0F));
|
|
this.goalSelector.addGoal(2, new MoveBackToVillageGoal(this, 0.6, false));
|
|
@@ -85,6 +104,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));
|
|
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt));
|
|
@@ -273,12 +293,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 health = this.getHealth();
|
|
this.heal(25.0F);
|
|
if (this.getHealth() == health) {
|
|
- return InteractionResult.PASS;
|
|
+ return tryRide(player, hand); // Purpur - Ridables
|
|
} else {
|
|
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 a3e2aea5de34809220979cb14b70261acae49bfa..cd13cff73e4a882a7d9aa246bfdf0c7ade99d987 100644
|
|
--- a/net/minecraft/world/entity/animal/MushroomCow.java
|
|
+++ b/net/minecraft/world/entity/animal/MushroomCow.java
|
|
@@ -63,6 +63,23 @@ public class MushroomCow extends AbstractCow implements Shearable {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.mooshroomRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.mooshroomRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.mooshroomControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
public float getWalkTargetValue(BlockPos pos, LevelReader level) {
|
|
return level.getBlockState(pos.below()).is(Blocks.MYCELIUM) ? 10.0F : level.getPathfindingCostFromLightLevels(pos);
|
|
@@ -123,7 +140,7 @@ public class MushroomCow extends AbstractCow implements Shearable {
|
|
java.util.List<ItemStack> 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;
|
|
+ if (event.isCancelled()) return tryRide(player, hand); // Purpur - Ridables
|
|
drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
|
|
// Paper end - custom shear drops
|
|
}
|
|
diff --git a/net/minecraft/world/entity/animal/Ocelot.java b/net/minecraft/world/entity/animal/Ocelot.java
|
|
index 3b29ad366586b12a61bf7bd4c2f8417773cf2f27..0340813f71980d2c48853a68b37d353cd50a28cb 100644
|
|
--- a/net/minecraft/world/entity/animal/Ocelot.java
|
|
+++ b/net/minecraft/world/entity/animal/Ocelot.java
|
|
@@ -64,6 +64,23 @@ public class Ocelot extends Animal {
|
|
this.reassessTrustingGoals();
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.ocelotRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.ocelotRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.ocelotControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public boolean isTrusting() {
|
|
return this.entityData.get(DATA_TRUSTING);
|
|
}
|
|
@@ -95,12 +112,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.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 3da6752ba714988a6558332e4eb205db9cf31f5b..65874fa6b80f5d0953317629ff997fafec68f66d 100644
|
|
--- a/net/minecraft/world/entity/animal/Panda.java
|
|
+++ b/net/minecraft/world/entity/animal/Panda.java
|
|
@@ -107,6 +107,32 @@ public class Panda extends Animal {
|
|
}
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.pandaRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.pandaRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.pandaControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onMount(Player rider) {
|
|
+ super.onMount(rider);
|
|
+ setForwardMot(0.0F);
|
|
+ sit(false);
|
|
+ eat(false);
|
|
+ setOnBack(false);
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected boolean canDispenserEquipIntoSlot(EquipmentSlot slot) {
|
|
return slot == EquipmentSlot.MAINHAND && this.canPickUpLoot();
|
|
@@ -260,6 +286,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.0));
|
|
this.goalSelector.addGoal(2, new Panda.PandaBreedGoal(this, 1.0));
|
|
this.goalSelector.addGoal(3, new Panda.PandaAttackGoal(this, 1.2F, true));
|
|
@@ -275,6 +302,7 @@ public class Panda extends Animal {
|
|
this.goalSelector.addGoal(12, new Panda.PandaRollGoal(this));
|
|
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).setAlertOthers(new Class[0]));
|
|
}
|
|
|
|
@@ -618,7 +646,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;
|
|
@@ -654,7 +682,7 @@ public class Panda extends Animal {
|
|
|
|
return InteractionResult.SUCCESS_SERVER;
|
|
} else {
|
|
- return InteractionResult.PASS;
|
|
+ return tryRide(player, hand); // Purpur - Ridables
|
|
}
|
|
}
|
|
|
|
@@ -962,7 +990,7 @@ public class Panda extends Animal {
|
|
}
|
|
}
|
|
|
|
- static class PandaMoveControl extends MoveControl {
|
|
+ static class PandaMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables
|
|
private final Panda panda;
|
|
|
|
public PandaMoveControl(Panda mob) {
|
|
@@ -971,9 +999,9 @@ public class Panda extends Animal {
|
|
}
|
|
|
|
@Override
|
|
- public void tick() {
|
|
+ public void vanillaTick() { // Purpur - Ridables
|
|
if (this.panda.canPerformAction()) {
|
|
- super.tick();
|
|
+ super.vanillaTick(); // Purpur - Ridables
|
|
}
|
|
}
|
|
}
|
|
diff --git a/net/minecraft/world/entity/animal/Parrot.java b/net/minecraft/world/entity/animal/Parrot.java
|
|
index 9029eed9a5e578a7fa216cbfa084b3cf7622eebc..60e1810f91c086debb4ada192720398834c8ca84 100644
|
|
--- a/net/minecraft/world/entity/animal/Parrot.java
|
|
+++ b/net/minecraft/world/entity/animal/Parrot.java
|
|
@@ -131,12 +131,68 @@ public class Parrot extends ShoulderRidingEntity implements FlyingAnimal {
|
|
|
|
public Parrot(EntityType<? extends Parrot> 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);
|
|
+ class ParrotMoveControl extends FlyingMoveControl {
|
|
+ public ParrotMoveControl(Mob entity, int maxPitchChange, boolean noGravity) {
|
|
+ super(entity, maxPitchChange, noGravity);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void tick() {
|
|
+ if (mob.getRider() != null && mob.isControllable()) {
|
|
+ flyingController.purpurTick(mob.getRider());
|
|
+ } else {
|
|
+ super.tick();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean hasWanted() {
|
|
+ return mob.getRider() != null && mob.isControllable() ? getForwardMot() != 0 || getStrafeMot() != 0 : super.hasWanted();
|
|
+ }
|
|
+ }
|
|
+ this.moveControl = new ParrotMoveControl(this, 10, false);
|
|
+ // Purpur end - Ridables
|
|
this.setPathfindingMalus(PathType.DANGER_FIRE, -1.0F);
|
|
this.setPathfindingMalus(PathType.DAMAGE_FIRE, -1.0F);
|
|
this.setPathfindingMalus(PathType.COCOA, -1.0F);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.parrotRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.parrotRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.parrotControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public double getMaxY() {
|
|
+ return level().purpurConfig.parrotMaxY;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void travel(Vec3 vec3) {
|
|
+ super.travel(vec3);
|
|
+ if (getRider() != null && this.isControllable() && !onGround) {
|
|
+ float speed = (float) getAttributeValue(Attributes.FLYING_SPEED) * 2;
|
|
+ setSpeed(speed);
|
|
+ Vec3 mot = getDeltaMovement();
|
|
+ move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, 0.25, speed));
|
|
+ setDeltaMovement(mot.scale(0.9D));
|
|
+ }
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Nullable
|
|
@Override
|
|
public SpawnGroupData finalizeSpawn(
|
|
@@ -157,9 +213,11 @@ public class Parrot extends ShoulderRidingEntity implements FlyingAnimal {
|
|
|
|
@Override
|
|
protected void registerGoals() {
|
|
- this.goalSelector.addGoal(0, new TamableAnimal.TamableAnimalPanicGoal(1.25));
|
|
+ //this.goalSelector.addGoal(0, new TamableAnimal.TamableAnimalPanicGoal(1.25)); // Purpur - move down
|
|
this.goalSelector.addGoal(0, new FloatGoal(this));
|
|
if (this.level().purpurConfig.parrotBreedable) this.goalSelector.addGoal(1, new net.minecraft.world.entity.ai.goal.BreedGoal(this, 1.0D)); // Purpur - Breedable parrots
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
+ this.goalSelector.addGoal(1, new TamableAnimal.TamableAnimalPanicGoal(1.25D)); // Purpur - Ridables
|
|
this.goalSelector.addGoal(1, new LookAtPlayerGoal(this, Player.class, 8.0F));
|
|
this.goalSelector.addGoal(2, new SitWhenOrderedToGoal(this));
|
|
this.goalSelector.addGoal(2, new FollowOwnerGoal(this, 1.0, 5.0F, 1.0F));
|
|
diff --git a/net/minecraft/world/entity/animal/Pig.java b/net/minecraft/world/entity/animal/Pig.java
|
|
index 9366bb9b0c297f6c914be6001cfaa070e0cb2d7b..70c9629e6f1f82f44e14487ed3c81e391d480029 100644
|
|
--- a/net/minecraft/world/entity/animal/Pig.java
|
|
+++ b/net/minecraft/world/entity/animal/Pig.java
|
|
@@ -66,9 +66,27 @@ public class Pig extends Animal implements ItemSteerable {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.pigRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.pigRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.pigControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@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(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 8e6168ddfc3c1b335bee035dec5ae55ab358c778..b0f1c80465b3e4dd8ff220209df8a00f60ede84a 100644
|
|
--- a/net/minecraft/world/entity/animal/PolarBear.java
|
|
+++ b/net/minecraft/world/entity/animal/PolarBear.java
|
|
@@ -60,6 +60,7 @@ public class PolarBear extends Animal implements NeutralMob {
|
|
private int remainingPersistentAngerTime;
|
|
@Nullable
|
|
private UUID persistentAngerTarget;
|
|
+ private int standTimer = 0; // Purpur - Ridables
|
|
|
|
public PolarBear(EntityType<? extends PolarBear> entityType, Level level) {
|
|
super(entityType, level);
|
|
@@ -88,6 +89,34 @@ public class PolarBear extends Animal implements NeutralMob {
|
|
}
|
|
// Purpur end - Breedable Polar Bears
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.polarBearRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.polarBearRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.polarBearControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean onSpacebar() {
|
|
+ if (!isStanding()) {
|
|
+ if (getRider() != null && getRider().getForwardMot() == 0 && getRider().getStrafeMot() == 0) {
|
|
+ setStanding(true);
|
|
+ playSound(SoundEvents.POLAR_BEAR_WARNING, 1.0F, 1.0F);
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Nullable
|
|
@Override
|
|
public AgeableMob getBreedOffspring(ServerLevel level, AgeableMob otherParent) {
|
|
@@ -103,6 +132,7 @@ 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, mob -> mob.isBaby() ? DamageTypeTags.PANIC_CAUSES : DamageTypeTags.PANIC_ENVIRONMENTAL_CAUSES));
|
|
// Purpur start - Breedable Polar Bears
|
|
@@ -115,6 +145,7 @@ public class PolarBear extends Animal implements NeutralMob {
|
|
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));
|
|
+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
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));
|
|
@@ -233,6 +264,12 @@ public class PolarBear extends Animal implements NeutralMob {
|
|
if (!this.level().isClientSide()) {
|
|
this.updatePersistentAnger((ServerLevel)this.level(), true);
|
|
}
|
|
+
|
|
+ // Purpur start - Ridables
|
|
+ if (isStanding() && --standTimer <= 0) {
|
|
+ setStanding(false);
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
}
|
|
|
|
@Override
|
|
@@ -252,6 +289,7 @@ public class PolarBear extends Animal implements NeutralMob {
|
|
|
|
public void setStanding(boolean standing) {
|
|
this.entityData.set(DATA_STANDING_ID, standing);
|
|
+ standTimer = standing ? 20 : -1; // Purpur - Ridables
|
|
}
|
|
|
|
public float getStandingAnimationScale(float partialTick) {
|
|
diff --git a/net/minecraft/world/entity/animal/Pufferfish.java b/net/minecraft/world/entity/animal/Pufferfish.java
|
|
index de7d1fd5a55c7b2b9cd9fc87959931232a1037d6..7c2d200165111e0a6fb804157074a28322304d95 100644
|
|
--- a/net/minecraft/world/entity/animal/Pufferfish.java
|
|
+++ b/net/minecraft/world/entity/animal/Pufferfish.java
|
|
@@ -47,6 +47,18 @@ public class Pufferfish extends AbstractFish {
|
|
this.refreshDimensions();
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.pufferfishRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.pufferfishControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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 c500caf43b458ea7cb0c7b6ac942e1f01648724e..daab94acd64b75ee19d582014eacfe4944aeda55 100644
|
|
--- a/net/minecraft/world/entity/animal/Rabbit.java
|
|
+++ b/net/minecraft/world/entity/animal/Rabbit.java
|
|
@@ -91,6 +91,7 @@ public class Rabbit extends Animal {
|
|
private boolean wasOnGround;
|
|
private int jumpDelayTicks;
|
|
public int moreCarrotTicks = 0;
|
|
+ private boolean actualJump; // Purpur - Ridables
|
|
|
|
public Rabbit(EntityType<? extends Rabbit> entityType, Level level) {
|
|
super(entityType, level);
|
|
@@ -99,9 +100,55 @@ public class Rabbit extends Animal {
|
|
//this.setSpeedModifier(0.0); // CraftBukkit
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.rabbitRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.rabbitRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.rabbitControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean onSpacebar() {
|
|
+ if (onGround) {
|
|
+ actualJump = true;
|
|
+ jumpFromGround();
|
|
+ actualJump = false;
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ private void handleJumping() {
|
|
+ if (onGround) {
|
|
+ RabbitJumpControl jumpController = (RabbitJumpControl) jumpControl;
|
|
+ if (!wasOnGround) {
|
|
+ setJumping(false);
|
|
+ jumpController.setCanJump(false);
|
|
+ }
|
|
+ if (!jumpController.wantJump()) {
|
|
+ if (moveControl.hasWanted()) {
|
|
+ startJumping();
|
|
+ }
|
|
+ } else if (!jumpController.canJump()) {
|
|
+ jumpController.setCanJump(true);
|
|
+ }
|
|
+ }
|
|
+ wasOnGround = onGround;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
public 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(1, new ClimbOnTopOfPowderSnowGoal(this, this.level()));
|
|
this.goalSelector.addGoal(1, new Rabbit.RabbitPanicGoal(this, 2.2));
|
|
this.goalSelector.addGoal(2, new BreedGoal(this, 0.8));
|
|
@@ -116,6 +163,14 @@ public class Rabbit extends Animal {
|
|
|
|
@Override
|
|
protected float getJumpPower() {
|
|
+ // Purpur start - Ridables
|
|
+ if (getRider() != null && this.isControllable()) {
|
|
+ if (getForwardMot() < 0) {
|
|
+ setSpeed(getForwardMot() * 2F);
|
|
+ }
|
|
+ return actualJump ? 0.5F : 0.3F;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
float f = 0.3F;
|
|
if (this.moveControl.getSpeedModifier() <= 0.6) {
|
|
f = 0.2F;
|
|
@@ -183,6 +238,12 @@ public class Rabbit extends Animal {
|
|
|
|
@Override
|
|
public void customServerAiStep(ServerLevel level) {
|
|
+ // Purpur start - Ridables
|
|
+ if (getRider() != null && this.isControllable()) {
|
|
+ handleJumping();
|
|
+ return;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
if (this.jumpDelayTicks > 0) {
|
|
this.jumpDelayTicks--;
|
|
}
|
|
@@ -511,7 +572,7 @@ public class Rabbit extends Animal {
|
|
}
|
|
}
|
|
|
|
- static class RabbitMoveControl extends MoveControl {
|
|
+ static class RabbitMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables
|
|
private final Rabbit rabbit;
|
|
private double nextJumpSpeed;
|
|
|
|
@@ -521,14 +582,14 @@ public class Rabbit extends Animal {
|
|
}
|
|
|
|
@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.0);
|
|
} else if (this.hasWanted() || this.operation == MoveControl.Operation.JUMPING) {
|
|
this.rabbit.setSpeedModifier(this.nextJumpSpeed);
|
|
}
|
|
|
|
- super.tick();
|
|
+ super.vanillaTick(); // Purpur - Ridables
|
|
}
|
|
|
|
@Override
|
|
diff --git a/net/minecraft/world/entity/animal/Salmon.java b/net/minecraft/world/entity/animal/Salmon.java
|
|
index 8a3e1d420263ac53b87ffed026380dcdc4a48285..265b2a6db778cabc1a97726c22c991051e3007fe 100644
|
|
--- a/net/minecraft/world/entity/animal/Salmon.java
|
|
+++ b/net/minecraft/world/entity/animal/Salmon.java
|
|
@@ -39,6 +39,18 @@ public class Salmon extends AbstractSchoolingFish {
|
|
this.refreshDimensions();
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.salmonRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.salmonControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
public int getMaxSchoolSize() {
|
|
return 5;
|
|
diff --git a/net/minecraft/world/entity/animal/SnowGolem.java b/net/minecraft/world/entity/animal/SnowGolem.java
|
|
index 55e751c12cd3c9a87834fdd1367a75c46ccaf05d..6d0d1bb14b64d2a176db6a74f3a5ff0fa78a5434 100644
|
|
--- a/net/minecraft/world/entity/animal/SnowGolem.java
|
|
+++ b/net/minecraft/world/entity/animal/SnowGolem.java
|
|
@@ -63,12 +63,31 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
|
|
}
|
|
// Purpur end - Summoner API
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.snowGolemRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.snowGolemRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.snowGolemControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@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, level().purpurConfig.snowGolemAttackDistance, level().purpurConfig.snowGolemSnowBallMin, level().purpurConfig.snowGolemSnowBallMax, level().purpurConfig.snowGolemSnowBallModifier)); // Purpur - Snow Golem rate of fire config
|
|
this.goalSelector.addGoal(2, new WaterAvoidingRandomStrollGoal(this, 1.0D, 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, (entity, level) -> entity instanceof Enemy));
|
|
}
|
|
|
|
@@ -113,6 +132,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 blockState = Blocks.SNOW.defaultBlockState();
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
@@ -155,7 +175,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
|
|
@@ -176,7 +196,7 @@ public class SnowGolem extends AbstractGolem implements Shearable, RangedAttackM
|
|
return InteractionResult.SUCCESS;
|
|
// Purpur end - Snowman drop and put back pumpkin
|
|
} else {
|
|
- return InteractionResult.PASS;
|
|
+ return tryRide(player, hand); // Purpur - Ridables
|
|
}
|
|
}
|
|
|
|
diff --git a/net/minecraft/world/entity/animal/Squid.java b/net/minecraft/world/entity/animal/Squid.java
|
|
index f8b4a97cf0558dcf1fc4916a38867f97f0dca868..438765bc5799dff8b9cfd6fa77808712e6ada9b2 100644
|
|
--- a/net/minecraft/world/entity/animal/Squid.java
|
|
+++ b/net/minecraft/world/entity/animal/Squid.java
|
|
@@ -69,9 +69,32 @@ public class Squid extends AgeableWaterCreature {
|
|
}
|
|
// Purpur end - Flying squids! Oh my!
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.squidRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.squidControllable;
|
|
+ }
|
|
+
|
|
+ protected static void rotateVectorAroundY(org.bukkit.util.Vector vector, double degrees) {
|
|
+ double rad = Math.toRadians(degrees);
|
|
+ double cos = Math.cos(rad);
|
|
+ double sine = Math.sin(rad);
|
|
+ double x = vector.getX();
|
|
+ double z = vector.getZ();
|
|
+ vector.setX(cos * x - sine * z);
|
|
+ vector.setZ(sine * x + cos * z);
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void registerGoals() {
|
|
this.goalSelector.addGoal(0, new Squid.SquidRandomMovementGoal(this));
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
this.goalSelector.addGoal(1, new Squid.SquidFleeGoal());
|
|
}
|
|
|
|
@@ -325,6 +348,37 @@ public class Squid extends AgeableWaterCreature {
|
|
|
|
@Override
|
|
public void tick() {
|
|
+ // Purpur start - Ridables
|
|
+ net.minecraft.world.entity.player.Player rider = squid.getRider();
|
|
+ if (rider != null && squid.isControllable()) {
|
|
+ if (rider.jumping) {
|
|
+ squid.onSpacebar();
|
|
+ }
|
|
+ float forward = rider.getForwardMot();
|
|
+ float strafe = rider.getStrafeMot();
|
|
+ float speed = (float) squid.getAttributeValue(Attributes.MOVEMENT_SPEED) * 10F;
|
|
+ if (forward < 0.0F) {
|
|
+ speed *= -0.5;
|
|
+ }
|
|
+ org.bukkit.util.Vector dir = rider.getBukkitEntity().getEyeLocation().getDirection().normalize().multiply(speed / 20.0F);
|
|
+ if (strafe != 0.0F) {
|
|
+ if (forward == 0.0F) {
|
|
+ dir.setY(0);
|
|
+ rotateVectorAroundY(dir, strafe > 0.0F ? -90 : 90);
|
|
+ } else if (forward < 0.0F) {
|
|
+ rotateVectorAroundY(dir, strafe > 0.0F ? 45 : -45);
|
|
+ } else {
|
|
+ rotateVectorAroundY(dir, strafe > 0.0F ? -45 : 45);
|
|
+ }
|
|
+ }
|
|
+ if (forward != 0.0F || strafe != 0.0F) {
|
|
+ squid.movementVector = new Vec3((float) dir.getX(), (float) dir.getY(), (float) dir.getZ());
|
|
+ } else {
|
|
+ squid.movementVector = Vec3.ZERO;
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
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 806fb2561d1eb0fba56dc40ba5c1f306c3105880..cc26b929abd249536659df03a1cafbe83cde6f0f 100644
|
|
--- a/net/minecraft/world/entity/animal/TropicalFish.java
|
|
+++ b/net/minecraft/world/entity/animal/TropicalFish.java
|
|
@@ -77,6 +77,18 @@ public class TropicalFish extends AbstractSchoolingFish {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.tropicalFishRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.tropicalFishControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
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 9262bd842b4f012a68a2a99531695e51cdfaf611..542adc537723f9878a217aa3b71d67d1e4c1a8d2 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 {
|
|
this.moveControl = new Turtle.TurtleMoveControl(this);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.turtleRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.turtleRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.turtleControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public void setHomePos(BlockPos homePos) {
|
|
this.homePos = homePos;
|
|
}
|
|
@@ -145,6 +162,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.2));
|
|
this.goalSelector.addGoal(1, new Turtle.TurtleBreedGoal(this, 1.0));
|
|
this.goalSelector.addGoal(1, new Turtle.TurtleLayEggGoal(this, 1.0));
|
|
@@ -493,12 +511,14 @@ public class Turtle extends Animal {
|
|
}
|
|
}
|
|
|
|
- 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 mob) {
|
|
super(mob);
|
|
this.turtle = mob;
|
|
+ waterController = new org.purpurmc.purpur.controller.WaterMoveControllerWASD(turtle, 0.25D); // Purpur - Ridables
|
|
}
|
|
|
|
private void updateSpeed() {
|
|
@@ -517,7 +537,7 @@ public class Turtle extends Animal {
|
|
}
|
|
|
|
@Override
|
|
- public void tick() {
|
|
+ public void vanillaTick() { // Purpur - Ridables
|
|
this.updateSpeed();
|
|
if (this.operation == MoveControl.Operation.MOVE_TO && !this.turtle.getNavigation().isDone()) {
|
|
double d = this.wantedX - this.turtle.getX();
|
|
@@ -531,7 +551,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)); // Purpur - Ridables
|
|
this.turtle.setSpeed(Mth.lerp(0.125F, this.turtle.getSpeed(), f1));
|
|
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/allay/Allay.java b/net/minecraft/world/entity/animal/allay/Allay.java
|
|
index 2cd30038c9b82d074408be33447d1401de876fb8..173101a3b5bb1057adec2b5df396fd3000c028bc 100644
|
|
--- a/net/minecraft/world/entity/animal/allay/Allay.java
|
|
+++ b/net/minecraft/world/entity/animal/allay/Allay.java
|
|
@@ -113,10 +113,23 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS
|
|
private float spinningAnimationTicks;
|
|
private float spinningAnimationTicks0;
|
|
public boolean forceDancing = false; // CraftBukkit
|
|
+ private org.purpurmc.purpur.controller.FlyingMoveControllerWASD purpurController; // Purpur - Ridables
|
|
|
|
public Allay(EntityType<? extends Allay> 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);
|
|
+ this.moveControl = new FlyingMoveControl(this, 20, true) {
|
|
+ @Override
|
|
+ public void tick() {
|
|
+ if (mob.getRider() != null && mob.isControllable()) {
|
|
+ purpurController.purpurTick(mob.getRider());
|
|
+ } else {
|
|
+ super.tick();
|
|
+ }
|
|
+ }
|
|
+ };
|
|
+ // Purpur end - Ridables
|
|
this.setCanPickUpLoot(this.canPickUpLoot());
|
|
this.vibrationUser = new Allay.VibrationUser();
|
|
this.vibrationData = new VibrationSystem.Data();
|
|
@@ -132,6 +145,28 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS
|
|
}
|
|
// CraftBukkit end
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.allayRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.allayRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.allayControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void registerGoals() {
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected Brain.Provider<Allay> brainProvider() {
|
|
return Brain.provider(MEMORY_TYPES, SENSOR_TYPES);
|
|
@@ -227,6 +262,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()) // Purpur - only use brain if no rider
|
|
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 4792e7e6b720a315d64f18d9c3b12f703da8fb21..a394bc9e4de64a862acc2d33a01c1dd298bce464 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.0).add(Attributes.MOVEMENT_SPEED, 0.14);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.armadilloRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.armadilloRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.armadilloControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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 3cf26691c453aff306194b28c0610168cf75c950..d350bd4a29e3ce6196e3df9f0757ca24bd667075 100644
|
|
--- a/net/minecraft/world/entity/animal/axolotl/Axolotl.java
|
|
+++ b/net/minecraft/world/entity/animal/axolotl/Axolotl.java
|
|
@@ -121,6 +121,23 @@ public class Axolotl extends Animal implements Bucketable {
|
|
this.lookControl = new Axolotl.AxolotlLookControl(this, 20);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.axolotlRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.axolotlControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void registerGoals() {
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
public float getWalkTargetValue(BlockPos pos, LevelReader level) {
|
|
return 0.0F;
|
|
@@ -330,6 +347,7 @@ public class Axolotl extends Animal implements Bucketable {
|
|
protected void customServerAiStep(ServerLevel level) {
|
|
ProfilerFiller profilerFiller = Profiler.get();
|
|
profilerFiller.push("axolotlBrain");
|
|
+ if (getRider() == null || !this.isControllable()) // Purpur - only use brain if no rider
|
|
this.getBrain().tick(level, this);
|
|
profilerFiller.pop();
|
|
profilerFiller.push("axolotlActivityUpdate");
|
|
@@ -573,23 +591,31 @@ public class Axolotl extends Animal implements Bucketable {
|
|
}
|
|
|
|
@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
|
|
|
|
public AxolotlMoveControl(Axolotl axolotl) {
|
|
super(axolotl, 85, 10, 0.1F, 0.5F, false);
|
|
this.axolotl = axolotl;
|
|
+ waterController = new org.purpurmc.purpur.controller.WaterMoveControllerWASD(axolotl, 0.5D); // Purpur - Ridables
|
|
}
|
|
|
|
@Override
|
|
public void tick() {
|
|
+ // Purpur start - Ridables
|
|
+ if (axolotl.getRider() != null && axolotl.isControllable()) {
|
|
+ waterController.purpurTick(axolotl.getRider());
|
|
+ return;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
if (!this.axolotl.isPlayingDead()) {
|
|
super.tick();
|
|
}
|
|
diff --git a/net/minecraft/world/entity/animal/camel/Camel.java b/net/minecraft/world/entity/animal/camel/Camel.java
|
|
index 9ad94aca22a100dddaded5833763f9acd2a0ce56..96c98f032b1b3aec32aba38244ee8b45aca9078c 100644
|
|
--- a/net/minecraft/world/entity/animal/camel/Camel.java
|
|
+++ b/net/minecraft/world/entity/animal/camel/Camel.java
|
|
@@ -90,6 +90,13 @@ public class Camel extends AbstractHorse {
|
|
groundPathNavigation.setCanWalkOverFences(true);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.camelRidableInWater;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void addAdditionalSaveData(ValueOutput output) {
|
|
super.addAdditionalSaveData(output);
|
|
diff --git a/net/minecraft/world/entity/animal/coppergolem/CopperGolem.java b/net/minecraft/world/entity/animal/coppergolem/CopperGolem.java
|
|
index f9c3a33a7c5efc30a97f1ce74b94f5e6213298fe..20d2f081fa2576ea946489d3e717b389092abaef 100644
|
|
--- a/net/minecraft/world/entity/animal/coppergolem/CopperGolem.java
|
|
+++ b/net/minecraft/world/entity/animal/coppergolem/CopperGolem.java
|
|
@@ -109,6 +109,28 @@ public class CopperGolem extends AbstractGolem implements ContainerUser, Shearab
|
|
}
|
|
// Purpur end - Summoner API
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.copperGolemRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.copperGolemRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.copperGolemControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void registerGoals() {
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this));
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public static AttributeSupplier.Builder createAttributes() {
|
|
return Mob.createMobAttributes().add(Attributes.MOVEMENT_SPEED, 0.2F).add(Attributes.STEP_HEIGHT, 1.0).add(Attributes.MAX_HEALTH, 12.0);
|
|
}
|
|
@@ -199,6 +221,7 @@ public class CopperGolem extends AbstractGolem implements ContainerUser, Shearab
|
|
protected void customServerAiStep(ServerLevel level) {
|
|
ProfilerFiller profilerFiller = Profiler.get();
|
|
profilerFiller.push("copperGolemBrain");
|
|
+ if (getRider() == null || !this.isControllable()) // Purpur - only use brain if no rider
|
|
this.getBrain().tick(level, this);
|
|
profilerFiller.pop();
|
|
profilerFiller.push("copperGolemActivityUpdate");
|
|
@@ -238,7 +261,7 @@ public class CopperGolem extends AbstractGolem implements ContainerUser, Shearab
|
|
java.util.List<ItemStack> 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;
|
|
+ if (event.isCancelled()) return tryRide(player, hand); // Purpur - Ridables
|
|
drops = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getDrops());
|
|
}
|
|
this.shear(serverLevel, SoundSource.PLAYERS, itemInHand, drops);
|
|
@@ -274,6 +297,8 @@ public class CopperGolem extends AbstractGolem implements ContainerUser, Shearab
|
|
}
|
|
}
|
|
|
|
+ if (level().purpurConfig.villagerRidable && itemInHand.isEmpty()) return tryRide(player, hand); // Purpur - Ridables
|
|
+
|
|
return super.mobInteract(player, hand);
|
|
}
|
|
}
|
|
diff --git a/net/minecraft/world/entity/animal/frog/Frog.java b/net/minecraft/world/entity/animal/frog/Frog.java
|
|
index 7d63881ec187f11544947a487fd0445561228247..e451e604b37f078cb94f3204ebb25dbc153d2551 100644
|
|
--- a/net/minecraft/world/entity/animal/frog/Frog.java
|
|
+++ b/net/minecraft/world/entity/animal/frog/Frog.java
|
|
@@ -105,6 +105,8 @@ public class Frog extends Animal {
|
|
public final AnimationState croakAnimationState = new AnimationState();
|
|
public final AnimationState tongueAnimationState = new AnimationState();
|
|
public final AnimationState swimIdleAnimationState = new AnimationState();
|
|
+ private org.purpurmc.purpur.controller.MoveControllerWASD purpurLandController; // Purpur - Ridables
|
|
+ private org.purpurmc.purpur.controller.WaterMoveControllerWASD purpurWaterController; // Purpur - Ridables
|
|
|
|
public Frog(EntityType<? extends Animal> entityType, Level level) {
|
|
super(entityType, level);
|
|
@@ -112,7 +114,55 @@ public class Frog extends Animal {
|
|
this.setPathfindingMalus(PathType.WATER, 4.0F);
|
|
this.setPathfindingMalus(PathType.TRAPDOOR, -1.0F);
|
|
this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true);
|
|
+ // Purpur start - Ridables
|
|
+ this.purpurLandController = new org.purpurmc.purpur.controller.MoveControllerWASD(this, 0.2F);
|
|
+ this.purpurWaterController = new org.purpurmc.purpur.controller.WaterMoveControllerWASD(this, 0.5F);
|
|
+ this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true) {
|
|
+ @Override
|
|
+ public void tick() {
|
|
+ net.minecraft.world.entity.player.Player rider = mob.getRider();
|
|
+ if (rider != null && mob.isControllable()) {
|
|
+ if (mob.isInWater()) {
|
|
+ purpurWaterController.purpurTick(rider);
|
|
+ mob.setDeltaMovement(mob.getDeltaMovement().add(0.0D, -0.005D, 0.0D));
|
|
+ } else {
|
|
+ purpurLandController.purpurTick(rider);
|
|
+ }
|
|
+ } else {
|
|
+ super.tick();
|
|
+ }
|
|
+ }
|
|
+ };
|
|
+ // Purpur end - Ridables
|
|
+ }
|
|
+
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.frogRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.frogRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.frogControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void registerGoals() {
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public float getJumpPower() {
|
|
+ return (getRider() != null && isControllable()) ? level().purpurConfig.frogRidableJumpHeight * this.getBlockJumpFactor() : super.getJumpPower();
|
|
}
|
|
+ // Purpur end - Ridables
|
|
|
|
@Override
|
|
protected Brain.Provider<Frog> brainProvider() {
|
|
@@ -205,6 +255,7 @@ public class Frog extends Animal {
|
|
protected void customServerAiStep(ServerLevel level) {
|
|
ProfilerFiller profilerFiller = Profiler.get();
|
|
profilerFiller.push("frogBrain");
|
|
+ if (getRider() == null || !this.isControllable()) // Purpur - only use brain if no rider
|
|
this.getBrain().tick(level, this);
|
|
profilerFiller.pop();
|
|
profilerFiller.push("frogActivityUpdate");
|
|
@@ -383,7 +434,7 @@ public class Frog extends Animal {
|
|
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 mob) {
|
|
super(mob);
|
|
}
|
|
diff --git a/net/minecraft/world/entity/animal/frog/Tadpole.java b/net/minecraft/world/entity/animal/frog/Tadpole.java
|
|
index d216c2fbf2fe846c0d9b7164d24eb3815b7235ff..e2fdcc1bc0c2db5702430d593f7541840ef26337 100644
|
|
--- a/net/minecraft/world/entity/animal/frog/Tadpole.java
|
|
+++ b/net/minecraft/world/entity/animal/frog/Tadpole.java
|
|
@@ -65,13 +65,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<? extends AbstractFish> 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);
|
|
+ this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true) {
|
|
+ @Override
|
|
+ public void tick() {
|
|
+ Player rider = mob.getRider();
|
|
+ if (rider != null && mob.isControllable()) {
|
|
+ purpurController.purpurTick(rider);
|
|
+ mob.setDeltaMovement(mob.getDeltaMovement().add(0.0D, 0.002D, 0.0D));
|
|
+ } else {
|
|
+ super.tick();
|
|
+ }
|
|
+ }
|
|
+ };
|
|
+ // Purpur end - Ridables
|
|
this.lookControl = new SmoothSwimmingLookControl(this, 10);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.tadpoleRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.tadpoleRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.tadpoleControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void registerGoals() {
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected PathNavigation createNavigation(Level level) {
|
|
return new WaterBoundPathNavigation(this, level);
|
|
@@ -101,6 +138,7 @@ public class Tadpole extends AbstractFish {
|
|
protected void customServerAiStep(ServerLevel level) {
|
|
ProfilerFiller profilerFiller = Profiler.get();
|
|
profilerFiller.push("tadpoleBrain");
|
|
+ if (getRider() == null || !this.isControllable()) // Purpur - only use brain if no rider
|
|
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 76e85c905e12a56f14b1e4cf14986e0a62847b1f..ba603ac36e7fc6bee605c9f49a53d20085b0c6ee 100644
|
|
--- a/net/minecraft/world/entity/animal/goat/Goat.java
|
|
+++ b/net/minecraft/world/entity/animal/goat/Goat.java
|
|
@@ -114,6 +114,23 @@ public class Goat extends Animal {
|
|
.orElseGet(() -> new ItemStack(Items.GOAT_HORN));
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.goatRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.goatRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.goatControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected Brain.Provider<Goat> brainProvider() {
|
|
return Brain.provider(MEMORY_TYPES, SENSOR_TYPES);
|
|
@@ -191,6 +208,7 @@ public class Goat extends Animal {
|
|
protected void customServerAiStep(ServerLevel level) {
|
|
ProfilerFiller profilerFiller = Profiler.get();
|
|
profilerFiller.push("goatBrain");
|
|
+ if (getRider() == null || !this.isControllable()) // Purpur - only use brain if no rider
|
|
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 fde1f235332127f727da8491e03b54680e42ea4a..b528bd7cc2001a3c0ec1cf615a4c306a9cd7e9f1 100644
|
|
--- a/net/minecraft/world/entity/animal/horse/AbstractHorse.java
|
|
+++ b/net/minecraft/world/entity/animal/horse/AbstractHorse.java
|
|
@@ -127,11 +127,21 @@ public abstract class AbstractHorse extends Animal implements HasCustomInventory
|
|
|
|
protected AbstractHorse(EntityType<? extends AbstractHorse> 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();
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return false; // vanilla handles
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@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.2));
|
|
this.goalSelector.addGoal(1, new RunAroundLikeCrazyGoal(this, 1.2));
|
|
this.goalSelector.addGoal(2, new BreedGoal(this, 1.0, AbstractHorse.class));
|
|
@@ -142,6 +152,7 @@ public abstract class AbstractHorse extends Animal implements HasCustomInventory
|
|
if (this.canPerformRearing()) {
|
|
this.goalSelector.addGoal(9, new RandomStandGoal(this));
|
|
}
|
|
+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HorseHasRider(this)); // Purpur - Ridables
|
|
|
|
this.addBehaviourGoals();
|
|
}
|
|
diff --git a/net/minecraft/world/entity/animal/horse/Donkey.java b/net/minecraft/world/entity/animal/horse/Donkey.java
|
|
index 5dff98b5b2e4bba5f874d6a99d034a3905775c9b..66dda36aeb668488076f0c93dc83ab6cc4ec1a31 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(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.donkeyRidableInWater;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
public 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 2a1d720557c0bd4895a32723e34512c0a557e4f2..f1cb2e315e1d86f9fcd87db11d3ee7a81cfe12f6 100644
|
|
--- a/net/minecraft/world/entity/animal/horse/Horse.java
|
|
+++ b/net/minecraft/world/entity/animal/horse/Horse.java
|
|
@@ -47,6 +47,13 @@ public class Horse extends AbstractHorse {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.horseRidableInWater;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void randomizeAttributes(RandomSource random) {
|
|
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 7afb96b89a7f2b3d4155031016e51e03dd9b31ce..c3efc59c5e396c664022dd91bca143c60164fe0c 100644
|
|
--- a/net/minecraft/world/entity/animal/horse/Llama.java
|
|
+++ b/net/minecraft/world/entity/animal/horse/Llama.java
|
|
@@ -84,7 +84,58 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob {
|
|
super(entityType, level);
|
|
this.getNavigation().setRequiredPathLength(40.0F);
|
|
this.maxDomestication = 30; // Paper - Missing entity API; configure max temper instead of a hardcoded value
|
|
+ // Purpur start - Ridables
|
|
+ this.moveControl = new org.purpurmc.purpur.controller.MoveControllerWASD(this) {
|
|
+ @Override
|
|
+ public void tick() {
|
|
+ if (entity.getRider() != null && entity.isControllable() && isSaddled()) {
|
|
+ purpurTick(entity.getRider());
|
|
+ } else {
|
|
+ vanillaTick();
|
|
+ }
|
|
+ }
|
|
+ };
|
|
+ this.lookControl = new org.purpurmc.purpur.controller.LookControllerWASD(this) {
|
|
+ @Override
|
|
+ public void tick() {
|
|
+ if (entity.getRider() != null && entity.isControllable() && isSaddled()) {
|
|
+ purpurTick(entity.getRider());
|
|
+ } else {
|
|
+ vanillaTick();
|
|
+ }
|
|
+ }
|
|
+ };
|
|
+ // Purpur end - Ridables
|
|
+ }
|
|
+
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.llamaRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.llamaRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.llamaControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isSaddled() {
|
|
+ return super.isWearingBodyArmor() || this.isTamed();
|
|
+ }
|
|
+
|
|
+ @Nullable
|
|
+ @Override
|
|
+ public LivingEntity getControllingPassenger() {
|
|
+ Entity firstPassenger = this.getFirstPassenger();
|
|
+ return !this.isNoAi() && firstPassenger instanceof net.minecraft.world.entity.Mob mob && firstPassenger.canControlVehicle() ? mob : null;
|
|
}
|
|
+ // Purpur end - Ridables
|
|
|
|
public boolean isTraderLlama() {
|
|
return false;
|
|
@@ -127,6 +178,7 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob {
|
|
@Override
|
|
protected void registerGoals() {
|
|
this.goalSelector.addGoal(0, new FloatGoal(this));
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.LlamaHasRider(this)); // Purpur - Ridables
|
|
this.goalSelector.addGoal(1, new RunAroundLikeCrazyGoal(this, 1.2));
|
|
this.goalSelector.addGoal(2, new LlamaFollowCaravanGoal(this, 2.1F));
|
|
this.goalSelector.addGoal(3, new RangedAttackGoal(this, 1.25, 40, 20.0F));
|
|
@@ -137,6 +189,7 @@ public class Llama extends AbstractChestedHorse implements RangedAttackMob {
|
|
this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 0.7));
|
|
this.goalSelector.addGoal(8, new LookAtPlayerGoal(this, Player.class, 6.0F));
|
|
this.goalSelector.addGoal(9, new RandomLookAroundGoal(this));
|
|
+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.LlamaHasRider(this)); // Purpur - Ridables
|
|
this.targetSelector.addGoal(1, new Llama.LlamaHurtByTargetGoal(this));
|
|
this.targetSelector.addGoal(2, new Llama.LlamaAttackWolfGoal(this));
|
|
}
|
|
diff --git a/net/minecraft/world/entity/animal/horse/Mule.java b/net/minecraft/world/entity/animal/horse/Mule.java
|
|
index 39725b7a6bac9390406733cd51d7341d0cb363d1..b1c96936ba8dcba4435a649dd7e6ec3c921c3702 100644
|
|
--- a/net/minecraft/world/entity/animal/horse/Mule.java
|
|
+++ b/net/minecraft/world/entity/animal/horse/Mule.java
|
|
@@ -15,6 +15,13 @@ public class Mule extends AbstractChestedHorse {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.muleRidableInWater;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
public SoundEvent getAmbientSound() {
|
|
return SoundEvents.MULE_AMBIENT;
|
|
diff --git a/net/minecraft/world/entity/animal/horse/SkeletonHorse.java b/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
|
|
index 580134c5a075c7efdc7c2f86a179df2fa336eba9..ba0e483df57cc56f356282519105a2e3e77601f8 100644
|
|
--- a/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
|
|
+++ b/net/minecraft/world/entity/animal/horse/SkeletonHorse.java
|
|
@@ -42,6 +42,13 @@ public class SkeletonHorse extends AbstractHorse {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isTamed() {
|
|
+ return super.isTamed() || this.level().purpurConfig.skeletonHorseRidable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public static AttributeSupplier.Builder createAttributes() {
|
|
return createBaseHorseAttributes().add(Attributes.MAX_HEALTH, 15.0).add(Attributes.MOVEMENT_SPEED, 0.2F);
|
|
}
|
|
@@ -61,6 +68,7 @@ public class SkeletonHorse extends AbstractHorse {
|
|
|
|
@Override
|
|
protected void addBehaviourGoals() {
|
|
+ if (level().purpurConfig.skeletonHorseCanSwim) goalSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.FloatGoal(this)); // Purpur - Ridables
|
|
}
|
|
|
|
@Override
|
|
diff --git a/net/minecraft/world/entity/animal/horse/TraderLlama.java b/net/minecraft/world/entity/animal/horse/TraderLlama.java
|
|
index 37cb92e6fe2318495fc69928b01e7d63dfb313a8..626b129b54aa622267dfc2ee5ec13bb9f10d6390 100644
|
|
--- a/net/minecraft/world/entity/animal/horse/TraderLlama.java
|
|
+++ b/net/minecraft/world/entity/animal/horse/TraderLlama.java
|
|
@@ -31,6 +31,28 @@ public class TraderLlama extends Llama {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.traderLlamaRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.traderLlamaRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.traderLlamaControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isSaddled() {
|
|
+ return super.isSaddled() || isTamed();
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
public boolean isTraderLlama() {
|
|
return true;
|
|
diff --git a/net/minecraft/world/entity/animal/horse/ZombieHorse.java b/net/minecraft/world/entity/animal/horse/ZombieHorse.java
|
|
index ee327bdec37df5197c35aef60cf456bb81f8d048..45d09ebcc9ce4321285a4ec49e8ee369290f6b2c 100644
|
|
--- a/net/minecraft/world/entity/animal/horse/ZombieHorse.java
|
|
+++ b/net/minecraft/world/entity/animal/horse/ZombieHorse.java
|
|
@@ -33,6 +33,18 @@ public class ZombieHorse extends AbstractHorse {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.zombieHorseRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isTamed() {
|
|
+ return super.isTamed() || this.level().purpurConfig.zombieHorseRidable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public static AttributeSupplier.Builder createAttributes() {
|
|
return createBaseHorseAttributes().add(Attributes.MAX_HEALTH, 15.0).add(Attributes.MOVEMENT_SPEED, 0.2F);
|
|
}
|
|
@@ -78,6 +90,7 @@ public class ZombieHorse extends AbstractHorse {
|
|
|
|
@Override
|
|
protected void addBehaviourGoals() {
|
|
+ if (level().purpurConfig.zombieHorseCanSwim) goalSelector.addGoal(0, new net.minecraft.world.entity.ai.goal.FloatGoal(this)); // Purpur - Ridables
|
|
}
|
|
|
|
@Override
|
|
diff --git a/net/minecraft/world/entity/animal/sheep/Sheep.java b/net/minecraft/world/entity/animal/sheep/Sheep.java
|
|
index aa97a98cc7e87c5e23684e97bef3fdb2abc6a509..1975976c92e3acb361dcc1ec49c6ce5818173806 100644
|
|
--- a/net/minecraft/world/entity/animal/sheep/Sheep.java
|
|
+++ b/net/minecraft/world/entity/animal/sheep/Sheep.java
|
|
@@ -62,10 +62,28 @@ public class Sheep extends Animal implements Shearable {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.sheepRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.sheepRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.sheepControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void registerGoals() {
|
|
this.eatBlockGoal = new EatBlockGoal(this);
|
|
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, 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/sniffer/Sniffer.java b/net/minecraft/world/entity/animal/sniffer/Sniffer.java
|
|
index 9736ecdeefa2c8ed9f618672f2b63492cac2a6be..85a5cad5d7c4056fccf11807e6bcce5432febbc5 100644
|
|
--- a/net/minecraft/world/entity/animal/sniffer/Sniffer.java
|
|
+++ b/net/minecraft/world/entity/animal/sniffer/Sniffer.java
|
|
@@ -88,6 +88,23 @@ public class Sniffer extends Animal {
|
|
this.setPathfindingMalus(PathType.DAMAGE_CAUTIOUS, -1.0F);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.snifferRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.snifferRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.snifferControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void defineSynchedData(SynchedEntityData.Builder builder) {
|
|
super.defineSynchedData(builder);
|
|
@@ -466,6 +483,7 @@ public class Sniffer extends Animal {
|
|
protected void customServerAiStep(ServerLevel level) {
|
|
ProfilerFiller profilerFiller = Profiler.get();
|
|
profilerFiller.push("snifferBrain");
|
|
+ if (getRider() == null || !this.isControllable()) // Purpur - only use brain if no rider
|
|
this.getBrain().tick(level, this);
|
|
profilerFiller.popPush("snifferActivityUpdate");
|
|
SnifferAi.updateActivity(this);
|
|
diff --git a/net/minecraft/world/entity/animal/wolf/Wolf.java b/net/minecraft/world/entity/animal/wolf/Wolf.java
|
|
index 5bbcd6fdf7e01e1a4e94668e6a5d39e171ba4bb7..ba0f003546d70651eddb1907f33ceb549584c0ca 100644
|
|
--- a/net/minecraft/world/entity/animal/wolf/Wolf.java
|
|
+++ b/net/minecraft/world/entity/animal/wolf/Wolf.java
|
|
@@ -186,9 +186,32 @@ public class Wolf extends TamableAnimal implements NeutralMob {
|
|
}
|
|
// Purpur end - Configurable default collar color
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.wolfRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.wolfRidableInWater;
|
|
+ }
|
|
+
|
|
+ public void onMount(Player rider) {
|
|
+ super.onMount(rider);
|
|
+ setInSittingPose(false);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.wolfControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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(1, new TamableAnimal.TamableAnimalPanicGoal(1.5, DamageTypeTags.PANIC_ENVIRONMENTAL_CAUSES));
|
|
this.goalSelector.addGoal(2, new SitWhenOrderedToGoal(this));
|
|
this.goalSelector.addGoal(3, new Wolf.WolfAvoidEntityGoal<>(this, Llama.class, 24.0F, 1.5, 1.5));
|
|
@@ -201,6 +224,7 @@ public class Wolf extends TamableAnimal implements NeutralMob {
|
|
this.goalSelector.addGoal(9, new BegGoal(this, 8.0F));
|
|
this.goalSelector.addGoal(10, new LookAtPlayerGoal(this, Player.class, 8.0F));
|
|
this.goalSelector.addGoal(10, new RandomLookAroundGoal(this));
|
|
+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
this.targetSelector.addGoal(1, new OwnerHurtByTargetGoal(this));
|
|
this.targetSelector.addGoal(2, new OwnerHurtTargetGoal(this));
|
|
this.targetSelector.addGoal(3, new HurtByTargetGoal(this).setAlertOthers());
|
|
diff --git a/net/minecraft/world/entity/boss/EnderDragonPart.java b/net/minecraft/world/entity/boss/EnderDragonPart.java
|
|
index c9443cbde85109b19e6c84274c562d83a229c763..ec82bd00f7be253beac1dfbe00a36d25daa11775 100644
|
|
--- a/net/minecraft/world/entity/boss/EnderDragonPart.java
|
|
+++ b/net/minecraft/world/entity/boss/EnderDragonPart.java
|
|
@@ -28,6 +28,13 @@ public class EnderDragonPart extends Entity {
|
|
this.name = name;
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public net.minecraft.world.InteractionResult interact(net.minecraft.world.entity.player.Player player, net.minecraft.world.InteractionHand hand) {
|
|
+ return parentMob.isAlive() ? parentMob.tryRide(player, hand) : net.minecraft.world.InteractionResult.PASS;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void defineSynchedData(SynchedEntityData.Builder builder) {
|
|
}
|
|
diff --git a/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
|
index 8a2f8cefe23f7599dab9a4a8cc948772475cc0f7..c3eefe0a4a3b13e20853193450e8634c61257a0a 100644
|
|
--- a/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
|
+++ b/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
|
@@ -92,6 +92,7 @@ public class EnderDragon extends Mob implements Enemy {
|
|
private final net.minecraft.world.level.Explosion explosionSource; // Paper - reusable source for CraftTNTPrimed.getSource()
|
|
@Nullable private BlockPos podium;
|
|
// Paper end
|
|
+ private boolean hadRider; // Purpur - Ridables
|
|
|
|
public EnderDragon(EntityType<? extends EnderDragon> entityType, Level level) {
|
|
super(EntityType.ENDER_DRAGON, level);
|
|
@@ -108,6 +109,37 @@ public class EnderDragon extends Mob implements Enemy {
|
|
this.noPhysics = true;
|
|
this.phaseManager = new EnderDragonPhaseManager(this);
|
|
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) {
|
|
+ @Override
|
|
+ public void vanillaTick() {
|
|
+ // dragon doesn't use the controller. do nothing
|
|
+ }
|
|
+ };
|
|
+ this.lookControl = new org.purpurmc.purpur.controller.LookControllerWASD(this) {
|
|
+ @Override
|
|
+ public void vanillaTick() {
|
|
+ // dragon doesn't use the controller. do nothing
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void purpurTick(Player rider) {
|
|
+ setYawPitch(rider.getYRot() - 180F, rider.xRotO * 0.5F);
|
|
+ }
|
|
+ };
|
|
+ // Purpur end - Ridables
|
|
+ }
|
|
+
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.enderDragonRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.enderDragonRidableInWater;
|
|
}
|
|
|
|
public void setDragonFight(EndDragonFight dragonFight) {
|
|
@@ -122,6 +154,17 @@ public class EnderDragon extends Mob implements Enemy {
|
|
return this.fightOrigin;
|
|
}
|
|
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.enderDragonControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public double getMaxY() {
|
|
+ return level().purpurConfig.enderDragonMaxY;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public static AttributeSupplier.Builder createAttributes() {
|
|
return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 200.0).add(Attributes.CAMERA_DISTANCE, 16.0);
|
|
}
|
|
@@ -171,6 +214,37 @@ public class EnderDragon extends Mob implements Enemy {
|
|
|
|
@Override
|
|
public void aiStep() {
|
|
+ // Purpur start - Ridables
|
|
+ boolean hasRider = getRider() != null && this.isControllable();
|
|
+ if (hasRider) {
|
|
+ if (!hadRider) {
|
|
+ hadRider = true;
|
|
+ noPhysics = false;
|
|
+ this.dimensions = net.minecraft.world.entity.EntityDimensions.scalable(4.0F, 2.0F);
|
|
+ }
|
|
+
|
|
+ // dragon doesn't use controllers, so must tick manually
|
|
+ moveControl.tick();
|
|
+ lookControl.tick();
|
|
+
|
|
+ moveRelative((float) getAttributeValue(Attributes.MOVEMENT_SPEED) * 0.1F, new Vec3(-getStrafeMot(), getVerticalMot(), -getForwardMot()));
|
|
+ Vec3 mot = getDeltaMovement();
|
|
+ setDeltaMovement(mot);
|
|
+ move(MoverType.PLAYER, mot);
|
|
+
|
|
+ mot = mot.multiply(0.9F, 0.9F, 0.9F);
|
|
+ setDeltaMovement(mot);
|
|
+
|
|
+ // control wing flap speed on client
|
|
+ phaseManager.setPhase(mot.x() * mot.x() + mot.z() * mot.z() < 0.005F ? EnderDragonPhase.HOVERING : EnderDragonPhase.HOLDING_PATTERN);
|
|
+ } else if (hadRider) {
|
|
+ hadRider = false;
|
|
+ noPhysics = true;
|
|
+ this.dimensions = net.minecraft.world.entity.EntityDimensions.scalable(16.0F, 8.0F);
|
|
+ phaseManager.setPhase(EnderDragonPhase.HOLDING_PATTERN); // HoldingPattern
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
this.processFlappingMovement();
|
|
if (this.level().isClientSide()) {
|
|
this.setHealth(this.getHealth());
|
|
@@ -199,6 +273,8 @@ public class EnderDragon extends Mob implements Enemy {
|
|
|
|
this.oFlapTime = this.flapTime;
|
|
if (this.isDeadOrDying()) {
|
|
+ if (hasRider) ejectPassengers(); // Purpur - Ridables
|
|
+
|
|
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;
|
|
@@ -208,9 +284,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 += f1 * 0.5F;
|
|
} else {
|
|
this.flapTime += f1;
|
|
@@ -221,7 +297,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) {
|
|
@@ -296,7 +372,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(
|
|
@@ -346,9 +422,9 @@ public class EnderDragon extends Mob implements Enemy {
|
|
}
|
|
|
|
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 142731cc843a596ec1f156d7f25d97a0ca11f880..110ef9d81fdfa099316abf7b9c7ef4e1fdc976f7 100644
|
|
--- a/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
|
+++ b/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
|
@@ -71,6 +71,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
|
|
private boolean canPortal = false; // Paper
|
|
public final ServerBossEvent bossEvent = (ServerBossEvent)new ServerBossEvent(
|
|
this.getDisplayName(), BossEvent.BossBarColor.PURPLE, BossEvent.BossBarOverlay.PROGRESS
|
|
@@ -80,9 +81,23 @@ public class WitherBoss extends Monster implements RangedAttackMob {
|
|
&& entity.attackable();
|
|
private static final TargetingConditions TARGETING_CONDITIONS = TargetingConditions.forCombat().range(20.0).selector(LIVING_ENTITY_SELECTOR);
|
|
@Nullable private java.util.UUID summoner; // Purpur - Summoner API
|
|
+ private org.purpurmc.purpur.controller.FlyingWithSpacebarMoveControllerWASD purpurController; // Purpur - Ridables
|
|
|
|
public WitherBoss(EntityType<? extends WitherBoss> 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) {
|
|
+ @Override
|
|
+ public void tick() {
|
|
+ if (mob.getRider() != null && mob.isControllable()) {
|
|
+ purpurController.purpurTick(mob.getRider());
|
|
+ } else {
|
|
+ super.tick();
|
|
+ }
|
|
+ }
|
|
+ };
|
|
+ // Purpur end - Ridables
|
|
this.moveControl = new FlyingMoveControl(this, 10, false);
|
|
this.setHealth(this.getMaxHealth());
|
|
this.xpReward = 50;
|
|
@@ -99,6 +114,105 @@ public class WitherBoss extends Monster implements RangedAttackMob {
|
|
}
|
|
// Purpur end - Summoner API
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.witherRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.witherRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.witherControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public double getMaxY() {
|
|
+ return level().purpurConfig.witherMaxY;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void travel(Vec3 vec3) {
|
|
+ super.travel(vec3);
|
|
+ if (getRider() != null && this.isControllable() && !onGround) {
|
|
+ float speed = (float) getAttributeValue(Attributes.FLYING_SPEED) * 5F;
|
|
+ setSpeed(speed);
|
|
+ Vec3 mot = getDeltaMovement();
|
|
+ move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, 0.5, speed));
|
|
+ setDeltaMovement(mot.scale(0.9D));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onMount(Player rider) {
|
|
+ super.onMount(rider);
|
|
+ this.entityData.set(DATA_TARGETS.get(0), 0);
|
|
+ this.entityData.set(DATA_TARGETS.get(1), 0);
|
|
+ this.entityData.set(DATA_TARGETS.get(2), 0);
|
|
+ getNavigation().stop();
|
|
+ shootCooldown = 20;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean onClick(net.minecraft.world.InteractionHand hand) {
|
|
+ return shoot(getRider(), hand == net.minecraft.world.InteractionHand.MAIN_HAND ? new int[]{1} : new int[]{2});
|
|
+ }
|
|
+
|
|
+ public boolean shoot(@Nullable Player rider, int[] heads) {
|
|
+ if (shootCooldown > 0) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ shootCooldown = 20;
|
|
+ if (rider == null) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ org.bukkit.craftbukkit.entity.CraftHumanEntity player = rider.getBukkitEntity();
|
|
+ if (!player.hasPermission("allow.special.wither")) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ net.minecraft.world.phys.HitResult rayTrace = getRayTrace(120, net.minecraft.world.level.ClipContext.Fluid.NONE);
|
|
+ if (rayTrace == null) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ Vec3 loc;
|
|
+ if (rayTrace.getType() == net.minecraft.world.phys.HitResult.Type.BLOCK) {
|
|
+ BlockPos pos = ((net.minecraft.world.phys.BlockHitResult) rayTrace).getBlockPos();
|
|
+ loc = new Vec3(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D);
|
|
+ } else if (rayTrace.getType() == net.minecraft.world.phys.HitResult.Type.ENTITY) {
|
|
+ Entity target = ((net.minecraft.world.phys.EntityHitResult) rayTrace).getEntity();
|
|
+ loc = new Vec3(target.getX(), target.getY() + (target.getEyeHeight() / 2), target.getZ());
|
|
+ } else {
|
|
+ org.bukkit.block.Block block = player.getTargetBlock(null, 120);
|
|
+ loc = new Vec3(block.getX() + 0.5D, block.getY() + 0.5D, block.getZ() + 0.5D);
|
|
+ }
|
|
+
|
|
+ for (int head : heads) {
|
|
+ shoot(head, loc.x(), loc.y(), loc.z(), rider);
|
|
+ }
|
|
+
|
|
+ return true; // handled
|
|
+ }
|
|
+
|
|
+ public void shoot(int head, double x, double y, double z, Player rider) {
|
|
+ level().levelEvent(null, 1024, blockPosition(), 0);
|
|
+ double headX = getHeadX(head);
|
|
+ double headY = getHeadY(head);
|
|
+ double headZ = getHeadZ(head);
|
|
+ Vec3 vec3d = new Vec3(x - headX, y - headY, z - headZ);
|
|
+ WitherSkull skull = new WitherSkull(level(), this, vec3d.normalize());
|
|
+ skull.setPosRaw(headX, headY, headZ);
|
|
+ level().addFreshEntity(skull);
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected PathNavigation createNavigation(Level level) {
|
|
FlyingPathNavigation flyingPathNavigation = new FlyingPathNavigation(this, level);
|
|
@@ -109,11 +223,13 @@ public class WitherBoss extends Monster implements RangedAttackMob {
|
|
|
|
@Override
|
|
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.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));
|
|
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, LivingEntity.class, 0, false, false, LIVING_ENTITY_SELECTOR));
|
|
}
|
|
@@ -273,6 +389,15 @@ public class WitherBoss extends Monster implements RangedAttackMob {
|
|
|
|
@Override
|
|
protected void customServerAiStep(ServerLevel level) {
|
|
+ // Purpur start - Ridables
|
|
+ if (getRider() != null && this.isControllable()) {
|
|
+ Vec3 mot = getDeltaMovement();
|
|
+ setDeltaMovement(mot.x(), mot.y() + (getVerticalMot() > 0 ? 0.07D : 0.0D), mot.z());
|
|
+ }
|
|
+ if (shootCooldown > 0) {
|
|
+ shootCooldown--;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
if (this.getInvulnerableTicks() > 0) {
|
|
int i = this.getInvulnerableTicks() - 1;
|
|
this.bossEvent.setProgress(1.0F - i / 220.0F);
|
|
@@ -579,11 +704,11 @@ public class WitherBoss extends Monster implements RangedAttackMob {
|
|
}
|
|
|
|
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 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 ac5afa9e0605524f5a4e8541ba1e91775901eb11..2ef478b287e1240dd172235f7cabf31f60456a8a 100644
|
|
--- a/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
|
+++ b/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
|
@@ -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.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));
|
|
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 463ec6bec0b4b606cfc5276aa7803176e476d450..e0a38808c3757aaaabb6d3d8a0f9c1c0133c792f 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<? extends Blaze> 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);
|
|
this.setPathfindingMalus(PathType.DANGER_FIRE, 0.0F);
|
|
@@ -40,19 +41,55 @@ public class Blaze extends Monster {
|
|
this.xpReward = 10;
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.blazeRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.blazeRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.blazeControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public double getMaxY() {
|
|
+ return level().purpurConfig.blazeMaxY;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void travel(Vec3 vec3) {
|
|
+ super.travel(vec3);
|
|
+ if (getRider() != null && this.isControllable() && !onGround) {
|
|
+ float speed = (float) getAttributeValue(Attributes.FLYING_SPEED);
|
|
+ setSpeed(speed);
|
|
+ Vec3 mot = getDeltaMovement();
|
|
+ move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, 1.0, speed));
|
|
+ setDeltaMovement(mot.scale(0.9D));
|
|
+ }
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void registerGoals() {
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
this.goalSelector.addGoal(4, new Blaze.BlazeAttackGoal(this));
|
|
this.goalSelector.addGoal(5, new MoveTowardsRestrictionGoal(this, 1.0));
|
|
this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0, 0.0F));
|
|
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
|
|
this.targetSelector.addGoal(1, new HurtByTargetGoal(this).setAlertOthers());
|
|
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
|
|
}
|
|
|
|
public static AttributeSupplier.Builder createAttributes() {
|
|
- return Monster.createMonsterAttributes().add(Attributes.ATTACK_DAMAGE, 6.0).add(Attributes.MOVEMENT_SPEED, 0.23F).add(Attributes.FOLLOW_RANGE, 48.0);
|
|
+ return Monster.createMonsterAttributes().add(Attributes.ATTACK_DAMAGE, 6.0).add(Attributes.MOVEMENT_SPEED, 0.23F).add(Attributes.FOLLOW_RANGE, 48.0).add(Attributes.FLYING_SPEED, 0.6D); // Purpur - Ridables
|
|
}
|
|
|
|
@Override
|
|
@@ -117,6 +154,13 @@ public class Blaze extends Monster {
|
|
|
|
@Override
|
|
protected void customServerAiStep(ServerLevel level) {
|
|
+ // Purpur start - Ridables
|
|
+ if (getRider() != null && this.isControllable()) {
|
|
+ Vec3 mot = getDeltaMovement();
|
|
+ setDeltaMovement(mot.x(), getVerticalMot() > 0 ? 0.07D : -0.07D, mot.z());
|
|
+ return;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
this.nextHeightOffsetChangeTick--;
|
|
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 7b6c9d2e223d501e8a754e935d95e5aa7b530fd2..9ab5b3f88eeec22110b8aba71714e05209e4b855 100644
|
|
--- a/net/minecraft/world/entity/monster/Bogged.java
|
|
+++ b/net/minecraft/world/entity/monster/Bogged.java
|
|
@@ -43,6 +43,23 @@ public class Bogged extends AbstractSkeleton implements Shearable {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.boggedRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.boggedRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.boggedControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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 2e32567fca7a2a4cd87bc078a6eeb30e3ffabfce..4873a3d8dd9c160ecdbda594ee546c35ec03a1e7 100644
|
|
--- a/net/minecraft/world/entity/monster/CaveSpider.java
|
|
+++ b/net/minecraft/world/entity/monster/CaveSpider.java
|
|
@@ -26,6 +26,23 @@ public class CaveSpider extends Spider {
|
|
return Spider.createAttributes().add(Attributes.MAX_HEALTH, 12.0);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.caveSpiderRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.caveSpiderRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.caveSpiderControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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 98c8942993e8cb5073a794552082f63ed1f4d542..d250d8a2d0cbe41b2336a0a697c1c179b24dc823 100644
|
|
--- a/net/minecraft/world/entity/monster/Creeper.java
|
|
+++ b/net/minecraft/world/entity/monster/Creeper.java
|
|
@@ -57,21 +57,98 @@ public class Creeper extends Monster {
|
|
private boolean droppedSkulls;
|
|
public @Nullable Entity entityIgniter; // CraftBukkit
|
|
private boolean exploding = false; // Purpur - Config to make Creepers explode on death
|
|
+ // Purpur start - Ridables
|
|
+ private int spacebarCharge = 0;
|
|
+ private int prevSpacebarCharge = 0;
|
|
+ private int powerToggleDelay = 0;
|
|
+ // Purpur end - Ridables
|
|
|
|
public Creeper(EntityType<? extends Creeper> entityType, Level level) {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.creeperRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.creeperRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.creeperControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void customServerAiStep(ServerLevel world) {
|
|
+ if (powerToggleDelay > 0) {
|
|
+ powerToggleDelay--;
|
|
+ }
|
|
+ if (getRider() != null && this.isControllable()) {
|
|
+ if (getRider().getForwardMot() != 0 || getRider().getStrafeMot() != 0) {
|
|
+ spacebarCharge = 0;
|
|
+ setIgnited(false);
|
|
+ setSwellDir(-1);
|
|
+ }
|
|
+ if (spacebarCharge == prevSpacebarCharge) {
|
|
+ spacebarCharge = 0;
|
|
+ }
|
|
+ prevSpacebarCharge = spacebarCharge;
|
|
+ }
|
|
+ super.customServerAiStep(world);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onMount(Player rider) {
|
|
+ super.onMount(rider);
|
|
+ setIgnited(false);
|
|
+ setSwellDir(-1);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean onSpacebar() {
|
|
+ if (powerToggleDelay > 0) {
|
|
+ return true; // just toggled power, do not jump or ignite
|
|
+ }
|
|
+ spacebarCharge++;
|
|
+ if (spacebarCharge > maxSwell - 2) {
|
|
+ spacebarCharge = 0;
|
|
+ if (getRider() != null && getRider().getBukkitEntity().hasPermission("allow.powered.creeper")) {
|
|
+ powerToggleDelay = 20;
|
|
+ setPowered(!isPowered());
|
|
+ setIgnited(false);
|
|
+ setSwellDir(-1);
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ if (!isIgnited()) {
|
|
+ if (getRider() != null && getRider().getForwardMot() == 0 && getRider().getStrafeMot() == 0 &&
|
|
+ getRider().getBukkitEntity().hasPermission("allow.special.creeper")) {
|
|
+ setIgnited(true);
|
|
+ setSwellDir(1);
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ return getForwardMot() == 0 && getStrafeMot() == 0; // do not jump if standing still
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void registerGoals() {
|
|
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.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));
|
|
}
|
|
@@ -314,6 +391,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(DATA_IS_IGNITED, event.isIgnited());
|
|
+ if (!event.isIgnited()) setSwellDir(-1); // Purpur - Ridables
|
|
}
|
|
}
|
|
}
|
|
diff --git a/net/minecraft/world/entity/monster/Drowned.java b/net/minecraft/world/entity/monster/Drowned.java
|
|
index 1dc745180a2671415f526f8afeedf61d90c21bd9..eb70d05d2540295f79d24fbd0c07a9a349783f88 100644
|
|
--- a/net/minecraft/world/entity/monster/Drowned.java
|
|
+++ b/net/minecraft/world/entity/monster/Drowned.java
|
|
@@ -71,6 +71,23 @@ public class Drowned extends Zombie implements RangedAttackMob {
|
|
return Zombie.createAttributes().add(Attributes.STEP_HEIGHT, 1.0);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.drownedRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.drownedRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.drownedControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected PathNavigation createNavigation(Level level) {
|
|
return new AmphibiousPathNavigation(this, level);
|
|
@@ -400,7 +417,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
|
|
}
|
|
}
|
|
|
|
- static class DrownedMoveControl extends MoveControl {
|
|
+ static class DrownedMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables
|
|
private final Drowned drowned;
|
|
|
|
public DrownedMoveControl(Drowned mob) {
|
|
@@ -409,7 +426,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
|
|
}
|
|
|
|
@Override
|
|
- public void tick() {
|
|
+ public void vanillaTick() { // Purpur - Ridables
|
|
LivingEntity target = this.drowned.getTarget();
|
|
if (this.drowned.wantsToSwim() && this.drowned.isInWater()) {
|
|
if (target != null && target.getY() > this.drowned.getY() || this.drowned.searchingForLand) {
|
|
@@ -429,7 +446,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 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));
|
|
@@ -438,7 +455,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
|
|
this.drowned.setDeltaMovement(this.drowned.getDeltaMovement().add(0.0, -0.008, 0.0));
|
|
}
|
|
|
|
- super.tick();
|
|
+ super.vanillaTick(); // Purpur - Ridables
|
|
}
|
|
}
|
|
}
|
|
diff --git a/net/minecraft/world/entity/monster/ElderGuardian.java b/net/minecraft/world/entity/monster/ElderGuardian.java
|
|
index 7eef05b988d52391ab061382fd8898705c705e03..07355eb21c7b06d282be32f6956d4de9e399b9c9 100644
|
|
--- a/net/minecraft/world/entity/monster/ElderGuardian.java
|
|
+++ b/net/minecraft/world/entity/monster/ElderGuardian.java
|
|
@@ -31,6 +31,18 @@ public class ElderGuardian extends Guardian {
|
|
}
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.elderGuardianRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.elderGuardianControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public static AttributeSupplier.Builder createAttributes() {
|
|
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 956e6e2f0c7cff67a39e5a8487c0607f38971bd0..612b0caa28d214886edab3b2de34838659bd39f2 100644
|
|
--- a/net/minecraft/world/entity/monster/EnderMan.java
|
|
+++ b/net/minecraft/world/entity/monster/EnderMan.java
|
|
@@ -90,9 +90,27 @@ public class EnderMan extends Monster implements NeutralMob {
|
|
this.setPathfindingMalus(PathType.WATER, -1.0F);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.endermanRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.endermanRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.endermanControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@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(1, new EnderMan.EndermanFreezeWhenLookedAt(this));
|
|
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));
|
|
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Endermite.class, 10, true, false, (entityliving, ignored) -> entityliving.level().purpurConfig.endermanAggroEndermites && entityliving instanceof Endermite endermite && (!entityliving.level().purpurConfig.endermanAggroEndermitesOnlyIfPlayerSpawned || endermite.isPlayerSpawned()))); // Purpur
|
|
@@ -265,7 +284,7 @@ public class EnderMan extends Monster implements NeutralMob {
|
|
|
|
@Override
|
|
protected void customServerAiStep(ServerLevel level) {
|
|
- if (level.isBrightOutside() && this.tickCount >= this.targetChangeTime + 600) {
|
|
+ if ((getRider() == null || !this.isControllable()) && level.isBrightOutside() && this.tickCount >= this.targetChangeTime + 600) { // Purpur - Ridables - no random teleporting
|
|
float lightLevelDependentMagicValue = this.getLightLevelDependentMagicValue();
|
|
if (lightLevelDependentMagicValue > 0.5F
|
|
&& level.canSeeSky(this.blockPosition())
|
|
@@ -378,6 +397,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(level, damageSource, amount); // Purpur - no teleporting on damage
|
|
} else if (org.purpurmc.purpur.PurpurConfig.endermanShortHeight && damageSource.is(net.minecraft.world.damagesource.DamageTypes.IN_WALL)) { return false; // Purpur - no suffocation damage if short height - Short enderman height
|
|
} else {
|
|
AbstractThrownPotion abstractThrownPotion1 = damageSource.getDirectEntity() instanceof AbstractThrownPotion abstractThrownPotion
|
|
diff --git a/net/minecraft/world/entity/monster/Endermite.java b/net/minecraft/world/entity/monster/Endermite.java
|
|
index 74ce5bc242838c8979b07e1f6936f93d758b8396..c7e3a80a678df50cbb03349826f7e03c23a2c622 100644
|
|
--- a/net/minecraft/world/entity/monster/Endermite.java
|
|
+++ b/net/minecraft/world/entity/monster/Endermite.java
|
|
@@ -47,14 +47,33 @@ public class Endermite extends Monster {
|
|
}
|
|
// Purpur end - Add back player spawned endermite API
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.endermiteRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.endermiteRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.endermiteControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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(1, new ClimbOnTopOfPowderSnowGoal(this, this.level()));
|
|
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).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 7efa39ab1fb34da41a04cd6816f2571c6eba98f5..10142de6bdf9474958ca939c956a428218ee48db 100644
|
|
--- a/net/minecraft/world/entity/monster/Evoker.java
|
|
+++ b/net/minecraft/world/entity/monster/Evoker.java
|
|
@@ -48,10 +48,28 @@ public class Evoker extends SpellcasterIllager {
|
|
this.xpReward = 10;
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.evokerRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.evokerRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.evokerControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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 Evoker.EvokerCastingSpellGoal());
|
|
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));
|
|
@@ -61,6 +79,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, 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 9d5abdd8f25a84f1e5f27ab7a49a34ddce93f764..49925c8db7166359fdcc0008d5be2130d01686b6 100644
|
|
--- a/net/minecraft/world/entity/monster/Ghast.java
|
|
+++ b/net/minecraft/world/entity/monster/Ghast.java
|
|
@@ -52,11 +52,35 @@ public class Ghast extends Mob implements Enemy {
|
|
this.moveControl = new Ghast.GhastMoveControl(this, false, () -> false);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.ghastRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.ghastRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.ghastControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public double getMaxY() {
|
|
+ return level().purpurConfig.ghastMaxY;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void registerGoals() {
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
this.goalSelector.addGoal(5, new Ghast.RandomFloatAroundGoal(this));
|
|
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, (entity, level) -> Math.abs(entity.getY() - this.getY()) <= 4.0));
|
|
}
|
|
@@ -101,6 +125,15 @@ public class Ghast extends Mob implements Enemy {
|
|
@Override
|
|
public void travel(Vec3 travelVector) {
|
|
this.travelFlying(travelVector, 0.02F);
|
|
+ // Purpur start - Ridables
|
|
+ if (getRider() != null && this.isControllable() && !onGround) {
|
|
+ float speed = (float) getAttributeValue(Attributes.FLYING_SPEED);
|
|
+ setSpeed(speed);
|
|
+ Vec3 mot = getDeltaMovement();
|
|
+ move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, 1.0, speed));
|
|
+ setDeltaMovement(mot.scale(0.9D));
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
}
|
|
|
|
@Override
|
|
@@ -231,7 +264,7 @@ public class Ghast extends Mob implements Enemy {
|
|
}
|
|
}
|
|
|
|
- public static class GhastMoveControl extends MoveControl {
|
|
+ public static class GhastMoveControl extends org.purpurmc.purpur.controller.FlyingMoveControllerWASD { // Purpur - Ridables
|
|
private final Mob ghast;
|
|
private int floatDuration;
|
|
private final boolean careful;
|
|
@@ -245,7 +278,7 @@ public class Ghast extends Mob implements Enemy {
|
|
}
|
|
|
|
@Override
|
|
- public void tick() {
|
|
+ public void vanillaTick() { // Purpur - Ridables
|
|
if (this.shouldBeStopped.getAsBoolean()) {
|
|
this.operation = MoveControl.Operation.WAIT;
|
|
this.ghast.stopInPlace();
|
|
diff --git a/net/minecraft/world/entity/monster/Giant.java b/net/minecraft/world/entity/monster/Giant.java
|
|
index ab0b44fd3e20fcab4e2fea985e7471575b619069..c098fc14eb4f2ebd7dc1f6be9507279296416eea 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(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.giantRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.giantRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.giantControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void registerGoals() {
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this));
|
|
+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this));
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public static AttributeSupplier.Builder createAttributes() {
|
|
return Monster.createMonsterAttributes()
|
|
.add(Attributes.MAX_HEALTH, 100.0)
|
|
diff --git a/net/minecraft/world/entity/monster/Guardian.java b/net/minecraft/world/entity/monster/Guardian.java
|
|
index 911b98264f29d08cc57143258ec53e6af8aa271c..7202edbad08975fc62f9aa876d9e53a238182b20 100644
|
|
--- a/net/minecraft/world/entity/monster/Guardian.java
|
|
+++ b/net/minecraft/world/entity/monster/Guardian.java
|
|
@@ -66,14 +66,35 @@ public class Guardian extends Monster {
|
|
this.xpReward = 10;
|
|
this.setPathfindingMalus(PathType.WATER, 0.0F);
|
|
this.moveControl = new Guardian.GuardianMoveControl(this);
|
|
+ // Purpur start - Ridables
|
|
+ this.lookControl = new org.purpurmc.purpur.controller.LookControllerWASD(this) {
|
|
+ @Override
|
|
+ public void setYawPitch(float yaw, float pitch) {
|
|
+ super.setYawPitch(yaw, pitch * 0.35F);
|
|
+ }
|
|
+ };
|
|
+ // Purpur end - Ridables
|
|
this.clientSideTailAnimation = this.random.nextFloat();
|
|
this.clientSideTailAnimationO = this.clientSideTailAnimation;
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.guardianRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.guardianControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void registerGoals() {
|
|
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, moveTowardsRestrictionGoal);
|
|
this.goalSelector.addGoal(7, this.randomStrollGoal);
|
|
@@ -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));
|
|
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)));
|
|
}
|
|
|
|
@@ -344,7 +366,7 @@ public class Guardian extends Monster {
|
|
@Override
|
|
public void travel(Vec3 travelVector) {
|
|
if (this.isInWater()) {
|
|
- 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.9));
|
|
if (!this.isMoving() && this.getTarget() == null) {
|
|
@@ -452,7 +474,7 @@ public class Guardian extends Monster {
|
|
}
|
|
}
|
|
|
|
- static class GuardianMoveControl extends MoveControl {
|
|
+ static class GuardianMoveControl extends org.purpurmc.purpur.controller.WaterMoveControllerWASD { // Purpur - Ridables
|
|
private final Guardian guardian;
|
|
|
|
public GuardianMoveControl(Guardian mob) {
|
|
@@ -460,8 +482,17 @@ public class Guardian extends Monster {
|
|
this.guardian = mob;
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
@Override
|
|
- public void tick() {
|
|
+ public void purpurTick(Player rider) {
|
|
+ super.purpurTick(rider);
|
|
+ guardian.setDeltaMovement(guardian.getDeltaMovement().add(0.0D, 0.005D, 0.0D));
|
|
+ guardian.setMoving(guardian.getForwardMot() > 0.0F); // control tail speed
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
+ @Override
|
|
+ public void vanillaTick() { // Purpur - Ridables
|
|
if (this.operation == MoveControl.Operation.MOVE_TO && !this.guardian.getNavigation().isDone()) {
|
|
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 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 4de3e70d78e861f15d2aedb54280158988823caa..b8b7700df42feb2309d9e845e37aa0e9ca026f9b 100644
|
|
--- a/net/minecraft/world/entity/monster/Husk.java
|
|
+++ b/net/minecraft/world/entity/monster/Husk.java
|
|
@@ -20,6 +20,23 @@ public class Husk extends Zombie {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.huskRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.huskRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.huskControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public static boolean checkHuskSpawnRules(
|
|
EntityType<Husk> 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 c56665b7d0173542dcddeb1a3aa9eb8e7847e2a1..c41d43d20db8a573efcbbe8593f5b1f56a18aa0e 100644
|
|
--- a/net/minecraft/world/entity/monster/Illusioner.java
|
|
+++ b/net/minecraft/world/entity/monster/Illusioner.java
|
|
@@ -57,10 +57,28 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob {
|
|
}
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.illusionerRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.illusionerRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.illusionerControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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 SpellcasterIllager.SpellcasterCastingSpellGoal());
|
|
this.goalSelector.addGoal(3, new AvoidEntityGoal<>(this, Creaking.class, 8.0F, 1.0, 1.2));
|
|
this.goalSelector.addGoal(4, new Illusioner.IllusionerMirrorSpellGoal());
|
|
@@ -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, 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 889c31cc9257fbbd5df8325ccee9ce39b026ec4b..4a1299d6cee2807522de0c2d0d4745c5810e4121 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(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.magmaCubeRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.magmaCubeRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.magmaCubeControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public float getJumpPower() {
|
|
+ return 0.42F * this.getBlockJumpFactor(); // from EntityLiving
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public static AttributeSupplier.Builder createAttributes() {
|
|
return Monster.createMonsterAttributes().add(Attributes.MOVEMENT_SPEED, 0.2F);
|
|
}
|
|
@@ -71,6 +93,7 @@ public class MagmaCube extends Slime {
|
|
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 59e100360ce960c98d3df69052795e4100bc415b..f5cc26632345bdae6fbda72e1084bacf79a75752 100644
|
|
--- a/net/minecraft/world/entity/monster/Phantom.java
|
|
+++ b/net/minecraft/world/entity/monster/Phantom.java
|
|
@@ -62,6 +62,52 @@ public class Phantom extends Mob implements Enemy {
|
|
this.lookControl = new Phantom.PhantomLookControl(this);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.phantomRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.phantomRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.phantomControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public double getMaxY() {
|
|
+ return level().purpurConfig.phantomMaxY;
|
|
+ }
|
|
+
|
|
+ public static net.minecraft.world.entity.ai.attributes.AttributeSupplier.Builder createAttributes() {
|
|
+ return Monster.createMonsterAttributes().add(Attributes.FLYING_SPEED, 3.0D);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean onSpacebar() {
|
|
+ if (getRider() != null && getRider().getBukkitEntity().hasPermission("allow.special.phantom")) {
|
|
+ shoot();
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ public boolean shoot() {
|
|
+ org.bukkit.Location loc = ((org.bukkit.entity.LivingEntity) getBukkitEntity()).getEyeLocation();
|
|
+ loc.setPitch(-loc.getPitch());
|
|
+ org.bukkit.util.Vector target = loc.getDirection().normalize().multiply(100).add(loc.toVector());
|
|
+
|
|
+ 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);
|
|
+ return true;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
public boolean isFlapping() {
|
|
return (this.getUniqueFlapTickOffset() + this.tickCount) % TICKS_PER_FLAP == 0;
|
|
@@ -74,9 +120,11 @@ public class Phantom extends Mob implements Enemy {
|
|
|
|
@Override
|
|
protected void registerGoals() {
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
this.goalSelector.addGoal(1, new Phantom.PhantomAttackStrategyGoal());
|
|
this.goalSelector.addGoal(2, new Phantom.PhantomSweepAttackGoal());
|
|
this.goalSelector.addGoal(3, new Phantom.PhantomCircleAroundAnchorGoal());
|
|
+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
this.targetSelector.addGoal(1, new Phantom.PhantomAttackPlayerTargetGoal());
|
|
}
|
|
|
|
@@ -92,6 +140,7 @@ public class Phantom extends Mob implements Enemy {
|
|
|
|
private void updatePhantomSizeInfo() {
|
|
this.refreshDimensions();
|
|
+ if (level().purpurConfig.phantomFlamesOnSwoop && attackPhase == AttackPhase.SWOOP) shoot(); // Purpur - Ridables - Phantom flames on swoop
|
|
this.getAttribute(Attributes.ATTACK_DAMAGE).setBaseValue(6 + this.getPhantomSize());
|
|
}
|
|
|
|
@@ -144,6 +193,7 @@ public class Phantom extends Mob implements Enemy {
|
|
@Override
|
|
public void aiStep() {
|
|
if (this.isAlive() && this.shouldBurnInDay && this.isSunBurnTick()) { // Paper - shouldBurnInDay API
|
|
+ if (getRider() == null || !this.isControllable()) // Purpur - Ridables
|
|
this.igniteForSeconds(8.0F);
|
|
}
|
|
|
|
@@ -162,6 +212,15 @@ public class Phantom extends Mob implements Enemy {
|
|
@Override
|
|
public void travel(Vec3 travelVector) {
|
|
this.travelFlying(travelVector, 0.2F);
|
|
+ // Purpur start - Ridables
|
|
+ if (this.getRider() != null && this.isControllable() && !this.onGround) {
|
|
+ float speed = (float) this.getAttributeValue(Attributes.FLYING_SPEED);
|
|
+ this.setSpeed(speed);
|
|
+ Vec3 mot = this.getDeltaMovement();
|
|
+ this.move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, speed, speed));
|
|
+ this.setDeltaMovement(mot.scale(0.9D));
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
}
|
|
|
|
@Override
|
|
@@ -415,25 +474,42 @@ public class Phantom extends Mob implements Enemy {
|
|
}
|
|
}
|
|
|
|
- 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;
|
|
|
|
public PhantomMoveControl(final Mob mob) {
|
|
super(mob);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ public void purpurTick(Player rider) {
|
|
+ if (!Phantom.this.onGround) {
|
|
+ // phantom is always in motion when flying
|
|
+ // TODO - FIX THIS
|
|
+ // rider.setForward(1.0F);
|
|
+ }
|
|
+ super.purpurTick(rider);
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
- public void tick() {
|
|
+ public void vanillaTick() { // Purpur - Ridables
|
|
if (Phantom.this.horizontalCollision) {
|
|
Phantom.this.setYRot(Phantom.this.getYRot() + 180.0F);
|
|
this.speed = 0.1F;
|
|
diff --git a/net/minecraft/world/entity/monster/Pillager.java b/net/minecraft/world/entity/monster/Pillager.java
|
|
index 4f72db7e6f99844761de2f749e52cda156b08ad7..fa49ed77f33bca6335812e9f56176cc053a364ad 100644
|
|
--- a/net/minecraft/world/entity/monster/Pillager.java
|
|
+++ b/net/minecraft/world/entity/monster/Pillager.java
|
|
@@ -64,16 +64,35 @@ public class Pillager extends AbstractIllager implements CrossbowAttackMob, Inve
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.pillagerRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.pillagerRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.pillagerControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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 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.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, 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 2b9a72b8742bf13c69df5ce0c905d47a92b9d8bc..b67ac487ce4a7fd8b2f62452ab0b87f4a55006f2 100644
|
|
--- a/net/minecraft/world/entity/monster/Ravager.java
|
|
+++ b/net/minecraft/world/entity/monster/Ravager.java
|
|
@@ -70,15 +70,40 @@ public class Ravager extends Raider {
|
|
this.setPathfindingMalus(PathType.LEAVES, 0.0F);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.ravagerRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.ravagerRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.ravagerControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void onMount(Player rider) {
|
|
+ super.onMount(rider);
|
|
+ getNavigation().stop();
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void registerGoals() {
|
|
super.registerGoals();
|
|
this.goalSelector.addGoal(0, new FloatGoal(this));
|
|
if (level().purpurConfig.ravagerAvoidRabbits) this.goalSelector.addGoal(3, new net.minecraft.world.entity.ai.goal.AvoidEntityGoal<>(this, net.minecraft.world.entity.animal.Rabbit.class, 6.0F, 1.0D, 1.2D)); // Purpur - option to make ravagers afraid of rabbits
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
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, Raider.class).setAlertOthers());
|
|
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Player.class, true));
|
|
this.targetSelector.addGoal(4, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, true, (entity, level) -> !entity.isBaby()));
|
|
@@ -135,7 +160,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.0);
|
|
} else {
|
|
diff --git a/net/minecraft/world/entity/monster/Shulker.java b/net/minecraft/world/entity/monster/Shulker.java
|
|
index ed89eae7f941b4a771691006b7150537ffb97d19..d3b14cfb5310423e52899edd5873e9ba7f6a30fc 100644
|
|
--- a/net/minecraft/world/entity/monster/Shulker.java
|
|
+++ b/net/minecraft/world/entity/monster/Shulker.java
|
|
@@ -109,12 +109,31 @@ public class Shulker extends AbstractGolem implements Enemy {
|
|
}
|
|
// Purpur end - Shulker change color with dye
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.shulkerRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.shulkerRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.shulkerControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void registerGoals() {
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
this.goalSelector.addGoal(1, new LookAtPlayerGoal(this, Player.class, 8.0F, 0.02F, true));
|
|
this.goalSelector.addGoal(4, new Shulker.ShulkerAttackGoal());
|
|
this.goalSelector.addGoal(7, new Shulker.ShulkerPeekGoal());
|
|
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, this.getClass()).setAlertOthers());
|
|
this.targetSelector.addGoal(2, new Shulker.ShulkerNearestAttackGoal(this));
|
|
this.targetSelector.addGoal(3, new Shulker.ShulkerDefenseAttackGoal(this));
|
|
@@ -714,7 +733,7 @@ public class Shulker extends AbstractGolem implements Enemy {
|
|
}
|
|
}
|
|
|
|
- class ShulkerLookControl extends LookControl {
|
|
+ class ShulkerLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - Ridables
|
|
public ShulkerLookControl(final Mob mob) {
|
|
super(mob);
|
|
}
|
|
diff --git a/net/minecraft/world/entity/monster/Silverfish.java b/net/minecraft/world/entity/monster/Silverfish.java
|
|
index 4e34833ea5c71b817c9f42a58320fe100981ec93..19dcc657fd2a995638d5e23c2b043d012d978e79 100644
|
|
--- a/net/minecraft/world/entity/monster/Silverfish.java
|
|
+++ b/net/minecraft/world/entity/monster/Silverfish.java
|
|
@@ -39,14 +39,33 @@ public class Silverfish extends Monster {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.silverfishRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.silverfishRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.silverfishControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void registerGoals() {
|
|
this.friendsGoal = new Silverfish.SilverfishWakeUpFriendsGoal(this);
|
|
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(3, this.friendsGoal);
|
|
this.goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0, false));
|
|
this.goalSelector.addGoal(5, new Silverfish.SilverfishMergeWithStoneGoal(this));
|
|
+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
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/Skeleton.java b/net/minecraft/world/entity/monster/Skeleton.java
|
|
index 2661c73bb09e885d68ed57cbbeb9611fb990669e..bb7f93435168da4023ee07585e92192717881acc 100644
|
|
--- a/net/minecraft/world/entity/monster/Skeleton.java
|
|
+++ b/net/minecraft/world/entity/monster/Skeleton.java
|
|
@@ -25,6 +25,23 @@ public class Skeleton extends AbstractSkeleton {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.skeletonRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.skeletonRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.skeletonControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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 678b065a8119d23c3c6b3b3657ae6e728bd7a046..ce6e19b9cf943a8a9d1e85c8764d57b7f282cd69 100644
|
|
--- a/net/minecraft/world/entity/monster/Slime.java
|
|
+++ b/net/minecraft/world/entity/monster/Slime.java
|
|
@@ -59,6 +59,7 @@ public class Slime extends Mob implements Enemy {
|
|
public float oSquish;
|
|
private boolean wasOnGround = false;
|
|
private boolean canWander = true; // Paper - Slime pathfinder events
|
|
+ protected boolean actualJump; // Purpur - Ridables
|
|
|
|
public Slime(EntityType<? extends Slime> entityType, Level level) {
|
|
super(entityType, level);
|
|
@@ -66,12 +67,48 @@ public class Slime extends Mob implements Enemy {
|
|
this.moveControl = new Slime.SlimeMoveControl(this);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.slimeRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.slimeRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.slimeControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public float getJumpPower() {
|
|
+ float height = super.getJumpPower();
|
|
+ return getRider() != null && this.isControllable() && actualJump ? height * 1.5F : height;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean onSpacebar() {
|
|
+ if (onGround && getRider() != null && this.isControllable()) {
|
|
+ actualJump = true;
|
|
+ if (getRider().getForwardMot() == 0 || getRider().getStrafeMot() == 0) {
|
|
+ jumpFromGround(); // jump() here if not moving
|
|
+ }
|
|
+ }
|
|
+ return true; // do not jump() in wasd controller, let vanilla controller handle
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void registerGoals() {
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
this.goalSelector.addGoal(1, new Slime.SlimeFloatGoal(this));
|
|
this.goalSelector.addGoal(2, new Slime.SlimeAttackGoal(this));
|
|
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, (entity, level) -> Math.abs(entity.getY() - this.getY()) <= 4.0));
|
|
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));
|
|
@@ -355,6 +392,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
|
|
@@ -519,7 +557,7 @@ public class Slime extends Mob implements Enemy {
|
|
}
|
|
}
|
|
|
|
- static class SlimeMoveControl extends MoveControl {
|
|
+ static class SlimeMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables
|
|
private float yRot;
|
|
private int jumpDelay;
|
|
private final Slime slime;
|
|
@@ -537,21 +575,33 @@ public class Slime extends Mob implements Enemy {
|
|
}
|
|
|
|
public void setWantedMovement(double speed) {
|
|
- this.speedModifier = speed;
|
|
+ this.setSpeedModifier(speed); // Purpur - Ridables
|
|
this.operation = MoveControl.Operation.MOVE_TO;
|
|
}
|
|
|
|
@Override
|
|
public void tick() {
|
|
+ // Purpur start - Ridables
|
|
+ if (slime.getRider() != null && slime.isControllable()) {
|
|
+ purpurTick(slime.getRider());
|
|
+ if (slime.getForwardMot() != 0 || slime.getStrafeMot() != 0) {
|
|
+ if (jumpDelay > 10) {
|
|
+ jumpDelay = 6;
|
|
+ }
|
|
+ } else {
|
|
+ jumpDelay = 20;
|
|
+ }
|
|
+ } else {
|
|
+ // Purpur end - Ridables
|
|
this.mob.setYRot(this.rotlerp(this.mob.getYRot(), this.yRot, 90.0F));
|
|
this.mob.yHeadRot = this.mob.getYRot();
|
|
this.mob.yBodyRot = this.mob.getYRot();
|
|
- if (this.operation != MoveControl.Operation.MOVE_TO) {
|
|
+ } if ((slime.getRider() == null || !slime.isControllable()) && this.operation != MoveControl.Operation.MOVE_TO) { // Purpur - Ridables
|
|
this.mob.setZza(0.0F);
|
|
} 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
|
|
if (this.jumpDelay-- <= 0) {
|
|
this.jumpDelay = this.slime.getJumpDelay();
|
|
if (this.isAggressive) {
|
|
@@ -568,7 +618,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
|
|
}
|
|
}
|
|
}
|
|
diff --git a/net/minecraft/world/entity/monster/Spider.java b/net/minecraft/world/entity/monster/Spider.java
|
|
index 13f49a2e43adbbbb4ec9cd5b479814fefcca1cce..771592182fe56efc6fc0dae7fa852483b3b99c57 100644
|
|
--- a/net/minecraft/world/entity/monster/Spider.java
|
|
+++ b/net/minecraft/world/entity/monster/Spider.java
|
|
@@ -50,15 +50,34 @@ public class Spider extends Monster {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.spiderRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.spiderRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.spiderControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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.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));
|
|
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 f3de370ee4bafc2cca033293d0d8e5c9c2a6737b..4a7dbd1e4d927240433882a95822e9edfc83b827 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(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.strayRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.strayRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.strayControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public static boolean checkStraySpawnRules(
|
|
EntityType<Stray> 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 824e5d81d392566fb14647ab3672f1fdb1111e7e..f1e559f552b932d1d66b67ff35ca519ee273fc50 100644
|
|
--- a/net/minecraft/world/entity/monster/Strider.java
|
|
+++ b/net/minecraft/world/entity/monster/Strider.java
|
|
@@ -92,6 +92,23 @@ public class Strider extends Animal implements ItemSteerable {
|
|
this.setPathfindingMalus(PathType.DAMAGE_FIRE, 0.0F);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.striderRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.striderRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.striderControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public static boolean checkStriderSpawnRules(
|
|
EntityType<Strider> entityType, LevelAccessor level, EntitySpawnReason spawnReason, BlockPos pos, RandomSource random
|
|
) {
|
|
@@ -138,6 +155,7 @@ public class Strider extends Animal implements ItemSteerable {
|
|
@Override
|
|
protected void registerGoals() {
|
|
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.0));
|
|
this.temptGoal = new TemptGoal(this, 1.4, itemStack -> itemStack.is(ItemTags.STRIDER_TEMPT_ITEMS), false);
|
|
this.goalSelector.addGoal(3, this.temptGoal);
|
|
@@ -417,7 +435,7 @@ public class Strider extends Animal implements ItemSteerable {
|
|
ItemStack itemInHand = player.getItemInHand(hand);
|
|
return (InteractionResult)(this.isEquippableInSlot(itemInHand, EquipmentSlot.SADDLE)
|
|
? itemInHand.interactLivingEntity(player, this, hand)
|
|
- : InteractionResult.PASS);
|
|
+ : tryRide(player, hand)); // Purpur - Ridables
|
|
} else {
|
|
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 71ccccf12289972cb35686c1bda11510da7663dd..f8fb8de570468151e1b82e8f15e66e2ea6fd8e22 100644
|
|
--- a/net/minecraft/world/entity/monster/Vex.java
|
|
+++ b/net/minecraft/world/entity/monster/Vex.java
|
|
@@ -60,6 +60,50 @@ public class Vex extends Monster implements TraceableEntity {
|
|
this.xpReward = 3;
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.vexRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.vexRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.vexControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public double getMaxY() {
|
|
+ return level().purpurConfig.vexMaxY;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void travel(Vec3 vec3) {
|
|
+ super.travel(vec3);
|
|
+ if (getRider() != null && this.isControllable()) {
|
|
+ float speed;
|
|
+ if (onGround) {
|
|
+ speed = (float) getAttributeValue(Attributes.MOVEMENT_SPEED) * 0.1F;
|
|
+ } else {
|
|
+ speed = (float) getAttributeValue(Attributes.FLYING_SPEED);
|
|
+ }
|
|
+ setSpeed(speed);
|
|
+ Vec3 mot = getDeltaMovement();
|
|
+ move(net.minecraft.world.entity.MoverType.SELF, mot.multiply(speed, 1.0, speed));
|
|
+ setDeltaMovement(mot.scale(0.9D));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean causeFallDamage(double fallDistance, float damageMultiplier, DamageSource damageSource) {
|
|
+ return false; // no fall damage please
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
public boolean isFlapping() {
|
|
return this.tickCount % TICKS_PER_FLAP == 0;
|
|
@@ -72,7 +116,7 @@ public class Vex extends Monster implements TraceableEntity {
|
|
|
|
@Override
|
|
public void tick() {
|
|
- this.noPhysics = true;
|
|
+ this.noPhysics = getRider() == null || !this.isControllable(); // Purpur - Ridables
|
|
super.tick();
|
|
this.noPhysics = false;
|
|
this.setNoGravity(true);
|
|
@@ -86,17 +130,19 @@ public class Vex extends Monster implements TraceableEntity {
|
|
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(4, new Vex.VexChargeAttackGoal());
|
|
this.goalSelector.addGoal(8, new Vex.VexRandomMoveGoal());
|
|
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, 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.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
|
|
@@ -298,13 +344,13 @@ public class Vex extends Monster implements TraceableEntity {
|
|
}
|
|
}
|
|
|
|
- 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 vec3 = new Vec3(this.wantedX - Vex.this.getX(), this.wantedY - Vex.this.getY(), this.wantedZ - Vex.this.getZ());
|
|
double len = vec3.length();
|
|
@@ -312,7 +358,7 @@ public class Vex extends Monster implements TraceableEntity {
|
|
this.operation = MoveControl.Operation.WAIT;
|
|
Vex.this.setDeltaMovement(Vex.this.getDeltaMovement().scale(0.5));
|
|
} else {
|
|
- 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 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 71d84306788be023bc949400d30966548d968c86..8e5bf153a457026808e2ea670e874e66ca0d5e98 100644
|
|
--- a/net/minecraft/world/entity/monster/Vindicator.java
|
|
+++ b/net/minecraft/world/entity/monster/Vindicator.java
|
|
@@ -56,15 +56,34 @@ public class Vindicator extends AbstractIllager {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.vindicatorRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.vindicatorRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.vindicatorControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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 AvoidEntityGoal<>(this, Creaking.class, 8.0F, 1.0, 1.2));
|
|
this.goalSelector.addGoal(2, new Vindicator.VindicatorBreakDoorGoal(this));
|
|
this.goalSelector.addGoal(3, new AbstractIllager.RaiderOpenDoorGoal(this));
|
|
this.goalSelector.addGoal(4, new Raider.HoldGroundAttackGoal(this, 10.0F));
|
|
this.goalSelector.addGoal(5, new MeleeAttackGoal(this, 1.0, false));
|
|
+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
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, true));
|
|
diff --git a/net/minecraft/world/entity/monster/Witch.java b/net/minecraft/world/entity/monster/Witch.java
|
|
index 1e573104a1f6d296d15315da3465a046bce157e1..e420d7dc0fc09d712ee63238f2107a2fa0f799b7 100644
|
|
--- a/net/minecraft/world/entity/monster/Witch.java
|
|
+++ b/net/minecraft/world/entity/monster/Witch.java
|
|
@@ -56,6 +56,23 @@ public class Witch extends Raider implements RangedAttackMob {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.witchRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.witchRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.witchControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void registerGoals() {
|
|
super.registerGoals();
|
|
@@ -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.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, 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 32b730338eb510d374a6ec5e279b0112f7bee286..48f9d87d26bad99b81af001a81d2c3d274cad007 100644
|
|
--- a/net/minecraft/world/entity/monster/WitherSkeleton.java
|
|
+++ b/net/minecraft/world/entity/monster/WitherSkeleton.java
|
|
@@ -34,6 +34,23 @@ public class WitherSkeleton extends AbstractSkeleton {
|
|
this.setPathfindingMalus(PathType.LAVA, 8.0F);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.witherSkeletonRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.witherSkeletonRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.witherSkeletonControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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 4feaa6167d82278a104a37c3b10257e24b299e6c..44ad3bbcfdf8615d6e5a896fb923685c481ae5b5 100644
|
|
--- a/net/minecraft/world/entity/monster/Zoglin.java
|
|
+++ b/net/minecraft/world/entity/monster/Zoglin.java
|
|
@@ -86,6 +86,23 @@ public class Zoglin extends Monster implements HoglinBase {
|
|
this.xpReward = 5;
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.zoglinRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.zoglinRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.zoglinControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected Brain.Provider<Zoglin> brainProvider() {
|
|
return Brain.provider(MEMORY_TYPES, SENSOR_TYPES);
|
|
@@ -251,6 +268,7 @@ public class Zoglin extends Monster implements HoglinBase {
|
|
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(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 a3b8bdacfde77963efba4a7e475031598c44e82f..1aeea30498e089d686b845f31b44aef0ff994c60 100644
|
|
--- a/net/minecraft/world/entity/monster/Zombie.java
|
|
+++ b/net/minecraft/world/entity/monster/Zombie.java
|
|
@@ -102,11 +102,30 @@ public class Zombie extends Monster {
|
|
this(EntityType.ZOMBIE, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.zombieRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.zombieRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.zombieControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@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.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
|
|
this.addBehaviourGoals();
|
|
}
|
|
|
|
diff --git a/net/minecraft/world/entity/monster/ZombieVillager.java b/net/minecraft/world/entity/monster/ZombieVillager.java
|
|
index 22a5c966feed50ebb9ed771f7e8a9cc59ac4d2bc..454e2795e04c7b7cac88f782df3dfb4200b192fc 100644
|
|
--- a/net/minecraft/world/entity/monster/ZombieVillager.java
|
|
+++ b/net/minecraft/world/entity/monster/ZombieVillager.java
|
|
@@ -73,6 +73,23 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
|
|
super(entityType, level);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.zombieVillagerRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.zombieVillagerRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.zombieVillagerControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
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 d6e9fc7e084fbc4e2d643f2408b36d52357c7af5..5919405428eb03c499167bc7b963e3f96f721c8c 100644
|
|
--- a/net/minecraft/world/entity/monster/ZombifiedPiglin.java
|
|
+++ b/net/minecraft/world/entity/monster/ZombifiedPiglin.java
|
|
@@ -64,6 +64,23 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob {
|
|
this.setPathfindingMalus(PathType.LAVA, 8.0F);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.zombifiedPiglinRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.zombifiedPiglinRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.zombifiedPiglinControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
public void setPersistentAngerTarget(@Nullable UUID target) {
|
|
this.persistentAngerTarget = target;
|
|
diff --git a/net/minecraft/world/entity/monster/breeze/Breeze.java b/net/minecraft/world/entity/monster/breeze/Breeze.java
|
|
index c1e391bac9976f74f5fe3f5b0d91130c927ebec2..11408fd409eb00e6bf3289e6a5a35e98178fa6e2 100644
|
|
--- a/net/minecraft/world/entity/monster/breeze/Breeze.java
|
|
+++ b/net/minecraft/world/entity/monster/breeze/Breeze.java
|
|
@@ -236,6 +236,7 @@ public class Breeze extends Monster {
|
|
protected void customServerAiStep(ServerLevel level) {
|
|
ProfilerFiller profilerFiller = Profiler.get();
|
|
profilerFiller.push("breezeBrain");
|
|
+ if (getRider() == null || !this.isControllable()) // Purpur - only use brain if no rider
|
|
this.getBrain().tick(level, this);
|
|
profilerFiller.popPush("breezeActivityUpdate");
|
|
BreezeAi.updateActivity(this);
|
|
diff --git a/net/minecraft/world/entity/monster/creaking/Creaking.java b/net/minecraft/world/entity/monster/creaking/Creaking.java
|
|
index f18b893cf7c7f87edb18beb3ef8781d892f6fc86..982790edbd74bd80988df1400b0e67669bfd164c 100644
|
|
--- a/net/minecraft/world/entity/monster/creaking/Creaking.java
|
|
+++ b/net/minecraft/world/entity/monster/creaking/Creaking.java
|
|
@@ -102,6 +102,29 @@ public class Creaking extends Monster {
|
|
return this.getHomePos() != null;
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.creakingRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.creakingRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.creakingControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void registerGoals() {
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected BodyRotationControl createBodyControl() {
|
|
return new Creaking.CreakingBodyRotationControl(this);
|
|
@@ -565,28 +588,28 @@ public class Creaking extends Monster {
|
|
}
|
|
}
|
|
|
|
- class CreakingLookControl extends LookControl {
|
|
+ class CreakingLookControl extends org.purpurmc.purpur.controller.LookControllerWASD { // Purpur - Ridables {
|
|
public CreakingLookControl(final Creaking mob) {
|
|
super(mob);
|
|
}
|
|
|
|
@Override
|
|
- public void tick() {
|
|
+ public void vanillaTick() { // Purpur - Ridables
|
|
if (Creaking.this.canMove()) {
|
|
- super.tick();
|
|
+ super.vanillaTick(); // Purpur - Ridables
|
|
}
|
|
}
|
|
}
|
|
|
|
- class CreakingMoveControl extends MoveControl {
|
|
+ class CreakingMoveControl extends org.purpurmc.purpur.controller.MoveControllerWASD { // Purpur - Ridables
|
|
public CreakingMoveControl(final Creaking mob) {
|
|
super(mob);
|
|
}
|
|
|
|
@Override
|
|
- public void tick() {
|
|
+ public void vanillaTick() { // Purpur - Ridables
|
|
if (Creaking.this.canMove()) {
|
|
- 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 422401ebe7ed5bbf69cad7083b333b9279978494..c3d08cfdb15602f6fbe2ac81c751e879668a4dd7 100644
|
|
--- a/net/minecraft/world/entity/monster/hoglin/Hoglin.java
|
|
+++ b/net/minecraft/world/entity/monster/hoglin/Hoglin.java
|
|
@@ -95,6 +95,23 @@ public class Hoglin extends Animal implements Enemy, HoglinBase {
|
|
this.xpReward = 5;
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.hoglinRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.hoglinRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.hoglinControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@VisibleForTesting
|
|
public void setTimeInOverworld(int timeInOverworld) {
|
|
this.timeInOverworld = timeInOverworld;
|
|
@@ -163,6 +180,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()) // Purpur - only use brain if no rider
|
|
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 d220e8f1517cf68a6083fc4791cb34ca926dd165..8a7c6326e056772fb89ca73b20cc1d9d1a029db9 100644
|
|
--- a/net/minecraft/world/entity/monster/piglin/Piglin.java
|
|
+++ b/net/minecraft/world/entity/monster/piglin/Piglin.java
|
|
@@ -136,6 +136,23 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
|
|
this.xpReward = 5;
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.piglinRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.piglinRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.piglinControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void addAdditionalSaveData(ValueOutput output) {
|
|
super.addAdditionalSaveData(output);
|
|
@@ -310,6 +327,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()) // Purpur - only use brain if no rider
|
|
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 219978cb0341b2d691f44c1146707d875788881e..4c8e49ba064241ec7ac505fa6f5df6d7f9c009b6 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 {
|
|
this.xpReward = 20;
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.piglinBruteRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.piglinBruteRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.piglinBruteControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public static AttributeSupplier.Builder createAttributes() {
|
|
return Monster.createMonsterAttributes()
|
|
.add(Attributes.MAX_HEALTH, 50.0)
|
|
@@ -117,6 +134,7 @@ public class PiglinBrute extends AbstractPiglin {
|
|
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(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 45fa724f7f6ff911a09d4c20811386fe2a10a80a..137510f81e6454f45010f8d96001ad1ebdddfde6 100644
|
|
--- a/net/minecraft/world/entity/monster/warden/Warden.java
|
|
+++ b/net/minecraft/world/entity/monster/warden/Warden.java
|
|
@@ -123,8 +123,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);
|
|
+ this.moveControl = new org.purpurmc.purpur.controller.MoveControllerWASD(this, 0.5F); // Purpur - Ridables
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.wardenRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.wardenRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.wardenControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void registerGoals() {
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
+ this.targetSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this)); // Purpur - Ridables
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
public Packet<ClientGamePacketListener> getAddEntityPacket(ServerEntity entity) {
|
|
return new ClientboundAddEntityPacket(this, entity, this.hasPose(Pose.EMERGING) ? 1 : 0);
|
|
@@ -280,6 +304,7 @@ public class Warden extends Monster implements VibrationSystem {
|
|
protected void customServerAiStep(ServerLevel level) {
|
|
ProfilerFiller profilerFiller = Profiler.get();
|
|
profilerFiller.push("wardenBrain");
|
|
+ if (getRider() == null || !this.isControllable()) // Purpur - only use brain if no rider
|
|
this.getBrain().tick(level, this);
|
|
profilerFiller.pop();
|
|
super.customServerAiStep(level);
|
|
@@ -382,6 +407,7 @@ public class Warden extends Monster implements VibrationSystem {
|
|
|
|
@Contract("null->false")
|
|
public boolean canTargetEntity(@Nullable Entity entity) {
|
|
+ if (getRider() != null && isControllable()) return false; // Purpur - Ridables
|
|
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 d440e27c81925da6c532de701815f5f7d61fa226..cf92712dbe0eee7296bd641e1acaf9000fca9189 100644
|
|
--- a/net/minecraft/world/entity/npc/Villager.java
|
|
+++ b/net/minecraft/world/entity/npc/Villager.java
|
|
@@ -249,6 +249,28 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
|
}
|
|
// Purpur end - Lobotomize stuck villagers
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.villagerRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.villagerRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.villagerControllable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected void registerGoals() {
|
|
+ this.goalSelector.addGoal(0, new org.purpurmc.purpur.entity.ai.HasRider(this));
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
public Brain<Villager> getBrain() {
|
|
return (Brain<Villager>)super.getBrain();
|
|
@@ -356,7 +378,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
|
} else {
|
|
this.isLobotomized = false;
|
|
}
|
|
- if (!inactive) {
|
|
+ if (!inactive && (getRider() == null || !this.isControllable())) { // Purpur - Ridables
|
|
this.getBrain().tick(level, this); // Paper - EAR 2
|
|
}
|
|
else if (this.isLobotomized && shouldRestock()) restock();
|
|
@@ -416,7 +438,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();
|
|
@@ -429,9 +451,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
|
|
+
|
|
if (this.level().purpurConfig.villagerAllowTrading) // Purpur - Add config for villager trading
|
|
this.startTrading(player);
|
|
}
|
|
diff --git a/net/minecraft/world/entity/npc/WanderingTrader.java b/net/minecraft/world/entity/npc/WanderingTrader.java
|
|
index fa281aba7212be33d71d900564783ed23d4f8df5..10f2b2f96418b059c7f6b43e1f060b0ccb03362f 100644
|
|
--- a/net/minecraft/world/entity/npc/WanderingTrader.java
|
|
+++ b/net/minecraft/world/entity/npc/WanderingTrader.java
|
|
@@ -67,6 +67,23 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill
|
|
}
|
|
// Purpur end - Allow leashing villagers
|
|
|
|
+ // Purpur - start - Ridables
|
|
+ @Override
|
|
+ public boolean isRidable() {
|
|
+ return level().purpurConfig.wanderingTraderRidable;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean dismountsUnderwater() {
|
|
+ return level().purpurConfig.useDismountsUnderwaterTag ? super.dismountsUnderwater() : !level().purpurConfig.wanderingTraderRidableInWater;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isControllable() {
|
|
+ return level().purpurConfig.wanderingTraderControllable;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void registerGoals() {
|
|
this.goalSelector.addGoal(0, new FloatGoal(this));
|
|
@@ -128,8 +145,9 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill
|
|
|
|
if (!this.level().isClientSide()) {
|
|
if (this.getOffers().isEmpty()) {
|
|
- return InteractionResult.CONSUME;
|
|
+ return tryRide(player, hand, InteractionResult.CONSUME); // Purpur - Ridables
|
|
}
|
|
+ if (level().purpurConfig.wanderingTraderRidable && itemInHand.isEmpty()) return tryRide(player, hand); // Purpur - Ridables
|
|
|
|
if (this.level().purpurConfig.wanderingTraderAllowTrading) { // Purpur - Add config for villager trading
|
|
this.setTradingPlayer(player);
|
|
diff --git a/net/minecraft/world/entity/player/Player.java b/net/minecraft/world/entity/player/Player.java
|
|
index 2ce4e79966a8542896d8870e06b2364e182e512e..3c1641a906f301dbfb0f30a597479fb727f4639c 100644
|
|
--- a/net/minecraft/world/entity/player/Player.java
|
|
+++ b/net/minecraft/world/entity/player/Player.java
|
|
@@ -200,6 +200,19 @@ public abstract class Player extends Avatar implements ContainerUser {
|
|
}
|
|
// CraftBukkit end
|
|
|
|
+ // Purpur start - Ridables
|
|
+ public abstract void resetLastActionTime();
|
|
+
|
|
+ @Override
|
|
+ public boolean processClick(InteractionHand hand) {
|
|
+ Entity vehicle = getRootVehicle();
|
|
+ if (vehicle != null && vehicle.getRider() == this) {
|
|
+ return vehicle.onClick(hand);
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
public Player(Level level, GameProfile gameProfile) {
|
|
super(EntityType.PLAYER, level);
|
|
this.setUUID(gameProfile.id());
|
|
diff --git a/net/minecraft/world/entity/projectile/LlamaSpit.java b/net/minecraft/world/entity/projectile/LlamaSpit.java
|
|
index 51366d17e521b1f01ddb2e425328938cd069bc93..3e2cf2f74b0c788ec3ec6fd83ff51a1f52f197e0 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 {
|
|
);
|
|
}
|
|
|
|
+ // Purpur start - Ridables
|
|
+ public void projectileTick() {
|
|
+ super.tick();
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected double getDefaultGravity() {
|
|
return 0.06;
|
|
diff --git a/net/minecraft/world/entity/projectile/WitherSkull.java b/net/minecraft/world/entity/projectile/WitherSkull.java
|
|
index 5e7642b982b58ae21cbf772b1c6667b3429facaf..1c9fae3eddd7372a60192a9361e67c2829078ab9 100644
|
|
--- a/net/minecraft/world/entity/projectile/WitherSkull.java
|
|
+++ b/net/minecraft/world/entity/projectile/WitherSkull.java
|
|
@@ -110,6 +110,14 @@ public class WitherSkull extends AbstractHurtingProjectile {
|
|
}
|
|
// Purpur end - Add canSaveToDisk to Entity
|
|
|
|
+ // Purpur start - Ridables
|
|
+ @Override
|
|
+ public boolean canHitEntity(Entity target) {
|
|
+ // do not hit rider
|
|
+ return target != this.getRider() && super.canHitEntity(target);
|
|
+ }
|
|
+ // Purpur end - Ridables
|
|
+
|
|
@Override
|
|
protected void defineSynchedData(SynchedEntityData.Builder builder) {
|
|
builder.define(DATA_DANGEROUS, false);
|