Files
Purpur/patches/server/0118-Ridables.patch
William Blake Galbreath 67be68c780 Updated Upstream (Tuinity)
Upstream has released updates that appears to apply and compile correctly

Tuinity Changes:
3b008f5 Optimisations
200f825 Actually unload POI data
db64f14 Make sure to despawn entities if they are outside the player general
89276ac Fix villagers aggressively looking at people
8830cef Remove streams for poi searching in some zombie pathfinding
a17dc2c Attempt to fix incorrect nearest village distance tracker updating
ef8cd34 Fix NPE
3e45700Do not return complex parts for entity by class lookup
2110847 Rewrite getClosestEntity
460581d Fix getClosestEntity not working
2cb36ca Optimise non-flush packet sending
784b838 Some fixes
e2dcdd1 Correct return value for ChunkCache#getCubes
968512b Add Velocity natives for encryption and compression (#188)
102d60b Rebuild patches
57fed71 Fix decompression with Velocity natives
442890b Fix decompression with Velocity natives (#191)
0179ea8 Re-Add region manager and notify patch
cbffdcc Do not mark entities in unloaded chunks as being in blocks
f2eef4a Fixup dev branch patches and store reverted patches in revert folder
2020-11-05 18:14:13 -06:00

6374 lines
274 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/src/main/java/net/minecraft/server/AttributeDefaults.java b/src/main/java/net/minecraft/server/AttributeDefaults.java
index 8f95a4e497..ab05b5e403 100644
--- a/src/main/java/net/minecraft/server/AttributeDefaults.java
+++ b/src/main/java/net/minecraft/server/AttributeDefaults.java
@@ -9,7 +9,80 @@ import org.apache.logging.log4j.Logger;
public class AttributeDefaults {
private static final Logger LOGGER = LogManager.getLogger();
- private static final Map<EntityTypes<? extends EntityLiving>, AttributeProvider> b = ImmutableMap.builder().put(EntityTypes.ARMOR_STAND, EntityLiving.cL().a()).put(EntityTypes.BAT, EntityBat.m().a()).put(EntityTypes.BEE, EntityBee.eZ().a()).put(EntityTypes.BLAZE, EntityBlaze.m().a()).put(EntityTypes.CAT, EntityCat.fa().a()).put(EntityTypes.CAVE_SPIDER, EntityCaveSpider.m().a()).put(EntityTypes.CHICKEN, EntityChicken.eK().a()).put(EntityTypes.COD, EntityFish.m().a()).put(EntityTypes.COW, EntityCow.eK().a()).put(EntityTypes.CREEPER, EntityCreeper.m().a()).put(EntityTypes.DOLPHIN, EntityDolphin.eM().a()).put(EntityTypes.DONKEY, EntityHorseChestedAbstract.eL().a()).put(EntityTypes.DROWNED, EntityZombie.eS().a()).put(EntityTypes.ELDER_GUARDIAN, EntityGuardianElder.m().a()).put(EntityTypes.ENDERMAN, EntityEnderman.m().a()).put(EntityTypes.ENDERMITE, EntityEndermite.m().a()).put(EntityTypes.ENDER_DRAGON, EntityEnderDragon.m().a()).put(EntityTypes.EVOKER, EntityEvoker.eK().a()).put(EntityTypes.FOX, EntityFox.eK().a()).put(EntityTypes.GHAST, EntityGhast.eJ().a()).put(EntityTypes.GIANT, EntityGiantZombie.m().a()).put(EntityTypes.GUARDIAN, EntityGuardian.eM().a()).put(EntityTypes.HOGLIN, EntityHoglin.eK().a()).put(EntityTypes.HORSE, EntityHorseAbstract.fi().a()).put(EntityTypes.HUSK, EntityZombie.eS().a()).put(EntityTypes.ILLUSIONER, EntityIllagerIllusioner.eK().a()).put(EntityTypes.IRON_GOLEM, EntityIronGolem.m().a()).put(EntityTypes.LLAMA, EntityLlama.fw().a()).put(EntityTypes.MAGMA_CUBE, EntityMagmaCube.m().a()).put(EntityTypes.MOOSHROOM, EntityCow.eK().a()).put(EntityTypes.MULE, EntityHorseChestedAbstract.eL().a()).put(EntityTypes.OCELOT, EntityOcelot.eK().a()).put(EntityTypes.PANDA, EntityPanda.eY().a()).put(EntityTypes.PARROT, EntityParrot.eU().a()).put(EntityTypes.PHANTOM, EntityMonster.eR().a()).put(EntityTypes.PIG, EntityPig.eK().a()).put(EntityTypes.PIGLIN, EntityPiglin.eT().a()).put(EntityTypes.PIGLIN_BRUTE, EntityPiglinBrute.eS().a()).put(EntityTypes.PILLAGER, EntityPillager.eK().a()).put(EntityTypes.PLAYER, EntityHuman.ep().a()).put(EntityTypes.POLAR_BEAR, EntityPolarBear.eK().a()).put(EntityTypes.PUFFERFISH, EntityFish.m().a()).put(EntityTypes.RABBIT, EntityRabbit.eL().a()).put(EntityTypes.RAVAGER, EntityRavager.m().a()).put(EntityTypes.SALMON, EntityFish.m().a()).put(EntityTypes.SHEEP, EntitySheep.eK().a()).put(EntityTypes.SHULKER, EntityShulker.m().a()).put(EntityTypes.SILVERFISH, EntitySilverfish.m().a()).put(EntityTypes.SKELETON, EntitySkeletonAbstract.m().a()).put(EntityTypes.SKELETON_HORSE, EntityHorseSkeleton.eL().a()).put(EntityTypes.SLIME, EntityMonster.eR().a()).put(EntityTypes.SNOW_GOLEM, EntitySnowman.m().a()).put(EntityTypes.SPIDER, EntitySpider.eK().a()).put(EntityTypes.SQUID, EntitySquid.m().a()).put(EntityTypes.STRAY, EntitySkeletonAbstract.m().a()).put(EntityTypes.STRIDER, EntityStrider.eM().a()).put(EntityTypes.TRADER_LLAMA, EntityLlama.fw().a()).put(EntityTypes.TROPICAL_FISH, EntityFish.m().a()).put(EntityTypes.TURTLE, EntityTurtle.eM().a()).put(EntityTypes.VEX, EntityVex.m().a()).put(EntityTypes.VILLAGER, EntityVillager.eY().a()).put(EntityTypes.VINDICATOR, EntityVindicator.eK().a()).put(EntityTypes.WANDERING_TRADER, EntityInsentient.p().a()).put(EntityTypes.WITCH, EntityWitch.eK().a()).put(EntityTypes.WITHER, EntityWither.eK().a()).put(EntityTypes.WITHER_SKELETON, EntitySkeletonAbstract.m().a()).put(EntityTypes.WOLF, EntityWolf.eU().a()).put(EntityTypes.ZOGLIN, EntityZoglin.m().a()).put(EntityTypes.ZOMBIE, EntityZombie.eS().a()).put(EntityTypes.ZOMBIE_HORSE, EntityHorseZombie.eL().a()).put(EntityTypes.ZOMBIE_VILLAGER, EntityZombie.eS().a()).put(EntityTypes.ZOMBIFIED_PIGLIN, EntityPigZombie.eW().a()).build();
+ private static final Map<EntityTypes<? extends EntityLiving>, AttributeProvider> b = ImmutableMap.<EntityTypes<? extends EntityLiving>, AttributeProvider>builder() // Purpur decompile error
+ .put(EntityTypes.ARMOR_STAND, EntityLiving.cL().a())
+ .put(EntityTypes.BAT, EntityBat.m().a())
+ .put(EntityTypes.BEE, EntityBee.eZ().a())
+ .put(EntityTypes.BLAZE, EntityBlaze.m().a())
+ .put(EntityTypes.CAT, EntityCat.fa().a())
+ .put(EntityTypes.CAVE_SPIDER, EntityCaveSpider.m().a())
+ .put(EntityTypes.CHICKEN, EntityChicken.eK().a())
+ .put(EntityTypes.COD, EntityFish.m().a())
+ .put(EntityTypes.COW, EntityCow.eK().a())
+ .put(EntityTypes.CREEPER, EntityCreeper.m().a())
+ .put(EntityTypes.DOLPHIN, EntityDolphin.eM().a())
+ .put(EntityTypes.DONKEY, EntityHorseChestedAbstract.eL().a())
+ .put(EntityTypes.DROWNED, EntityZombie.eS().a())
+ .put(EntityTypes.ELDER_GUARDIAN, EntityGuardianElder.m().a())
+ .put(EntityTypes.ENDERMAN, EntityEnderman.m().a())
+ .put(EntityTypes.ENDERMITE, EntityEndermite.m().a())
+ .put(EntityTypes.ENDER_DRAGON, EntityEnderDragon.m().a())
+ .put(EntityTypes.EVOKER, EntityEvoker.eK().a())
+ .put(EntityTypes.FOX, EntityFox.eK().a())
+ .put(EntityTypes.GHAST, EntityGhast.eJ().a())
+ .put(EntityTypes.GIANT, EntityGiantZombie.m().a())
+ .put(EntityTypes.GUARDIAN, EntityGuardian.eM().a())
+ .put(EntityTypes.HOGLIN, EntityHoglin.eK().a())
+ .put(EntityTypes.HORSE, EntityHorseAbstract.fi().a())
+ .put(EntityTypes.HUSK, EntityZombie.eS().a())
+ .put(EntityTypes.ILLUSIONER, EntityIllagerIllusioner.eK().a())
+ .put(EntityTypes.IRON_GOLEM, EntityIronGolem.m().a())
+ .put(EntityTypes.LLAMA, EntityLlama.fw().a())
+ .put(EntityTypes.MAGMA_CUBE, EntityMagmaCube.m().a())
+ .put(EntityTypes.MOOSHROOM, EntityCow.eK().a())
+ .put(EntityTypes.MULE, EntityHorseChestedAbstract.eL().a())
+ .put(EntityTypes.OCELOT, EntityOcelot.eK().a())
+ .put(EntityTypes.PANDA, EntityPanda.eY().a())
+ .put(EntityTypes.PARROT, EntityParrot.eU().a())
+ .put(EntityTypes.PHANTOM, EntityPhantom.defaultAttributes().build()) // Purpur
+ .put(EntityTypes.PIG, EntityPig.eK().a())
+ .put(EntityTypes.PIGLIN, EntityPiglin.eT().a())
+ .put(EntityTypes.PIGLIN_BRUTE, EntityPiglinBrute.eS().a())
+ .put(EntityTypes.PILLAGER, EntityPillager.eK().a())
+ .put(EntityTypes.PLAYER, EntityHuman.ep().a())
+ .put(EntityTypes.POLAR_BEAR, EntityPolarBear.eK().a())
+ .put(EntityTypes.PUFFERFISH, EntityFish.m().a())
+ .put(EntityTypes.RABBIT, EntityRabbit.eL().a())
+ .put(EntityTypes.RAVAGER, EntityRavager.m().a())
+ .put(EntityTypes.SALMON, EntityFish.m().a())
+ .put(EntityTypes.SHEEP, EntitySheep.eK().a())
+ .put(EntityTypes.SHULKER, EntityShulker.m().a())
+ .put(EntityTypes.SILVERFISH, EntitySilverfish.m().a())
+ .put(EntityTypes.SKELETON, EntitySkeletonAbstract.m().a())
+ .put(EntityTypes.SKELETON_HORSE, EntityHorseSkeleton.eL().a())
+ .put(EntityTypes.SLIME, EntityMonster.eR().a())
+ .put(EntityTypes.SNOW_GOLEM, EntitySnowman.m().a())
+ .put(EntityTypes.SPIDER, EntitySpider.eK().a())
+ .put(EntityTypes.SQUID, EntitySquid.m().a())
+ .put(EntityTypes.STRAY, EntitySkeletonAbstract.m().a())
+ .put(EntityTypes.STRIDER, EntityStrider.eM().a())
+ .put(EntityTypes.TRADER_LLAMA, EntityLlama.fw().a())
+ .put(EntityTypes.TROPICAL_FISH, EntityFish.m().a())
+ .put(EntityTypes.TURTLE, EntityTurtle.eM().a())
+ .put(EntityTypes.VEX, EntityVex.m().a())
+ .put(EntityTypes.VILLAGER, EntityVillager.eY().a())
+ .put(EntityTypes.VINDICATOR, EntityVindicator.eK().a())
+ .put(EntityTypes.WANDERING_TRADER, EntityInsentient.p().a())
+ .put(EntityTypes.WITCH, EntityWitch.eK().a())
+ .put(EntityTypes.WITHER, EntityWither.eK().a())
+ .put(EntityTypes.WITHER_SKELETON, EntitySkeletonAbstract.m().a())
+ .put(EntityTypes.WOLF, EntityWolf.eU().a())
+ .put(EntityTypes.ZOGLIN, EntityZoglin.m().a())
+ .put(EntityTypes.ZOMBIE, EntityZombie.eS().a())
+ .put(EntityTypes.ZOMBIE_HORSE, EntityHorseZombie.eL().a())
+ .put(EntityTypes.ZOMBIE_VILLAGER, EntityZombie.eS().a())
+ .put(EntityTypes.ZOMBIFIED_PIGLIN, EntityPigZombie.eW().a())
+ .build();
public static AttributeProvider a(EntityTypes<? extends EntityLiving> entitytypes) {
return (AttributeProvider) AttributeDefaults.b.get(entitytypes);
diff --git a/src/main/java/net/minecraft/server/AttributeProvider.java b/src/main/java/net/minecraft/server/AttributeProvider.java
index dd235a6fc4..ac902c614d 100644
--- a/src/main/java/net/minecraft/server/AttributeProvider.java
+++ b/src/main/java/net/minecraft/server/AttributeProvider.java
@@ -101,6 +101,7 @@ public class AttributeProvider {
return this;
}
+ public AttributeProvider build() { return a(); } // Purpur - OBFHELPER
public AttributeProvider a() {
this.b = true;
return new AttributeProvider(this.a);
diff --git a/src/main/java/net/minecraft/server/ControllerLookDolphin.java b/src/main/java/net/minecraft/server/ControllerLookDolphin.java
index e5bdddfc14..8200ba60b7 100644
--- a/src/main/java/net/minecraft/server/ControllerLookDolphin.java
+++ b/src/main/java/net/minecraft/server/ControllerLookDolphin.java
@@ -1,6 +1,6 @@
package net.minecraft.server;
-public class ControllerLookDolphin extends ControllerLook {
+public class ControllerLookDolphin extends net.pl3x.purpur.controller.ControllerLookWASD { // Purpur
private final int h;
@@ -10,7 +10,7 @@ public class ControllerLookDolphin extends ControllerLook {
}
@Override
- public void a() {
+ public void tick() { // Purpur
if (this.d) {
this.d = false;
this.a.aC = this.a(this.a.aC, this.h() + 20.0F, this.b);
diff --git a/src/main/java/net/minecraft/server/ControllerMove.java b/src/main/java/net/minecraft/server/ControllerMove.java
index 8f9fb058c1..eaf4469468 100644
--- a/src/main/java/net/minecraft/server/ControllerMove.java
+++ b/src/main/java/net/minecraft/server/ControllerMove.java
@@ -6,9 +6,9 @@ public class ControllerMove {
protected double b;
protected double c;
protected double d;
- protected double e;
- protected float f;
- protected float g;
+ protected double e; public double getSpeed() { return e; } public void setSpeed(double speed) { this.e = speed; } // Purpur - OBFHELPER
+ protected float f; public float getForward() { return f; } public void setForward(float forward) { this.f = forward; } // Purpur - OBFHELPER
+ protected float g; public float getStrafe() { return g; } public void setStrafe(float strafe) { this.g = strafe; } // Purpur - OBFHELPER
protected ControllerMove.Operation h;
public ControllerMove(EntityInsentient entityinsentient) {
diff --git a/src/main/java/net/minecraft/server/DamageSource.java b/src/main/java/net/minecraft/server/DamageSource.java
index bd0267ee4b..8b36ac2b09 100644
--- a/src/main/java/net/minecraft/server/DamageSource.java
+++ b/src/main/java/net/minecraft/server/DamageSource.java
@@ -56,6 +56,7 @@ public class DamageSource {
return new EntityDamageSource("mob", entityliving);
}
+ public static DamageSource indirectMobAttack(Entity entity, EntityLiving entityliving) { return a(entity, entityliving); } // Purpur - OBFHELPER
public static DamageSource a(Entity entity, EntityLiving entityliving) {
return new EntityDamageSourceIndirect("mob", entity, entityliving);
}
@@ -117,6 +118,7 @@ public class DamageSource {
return this.B;
}
+ public DamageSource setProjectile() { return c(); } // Purpur - OBFHELPER
public DamageSource c() {
this.B = true;
return this;
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 41dcd97f9c..22009f8cdf 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -80,7 +80,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper
private CraftEntity bukkitEntity;
- PlayerChunkMap.EntityTracker tracker; // Paper
+ PlayerChunkMap.EntityTracker tracker; public PlayerChunkMap.EntityTracker getTracker() { return tracker; } // Paper // Purpur
boolean collisionLoadChunks = false; // Paper
Throwable addedToWorldStack; // Paper - entity debug
public CraftEntity getBukkitEntity() {
@@ -105,7 +105,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
private int id;
public boolean i; public final boolean blocksEntitySpawning() { return this.i; } // Paper - OBFHELPER
public final List<Entity> passengers;
- protected int j;
+ protected int j; public int getRideCooldown() { return j; } // Purpur - OBFHELPER
@Nullable
private Entity vehicle;
public boolean attachedToPlayer;
@@ -121,7 +121,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
public float lastYaw;
public float lastPitch;
private AxisAlignedBB boundingBox;
- protected boolean onGround;
+ public boolean onGround; // Purpur - protected -> public
public boolean positionChanged;
public boolean v;
public boolean velocityChanged;
@@ -177,7 +177,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
private boolean az;
private final double[] aA;
private long aB;
- private EntitySize size;
+ protected EntitySize size; // Purpur - private -> protected
private float headHeight;
// CraftBukkit start
public boolean persist = true;
@@ -1488,6 +1488,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
return !this.justCreated && this.M.getDouble(TagsFluid.LAVA) > 0.0D;
}
+ public void moveRelative(float speed, Vec3D motion) { this.a(speed, motion); } // Purpur - OBFHELPER
public void a(float f, Vec3D vec3d) {
Vec3D vec3d1 = a(vec3d, f, this.yaw);
@@ -2243,6 +2244,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
return this.a(entity, false);
}
+ public boolean startRiding(Entity entity, boolean flag) { return a(entity, flag); } // Purpur - OBFHELPER
public boolean a(Entity entity, boolean flag) {
for (Entity entity1 = entity; entity1.vehicle != null; entity1 = entity1.vehicle) {
if (entity1.vehicle == this) {
@@ -2338,6 +2340,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
this.passengers.add(entity);
}
+ // Purpur start
+ if (isRidable() && passengers.get(0) == entity && entity instanceof EntityHuman) {
+ EntityHuman entityhuman = (EntityHuman) entity;
+ onMount(entityhuman);
+ this.rider = entityhuman;
+ }
+ // Purpur end
}
return true; // CraftBukkit
}
@@ -2378,6 +2387,12 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
return false;
}
// Spigot end
+ // Purpur start
+ if (rider != null && passengers.get(0) == rider) {
+ onDismount(rider);
+ this.rider = null;
+ }
+ // Purpur end
this.passengers.remove(entity);
entity.j = 60;
}
@@ -2543,6 +2558,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
this.setFlag(4, flag);
}
+ public boolean isGlowing() { return bE(); } // Purpur - OBFHELPER
public boolean bE() {
return this.glowing || this.world.isClientSide && this.getFlag(6);
}
@@ -2765,6 +2781,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
public void setHeadRotation(float f) {}
+ public void setBodyYaw(float yaw) { n(yaw); } // Purpur - OBFHELPER
public void n(float f) {}
public boolean bL() {
@@ -3199,6 +3216,18 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
return false;
}
+ // Purpur Start
+ public void sendMessage(String str) {
+ sendMessage(org.bukkit.craftbukkit.util.CraftChatMessage.fromStringOrNull(str));
+ }
+
+ public void sendMessage(IChatBaseComponent ichatbasecomponent) {
+ if (ichatbasecomponent != null) {
+ sendMessage(ichatbasecomponent, SystemUtils.getNullUUID());
+ }
+ }
+ // Purpur end
+
@Override
public void sendMessage(IChatBaseComponent ichatbasecomponent, UUID uuid) {}
@@ -3651,4 +3680,47 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
return ((ChunkProviderServer) world.getChunkProvider()).isInEntityTickingChunk(this);
}
// Paper end
+
+ // Purpur start
+ private EntityHuman rider;
+
+ public EntityHuman getRider() {
+ return rider;
+ }
+
+ public boolean hasRider() {
+ return rider != null;
+ }
+
+ public boolean isRidable() {
+ return false;
+ }
+
+ public boolean isRidableInWater() {
+ return false;
+ }
+
+ public void onMount(EntityHuman entityhuman) {
+ if (this instanceof EntityInsentient) {
+ ((EntityInsentient) this).setGoalTarget(null, null, false);
+ ((EntityInsentient) this).getNavigation().stopPathfinding();
+ }
+ entityhuman.setJumping(false); // fixes jump on mount
+ }
+
+ public void onDismount(EntityHuman entityhuman) {
+ }
+
+ public boolean onSpacebar() {
+ return false;
+ }
+
+ public boolean onClick(EnumHand hand) {
+ return false;
+ }
+
+ public boolean processClick(EnumHand hand) {
+ return false;
+ }
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/server/EntityBat.java b/src/main/java/net/minecraft/server/EntityBat.java
index 85371542e4..a031f8778c 100644
--- a/src/main/java/net/minecraft/server/EntityBat.java
+++ b/src/main/java/net/minecraft/server/EntityBat.java
@@ -14,9 +14,48 @@ public class EntityBat extends EntityAmbient {
public EntityBat(EntityTypes<? extends EntityBat> entitytypes, World world) {
super(entitytypes, world);
+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar(this, 0.075F); // Purpur
this.setAsleep(true);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.batRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.batRidableInWater;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.batMaxY;
+ }
+
+ @Override
+ public void onMount(EntityHuman entityhuman) {
+ super.onMount(entityhuman);
+ if (isAsleep()) {
+ setAsleep(false);
+ world.playEffect(null, 1025, new BlockPosition(this).up(), 0);
+ }
+ }
+
+ @Override
+ public void g(Vec3D vec3d) {
+ super.g(vec3d);
+ if (hasRider() && !onGround) {
+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue() * 2;
+ setSpeed(speed);
+ Vec3D mot = getMot();
+ move(EnumMoveType.SELF, mot.multiply(speed, 0.25, speed));
+ setMot(mot.a(0.9D));
+ }
+ }
+ // Purpur end
+
@Override
protected void initDatawatcher() {
super.initDatawatcher();
@@ -61,7 +100,7 @@ public class EntityBat extends EntityAmbient {
protected void collideNearby() {}
public static AttributeProvider.Builder m() {
- return EntityInsentient.p().a(GenericAttributes.MAX_HEALTH, 6.0D);
+ return EntityInsentient.p().a(GenericAttributes.MAX_HEALTH, 6.0D).a(GenericAttributes.FLYING_SPEED, 0.6D); // Purpur
}
public boolean isAsleep() {
@@ -93,6 +132,13 @@ public class EntityBat extends EntityAmbient {
@Override
protected void mobTick() {
+ // Purpur start
+ if (hasRider()) {
+ Vec3D mot = getMot();
+ setMot(mot.x, mot.y + (getVertical() > 0 ? 0.07D : 0.0D), mot.z);
+ return;
+ }
+ // Purpur end
super.mobTick();
BlockPosition blockposition = this.getChunkCoordinates();
BlockPosition blockposition1 = blockposition.up();
diff --git a/src/main/java/net/minecraft/server/EntityBee.java b/src/main/java/net/minecraft/server/EntityBee.java
index f73641ddb3..d8354ec4d1 100644
--- a/src/main/java/net/minecraft/server/EntityBee.java
+++ b/src/main/java/net/minecraft/server/EntityBee.java
@@ -37,6 +37,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
public EntityBee(EntityTypes<? extends EntityBee> entitytypes, World world) {
super(entitytypes, world);
+ final net.pl3x.purpur.controller.ControllerMoveWASDFlying flyingController = new net.pl3x.purpur.controller.ControllerMoveWASDFlying(this, 0.25F, false); // Purpur
// Paper start - apply gravity to bees when they get stuck in the void, fixes MC-167279
this.moveController = new ControllerMoveFlying(this, 20, true) {
@Override
@@ -46,6 +47,22 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
}
super.tick();
}
+
+ // Purpur start
+ @Override
+ public void a() { // tick
+ if (getEntity().hasRider()) {
+ flyingController.tick(getEntity().getRider());
+ } else {
+ tick();
+ }
+ }
+
+ @Override
+ public boolean b() { // isUpdating
+ return getEntity().hasRider() || super.b();
+ }
+ // Purpur end
};
// Paper end
this.lookController = new EntityBee.j(this);
@@ -56,6 +73,35 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
this.a(PathType.FENCE, -1.0F);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.beeRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.beeRidableInWater;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.beeMaxY;
+ }
+
+ @Override
+ public void g(Vec3D vec3d) {
+ super.g(vec3d);
+ if (hasRider() && !onGround) {
+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue() * 2;
+ setSpeed(speed);
+ Vec3D mot = getMot();
+ move(EnumMoveType.SELF, mot.multiply(speed, speed, speed));
+ setMot(mot.a(0.9D));
+ }
+ }
+ // Purpur end
+
@Override
protected void initDatawatcher() {
super.initDatawatcher();
@@ -70,6 +116,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(0, new EntityBee.b(this, 1.399999976158142D, true));
this.goalSelector.a(1, new EntityBee.d());
this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D));
@@ -85,6 +132,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
this.goalSelector.a(7, new EntityBee.g());
this.goalSelector.a(8, new EntityBee.l());
this.goalSelector.a(9, new PathfinderGoalFloat(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, (new EntityBee.h(this)).a(new Class[0]));
this.targetSelector.a(2, new EntityBee.c(this));
this.targetSelector.a(3, new PathfinderGoalUniversalAngerReset<>(this, true));
@@ -555,6 +603,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
private d() {
super(); // CraftBukkit - decompile error
+ this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - enter hive
}
@Override
@@ -617,6 +666,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
private g() {
super(); // CraftBukkit - decompile error
+ this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - grow crop
}
@Override
@@ -681,6 +731,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
private i() {
super(); // CraftBukkit - decompile error
+ this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - go to hive
}
@Override
@@ -904,16 +955,16 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
}
}
- class j extends ControllerLook {
+ class j extends net.pl3x.purpur.controller.ControllerLookWASD { // Purpur
j(EntityInsentient entityinsentient) {
super(entityinsentient);
}
@Override
- public void a() {
+ public void tick() { // Purpur
if (!EntityBee.this.isAngry()) {
- super.a();
+ super.tick(); // Purpur
}
}
diff --git a/src/main/java/net/minecraft/server/EntityBlaze.java b/src/main/java/net/minecraft/server/EntityBlaze.java
index 74082136b3..dcfad16e06 100644
--- a/src/main/java/net/minecraft/server/EntityBlaze.java
+++ b/src/main/java/net/minecraft/server/EntityBlaze.java
@@ -10,6 +10,7 @@ public class EntityBlaze extends EntityMonster {
public EntityBlaze(EntityTypes<? extends EntityBlaze> entitytypes, World world) {
super(entitytypes, world);
+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar(this, 0.3F); // Purpur
this.a(PathType.WATER, -1.0F);
this.a(PathType.LAVA, 8.0F);
this.a(PathType.DANGER_FIRE, 0.0F);
@@ -17,19 +18,50 @@ public class EntityBlaze extends EntityMonster {
this.f = 10;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.blazeRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.blazeRidableInWater;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.blazeMaxY;
+ }
+
+ @Override
+ public void g(Vec3D vec3d) {
+ super.g(vec3d);
+ if (hasRider() && !onGround) {
+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue();
+ setSpeed(speed);
+ Vec3D mot = getMot();
+ move(EnumMoveType.SELF, mot.multiply(speed, 1.0, speed));
+ setMot(mot.a(0.9D));
+ }
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(4, new EntityBlaze.PathfinderGoalBlazeFireball(this));
this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0D));
this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D, 0.0F));
this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
- this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a());
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
+ this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // Purpur - decompile error
this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true));
}
public static AttributeProvider.Builder m() {
- return EntityMonster.eR().a(GenericAttributes.ATTACK_DAMAGE, 6.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.23000000417232513D).a(GenericAttributes.FOLLOW_RANGE, 48.0D);
+ return EntityMonster.eR().a(GenericAttributes.ATTACK_DAMAGE, 6.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.23000000417232513D).a(GenericAttributes.FOLLOW_RANGE, 48.0D).a(GenericAttributes.FLYING_SPEED, 0.6D); // Purpur
}
@Override
@@ -84,6 +116,14 @@ public class EntityBlaze extends EntityMonster {
@Override
protected void mobTick() {
+ // Purpur start
+ if (hasRider()) {
+ Vec3D mot = getMot();
+ setMot(mot.x, getVertical() > 0 ? 0.07D : -0.07D, mot.z);
+ return;
+ }
+ // Purpur end
+
--this.c;
if (this.c <= 0) {
this.c = 100;
diff --git a/src/main/java/net/minecraft/server/EntityCat.java b/src/main/java/net/minecraft/server/EntityCat.java
index 57166a543a..05929d5c53 100644
--- a/src/main/java/net/minecraft/server/EntityCat.java
+++ b/src/main/java/net/minecraft/server/EntityCat.java
@@ -41,6 +41,25 @@ public class EntityCat extends EntityTameableAnimal {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.catRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.catRidableInWater;
+ }
+
+ public void onMount(EntityHuman entityhuman) {
+ super.onMount(entityhuman);
+ setSitting(false);
+ setSleepingWithOwner(false);
+ setHeadDown(false);
+ }
+ // Purpur end
+
public MinecraftKey eU() {
return (MinecraftKey) EntityCat.bq.getOrDefault(this.getCatType(), EntityCat.bq.get(0));
}
@@ -48,7 +67,8 @@ public class EntityCat extends EntityTameableAnimal {
@Override
protected void initPathfinder() {
this.bx = new EntityCat.PathfinderGoalTemptChance(this, 0.6D, EntityCat.br, true);
- this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalFloat(this)); // Purpur
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new PathfinderGoalSit(this));
this.goalSelector.a(2, new EntityCat.b(this));
this.goalSelector.a(3, this.bx);
@@ -60,6 +80,7 @@ public class EntityCat extends EntityTameableAnimal {
this.goalSelector.a(10, new PathfinderGoalBreed(this, 0.8D));
this.goalSelector.a(11, new PathfinderGoalRandomStrollLand(this, 0.8D, 1.0000001E-5F));
this.goalSelector.a(12, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 10.0F));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalRandomTargetNonTamed<>(this, EntityRabbit.class, false, (Predicate) null));
this.targetSelector.a(1, new PathfinderGoalRandomTargetNonTamed<>(this, EntityTurtle.class, false, EntityTurtle.bo));
}
@@ -76,6 +97,7 @@ public class EntityCat extends EntityTameableAnimal {
this.datawatcher.set(EntityCat.bs, i);
}
+ public void setSleepingWithOwner(boolean flag) { x(flag); } // Purpur - OBFHELPER
public void x(boolean flag) {
this.datawatcher.set(EntityCat.bt, flag);
}
@@ -84,6 +106,7 @@ public class EntityCat extends EntityTameableAnimal {
return (Boolean) this.datawatcher.get(EntityCat.bt);
}
+ public void setHeadDown(boolean flag) { y(flag); } // Purpur - OBFHELPER
public void y(boolean flag) {
this.datawatcher.set(EntityCat.bu, flag);
}
@@ -302,6 +325,7 @@ public class EntityCat extends EntityTameableAnimal {
@Override
public EnumInteractionResult b(EntityHuman entityhuman, EnumHand enumhand) {
+ if (hasRider()) return EnumInteractionResult.PASS; // Purpur
ItemStack itemstack = entityhuman.b(enumhand);
Item item = itemstack.getItem();
@@ -399,6 +423,7 @@ public class EntityCat extends EntityTameableAnimal {
public b(EntityCat entitycat) {
this.a = entitycat;
+ this.a(java.util.EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - lay on owner
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityCaveSpider.java b/src/main/java/net/minecraft/server/EntityCaveSpider.java
index 776f3d25a6..2e1f2dec17 100644
--- a/src/main/java/net/minecraft/server/EntityCaveSpider.java
+++ b/src/main/java/net/minecraft/server/EntityCaveSpider.java
@@ -8,6 +8,18 @@ public class EntityCaveSpider extends EntitySpider {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.caveSpiderRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.caveSpiderRidableInWater;
+ }
+ // Purpur end
+
public static AttributeProvider.Builder m() {
return EntitySpider.eK().a(GenericAttributes.MAX_HEALTH, 12.0D);
}
diff --git a/src/main/java/net/minecraft/server/EntityChicken.java b/src/main/java/net/minecraft/server/EntityChicken.java
index 11a612fa39..a16ecd7edc 100644
--- a/src/main/java/net/minecraft/server/EntityChicken.java
+++ b/src/main/java/net/minecraft/server/EntityChicken.java
@@ -18,6 +18,16 @@ public class EntityChicken extends EntityAnimal {
}
// Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.chickenRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.chickenRidableInWater;
+ }
+
@Override
protected void initAttributes(World world) {
if (world != null) {
@@ -31,6 +41,7 @@ public class EntityChicken extends EntityAnimal {
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
//this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D)); // Purpur - moved down
this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D));
this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, EntityChicken.bv));
@@ -41,6 +52,7 @@ public class EntityChicken extends EntityAnimal {
// Purpur start
if (world.purpurConfig.chickenRetaliate) {
this.goalSelector.a(1, new PathfinderGoalMeleeAttack(this, 1.0D, false));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this));
} else {
this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D));
diff --git a/src/main/java/net/minecraft/server/EntityCod.java b/src/main/java/net/minecraft/server/EntityCod.java
index 9a99af6e9c..039fae4c29 100644
--- a/src/main/java/net/minecraft/server/EntityCod.java
+++ b/src/main/java/net/minecraft/server/EntityCod.java
@@ -6,6 +6,18 @@ public class EntityCod extends EntityFishSchool {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.codRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return true;
+ }
+ // Purpur end
+
@Override
protected ItemStack eK() {
return new ItemStack(Items.COD_BUCKET);
diff --git a/src/main/java/net/minecraft/server/EntityComplexPart.java b/src/main/java/net/minecraft/server/EntityComplexPart.java
index c1b1bd123e..26ff230ef7 100644
--- a/src/main/java/net/minecraft/server/EntityComplexPart.java
+++ b/src/main/java/net/minecraft/server/EntityComplexPart.java
@@ -47,4 +47,11 @@ public class EntityComplexPart extends Entity {
public EntitySize a(EntityPose entitypose) {
return this.d;
}
+
+ // Purpur start
+ @Override
+ public EnumInteractionResult a(EntityHuman entityhuman, EnumHand enumhand) {
+ return owner.isAlive() ? owner.tryRide(entityhuman, enumhand) : EnumInteractionResult.PASS;
+ }
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/server/EntityCow.java b/src/main/java/net/minecraft/server/EntityCow.java
index cfb009c811..1219b0aa9c 100644
--- a/src/main/java/net/minecraft/server/EntityCow.java
+++ b/src/main/java/net/minecraft/server/EntityCow.java
@@ -11,9 +11,22 @@ public class EntityCow extends EntityAnimal {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.cowRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.cowRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new PathfinderGoalPanic(this, 2.0D));
this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D));
if (world.purpurConfig.cowFeedMushrooms > 0) this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.25D, RecipeItemStack.a(Items.WHEAT, Blocks.RED_MUSHROOM.getItem(), Blocks.BROWN_MUSHROOM.getItem()), false)); else // Purpur
@@ -55,6 +68,7 @@ public class EntityCow extends EntityAnimal {
@Override
public EnumInteractionResult b(EntityHuman entityhuman, EnumHand enumhand) {
+ if (hasRider()) return EnumInteractionResult.PASS; // Purpur
ItemStack itemstack = entityhuman.b(enumhand);
if (itemstack.getItem() == Items.BUCKET && !this.isBaby()) {
@@ -62,7 +76,7 @@ public class EntityCow extends EntityAnimal {
org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((WorldServer) entityhuman.world, entityhuman, this.getChunkCoordinates(), this.getChunkCoordinates(), null, itemstack, Items.MILK_BUCKET, enumhand); // Paper - add enumHand
if (event.isCancelled()) {
- return EnumInteractionResult.PASS;
+ return tryRide(entityhuman, enumhand); // Purpur
}
// CraftBukkit end
@@ -73,7 +87,7 @@ public class EntityCow extends EntityAnimal {
return EnumInteractionResult.a(this.world.isClientSide);
// Purpur start - feed mushroom to change to mooshroom
} else if (world.purpurConfig.cowFeedMushrooms > 0 && getEntityType() != EntityTypes.MOOSHROOM && isMushroom(itemstack)) {
- return feedMushroom(entityhuman, itemstack);
+ return feedMushroom(entityhuman, enumhand, itemstack);
// Purpur end
} else {
return super.b(entityhuman, enumhand);
@@ -96,7 +110,7 @@ public class EntityCow extends EntityAnimal {
}
}
- private EnumInteractionResult feedMushroom(EntityHuman entityhuman, ItemStack itemstack) {
+ private EnumInteractionResult feedMushroom(EntityHuman entityhuman, EnumHand enumhand, ItemStack itemstack) {
world.broadcastEntityEffect(this, (byte) 18); // hearts
playSound(SoundEffects.ENTITY_COW_MILK, 1.0F, 1.0F);
if (incrementFeedCount(itemstack) < world.purpurConfig.cowFeedMushrooms) {
@@ -107,7 +121,7 @@ public class EntityCow extends EntityAnimal {
}
EntityMushroomCow mooshroom = EntityTypes.MOOSHROOM.create(world);
if (mooshroom == null) {
- return EnumInteractionResult.PASS;
+ return tryRide(entityhuman, enumhand);
}
if (itemstack.getItem() == Blocks.BROWN_MUSHROOM.getItem()) {
mooshroom.setVariant(EntityMushroomCow.Type.BROWN);
@@ -126,10 +140,10 @@ public class EntityCow extends EntityAnimal {
mooshroom.setCustomName(this.getCustomName());
}
if (CraftEventFactory.callEntityTransformEvent(this, mooshroom, org.bukkit.event.entity.EntityTransformEvent.TransformReason.INFECTION).isCancelled()) {
- return EnumInteractionResult.PASS;
+ return tryRide(entityhuman, enumhand);
}
if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), mooshroom.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.INFECTED).callEvent()) {
- return EnumInteractionResult.PASS;
+ return tryRide(entityhuman, enumhand);
}
this.world.addEntity(mooshroom);
this.die();
diff --git a/src/main/java/net/minecraft/server/EntityCreeper.java b/src/main/java/net/minecraft/server/EntityCreeper.java
index 2256b81624..d186f257fa 100644
--- a/src/main/java/net/minecraft/server/EntityCreeper.java
+++ b/src/main/java/net/minecraft/server/EntityCreeper.java
@@ -18,12 +18,27 @@ public class EntityCreeper extends EntityMonster {
public int maxFuseTicks = 30;
public int explosionRadius = 3;
private int bs;
+ // Purpur start
+ private int spacebarCharge = 0;
+ private int prevSpacebarCharge = 0;
+ private int powerToggleDelay = 0;
+ // Purpur end
public EntityCreeper(EntityTypes<? extends EntityCreeper> entitytypes, World world) {
super(entitytypes, world);
}
// Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.creeperRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.creeperRidableInWater;
+ }
+
@Override
public GroupDataEntity prepare(WorldAccess worldaccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @javax.annotation.Nullable GroupDataEntity groupdataentity, @javax.annotation.Nullable NBTTagCompound nbttagcompound) {
double chance = worldaccess.getMinecraftWorld().purpurConfig.creeperChargedChance;
@@ -32,18 +47,69 @@ public class EntityCreeper extends EntityMonster {
}
return super.prepare(worldaccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound);
}
+
+ @Override
+ protected void mobTick() {
+ if (powerToggleDelay > 0) {
+ powerToggleDelay--;
+ }
+ if (hasRider()) {
+ if (getRider().getForward() != 0 || getRider().getStrafe() != 0) {
+ spacebarCharge = 0;
+ setIgnited(false);
+ }
+ if (spacebarCharge == prevSpacebarCharge) {
+ spacebarCharge = 0;
+ }
+ prevSpacebarCharge = spacebarCharge;
+ }
+ super.mobTick();
+ }
+
+ @Override
+ public void onMount(EntityHuman entityhuman) {
+ super.onMount(entityhuman);
+ setIgnited(false);
+ }
+
+ @Override
+ public boolean onSpacebar() {
+ if (powerToggleDelay > 0) {
+ return true; // just toggled power, do not jump or ignite
+ }
+ spacebarCharge++;
+ if (spacebarCharge > maxFuseTicks - 2) {
+ spacebarCharge = 0;
+ if (getRider().getBukkitEntity().hasPermission("allow.powered.creeper")) {
+ powerToggleDelay = 20;
+ setPowered(!isPowered());
+ setIgnited(false);
+ return true;
+ }
+ }
+ if (!isIgnited()) {
+ if (hasRider() && getRider().getForward() == 0 && getRider().getStrafe() == 0 &&
+ getRider().getBukkitEntity().hasPermission("allow.special.creeper")) {
+ setIgnited(true);
+ return true;
+ }
+ }
+ return getForward() == 0 && getStrafe() == 0; // do not jump if standing still
+ }
// Purpur end
@Override
protected void initPathfinder() {
this.goalSelector.a(1, new PathfinderGoalFloat(this));
this.goalSelector.a(2, new PathfinderGoalSwell(this));
+ this.goalSelector.a(3, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityOcelot.class, 6.0F, 1.0D, 1.2D));
this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityCat.class, 6.0F, 1.0D, 1.2D));
this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, 1.0D, false));
this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 0.8D));
this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true));
this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, new Class[0]));
}
@@ -174,6 +240,7 @@ public class EntityCreeper extends EntityMonster {
return (Integer) this.datawatcher.get(EntityCreeper.b);
}
+ public void setSwellDirection(int i) { a(i); } // Purpur - OBFHELPER
public void a(int i) {
this.datawatcher.set(EntityCreeper.b, i);
}
@@ -274,6 +341,7 @@ public class EntityCreeper extends EntityMonster {
com.destroystokyo.paper.event.entity.CreeperIgniteEvent event = new com.destroystokyo.paper.event.entity.CreeperIgniteEvent((org.bukkit.entity.Creeper) getBukkitEntity(), ignited);
if (event.callEvent()) {
this.datawatcher.set(EntityCreeper.d, event.isIgnited());
+ if (!event.isIgnited()) setSwellDirection(-1); // Purpur
}
}
// Paper end
diff --git a/src/main/java/net/minecraft/server/EntityDolphin.java b/src/main/java/net/minecraft/server/EntityDolphin.java
index 664f969336..9d5d143a99 100644
--- a/src/main/java/net/minecraft/server/EntityDolphin.java
+++ b/src/main/java/net/minecraft/server/EntityDolphin.java
@@ -17,6 +17,7 @@ public class EntityDolphin extends EntityWaterAnimal {
public static final Predicate<EntityItem> b = (entityitem) -> {
return !entityitem.p() && entityitem.isAlive() && entityitem.isInWater();
};
+ private int spitCooldown; // Purpur
public EntityDolphin(EntityTypes<? extends EntityDolphin> entitytypes, World world) {
super(entitytypes, world);
@@ -25,6 +26,45 @@ public class EntityDolphin extends EntityWaterAnimal {
this.setCanPickupLoot(true);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.dolphinRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return true;
+ }
+
+ @Override
+ public boolean onSpacebar() {
+ if (spitCooldown == 0 && hasRider()) {
+ spitCooldown = world.purpurConfig.dolphinSpitCooldown;
+ if (!hasRider()) {
+ return false;
+ }
+
+ 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());
+
+ net.pl3x.purpur.entity.DolphinSpit spit = new net.pl3x.purpur.entity.DolphinSpit(world, this);
+ spit.shoot(target.getX() - locX(), target.getY() - locY(), target.getZ() - locZ(), world.purpurConfig.dolphinSpitSpeed, 5.0F);
+
+ world.addEntity(spit);
+ playSound(SoundEffects.ENTITY_DOLPHIN_ATTACK, 1.0F, 1.0F + (random.nextFloat() - random.nextFloat()) * 0.2F);
+ return true;
+ }
+ return false;
+ }
+ // Purpur end
+
@Nullable
@Override
public GroupDataEntity prepare(WorldAccess worldaccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) {
@@ -99,6 +139,7 @@ public class EntityDolphin extends EntityWaterAnimal {
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalBreath(this));
this.goalSelector.a(0, new PathfinderGoalWater(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new EntityDolphin.b(this));
this.goalSelector.a(2, new EntityDolphin.c(this, 4.0D));
this.goalSelector.a(4, new PathfinderGoalRandomSwim(this, 1.0D, 10));
@@ -109,6 +150,7 @@ public class EntityDolphin extends EntityWaterAnimal {
this.goalSelector.a(8, new EntityDolphin.d());
this.goalSelector.a(8, new PathfinderGoalFollowBoat(this));
this.goalSelector.a(9, new PathfinderGoalAvoidTarget<>(this, EntityGuardian.class, 8.0F, 1.0D, 1.0D));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityGuardian.class})).a(new Class[0])); // CraftBukkit - decompile error
}
@@ -160,7 +202,7 @@ public class EntityDolphin extends EntityWaterAnimal {
@Override
protected boolean n(Entity entity) {
- return true;
+ return getRideCooldown() <= 0; // Purpur - make dolphin honor ride cooldown like all other non-boss mobs
}
@Override
@@ -195,6 +237,9 @@ public class EntityDolphin extends EntityWaterAnimal {
@Override
public void tick() {
super.tick();
+ if (spitCooldown > 0) {
+ spitCooldown--;
+ }
if (this.isNoAI()) {
this.setAirTicks(this.bH());
} else {
@@ -468,7 +513,7 @@ public class EntityDolphin extends EntityWaterAnimal {
private int b;
- private d() {}
+ private d() { this.a(java.util.EnumSet.of(PathfinderGoal.Type.MOVE)); } // Purpur - play with item
@Override
public boolean a() {
@@ -536,7 +581,7 @@ public class EntityDolphin extends EntityWaterAnimal {
}
}
- static class a extends ControllerMove {
+ static class a extends net.pl3x.purpur.controller.ControllerMoveWASDWater { // Purpur
private final EntityDolphin i;
@@ -546,7 +591,20 @@ public class EntityDolphin extends EntityWaterAnimal {
}
@Override
- public void a() {
+ // Purpur start
+ public void tick(EntityHuman rider) {
+ if (this.i.getAirTicks() < 150) {
+ // if drowning override player WASD controls to find air
+ tick();
+ } else {
+ super.tick(rider);
+ this.i.setMot(this.i.getMot().add(0.0D, 0.005D, 0.0D));
+ }
+ }
+
+ @Override
+ public void tick() {
+ // Purpur end
if (this.i.isInWater()) {
this.i.setMot(this.i.getMot().add(0.0D, 0.005D, 0.0D));
}
diff --git a/src/main/java/net/minecraft/server/EntityDrowned.java b/src/main/java/net/minecraft/server/EntityDrowned.java
index 1a10281692..125eab60f2 100644
--- a/src/main/java/net/minecraft/server/EntityDrowned.java
+++ b/src/main/java/net/minecraft/server/EntityDrowned.java
@@ -22,6 +22,16 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity {
}
// Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.drownedRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.drownedRidableInWater;
+ }
+
@Override
public boolean jockeyOnlyBaby() {
return world.purpurConfig.drownedJockeyOnlyBaby;
@@ -219,7 +229,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity {
this.d = flag;
}
- static class d extends ControllerMove {
+ static class d extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur
private final EntityDrowned i;
@@ -229,7 +239,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity {
}
@Override
- public void a() {
+ public void tick() { // Purpur
EntityLiving entityliving = this.i.getGoalTarget();
if (this.i.eW() && this.i.isInWater()) {
@@ -262,7 +272,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity {
this.i.setMot(this.i.getMot().add(0.0D, -0.008D, 0.0D));
}
- super.a();
+ super.tick(); // Purpur
}
}
@@ -401,6 +411,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity {
this.a = entitydrowned;
this.b = d0;
this.c = i;
+ this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - swim up
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java
index d2fcd0bc16..fd1e966d1a 100644
--- a/src/main/java/net/minecraft/server/EntityEnderDragon.java
+++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java
@@ -46,6 +46,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
private final int[] bK = new int[24];
private final Path bL = new Path();
private Explosion explosionSource = new Explosion(null, this, null, null, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, Explosion.Effect.DESTROY); // CraftBukkit - reusable source for CraftTNTPrimed.getSource()
+ private boolean hadRider; // Purpur
public EntityEnderDragon(EntityTypes<? extends EntityEnderDragon> entitytypes, World world) {
super(EntityTypes.ENDER_DRAGON, world);
@@ -60,9 +61,43 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
}
this.bG = new DragonControllerManager(this);
+ // Purpur start
+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASDFlying(this) {
+ @Override
+ public void tick() {
+ // dragon doesn't use the controller. do nothing
+ }
+ };
+ this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this) {
+ @Override
+ public void tick() {
+ // dragon doesn't use the controller. do nothing
+ }
+
+ @Override
+ public void tick(EntityHuman rider) {
+ setYawPitch(rider.yaw - 180F, rider.pitch * 0.5F);
+ }
+ };
+ // Purpur end
}
// Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.enderDragonRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.enderDragonRidableInWater;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.enderDragonMaxY;
+ }
+
@Override
public void initAttributes(World world) {
if (world != null) {
@@ -104,6 +139,37 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
@Override
public void movementTick() {
+ // Purpur start
+ boolean hasRider = getRider() != null;
+ if (hasRider) {
+ if (!hadRider) {
+ hadRider = true;
+ noclip = false;
+ this.size = EntitySize.b(4.0F, 2.0F);
+ }
+
+ // dragon doesn't use controllers, so must tick manually
+ moveController.a();
+ lookController.a();
+
+ moveRelative((float) getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * 0.1F, new Vec3D(-getStrafe(), getVertical(), -getForward()));
+ Vec3D mot = getMot();
+ setMot(mot);
+ move(EnumMoveType.PLAYER, mot);
+
+ mot = mot.multiply(0.9F, 0.9F, 0.9F);
+ setMot(mot);
+
+ // control wing flap speed on client
+ getDragonControllerManager().setControllerPhase(mot.getX() * mot.getX() + mot.getZ() * mot.getZ() < 0.005F ? DragonControllerPhase.HOVER : DragonControllerPhase.HOLDING_PATTERN);
+ } else if (hadRider) {
+ hadRider = false;
+ noclip = true;
+ this.size = EntitySize.b(16.0F, 8.0F);
+ getDragonControllerManager().setControllerPhase(DragonControllerPhase.HOLDING_PATTERN); // HoldingPattern
+ }
+ // Purpur end
+
float f;
float f1;
@@ -125,6 +191,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
this.bp = this.bq;
if (this.dl()) {
+ if (hasRider) ejectPassengers(); // Purpur
f = (this.random.nextFloat() - 0.5F) * 8.0F;
f1 = (this.random.nextFloat() - 0.5F) * 4.0F;
float f2 = (this.random.nextFloat() - 0.5F) * 8.0F;
@@ -136,9 +203,9 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
f1 = 0.2F / (MathHelper.sqrt(c(vec3d)) * 10.0F + 1.0F);
f1 *= (float) Math.pow(2.0D, vec3d.y);
- if (this.bG.a().a()) {
+ if (!hasRider && this.bG.a().a()) { // Purpur
this.bq += 0.1F;
- } else if (this.br) {
+ } else if (!hasRider && this.br) { // Purpur
this.bq += f1 * 0.5F;
} else {
this.bq += f1;
@@ -182,7 +249,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
}
this.bG.a().b();
- } else {
+ } else if (!hasRider) { // Purpur
IDragonController idragoncontroller = this.bG.a();
idragoncontroller.c();
@@ -249,7 +316,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
this.a(this.bz, (double) (f11 * 0.5F), 0.0D, (double) (-f12 * 0.5F));
this.a(this.bD, (double) (f12 * 4.5F), 2.0D, (double) (f11 * 4.5F));
this.a(this.bE, (double) (f12 * -4.5F), 2.0D, (double) (f11 * -4.5F));
- if (!this.world.isClientSide && this.hurtTicks == 0) {
+ if (!hasRider && !this.world.isClientSide && this.hurtTicks == 0) { // Purpur
this.a(this.world.getEntities(this, this.bD.getBoundingBox().grow(4.0D, 2.0D, 4.0D).d(0.0D, -2.0D, 0.0D), IEntitySelector.e));
this.a(this.world.getEntities(this, this.bE.getBoundingBox().grow(4.0D, 2.0D, 4.0D).d(0.0D, -2.0D, 0.0D), IEntitySelector.e));
this.b(this.world.getEntities(this, this.bo.getBoundingBox().g(1.0D), IEntitySelector.e));
@@ -292,7 +359,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
}
if (!this.world.isClientSide) {
- this.br = this.b(this.bo.getBoundingBox()) | this.b(this.by.getBoundingBox()) | this.b(this.bz.getBoundingBox());
+ this.br = !hasRider && this.b(this.bo.getBoundingBox()) | this.b(this.by.getBoundingBox()) | this.b(this.bz.getBoundingBox()); // Purpur
if (this.bF != null) {
this.bF.b(this);
}
@@ -959,7 +1026,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
@Override
protected boolean n(Entity entity) {
- return false;
+ return getRideCooldown() <= 0; // Purpur
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityEnderman.java b/src/main/java/net/minecraft/server/EntityEnderman.java
index e336403266..995849212c 100644
--- a/src/main/java/net/minecraft/server/EntityEnderman.java
+++ b/src/main/java/net/minecraft/server/EntityEnderman.java
@@ -30,9 +30,22 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable {
this.a(PathType.WATER, -1.0F);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.endermanRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.endermanRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new EntityEnderman.a(this));
this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0D, false));
this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D, 0.0F));
@@ -40,6 +53,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable {
this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
this.goalSelector.a(10, new EntityEnderman.PathfinderGoalEndermanPlaceBlock(this));
this.goalSelector.a(11, new EntityEnderman.PathfinderGoalEndermanPickupBlock(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new EntityEnderman.PathfinderGoalPlayerWhoLookedAtTarget(this, this::a_));
this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, new Class[0]));
this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityEndermite.class, 10, true, false, EntityEnderman.bq));
@@ -220,7 +234,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable {
@Override
protected void mobTick() {
- if (this.world.isDay() && this.ticksLived >= this.bs + 600) {
+ if (!hasRider() && this.world.isDay() && this.ticksLived >= this.bs + 600) { // Purpur - no random teleporting
float f = this.aR();
if (f > 0.5F && this.world.e(this.getChunkCoordinates()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper
@@ -322,6 +336,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable {
if (this.isInvulnerable(damagesource)) {
return false;
} else if (net.pl3x.purpur.PurpurConfig.endermanShortHeight && damagesource == DamageSource.STUCK) { return false; // Purpur - no suffocation damage if short height
+ } else if (hasRider()) { return super.damageEntity(damagesource, f); // Purpur - no teleporting on damage
} else if (damagesource instanceof EntityDamageSourceIndirect) {
if (this.tryEscape(EndermanEscapeEvent.Reason.INDIRECT)) { // Paper start
for (int i = 0; i < 64; ++i) {
@@ -366,6 +381,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable {
public PathfinderGoalEndermanPickupBlock(EntityEnderman entityenderman) {
this.enderman = entityenderman;
+ this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur
}
@Override
@@ -408,6 +424,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable {
public PathfinderGoalEndermanPlaceBlock(EntityEnderman entityenderman) {
this.a = entityenderman;
+ this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityEndermite.java b/src/main/java/net/minecraft/server/EntityEndermite.java
index fcebf36312..7eef7f523a 100644
--- a/src/main/java/net/minecraft/server/EntityEndermite.java
+++ b/src/main/java/net/minecraft/server/EntityEndermite.java
@@ -12,14 +12,28 @@ public class EntityEndermite extends EntityMonster {
this.f = 3;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.endermiteRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.endermiteRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0D, false));
this.goalSelector.a(3, new PathfinderGoalRandomStrollLand(this, 1.0D));
this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
- this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a());
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
+ this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // Purpur - decompile error
this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true));
}
diff --git a/src/main/java/net/minecraft/server/EntityEvoker.java b/src/main/java/net/minecraft/server/EntityEvoker.java
index f40fbef32f..c75dc75611 100644
--- a/src/main/java/net/minecraft/server/EntityEvoker.java
+++ b/src/main/java/net/minecraft/server/EntityEvoker.java
@@ -12,10 +12,23 @@ public class EntityEvoker extends EntityIllagerWizard {
this.f = 10;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.evokerRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.evokerRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
super.initPathfinder();
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new EntityEvoker.b());
this.goalSelector.a(2, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 0.6D, 1.0D));
this.goalSelector.a(4, new EntityEvoker.c());
@@ -24,6 +37,7 @@ public class EntityEvoker extends EntityIllagerWizard {
this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D));
this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F));
this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // Paper - decompile fix
this.targetSelector.a(2, (new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)).a(300));
this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)).a(300));
@@ -104,6 +118,7 @@ public class EntityEvoker extends EntityIllagerWizard {
public d() {
super();
+ this.a(java.util.EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - wolololo spell
}
@Override
@@ -182,6 +197,7 @@ public class EntityEvoker extends EntityIllagerWizard {
private c() {
super();
this.e = (new PathfinderTargetCondition()).a(16.0D).c().e().a().b();
+ this.a(java.util.EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - summon spell
}
@Override
@@ -238,6 +254,7 @@ public class EntityEvoker extends EntityIllagerWizard {
private a() {
super();
+ this.a(java.util.EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - attack with spell
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityFish.java b/src/main/java/net/minecraft/server/EntityFish.java
index 9b84564401..668f9d61b7 100644
--- a/src/main/java/net/minecraft/server/EntityFish.java
+++ b/src/main/java/net/minecraft/server/EntityFish.java
@@ -70,13 +70,12 @@ public abstract class EntityFish extends EntityWaterAnimal {
@Override
protected void initPathfinder() {
super.initPathfinder();
- this.goalSelector.a(0, new PathfinderGoalPanic(this, 1.25D));
- PathfinderGoalSelector pathfindergoalselector = this.goalSelector;
- Predicate predicate = IEntitySelector.g;
-
- predicate.getClass();
- pathfindergoalselector.a(2, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 1.6D, 1.4D, predicate::test));
- this.goalSelector.a(4, new EntityFish.b(this));
+ // Purpur start
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
+ this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D));
+ this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 1.6D, 1.4D, IEntitySelector.g::test)); // Purpur - decompile error
+ this.goalSelector.a(5, new EntityFish.b(this));
+ // Purpur end
}
@Override
@@ -87,7 +86,7 @@ public abstract class EntityFish extends EntityWaterAnimal {
@Override
public void g(Vec3D vec3d) {
if (this.doAITick() && this.isInWater()) {
- this.a(0.01F, vec3d);
+ this.a(hasRider() ? getSpeed() : 0.01F, vec3d); // Purpur
this.move(EnumMoveType.SELF, this.getMot());
this.setMot(this.getMot().a(0.9D));
if (this.getGoalTarget() == null) {
@@ -161,9 +160,9 @@ public abstract class EntityFish extends EntityWaterAnimal {
@Override
protected void b(BlockPosition blockposition, IBlockData iblockdata) {}
- static class a extends ControllerMove {
+ static class a extends net.pl3x.purpur.controller.ControllerMoveWASDWater { // Purpur
- private final EntityFish i;
+ private final EntityFish i; public EntityFish getFish() { return i; } // Purpur - OBFHELPER
a(EntityFish entityfish) {
super(entityfish);
@@ -171,7 +170,15 @@ public abstract class EntityFish extends EntityWaterAnimal {
}
@Override
- public void a() {
+ // Purpur start
+ public void tick(EntityHuman rider) {
+ super.tick(rider);
+ getFish().setMot(getFish().getMot().add(0.0D, 0.005D, 0.0D));
+ }
+
+ @Override
+ public void tick() {
+ // Purpur end
if (this.i.a((Tag) TagsFluid.WATER)) {
this.i.setMot(this.i.getMot().add(0.0D, 0.005D, 0.0D));
}
diff --git a/src/main/java/net/minecraft/server/EntityFishSchool.java b/src/main/java/net/minecraft/server/EntityFishSchool.java
index 08372b7226..6a8e15f016 100644
--- a/src/main/java/net/minecraft/server/EntityFishSchool.java
+++ b/src/main/java/net/minecraft/server/EntityFishSchool.java
@@ -16,7 +16,7 @@ public abstract class EntityFishSchool extends EntityFish {
@Override
protected void initPathfinder() {
super.initPathfinder();
- this.goalSelector.a(5, new PathfinderGoalFishSchool(this));
+ this.goalSelector.a(6, new PathfinderGoalFishSchool(this)); // Purpur
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityFox.java b/src/main/java/net/minecraft/server/EntityFox.java
index 8845afd83d..f5defe4713 100644
--- a/src/main/java/net/minecraft/server/EntityFox.java
+++ b/src/main/java/net/minecraft/server/EntityFox.java
@@ -55,6 +55,39 @@ public class EntityFox extends EntityAnimal {
this.setCanPickupLoot(true);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.foxRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.foxRidableInWater;
+ }
+
+ @Override
+ public float getJumpHeight() {
+ return !hasRider() ? super.getJumpHeight() : 0.5F;
+ }
+
+ @Override
+ public void onMount(EntityHuman entityhuman) {
+ super.onMount(entityhuman);
+ setCanPickupLoot(false);
+ stopActions();
+ setChasing(false);
+ spit(getEquipment(EnumItemSlot.MAINHAND));
+ setSlot(EnumItemSlot.MAINHAND, ItemStack.NULL_ITEM);
+ }
+
+ @Override
+ public void onDismount(EntityHuman entityhuman) {
+ super.onDismount(entityhuman);
+ setCanPickupLoot(true);
+ }
+ // Purpur end
+
@Override
protected void initDatawatcher() {
super.initDatawatcher();
@@ -74,6 +107,7 @@ public class EntityFox extends EntityAnimal {
return entityliving instanceof EntityFishSchool;
});
this.goalSelector.a(0, new EntityFox.g());
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new EntityFox.b());
this.goalSelector.a(2, new EntityFox.n(2.2D));
this.goalSelector.a(3, new EntityFox.e(1.0D));
@@ -99,6 +133,7 @@ public class EntityFox extends EntityAnimal {
this.goalSelector.a(11, new EntityFox.p());
this.goalSelector.a(12, new EntityFox.j(this, EntityHuman.class, 24.0F));
this.goalSelector.a(13, new EntityFox.r());
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(3, new EntityFox.a(EntityLiving.class, false, false, (entityliving) -> {
return EntityFox.bt.test(entityliving) && !this.c(entityliving.getUniqueID());
}));
@@ -386,6 +421,7 @@ public class EntityFox extends EntityAnimal {
return itemstack1.isEmpty() || this.bD > 0 && item.isFood() && !itemstack1.getItem().isFood();
}
+ public void spit(ItemStack itemstack) { m(itemstack); } // Purpur - OBFHELPER
private void m(ItemStack itemstack) {
if (!itemstack.isEmpty() && !this.world.isClientSide) {
EntityItem entityitem = new EntityItem(this.world, this.locX() + this.getLookDirection().x, this.locY() + 1.0D, this.locZ() + this.getLookDirection().z, itemstack);
@@ -481,6 +517,7 @@ public class EntityFox extends EntityAnimal {
return this.t(16);
}
+ public void setChasing(boolean flag) { u(flag); } // Purpur - OBFHELPER
public void u(boolean flag) {
this.d(16, flag);
}
@@ -523,6 +560,7 @@ public class EntityFox extends EntityAnimal {
this.setSleeping(false);
}
+ public void stopActions() { fd(); } // Purpur - OBFHELPER
private void fd() {
this.w(false);
this.setCrouching(false);
@@ -688,16 +726,16 @@ public class EntityFox extends EntityAnimal {
}
}
- public class k extends ControllerLook {
+ public class k extends net.pl3x.purpur.controller.ControllerLookWASD { // Purpur
public k() {
super(EntityFox.this);
}
@Override
- public void a() {
+ public void tick() { // Purpur
if (!EntityFox.this.isSleeping()) {
- super.a();
+ super.tick(); // Purpur
}
}
@@ -1367,16 +1405,16 @@ public class EntityFox extends EntityAnimal {
}
}
- class m extends ControllerMove {
+ class m extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur
public m() {
super(EntityFox.this);
}
@Override
- public void a() {
+ public void tick() { // Purpur
if (EntityFox.this.fe()) {
- super.a();
+ super.tick(); // Purpur
}
}
diff --git a/src/main/java/net/minecraft/server/EntityGhast.java b/src/main/java/net/minecraft/server/EntityGhast.java
index a67611c4f9..216506a7b1 100644
--- a/src/main/java/net/minecraft/server/EntityGhast.java
+++ b/src/main/java/net/minecraft/server/EntityGhast.java
@@ -14,11 +14,42 @@ public class EntityGhast extends EntityFlying implements IMonster {
this.moveController = new EntityGhast.ControllerGhast(this);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.ghastRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.ghastRidableInWater;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.ghastMaxY;
+ }
+
+ @Override
+ public void g(Vec3D vec3d) {
+ super.g(vec3d);
+ if (hasRider() && !onGround) {
+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue();
+ setSpeed(speed);
+ Vec3D mot = getMot();
+ move(EnumMoveType.SELF, mot.multiply(speed, 1.0, speed));
+ setMot(mot.a(0.9D));
+ }
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(5, new EntityGhast.PathfinderGoalGhastIdleMove(this));
this.goalSelector.a(7, new EntityGhast.PathfinderGoalGhastMoveTowardsTarget(this));
this.goalSelector.a(7, new EntityGhast.PathfinderGoalGhastAttackTarget(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, (entityliving) -> {
return Math.abs(entityliving.locY() - this.locY()) <= 4.0D;
}));
@@ -56,7 +87,7 @@ public class EntityGhast extends EntityFlying implements IMonster {
}
public static AttributeProvider.Builder eJ() {
- return EntityInsentient.p().a(GenericAttributes.MAX_HEALTH, 10.0D).a(GenericAttributes.FOLLOW_RANGE, 100.0D);
+ return EntityInsentient.p().a(GenericAttributes.MAX_HEALTH, 10.0D).a(GenericAttributes.FOLLOW_RANGE, 100.0D).a(GenericAttributes.FLYING_SPEED, 0.6D); // Purpur
}
@Override
@@ -255,7 +286,7 @@ public class EntityGhast extends EntityFlying implements IMonster {
}
}
- static class ControllerGhast extends ControllerMove {
+ static class ControllerGhast extends net.pl3x.purpur.controller.ControllerMoveWASDFlying { // Purpur
private final EntityGhast i;
private int j;
@@ -266,7 +297,7 @@ public class EntityGhast extends EntityFlying implements IMonster {
}
@Override
- public void a() {
+ public void tick() { // Purpur
if (this.h == ControllerMove.Operation.MOVE_TO) {
if (this.j-- <= 0) {
this.j += this.i.getRandom().nextInt(5) + 2;
diff --git a/src/main/java/net/minecraft/server/EntityGiantZombie.java b/src/main/java/net/minecraft/server/EntityGiantZombie.java
index 8dce2aad77..2c0a696b8d 100644
--- a/src/main/java/net/minecraft/server/EntityGiantZombie.java
+++ b/src/main/java/net/minecraft/server/EntityGiantZombie.java
@@ -11,16 +11,28 @@ public class EntityGiantZombie extends EntityMonster {
}
// Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.giantRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.giantRidableInWater;
+ }
+
@Override
protected void initPathfinder() {
if (world.purpurConfig.giantHaveAI) {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D));
this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 16.0F));
this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0D));
if (world.purpurConfig.giantHaveHostileAI) {
this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0D, false));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this).a(EntityPigZombie.class));
this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true));
this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false));
diff --git a/src/main/java/net/minecraft/server/EntityGuardian.java b/src/main/java/net/minecraft/server/EntityGuardian.java
index 27ec46c0b2..0a7f51a2a1 100644
--- a/src/main/java/net/minecraft/server/EntityGuardian.java
+++ b/src/main/java/net/minecraft/server/EntityGuardian.java
@@ -24,15 +24,36 @@ public class EntityGuardian extends EntityMonster {
this.f = 10;
this.a(PathType.WATER, 0.0F);
this.moveController = new EntityGuardian.ControllerMoveGuardian(this);
+ // Purpur start
+ this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this) {
+ @Override
+ public void setYawPitch(float yaw, float pitch) {
+ super.setYawPitch(yaw, pitch * 0.35F);
+ }
+ };
+ // Purpur end
this.bo = this.random.nextFloat();
this.bp = this.bo;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.guardianRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return true;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
PathfinderGoalMoveTowardsRestriction pathfindergoalmovetowardsrestriction = new PathfinderGoalMoveTowardsRestriction(this, 1.0D);
this.goalRandomStroll = new PathfinderGoalRandomStroll(this, 1.0D, 80);
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(4, new EntityGuardian.PathfinderGoalGuardianAttack(this));
this.goalSelector.a(5, pathfindergoalmovetowardsrestriction);
this.goalSelector.a(7, this.goalRandomStroll);
@@ -41,6 +62,7 @@ public class EntityGuardian extends EntityMonster {
this.goalSelector.a(9, new PathfinderGoalRandomLookaround(this));
this.goalRandomStroll.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK));
pathfindergoalmovetowardsrestriction.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityLiving.class, 10, true, false, new EntityGuardian.EntitySelectorGuardianTargetHumanSquid(this)));
}
@@ -74,6 +96,7 @@ public class EntityGuardian extends EntityMonster {
return (Boolean) this.datawatcher.get(EntityGuardian.b);
}
+ private void setMovingFlag(boolean movingFlag) { t(movingFlag); } // Purpur - OBFHELPER
private void t(boolean flag) {
this.datawatcher.set(EntityGuardian.b, flag);
}
@@ -288,7 +311,7 @@ public class EntityGuardian extends EntityMonster {
@Override
public void g(Vec3D vec3d) {
if (this.doAITick() && this.isInWater()) {
- this.a(0.1F, vec3d);
+ this.a(hasRider() ? getSpeed() : 0.1F, vec3d); // Purpur
this.move(EnumMoveType.SELF, this.getMot());
this.setMot(this.getMot().a(0.9D));
if (!this.eN() && this.getGoalTarget() == null) {
@@ -300,17 +323,26 @@ public class EntityGuardian extends EntityMonster {
}
- static class ControllerMoveGuardian extends ControllerMove {
+ static class ControllerMoveGuardian extends net.pl3x.purpur.controller.ControllerMoveWASDWater { // Purpur
- private final EntityGuardian i;
+ private final EntityGuardian i; private EntityGuardian getGuardian() { return i; } // Purpur - OBFHELPER
public ControllerMoveGuardian(EntityGuardian entityguardian) {
super(entityguardian);
this.i = entityguardian;
}
+ // Purpur start
+ @Override
+ public void tick(EntityHuman rider) {
+ super.tick(rider);
+ getGuardian().setMot(getGuardian().getMot().add(0.0D, 0.005D, 0.0D));
+ getGuardian().setMovingFlag(getGuardian().getForward() > 0.0F); // control tail speed
+ }
+ // Purpur end
+
@Override
- public void a() {
+ public void tick() { // Purpur
if (this.h == ControllerMove.Operation.MOVE_TO && !this.i.getNavigation().m()) {
Vec3D vec3d = new Vec3D(this.b - this.i.locX(), this.c - this.i.locY(), this.d - this.i.locZ());
double d0 = vec3d.f();
diff --git a/src/main/java/net/minecraft/server/EntityGuardianElder.java b/src/main/java/net/minecraft/server/EntityGuardianElder.java
index b691e84495..f6f8827469 100644
--- a/src/main/java/net/minecraft/server/EntityGuardianElder.java
+++ b/src/main/java/net/minecraft/server/EntityGuardianElder.java
@@ -16,6 +16,18 @@ public class EntityGuardianElder extends EntityGuardian {
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.elderGuardianRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return true;
+ }
+ // Purpur end
+
public static AttributeProvider.Builder m() {
return EntityGuardian.eM().a(GenericAttributes.MOVEMENT_SPEED, 0.30000001192092896D).a(GenericAttributes.ATTACK_DAMAGE, 8.0D).a(GenericAttributes.MAX_HEALTH, 80.0D);
}
diff --git a/src/main/java/net/minecraft/server/EntityHoglin.java b/src/main/java/net/minecraft/server/EntityHoglin.java
index f679792536..548ff4449f 100644
--- a/src/main/java/net/minecraft/server/EntityHoglin.java
+++ b/src/main/java/net/minecraft/server/EntityHoglin.java
@@ -13,13 +13,25 @@ public class EntityHoglin extends EntityAnimal implements IMonster, IOglin {
public int conversionTicks = 0;
public boolean cannotBeHunted = false;
protected static final ImmutableList<? extends SensorType<? extends Sensor<? super EntityHoglin>>> bo = ImmutableList.of(SensorType.c, SensorType.d, SensorType.n, SensorType.m);
- protected static final ImmutableList<? extends MemoryModuleType<?>> bp = ImmutableList.of(MemoryModuleType.BREED_TARGET, MemoryModuleType.MOBS, MemoryModuleType.VISIBLE_MOBS, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_TARGETABLE_PLAYER, MemoryModuleType.LOOK_TARGET, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.ATTACK_TARGET, MemoryModuleType.ATTACK_COOLING_DOWN, MemoryModuleType.NEAREST_VISIBLE_ADULT_PIGLIN, new MemoryModuleType[]{MemoryModuleType.AVOID_TARGET, MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT, MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT, MemoryModuleType.NEAREST_VISIBLE_ADULT_HOGLINS, MemoryModuleType.NEAREST_VISIBLE_ADULY, MemoryModuleType.NEAREST_REPELLENT, MemoryModuleType.PACIFIED});
+ protected static final ImmutableList<? extends MemoryModuleType<?>> bp = ImmutableList.of(MemoryModuleType.BREED_TARGET, MemoryModuleType.MOBS, MemoryModuleType.VISIBLE_MOBS, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_TARGETABLE_PLAYER, MemoryModuleType.LOOK_TARGET, MemoryModuleType.WALK_TARGET, MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryModuleType.PATH, MemoryModuleType.ATTACK_TARGET, MemoryModuleType.ATTACK_COOLING_DOWN, MemoryModuleType.NEAREST_VISIBLE_ADULT_PIGLIN, MemoryModuleType.AVOID_TARGET, MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT, MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT, MemoryModuleType.NEAREST_VISIBLE_ADULT_HOGLINS, MemoryModuleType.NEAREST_VISIBLE_ADULY, MemoryModuleType.NEAREST_REPELLENT, MemoryModuleType.PACIFIED); // Purpur - decompile error
public EntityHoglin(EntityTypes<? extends EntityHoglin> entitytypes, World world) {
super(entitytypes, world);
this.f = 5;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.hoglinRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.hoglinRidableInWater;
+ }
+ // Purpur end
+
@Override
public boolean a(EntityHuman entityhuman) {
return !this.isLeashed();
@@ -77,13 +89,14 @@ public class EntityHoglin extends EntityAnimal implements IMonster, IOglin {
@Override
public BehaviorController<EntityHoglin> getBehaviorController() {
- return super.getBehaviorController();
+ return (BehaviorController<EntityHoglin>) super.getBehaviorController(); // Purpur - decompile error
}
@Override
protected void mobTick() {
this.world.getMethodProfiler().enter("hoglinBrain");
- this.getBehaviorController().a((WorldServer) this.world, (EntityLiving) this);
+ if (getRider() == null) // Purpur - only use brain if no rider
+ this.getBehaviorController().a((WorldServer) this.world, this); // Purpur - decompile error
this.world.getMethodProfiler().exit();
HoglinAI.a(this);
if (this.isConverting()) {
@@ -259,7 +272,7 @@ public class EntityHoglin extends EntityAnimal implements IMonster, IOglin {
@Override
protected SoundEffect getSoundAmbient() {
- return this.world.isClientSide ? null : (SoundEffect) HoglinAI.b(this).orElse((Object) null);
+ return this.world.isClientSide ? null : (SoundEffect) HoglinAI.b(this).orElse(null); // Purpur - decompile error
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityHorse.java b/src/main/java/net/minecraft/server/EntityHorse.java
index e0e60bb6d8..0415a4d1f3 100644
--- a/src/main/java/net/minecraft/server/EntityHorse.java
+++ b/src/main/java/net/minecraft/server/EntityHorse.java
@@ -12,6 +12,13 @@ public class EntityHorse extends EntityHorseAbstract {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.horseRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void eK() {
this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue((double) this.fp());
diff --git a/src/main/java/net/minecraft/server/EntityHorseAbstract.java b/src/main/java/net/minecraft/server/EntityHorseAbstract.java
index 573d4a5c78..4b41a58833 100644
--- a/src/main/java/net/minecraft/server/EntityHorseAbstract.java
+++ b/src/main/java/net/minecraft/server/EntityHorseAbstract.java
@@ -39,12 +39,27 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven
protected EntityHorseAbstract(EntityTypes<? extends EntityHorseAbstract> entitytypes, World world) {
super(entitytypes, world);
+ this.moveController = new ControllerMove(this); // Purpur - use vanilla controller
+ this.lookController = new ControllerLook(this); // Purpur - use vanilla controller
this.G = 1.0F;
this.loadChest();
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return false; // vanilla handles
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return false;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new PathfinderGoalHorseHasRider(this)); // Purpur
this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.2D));
this.goalSelector.a(1, new PathfinderGoalTame(this, 1.2D));
this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D, EntityHorseAbstract.class));
@@ -52,6 +67,7 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven
this.goalSelector.a(6, new PathfinderGoalRandomStrollLand(this, 0.7D));
this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F));
this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new PathfinderGoalHorseHasRider(this)); // Purpur
this.eV();
}
diff --git a/src/main/java/net/minecraft/server/EntityHorseDonkey.java b/src/main/java/net/minecraft/server/EntityHorseDonkey.java
index 767d18d5a0..cb8aee5691 100644
--- a/src/main/java/net/minecraft/server/EntityHorseDonkey.java
+++ b/src/main/java/net/minecraft/server/EntityHorseDonkey.java
@@ -8,6 +8,13 @@ public class EntityHorseDonkey extends EntityHorseChestedAbstract {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.donkeyRidableInWater;
+ }
+ // Purpur end
+
@Override
protected SoundEffect getSoundAmbient() {
super.getSoundAmbient();
diff --git a/src/main/java/net/minecraft/server/EntityHorseMule.java b/src/main/java/net/minecraft/server/EntityHorseMule.java
index 3dd4d4f0f3..243aeb736e 100644
--- a/src/main/java/net/minecraft/server/EntityHorseMule.java
+++ b/src/main/java/net/minecraft/server/EntityHorseMule.java
@@ -8,6 +8,12 @@ public class EntityHorseMule extends EntityHorseChestedAbstract {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.muleRidableInWater;
+ }
+ // Purpur end
@Override
protected SoundEffect getSoundAmbient() {
super.getSoundAmbient();
diff --git a/src/main/java/net/minecraft/server/EntityHorseSkeleton.java b/src/main/java/net/minecraft/server/EntityHorseSkeleton.java
index a53d335f3a..e2c6a5807a 100644
--- a/src/main/java/net/minecraft/server/EntityHorseSkeleton.java
+++ b/src/main/java/net/minecraft/server/EntityHorseSkeleton.java
@@ -12,6 +12,18 @@ public class EntityHorseSkeleton extends EntityHorseAbstract {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.skeletonHorseRidableInWater;
+ }
+
+ @Override
+ public boolean isTamed() {
+ return true;
+ }
+ // Purpur end
+
public static AttributeProvider.Builder eL() {
return fi().a(GenericAttributes.MAX_HEALTH, 15.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.20000000298023224D);
}
@@ -22,7 +34,7 @@ public class EntityHorseSkeleton extends EntityHorseAbstract {
}
@Override
- protected void eV() {}
+ protected void eV() { if (world.purpurConfig.skeletonHorseCanSwim) goalSelector.a(0, new PathfinderGoalFloat(this)); } // Purpur
@Override
protected SoundEffect getSoundAmbient() {
@@ -117,7 +129,7 @@ public class EntityHorseSkeleton extends EntityHorseAbstract {
@Override
public boolean bt() {
- return true;
+ return super.bt(); // Purpur
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityHorseZombie.java b/src/main/java/net/minecraft/server/EntityHorseZombie.java
index 0e98173607..559ba50977 100644
--- a/src/main/java/net/minecraft/server/EntityHorseZombie.java
+++ b/src/main/java/net/minecraft/server/EntityHorseZombie.java
@@ -8,6 +8,18 @@ public class EntityHorseZombie extends EntityHorseAbstract {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.zombieHorseRidableInWater;
+ }
+
+ @Override
+ public boolean isTamed() {
+ return true;
+ }
+ // Purpur end
+
public static AttributeProvider.Builder eL() {
return fi().a(GenericAttributes.MAX_HEALTH, 15.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.20000000298023224D);
}
@@ -79,5 +91,5 @@ public class EntityHorseZombie extends EntityHorseAbstract {
}
@Override
- protected void eV() {}
+ protected void eV() { if (world.purpurConfig.zombieHorseCanSwim) goalSelector.a(0, new PathfinderGoalFloat(this)); } // Purpur
}
diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java
index 75f9874115..deb6c93426 100644
--- a/src/main/java/net/minecraft/server/EntityHuman.java
+++ b/src/main/java/net/minecraft/server/EntityHuman.java
@@ -2148,4 +2148,15 @@ public abstract class EntityHuman extends EntityLiving {
return this.g;
}
}
+
+ // Purpur start
+ @Override
+ public boolean processClick(EnumHand hand) {
+ Entity vehicle = getRootVehicle();
+ if (vehicle != null && vehicle.getRider() == this) {
+ return vehicle.onClick(hand);
+ }
+ return false;
+ }
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java b/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java
index b6c6b4d54e..f5b6d83f87 100644
--- a/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java
+++ b/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java
@@ -20,6 +20,16 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan
}
// Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.illusionerRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.illusionerRidableInWater;
+ }
+
@Override
protected void initAttributes(World world) {
if (world != null) {
@@ -34,6 +44,7 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan
protected void initPathfinder() {
super.initPathfinder();
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new EntityIllagerWizard.b());
this.goalSelector.a(4, new EntityIllagerIllusioner.b());
this.goalSelector.a(5, new EntityIllagerIllusioner.a());
@@ -41,6 +52,7 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan
this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D));
this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F));
this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error
this.targetSelector.a(2, (new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)).a(300));
this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)).a(300));
diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java
index 2fcd7f461a..6952832458 100644
--- a/src/main/java/net/minecraft/server/EntityInsentient.java
+++ b/src/main/java/net/minecraft/server/EntityInsentient.java
@@ -29,7 +29,7 @@ public abstract class EntityInsentient extends EntityLiving {
protected int f;
protected ControllerLook lookController;
protected ControllerMove moveController;
- protected ControllerJump bi;
+ protected ControllerJump bi; public ControllerJump getJumpController() { return bi; } // Purpur - OBFHELPER
private final EntityAIBodyControl c;
protected NavigationAbstract navigation;
public PathfinderGoalSelector goalSelector;
@@ -67,8 +67,8 @@ public abstract class EntityInsentient extends EntityLiving {
this.bA = -1.0F;
this.goalSelector = new PathfinderGoalSelector(world.getMethodProfilerSupplier());
this.targetSelector = new PathfinderGoalSelector(world.getMethodProfilerSupplier());
- this.lookController = new ControllerLook(this);
- this.moveController = new ControllerMove(this);
+ this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this); // Purpur
+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASD(this); // Purpur
this.bi = new ControllerJump(this);
this.c = this.r();
this.navigation = this.b(world);
@@ -254,10 +254,10 @@ public abstract class EntityInsentient extends EntityLiving {
// Purpur start
private void incrementTicksSinceLastInteraction() {
++ticksSinceLastInteraction;
- //if (hasRider()) {
- // ticksSinceLastInteraction = 0;
- // return;
- //}
+ if (hasRider()) {
+ ticksSinceLastInteraction = 0;
+ return;
+ }
if (world.purpurConfig.entityLifeSpan <= 0) {
return; // feature disabled
}
@@ -552,14 +552,17 @@ public abstract class EntityInsentient extends EntityLiving {
return super.dp();
}
+ public void setForwardSpeed(float speed) { this.t(speed); } // Purpur - OBFHELPER
public void t(float f) {
this.aT = f;
}
+ public void setVerticalSpeed(float speed) { this.u(speed); } // Purpur - OBFHELPER
public void u(float f) {
this.aS = f;
}
+ public void setStrafeSpeed(float speed) { this.v(speed); } // Purpur - OBFHELPER
public void v(float f) {
this.aR = f;
}
@@ -1248,7 +1251,7 @@ public abstract class EntityInsentient extends EntityLiving {
protected void a(EntityHuman entityhuman, EntityInsentient entityinsentient) {}
protected EnumInteractionResult b(EntityHuman entityhuman, EnumHand enumhand) {
- return EnumInteractionResult.PASS;
+ return tryRide(entityhuman, enumhand); // Purpur
}
public boolean ev() {
@@ -1620,4 +1623,54 @@ public abstract class EntityInsentient extends EntityLiving {
this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit
this.unleash(true, false);
}
+
+ // Purpur start
+ public double getMaxY() {
+ return world.getHeight();
+ }
+
+ public EnumInteractionResult tryRide(EntityHuman entityhuman, EnumHand enumhand) {
+ if (!isRidable()) {
+ return EnumInteractionResult.PASS;
+ }
+ if (enumhand != EnumHand.MAIN_HAND) {
+ return EnumInteractionResult.PASS;
+ }
+ if (entityhuman.isSneaking()) {
+ return EnumInteractionResult.PASS;
+ }
+ if (!entityhuman.getItemInHand(enumhand).isEmpty()) {
+ return EnumInteractionResult.PASS;
+ }
+ if (!passengers.isEmpty() || entityhuman.isPassenger()) {
+ return EnumInteractionResult.PASS;
+ }
+ if (this instanceof EntityTameableAnimal) {
+ EntityTameableAnimal tameable = (EntityTameableAnimal) this;
+ if (tameable.isTamed() && !tameable.isOwner(entityhuman)) {
+ return EnumInteractionResult.PASS;
+ }
+ if (!tameable.isTamed() && !world.purpurConfig.untamedTamablesAreRidable) {
+ return EnumInteractionResult.PASS;
+ }
+ }
+ if (this instanceof EntityAgeable) {
+ EntityAgeable ageable = (EntityAgeable) this;
+ if (ageable.isBaby() && !world.purpurConfig.babiesAreRidable) {
+ return EnumInteractionResult.PASS;
+ }
+ }
+ if (!entityhuman.getBukkitEntity().hasPermission("allow.ride." + getEntityType().getName())) {
+ entityhuman.sendMessage(net.pl3x.purpur.PurpurConfig.cannotRideMob);
+ return EnumInteractionResult.PASS;
+ }
+ entityhuman.yaw = this.yaw;
+ entityhuman.pitch = this.pitch;
+ if (entityhuman.startRiding(this)) {
+ return EnumInteractionResult.SUCCESS;
+ } else {
+ return EnumInteractionResult.PASS;
+ }
+ }
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/server/EntityIronGolem.java b/src/main/java/net/minecraft/server/EntityIronGolem.java
index bdff236883..9ee03b233b 100644
--- a/src/main/java/net/minecraft/server/EntityIronGolem.java
+++ b/src/main/java/net/minecraft/server/EntityIronGolem.java
@@ -22,9 +22,22 @@ public class EntityIronGolem extends EntityGolem implements IEntityAngerable {
this.G = 1.0F;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.ironGolemRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.ironGolemRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
if (world.purpurConfig.ironGolemCanSwim) this.goalSelector.a(0, new PathfinderGoalFloat(this)); // Purpur
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new PathfinderGoalMeleeAttack(this, 1.0D, true));
this.goalSelector.a(2, new PathfinderGoalMoveTowardsTarget(this, 0.9D, 32.0F));
this.goalSelector.a(2, new PathfinderGoalStrollVillage(this, 0.6D, false));
@@ -32,6 +45,7 @@ public class EntityIronGolem extends EntityGolem implements IEntityAngerable {
this.goalSelector.a(5, new PathfinderGoalOfferFlower(this));
this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F));
this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalDefendVillage(this));
this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, new Class[0]));
this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, this::a_));
@@ -201,13 +215,13 @@ public class EntityIronGolem extends EntityGolem implements IEntityAngerable {
Item item = itemstack.getItem();
if (item != Items.IRON_INGOT) {
- return EnumInteractionResult.PASS;
+ return tryRide(entityhuman, enumhand); // Purpur
} else {
float f = this.getHealth();
this.heal(25.0F);
if (this.getHealth() == f) {
- return EnumInteractionResult.PASS;
+ return tryRide(entityhuman, enumhand); // Purpur
} else {
float f1 = 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F;
diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java
index 1e47a741cf..c33909e20a 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -466,7 +466,7 @@ public abstract class EntityLiving extends Entity {
@Override
public boolean bt() {
- return false;
+ return isRidableInWater(); // Purpur
}
protected void cU() {
@@ -2186,7 +2186,7 @@ public abstract class EntityLiving extends Entity {
return 0.42F * this.getBlockJumpFactor();
}
- protected void jump() {
+ public void jump() { // Purpur - protected -> public
float f = this.dJ();
if (this.hasEffect(MobEffects.JUMP)) {
@@ -2435,10 +2435,12 @@ public abstract class EntityLiving extends Entity {
return this.onGround ? this.dN() * (0.21600002F / (f * f * f)) : this.aE;
}
+ public float getSpeed() { return dN(); } // Purpur - OBFHELPER
public float dN() {
return this.bu;
}
+ public void setSpeed(float speed) { q(speed); } // Purpur - OBFHELPER
public void q(float f) {
this.bu = f;
}
diff --git a/src/main/java/net/minecraft/server/EntityLlama.java b/src/main/java/net/minecraft/server/EntityLlama.java
index e61f53816c..1099277868 100644
--- a/src/main/java/net/minecraft/server/EntityLlama.java
+++ b/src/main/java/net/minecraft/server/EntityLlama.java
@@ -18,7 +18,46 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
public EntityLlama(EntityTypes<? extends EntityLlama> entitytypes, World world) {
super(entitytypes, world);
+ // Purpur start
+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASD(this) {
+ @Override
+ public void a() { // tick
+ if (entity.hasRider() && hasSaddle()) {
+ tick(entity.getRider());
+ } else {
+ tick();
+ }
+ }
+ };
+ this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this) {
+ @Override
+ public void a() { // tick
+ if (entity.hasRider() && hasSaddle()) {
+ tick(entity.getRider());
+ } else {
+ tick();
+ }
+ }
+ };
+ // Purpur end
+ }
+
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.llamaRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.llamaRidableInWater;
+ }
+
+ @Override
+ public boolean hasSaddle() {
+ return super.hasSaddle() || (isTamed() && getColor() != null);
}
+ // Purpur end
public void setStrength(int i) {
this.datawatcher.set(EntityLlama.bx, Math.max(1, Math.min(5, i)));
@@ -66,6 +105,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHorseHasRider(this)); // Purpur
this.goalSelector.a(1, new PathfinderGoalTame(this, 1.2D));
this.goalSelector.a(2, new PathfinderGoalLlamaFollow(this, 2.0999999046325684D));
this.goalSelector.a(3, new PathfinderGoalArrowAttack(this, 1.25D, 40, 20.0F));
@@ -75,6 +115,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
this.goalSelector.a(6, new PathfinderGoalRandomStrollLand(this, 0.7D));
this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F));
this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new PathfinderGoalHorseHasRider(this)); // Purpur
this.targetSelector.a(1, new EntityLlama.c(this));
this.targetSelector.a(2, new EntityLlama.a(this));
}
@@ -312,7 +353,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
}
@Nullable
- public EnumColor fy() {
+ public EnumColor fy() { return getColor(); } public EnumColor getColor() { // Purpur - OBFHELPER
int i = (Integer) this.datawatcher.get(EntityLlama.by);
return i == -1 ? null : EnumColor.fromColorIndex(i);
diff --git a/src/main/java/net/minecraft/server/EntityLlamaTrader.java b/src/main/java/net/minecraft/server/EntityLlamaTrader.java
index 7d30e5c237..b6aae5cdee 100644
--- a/src/main/java/net/minecraft/server/EntityLlamaTrader.java
+++ b/src/main/java/net/minecraft/server/EntityLlamaTrader.java
@@ -11,6 +11,23 @@ public class EntityLlamaTrader extends EntityLlama {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.llamaTraderRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.llamaTraderRidableInWater;
+ }
+
+ @Override
+ public boolean hasSaddle() {
+ return super.hasSaddle() || isTamed();
+ }
+ // Purpur end
+
@Override
protected EntityLlama fz() {
return (EntityLlama) EntityTypes.TRADER_LLAMA.a(this.world);
diff --git a/src/main/java/net/minecraft/server/EntityMagmaCube.java b/src/main/java/net/minecraft/server/EntityMagmaCube.java
index 874dd39825..cd28463e2b 100644
--- a/src/main/java/net/minecraft/server/EntityMagmaCube.java
+++ b/src/main/java/net/minecraft/server/EntityMagmaCube.java
@@ -8,6 +8,23 @@ public class EntityMagmaCube extends EntitySlime {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.magmaCubeRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.magmaCubeRidableInWater;
+ }
+
+ @Override
+ public float getJumpHeight() {
+ return 0.42F * this.getBlockJumpFactor(); // from EntityLiving
+ }
+ // Purpur end
+
public static AttributeProvider.Builder m() {
return EntityMonster.eR().a(GenericAttributes.MOVEMENT_SPEED, 0.20000000298023224D);
}
@@ -58,11 +75,12 @@ public class EntityMagmaCube extends EntitySlime {
}
@Override
- protected void jump() {
+ public void jump() { // Purpur - protected -> public
Vec3D vec3d = this.getMot();
this.setMot(vec3d.x, (double) (this.dJ() + (float) this.getSize() * 0.1F), vec3d.z);
this.impulse = true;
+ this.actualJump = false; // Purpur
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityMushroomCow.java b/src/main/java/net/minecraft/server/EntityMushroomCow.java
index 38df17bd20..7966b34f8d 100644
--- a/src/main/java/net/minecraft/server/EntityMushroomCow.java
+++ b/src/main/java/net/minecraft/server/EntityMushroomCow.java
@@ -20,6 +20,18 @@ public class EntityMushroomCow extends EntityCow implements IShearable {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.mooshroomRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.mooshroomRidableInWater;
+ }
+ // Purpur end
+
@Override
public float a(BlockPosition blockposition, IWorldReader iworldreader) {
return iworldreader.getType(blockposition.down()).a(Blocks.MYCELIUM) ? 10.0F : iworldreader.y(blockposition) - 0.5F;
@@ -81,7 +93,7 @@ public class EntityMushroomCow extends EntityCow implements IShearable {
} else if (itemstack.getItem() == Items.SHEARS && this.canShear()) {
// CraftBukkit start
if (!CraftEventFactory.handlePlayerShearEntityEvent(entityhuman, this, itemstack, enumhand)) {
- return EnumInteractionResult.PASS;
+ return tryRide(entityhuman, enumhand); // Purpur
}
// CraftBukkit end
this.shear(SoundCategory.PLAYERS);
@@ -101,7 +113,7 @@ public class EntityMushroomCow extends EntityCow implements IShearable {
Optional<Pair<MobEffectList, Integer>> optional = this.l(itemstack);
if (!optional.isPresent()) {
- return EnumInteractionResult.PASS;
+ return tryRide(entityhuman, enumhand); // Purpur
}
Pair<MobEffectList, Integer> pair = (Pair) optional.get();
diff --git a/src/main/java/net/minecraft/server/EntityOcelot.java b/src/main/java/net/minecraft/server/EntityOcelot.java
index 7bd3fea6e0..2f8275cd6b 100644
--- a/src/main/java/net/minecraft/server/EntityOcelot.java
+++ b/src/main/java/net/minecraft/server/EntityOcelot.java
@@ -16,6 +16,18 @@ public class EntityOcelot extends EntityAnimal {
this.eL();
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.ocelotRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.ocelotRidableInWater;
+ }
+ // Purpur end
+
private boolean isTrusting() {
return (Boolean) this.datawatcher.get(EntityOcelot.bp);
}
@@ -47,12 +59,14 @@ public class EntityOcelot extends EntityAnimal {
protected void initPathfinder() {
this.br = new EntityOcelot.b(this, 0.6D, EntityOcelot.bo, true);
this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(3, this.br);
this.goalSelector.a(7, new PathfinderGoalLeapAtTarget(this, 0.3F));
this.goalSelector.a(8, new PathfinderGoalOcelotAttack(this));
this.goalSelector.a(9, new PathfinderGoalBreed(this, 0.8D));
this.goalSelector.a(10, new PathfinderGoalRandomStrollLand(this, 0.8D, 1.0000001E-5F));
this.goalSelector.a(11, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 10.0F));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityChicken.class, false));
this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityTurtle.class, 10, false, false, EntityTurtle.bo));
}
diff --git a/src/main/java/net/minecraft/server/EntityPanda.java b/src/main/java/net/minecraft/server/EntityPanda.java
index b36cc95168..eafae5516b 100644
--- a/src/main/java/net/minecraft/server/EntityPanda.java
+++ b/src/main/java/net/minecraft/server/EntityPanda.java
@@ -46,6 +46,27 @@ public class EntityPanda extends EntityAnimal {
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.pandaRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.pandaRidableInWater;
+ }
+
+ @Override
+ public void onMount(EntityHuman entityhuman) {
+ super.onMount(entityhuman);
+ this.setForwardSpeed(0.0F);
+ this.setScared(false);
+ this.setEating(false);
+ this.setLayingOnBack(false);
+ }
+ // Purpur end
+
@Override
public boolean e(ItemStack itemstack) {
EnumItemSlot enumitemslot = EntityInsentient.j(itemstack);
@@ -69,6 +90,7 @@ public class EntityPanda extends EntityAnimal {
return this.w(8);
}
+ public void setScared(boolean scared) { this.t(scared); } // Purpur - OBFHELPER
public void t(boolean flag) {
this.d(8, flag);
}
@@ -77,6 +99,7 @@ public class EntityPanda extends EntityAnimal {
return this.w(16);
}
+ public void setLayingOnBack(boolean layingOnBack) { this.u(layingOnBack); } // Purpur - OBFHELPER
public void u(boolean flag) {
this.d(16, flag);
}
@@ -93,6 +116,7 @@ public class EntityPanda extends EntityAnimal {
return (Integer) this.datawatcher.get(EntityPanda.br);
}
+ public void setEating(boolean eating) { this.v(eating); } // Purpur - OBFHELPER
private void v(int i) {
this.datawatcher.set(EntityPanda.br, i);
}
@@ -201,6 +225,7 @@ public class EntityPanda extends EntityAnimal {
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(2, new EntityPanda.i(this, 2.0D));
this.goalSelector.a(2, new EntityPanda.d(this, 1.0D));
this.goalSelector.a(3, new EntityPanda.b(this, 1.2000000476837158D, true));
@@ -216,6 +241,7 @@ public class EntityPanda extends EntityAnimal {
this.goalSelector.a(12, new EntityPanda.j(this));
this.goalSelector.a(13, new PathfinderGoalFollowParent(this, 1.25D));
this.goalSelector.a(14, new PathfinderGoalRandomStrollLand(this, 1.0D));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, (new EntityPanda.e(this, new Class[0])).a(new Class[0]));
}
@@ -536,7 +562,7 @@ public class EntityPanda extends EntityAnimal {
ItemStack itemstack = entityhuman.b(enumhand);
if (this.ff()) {
- return EnumInteractionResult.PASS;
+ return tryRide(entityhuman, enumhand); // Purpur
} else if (this.eN()) {
this.u(false);
return EnumInteractionResult.a(this.world.isClientSide);
@@ -553,7 +579,7 @@ public class EntityPanda extends EntityAnimal {
this.g(entityhuman);
} else {
if (this.world.isClientSide || this.eM() || this.isInWater()) {
- return EnumInteractionResult.PASS;
+ return tryRide(entityhuman, enumhand); // Purpur
}
this.ft();
@@ -570,7 +596,7 @@ public class EntityPanda extends EntityAnimal {
return EnumInteractionResult.SUCCESS;
} else {
- return EnumInteractionResult.PASS;
+ return tryRide(entityhuman, enumhand); // Purpur
}
}
@@ -683,6 +709,7 @@ public class EntityPanda extends EntityAnimal {
public f(EntityPanda entitypanda) {
this.a = entitypanda;
+ this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - lay on back
}
@Override
@@ -846,6 +873,7 @@ public class EntityPanda extends EntityAnimal {
public l(EntityPanda entitypanda) {
this.a = entitypanda;
+ this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - sneeze
}
@Override
@@ -975,7 +1003,7 @@ public class EntityPanda extends EntityAnimal {
}
}
- static class h extends ControllerMove {
+ static class h extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur
private final EntityPanda i;
@@ -985,9 +1013,9 @@ public class EntityPanda extends EntityAnimal {
}
@Override
- public void a() {
+ public void tick() { // Purpur
if (this.i.fh()) {
- super.a();
+ super.tick(); // Purpur
}
}
}
diff --git a/src/main/java/net/minecraft/server/EntityParrot.java b/src/main/java/net/minecraft/server/EntityParrot.java
index f7b92078ea..66c1d666cd 100644
--- a/src/main/java/net/minecraft/server/EntityParrot.java
+++ b/src/main/java/net/minecraft/server/EntityParrot.java
@@ -65,12 +65,58 @@ public class EntityParrot extends EntityPerchable implements EntityBird {
public EntityParrot(EntityTypes<? extends EntityParrot> entitytypes, World world) {
super(entitytypes, world);
- this.moveController = new ControllerMoveFlying(this, 10, false);
+ // Purpur start
+ final net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar flyingController = new net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar(this, 0.3F);
+ this.moveController = new ControllerMoveFlying(this, 10, false) {
+ @Override
+ public void a() { // tick
+ if (getEntity().hasRider()) {
+ flyingController.tick(getEntity().getRider());
+ } else {
+ tick();
+ }
+ }
+
+ @Override
+ public boolean b() { // isUpdating
+ return getEntity().hasRider() ? getForward() != 0 || getStrafe() != 0 : super.b();
+ }
+ };
+ // Purpur end
this.a(PathType.DANGER_FIRE, -1.0F);
this.a(PathType.DAMAGE_FIRE, -1.0F);
this.a(PathType.COCOA, -1.0F);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.parrotRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.parrotRidableInWater;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.parrotMaxY;
+ }
+
+ @Override
+ public void g(Vec3D vec3d) {
+ super.g(vec3d);
+ if (hasRider() && !onGround) {
+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue() * 2;
+ setSpeed(speed);
+ Vec3D mot = getMot();
+ move(EnumMoveType.SELF, mot.multiply(speed, 0.25, speed));
+ setMot(mot.a(0.9D));
+ }
+ }
+ // Purpur end
+
@Nullable
@Override
public GroupDataEntity prepare(WorldAccess worldaccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) {
@@ -89,8 +135,10 @@ public class EntityParrot extends EntityPerchable implements EntityBird {
@Override
protected void initPathfinder() {
- this.goalSelector.a(0, new PathfinderGoalPanic(this, 1.25D));
+ // this.goalSelector.a(0, new PathfinderGoalPanic(this, 1.25D)); // Purpur - move down
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
+ this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D)); // Purpur
this.goalSelector.a(1, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(2, new PathfinderGoalSit(this));
this.goalSelector.a(2, new PathfinderGoalFollowOwner(this, 1.0D, 5.0F, 1.0F, true));
diff --git a/src/main/java/net/minecraft/server/EntityPhantom.java b/src/main/java/net/minecraft/server/EntityPhantom.java
index bdfe073dcd..f8c3480045 100644
--- a/src/main/java/net/minecraft/server/EntityPhantom.java
+++ b/src/main/java/net/minecraft/server/EntityPhantom.java
@@ -25,6 +25,58 @@ public class EntityPhantom extends EntityFlying implements IMonster {
this.lookController = new EntityPhantom.f(this);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.phantomRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.phantomRidableInWater;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.phantomMaxY;
+ }
+
+ @Override
+ public void g(Vec3D vec3d) {
+ super.g(vec3d);
+ if (hasRider() && !onGround) {
+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue();
+ setSpeed(speed);
+ Vec3D mot = getMot();
+ move(EnumMoveType.SELF, mot.multiply(speed, speed, speed));
+ setMot(mot.a(0.9D));
+ }
+ }
+
+ public static AttributeProvider.Builder defaultAttributes() {
+ return EntityMonster.eR().a(GenericAttributes.FLYING_SPEED, 3.0D);
+ }
+
+ @Override
+ public boolean onSpacebar() {
+ if (hasRider() && 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());
+
+ net.pl3x.purpur.entity.PhantomFlames flames = new net.pl3x.purpur.entity.PhantomFlames(world, this);
+ flames.shoot(target.getX() - locX(), target.getY() - locY(), target.getZ() - locZ(), 1.0F, 5.0F);
+ world.addEntity(flames);
+ return true;
+ }
+ // Purpur end
+
@Override
protected EntityAIBodyControl r() {
return new EntityPhantom.d(this);
@@ -33,6 +85,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
@Override
protected void initPathfinder() {
// Purpur start
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this));
if (world.purpurConfig.phantomOrbitCrystalRadius > 0) {
this.goalSelector.a(1, new FindCrystalGoal(this));
this.goalSelector.a(2, new OrbitCrystalGoal(this));
@@ -40,6 +93,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
this.goalSelector.a(3, new EntityPhantom.c()); // PickAttackGoal
this.goalSelector.a(4, new EntityPhantom.i()); // SweepAttackGoal
this.goalSelector.a(5, new EntityPhantom.e()); // OrbitPointGoal
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this));
this.targetSelector.a(1, new EntityPhantom.b()); // AttackPlayer Goal
// Purpur end
}
@@ -126,7 +180,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
@Override
public void movementTick() {
- if (this.isAlive() && ((world.purpurConfig.phantomBurnInDaylight && this.isInDaylight()) || (world.purpurConfig.phantomBurnInLight > 0 && world.getLightLevel(new BlockPosition(this)) >= world.purpurConfig.phantomBurnInLight))) { // Purpur
+ if (this.isAlive() && !hasRider() && ((world.purpurConfig.phantomBurnInDaylight && this.isInDaylight()) || (world.purpurConfig.phantomBurnInLight > 0 && world.getLightLevel(new BlockPosition(this)) >= world.purpurConfig.phantomBurnInLight))) { // Purpur
this.setOnFire(8);
}
@@ -368,7 +422,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
@Override
public boolean a() {
- if (isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag
+ if (getRider() != null || isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag
if (this.c > 0) {
--this.c;
return false;
@@ -397,7 +451,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
@Override
public boolean b() {
- if (isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag
+ if (getRider() != null || isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag
EntityLiving entityliving = EntityPhantom.this.getGoalTarget();
return entityliving != null ? EntityPhantom.this.a(entityliving, PathfinderTargetCondition.a) : false;
@@ -412,7 +466,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
@Override
public boolean a() {
- if (isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag
+ if (getRider() != null || isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag
EntityLiving entityliving = EntityPhantom.this.getGoalTarget();
return entityliving != null ? EntityPhantom.this.a(EntityPhantom.this.getGoalTarget(), PathfinderTargetCondition.a) : false;
@@ -610,14 +664,23 @@ public class EntityPhantom extends EntityFlying implements IMonster {
}
}
- class f extends ControllerLook {
+ class f extends net.pl3x.purpur.controller.ControllerLookWASD { // Purpur
public f(EntityInsentient entityinsentient) {
super(entityinsentient);
}
@Override
- public void a() {}
+ // Purpur start
+ public void tick(EntityHuman rider) {
+ setYawPitch(rider.yaw, -rider.pitch * 0.75F);
+ }
+
+ @Override
+ public void tick() {
+ // do nothing
+ }
+ // Purpur end
}
class d extends EntityAIBodyControl {
@@ -633,7 +696,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
}
}
- class g extends ControllerMove {
+ class g extends net.pl3x.purpur.controller.ControllerMoveWASDFlying { // Purpur
private float j = 0.1F;
@@ -642,7 +705,19 @@ public class EntityPhantom extends EntityFlying implements IMonster {
}
@Override
- public void a() {
+ // Purpur start
+ public void tick(EntityHuman rider) {
+ if (!EntityPhantom.this.onGround) {
+ // phantom is always in motion when flying
+ // TODO - FIX THIS
+ // rider.setForward(1.0F);
+ }
+ super.tick(rider);
+ }
+
+ @Override
+ public void tick() {
+ // Purpur end
if (EntityPhantom.this.positionChanged) {
EntityPhantom.this.yaw += 180.0F;
this.j = 0.1F;
diff --git a/src/main/java/net/minecraft/server/EntityPig.java b/src/main/java/net/minecraft/server/EntityPig.java
index 7f52c39234..dade0bb294 100644
--- a/src/main/java/net/minecraft/server/EntityPig.java
+++ b/src/main/java/net/minecraft/server/EntityPig.java
@@ -19,9 +19,22 @@ public class EntityPig extends EntityAnimal implements ISteerable, ISaddleable {
this.saddleStorage = new SaddleStorage(this.datawatcher, EntityPig.bp, EntityPig.bo);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.pigRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.pigRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D));
this.goalSelector.a(3, new PathfinderGoalBreed(this, 1.0D));
this.goalSelector.a(4, new PathfinderGoalTempt(this, 1.2D, RecipeItemStack.a(Items.CARROT_ON_A_STICK), false));
diff --git a/src/main/java/net/minecraft/server/EntityPigZombie.java b/src/main/java/net/minecraft/server/EntityPigZombie.java
index 32b75f710b..3327dbbf87 100644
--- a/src/main/java/net/minecraft/server/EntityPigZombie.java
+++ b/src/main/java/net/minecraft/server/EntityPigZombie.java
@@ -22,6 +22,16 @@ public class EntityPigZombie extends EntityZombie implements IEntityAngerable {
}
// Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.zombifiedPiglinRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.zombifiedPiglinRidableInWater;
+ }
+
@Override
public boolean jockeyOnlyBaby() {
return world.purpurConfig.zombifiedPiglinJockeyOnlyBaby;
diff --git a/src/main/java/net/minecraft/server/EntityPiglin.java b/src/main/java/net/minecraft/server/EntityPiglin.java
index ca7f9dc54e..334e0f73e6 100644
--- a/src/main/java/net/minecraft/server/EntityPiglin.java
+++ b/src/main/java/net/minecraft/server/EntityPiglin.java
@@ -25,6 +25,18 @@ public class EntityPiglin extends EntityPiglinAbstract implements ICrossbow {
this.f = 5;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.piglinRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.piglinRidableInWater;
+ }
+ // Purpur end
+
@Override
public void saveData(NBTTagCompound nbttagcompound) {
super.saveData(nbttagcompound);
@@ -143,7 +155,7 @@ public class EntityPiglin extends EntityPiglinAbstract implements ICrossbow {
@Override
public BehaviorController<EntityPiglin> getBehaviorController() {
- return super.getBehaviorController();
+ return (BehaviorController<EntityPiglin>) super.getBehaviorController(); // Purpur - decompile error
}
@Override
@@ -202,7 +214,8 @@ public class EntityPiglin extends EntityPiglinAbstract implements ICrossbow {
@Override
protected void mobTick() {
this.world.getMethodProfiler().enter("piglinBrain");
- this.getBehaviorController().a((WorldServer) this.world, (EntityLiving) this);
+ if (getRider() == null) // Purpur - only use brain if no rider
+ this.getBehaviorController().a((WorldServer) this.world, this); // Purpur - decompile error
this.world.getMethodProfiler().exit();
PiglinAI.b(this);
super.mobTick();
@@ -341,7 +354,7 @@ public class EntityPiglin extends EntityPiglinAbstract implements ICrossbow {
@Override
protected SoundEffect getSoundAmbient() {
- return this.world.isClientSide ? null : (SoundEffect) PiglinAI.d(this).orElse((Object) null);
+ return this.world.isClientSide ? null : (SoundEffect) PiglinAI.d(this).orElse(null); // Purpur - decompile error
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityPiglinBrute.java b/src/main/java/net/minecraft/server/EntityPiglinBrute.java
index 3e9a4af09d..f6b1708111 100644
--- a/src/main/java/net/minecraft/server/EntityPiglinBrute.java
+++ b/src/main/java/net/minecraft/server/EntityPiglinBrute.java
@@ -15,6 +15,18 @@ public class EntityPiglinBrute extends EntityPiglinAbstract {
this.f = 20;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.piglinBruteRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.piglinBruteRidableInWater;
+ }
+ // Purpur end
+
public static AttributeProvider.Builder eS() {
return EntityMonster.eR().a(GenericAttributes.MAX_HEALTH, 50.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.3499999940395355D).a(GenericAttributes.ATTACK_DAMAGE, 7.0D);
}
@@ -44,7 +56,7 @@ public class EntityPiglinBrute extends EntityPiglinAbstract {
@Override
public BehaviorController<EntityPiglinBrute> getBehaviorController() {
- return super.getBehaviorController();
+ return (BehaviorController<EntityPiglinBrute>) super.getBehaviorController(); // Purpur - decompile error
}
@Override
@@ -60,7 +72,8 @@ public class EntityPiglinBrute extends EntityPiglinAbstract {
@Override
protected void mobTick() {
this.world.getMethodProfiler().enter("piglinBruteBrain");
- this.getBehaviorController().a((WorldServer) this.world, (EntityLiving) this);
+ if (getRider() == null) // Purpur - only use brain if no rider
+ this.getBehaviorController().a((WorldServer) this.world, this); // Purpur - decompile error
this.world.getMethodProfiler().exit();
PiglinBruteAI.b(this);
PiglinBruteAI.c(this);
diff --git a/src/main/java/net/minecraft/server/EntityPillager.java b/src/main/java/net/minecraft/server/EntityPillager.java
index a3a428da99..cf7de01271 100644
--- a/src/main/java/net/minecraft/server/EntityPillager.java
+++ b/src/main/java/net/minecraft/server/EntityPillager.java
@@ -13,15 +13,29 @@ public class EntityPillager extends EntityIllagerAbstract implements ICrossbow {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.pillagerRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.pillagerRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
super.initPathfinder();
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(2, new EntityRaider.a(this, 10.0F));
this.goalSelector.a(3, new PathfinderGoalCrossbowAttack<>(this, 1.0D, 8.0F));
this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D));
this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 15.0F, 1.0F));
this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 15.0F));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error
this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true));
this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false));
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 6a2f9d831b..51736dfdee 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -505,6 +505,15 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
this.advancementDataPlayer.b(this);
+
+ // Purpur start
+ if (this.world.purpurConfig.useNightVisionWhenRiding && this.getVehicle() != null && this.getVehicle().getRider() == this && world.getTime() % 100 == 0) { // 5 seconds
+ MobEffect nightVision = this.getEffect(MobEffects.NIGHT_VISION);
+ if (nightVision == null || nightVision.getDuration() <= 300) { // 15 seconds
+ this.addEffect(new MobEffect(MobEffects.NIGHT_VISION, 400, 0)); // 20 seconds
+ }
+ }
+ // Purpur end
}
public void playerTick() {
diff --git a/src/main/java/net/minecraft/server/EntityPolarBear.java b/src/main/java/net/minecraft/server/EntityPolarBear.java
index 99f0bd8f82..3d649843f5 100644
--- a/src/main/java/net/minecraft/server/EntityPolarBear.java
+++ b/src/main/java/net/minecraft/server/EntityPolarBear.java
@@ -18,12 +18,34 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable {
private static final IntRange bs = TimeRange.a(20, 39);
private int bt;
private UUID bu;
+ private int standTimer = 0; // Purpur
public EntityPolarBear(EntityTypes<? extends EntityPolarBear> entitytypes, World world) {
super(entitytypes, world);
}
// Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.polarBearRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.polarBearRidableInWater;
+ }
+
+ @Override
+ public boolean onSpacebar() {
+ if (!isStanding()) {
+ if (hasRider() && getRider().getForward() == 0 && getRider().getStrafe() == 0) {
+ setStanding(true);
+ playSound(SoundEffects.ENTITY_POLAR_BEAR_WARNING, 1.0F, 1.0F);
+ }
+ }
+ return false;
+ }
+
@Override
public boolean mate(EntityAnimal entityanimal) {
if (entityanimal == this) {
@@ -61,6 +83,7 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable {
protected void initPathfinder() {
super.initPathfinder();
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new EntityPolarBear.c());
this.goalSelector.a(1, new EntityPolarBear.d());
// Purpur start
@@ -73,6 +96,7 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable {
this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 1.0D));
this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F));
this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new EntityPolarBear.b());
this.targetSelector.a(2, new EntityPolarBear.a());
this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, this::a_));
@@ -185,6 +209,11 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable {
this.a((WorldServer) this.world, true);
}
+ // Purpur start
+ if (isStanding() && --standTimer <= 0) {
+ setStanding(false);
+ }
+ // Purpur end
}
@Override
@@ -218,6 +247,7 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable {
public void setStanding(boolean standing) { t(standing); } // Purpur - OBFHELPER
public void t(boolean flag) {
this.datawatcher.set(EntityPolarBear.bo, flag);
+ standTimer = flag ? 20 : -1; // Purpur
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityPufferFish.java b/src/main/java/net/minecraft/server/EntityPufferFish.java
index 330ec38d09..16a4df27c5 100644
--- a/src/main/java/net/minecraft/server/EntityPufferFish.java
+++ b/src/main/java/net/minecraft/server/EntityPufferFish.java
@@ -17,6 +17,18 @@ public class EntityPufferFish extends EntityFish {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.pufferfishRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return true;
+ }
+ // Purpur end
+
@Override
protected void initDatawatcher() {
super.initDatawatcher();
@@ -60,7 +72,7 @@ public class EntityPufferFish extends EntityFish {
@Override
protected void initPathfinder() {
super.initPathfinder();
- this.goalSelector.a(1, new EntityPufferFish.a(this));
+ this.goalSelector.a(2, new EntityPufferFish.a(this)); // Purpur
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityRabbit.java b/src/main/java/net/minecraft/server/EntityRabbit.java
index 25a9b7906b..b766a27e98 100644
--- a/src/main/java/net/minecraft/server/EntityRabbit.java
+++ b/src/main/java/net/minecraft/server/EntityRabbit.java
@@ -20,6 +20,18 @@ public class EntityRabbit extends EntityAnimal {
this.initializePathFinderGoals(); // CraftBukkit - moved code
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.rabbitRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.rabbitRidableInWater;
+ }
+ // Purpur end
+
// CraftBukkit start - code from constructor
public void initializePathFinderGoals(){
this.i(0.0D);
@@ -28,7 +40,8 @@ public class EntityRabbit extends EntityAnimal {
@Override
public void initPathfinder() {
- this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalFloat(this)); // Purpur
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new EntityRabbit.PathfinderGoalRabbitPanic(this, 2.2D));
this.goalSelector.a(2, new PathfinderGoalBreed(this, 0.8D));
this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, RecipeItemStack.a(Items.CARROT, Items.GOLDEN_CARROT, Blocks.DANDELION), false));
@@ -41,7 +54,15 @@ public class EntityRabbit extends EntityAnimal {
}
@Override
- protected float dJ() {
+ // Purpur start
+ public float getJumpHeight() {
+ if (hasRider()) {
+ if (getForward() < 0) {
+ setSpeed(getForward() * 2F);
+ }
+ return actualJump ? 0.5F : 0.3F;
+ }
+ // Purpur end
if (!this.positionChanged && (!this.moveController.b() || this.moveController.e() <= this.locY() + 0.5D)) {
PathEntity pathentity = this.navigation.k();
@@ -60,7 +81,7 @@ public class EntityRabbit extends EntityAnimal {
}
@Override
- protected void jump() {
+ public void jump() { // Purpur - protected -> public
super.jump();
double d0 = this.moveController.c();
@@ -92,6 +113,7 @@ public class EntityRabbit extends EntityAnimal {
}
+ public void startJumping() { eK(); } // Purpur - OBFHELPER
public void eK() {
this.setJumping(true);
this.br = 10;
@@ -106,6 +128,13 @@ public class EntityRabbit extends EntityAnimal {
@Override
public void mobTick() {
+ // Purpur start
+ if (hasRider()) {
+ handleJumping();
+ return;
+ }
+ // Purpur end
+
if (this.bt > 0) {
--this.bt;
}
@@ -156,6 +185,39 @@ public class EntityRabbit extends EntityAnimal {
this.bs = this.onGround;
}
+ // Purpur start
+ private boolean wasOnGround;
+ private boolean actualJump;
+
+ private void handleJumping() {
+ if (onGround) {
+ ControllerJumpRabbit jumpController = (ControllerJumpRabbit) getJumpController();
+ if (!wasOnGround) {
+ setJumping(false);
+ jumpController.setCanJump(false);
+ }
+ if (!jumpController.isJumping()) {
+ if (moveController.b()) { // isUpdating
+ startJumping();
+ }
+ } else if (!jumpController.canJump()) {
+ jumpController.setCanJump(true);
+ }
+ }
+ wasOnGround = onGround;
+ }
+
+ @Override
+ public boolean onSpacebar() {
+ if (onGround) {
+ actualJump = true;
+ jump();
+ actualJump = false;
+ }
+ return true;
+ }
+ // Purpur end
+
@Override
public boolean aO() {
return false;
@@ -485,7 +547,7 @@ public class EntityRabbit extends EntityAnimal {
}
}
- static class ControllerMoveRabbit extends ControllerMove {
+ static class ControllerMoveRabbit extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur
private final EntityRabbit i;
private double j;
@@ -496,14 +558,14 @@ public class EntityRabbit extends EntityAnimal {
}
@Override
- public void a() {
+ public void tick() { // Purpur
if (this.i.onGround && !this.i.jumping && !((EntityRabbit.ControllerJumpRabbit) this.i.bi).c()) {
this.i.i(0.0D);
} else if (this.b()) {
this.i.i(this.j);
}
- super.a();
+ super.tick(); // Purpur
}
@Override
@@ -530,14 +592,17 @@ public class EntityRabbit extends EntityAnimal {
this.c = entityrabbit;
}
+ public boolean isJumping() { return c(); } // Purpur - OBFHELPER
public boolean c() {
return this.a;
}
+ public boolean canJump() { return d(); } // Purpur - OBFHELPER
public boolean d() {
return this.d;
}
+ public void setCanJump(boolean canJump) { a(canJump); } // Purpur - OBFHELPER
public void a(boolean flag) {
this.d = flag;
}
diff --git a/src/main/java/net/minecraft/server/EntityRavager.java b/src/main/java/net/minecraft/server/EntityRavager.java
index fd1ac7df68..a902145881 100644
--- a/src/main/java/net/minecraft/server/EntityRavager.java
+++ b/src/main/java/net/minecraft/server/EntityRavager.java
@@ -20,14 +20,37 @@ public class EntityRavager extends EntityRaider {
this.f = 20;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.ravagerRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.ravagerRidableInWater;
+ }
+
+ @Override
+ public void onMount(EntityHuman entityhuman) {
+ super.onMount(entityhuman);
+ getNavigation().stopPathfinding();
+
+ double speed = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getBaseValue();
+ getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(speed);
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
super.initPathfinder();
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(4, new EntityRavager.a());
this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 0.4D));
this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F));
this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(2, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error
this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true));
this.targetSelector.a(4, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, true));
@@ -99,7 +122,7 @@ public class EntityRavager extends EntityRaider {
@Override
public void movementTick() {
super.movementTick();
- if (this.isAlive()) {
+ if (this.isAlive() && !hasRider()) {
if (this.isFrozen()) {
this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.0D);
} else {
diff --git a/src/main/java/net/minecraft/server/EntitySalmon.java b/src/main/java/net/minecraft/server/EntitySalmon.java
index 51ec634133..6dfcee2c9b 100644
--- a/src/main/java/net/minecraft/server/EntitySalmon.java
+++ b/src/main/java/net/minecraft/server/EntitySalmon.java
@@ -6,6 +6,18 @@ public class EntitySalmon extends EntityFishSchool {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.salmonRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return true;
+ }
+ // Purpur end
+
@Override
public int eN() {
return 5;
diff --git a/src/main/java/net/minecraft/server/EntitySheep.java b/src/main/java/net/minecraft/server/EntitySheep.java
index 2908e9cc47..a151d4295c 100644
--- a/src/main/java/net/minecraft/server/EntitySheep.java
+++ b/src/main/java/net/minecraft/server/EntitySheep.java
@@ -56,10 +56,23 @@ public class EntitySheep extends EntityAnimal implements IShearable {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.sheepRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.sheepRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.bs = new PathfinderGoalEatTile(this);
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D));
this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D));
this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.1D, RecipeItemStack.a(Items.WHEAT), false));
diff --git a/src/main/java/net/minecraft/server/EntityShulker.java b/src/main/java/net/minecraft/server/EntityShulker.java
index 7bedaf02c4..30e0e14162 100644
--- a/src/main/java/net/minecraft/server/EntityShulker.java
+++ b/src/main/java/net/minecraft/server/EntityShulker.java
@@ -29,12 +29,26 @@ public class EntityShulker extends EntityGolem implements IMonster {
this.f = 5;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.shulkerRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.shulkerRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(4, new EntityShulker.a());
this.goalSelector.a(7, new EntityShulker.e());
this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error
this.targetSelector.a(2, new EntityShulker.d(this));
this.targetSelector.a(3, new EntityShulker.c(this));
@@ -518,7 +532,7 @@ public class EntityShulker extends EntityGolem implements IMonster {
private int b;
- private e() {}
+ private e() { this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); } // Purpur - peek
@Override
public boolean a() {
diff --git a/src/main/java/net/minecraft/server/EntitySilverfish.java b/src/main/java/net/minecraft/server/EntitySilverfish.java
index 28b490cc14..ad428e0900 100644
--- a/src/main/java/net/minecraft/server/EntitySilverfish.java
+++ b/src/main/java/net/minecraft/server/EntitySilverfish.java
@@ -11,13 +11,27 @@ public class EntitySilverfish extends EntityMonster {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.silverfishRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.silverfishRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.b = new EntitySilverfish.PathfinderGoalSilverfishWakeOthers(this);
this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(3, this.b);
this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, 1.0D, false));
this.goalSelector.a(5, new EntitySilverfish.PathfinderGoalSilverfishHideInBlock(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error
this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true));
}
@@ -177,6 +191,7 @@ public class EntitySilverfish extends EntityMonster {
public PathfinderGoalSilverfishWakeOthers(EntitySilverfish entitysilverfish) {
this.silverfish = entitysilverfish;
+ this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur
}
public void g() {
diff --git a/src/main/java/net/minecraft/server/EntitySkeleton.java b/src/main/java/net/minecraft/server/EntitySkeleton.java
index 7c39bec831..3f130e03bf 100644
--- a/src/main/java/net/minecraft/server/EntitySkeleton.java
+++ b/src/main/java/net/minecraft/server/EntitySkeleton.java
@@ -6,6 +6,18 @@ public class EntitySkeleton extends EntitySkeletonAbstract {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.skeletonRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.skeletonRidableInWater;
+ }
+ // Purpur end
+
@Override
protected SoundEffect getSoundAmbient() {
return SoundEffects.ENTITY_SKELETON_AMBIENT;
diff --git a/src/main/java/net/minecraft/server/EntitySkeletonAbstract.java b/src/main/java/net/minecraft/server/EntitySkeletonAbstract.java
index ced89af70c..4d5af11734 100644
--- a/src/main/java/net/minecraft/server/EntitySkeletonAbstract.java
+++ b/src/main/java/net/minecraft/server/EntitySkeletonAbstract.java
@@ -28,12 +28,14 @@ public abstract class EntitySkeletonAbstract extends EntityMonster implements IR
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(2, new PathfinderGoalRestrictSun(this));
this.goalSelector.a(3, new PathfinderGoalFleeSun(this, 1.0D));
this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityWolf.class, 6.0F, 1.0D, 1.2D));
this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 1.0D));
this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[0]));
this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true));
this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true));
diff --git a/src/main/java/net/minecraft/server/EntitySkeletonStray.java b/src/main/java/net/minecraft/server/EntitySkeletonStray.java
index f985caada0..d123fb82b6 100644
--- a/src/main/java/net/minecraft/server/EntitySkeletonStray.java
+++ b/src/main/java/net/minecraft/server/EntitySkeletonStray.java
@@ -8,6 +8,18 @@ public class EntitySkeletonStray extends EntitySkeletonAbstract {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.strayRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.strayRidableInWater;
+ }
+ // Purpur end
+
public static boolean a(EntityTypes<EntitySkeletonStray> entitytypes, WorldAccess worldaccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) {
return b(entitytypes, worldaccess, enummobspawn, blockposition, random) && (enummobspawn == EnumMobSpawn.SPAWNER || worldaccess.e(blockposition));
}
diff --git a/src/main/java/net/minecraft/server/EntitySkeletonWither.java b/src/main/java/net/minecraft/server/EntitySkeletonWither.java
index c872be77a6..96cb080d94 100644
--- a/src/main/java/net/minecraft/server/EntitySkeletonWither.java
+++ b/src/main/java/net/minecraft/server/EntitySkeletonWither.java
@@ -9,6 +9,18 @@ public class EntitySkeletonWither extends EntitySkeletonAbstract {
this.a(PathType.LAVA, 8.0F);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.witherSkeletonRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.witherSkeletonRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityPiglinAbstract.class, true));
diff --git a/src/main/java/net/minecraft/server/EntitySlime.java b/src/main/java/net/minecraft/server/EntitySlime.java
index e99fd88118..4602636298 100644
--- a/src/main/java/net/minecraft/server/EntitySlime.java
+++ b/src/main/java/net/minecraft/server/EntitySlime.java
@@ -34,12 +34,45 @@ public class EntitySlime extends EntityInsentient implements IMonster {
this.moveController = new EntitySlime.ControllerMoveSlime(this);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.slimeRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.slimeRidableInWater;
+ }
+
+ protected boolean actualJump;
+
+ @Override
+ public float getJumpHeight() {
+ float height = super.getJumpHeight();
+ return hasRider() && actualJump ? height * 1.5F : height;
+ }
+
+ @Override
+ public boolean onSpacebar() {
+ if (onGround && hasRider()) {
+ actualJump = true;
+ if (getRider().getForward() == 0 || getRider().getStrafe() == 0) {
+ jump(); // jump() here if not moving
+ }
+ }
+ return true; // do not jump() in wasd controller, let vanilla controller handle
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new EntitySlime.PathfinderGoalSlimeRandomJump(this));
this.goalSelector.a(2, new EntitySlime.PathfinderGoalSlimeNearestPlayer(this));
this.goalSelector.a(3, new EntitySlime.PathfinderGoalSlimeRandomDirection(this));
this.goalSelector.a(5, new EntitySlime.PathfinderGoalSlimeIdle(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, (entityliving) -> {
return Math.abs(entityliving.locY() - this.locY()) <= 4.0D;
}));
@@ -324,11 +357,12 @@ public class EntitySlime extends EntityInsentient implements IMonster {
}
@Override
- protected void jump() {
+ public void jump() { // Purpur - protected -> public
Vec3D vec3d = this.getMot();
this.setMot(vec3d.x, (double) this.dJ(), vec3d.z);
this.impulse = true;
+ this.actualJump = false; // Purpur
}
@Nullable
@@ -497,10 +531,10 @@ public class EntitySlime extends EntityInsentient implements IMonster {
// Paper end
}
- static class ControllerMoveSlime extends ControllerMove {
+ static class ControllerMoveSlime extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur
private float i;
- private int j;
+ private int j; private int getJumpDelay() { return j; } private void setJumpDelay(int delay) { j = delay; } // Purpur - OBFHELPER
private final EntitySlime k;
private boolean l;
@@ -522,15 +556,27 @@ public class EntitySlime extends EntityInsentient implements IMonster {
@Override
public void a() {
+ // Purpur start
+ if (entity.hasRider()) {
+ tick(entity.getRider());
+ if (entity.getForward() != 0 || entity.getStrafe() != 0) {
+ if (getJumpDelay() > 10) {
+ setJumpDelay(6);
+ }
+ } else {
+ setJumpDelay(20);
+ }
+ } else {
+ // Purpur end
this.a.yaw = this.a(this.a.yaw, this.i, 90.0F);
this.a.aC = this.a.yaw;
this.a.aA = this.a.yaw;
- if (this.h != ControllerMove.Operation.MOVE_TO) {
+ } if (!entity.hasRider() && this.h != ControllerMove.Operation.MOVE_TO) { // Purpur
this.a.t(0.0F);
} else {
this.h = ControllerMove.Operation.WAIT;
if (this.a.isOnGround()) {
- this.a.q((float) (this.e * this.a.b(GenericAttributes.MOVEMENT_SPEED)));
+ this.a.q((float) (this.e * this.a.b(GenericAttributes.MOVEMENT_SPEED) * (entity.hasRider() && (entity.getRider().getForward() != 0 || entity.getRider().getStrafe() != 0) ? 2.0D : 1.0D))); // Purpur
if (this.j-- <= 0) {
this.j = this.k.eJ();
if (this.l) {
@@ -547,7 +593,7 @@ public class EntitySlime extends EntityInsentient implements IMonster {
this.a.q(0.0F);
}
} else {
- this.a.q((float) (this.e * this.a.b(GenericAttributes.MOVEMENT_SPEED)));
+ this.a.q((float) (this.e * this.a.b(GenericAttributes.MOVEMENT_SPEED) * (entity.hasRider() && (entity.getRider().getForward() != 0 || entity.getRider().getStrafe() != 0) ? 2.0D : 1.0D))); // Purpur
}
}
diff --git a/src/main/java/net/minecraft/server/EntitySnowman.java b/src/main/java/net/minecraft/server/EntitySnowman.java
index 95ee716fc9..e980da14cf 100644
--- a/src/main/java/net/minecraft/server/EntitySnowman.java
+++ b/src/main/java/net/minecraft/server/EntitySnowman.java
@@ -14,12 +14,26 @@ public class EntitySnowman extends EntityGolem implements IShearable, IRangedEnt
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.snowGolemRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.snowGolemRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new PathfinderGoalArrowAttack(this, 1.25D, 20, 10.0F));
this.goalSelector.a(2, new PathfinderGoalRandomStrollLand(this, 1.0D, 1.0000001E-5F));
this.goalSelector.a(3, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F));
this.goalSelector.a(4, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityInsentient.class, 10, true, false, (entityliving) -> {
return entityliving instanceof IMonster;
}));
@@ -71,6 +85,7 @@ public class EntitySnowman extends EntityGolem implements IShearable, IRangedEnt
return;
}
+ if (hasRider() && !world.purpurConfig.snowGolemLeaveTrailWhenRidden) return; // Purpur - don't leave snow trail when being ridden
IBlockData iblockdata = Blocks.SNOW.getBlockData();
for (int l = 0; l < 4; ++l) {
@@ -113,7 +128,7 @@ public class EntitySnowman extends EntityGolem implements IShearable, IRangedEnt
if (itemstack.getItem() == Items.SHEARS && this.canShear()) {
// CraftBukkit start
if (!CraftEventFactory.handlePlayerShearEntityEvent(entityhuman, this, itemstack, enumhand)) {
- return EnumInteractionResult.PASS;
+ return tryRide(entityhuman, enumhand); // Purpur
}
// CraftBukkit end
this.shear(SoundCategory.PLAYERS);
@@ -141,7 +156,7 @@ public class EntitySnowman extends EntityGolem implements IShearable, IRangedEnt
return EnumInteractionResult.SUCCESS;
// Purpur end
} else {
- return EnumInteractionResult.PASS;
+ return tryRide(entityhuman, enumhand); // Purpur
}
}
diff --git a/src/main/java/net/minecraft/server/EntitySpider.java b/src/main/java/net/minecraft/server/EntitySpider.java
index bf68efd52f..92d7413787 100644
--- a/src/main/java/net/minecraft/server/EntitySpider.java
+++ b/src/main/java/net/minecraft/server/EntitySpider.java
@@ -11,14 +11,28 @@ public class EntitySpider extends EntityMonster {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.spiderRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.spiderRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(3, new PathfinderGoalLeapAtTarget(this, 0.4F));
this.goalSelector.a(4, new EntitySpider.PathfinderGoalSpiderMeleeAttack(this));
this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 0.8D));
this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[0]));
this.targetSelector.a(2, new EntitySpider.PathfinderGoalSpiderNearestAttackableTarget<>(this, EntityHuman.class));
this.targetSelector.a(3, new EntitySpider.PathfinderGoalSpiderNearestAttackableTarget<>(this, EntityIronGolem.class));
diff --git a/src/main/java/net/minecraft/server/EntitySquid.java b/src/main/java/net/minecraft/server/EntitySquid.java
index 148e4b1587..70b952f10a 100644
--- a/src/main/java/net/minecraft/server/EntitySquid.java
+++ b/src/main/java/net/minecraft/server/EntitySquid.java
@@ -26,17 +26,38 @@ public class EntitySquid extends EntityWaterAnimal {
}
// Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.squidRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return true;
+ }
+
@Override
public AxisAlignedBB getAxisForFluidCheck() {
// Stops squids from floating just over the water
return this.getBoundingBox().shrink(0.001D).offsetY(world.purpurConfig.squidOffsetWaterCheck);
}
+
+ private 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
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new EntitySquid.PathfinderGoalSquid(this));
- this.goalSelector.a(1, new EntitySquid.a());
+ this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur
+ this.goalSelector.a(2, new EntitySquid.a()); // Purpur
}
public static AttributeProvider.Builder m() {
@@ -181,6 +202,7 @@ public class EntitySquid extends EntityWaterAnimal {
return blockposition.getY() > generatoraccess.getMinecraftWorld().spigotConfig.squidSpawnRangeMin && blockposition.getY() < maxHeight; // Spigot // Paper
}
+ public void setMovementVector(float x, float y, float z) { a(x, y, z); } // Purpur - OBFHELPER
public void a(float f, float f1, float f2) {
this.bw = f;
this.bx = f1;
@@ -252,7 +274,7 @@ public class EntitySquid extends EntityWaterAnimal {
class PathfinderGoalSquid extends PathfinderGoal {
- private final EntitySquid b;
+ private final EntitySquid b; public EntitySquid getSquid() { return b; } // Purpur - OBFHELPER
public PathfinderGoalSquid(EntitySquid entitysquid) {
this.b = entitysquid;
@@ -265,6 +287,38 @@ public class EntitySquid extends EntityWaterAnimal {
@Override
public void e() {
+ // Purpur start
+ EntitySquid squid = getSquid();
+ EntityHuman rider = squid.getRider();
+ if (rider != null) {
+ if (rider.jumping) {
+ squid.onSpacebar();
+ }
+ float forward = rider.getForward();
+ float strafe = rider.getStrafe();
+ float speed = (float) squid.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * 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.setMovementVector((float) dir.getX(), (float) dir.getY(), (float) dir.getZ());
+ } else {
+ squid.setMovementVector(0.0F, 0.0F, 0.0F);
+ }
+ return;
+ }
+ // Purpur end
int i = this.b.dd();
if (i > 100) {
diff --git a/src/main/java/net/minecraft/server/EntityStrider.java b/src/main/java/net/minecraft/server/EntityStrider.java
index 6d4c6a8f1c..172867f50d 100644
--- a/src/main/java/net/minecraft/server/EntityStrider.java
+++ b/src/main/java/net/minecraft/server/EntityStrider.java
@@ -28,6 +28,18 @@ public class EntityStrider extends EntityAnimal implements ISteerable, ISaddleab
this.a(PathType.DAMAGE_FIRE, 0.0F);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.striderRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.striderRidableInWater;
+ }
+ // Purpur end
+
public static boolean c(EntityTypes<EntityStrider> entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) {
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = blockposition.i();
@@ -89,6 +101,7 @@ public class EntityStrider extends EntityAnimal implements ISteerable, ISaddleab
@Override
protected void initPathfinder() {
this.bv = new PathfinderGoalPanic(this, 1.65D);
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, this.bv);
this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D));
this.bu = new PathfinderGoalTempt(this, 1.4D, false, EntityStrider.bp);
@@ -363,7 +376,7 @@ public class EntityStrider extends EntityAnimal implements ISteerable, ISaddleab
if (!enuminteractionresult.a()) {
ItemStack itemstack = entityhuman.b(enumhand);
- return itemstack.getItem() == Items.SADDLE ? itemstack.a(entityhuman, (EntityLiving) this, enumhand) : EnumInteractionResult.PASS;
+ return itemstack.getItem() == Items.SADDLE ? itemstack.a(entityhuman, (EntityLiving) this, enumhand) : tryRide(entityhuman, enumhand); // Purpur
} else {
if (flag && !this.isSilent()) {
this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_STRIDER_EAT, this.getSoundCategory(), 1.0F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F);
diff --git a/src/main/java/net/minecraft/server/EntityTameableAnimal.java b/src/main/java/net/minecraft/server/EntityTameableAnimal.java
index 9e008d56bb..8f227678dc 100644
--- a/src/main/java/net/minecraft/server/EntityTameableAnimal.java
+++ b/src/main/java/net/minecraft/server/EntityTameableAnimal.java
@@ -130,6 +130,7 @@ public abstract class EntityTameableAnimal extends EntityAnimal {
return this.i(entityliving) ? false : super.c(entityliving);
}
+ public boolean isOwner(EntityLiving entityLiving) { return i(entityLiving); } // Purpur - OBFHELPER
public boolean i(EntityLiving entityliving) {
return entityliving == this.getOwner();
}
diff --git a/src/main/java/net/minecraft/server/EntityTropicalFish.java b/src/main/java/net/minecraft/server/EntityTropicalFish.java
index 495c28ccb8..2c9df356e6 100644
--- a/src/main/java/net/minecraft/server/EntityTropicalFish.java
+++ b/src/main/java/net/minecraft/server/EntityTropicalFish.java
@@ -19,6 +19,18 @@ public class EntityTropicalFish extends EntityFishSchool {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.tropicalFishRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return true;
+ }
+ // Purpur end
+
@Override
protected void initDatawatcher() {
super.initDatawatcher();
diff --git a/src/main/java/net/minecraft/server/EntityTurtle.java b/src/main/java/net/minecraft/server/EntityTurtle.java
index 4ad393bc99..2b34e6cf3b 100644
--- a/src/main/java/net/minecraft/server/EntityTurtle.java
+++ b/src/main/java/net/minecraft/server/EntityTurtle.java
@@ -27,6 +27,18 @@ public class EntityTurtle extends EntityAnimal {
this.G = 1.0F;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.turtleRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.turtleRidableInWater;
+ }
+ // Purpur end
+
public void setHomePos(BlockPosition blockposition) {
this.datawatcher.set(EntityTurtle.bp, blockposition.immutableCopy()); // Paper - called with mutablepos...
}
@@ -135,12 +147,13 @@ public class EntityTurtle extends EntityAnimal {
@Override
protected void initPathfinder() {
- this.goalSelector.a(0, new EntityTurtle.f(this, 1.2D));
- this.goalSelector.a(1, new EntityTurtle.a(this, 1.0D));
- this.goalSelector.a(1, new EntityTurtle.d(this, 1.0D));
- this.goalSelector.a(2, new EntityTurtle.i(this, 1.1D, Blocks.SEAGRASS.getItem()));
- this.goalSelector.a(3, new EntityTurtle.c(this, 1.0D));
- this.goalSelector.a(4, new EntityTurtle.b(this, 1.0D));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
+ this.goalSelector.a(1, new EntityTurtle.f(this, 1.2D)); // Purpur
+ this.goalSelector.a(2, new EntityTurtle.a(this, 1.0D)); // Purpur
+ this.goalSelector.a(2, new EntityTurtle.d(this, 1.0D)); // Purpur
+ this.goalSelector.a(3, new EntityTurtle.i(this, 1.1D, Blocks.SEAGRASS.getItem())); // Purpur
+ this.goalSelector.a(4, new EntityTurtle.c(this, 1.0D)); // Purpur
+ this.goalSelector.a(5, new EntityTurtle.b(this, 1.0D)); // Purpur
this.goalSelector.a(7, new EntityTurtle.j(this, 1.0D));
this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(9, new EntityTurtle.h(this, 1.0D, 100));
@@ -323,13 +336,15 @@ public class EntityTurtle extends EntityAnimal {
}
}
- static class e extends ControllerMove {
+ static class e extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur
- private final EntityTurtle i;
+ private final EntityTurtle i; public EntityTurtle getTurtle() { return i; } // Purpur - OBFHELPER
+ private final net.pl3x.purpur.controller.ControllerMoveWASDWater waterController; // Purpur
e(EntityTurtle entityturtle) {
- super(entityturtle);
+ super(entityturtle, 0.1D); // Purpur
this.i = entityturtle;
+ waterController = new net.pl3x.purpur.controller.ControllerMoveWASDWater(entityturtle, 0.25D); // Purpur
}
private void g() {
@@ -349,7 +364,18 @@ public class EntityTurtle extends EntityAnimal {
}
@Override
- public void a() {
+ // Purpur start
+ public void tick(EntityHuman rider) {
+ if (getTurtle().isInWater()) {
+ waterController.tick(rider);
+ } else {
+ super.tick(rider);
+ }
+ }
+
+ @Override
+ public void tick() {
+ // Purpur end
this.g();
if (this.h == ControllerMove.Operation.MOVE_TO && !this.i.getNavigation().m()) {
double d0 = this.b - this.i.locX();
diff --git a/src/main/java/net/minecraft/server/EntityVex.java b/src/main/java/net/minecraft/server/EntityVex.java
index ed6a47ad2f..ac75ed3e2e 100644
--- a/src/main/java/net/minecraft/server/EntityVex.java
+++ b/src/main/java/net/minecraft/server/EntityVex.java
@@ -19,6 +19,45 @@ public class EntityVex extends EntityMonster {
this.f = 3;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.vexRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.vexRidableInWater;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.vexMaxY;
+ }
+
+ @Override
+ public void g(Vec3D vec3d) {
+ super.g(vec3d);
+ if (hasRider()) {
+ float speed;
+ if (onGround) {
+ speed = (float) getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * 0.1F;
+ } else {
+ speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue();
+ }
+ setSpeed(speed);
+ Vec3D mot = getMot();
+ move(EnumMoveType.SELF, mot.multiply(speed, 1.0, speed));
+ setMot(mot.a(0.9D));
+ }
+ }
+
+ @Override
+ public boolean b(float f, float f1) {
+ return false; // no fall damage please
+ }
+ // Purpur end
+
@Override
public void move(EnumMoveType enummovetype, Vec3D vec3d) {
super.move(enummovetype, vec3d);
@@ -27,7 +66,7 @@ public class EntityVex extends EntityMonster {
@Override
public void tick() {
- this.noclip = true;
+ this.noclip = !hasRider(); // Purpur
super.tick();
this.noclip = false;
this.setNoGravity(true);
@@ -42,17 +81,19 @@ public class EntityVex extends EntityMonster {
protected void initPathfinder() {
super.initPathfinder();
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(4, new EntityVex.a());
this.goalSelector.a(8, new EntityVex.d());
this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F));
this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error
this.targetSelector.a(2, new EntityVex.b(this));
this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true));
}
public static AttributeProvider.Builder m() {
- return EntityMonster.eR().a(GenericAttributes.MAX_HEALTH, 14.0D).a(GenericAttributes.ATTACK_DAMAGE, 4.0D);
+ return EntityMonster.eR().a(GenericAttributes.MAX_HEALTH, 14.0D).a(GenericAttributes.ATTACK_DAMAGE, 4.0D).a(GenericAttributes.FLYING_SPEED, 0.6D); // Purpur
}
@Override
@@ -284,14 +325,14 @@ public class EntityVex extends EntityMonster {
}
}
- class c extends ControllerMove {
+ class c extends net.pl3x.purpur.controller.ControllerMoveWASDFlying { // Purpur
public c(EntityVex entityvex) {
super(entityvex);
}
@Override
- public void a() {
+ public void tick() { // Purpur
if (this.h == ControllerMove.Operation.MOVE_TO) {
Vec3D vec3d = new Vec3D(this.b - EntityVex.this.locX(), this.c - EntityVex.this.locY(), this.d - EntityVex.this.locZ());
double d0 = vec3d.f();
diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java
index a95bf56823..cead15b075 100644
--- a/src/main/java/net/minecraft/server/EntityVillager.java
+++ b/src/main/java/net/minecraft/server/EntityVillager.java
@@ -75,8 +75,19 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
}
// Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.villagerRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.villagerRidableInWater;
+ }
+
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
if (world.purpurConfig.villagerFollowEmeraldBlock) this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, TEMPT_ITEMS));
}
@@ -241,7 +252,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
if (itemstack.getItem() != Items.VILLAGER_SPAWN_EGG && this.isAlive() && !this.eN() && !this.isSleeping()) {
if (this.isBaby()) {
this.fk();
- return EnumInteractionResult.a(this.world.isClientSide);
+ return super.b(entityhuman, enumhand); // Purpur
} else {
boolean flag = this.getOffers().isEmpty();
@@ -254,8 +265,9 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
}
if (flag) {
- return EnumInteractionResult.a(this.world.isClientSide);
+ return tryRide(entityhuman, enumhand); // Purpur
} else {
+ if (world.purpurConfig.villagerRidable && itemstack.isEmpty()) return tryRide(entityhuman, enumhand); // Purpur
if (!this.world.isClientSide && !this.trades.isEmpty()) {
this.h(entityhuman);
}
diff --git a/src/main/java/net/minecraft/server/EntityVillagerTrader.java b/src/main/java/net/minecraft/server/EntityVillagerTrader.java
index 96dda6a14f..3ea66955df 100644
--- a/src/main/java/net/minecraft/server/EntityVillagerTrader.java
+++ b/src/main/java/net/minecraft/server/EntityVillagerTrader.java
@@ -23,6 +23,7 @@ public class EntityVillagerTrader extends EntityVillagerAbstract {
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(0, new PathfinderGoalUseItem<>(this, PotionUtil.a(new ItemStack(Items.POTION), Potions.INVISIBILITY), SoundEffects.ENTITY_WANDERING_TRADER_DISAPPEARED, (entityvillagertrader) -> {
return this.world.isNight() && !entityvillagertrader.isInvisible();
}));
@@ -48,6 +49,16 @@ public class EntityVillagerTrader extends EntityVillagerAbstract {
}
// Purpur - start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.villagerTraderRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.villagerTraderRidableInWater;
+ }
+
@Override
public boolean a(EntityHuman entityhuman) {
return world.purpurConfig.villagerTraderCanBeLeashed && !this.isLeashed();
@@ -75,8 +86,9 @@ public class EntityVillagerTrader extends EntityVillagerAbstract {
}
if (this.getOffers().isEmpty()) {
- return EnumInteractionResult.a(this.world.isClientSide);
+ return tryRide(entityhuman, enumhand); // Purpur
} else {
+ if (world.purpurConfig.villagerTraderRidable && itemstack.isEmpty()) return tryRide(entityhuman, enumhand); // Purpur
if (!this.world.isClientSide) {
this.setTradingPlayer(entityhuman);
this.openTrade(entityhuman, this.getScoreboardDisplayName(), 1);
diff --git a/src/main/java/net/minecraft/server/EntityVindicator.java b/src/main/java/net/minecraft/server/EntityVindicator.java
index 8f812aa913..9950bda50f 100644
--- a/src/main/java/net/minecraft/server/EntityVindicator.java
+++ b/src/main/java/net/minecraft/server/EntityVindicator.java
@@ -17,14 +17,28 @@ public class EntityVindicator extends EntityIllagerAbstract {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.vindicatorRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.vindicatorRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
super.initPathfinder();
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new EntityVindicator.a(this));
this.goalSelector.a(2, new EntityIllagerAbstract.b(this));
this.goalSelector.a(3, new EntityRaider.a(this, 10.0F));
this.goalSelector.a(4, new EntityVindicator.c(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // Paper - decompile fix
this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true));
this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, true));
diff --git a/src/main/java/net/minecraft/server/EntityWitch.java b/src/main/java/net/minecraft/server/EntityWitch.java
index ca3c5150bc..323d79a994 100644
--- a/src/main/java/net/minecraft/server/EntityWitch.java
+++ b/src/main/java/net/minecraft/server/EntityWitch.java
@@ -24,6 +24,18 @@ public class EntityWitch extends EntityRaider implements IRangedEntity {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.witchRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.witchRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
super.initPathfinder();
@@ -32,10 +44,12 @@ public class EntityWitch extends EntityRaider implements IRangedEntity {
});
this.bs = new PathfinderGoalNearestAttackableTargetWitch<>(this, EntityHuman.class, 10, true, false, (Predicate) null);
this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(2, new PathfinderGoalArrowAttack(this, 1.0D, 60, 10.0F));
this.goalSelector.a(2, new PathfinderGoalRandomStrollLand(this, 1.0D));
this.goalSelector.a(3, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(3, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class}));
this.targetSelector.a(2, this.br);
this.targetSelector.a(3, this.bs);
diff --git a/src/main/java/net/minecraft/server/EntityWither.java b/src/main/java/net/minecraft/server/EntityWither.java
index 53482a420c..f68cf834aa 100644
--- a/src/main/java/net/minecraft/server/EntityWither.java
+++ b/src/main/java/net/minecraft/server/EntityWither.java
@@ -32,6 +32,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
return entityliving.getMonsterType() != EnumMonsterType.UNDEAD && entityliving.ei();
};
private static final PathfinderTargetCondition bz = (new PathfinderTargetCondition()).a(20.0D).a(EntityWither.by);
+ private int shootCooldown = 0; // Purpur
public EntityWither(EntityTypes<? extends EntityWither> entitytypes, World world) {
super(entitytypes, world);
@@ -39,15 +40,122 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
this.setHealth(this.getMaxHealth());
this.getNavigation().d(true);
this.f = 50;
+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar(this, 0.1F); // Purpur
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.witherRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.witherRidableInWater;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.witherMaxY;
+ }
+
+ @Override
+ public void g(Vec3D vec3d) {
+ super.g(vec3d);
+ if (hasRider() && !onGround) {
+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue() * 5F;
+ setSpeed(speed);
+ Vec3D mot = getMot();
+ move(EnumMoveType.SELF, mot.multiply(speed, 0.5, speed));
+ setMot(mot.a(0.9D));
+ }
+ }
+
+ @Override
+ public void onMount(EntityHuman entityhuman) {
+ super.onMount(entityhuman);
+ this.datawatcher.set(bo.get(0), 0);
+ this.datawatcher.set(bo.get(1), 0);
+ this.datawatcher.set(bo.get(2), 0);
+ getNavigation().stopPathfinding();
+ shootCooldown = 20;
+ }
+
+ @Override
+ public boolean onClick(EnumHand hand) {
+ return shoot(getRider(), hand == EnumHand.MAIN_HAND ? new int[]{1} : new int[]{2});
+ }
+
+ public boolean shoot(EntityHuman 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;
+ }
+
+ MovingObjectPosition rayTrace = getRayTrace(120, RayTrace.FluidCollisionOption.NONE);
+ if (rayTrace == null) {
+ return false;
+ }
+
+ Vec3D loc;
+ if (rayTrace.getType() == MovingObjectPosition.EnumMovingObjectType.BLOCK) {
+ BlockPosition pos = ((MovingObjectPositionBlock) rayTrace).getBlockPosition();
+ loc = new Vec3D(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D);
+ } else if (rayTrace.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY) {
+ Entity target = ((MovingObjectPositionEntity) rayTrace).getEntity();
+ loc = new Vec3D(target.locX(), target.locY() + (target.getHeadHeight() / 2), target.locZ());
+ } else {
+ org.bukkit.block.Block block = player.getTargetBlock(null, 120);
+ loc = new Vec3D(block.getX() + 0.5D, block.getY() + 0.5D, block.getZ() + 0.5D);
+ }
+
+ for (int head : heads) {
+ shoot(head, loc.getX(), loc.getY(), loc.getZ(), rider);
+ }
+
+ return true; // handled
+ }
+
+ public void shoot(int head, double x, double y, double z, EntityHuman rider) {
+ world.playEvent(null, 1024, getChunkCoordinates(), 0);
+ double headX = getHeadX(head);
+ double headY = getHeadY(head);
+ double headZ = getHeadZ(head);
+ EntityWitherSkull skull = new EntityWitherSkull(world, this, x - headX, y - headY, z - headZ) {
+ @Override
+ public boolean canSaveToDisk() {
+ return false;
+ }
+
+ @Override
+ public boolean hitPredicate(Entity target) {
+ // do not hit rider
+ return target != rider && super.hitPredicate(target);
+ }
+ };
+ skull.setPositionRaw(headX, headY, headZ);
+ world.addEntity(skull);
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
- this.goalSelector.a(0, new EntityWither.a());
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
+ this.goalSelector.a(1, new EntityWither.a()); // Purpur
this.goalSelector.a(2, new PathfinderGoalArrowAttack(this, 1.0D, 40, 20.0F));
this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 1.0D));
this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[0]));
this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityInsentient.class, 0, false, false, EntityWither.by));
}
@@ -189,6 +297,16 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
@Override
protected void mobTick() {
+ // Purpur start
+ if (hasRider()) {
+ Vec3D mot = getMot();
+ setMot(mot.x, mot.y + (getVertical() > 0 ? 0.07D : 0.0D), mot.z);
+ }
+ if (shootCooldown > 0) {
+ shootCooldown--;
+ }
+ // Purpur end
+
int i;
if (this.getInvul() > 0) {
@@ -372,7 +490,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
this.bossBattle.removePlayer(entityplayer);
}
- private double u(int i) {
+ private double u(int i) { return getHeadX(i); } private double getHeadX(int i) { // Purpur - OBFHELPER
if (i <= 0) {
return this.locX();
} else {
@@ -383,11 +501,11 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
}
}
- private double v(int i) {
+ private double v(int i) { return getHeadY(i); } private double getHeadY(int i) { // Purpur - OBFHELPER
return i <= 0 ? this.locY() + 3.0D : this.locY() + 2.2D;
}
- private double w(int i) {
+ private double w(int i) { return getHeadZ(i); } private double getHeadZ(int i) { // Purpur - OBFHELPER
if (i <= 0) {
return this.locZ();
} else {
@@ -511,7 +629,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
}
public static AttributeProvider.Builder eK() {
- return EntityMonster.eR().a(GenericAttributes.MAX_HEALTH, 300.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.6000000238418579D).a(GenericAttributes.FOLLOW_RANGE, 40.0D).a(GenericAttributes.ARMOR, 4.0D);
+ return EntityMonster.eR().a(GenericAttributes.MAX_HEALTH, 300.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.6000000238418579D).a(GenericAttributes.FOLLOW_RANGE, 40.0D).a(GenericAttributes.ARMOR, 4.0D).a(GenericAttributes.FLYING_SPEED, 0.6D); // Purpur
}
public int getInvul() {
@@ -523,11 +641,11 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
}
public int getHeadTarget(int i) {
- return (Integer) this.datawatcher.get((DataWatcherObject) EntityWither.bo.get(i));
+ return hasRider() ? 0 : this.datawatcher.get(EntityWither.bo.get(i)); // Purpur
}
public void setHeadTarget(int i, int j) {
- this.datawatcher.set((DataWatcherObject) EntityWither.bo.get(i), j);
+ if (!hasRider()) this.datawatcher.set(EntityWither.bo.get(i), j); // Purpur
}
public boolean S_() {
@@ -541,7 +659,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
@Override
protected boolean n(Entity entity) {
- return false;
+ return getRideCooldown() <= 0; // Purpur
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityWolf.java b/src/main/java/net/minecraft/server/EntityWolf.java
index dcbb34313f..9ae7168595 100644
--- a/src/main/java/net/minecraft/server/EntityWolf.java
+++ b/src/main/java/net/minecraft/server/EntityWolf.java
@@ -33,9 +33,27 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable
this.setTamed(false);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.wolfRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.wolfRidableInWater;
+ }
+
+ public void onMount(EntityHuman entityhuman) {
+ super.onMount(entityhuman);
+ setSitting(false);
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(2, new PathfinderGoalSit(this));
this.goalSelector.a(3, new EntityWolf.a<>(this, EntityLlama.class, 24.0F, 1.5D, 1.5D));
this.goalSelector.a(4, new PathfinderGoalLeapAtTarget(this, 0.4F));
@@ -46,6 +64,7 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable
this.goalSelector.a(9, new PathfinderGoalBeg(this, 8.0F));
this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(10, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalOwnerHurtByTarget(this));
this.targetSelector.a(2, new PathfinderGoalOwnerHurtTarget(this));
this.targetSelector.a(3, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error
diff --git a/src/main/java/net/minecraft/server/EntityZoglin.java b/src/main/java/net/minecraft/server/EntityZoglin.java
index e76e6ebde7..d92fe8013f 100644
--- a/src/main/java/net/minecraft/server/EntityZoglin.java
+++ b/src/main/java/net/minecraft/server/EntityZoglin.java
@@ -21,6 +21,18 @@ public class EntityZoglin extends EntityMonster implements IMonster, IOglin {
this.f = 5;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.zoglinRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.zoglinRidableInWater;
+ }
+ // Purpur end
+
@Override
protected BehaviorController.b<EntityZoglin> cK() {
return BehaviorController.a((Collection) EntityZoglin.c, (Collection) EntityZoglin.b);
@@ -52,10 +64,10 @@ public class EntityZoglin extends EntityMonster implements IMonster, IOglin {
}
private Optional<? extends EntityLiving> eO() {
- return ((List) this.getBehaviorController().getMemory(MemoryModuleType.VISIBLE_MOBS).orElse(ImmutableList.of())).stream().filter(EntityZoglin::i).findFirst();
+ return (this.getBehaviorController().getMemory(MemoryModuleType.VISIBLE_MOBS).orElse(ImmutableList.of())).stream().filter(EntityZoglin::predicate).findFirst(); // Purpur - decompile error
}
- private static boolean i(EntityLiving entityliving) {
+ private static boolean predicate(EntityLiving entityliving) { // Purpur - decompile error
EntityTypes<?> entitytypes = entityliving.getEntityType();
return entitytypes != EntityTypes.ZOGLIN && entitytypes != EntityTypes.CREEPER && IEntitySelector.f.test(entityliving);
@@ -140,14 +152,14 @@ public class EntityZoglin extends EntityMonster implements IMonster, IOglin {
@Override
public BehaviorController<EntityZoglin> getBehaviorController() {
- return super.getBehaviorController();
+ return (BehaviorController<EntityZoglin>) super.getBehaviorController(); // Purpur - decompile error
}
protected void eL() {
- Activity activity = (Activity) this.bg.f().orElse((Object) null);
+ Activity activity = (Activity) this.bg.f().orElse(null); // Purpur - decompile error
this.bg.a((List) ImmutableList.of(Activity.FLIGHT, Activity.IDLE));
- Activity activity1 = (Activity) this.bg.f().orElse((Object) null);
+ Activity activity1 = (Activity) this.bg.f().orElse(null); // Purpur - decompile error
if (activity1 == Activity.FLIGHT && activity != Activity.FLIGHT) {
this.eN();
@@ -159,7 +171,8 @@ public class EntityZoglin extends EntityMonster implements IMonster, IOglin {
@Override
protected void mobTick() {
this.world.getMethodProfiler().enter("zoglinBrain");
- this.getBehaviorController().a((WorldServer) this.world, (EntityLiving) this);
+ if (getRider() == null) // Purpur - only use brain if no rider
+ this.getBehaviorController().a((WorldServer) this.world, this); // Purpur - decompile error
this.world.getMethodProfiler().exit();
this.eL();
}
diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java
index b90ea31440..e2f68d843c 100644
--- a/src/main/java/net/minecraft/server/EntityZombie.java
+++ b/src/main/java/net/minecraft/server/EntityZombie.java
@@ -46,6 +46,16 @@ public class EntityZombie extends EntityMonster {
}
// Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.zombieRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.zombieRidableInWater;
+ }
+
public boolean jockeyOnlyBaby() {
return world.purpurConfig.zombieJockeyOnlyBaby;
}
@@ -61,9 +71,11 @@ public class EntityZombie extends EntityMonster {
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
if (world.paperConfig.zombiesTargetTurtleEggs) this.goalSelector.a(4, new EntityZombie.a(this, 1.0D, 3)); // Paper
this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur
this.m();
}
diff --git a/src/main/java/net/minecraft/server/EntityZombieHusk.java b/src/main/java/net/minecraft/server/EntityZombieHusk.java
index ce6d797801..02b0ae550a 100644
--- a/src/main/java/net/minecraft/server/EntityZombieHusk.java
+++ b/src/main/java/net/minecraft/server/EntityZombieHusk.java
@@ -9,6 +9,16 @@ public class EntityZombieHusk extends EntityZombie {
}
// Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.huskRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.huskRidableInWater;
+ }
+
@Override
public boolean jockeyOnlyBaby() {
return world.purpurConfig.huskJockeyOnlyBaby;
diff --git a/src/main/java/net/minecraft/server/EntityZombieVillager.java b/src/main/java/net/minecraft/server/EntityZombieVillager.java
index b86816205c..7db942c659 100644
--- a/src/main/java/net/minecraft/server/EntityZombieVillager.java
+++ b/src/main/java/net/minecraft/server/EntityZombieVillager.java
@@ -29,6 +29,16 @@ public class EntityZombieVillager extends EntityZombie implements VillagerDataHo
}
// Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.zombieVillagerRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.zombieVillagerRidableInWater;
+ }
+
@Override
public boolean jockeyOnlyBaby() {
return world.purpurConfig.zombieVillagerJockeyOnlyBaby;
diff --git a/src/main/java/net/minecraft/server/GeneratorAccess.java b/src/main/java/net/minecraft/server/GeneratorAccess.java
index cbc0b8bc85..89d64ea0d1 100644
--- a/src/main/java/net/minecraft/server/GeneratorAccess.java
+++ b/src/main/java/net/minecraft/server/GeneratorAccess.java
@@ -37,6 +37,7 @@ public interface GeneratorAccess extends ICombinedAccess, IWorldTime {
void addParticle(ParticleParam particleparam, double d0, double d1, double d2, double d3, double d4, double d5);
+ default void playEvent(@Nullable EntityHuman entityhuman, int i, BlockPosition blockposition, int j) { a(entityhuman, i, blockposition, j); } // Purpur - OBFHELPER
void a(@Nullable EntityHuman entityhuman, int i, BlockPosition blockposition, int j);
default int getHeight() {
diff --git a/src/main/java/net/minecraft/server/IProjectile.java b/src/main/java/net/minecraft/server/IProjectile.java
index 0bac6b0506..9a17eb6066 100644
--- a/src/main/java/net/minecraft/server/IProjectile.java
+++ b/src/main/java/net/minecraft/server/IProjectile.java
@@ -12,7 +12,7 @@ public abstract class IProjectile extends Entity {
private UUID shooter;
private int c;
- private boolean d;
+ private boolean d; public boolean leftOwner() { return d; } public void setLeftOwner(boolean leftOwner) { this.d = leftOwner; } // Purpur - OBFHELPER
IProjectile(EntityTypes<? extends IProjectile> entitytypes, World world) {
super(entitytypes, world);
@@ -81,6 +81,7 @@ public abstract class IProjectile extends Entity {
super.tick();
}
+ public boolean checkIfLeftOwner() { return this.h(); } // Purpur - OBFHELPER
private boolean h() {
Entity entity = this.getShooter();
@@ -144,7 +145,7 @@ public abstract class IProjectile extends Entity {
iblockdata.a(this.world, iblockdata, movingobjectpositionblock, this);
}
- protected boolean a(Entity entity) {
+ protected boolean a(Entity entity) { return hitPredicate(entity); } public boolean hitPredicate(Entity entity) { // Purpur - OBFHELPER
if (!entity.isSpectator() && entity.isAlive() && entity.isInteractable()) {
Entity entity1 = this.getShooter();
// Paper start - Cancel hit for vanished players
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalHasRider.java b/src/main/java/net/minecraft/server/PathfinderGoalHasRider.java
new file mode 100644
index 0000000000..da18e1235e
--- /dev/null
+++ b/src/main/java/net/minecraft/server/PathfinderGoalHasRider.java
@@ -0,0 +1,18 @@
+package net.minecraft.server;
+
+import java.util.EnumSet;
+
+public class PathfinderGoalHasRider extends PathfinderGoal {
+ public final EntityInsentient entity;
+
+ public PathfinderGoalHasRider(EntityInsentient entity) {
+ this.entity = entity;
+ setTypes(EnumSet.of(Type.JUMP, Type.MOVE, Type.LOOK, Type.TARGET, Type.UNKNOWN_BEHAVIOR));
+ }
+
+ // shouldExecute
+ @Override
+ public boolean a() {
+ return entity.hasRider();
+ }
+}
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalHorseHasRider.java b/src/main/java/net/minecraft/server/PathfinderGoalHorseHasRider.java
new file mode 100644
index 0000000000..44929182df
--- /dev/null
+++ b/src/main/java/net/minecraft/server/PathfinderGoalHorseHasRider.java
@@ -0,0 +1,16 @@
+package net.minecraft.server;
+
+public class PathfinderGoalHorseHasRider extends PathfinderGoalHasRider {
+ private final EntityHorseAbstract horse;
+
+ public PathfinderGoalHorseHasRider(EntityHorseAbstract entity) {
+ super(entity);
+ this.horse = entity;
+ }
+
+ // shouldExecute
+ @Override
+ public boolean a() {
+ return super.a() && horse.hasSaddle();
+ }
+}
diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java
index 9d6ef83ef5..d47902ac6c 100644
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
@@ -2232,6 +2232,8 @@ public class PlayerConnection implements PacketListenerPlayIn {
}
this.server.getPluginManager().callEvent(event);
+ player.processClick(enumhand); // Purpur
+
// Fish bucket - SPIGOT-4048
if ((entity instanceof EntityFish && origItem != null && origItem.getItem() == Items.WATER_BUCKET) && (event.isCancelled() || this.player.inventory.getItemInHand() == null || this.player.inventory.getItemInHand().getItem() != origItem)) {
this.sendPacket(new PacketPlayOutSpawnEntityLiving((EntityFish) entity));
diff --git a/src/main/java/net/minecraft/server/ProjectileHelper.java b/src/main/java/net/minecraft/server/ProjectileHelper.java
index b2c64b3144..515ba50aec 100644
--- a/src/main/java/net/minecraft/server/ProjectileHelper.java
+++ b/src/main/java/net/minecraft/server/ProjectileHelper.java
@@ -7,6 +7,7 @@ import javax.annotation.Nullable;
public final class ProjectileHelper {
+ public static MovingObjectPosition getHitResult(Entity entity, Predicate<Entity> predicate) { return a(entity, predicate); } // Purpur - OBFHELPER
public static MovingObjectPosition a(Entity entity, Predicate<Entity> predicate) {
Vec3D vec3d = entity.getMot();
World world = entity.world;
diff --git a/src/main/java/net/minecraft/server/Vec3D.java b/src/main/java/net/minecraft/server/Vec3D.java
index 5af554870b..c59305ef7d 100644
--- a/src/main/java/net/minecraft/server/Vec3D.java
+++ b/src/main/java/net/minecraft/server/Vec3D.java
@@ -39,6 +39,7 @@ public class Vec3D implements IPosition {
return new Vec3D(vec3d.x - this.x, vec3d.y - this.y, vec3d.z - this.z);
}
+ public Vec3D normalize() { return d(); } // Purpur - OBFHELPER
public Vec3D d() {
double d0 = (double) MathHelper.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
@@ -98,6 +99,7 @@ public class Vec3D implements IPosition {
return d3 * d3 + d4 * d4 + d5 * d5;
}
+ public Vec3D scale(double scale) { return a(scale); } // Purpur - OBFHELPER
public Vec3D a(double d0) {
return this.d(d0, d0, d0);
}
@@ -106,6 +108,7 @@ public class Vec3D implements IPosition {
return this.d(vec3d.x, vec3d.y, vec3d.z);
}
+ public Vec3D multiply (double x, double y, double z) { return d(x, y, z); } // Purpur - OBFHELPER
public Vec3D d(double d0, double d1, double d2) {
return new Vec3D(this.x * d0, this.y * d1, this.z * d2);
}
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index 10a2d2a20c..64824e708a 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -1648,5 +1648,10 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
public boolean isTheEnd() {
return getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END;
}
+
+ // Purpur start
+ public void playEffect(@Nullable EntityHuman entityhuman, int i, BlockPosition blockposition, int j) {
+ this.a(entityhuman, i, blockposition, j);
+ }
// Purpur end
}
diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java
index 8714d1574d..af3739c79a 100644
--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java
@@ -134,11 +134,13 @@ public class PurpurConfig {
public static String afkBroadcastBack = "§e§o%s is no longer AFK";
public static String afkTabListPrefix = "[AFK] ";
public static String pingCommandOutput = "§a%s's ping is %sms";
+ public static String cannotRideMob = "§cYou cannot mount that mob";
private static void messages() {
afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway);
afkBroadcastBack = getString("settings.messages.afk-broadcast-back", afkBroadcastBack);
afkTabListPrefix = getString("settings.messages.afk-tab-list-prefix", afkTabListPrefix);
pingCommandOutput = getString("settings.messages.ping-command-output", pingCommandOutput);
+ cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob);
}
public static int dungeonSeed = -1;
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index 6ee0a3179b..1a606b426b 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -42,11 +42,6 @@ public class PurpurWorldConfig {
}
}
- public double vindicatorJohnnySpawnChance = 0D;
- private void vindicatorSettings() {
- vindicatorJohnnySpawnChance = getDouble("mobs.vindicator.johnny.spawn-chance", vindicatorJohnnySpawnChance);
- }
-
private ConfigurationSection getConfigurationSection(String path) {
ConfigurationSection section = PurpurConfig.config.getConfigurationSection("world-settings." + worldName + "." + path);
return section != null ? section : PurpurConfig.config.getConfigurationSection("world-settings.default." + path);
@@ -320,65 +315,190 @@ public class PurpurWorldConfig {
turtleEggsBreakFromMinecarts = getBoolean("blocks.turtle_egg.break-from-minecarts", turtleEggsBreakFromMinecarts);
}
+ public boolean babiesAreRidable = true;
+ public boolean untamedTamablesAreRidable = true;
+ public boolean useNightVisionWhenRiding = false;
+ private void ridableSettings() {
+ babiesAreRidable = getBoolean("ridable-settings.babies-are-ridable", babiesAreRidable);
+ untamedTamablesAreRidable = getBoolean("ridable-settings.untamed-tamables-are-ridable", untamedTamablesAreRidable);
+ useNightVisionWhenRiding = getBoolean("ridable-settings.use-night-vision", useNightVisionWhenRiding);
+ }
+
+ public boolean batRidable = false;
+ public boolean batRidableInWater = false;
+ public double batMaxY = 256D;
+ private void batSettings() {
+ batRidable = getBoolean("mobs.bat.ridable", batRidable);
+ batRidableInWater = getBoolean("mobs.bat.ridable-in-water", batRidableInWater);
+ batMaxY = getDouble("mobs.bat.ridable-max-y", batMaxY);
+ }
+
+ public boolean beeRidable = false;
+ public boolean beeRidableInWater = false;
+ public double beeMaxY = 256D;
+ private void beeSettings() {
+ beeRidable = getBoolean("mobs.bee.ridable", beeRidable);
+ beeRidableInWater = getBoolean("mobs.bee.ridable-in-water", beeRidableInWater);
+ beeMaxY = getDouble("mobs.bee.ridable-max-y", beeMaxY);
+ }
+
+ public boolean blazeRidable = false;
+ public boolean blazeRidableInWater = false;
+ public double blazeMaxY = 256D;
+ private void blazeSettings() {
+ blazeRidable = getBoolean("mobs.blaze.ridable", blazeRidable);
+ blazeRidableInWater = getBoolean("mobs.blaze.ridable-in-water", blazeRidableInWater);
+ blazeMaxY = getDouble("mobs.blaze.ridable-max-y", blazeMaxY);
+ }
+
+ public boolean catRidable = false;
+ public boolean catRidableInWater = false;
public int catSpawnDelay = 1200;
public int catSpawnSwampHutScanRange = 16;
public int catSpawnVillageScanRange = 48;
private void catSettings() {
+ catRidable = getBoolean("mobs.cat.ridable", catRidable);
+ catRidableInWater = getBoolean("mobs.cat.ridable-in-water", catRidableInWater);
catSpawnDelay = getInt("mobs.cat.spawn-delay", catSpawnDelay);
catSpawnSwampHutScanRange = getInt("mobs.cat.scan-range-for-other-cats.swamp-hut", catSpawnSwampHutScanRange);
catSpawnVillageScanRange = getInt("mobs.cat.scan-range-for-other-cats.village", catSpawnVillageScanRange);
}
+ public boolean caveSpiderRidable = false;
+ public boolean caveSpiderRidableInWater = false;
+ private void caveSpiderSettings() {
+ caveSpiderRidable = getBoolean("mobs.cave_spider.ridable", caveSpiderRidable);
+ caveSpiderRidableInWater = getBoolean("mobs.cave_spider.ridable-in-water", caveSpiderRidableInWater);
+ }
+
+ public boolean chickenRidable = false;
+ public boolean chickenRidableInWater = false;
public boolean chickenRetaliate = false;
private void chickenSettings() {
+ chickenRidable = getBoolean("mobs.chicken.ridable", chickenRidable);
+ chickenRidableInWater = getBoolean("mobs.chicken.ridable-in-water", chickenRidableInWater);
chickenRetaliate = getBoolean("mobs.chicken.retaliate", chickenRetaliate);
}
+ public boolean codRidable = false;
+ private void codSettings() {
+ codRidable = getBoolean("mobs.cod.ridable", codRidable);
+ }
+
+ public boolean cowRidable = false;
+ public boolean cowRidableInWater = false;
public int cowFeedMushrooms = 0;
private void cowSettings() {
+ cowRidable = getBoolean("mobs.cow.ridable", cowRidable);
+ cowRidableInWater = getBoolean("mobs.cow.ridable-in-water", cowRidableInWater);
cowFeedMushrooms = getInt("mobs.cow.feed-mushrooms-for-mooshroom", cowFeedMushrooms);
}
+ public boolean creeperRidable = false;
+ public boolean creeperRidableInWater = false;
public boolean creeperAllowGriefing = true;
public double creeperChargedChance = 0.0D;
private void creeperSettings() {
+ creeperRidable = getBoolean("mobs.creeper.ridable", creeperRidable);
+ creeperRidableInWater = getBoolean("mobs.creeper.ridable-in-water", creeperRidableInWater);
creeperAllowGriefing = getBoolean("mobs.creeper.allow-griefing", creeperAllowGriefing);
creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance);
}
+ public boolean dolphinRidable = false;
+ public int dolphinSpitCooldown = 20;
+ public float dolphinSpitSpeed = 1.0F;
+ public float dolphinSpitDamage = 2.0F;
public boolean dolphinDisableTreasureSearching = false;
private void dolphinSettings() {
+ dolphinRidable = getBoolean("mobs.dolphin.ridable", dolphinRidable);
+ dolphinSpitCooldown = getInt("mobs.dolphin.spit.cooldown", dolphinSpitCooldown);
+ dolphinSpitSpeed = (float) getDouble("mobs.dolphin.spit.speed", dolphinSpitSpeed);
+ dolphinSpitDamage = (float) getDouble("mobs.dolphin.spit.damage", dolphinSpitDamage);
dolphinDisableTreasureSearching = getBoolean("mobs.dolphin.disable-treasure-searching", dolphinDisableTreasureSearching);
}
+ public boolean donkeyRidableInWater = false;
+ private void donkeySettings() {
+ donkeyRidableInWater = getBoolean("mobs.donkey.ridable-in-water", donkeyRidableInWater);
+ }
+
+ public boolean drownedRidable = false;
+ public boolean drownedRidableInWater = false;
public boolean drownedJockeyOnlyBaby = true;
public double drownedJockeyChance = 0.05D;
public boolean drownedJockeyTryExistingChickens = true;
private void drownedSettings() {
+ drownedRidable = getBoolean("mobs.drowned.ridable", drownedRidable);
+ drownedRidableInWater = getBoolean("mobs.drowned.ridable-in-water", drownedRidableInWater);
drownedJockeyOnlyBaby = getBoolean("mobs.drowned.jockey.only-babies", drownedJockeyOnlyBaby);
drownedJockeyChance = getDouble("mobs.drowned.jockey.chance", drownedJockeyChance);
drownedJockeyTryExistingChickens = getBoolean("mobs.drowned.jockey.try-existing-chickens", drownedJockeyTryExistingChickens);
}
+ public boolean elderGuardianRidable = false;
+ private void elderGuardianSettings() {
+ elderGuardianRidable = getBoolean("mobs.elder_guardian.ridable", elderGuardianRidable);
+ }
+
+ public boolean enderDragonRidable = false;
+ public boolean enderDragonRidableInWater = false;
+ public double enderDragonMaxY = 256D;
public boolean enderDragonAlwaysDropsEggBlock = false;
public boolean enderDragonAlwaysDropsFullExp = false;
public double enderDragonMaxHealth = 200.0D;
private void enderDragonSettings() {
+ enderDragonRidable = getBoolean("mobs.ender_dragon.ridable", enderDragonRidable);
+ enderDragonRidableInWater = getBoolean("mobs.ender_dragon.ridable-in-water", enderDragonRidableInWater);
+ enderDragonMaxY = getDouble("mobs.ender_dragon.ridable-max-y", enderDragonMaxY);
enderDragonAlwaysDropsEggBlock = getBoolean("mobs.ender_dragon.always-drop-egg-block", enderDragonAlwaysDropsEggBlock);
enderDragonAlwaysDropsFullExp = getBoolean("mobs.ender_dragon.always-drop-full-exp", enderDragonAlwaysDropsFullExp);
enderDragonMaxHealth = getDouble("mobs.ender_dragon.max-health", enderDragonMaxHealth);
}
+ public boolean endermanRidable = false;
+ public boolean endermanRidableInWater = false;
public boolean endermanAllowGriefing = true;
private void endermanSettings() {
+ endermanRidable = getBoolean("mobs.enderman.ridable", endermanRidable);
+ endermanRidableInWater = getBoolean("mobs.enderman.ridable-in-water", endermanRidableInWater);
endermanAllowGriefing = getBoolean("mobs.enderman.allow-griefing", endermanAllowGriefing);
}
+ public boolean endermiteRidable = false;
+ public boolean endermiteRidableInWater = false;
+ private void endermiteSettings() {
+ endermiteRidable = getBoolean("mobs.endermite.ridable", endermiteRidable);
+ endermiteRidableInWater = getBoolean("mobs.endermite.ridable-in-water", endermiteRidableInWater);
+ }
+
+ public boolean evokerRidable = false;
+ public boolean evokerRidableInWater = false;
+ private void evokerSettings() {
+ evokerRidable = getBoolean("mobs.evoker.ridable", evokerRidable);
+ evokerRidableInWater = getBoolean("mobs.evoker.ridable-in-water", evokerRidableInWater);
+ }
+
+ public boolean foxRidable = false;
+ public boolean foxRidableInWater = false;
public boolean foxTypeChangesWithTulips = false;
private void foxSettings() {
+ foxRidable = getBoolean("mobs.fox.ridable", foxRidable);
+ foxRidableInWater = getBoolean("mobs.fox.ridable-in-water", foxRidableInWater);
foxTypeChangesWithTulips = getBoolean("mobs.fox.tulips-change-type", foxTypeChangesWithTulips);
}
+ public boolean ghastRidable = false;
+ public boolean ghastRidableInWater = false;
+ public double ghastMaxY = 256D;
+ private void ghastSettings() {
+ ghastRidable = getBoolean("mobs.ghast.ridable", ghastRidable);
+ ghastRidableInWater = getBoolean("mobs.ghast.ridable-in-water", ghastRidableInWater);
+ ghastMaxY = getDouble("mobs.ghast.ridable-max-y", ghastMaxY);
+ }
+
+ public boolean giantRidable = false;
+ public boolean giantRidableInWater = false;
public float giantStepHeight = 2.0F;
public float giantJumpHeight = 1.0F;
public double giantMaxHealth = 100.0D;
@@ -387,6 +507,8 @@ public class PurpurWorldConfig {
public boolean giantHaveAI = false;
public boolean giantHaveHostileAI = false;
private void giantSettings() {
+ giantRidable = getBoolean("mobs.giant.ridable", giantRidable);
+ giantRidableInWater = getBoolean("mobs.giant.ridable-in-water", giantRidableInWater);
giantStepHeight = (float) getDouble("mobs.giant.step-height", giantStepHeight);
giantJumpHeight = (float) getDouble("mobs.giant.jump-height", giantJumpHeight);
giantMaxHealth = getDouble("mobs.giant.max-health", giantMaxHealth);
@@ -396,29 +518,119 @@ public class PurpurWorldConfig {
giantHaveHostileAI = getBoolean("mobs.giant.have-hostile-ai", giantHaveHostileAI);
}
+ public boolean guardianRidable = false;
+ private void guardianSettings() {
+ guardianRidable = getBoolean("mobs.guardian.ridable", guardianRidable);
+ }
+
+ public boolean hoglinRidable = false;
+ public boolean hoglinRidableInWater = false;
+ private void hoglinSettings() {
+ hoglinRidable = getBoolean("mobs.hoglin.ridable", hoglinRidable);
+ hoglinRidableInWater = getBoolean("mobs.hoglin.ridable-in-water", hoglinRidableInWater);
+ }
+
+ public boolean horseRidableInWater = false;
+ private void horseSettings() {
+ horseRidableInWater = getBoolean("mobs.horse.ridable-in-water", horseRidableInWater);
+ }
+
+ public boolean huskRidable = false;
+ public boolean huskRidableInWater = false;
public boolean huskJockeyOnlyBaby = true;
public double huskJockeyChance = 0.05D;
public boolean huskJockeyTryExistingChickens = true;
private void huskSettings() {
+ huskRidable = getBoolean("mobs.husk.ridable", huskRidable);
+ huskRidableInWater = getBoolean("mobs.husk.ridable-in-water", huskRidableInWater);
huskJockeyOnlyBaby = getBoolean("mobs.husk.jockey.only-babies", huskJockeyOnlyBaby);
huskJockeyChance = getDouble("mobs.husk.jockey.chance", huskJockeyChance);
huskJockeyTryExistingChickens = getBoolean("mobs.husk.jockey.try-existing-chickens", huskJockeyTryExistingChickens);
}
+ public boolean illusionerRidable = false;
+ public boolean illusionerRidableInWater = false;
public double illusionerMaxHealth = 32.0D;
public double illusionerMovementSpeed = 0.5D;
public double illusionerFollowRange = 18.0D;
private void illusionerSettings() {
+ illusionerRidable = getBoolean("mobs.illusioner.ridable", illusionerRidable);
+ illusionerRidableInWater = getBoolean("mobs.illusioner.ridable-in-water", illusionerRidableInWater);
illusionerMaxHealth = getDouble("mobs.illusioner.max-health", illusionerMaxHealth);
illusionerMovementSpeed = getDouble("mobs.illusioner.movement-speed", illusionerMovementSpeed);
illusionerFollowRange = getDouble("mobs.illusioner.follow-range", illusionerFollowRange);
}
+ public boolean ironGolemRidable = false;
+ public boolean ironGolemRidableInWater = false;
public boolean ironGolemCanSwim = false;
private void ironGolemSettings() {
+ ironGolemRidable = getBoolean("mobs.iron_golem.ridable", ironGolemRidable);
+ ironGolemRidableInWater = getBoolean("mobs.iron_golem.ridable-in-water", ironGolemRidableInWater);
ironGolemCanSwim = getBoolean("mobs.iron_golem.can-swim", ironGolemCanSwim);
}
+ public boolean llamaRidable = false;
+ public boolean llamaRidableInWater = false;
+ private void llamaSettings() {
+ llamaRidable = getBoolean("mobs.llama.ridable", llamaRidable);
+ llamaRidableInWater = getBoolean("mobs.llama.ridable-in-water", llamaRidableInWater);
+ }
+
+ public boolean llamaTraderRidable = false;
+ public boolean llamaTraderRidableInWater = false;
+ private void llamaTraderSettings() {
+ llamaTraderRidable = getBoolean("mobs.trader_llama.ridable", llamaTraderRidable);
+ llamaTraderRidableInWater = getBoolean("mobs.trader_llama.ridable-in-water", llamaTraderRidableInWater);
+ }
+
+ public boolean magmaCubeRidable = false;
+ public boolean magmaCubeRidableInWater = false;
+ private void magmaCubeSettings() {
+ magmaCubeRidable = getBoolean("mobs.magma_cube.ridable", magmaCubeRidable);
+ magmaCubeRidableInWater = getBoolean("mobs.magma_cube.ridable-in-water", magmaCubeRidableInWater);
+ }
+
+ public boolean mooshroomRidable = false;
+ public boolean mooshroomRidableInWater = false;
+ private void mooshroomSettings() {
+ mooshroomRidable = getBoolean("mobs.mooshroom.ridable", mooshroomRidable);
+ mooshroomRidableInWater = getBoolean("mobs.mooshroom.ridable-in-water", mooshroomRidableInWater);
+ }
+
+ public boolean muleRidableInWater = false;
+ private void muleSettings() {
+ muleRidableInWater = getBoolean("mobs.mule.ridable-in-water", muleRidableInWater);
+ }
+
+ public boolean ocelotRidable = false;
+ public boolean ocelotRidableInWater = false;
+ private void ocelotSettings() {
+ ocelotRidable = getBoolean("mobs.ocelot.ridable", ocelotRidable);
+ ocelotRidableInWater = getBoolean("mobs.ocelot.ridable-in-water", ocelotRidableInWater);
+ }
+
+ public boolean pandaRidable = false;
+ public boolean pandaRidableInWater = false;
+ private void pandaSettings() {
+ pandaRidable = getBoolean("mobs.panda.ridable", pandaRidable);
+ pandaRidableInWater = getBoolean("mobs.panda.ridable-in-water", pandaRidableInWater);
+ }
+
+ public boolean parrotRidable = false;
+ public boolean parrotRidableInWater = false;
+ public double parrotMaxY = 256D;
+ private void parrotSettings() {
+ parrotRidable = getBoolean("mobs.parrot.ridable", parrotRidable);
+ parrotRidableInWater = getBoolean("mobs.parrot.ridable-in-water", parrotRidableInWater);
+ parrotMaxY = getDouble("mobs.parrot.ridable-max-y", parrotMaxY);
+ }
+
+ public boolean phantomRidable = false;
+ public boolean phantomRidableInWater = false;
+ public double phantomMaxY = 256D;
+ public float phantomFlameDamage = 1.0F;
+ public int phantomFlameFireTime = 8;
public double phantomAttackedByCrystalRadius = 0.0D;
public float phantomAttackedByCrystalDamage = 1.0F;
public double phantomOrbitCrystalRadius = 0.0D;
@@ -438,6 +650,11 @@ public class PurpurWorldConfig {
public boolean phantomIgnorePlayersWithTorch = false;
public boolean phantomBurnInDaylight = true;
private void phantomSettings() {
+ phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable);
+ phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater);
+ phantomMaxY = getDouble("mobs.phantom.ridable-max-y", phantomMaxY);
+ phantomFlameDamage = (float) getDouble("mobs.phantom.flames.damage", phantomFlameDamage);
+ phantomFlameFireTime = getInt("mobs.phantom.flames.fire-time", phantomFlameFireTime);
phantomAttackedByCrystalRadius = getDouble("mobs.phantom.attacked-by-crystal-range", phantomAttackedByCrystalRadius);
phantomAttackedByCrystalDamage = (float) getDouble("mobs.phantom.attacked-by-crystal-damage", phantomAttackedByCrystalDamage);
phantomOrbitCrystalRadius = getDouble("mobs.phantom.orbit-crystal-radius", phantomOrbitCrystalRadius);
@@ -458,40 +675,184 @@ public class PurpurWorldConfig {
phantomIgnorePlayersWithTorch = getBoolean("mobs.phantom.ignore-players-with-torch", phantomIgnorePlayersWithTorch);
}
+ public boolean pigRidable = false;
+ public boolean pigRidableInWater = false;
public boolean pigGiveSaddleBack = false;
private void pigSettings() {
+ pigRidable = getBoolean("mobs.pig.ridable", pigRidable);
+ pigRidableInWater = getBoolean("mobs.pig.ridable-in-water", pigRidableInWater);
pigGiveSaddleBack = getBoolean("mobs.pig.give-saddle-back", pigGiveSaddleBack);
}
+ public boolean piglinRidable = false;
+ public boolean piglinRidableInWater = false;
+ private void piglinSettings() {
+ piglinRidable = getBoolean("mobs.piglin.ridable", piglinRidable);
+ piglinRidableInWater = getBoolean("mobs.piglin.ridable-in-water", piglinRidableInWater);
+ }
+
+ public boolean piglinBruteRidable = false;
+ public boolean piglinBruteRidableInWater = false;
+ private void piglinBruteSettings() {
+ piglinBruteRidable = getBoolean("mobs.piglin_brute.ridable", piglinBruteRidable);
+ piglinBruteRidableInWater = getBoolean("mobs.piglin_brute.ridable-in-water", piglinBruteRidableInWater);
+ }
+
+ public boolean pillagerRidable = false;
+ public boolean pillagerRidableInWater = false;
+ private void pillagerSettings() {
+ pillagerRidable = getBoolean("mobs.pillager.ridable", pillagerRidable);
+ pillagerRidableInWater = getBoolean("mobs.pillager.ridable-in-water", pillagerRidableInWater);
+ }
+
+ public boolean polarBearRidable = false;
+ public boolean polarBearRidableInWater = false;
public String polarBearBreedableItemString = "";
public Item polarBearBreedableItem = null;
private void polarBearSettings() {
+ polarBearRidable = getBoolean("mobs.polar_bear.ridable", polarBearRidable);
+ polarBearRidableInWater = getBoolean("mobs.polar_bear.ridable-in-water", polarBearRidableInWater);
polarBearBreedableItemString = getString("mobs.polar_bear.breedable-item", polarBearBreedableItemString);
Item item = IRegistry.ITEM.get(new MinecraftKey(polarBearBreedableItemString));
if (item != Items.AIR) polarBearBreedableItem = item;
}
+ public boolean pufferfishRidable = false;
+ private void pufferfishSettings() {
+ pufferfishRidable = getBoolean("mobs.pufferfish.ridable", pufferfishRidable);
+ }
+
+ public boolean rabbitRidable = false;
+ public boolean rabbitRidableInWater = false;
public double rabbitNaturalToast = 0.0D;
public double rabbitNaturalKiller = 0.0D;
private void rabbitSettings() {
+ rabbitRidable = getBoolean("mobs.rabbit.ridable", rabbitRidable);
+ rabbitRidableInWater = getBoolean("mobs.rabbit.ridable-in-water", rabbitRidableInWater);
rabbitNaturalToast = getDouble("mobs.rabbit.spawn-toast-chance", rabbitNaturalToast);
rabbitNaturalKiller = getDouble("mobs.rabbit.spawn-killer-rabbit-chance", rabbitNaturalKiller);
}
+ public boolean ravagerRidable = false;
+ public boolean ravagerRidableInWater = false;
+ private void ravagerSettings() {
+ ravagerRidable = getBoolean("mobs.ravager.ridable", ravagerRidable);
+ ravagerRidableInWater = getBoolean("mobs.ravager.ridable-in-water", ravagerRidableInWater);
+ }
+
+ public boolean salmonRidable = false;
+ private void salmonSettings() {
+ salmonRidable = getBoolean("mobs.salmon.ridable", salmonRidable);
+ }
+
+ public boolean sheepRidable = false;
+ public boolean sheepRidableInWater = false;
+ private void sheepSettings() {
+ sheepRidable = getBoolean("mobs.sheep.ridable", sheepRidable);
+ sheepRidableInWater = getBoolean("mobs.sheep.ridable-in-water", sheepRidableInWater);
+ }
+
+ public boolean shulkerRidable = false;
+ public boolean shulkerRidableInWater = false;
+ private void shulkerSettings() {
+ shulkerRidable = getBoolean("mobs.shulker.ridable", shulkerRidable);
+ shulkerRidableInWater = getBoolean("mobs.shulker.ridable-in-water", shulkerRidableInWater);
+ }
+
+ public boolean silverfishRidable = false;
+ public boolean silverfishRidableInWater = false;
+ private void silverfishSettings() {
+ silverfishRidable = getBoolean("mobs.silverfish.ridable", silverfishRidable);
+ silverfishRidableInWater = getBoolean("mobs.silverfish.ridable-in-water", silverfishRidableInWater);
+ }
+
+ public boolean skeletonRidable = false;
+ public boolean skeletonRidableInWater = false;
+ private void skeletonSettings() {
+ skeletonRidable = getBoolean("mobs.skeleton.ridable", skeletonRidable);
+ skeletonRidableInWater = getBoolean("mobs.skeleton.ridable-in-water", skeletonRidableInWater);
+ }
+
+ public boolean skeletonHorseCanSwim = false;
+ public boolean skeletonHorseRidableInWater = true;
+ private void skeletonHorseSettings() {
+ skeletonHorseCanSwim = getBoolean("mobs.skeleton_horse.can-swim", skeletonHorseCanSwim);
+ skeletonHorseRidableInWater = getBoolean("mobs.skeleton_horse.ridable-in-water", skeletonHorseRidableInWater);
+ }
+
+ public boolean slimeRidable = false;
+ public boolean slimeRidableInWater = false;
+ private void slimeSettings() {
+ slimeRidable = getBoolean("mobs.slime.ridable", slimeRidable);
+ slimeRidableInWater = getBoolean("mobs.slime.ridable-in-water", slimeRidableInWater);
+ }
+
+ public boolean snowGolemRidable = false;
+ public boolean snowGolemRidableInWater = false;
+ public boolean snowGolemLeaveTrailWhenRidden = false;
public boolean snowGolemDropsPumpkin = false;
public boolean snowGolemPutPumpkinBack = false;
private void snowGolemSettings() {
+ snowGolemRidable = getBoolean("mobs.snow_golem.ridable", snowGolemRidable);
+ snowGolemRidableInWater = getBoolean("mobs.snow_golem.ridable-in-water", snowGolemRidableInWater);
+ snowGolemLeaveTrailWhenRidden = getBoolean("mobs.snow_golem.leave-trail-when-ridden", snowGolemLeaveTrailWhenRidden);
snowGolemDropsPumpkin = getBoolean("mobs.snow_golem.drop-pumpkin-when-sheared", snowGolemDropsPumpkin);
snowGolemPutPumpkinBack = getBoolean("mobs.snow_golem.pumpkin-can-be-added-back", snowGolemPutPumpkinBack);
}
+ public boolean squidRidable = false;
public boolean squidImmuneToEAR = true;
public double squidOffsetWaterCheck = 0.0D;
private void squidSettings() {
+ squidRidable = getBoolean("mobs.squid.ridable", squidRidable);
squidImmuneToEAR = getBoolean("mobs.squid.immune-to-EAR", squidImmuneToEAR);
squidOffsetWaterCheck = getDouble("mobs.squid.water-offset-check", squidOffsetWaterCheck);
}
+ public boolean spiderRidable = false;
+ public boolean spiderRidableInWater = false;
+ private void spiderSettings() {
+ spiderRidable = getBoolean("mobs.spider.ridable", spiderRidable);
+ spiderRidableInWater = getBoolean("mobs.spider.ridable-in-water", spiderRidableInWater);
+ }
+
+ public boolean strayRidable = false;
+ public boolean strayRidableInWater = false;
+ private void straySettings() {
+ strayRidable = getBoolean("mobs.stray.ridable", strayRidable);
+ strayRidableInWater = getBoolean("mobs.stray.ridable-in-water", strayRidableInWater);
+ }
+
+ public boolean striderRidable = false;
+ public boolean striderRidableInWater = false;
+ private void striderSettings() {
+ striderRidable = getBoolean("mobs.strider.ridable", striderRidable);
+ striderRidableInWater = getBoolean("mobs.strider.ridable-in-water", striderRidableInWater);
+ }
+
+ public boolean tropicalFishRidable = false;
+ private void tropicalFishSettings() {
+ tropicalFishRidable = getBoolean("mobs.tropical_fish.ridable", tropicalFishRidable);
+ }
+
+ public boolean turtleRidable = false;
+ public boolean turtleRidableInWater = false;
+ private void turtleSettings() {
+ turtleRidable = getBoolean("mobs.turtle.ridable", turtleRidable);
+ turtleRidableInWater = getBoolean("mobs.turtle.ridable-in-water", turtleRidableInWater);
+ }
+
+ public boolean vexRidable = false;
+ public boolean vexRidableInWater = false;
+ public double vexMaxY = 256D;
+ private void vexSettings() {
+ vexRidable = getBoolean("mobs.vex.ridable", vexRidable);
+ vexRidableInWater = getBoolean("mobs.vex.ridable-in-water", vexRidableInWater);
+ vexMaxY = getDouble("mobs.vex.ridable-max-y", vexMaxY);
+ }
+
+ public boolean villagerRidable = false;
+ public boolean villagerRidableInWater = false;
public int villagerBrainTicks = 1;
public boolean villagerUseBrainTicksOnlyWhenLagging = true;
public boolean villagerCanBeLeashed = false;
@@ -501,6 +862,8 @@ public class PurpurWorldConfig {
public int villagerSpawnIronGolemLimit = 0;
public boolean villagerCanBreed = true;
private void villagerSettings() {
+ villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable);
+ villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater);
villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks);
villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging);
villagerCanBeLeashed = getBoolean("mobs.villager.can-be-leashed", villagerCanBeLeashed);
@@ -511,46 +874,109 @@ public class PurpurWorldConfig {
villagerCanBreed = getBoolean("mobs.villager.can-breed", villagerCanBreed);
}
+ public boolean villagerTraderRidable = false;
+ public boolean villagerTraderRidableInWater = false;
public boolean villagerTraderCanBeLeashed = false;
public boolean villagerTraderFollowEmeraldBlock = false;
private void villagerTraderSettings() {
+ villagerTraderRidable = getBoolean("mobs.wandering_trader.ridable", villagerTraderRidable);
+ villagerTraderRidableInWater = getBoolean("mobs.wandering_trader.ridable-in-water", villagerTraderRidableInWater);
villagerTraderCanBeLeashed = getBoolean("mobs.wandering_trader.can-be-leashed", villagerTraderCanBeLeashed);
villagerTraderFollowEmeraldBlock = getBoolean("mobs.wandering_trader.follow-emerald-blocks", villagerTraderFollowEmeraldBlock);
}
+ public boolean vindicatorRidable = false;
+ public boolean vindicatorRidableInWater = false;
+ public double vindicatorJohnnySpawnChance = 0D;
+ private void vindicatorSettings() {
+ vindicatorRidable = getBoolean("mobs.vindicator.ridable", vindicatorRidable);
+ vindicatorRidableInWater = getBoolean("mobs.vindicator.ridable-in-water", vindicatorRidableInWater);
+ vindicatorJohnnySpawnChance = getDouble("mobs.vindicator.johnny.spawn-chance", vindicatorJohnnySpawnChance);
+ }
+
+ public boolean witchRidable = false;
+ public boolean witchRidableInWater = false;
+ private void witchSettings() {
+ witchRidable = getBoolean("mobs.witch.ridable", witchRidable);
+ witchRidableInWater = getBoolean("mobs.witch.ridable-in-water", witchRidableInWater);
+ }
+
+ public boolean witherRidable = false;
+ public boolean witherRidableInWater = false;
+ public double witherMaxY = 256D;
+ private void witherSettings() {
+ witherRidable = getBoolean("mobs.wither.ridable", witherRidable);
+ witherRidableInWater = getBoolean("mobs.wither.ridable-in-water", witherRidableInWater);
+ witherMaxY = getDouble("mobs.wither.ridable-max-y", witherMaxY);
+ }
+
+ public boolean witherSkeletonRidable = false;
+ public boolean witherSkeletonRidableInWater = false;
public boolean witherSkeletonTakesWitherDamage = false;
private void witherSkeletonSettings() {
+ witherSkeletonRidable = getBoolean("mobs.wither_skeleton.ridable", witherSkeletonRidable);
+ witherSkeletonRidableInWater = getBoolean("mobs.wither_skeleton.ridable-in-water", witherSkeletonRidableInWater);
witherSkeletonTakesWitherDamage = getBoolean("mobs.wither_skeleton.takes-wither-damage", witherSkeletonTakesWitherDamage);
}
+ public boolean wolfRidable = false;
+ public boolean wolfRidableInWater = false;
+ private void wolfSettings() {
+ wolfRidable = getBoolean("mobs.wolf.ridable", wolfRidable);
+ wolfRidableInWater = getBoolean("mobs.wolf.ridable-in-water", wolfRidableInWater);
+ }
+
+ public boolean zoglinRidable = false;
+ public boolean zoglinRidableInWater = false;
+ private void zoglinSettings() {
+ zoglinRidable = getBoolean("mobs.zoglin.ridable", zoglinRidable);
+ zoglinRidableInWater = getBoolean("mobs.zoglin.ridable-in-water", zoglinRidableInWater);
+ }
+
+ public boolean zombieRidable = false;
+ public boolean zombieRidableInWater = false;
public boolean zombieJockeyOnlyBaby = true;
public double zombieJockeyChance = 0.05D;
public boolean zombieJockeyTryExistingChickens = true;
private void zombieSettings() {
+ zombieRidable = getBoolean("mobs.zombie.ridable", zombieRidable);
+ zombieRidableInWater = getBoolean("mobs.zombie.ridable-in-water", zombieRidableInWater);
zombieJockeyOnlyBaby = getBoolean("mobs.zombie.jockey.only-babies", zombieJockeyOnlyBaby);
zombieJockeyChance = getDouble("mobs.zombie.jockey.chance", zombieJockeyChance);
zombieJockeyTryExistingChickens = getBoolean("mobs.zombie.jockey.try-existing-chickens", zombieJockeyTryExistingChickens);
}
+ public boolean zombieHorseCanSwim = false;
+ public boolean zombieHorseRidableInWater = false;
public double zombieHorseSpawnChance = 0.0D;
private void zombieHorseSettings() {
+ zombieHorseCanSwim = getBoolean("mobs.zombie_horse.can-swim", zombieHorseCanSwim);
+ zombieHorseRidableInWater = getBoolean("mobs.zombie_horse.ridable-in-water", zombieHorseRidableInWater);
zombieHorseSpawnChance = getDouble("mobs.zombie_horse.spawn-chance", zombieHorseSpawnChance);
}
+ public boolean zombifiedPiglinRidable = false;
+ public boolean zombifiedPiglinRidableInWater = false;
public boolean zombifiedPiglinJockeyOnlyBaby = true;
public double zombifiedPiglinJockeyChance = 0.05D;
public boolean zombifiedPiglinJockeyTryExistingChickens = true;
private void zombifiedPiglinSettings() {
+ zombifiedPiglinRidable = getBoolean("mobs.zombified_piglin.ridable", zombifiedPiglinRidable);
+ zombifiedPiglinRidableInWater = getBoolean("mobs.zombified_piglin.ridable-in-water", zombifiedPiglinRidableInWater);
zombifiedPiglinJockeyOnlyBaby = getBoolean("mobs.zombified_piglin.jockey.only-babies", zombifiedPiglinJockeyOnlyBaby);
zombifiedPiglinJockeyChance = getDouble("mobs.zombified_piglin.jockey.chance", zombifiedPiglinJockeyChance);
zombifiedPiglinJockeyTryExistingChickens = getBoolean("mobs.zombified_piglin.jockey.try-existing-chickens", zombifiedPiglinJockeyTryExistingChickens);
}
+ public boolean zombieVillagerRidable = false;
+ public boolean zombieVillagerRidableInWater = false;
public boolean zombieVillagerJockeyOnlyBaby = true;
public double zombieVillagerJockeyChance = 0.05D;
public boolean zombieVillagerJockeyTryExistingChickens = true;
public boolean zombieVillagerResetReputationsWhenCured = false;
private void zombieVillagerSettings() {
+ zombieVillagerRidable = getBoolean("mobs.zombie_villager.ridable", zombieVillagerRidable);
+ zombieVillagerRidableInWater = getBoolean("mobs.zombie_villager.ridable-in-water", zombieVillagerRidableInWater);
zombieVillagerJockeyOnlyBaby = getBoolean("mobs.zombie_villager.jockey.only-babies", zombieVillagerJockeyOnlyBaby);
zombieVillagerJockeyChance = getDouble("mobs.zombie_villager.jockey.chance", zombieVillagerJockeyChance);
zombieVillagerJockeyTryExistingChickens = getBoolean("mobs.zombie_villager.jockey.try-existing-chickens", zombieVillagerJockeyTryExistingChickens);
diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerLookWASD.java b/src/main/java/net/pl3x/purpur/controller/ControllerLookWASD.java
new file mode 100644
index 0000000000..0b16a7b634
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/controller/ControllerLookWASD.java
@@ -0,0 +1,76 @@
+package net.pl3x.purpur.controller;
+
+import net.minecraft.server.ControllerLook;
+import net.minecraft.server.EntityHuman;
+import net.minecraft.server.EntityInsentient;
+import net.minecraft.server.MathHelper;
+import net.minecraft.server.PacketPlayOutEntity;
+
+public class ControllerLookWASD extends ControllerLook {
+ protected final EntityInsentient entity;
+ private float yawOffset = 0;
+ private float pitchOffset = 0;
+
+ public ControllerLookWASD(EntityInsentient entity) {
+ super(entity);
+ this.entity = entity;
+ }
+
+ // tick
+ @Override
+ public void a() {
+ if (entity.hasRider()) {
+ tick(entity.getRider());
+ } else {
+ tick();
+ }
+ }
+
+ protected void tick() {
+ super.a(); // tick
+ }
+
+ protected void tick(EntityHuman rider) {
+ setYawPitch(rider.yaw, rider.pitch);
+ }
+
+ public void setYawPitch(float yaw, float pitch) {
+ entity.yaw = normalizeYaw(yaw + yawOffset);
+ entity.lastYaw = entity.yaw;
+ entity.setBodyYaw(entity.yaw);
+ entity.setRenderYawOffset(entity.yaw);
+ entity.setHeadRotation(entity.yaw);
+ entity.pitch = normalizePitch(pitch + pitchOffset);
+
+ entity.getTracker().broadcast(new PacketPlayOutEntity
+ .PacketPlayOutRelEntityMoveLook(entity.getId(),
+ (short) 0, (short) 0, (short) 0,
+ (byte) MathHelper.d(entity.yaw * 256.0F / 360.0F),
+ (byte) MathHelper.d(entity.pitch * 256.0F / 360.0F),
+ entity.onGround));
+ }
+
+ public void setOffsets(float yaw, float pitch) {
+ yawOffset = yaw;
+ pitchOffset = pitch;
+ }
+
+ public float normalizeYaw(float yaw) {
+ yaw %= 360.0f;
+ if (yaw >= 180.0f) {
+ yaw -= 360.0f;
+ } else if (yaw < -180.0f) {
+ yaw += 360.0f;
+ }
+ return yaw;
+ }
+
+ public float normalizePitch(float pitch) {
+ if (pitch > 90.0f) {
+ pitch = 90.0f;
+ } else if (pitch < -90.0f) {
+ pitch = -90.0f;
+ }
+ return pitch;
+ }
+}
diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASD.java b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASD.java
new file mode 100644
index 0000000000..426688b3a6
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASD.java
@@ -0,0 +1,92 @@
+package net.pl3x.purpur.controller;
+
+import net.minecraft.server.ControllerMove;
+import net.minecraft.server.Entity;
+import net.minecraft.server.EntityHuman;
+import net.minecraft.server.EntityInsentient;
+import net.minecraft.server.GenericAttributes;
+import net.pl3x.purpur.event.entity.RidableSpacebarEvent;
+
+public class ControllerMoveWASD extends ControllerMove {
+ protected final EntityInsentient entity;
+ private final double speedModifier;
+
+ public ControllerMoveWASD(EntityInsentient entity) {
+ this(entity, 1.0D);
+ }
+
+ public ControllerMoveWASD(EntityInsentient entity, double speedModifier) {
+ super(entity);
+ this.entity = entity;
+ this.speedModifier = speedModifier;
+ }
+
+ // isUpdating
+ @Override
+ public boolean b() {
+ return entity.hasRider() ? getForward() != 0 || getStrafe() != 0 : super.b();
+ }
+
+ // tick
+ @Override
+ public void a() {
+ if (entity.hasRider()) {
+ tick(entity.getRider());
+ } else {
+ tick();
+ }
+ }
+
+ public void tick() {
+ super.a(); // tick
+ }
+
+ public void tick(EntityHuman rider) {
+ float forward = rider.getForward() * 0.5F;
+ float strafe = rider.getStrafe() * 0.25F;
+
+ if (forward <= 0.0F) {
+ forward *= 0.5F;
+ }
+
+ float yawOffset = 0;
+ if (strafe != 0) {
+ if (forward == 0) {
+ yawOffset += strafe > 0 ? -90 : 90;
+ forward = Math.abs(strafe * 2);
+ } else {
+ yawOffset += strafe > 0 ? -30 : 30;
+ strafe /= 2;
+ if (forward < 0) {
+ yawOffset += strafe > 0 ? -110 : 110;
+ forward *= -1;
+ }
+ }
+ } else if (forward < 0) {
+ yawOffset -= 180;
+ forward *= -1;
+ }
+
+ ((ControllerLookWASD) entity.getControllerLook()).setOffsets(yawOffset, 0);
+
+ if (rider.jumping && spacebarEvent(entity) && !entity.onSpacebar() && entity.onGround) {
+ entity.jump();
+ }
+
+ setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * speedModifier);
+
+ entity.setSpeed((float) getSpeed());
+ entity.setForward(forward);
+
+ setForward(entity.getForward());
+ setStrafe(entity.getStrafe());
+ }
+
+ public static boolean spacebarEvent(Entity entity) {
+ if (RidableSpacebarEvent.getHandlerList().getRegisteredListeners().length > 0) {
+ return new RidableSpacebarEvent(entity.getBukkitEntity()).callEvent();
+ } else {
+ return true;
+ }
+ }
+}
diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlying.java b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlying.java
new file mode 100644
index 0000000000..33c51460ab
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlying.java
@@ -0,0 +1,61 @@
+package net.pl3x.purpur.controller;
+
+import net.minecraft.server.EntityHuman;
+import net.minecraft.server.EntityInsentient;
+import net.minecraft.server.GenericAttributes;
+
+public class ControllerMoveWASDFlying extends ControllerMoveWASD {
+ protected final float groundSpeedModifier;
+ protected int tooHighCooldown = 0;
+ protected boolean setGravityFlag = true;
+
+ public ControllerMoveWASDFlying(EntityInsentient entity) {
+ this(entity, 1.0F);
+ }
+
+ public ControllerMoveWASDFlying(EntityInsentient entity, float groundSpeedModifier) {
+ this(entity, groundSpeedModifier, true);
+ }
+
+ public ControllerMoveWASDFlying(EntityInsentient entity, float groundSpeedModifier, boolean setGravityFlag) {
+ super(entity);
+ this.groundSpeedModifier = groundSpeedModifier;
+ this.setGravityFlag = setGravityFlag;
+ }
+
+ @Override
+ public void tick(EntityHuman rider) {
+ float forward = Math.max(0.0F, rider.getForward());
+ float vertical = forward == 0.0F ? 0.0F : -(rider.pitch / 45.0F);
+ float strafe = rider.getStrafe();
+
+ if (rider.jumping && spacebarEvent(entity)) {
+ entity.onSpacebar();
+ }
+
+ if (entity.locY() >= entity.getMaxY() || --tooHighCooldown > 0) {
+ tooHighCooldown = 60;
+ entity.setMot(entity.getMot().add(0.0D, -0.05D, 0.0D));
+ vertical = 0.0F;
+ }
+
+ setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue());
+ float speed = (float) getSpeed();
+
+ if (entity.onGround) {
+ speed *= groundSpeedModifier; // TODO = fix this!
+ }
+
+ if (setGravityFlag) {
+ entity.setNoGravity(forward > 0);
+ }
+
+ entity.setSpeed(speed);
+ entity.setVertical(vertical);
+ entity.setStrafe(strafe);
+ entity.setForward(forward);
+
+ setForward(entity.getForward());
+ setStrafe(entity.getStrafe());
+ }
+}
diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlyingWithSpacebar.java b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlyingWithSpacebar.java
new file mode 100644
index 0000000000..f753759361
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlyingWithSpacebar.java
@@ -0,0 +1,61 @@
+package net.pl3x.purpur.controller;
+
+import net.minecraft.server.EntityHuman;
+import net.minecraft.server.EntityInsentient;
+import net.minecraft.server.GenericAttributes;
+import net.minecraft.server.Vec3D;
+
+public class ControllerMoveWASDFlyingWithSpacebar extends ControllerMoveWASDFlying {
+ public ControllerMoveWASDFlyingWithSpacebar(EntityInsentient entity) {
+ super(entity);
+ }
+
+ public ControllerMoveWASDFlyingWithSpacebar(EntityInsentient entity, float groundSpeedModifier) {
+ super(entity, groundSpeedModifier);
+ }
+
+ @Override
+ public void tick(EntityHuman rider) {
+ float forward = rider.getForward();
+ float strafe = rider.getStrafe() * 0.5F;
+ float vertical = 0;
+
+ if (forward < 0.0F) {
+ forward *= 0.5F;
+ strafe *= 0.5F;
+ }
+
+ float speed = (float) entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue();
+
+ if (entity.onGround) {
+ speed *= groundSpeedModifier;
+ }
+
+ if (rider.jumping && spacebarEvent(entity) && !entity.onSpacebar()) {
+ entity.setNoGravity(true);
+ vertical = 1.0F;
+ } else {
+ entity.setNoGravity(false);
+ }
+
+ if (entity.locY() >= entity.getMaxY() || --tooHighCooldown > 0) {
+ tooHighCooldown = 60;
+ entity.setMot(entity.getMot().add(0.0D, -0.2D, 0.0D));
+ vertical = 0.0F;
+ }
+
+ setSpeed(speed);
+ entity.setSpeed((float) getSpeed());
+ entity.setVertical(vertical);
+ entity.setStrafe(strafe);
+ entity.setForward(forward);
+
+ setForward(entity.getForward());
+ setStrafe(entity.getStrafe());
+
+ Vec3D mot = entity.getMot();
+ if (mot.y > 0.2D) {
+ entity.setMot(mot.x, 0.2D, mot.z);
+ }
+ }
+}
diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java
new file mode 100644
index 0000000000..1b08a0905b
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java
@@ -0,0 +1,50 @@
+package net.pl3x.purpur.controller;
+
+import net.minecraft.server.EntityHuman;
+import net.minecraft.server.EntityInsentient;
+import net.minecraft.server.GenericAttributes;
+
+public class ControllerMoveWASDWater extends ControllerMoveWASD {
+ private final double speedModifier;
+
+ public ControllerMoveWASDWater(EntityInsentient entity) {
+ this(entity, 1.0D);
+ }
+
+ public ControllerMoveWASDWater(EntityInsentient entity, double speedModifier) {
+ super(entity);
+ this.speedModifier = speedModifier;
+ }
+
+ @Override
+ public void tick(EntityHuman rider) {
+ float forward = rider.getForward();
+ float strafe = rider.getStrafe() * 0.5F; // strafe slower by default
+ float vertical = -(rider.pitch / 90);
+
+ if (forward == 0.0F) {
+ // strafe slower if not moving forward
+ strafe *= 0.5F;
+ // do not move vertically if not moving forward
+ vertical = 0.0F;
+ } else if (forward < 0.0F) {
+ // water animals can't swim backwards
+ forward = 0.0F;
+ vertical = 0.0F;
+ }
+
+ if (rider.jumping && spacebarEvent(entity)) {
+ entity.onSpacebar();
+ }
+
+ setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * speedModifier);
+ entity.setSpeed((float) getSpeed() * 0.1F);
+
+ entity.setForward(forward * (float) speedModifier);
+ entity.setStrafe(strafe * (float) speedModifier);
+ entity.setVertical(vertical * (float) speedModifier);
+
+ setForward(entity.getForward());
+ setStrafe(entity.getStrafe());
+ }
+}
diff --git a/src/main/java/net/pl3x/purpur/entity/DolphinSpit.java b/src/main/java/net/pl3x/purpur/entity/DolphinSpit.java
new file mode 100644
index 0000000000..3b777c54f9
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/entity/DolphinSpit.java
@@ -0,0 +1,115 @@
+package net.pl3x.purpur.entity;
+
+import net.minecraft.server.BlockBase;
+import net.minecraft.server.DamageSource;
+import net.minecraft.server.Entity;
+import net.minecraft.server.EntityDolphin;
+import net.minecraft.server.EntityLiving;
+import net.minecraft.server.EntityLlamaSpit;
+import net.minecraft.server.EntityTypes;
+import net.minecraft.server.IBlockData;
+import net.minecraft.server.MovingObjectPosition;
+import net.minecraft.server.MovingObjectPositionBlock;
+import net.minecraft.server.MovingObjectPositionEntity;
+import net.minecraft.server.Particles;
+import net.minecraft.server.ProjectileHelper;
+import net.minecraft.server.Vec3D;
+import net.minecraft.server.World;
+import net.minecraft.server.WorldServer;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+
+public class DolphinSpit extends EntityLlamaSpit {
+ public EntityLiving dolphin;
+ public int ticksLived;
+
+ public DolphinSpit(EntityTypes<? extends EntityLlamaSpit> entitytypes, World world) {
+ super(entitytypes, world);
+ }
+
+ public DolphinSpit(World world, EntityDolphin dolphin) {
+ this(EntityTypes.LLAMA_SPIT, world);
+ setShooter(dolphin);
+ this.dolphin = dolphin;
+ }
+
+ @Override
+ public boolean canSaveToDisk() {
+ return false;
+ }
+
+ public void tick() {
+ if (dead || !valid) {
+ return;
+ }
+
+ if (!leftOwner()) {
+ setLeftOwner(checkIfLeftOwner());
+ }
+
+ setFlag(6, isGlowing());
+ entityBaseTick();
+
+ Vec3D mot = getMot();
+
+ MovingObjectPosition hitResult = ProjectileHelper.getHitResult(this, this::hitPredicate);
+ if (hitResult != null) {
+ onHit(hitResult);
+ }
+
+ double x = this.locX() + mot.x;
+ double y = this.locY() + mot.y;
+ double z = this.locZ() + mot.z;
+ setMot(mot.scale(0.99D));
+
+ Vec3D motDouble = mot.scale(2.0);
+ for (int i = 0; i < 5; i++) {
+ ((WorldServer) world).sendParticles(null, Particles.BUBBLE,
+ locX() + random.nextFloat() / 2 - 0.25F,
+ locY() + random.nextFloat() / 2 - 0.25F,
+ locZ() + random.nextFloat() / 2 - 0.25F,
+ 0, motDouble.getX(), motDouble.getY(), motDouble.getZ(), 0.1, true);
+ }
+
+ if (++ticksLived > 20) {
+ die();
+ } else {
+ setMot(mot.scale(0.99D));
+ if (!isNoGravity()) {
+ setMot(getMot().add(0.0D, -0.06D, 0.0D));
+ }
+ setPosition(x, y, z);
+ }
+ }
+
+ @Override
+ public void shoot(double x, double y, double z, float speed, float inaccuracy) {
+ setMot(new Vec3D(x, y, z).normalize().add(
+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy,
+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy,
+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy)
+ .scale(speed));
+ }
+
+ public void onHit(MovingObjectPosition rayTrace) {
+ CraftEventFactory.callProjectileHitEvent(this, rayTrace);
+ MovingObjectPosition.EnumMovingObjectType type = rayTrace.getType();
+ if (type == MovingObjectPosition.EnumMovingObjectType.ENTITY) {
+ onHit((MovingObjectPositionEntity) rayTrace);
+ } else if (type == MovingObjectPosition.EnumMovingObjectType.BLOCK) {
+ onHit((MovingObjectPositionBlock) rayTrace);
+ }
+ }
+
+ protected void onHit(MovingObjectPositionEntity rayTrace) {
+ Entity shooter = getShooter();
+ if (shooter instanceof EntityLiving) {
+ rayTrace.getEntity().damageEntity(DamageSource.indirectMobAttack(this, (EntityLiving) shooter).setProjectile(), world.purpurConfig.dolphinSpitDamage);
+ }
+ }
+
+ protected void onHit(MovingObjectPositionBlock rayTrace) {
+ IBlockData iblockdata = world.getType(rayTrace.getBlockPosition());
+ iblockdata.a(world, iblockdata, rayTrace, this);
+ die();
+ }
+}
diff --git a/src/main/java/net/pl3x/purpur/entity/PhantomFlames.java b/src/main/java/net/pl3x/purpur/entity/PhantomFlames.java
new file mode 100644
index 0000000000..f5da00b100
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/entity/PhantomFlames.java
@@ -0,0 +1,120 @@
+package net.pl3x.purpur.entity;
+
+import net.minecraft.server.BlockBase;
+import net.minecraft.server.DamageSource;
+import net.minecraft.server.Entity;
+import net.minecraft.server.EntityLiving;
+import net.minecraft.server.EntityLlamaSpit;
+import net.minecraft.server.EntityPhantom;
+import net.minecraft.server.EntityTypes;
+import net.minecraft.server.IBlockData;
+import net.minecraft.server.MovingObjectPosition;
+import net.minecraft.server.MovingObjectPositionBlock;
+import net.minecraft.server.MovingObjectPositionEntity;
+import net.minecraft.server.Particles;
+import net.minecraft.server.ProjectileHelper;
+import net.minecraft.server.Vec3D;
+import net.minecraft.server.World;
+import net.minecraft.server.WorldServer;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+
+public class PhantomFlames extends EntityLlamaSpit {
+ public EntityPhantom phantom;
+ public int ticksLived;
+
+ public PhantomFlames(EntityTypes<? extends EntityLlamaSpit> entitytypes, World world) {
+ super(entitytypes, world);
+ }
+
+ public PhantomFlames(World world, EntityPhantom phantom) {
+ this(EntityTypes.LLAMA_SPIT, world);
+ setShooter(phantom);
+ this.phantom = phantom;
+ }
+
+ @Override
+ public boolean canSaveToDisk() {
+ return false;
+ }
+
+ @Override
+ public void tick() {
+ if (dead || !valid) {
+ return;
+ }
+
+ if (!leftOwner()) {
+ setLeftOwner(checkIfLeftOwner());
+ }
+
+ setFlag(6, isGlowing());
+ entityBaseTick();
+
+ Vec3D mot = getMot();
+
+ MovingObjectPosition hitResult = ProjectileHelper.getHitResult(this, this::hitPredicate);
+ if (hitResult != null) {
+ onHit(hitResult);
+ }
+
+ double x = this.locX() + mot.x;
+ double y = this.locY() + mot.y;
+ double z = this.locZ() + mot.z;
+ setMot(mot.scale(0.99D));
+
+ Vec3D motDouble = mot.scale(2.0);
+ for (int i = 0; i < 5; i++) {
+ ((WorldServer) world).sendParticles(null, Particles.FLAME,
+ locX() + random.nextFloat() / 2 - 0.25F,
+ locY() + random.nextFloat() / 2 - 0.25F,
+ locZ() + random.nextFloat() / 2 - 0.25F,
+ 0, motDouble.getX(), motDouble.getY(), motDouble.getZ(), 0.1, true);
+ }
+
+ if (world.a(getBoundingBox()).noneMatch(BlockBase.BlockData::isAir)) {
+ die();
+ } else if (isInWaterOrBubbleColumn()) {
+ die();
+ } else if (++ticksLived > 20) {
+ die();
+ } else {
+ setMot(mot.scale(0.99D));
+ if (!isNoGravity()) {
+ setMot(getMot().add(0.0D, -0.06D, 0.0D));
+ }
+ setPosition(x, y, z);
+ }
+ }
+
+ @Override
+ public void shoot(double x, double y, double z, float speed, float inaccuracy) {
+ setMot(new Vec3D(x, y, z).normalize().add(
+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy,
+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy,
+ random.nextGaussian() * (double) 0.0075F * (double) inaccuracy)
+ .scale(speed));
+ }
+
+ public void onHit(MovingObjectPosition rayTrace) {
+ CraftEventFactory.callProjectileHitEvent(this, rayTrace);
+ MovingObjectPosition.EnumMovingObjectType type = rayTrace.getType();
+ if (type == MovingObjectPosition.EnumMovingObjectType.ENTITY) {
+ onHit((MovingObjectPositionEntity) rayTrace);
+ } else if (type == MovingObjectPosition.EnumMovingObjectType.BLOCK) {
+ onHit((MovingObjectPositionBlock) rayTrace);
+ }
+ }
+
+ protected void onHit(MovingObjectPositionEntity rayTrace) {
+ Entity shooter = getShooter();
+ if (shooter instanceof EntityLiving) {
+ rayTrace.getEntity().damageEntity(DamageSource.indirectMobAttack(this, (EntityLiving) shooter).setProjectile(), world.purpurConfig.phantomFlameDamage);
+ }
+ }
+
+ protected void onHit(MovingObjectPositionBlock rayTrace) {
+ IBlockData iblockdata = world.getType(rayTrace.getBlockPosition());
+ iblockdata.a(world, iblockdata, rayTrace, this);
+ die();
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 1fe253bc72..bf387664c2 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1159,4 +1159,26 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return getHandle().isTicking();
}
// Paper end
+
+ // Purpur start
+ @Override
+ public org.bukkit.entity.Player getRider() {
+ return hasRider() ? (org.bukkit.entity.Player) getHandle().getRider().getBukkitEntity() : null;
+ }
+
+ @Override
+ public boolean hasRider() {
+ return getHandle().hasRider();
+ }
+
+ @Override
+ public boolean isRidable() {
+ return getHandle().isRidable();
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return getHandle().isRidableInWater();
+ }
+ // Purpur end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
index 90d8631ddd..8bb9449a69 100644
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
@@ -502,6 +502,18 @@ public class CraftEventFactory {
}
craftServer.getPluginManager().callEvent(event);
+ // Purpur start
+ switch (action) {
+ case LEFT_CLICK_BLOCK:
+ case LEFT_CLICK_AIR:
+ who.processClick(EnumHand.MAIN_HAND);
+ break;
+ case RIGHT_CLICK_BLOCK:
+ case RIGHT_CLICK_AIR:
+ who.processClick(EnumHand.OFF_HAND);
+ }
+ // Purpur end
+
return event;
}
@@ -902,6 +914,7 @@ public class CraftEventFactory {
damageCause = DamageCause.ENTITY_EXPLOSION;
}
event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), entity.getBukkitEntity(), damageCause, modifiers, modifierFunctions);
+ damager.processClick(EnumHand.MAIN_HAND); // Purpur
}
event.setCancelled(cancelled);
@@ -986,6 +999,7 @@ public class CraftEventFactory {
if (!event.isCancelled()) {
event.getEntity().setLastDamageCause(event);
}
+ damager.getHandle().processClick(EnumHand.MAIN_HAND); // Purpur
return event;
}
@@ -1035,6 +1049,7 @@ public class CraftEventFactory {
EntityDamageEvent event;
if (damager != null) {
event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, modifiers, modifierFunctions);
+ damager.processClick(EnumHand.MAIN_HAND); // Purpur
} else {
event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, modifiers, modifierFunctions);
}