Files
Purpur/patches/server/0007-Ridables.patch
ChrystiGalbreath 6c4aab0053 Updated Upstream (Paper)
Upstream has released updates that appears to apply and compile correctly

Paper Changes:
0f06d380 Restrict vanilla teleport command to within worldborder
24d93aaf Fix Optional null issue - Fixes #3155
eb71c5fa Fix incorect timing of mspt
1ca80434 Optimise entity hard collision checking
b67a4237 Don't run entity collision code if not needed
bd9aa547 Optimise ArraySetSorted#removeIf
78871d07 Make JavaClassLoader thread-safe (Fixes #3137) (#3144)
2020-04-16 20:45:31 -05:00

6573 lines
268 KiB
Diff

From 3abc1359f398d88bc8f87a26e50e9c3083647a08 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Thu, 6 Feb 2020 19:53:59 -0600
Subject: [PATCH] Ridables
---
.../net/minecraft/server/AxisAlignedBB.java | 2 +
.../server/ControllerLookDolphin.java | 4 +-
.../net/minecraft/server/ControllerMove.java | 6 +-
.../net/minecraft/server/DamageSource.java | 3 +
.../java/net/minecraft/server/Entity.java | 69 +-
.../net/minecraft/server/EntityAgeable.java | 2 +-
.../java/net/minecraft/server/EntityBat.java | 58 ++
.../java/net/minecraft/server/EntityBee.java | 118 +++-
.../net/minecraft/server/EntityBlaze.java | 51 ++
.../java/net/minecraft/server/EntityCat.java | 34 +-
.../minecraft/server/EntityCaveSpider.java | 17 +
.../net/minecraft/server/EntityChicken.java | 19 +
.../java/net/minecraft/server/EntityCod.java | 17 +
.../minecraft/server/EntityComplexPart.java | 7 +
.../java/net/minecraft/server/EntityCow.java | 18 +
.../net/minecraft/server/EntityCreeper.java | 76 +++
.../net/minecraft/server/EntityDolphin.java | 78 ++-
.../net/minecraft/server/EntityDrowned.java | 24 +-
.../minecraft/server/EntityEnderDragon.java | 87 ++-
.../net/minecraft/server/EntityEnderman.java | 33 +-
.../net/minecraft/server/EntityEndermite.java | 19 +
.../net/minecraft/server/EntityEvoker.java | 22 +
.../java/net/minecraft/server/EntityFish.java | 21 +-
.../java/net/minecraft/server/EntityFox.java | 57 +-
.../net/minecraft/server/EntityGhast.java | 46 +-
.../minecraft/server/EntityGiantZombie.java | 25 +
.../net/minecraft/server/EntityGuardian.java | 47 +-
.../minecraft/server/EntityGuardianElder.java | 17 +
.../net/minecraft/server/EntityHorse.java | 7 +
.../minecraft/server/EntityHorseAbstract.java | 29 +-
.../minecraft/server/EntityHorseDonkey.java | 7 +
.../net/minecraft/server/EntityHorseMule.java | 7 +
.../minecraft/server/EntityHorseSkeleton.java | 16 +-
.../minecraft/server/EntityHorseZombie.java | 14 +-
.../net/minecraft/server/EntityHuman.java | 14 +-
.../server/EntityIllagerIllusioner.java | 19 +
.../minecraft/server/EntityInsentient.java | 48 +-
.../net/minecraft/server/EntityIronGolem.java | 23 +-
.../net/minecraft/server/EntityLiving.java | 21 +-
.../net/minecraft/server/EntityLlama.java | 64 +-
.../minecraft/server/EntityLlamaTrader.java | 23 +
.../net/minecraft/server/EntityMagmaCube.java | 17 +
.../minecraft/server/EntityMushroomCow.java | 17 +
.../net/minecraft/server/EntityOcelot.java | 19 +
.../net/minecraft/server/EntityPanda.java | 47 +-
.../net/minecraft/server/EntityParrot.java | 77 ++-
.../net/minecraft/server/EntityPhantom.java | 97 ++-
.../java/net/minecraft/server/EntityPig.java | 48 +-
.../net/minecraft/server/EntityPigZombie.java | 17 +
.../net/minecraft/server/EntityPillager.java | 19 +
.../net/minecraft/server/EntityPlayer.java | 2 +-
.../net/minecraft/server/EntityPolarBear.java | 42 ++
.../minecraft/server/EntityPufferFish.java | 19 +-
.../net/minecraft/server/EntityRabbit.java | 79 ++-
.../net/minecraft/server/EntityRavager.java | 19 +
.../net/minecraft/server/EntitySalmon.java | 17 +
.../net/minecraft/server/EntitySheep.java | 18 +
.../net/minecraft/server/EntityShulker.java | 21 +-
.../minecraft/server/EntitySilverfish.java | 20 +
.../net/minecraft/server/EntitySkeleton.java | 17 +
.../server/EntitySkeletonAbstract.java | 2 +
.../minecraft/server/EntitySkeletonStray.java | 17 +
.../server/EntitySkeletonWither.java | 17 +
.../net/minecraft/server/EntitySlime.java | 44 +-
.../net/minecraft/server/EntitySnowman.java | 24 +-
.../net/minecraft/server/EntitySpider.java | 19 +
.../net/minecraft/server/EntitySquid.java | 68 +-
.../server/EntityTameableAnimal.java | 1 +
.../minecraft/server/EntityTropicalFish.java | 17 +
.../net/minecraft/server/EntityTurtle.java | 115 +++-
.../net/minecraft/server/EntityTypes.java | 6 +
.../java/net/minecraft/server/EntityVex.java | 65 +-
.../net/minecraft/server/EntityVillager.java | 22 +
.../server/EntityVillagerTrader.java | 18 +
.../minecraft/server/EntityVindicator.java | 19 +
.../net/minecraft/server/EntityWitch.java | 21 +-
.../net/minecraft/server/EntityWither.java | 69 +-
.../java/net/minecraft/server/EntityWolf.java | 121 ++--
.../net/minecraft/server/EntityZombie.java | 19 +
.../minecraft/server/EntityZombieHusk.java | 17 +
.../server/EntityZombieVillager.java | 17 +
.../java/net/minecraft/server/FoodInfo.java | 1 +
.../java/net/minecraft/server/ItemDye.java | 1 +
.../java/net/minecraft/server/MathHelper.java | 2 +
.../net/minecraft/server/PathfinderGoal.java | 1 +
.../minecraft/server/PathfinderGoalSwell.java | 5 +-
.../minecraft/server/ProjectileHelper.java | 1 +
src/main/java/net/minecraft/server/Vec3D.java | 3 +
src/main/java/net/minecraft/server/World.java | 7 +
.../net/pl3x/purpur/PurpurWorldConfig.java | 599 ++++++++++++++++++
.../purpur/controller/ControllerLookWASD.java | 75 +++
.../purpur/controller/ControllerMoveWASD.java | 86 +++
.../controller/ControllerMoveWASDFlying.java | 53 ++
.../ControllerMoveWASDFlyingWithSpacebar.java | 61 ++
.../controller/ControllerMoveWASDWater.java | 43 ++
.../net/pl3x/purpur/entity/DolphinSpit.java | 119 ++++
.../net/pl3x/purpur/entity/PhantomFlames.java | 126 ++++
.../pathfinder/PathfinderGoalHasRider.java | 21 +
.../craftbukkit/entity/CraftEntity.java | 27 +
src/main/resources/purpur.lang | 4 +-
100 files changed, 3623 insertions(+), 211 deletions(-)
create mode 100644 src/main/java/net/pl3x/purpur/controller/ControllerLookWASD.java
create mode 100644 src/main/java/net/pl3x/purpur/controller/ControllerMoveWASD.java
create mode 100644 src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlying.java
create mode 100644 src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlyingWithSpacebar.java
create mode 100644 src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java
create mode 100644 src/main/java/net/pl3x/purpur/entity/DolphinSpit.java
create mode 100644 src/main/java/net/pl3x/purpur/entity/PhantomFlames.java
create mode 100644 src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHasRider.java
diff --git a/src/main/java/net/minecraft/server/AxisAlignedBB.java b/src/main/java/net/minecraft/server/AxisAlignedBB.java
index 3fdb52007..7e67292c2 100644
--- a/src/main/java/net/minecraft/server/AxisAlignedBB.java
+++ b/src/main/java/net/minecraft/server/AxisAlignedBB.java
@@ -104,6 +104,7 @@ public class AxisAlignedBB {
return new AxisAlignedBB(d3, d4, d5, d6, d7, d8);
}
+ public AxisAlignedBB expandTowards(Vec3D vec3d) { return a(vec3d); } // Purpur - OBFHELPER
public AxisAlignedBB a(Vec3D vec3d) {
return this.b(vec3d.x, vec3d.y, vec3d.z);
}
@@ -155,6 +156,7 @@ public class AxisAlignedBB {
return new AxisAlignedBB(d3, d4, d5, d6, d7, d8);
}
+ public AxisAlignedBB expand(double size) { return g(size); } // Purpur - OBFHELPER
public AxisAlignedBB g(double d0) {
return this.grow(d0, d0, d0);
}
diff --git a/src/main/java/net/minecraft/server/ControllerLookDolphin.java b/src/main/java/net/minecraft/server/ControllerLookDolphin.java
index 1d9ba04da..2bade947e 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.aK = this.a(this.a.aK, 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 a5c4cbb67..efe6afde9 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 816d301f1..f7344d3ae 100644
--- a/src/main/java/net/minecraft/server/DamageSource.java
+++ b/src/main/java/net/minecraft/server/DamageSource.java
@@ -57,6 +57,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);
}
@@ -101,10 +102,12 @@ public class DamageSource {
return new DamageSourceNetherBed();
}
+ public boolean isProjectile() { return b(); } // Purpur - OBFHELPER
public boolean b() {
return this.C;
}
+ public DamageSource setProjectile() { return c(); } // Purpur - OBFHELPER
public DamageSource c() {
this.C = true;
return this;
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 96a47dd1c..a3bee7bf2 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -79,7 +79,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
Throwable addedToWorldStack; // Paper - entity debug
public CraftEntity getBukkitEntity() {
if (bukkitEntity == null) {
@@ -103,7 +103,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;
@@ -136,7 +136,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
public double E;
public double F;
public double G;
- public float H;
+ public float H; public float getStepHeight() { return H; } public void setStepHeight(float stepHeight) { this.H = stepHeight; } // Purpur - OBFHELPER
public boolean noclip;
public float J;
protected final Random random;
@@ -180,7 +180,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
private boolean aF;
private final double[] aG;
private long aH;
- private EntitySize size;
+ protected EntitySize size; // Purpur - private -> protected
private float headHeight;
// CraftBukkit start
public boolean persist = true;
@@ -857,6 +857,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
return vec3d1;
}
+ public static double getHorizontalDistanceSqr(Vec3D vec3d) { return b(vec3d); } // Purpur - OBFHELPER
public static double b(Vec3D vec3d) {
return vec3d.x * vec3d.x + vec3d.z * vec3d.z;
}
@@ -1183,6 +1184,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
return flag;
}
+ public boolean isInBubbleColumn() { return l(); } // Purpur - OBFHELPER
private boolean l() {
return this.world.getType(new BlockPosition(this)).getBlock() == Blocks.BUBBLE_COLUMN;
}
@@ -1196,8 +1198,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
return this.isInWater() || this.isInRain() || this.l();
}
+ public boolean isInWaterOrBubbleColumn() { return az(); } // Purpur - OBFHELPER
public boolean az() {
- return this.isInWater() || this.l();
+ return this.isInWater() || this.isInBubbleColumn(); // Purpur
}
public boolean aA() {
@@ -1328,6 +1331,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
return this.inLava;
}
+ 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);
@@ -2159,7 +2163,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
} else {
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
}
@@ -2194,6 +2204,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;
}
@@ -2362,6 +2378,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
this.setFlag(4, flag);
}
+ public boolean isGlowing() { return bt(); } // Purpur - OBFHELPER
public boolean bt() {
return this.glowing || this.world.isClientSide && this.getFlag(6);
}
@@ -2580,6 +2597,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
public void setHeadRotation(float f) {}
+ public void setBodyYaw(float yaw) { l(yaw); } // Purpur - OBFHELPER
public void l(float f) {}
public boolean bA() {
@@ -3426,4 +3444,43 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
void accept(Entity entity, double d0, double d1, double d2);
}
+
+ // 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 boolean requireShiftToMount() {
+ return true;
+ }
+
+ 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;
+ }
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/server/EntityAgeable.java b/src/main/java/net/minecraft/server/EntityAgeable.java
index 3d27f0964..822316a65 100644
--- a/src/main/java/net/minecraft/server/EntityAgeable.java
+++ b/src/main/java/net/minecraft/server/EntityAgeable.java
@@ -86,7 +86,7 @@ public abstract class EntityAgeable extends EntityCreature {
return true;
} else {
- return false;
+ return super.a(entityhuman, enumhand); // Purpur
}
}
diff --git a/src/main/java/net/minecraft/server/EntityBat.java b/src/main/java/net/minecraft/server/EntityBat.java
index 34239160b..592408bac 100644
--- a/src/main/java/net/minecraft/server/EntityBat.java
+++ b/src/main/java/net/minecraft/server/EntityBat.java
@@ -14,9 +14,44 @@ 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 boolean requireShiftToMount() {
+ return world.purpurConfig.batRequireShiftToMount;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.batMaxY;
+ }
+
+ @Override
+ public void e(Vec3D vec3d) {
+ super.e(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 initDatawatcher() {
super.initDatawatcher();
@@ -64,6 +99,12 @@ public class EntityBat extends EntityAmbient {
protected void initAttributes() {
super.initAttributes();
this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(6.0D);
+ // Purpur start
+ if (world != null && world.purpurConfig.batRidable) {
+ this.getAttributeMap().b(GenericAttributes.FLYING_SPEED);
+ this.getAttributeInstance(GenericAttributes.FLYING_SPEED).setValue(0.6000000238418579D);
+ }
+ // Purpur end
}
public boolean isAsleep() {
@@ -95,6 +136,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 = new BlockPosition(this);
BlockPosition blockposition1 = blockposition.up();
@@ -229,4 +277,14 @@ public class EntityBat extends EntityAmbient {
protected float b(EntityPose entitypose, EntitySize entitysize) {
return entitysize.height / 2.0F;
}
+
+ // Purpur start
+ @Override
+ public void onMount(EntityHuman entityhuman) {
+ if (isAsleep()) {
+ setAsleep(false);
+ world.playEffect(null, 1025, new BlockPosition(this).up(), 0);
+ }
+ }
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/server/EntityBee.java b/src/main/java/net/minecraft/server/EntityBee.java
index dd1d246ae..f0f83baac 100644
--- a/src/main/java/net/minecraft/server/EntityBee.java
+++ b/src/main/java/net/minecraft/server/EntityBee.java
@@ -36,9 +36,7 @@ public class EntityBee extends EntityAnimal implements EntityBird {
public EntityBee(EntityTypes<? extends EntityBee> entitytypes, World world) {
super(entitytypes, world);
- // Paper start - apply gravity to bees when they get stuck in the void, fixes MC-167279
- this.moveController = new ControllerMoveFlying(this, 20, true) {
- @Override
+ this.moveController = new ControllerMoveWASDBee(this, 20, true) { // Purpur
public void tick() {
if (getEntity().locY() <= 0) {
getEntity().setNoGravity(false);
@@ -46,13 +44,55 @@ public class EntityBee extends EntityAnimal implements EntityBird {
super.tick();
}
};
- // Paper end
- this.lookController = new EntityBee.j(this);
+ // Purpur start
+ this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this) {
+ @Override
+ protected void tick() {
+ if (!((EntityBee) entity).isAngry()) {
+ super.tick();
+ }
+ }
+ };
+ // Purpur end
this.a(PathType.WATER, -1.0F);
this.a(PathType.COCOA, -1.0F);
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 boolean requireShiftToMount() {
+ return world.purpurConfig.beeRequireShiftToMount;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.beeMaxY;
+ }
+
+ @Override
+ public void e(Vec3D vec3d) {
+ super.e(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));
+ }
+ }
+ // Purpur end
+
@Override
protected void initDatawatcher() {
super.initDatawatcher();
@@ -67,6 +107,7 @@ public class EntityBee extends EntityAnimal implements EntityBird {
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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));
@@ -82,6 +123,7 @@ public class EntityBee extends EntityAnimal implements EntityBird {
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 net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, (new EntityBee.h(this)).a(new Class[0]));
this.targetSelector.a(2, new EntityBee.c(this));
}
@@ -590,6 +632,7 @@ public class EntityBee extends EntityAnimal implements EntityBird {
private d() {
super(); // CraftBukkit - decompile error
+ this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); // Purpur - enter hive
}
@Override
@@ -652,6 +695,7 @@ public class EntityBee extends EntityAnimal implements EntityBird {
private g() {
super(); // CraftBukkit - decompile error
+ this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); // Purpur - grow crop
}
@Override
@@ -716,6 +760,7 @@ public class EntityBee extends EntityAnimal implements EntityBird {
private i() {
super(); // CraftBukkit - decompile error
+ this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); // Purpur - go to hive
}
@Override
@@ -1234,4 +1279,67 @@ public class EntityBee extends EntityAnimal implements EntityBird {
}
}
+
+ // Purpur start
+ public static class ControllerMoveWASDBee extends ControllerMoveFlying {
+ protected final EntityBee entity;
+ protected int tooHighCooldown = 0;
+
+ public ControllerMoveWASDBee(EntityBee entity, int pitchDelta, boolean gravity) {
+ super(entity, pitchDelta, gravity);
+ this.entity = entity;
+ }
+
+ // isUpdating
+ @Override
+ public boolean b() {
+ return entity.hasRider() || super.b();
+ }
+
+ // tick
+ @Override
+ public void a() {
+ if (entity.hasRider()) {
+ tick(entity.getRider());
+ } else {
+ tick();
+ }
+ }
+
+ protected void tick(EntityHuman rider) {
+ float forward = Math.max(0.0F, rider.getForward());
+ float vertical = forward == 0.0F ? 0.0F : -(rider.pitch / 90.0F);
+ float strafe = rider.getStrafe();
+
+ if (rider.jumping && net.pl3x.purpur.controller.ControllerMoveWASD.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 *= 0.25F;
+ }
+
+ entity.setSpeed(speed);
+ entity.setVertical(vertical);
+ entity.setStrafe(strafe);
+ entity.setForward(forward);
+
+ setForward(entity.getForward());
+ setStrafe(entity.getStrafe());
+
+ if (forward == 0 && strafe == 0) {
+ entity.setMot(entity.getMot().multiply(0.95, 0.9, 0.95));
+ }
+ }
+ }
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/server/EntityBlaze.java b/src/main/java/net/minecraft/server/EntityBlaze.java
index da6a3fa2c..d02130e0d 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,13 +18,49 @@ 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 boolean requireShiftToMount() {
+ return world.purpurConfig.blazeRequireShiftToMount;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.blazeMaxY;
+ }
+
+ @Override
+ public void e(Vec3D vec3d) {
+ super.e(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 net.pl3x.purpur.pathfinder.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(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this).a(new Class[0])); // Purpur - decompile error
this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true));
}
@@ -34,6 +71,12 @@ public class EntityBlaze extends EntityMonster {
this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(6.0D);
this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.23000000417232513D);
this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(48.0D);
+ // Purpur start
+ if (world != null && world.purpurConfig.blazeRidable) {
+ this.getAttributeMap().b(GenericAttributes.FLYING_SPEED);
+ this.getAttributeInstance(GenericAttributes.FLYING_SPEED).setValue(0.6000000238418579D);
+ }
+ // Purpur end
}
@Override
@@ -87,6 +130,14 @@ public class EntityBlaze extends EntityMonster {
this.damageEntity(DamageSource.DROWN, 1.0F);
}
+ // 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 b3bdc194a..8b9222d77 100644
--- a/src/main/java/net/minecraft/server/EntityCat.java
+++ b/src/main/java/net/minecraft/server/EntityCat.java
@@ -42,6 +42,23 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.catRequireShiftToMount;
+ }
+ // Purpur end
+
public MinecraftKey ez() {
return (MinecraftKey) EntityCat.bz.getOrDefault(this.getCatType(), EntityCat.bz.get(0));
}
@@ -50,7 +67,8 @@ public class EntityCat extends EntityTameableAnimal {
protected void initPathfinder() {
this.goalSit = new PathfinderGoalSit(this);
this.bG = new EntityCat.PathfinderGoalTemptChance(this, 0.6D, EntityCat.bA, true);
- this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalFloat(this)); // Purpur
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new EntityCat.b(this));
this.goalSelector.a(2, this.goalSit);
this.goalSelector.a(3, this.bG);
@@ -62,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 net.pl3x.purpur.pathfinder.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.bw));
}
@@ -78,6 +97,7 @@ public class EntityCat extends EntityTameableAnimal {
this.datawatcher.set(EntityCat.bB, i);
}
+ public void setSleepingWithOwner(boolean flag) { u(flag); } // Purpur - OBFHELPER
public void u(boolean flag) {
this.datawatcher.set(EntityCat.bC, flag);
}
@@ -86,6 +106,7 @@ public class EntityCat extends EntityTameableAnimal {
return (Boolean) this.datawatcher.get(EntityCat.bC);
}
+ public void setHeadDown(boolean flag) { v(flag); } // Purpur - OBFHELPER
public void v(boolean flag) {
this.datawatcher.set(EntityCat.bD, flag);
}
@@ -306,6 +327,7 @@ public class EntityCat extends EntityTameableAnimal {
@Override
public boolean a(EntityHuman entityhuman, EnumHand enumhand) {
+ if (hasRider()) return false; // Purpur
ItemStack itemstack = entityhuman.b(enumhand);
Item item = itemstack.getItem();
@@ -396,6 +418,15 @@ public class EntityCat extends EntityTameableAnimal {
}
+ // Purpur start
+ public void onMount(EntityHuman entityhuman) {
+ super.onMount(entityhuman);
+ setSitting(false);
+ setSleepingWithOwner(false);
+ setHeadDown(false);
+ }
+ // Purpur end
+
static class b extends PathfinderGoal {
private final EntityCat a;
@@ -405,6 +436,7 @@ public class EntityCat extends EntityTameableAnimal {
public b(EntityCat entitycat) {
this.a = entitycat;
+ this.a(java.util.EnumSet.of(PathfinderGoal.Type.MOVE)); // 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 23ced2c7b..5b86b36f6 100644
--- a/src/main/java/net/minecraft/server/EntityCaveSpider.java
+++ b/src/main/java/net/minecraft/server/EntityCaveSpider.java
@@ -8,6 +8,23 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.caveSpiderRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initAttributes() {
super.initAttributes();
diff --git a/src/main/java/net/minecraft/server/EntityChicken.java b/src/main/java/net/minecraft/server/EntityChicken.java
index 65795fc89..5505b7ee9 100644
--- a/src/main/java/net/minecraft/server/EntityChicken.java
+++ b/src/main/java/net/minecraft/server/EntityChicken.java
@@ -17,9 +17,27 @@ public class EntityChicken extends EntityAnimal {
this.a(PathType.WATER, 0.0F);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.chickenRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.chickenRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.chickenRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D));
this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D));
this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, EntityChicken.bD));
@@ -66,6 +84,7 @@ public class EntityChicken extends EntityAnimal {
this.bw += this.bA * 2.0F;
if (!this.world.isClientSide && this.isAlive() && !this.isBaby() && !this.isChickenJockey() && --this.eggLayTime <= 0) {
+ if (world.purpurConfig.chickenDontLayEggsWhenRidden) return; // Purpur
this.a(SoundEffects.ENTITY_CHICKEN_EGG, 1.0F, (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F);
this.forceDrops = true; // CraftBukkit
this.a((IMaterial) Items.EGG);
diff --git a/src/main/java/net/minecraft/server/EntityCod.java b/src/main/java/net/minecraft/server/EntityCod.java
index 1e3782122..0153a821e 100644
--- a/src/main/java/net/minecraft/server/EntityCod.java
+++ b/src/main/java/net/minecraft/server/EntityCod.java
@@ -6,6 +6,23 @@ public class EntityCod extends EntityFishSchool {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.codRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.codRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.codRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected ItemStack l() {
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 a0b35c869..144e89f22 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 boolean b(EntityHuman entityhuman, EnumHand enumhand) {
+ return owner.isAlive() && owner.tryRide(entityhuman, enumhand);
+ }
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/server/EntityCow.java b/src/main/java/net/minecraft/server/EntityCow.java
index 2c8bbf20a..723a9fa1e 100644
--- a/src/main/java/net/minecraft/server/EntityCow.java
+++ b/src/main/java/net/minecraft/server/EntityCow.java
@@ -11,9 +11,27 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.cowRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new PathfinderGoalPanic(this, 2.0D));
this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D));
this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.25D, RecipeItemStack.a(Items.WHEAT), false));
diff --git a/src/main/java/net/minecraft/server/EntityCreeper.java b/src/main/java/net/minecraft/server/EntityCreeper.java
index 45dfc8104..48fd8e716 100644
--- a/src/main/java/net/minecraft/server/EntityCreeper.java
+++ b/src/main/java/net/minecraft/server/EntityCreeper.java
@@ -23,16 +23,35 @@ public class EntityCreeper extends EntityMonster {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.creeperRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.creeperRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.creeperRequireShiftToMount;
+ }
+ // 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 net.pl3x.purpur.pathfinder.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 net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true));
this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, new Class[0]));
}
@@ -165,6 +184,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);
}
@@ -265,6 +285,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);
}
}
// Paper end
@@ -277,4 +298,59 @@ public class EntityCreeper extends EntityMonster {
public void setCausedHeadDrop() {
++this.bA;
}
+
+ // Purpur start
+ @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);
+ }
+
+ private int spacebarCharge = 0;
+ private int prevSpacebarCharge = 0;
+ private int powerToggleDelay = 0;
+
+ @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
}
diff --git a/src/main/java/net/minecraft/server/EntityDolphin.java b/src/main/java/net/minecraft/server/EntityDolphin.java
index ce78586ea..81570b37b 100644
--- a/src/main/java/net/minecraft/server/EntityDolphin.java
+++ b/src/main/java/net/minecraft/server/EntityDolphin.java
@@ -1,5 +1,12 @@
package net.minecraft.server;
+// Purpur start
+import net.pl3x.purpur.entity.DolphinSpit;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.entity.CraftPlayer;
+import org.bukkit.util.Vector;
+// Purpur end
+
import java.util.EnumSet;
import java.util.List;
import java.util.Random;
@@ -15,6 +22,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);
@@ -23,6 +31,50 @@ public class EntityDolphin extends EntityWaterAnimal {
this.setCanPickupLoot(true);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.dolphinRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.dolphinRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.dolphinRequireShiftToMount;
+ }
+
+ @Override
+ public boolean onSpacebar() {
+ if (spitCooldown == 0 && hasRider()) {
+ spitCooldown = world.purpurConfig.dolphinSpitCooldown;
+ if (!hasRider()) {
+ return false;
+ }
+
+ CraftPlayer player = (CraftPlayer) getRider().getBukkitEntity();
+ if (!player.hasPermission("allow.special.dolphin")) {
+ return false;
+ }
+
+ Location loc = player.getEyeLocation();
+ loc.setPitch(loc.getPitch() - 10);
+ Vector target = loc.getDirection().normalize().multiply(10).add(loc.toVector());
+
+ DolphinSpit spit = new 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(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) {
@@ -97,6 +149,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 net.pl3x.purpur.pathfinder.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));
@@ -107,6 +160,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 net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityGuardian.class})).a(new Class[0])); // CraftBukkit - decompile error
}
@@ -163,7 +217,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
@@ -196,6 +250,9 @@ public class EntityDolphin extends EntityWaterAnimal {
@Override
public void tick() {
super.tick();
+ if (spitCooldown > 0) {
+ spitCooldown--;
+ }
if (!this.isNoAI()) {
if (this.ay()) {
this.b(2400);
@@ -459,7 +516,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() {
@@ -527,7 +584,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;
@@ -537,7 +594,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 77885f67f..63f5969b1 100644
--- a/src/main/java/net/minecraft/server/EntityDrowned.java
+++ b/src/main/java/net/minecraft/server/EntityDrowned.java
@@ -19,6 +19,23 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity {
this.navigationLand = new Navigation(this, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.drownedRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.drownedRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.drownedRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void l() {
this.goalSelector.a(1, new EntityDrowned.c(this, 1.0D));
@@ -200,7 +217,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity {
this.bw = flag;
}
- static class d extends ControllerMove {
+ static class d extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur
private final EntityDrowned i;
@@ -210,7 +227,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity {
}
@Override
- public void a() {
+ public void tick() { // Purpur
EntityLiving entityliving = this.i.getGoalTarget();
if (this.i.ez() && this.i.isInWater()) {
@@ -243,7 +260,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
}
}
@@ -382,6 +399,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity {
this.a = entitydrowned;
this.b = d0;
this.c = i;
+ this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); // 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 2887cb14e..a6a79f5e9 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[] bS = new int[24];
private final Path bT = new Path();
private Explosion explosionSource = new Explosion(null, this, 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,8 +61,50 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
}
this.bO = 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 boolean requireShiftToMount() {
+ return world.purpurConfig.enderDragonRequireShiftToMount;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.enderDragonMaxY;
+ }
+ // Purpur end
+
@Override
protected void initAttributes() {
super.initAttributes();
@@ -96,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;
@@ -117,6 +191,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
this.bx = this.by;
if (this.getHealth() <= 0.0F) {
+ 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;
@@ -128,9 +203,9 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
f1 = 0.2F / (MathHelper.sqrt(b(vec3d)) * 10.0F + 1.0F);
f1 *= (float) Math.pow(2.0D, vec3d.y);
- if (this.bO.a().a()) {
+ if (!hasRider && this.bO.a().a()) { // Purpur
this.by += 0.1F;
- } else if (this.bz) {
+ } else if (!hasRider && this.bz) { // Purpur
this.by += f1 * 0.5F;
} else {
this.by += f1;
@@ -174,7 +249,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
}
this.bO.a().b();
- } else {
+ } else if (!hasRider) { // Purpur
IDragonController idragoncontroller = this.bO.a();
idragoncontroller.c();
@@ -241,7 +316,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
this.a(this.bH, (double) (f11 * 0.5F), 0.0D, (double) (-f12 * 0.5F));
this.a(this.bL, (double) (f12 * 4.5F), 2.0D, (double) (f11 * 4.5F));
this.a(this.bM, (double) (f12 * -4.5F), 2.0D, (double) (f11 * -4.5F));
- if (!this.world.isClientSide && this.hurtTicks == 0) {
+ if (!hasRider && this.hurtTicks == 0) { // Purpur
this.a(this.world.getEntities(this, this.bL.getBoundingBox().grow(4.0D, 2.0D, 4.0D).d(0.0D, -2.0D, 0.0D), IEntitySelector.e));
this.a(this.world.getEntities(this, this.bM.getBoundingBox().grow(4.0D, 2.0D, 4.0D).d(0.0D, -2.0D, 0.0D), IEntitySelector.e));
this.b(this.world.getEntities(this, this.bw.getBoundingBox().g(1.0D), IEntitySelector.e));
@@ -284,7 +359,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster {
}
if (!this.world.isClientSide) {
- this.bz = this.b(this.bw.getBoundingBox()) | this.b(this.bG.getBoundingBox()) | this.b(this.bH.getBoundingBox());
+ this.bz = !hasRider && this.b(this.bw.getBoundingBox()) | this.b(this.bG.getBoundingBox()) | this.b(this.bH.getBoundingBox()); // Purpur
if (this.bN != null) {
this.bN.b(this);
}
@@ -951,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 212636dcb..de30ce483 100644
--- a/src/main/java/net/minecraft/server/EntityEnderman.java
+++ b/src/main/java/net/minecraft/server/EntityEnderman.java
@@ -27,9 +27,27 @@ public class EntityEnderman extends EntityMonster {
this.a(PathType.WATER, -1.0F);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.endermanRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.endermanRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.endermanRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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));
@@ -37,6 +55,7 @@ public class EntityEnderman extends EntityMonster {
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 net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new EntityEnderman.PathfinderGoalPlayerWhoLookedAtTarget(this));
this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, new Class[0]));
this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityEndermite.class, 10, true, false, EntityEnderman.by));
@@ -189,7 +208,7 @@ public class EntityEnderman extends EntityMonster {
this.damageEntity(DamageSource.DROWN, 1.0F); // Paper - copied in patch 13 (allow nerfed mobs to jump, float and take water damage)
}
- if (this.world.isDay() && this.ticksLived >= this.bA + 600) {
+ if (!hasRider() && this.world.isDay() && this.ticksLived >= this.bA + 600) { // Purpur - no random teleporting
float f = this.aI();
if (f > 0.5F && this.world.f(new BlockPosition(this)) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper
@@ -290,6 +309,7 @@ public class EntityEnderman extends EntityMonster {
public boolean damageEntity(DamageSource damagesource, float f) {
if (this.isInvulnerable(damagesource)) {
return false;
+ } else if (hasRider()) { return super.damageEntity(damagesource, f); // Purpur - no teleporting on damage
} else if (!(damagesource instanceof EntityDamageSourceIndirect) && damagesource != DamageSource.FIREWORKS) {
boolean flag = super.damageEntity(damagesource, f);
@@ -329,6 +349,7 @@ public class EntityEnderman extends EntityMonster {
public PathfinderGoalEndermanPickupBlock(EntityEnderman entityenderman) {
this.enderman = entityenderman;
+ this.a(EnumSet.of(PathfinderGoal.Type.TARGET)); // Purpur
}
@Override
@@ -367,11 +388,11 @@ public class EntityEnderman extends EntityMonster {
static class PathfinderGoalEndermanPlaceBlock extends PathfinderGoal {
- private EntityEnderman getEnderman() { return this.a; } // Paper - OBFHELPER
- private final EntityEnderman a;
+ private final EntityEnderman a; private EntityEnderman getEnderman() { return this.a; } // Paper - OBFHELPER
public PathfinderGoalEndermanPlaceBlock(EntityEnderman entityenderman) {
this.a = entityenderman;
+ this.a(EnumSet.of(PathfinderGoal.Type.TARGET)); // Purpur
}
@Override
@@ -381,6 +402,10 @@ public class EntityEnderman extends EntityMonster {
@Override
public void e() {
+ // Purpur start
+ IBlockData carried = getEnderman().getCarried();
+ if (carried == null) return;
+ // Purpur end
Random random = this.a.getRandom();
World world = this.a.world;
int i = MathHelper.floor(this.a.locX() - 1.0D + random.nextDouble() * 2.0D);
@@ -391,7 +416,7 @@ public class EntityEnderman extends EntityMonster {
if (iblockdata == null) return; // Paper
BlockPosition blockposition1 = blockposition.down();
IBlockData iblockdata1 = world.getType(blockposition1);
- IBlockData iblockdata2 = Block.getValidBlockForPosition(getEnderman().getCarried(), getEnderman().world, blockposition); // Paper - Fix MC-124320
+ IBlockData iblockdata2 = Block.getValidBlockForPosition(carried, getEnderman().world, blockposition); // Paper - Fix MC-124320 // Purpur
if (iblockdata2 != null && this.a(world, blockposition, iblockdata2, iblockdata, iblockdata1, blockposition1)) {
// CraftBukkit start - Place event
diff --git a/src/main/java/net/minecraft/server/EntityEndermite.java b/src/main/java/net/minecraft/server/EntityEndermite.java
index e4bd2796a..5eaf1920b 100644
--- a/src/main/java/net/minecraft/server/EntityEndermite.java
+++ b/src/main/java/net/minecraft/server/EntityEndermite.java
@@ -12,13 +12,32 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.endermiteRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(1, new net.pl3x.purpur.pathfinder.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(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this).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 b030fe957..179a26129 100644
--- a/src/main/java/net/minecraft/server/EntityEvoker.java
+++ b/src/main/java/net/minecraft/server/EntityEvoker.java
@@ -12,10 +12,28 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.evokerRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
super.initPathfinder();
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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 +42,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 net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, EntityRaider.class).a(new Class[0])); // Purpur - 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));
@@ -108,6 +127,7 @@ public class EntityEvoker extends EntityIllagerWizard {
public d() {
super();
+ this.a(java.util.EnumSet.of(PathfinderGoal.Type.TARGET)); // Purpur - wolololo spell
}
@Override
@@ -186,6 +206,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.TARGET)); // Purpur - summon spell
}
@Override
@@ -240,6 +261,7 @@ public class EntityEvoker extends EntityIllagerWizard {
private a() {
super();
+ this.a(java.util.EnumSet.of(PathfinderGoal.Type.TARGET)); // 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 b853fd0d9..b8d786fad 100644
--- a/src/main/java/net/minecraft/server/EntityFish.java
+++ b/src/main/java/net/minecraft/server/EntityFish.java
@@ -72,9 +72,10 @@ public abstract class EntityFish extends EntityWaterAnimal {
@Override
protected void initPathfinder() {
super.initPathfinder();
- this.goalSelector.a(0, new PathfinderGoalPanic(this, 1.25D));
- this.goalSelector.a(2, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 1.6D, 1.4D, IEntitySelector.f::test)); // Purpur - decompile error
- this.goalSelector.a(4, new EntityFish.b(this));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
+ this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D)); // Purpur
+ this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 1.6D, 1.4D, IEntitySelector.f::test)); // Purpur - decompile error
+ this.goalSelector.a(5, new EntityFish.b(this)); // Purpur
}
@Override
@@ -85,7 +86,7 @@ public abstract class EntityFish extends EntityWaterAnimal {
@Override
public void e(Vec3D vec3d) {
if (this.doAITick() && this.isInWater()) {
- this.a(0.01F, vec3d);
+ this.a(hasRider() ? getSpeed() : 0.1F, vec3d); // Purpur
this.move(EnumMoveType.SELF, this.getMot());
this.setMot(this.getMot().a(0.9D));
if (this.getGoalTarget() == null) {
@@ -156,7 +157,7 @@ public abstract class EntityFish extends EntityWaterAnimal {
return SoundEffects.ENTITY_FISH_SWIM;
}
- static class a extends ControllerMove {
+ static class a extends net.pl3x.purpur.controller.ControllerMoveWASDWater { // Purpur
private final EntityFish i;
@@ -165,8 +166,16 @@ public abstract class EntityFish extends EntityWaterAnimal {
this.i = entityfish;
}
+ // Purpur start
@Override
- public void a() {
+ public void tick(EntityHuman rider) {
+ 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.a(TagsFluid.WATER)) {
this.i.setMot(this.i.getMot().add(0.0D, 0.005D, 0.0D));
}
diff --git a/src/main/java/net/minecraft/server/EntityFox.java b/src/main/java/net/minecraft/server/EntityFox.java
index 82a32d5db..4f53090d3 100644
--- a/src/main/java/net/minecraft/server/EntityFox.java
+++ b/src/main/java/net/minecraft/server/EntityFox.java
@@ -55,6 +55,23 @@ 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 boolean requireShiftToMount() {
+ return world.purpurConfig.foxRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initDatawatcher() {
super.initDatawatcher();
@@ -74,6 +91,7 @@ public class EntityFox extends EntityAnimal {
return entityliving instanceof EntityFishSchool;
});
this.goalSelector.a(0, new EntityFox.g());
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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));
@@ -96,6 +114,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 net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(3, new EntityFox.a(EntityLiving.class, false, false, (entityliving) -> {
return EntityFox.bB.test(entityliving) && !this.c(entityliving.getUniqueID());
}));
@@ -376,6 +395,7 @@ public class EntityFox extends EntityAnimal {
return itemstack1.isEmpty() || this.bL > 0 && item.isFood() && !itemstack1.getItem().isFood();
}
+ public void spit(ItemStack itemstack) { k(itemstack); } // Purpur - OBFHELPER
private void k(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);
@@ -469,6 +489,7 @@ public class EntityFox extends EntityAnimal {
return this.t(16);
}
+ public void setChasing(boolean flag) { s(flag); } // Purpur - OBFHELPER
public void s(boolean flag) {
this.d(16, flag);
}
@@ -511,6 +532,7 @@ public class EntityFox extends EntityAnimal {
this.setSleeping(false);
}
+ public void stopActions() { eH(); } // Purpur - OBFHELPER
private void eH() {
this.u(false);
this.setCrouching(false);
@@ -592,6 +614,29 @@ public class EntityFox extends EntityAnimal {
return deathEvent; // Paper
}
+ // Purpur start
+ @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
+
public static boolean a(EntityFox entityfox, EntityLiving entityliving) {
double d0 = entityliving.locZ() - entityfox.locZ();
double d1 = entityliving.locX() - entityfox.locX();
@@ -655,16 +700,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
}
}
@@ -1335,16 +1380,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.eI()) {
- 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 e1c2540d1..46841df71 100644
--- a/src/main/java/net/minecraft/server/EntityGhast.java
+++ b/src/main/java/net/minecraft/server/EntityGhast.java
@@ -14,11 +14,47 @@ 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 boolean requireShiftToMount() {
+ return world.purpurConfig.ghastRequireShiftToMount;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.ghastMaxY;
+ }
+
+ @Override
+ public void e(Vec3D vec3d) {
+ super.e(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 net.pl3x.purpur.pathfinder.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 net.pl3x.purpur.pathfinder.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;
}));
@@ -60,6 +96,12 @@ public class EntityGhast extends EntityFlying implements IMonster {
super.initAttributes();
this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(10.0D);
this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(100.0D);
+ // Purpur start
+ if (world != null && world.purpurConfig.ghastRidable) {
+ this.getAttributeMap().b(GenericAttributes.FLYING_SPEED);
+ this.getAttributeInstance(GenericAttributes.FLYING_SPEED).setValue(0.6000000238418579D);
+ }
+ // Purpur end
}
@Override
@@ -255,7 +297,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 +308,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 d9e5eaad1..ff8a41a53 100644
--- a/src/main/java/net/minecraft/server/EntityGiantZombie.java
+++ b/src/main/java/net/minecraft/server/EntityGiantZombie.java
@@ -4,8 +4,33 @@ public class EntityGiantZombie extends EntityMonster {
public EntityGiantZombie(EntityTypes<? extends EntityGiantZombie> entitytypes, World world) {
super(entitytypes, world);
+ setStepHeight(world.purpurConfig.giantStepHeight); // Purpur
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.giantRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.giantRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.giantRequireShiftToMount;
+ }
+
+ @Override
+ public float getJumpHeight() {
+ // make giants jump as high as everything else relative to their size
+ // 1.0 makes bottom of feet about as high as their waist when they jump
+ return world.purpurConfig.giantJumpHeight;
+ }
+ // Purpur end
+
@Override
protected float b(EntityPose entitypose, EntitySize entitysize) {
return 10.440001F;
diff --git a/src/main/java/net/minecraft/server/EntityGuardian.java b/src/main/java/net/minecraft/server/EntityGuardian.java
index e69cb334f..97040872b 100644
--- a/src/main/java/net/minecraft/server/EntityGuardian.java
+++ b/src/main/java/net/minecraft/server/EntityGuardian.java
@@ -24,15 +24,39 @@ public class EntityGuardian extends EntityMonster {
this.f = 10;
this.a(PathType.WATER, 0.0F);
this.moveController = new EntityGuardian.ControllerMoveGuardian(this);
- this.c = this.random.nextFloat();
- this.d = this.c;
+ // 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
+ }
+
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.guardianRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.guardianRidableInWater;
}
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.guardianRequireShiftToMount;
+ }
+ // 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 net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(4, new EntityGuardian.PathfinderGoalGuardianAttack(this));
this.goalSelector.a(5, pathfindergoalmovetowardsrestriction);
this.goalSelector.a(7, this.goalRandomStroll);
@@ -41,6 +65,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 net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityLiving.class, 10, true, false, new EntityGuardian.EntitySelectorGuardianTargetHumanSquid(this)));
}
@@ -79,6 +104,7 @@ public class EntityGuardian extends EntityMonster {
return (Boolean) this.datawatcher.get(EntityGuardian.b);
}
+ private void setMovingFlag(boolean movingFlag) { r(movingFlag); } // Purpur - OBFHELPER
private void r(boolean flag) {
this.datawatcher.set(EntityGuardian.b, flag);
}
@@ -293,7 +319,7 @@ public class EntityGuardian extends EntityMonster {
@Override
public void e(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.es() && this.getGoalTarget() == null) {
@@ -305,17 +331,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
+ }
+
@Override
- public void a() {
+ public void tick() {
+ // Purpur end
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 7484bfeea..f231340d9 100644
--- a/src/main/java/net/minecraft/server/EntityGuardianElder.java
+++ b/src/main/java/net/minecraft/server/EntityGuardianElder.java
@@ -16,6 +16,23 @@ public class EntityGuardianElder extends EntityGuardian {
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.elderGuardianRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.elderGuardianRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.elderGuardianRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
public void initAttributes() {
super.initAttributes();
diff --git a/src/main/java/net/minecraft/server/EntityHorse.java b/src/main/java/net/minecraft/server/EntityHorse.java
index a6fb4ba5b..98b1e9375 100644
--- a/src/main/java/net/minecraft/server/EntityHorse.java
+++ b/src/main/java/net/minecraft/server/EntityHorse.java
@@ -19,6 +19,13 @@ public class EntityHorse extends EntityHorseAbstract {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.horseRidableInWater;
+ }
+ // Purpur end
+
@Override
protected void initDatawatcher() {
super.initDatawatcher();
diff --git a/src/main/java/net/minecraft/server/EntityHorseAbstract.java b/src/main/java/net/minecraft/server/EntityHorseAbstract.java
index c56efe035..e7ba83f32 100644
--- a/src/main/java/net/minecraft/server/EntityHorseAbstract.java
+++ b/src/main/java/net/minecraft/server/EntityHorseAbstract.java
@@ -38,12 +38,39 @@ 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.H = 1.0F;
this.loadChest();
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return false; // vanilla handles
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return false;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return false; // vanilla handles
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
+ // Purpur start
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this) {
+ @Override
+ public boolean a() {
+ return entity.getRidingPassenger() instanceof EntityHuman && isSaddled();
+ }
+ });
+ // 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));
@@ -281,7 +308,7 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven
return true;
}
- public boolean eL() {
+ public boolean eL() { return isSaddled(); } boolean isSaddled() { // Purpur - OBFHELPER
return this.t(4);
}
diff --git a/src/main/java/net/minecraft/server/EntityHorseDonkey.java b/src/main/java/net/minecraft/server/EntityHorseDonkey.java
index 9a52decdc..64d80081f 100644
--- a/src/main/java/net/minecraft/server/EntityHorseDonkey.java
+++ b/src/main/java/net/minecraft/server/EntityHorseDonkey.java
@@ -6,6 +6,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 4dd4d91eb..a9f26efe6 100644
--- a/src/main/java/net/minecraft/server/EntityHorseMule.java
+++ b/src/main/java/net/minecraft/server/EntityHorseMule.java
@@ -6,6 +6,13 @@ 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 290cb9337..7bf76e5a0 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
+
@Override
protected void initAttributes() {
super.initAttributes();
@@ -21,7 +33,7 @@ public class EntityHorseSkeleton extends EntityHorseAbstract {
}
@Override
- protected void ez() {}
+ protected void ez() { if (world.purpurConfig.skeletonHorseCanSwim) goalSelector.a(0, new PathfinderGoalFloat(this)); } // Purpur
@Override
protected SoundEffect getSoundAmbient() {
@@ -116,7 +128,7 @@ public class EntityHorseSkeleton extends EntityHorseAbstract {
@Override
public boolean bi() {
- return true;
+ return super.bi(); // Purpur
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityHorseZombie.java b/src/main/java/net/minecraft/server/EntityHorseZombie.java
index 5782a25ec..c87fc523f 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
+
@Override
protected void initAttributes() {
super.initAttributes();
@@ -78,5 +90,5 @@ public class EntityHorseZombie extends EntityHorseAbstract {
}
@Override
- protected void ez() {}
+ protected void ez() { 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 7afcde608..f372c13d8 100644
--- a/src/main/java/net/minecraft/server/EntityHuman.java
+++ b/src/main/java/net/minecraft/server/EntityHuman.java
@@ -374,9 +374,21 @@ public abstract class EntityHuman extends EntityLiving {
this.activeContainer = this.defaultContainer;
}
+ // Purpur start
+ boolean mounting = false;
+
+ @Override
+ public void setSneaking(boolean sneaking) {
+ if (this.mounting && !sneaking) {
+ this.mounting = false;
+ }
+ super.setSneaking(sneaking);
+ }
+ // Purpur end
+
@Override
public void passengerTick() {
- if (!this.world.isClientSide && this.dU() && this.isPassenger()) {
+ if (this.isSneaking() && this.isPassenger() && !this.mounting) { // Purpur
this.stopRiding();
this.setSneaking(false);
} else {
diff --git a/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java b/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java
index 81b7cd06f..3e6722cfc 100644
--- a/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java
+++ b/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java
@@ -19,10 +19,28 @@ 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
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.illusionerRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
super.initPathfinder();
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new EntityIllagerWizard.b());
this.goalSelector.a(4, new EntityIllagerIllusioner.b());
this.goalSelector.a(5, new EntityIllagerIllusioner.a());
@@ -30,6 +48,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 net.pl3x.purpur.pathfinder.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 1991cee43..d0a5687f0 100644
--- a/src/main/java/net/minecraft/server/EntityInsentient.java
+++ b/src/main/java/net/minecraft/server/EntityInsentient.java
@@ -28,7 +28,7 @@ public abstract class EntityInsentient extends EntityLiving {
protected int f;
protected ControllerLook lookController;
protected ControllerMove moveController;
- protected ControllerJump bq;
+ protected ControllerJump bq; public ControllerJump getJumpController() { return bq; } // Purpur - OBFHELPER
private final EntityAIBodyControl c;
protected NavigationAbstract navigation;
public PathfinderGoalSelector goalSelector;
@@ -66,8 +66,8 @@ public abstract class EntityInsentient extends EntityLiving {
this.bI = -1.0F;
this.goalSelector = new PathfinderGoalSelector(world != null && world.getMethodProfiler() != null ? world.getMethodProfiler() : null);
this.targetSelector = new PathfinderGoalSelector(world != null && world.getMethodProfiler() != null ? world.getMethodProfiler() : null);
- this.lookController = new ControllerLook(this);
- this.moveController = new ControllerMove(this);
+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASD(this); // Purpur
+ this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this); // Purpur
this.bq = new ControllerJump(this);
this.c = this.o();
this.navigation = this.b(world);
@@ -502,7 +502,7 @@ public abstract class EntityInsentient extends EntityLiving {
return super.cW();
}
- public void r(float f) {
+ public void setForwardSpeed(float speed) { this.r(speed); } public void r(float f) { // Purpur - OBFHELPER
this.bb = f;
}
@@ -514,8 +514,7 @@ public abstract class EntityInsentient extends EntityLiving {
this.aZ = f;
}
- @Override
- public void o(float f) {
+ public void setSpeed(float speed) { o(speed); } @Override public void o(float f) { // Purpur - OBFHELPER
super.o(f);
this.r(f);
}
@@ -1082,7 +1081,7 @@ public abstract class EntityInsentient extends EntityLiving {
}
protected boolean a(EntityHuman entityhuman, EnumHand enumhand) {
- return false;
+ return tryRide(entityhuman, enumhand); // Purpur
}
public boolean ec() {
@@ -1381,4 +1380,39 @@ public abstract class EntityInsentient extends EntityLiving {
public boolean a(Item item) {
return this.getItemInMainHand().getItem() == item || this.getItemInOffHand().getItem() == item;
}
+
+ // Purpur start
+ public double getMaxY() {
+ return world.getHeight();
+ }
+
+ public boolean tryRide(EntityHuman entityhuman, EnumHand enumhand) {
+ if (!isRidable()) {
+ return false;
+ }
+ if (enumhand != EnumHand.MAIN_HAND) {
+ return false;
+ }
+ if (requireShiftToMount() && !entityhuman.isSneaking()) {
+ return false;
+ }
+ if (!passengers.isEmpty() || entityhuman.isPassenger()) {
+ return false;
+ }
+ if (this instanceof EntityTameableAnimal) {
+ EntityTameableAnimal tameable = (EntityTameableAnimal) this;
+ if (tameable.isTamed() && !tameable.isOwner(entityhuman)) {
+ return false;
+ }
+ }
+ if (!entityhuman.getBukkitEntity().hasPermission("allow.ride." + getEntityType().getName())) {
+ entityhuman.sendMessage(LocaleLanguage.translate("cannot.ride.mob"));
+ return false;
+ }
+ entityhuman.mounting = true;
+ entityhuman.yaw = this.yaw;
+ entityhuman.pitch = this.pitch;
+ return entityhuman.startRiding(this) || (entityhuman.mounting = false);
+ }
+ // Purpur end
}
diff --git a/src/main/java/net/minecraft/server/EntityIronGolem.java b/src/main/java/net/minecraft/server/EntityIronGolem.java
index 7f6a56776..288a043fb 100644
--- a/src/main/java/net/minecraft/server/EntityIronGolem.java
+++ b/src/main/java/net/minecraft/server/EntityIronGolem.java
@@ -17,8 +17,26 @@ public class EntityIronGolem extends EntityGolem {
this.H = 1.0F;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.ironGolemRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.ironGolemRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.ironGolemRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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));
@@ -29,6 +47,7 @@ public class EntityIronGolem extends EntityGolem {
this.goalSelector.a(6, new PathfinderGoalRandomStrollLand(this, 0.6D));
this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F));
this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.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, EntityInsentient.class, 5, false, false, (entityliving) -> {
@@ -170,13 +189,13 @@ public class EntityIronGolem extends EntityGolem {
Item item = itemstack.getItem();
if (item != Items.IRON_INGOT) {
- return false;
+ return super.a(entityhuman, enumhand); // Purpur
} else {
float f = this.getHealth();
this.heal(25.0F);
if (this.getHealth() == f) {
- return false;
+ return super.a(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 dfb9421a1..53925d526 100644
--- a/src/main/java/net/minecraft/server/EntityLiving.java
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -75,7 +75,7 @@ public abstract class EntityLiving extends Entity {
public int maxNoDamageTicks;
public final float aG;
public final float aH;
- public float aI;
+ public float aI; public float getBodyRotation() { return aI; } // Purpur - OBFHELPER
public float aJ;
public float aK;
public float aL;
@@ -92,9 +92,9 @@ public abstract class EntityLiving extends Entity {
protected int aW; protected int getKillCount() { return this.aW; } // Paper - OBFHELPER
public float lastDamage;
public boolean jumping; // Paper - protected -> public
- public float aZ;
- public float ba;
- public float bb;
+ public float aZ; public float getStrafe() { return aZ; } public void setStrafe(float strafe) { aZ = strafe; } // Purpur - OBFHELPER
+ public float ba; public float getVertical() { return ba; } public void setVertical(float vertical) { ba = vertical; } // Purpur - OBFHELPER
+ public float bb; public float getForward() { return bb; } public void setForward(float forward) { bb = forward; } // Purpur - OBFHELPER
protected int bc;
protected double bd;
protected double be;
@@ -366,7 +366,7 @@ public abstract class EntityLiving extends Entity {
@Override
public boolean bi() {
- return false;
+ return isRidableInWater(); // Purpur
}
protected void cD() {
@@ -2085,12 +2085,12 @@ public abstract class EntityLiving extends Entity {
}
}
- protected float dp() {
+ protected float dp() { return getJumpHeight(); } public float getJumpHeight() { // Purpur - OBFHELPER
return 0.42F * this.ah();
}
- protected void jump() {
- float f = this.dp();
+ public void doJump() { jump(); } protected void jump() { // Purpur
+ float f = getJumpHeight(); // Purpur
if (this.hasEffect(MobEffects.JUMP)) {
f += 0.1F * (float) (this.getEffect(MobEffects.JUMP).getAmplifier() + 1);
@@ -2098,6 +2098,7 @@ public abstract class EntityLiving extends Entity {
Vec3D vec3d = this.getMot();
+ if (hasRider()) setMot(vec3d.x * 2D, (double) f, vec3d.z * 2D); else // Purpur - add small boost to velocity when jumping while being ridden
this.setMot(vec3d.x, (double) f, vec3d.z);
if (this.isSprinting()) {
float f1 = this.yaw * 0.017453292F;
@@ -2316,11 +2317,11 @@ public abstract class EntityLiving extends Entity {
return this.onGround ? this.dt() * (0.21600002F / (f * f * f)) : this.aM;
}
- public float dt() {
+ public float getSpeed() { return dt(); } public float dt() { // Purpur - OBFHELPER
return this.bB;
}
- public void o(float f) {
+ public void setSpeed(float speed) { o(speed); } public void o(float f) { // Purpur - OBFHELPER
this.bB = f;
}
diff --git a/src/main/java/net/minecraft/server/EntityLlama.java b/src/main/java/net/minecraft/server/EntityLlama.java
index 193dbfc5f..7a4e64a3d 100644
--- a/src/main/java/net/minecraft/server/EntityLlama.java
+++ b/src/main/java/net/minecraft/server/EntityLlama.java
@@ -16,8 +16,47 @@ 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() && isSaddled()) {
+ tick(entity.getRider());
+ } else {
+ tick();
+ }
+ }
+ };
+ this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this) {
+ @Override
+ public void a() { // tick
+ if (entity.hasRider() && isSaddled()) {
+ 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 requireShiftToMount() {
+ return false; // shift reserved for opening inventory
+ }
+ // Purpur end
+
public void setStrength(int i) {
this.datawatcher.set(EntityLlama.bF, Math.max(1, Math.min(5, i)));
}
@@ -58,6 +97,14 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ // Purpur start
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this) {
+ @Override
+ public boolean a() {
+ return super.a() && isSaddled();
+ }
+ });
+ // Purpur end
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));
@@ -67,6 +114,14 @@ 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));
+ // Purpur start
+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this) {
+ @Override
+ public boolean a() {
+ return entity.getRidingPassenger() instanceof EntityHuman && isSaddled();
+ }
+ });
+ // Purpur end
this.targetSelector.a(1, new EntityLlama.c(this));
this.targetSelector.a(2, new EntityLlama.a(this));
}
@@ -253,6 +308,13 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
return false;
}
+ // Purpur start
+ @Override
+ public boolean isSaddled() {
+ return isTamed() && getColor() != null;
+ }
+ // Purpur end
+
@Override
public void a(IInventory iinventory) {
EnumColor enumcolor = this.eZ();
@@ -286,7 +348,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
}
@Nullable
- public EnumColor eZ() {
+ public EnumColor eZ() { return getColor(); } public EnumColor getColor() { // Purpur - OBFHELPER
int i = (Integer) this.datawatcher.get(EntityLlama.bG);
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 4cebd67e8..08c4ca3f3 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 requireShiftToMount() {
+ return false; // shift reserved for opening inventory
+ }
+ // Purpur end
+
@Override
protected EntityLlama fa() {
return (EntityLlama) EntityTypes.TRADER_LLAMA.a(this.world);
@@ -79,6 +96,12 @@ public class EntityLlamaTrader extends EntityLlama {
return this.isLeashed() && !this.fh();
}
+ // Purpur start
+ public boolean isSaddled() {
+ return isTamed();
+ }
+ // Purpur end
+
@Nullable
@Override
public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) {
diff --git a/src/main/java/net/minecraft/server/EntityMagmaCube.java b/src/main/java/net/minecraft/server/EntityMagmaCube.java
index 1fdc248ba..a5a36af21 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 boolean requireShiftToMount() {
+ return world.purpurConfig.magmaCubeRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initAttributes() {
super.initAttributes();
diff --git a/src/main/java/net/minecraft/server/EntityMushroomCow.java b/src/main/java/net/minecraft/server/EntityMushroomCow.java
index 3706c31aa..b20f4afd3 100644
--- a/src/main/java/net/minecraft/server/EntityMushroomCow.java
+++ b/src/main/java/net/minecraft/server/EntityMushroomCow.java
@@ -20,6 +20,23 @@ public class EntityMushroomCow extends EntityCow {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.mooshroomRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.mooshroomRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.mooshroomRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
public float a(BlockPosition blockposition, IWorldReader iworldreader) {
return iworldreader.getType(blockposition.down()).getBlock() == Blocks.MYCELIUM ? 10.0F : iworldreader.w(blockposition) - 0.5F;
diff --git a/src/main/java/net/minecraft/server/EntityOcelot.java b/src/main/java/net/minecraft/server/EntityOcelot.java
index d9a7b8ac1..8fdf34857 100644
--- a/src/main/java/net/minecraft/server/EntityOcelot.java
+++ b/src/main/java/net/minecraft/server/EntityOcelot.java
@@ -16,6 +16,23 @@ public class EntityOcelot extends EntityAnimal {
this.eq();
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.ocelotRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.ocelotRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.ocelotRequireShiftToMount;
+ }
+ // Purpur end
+
private boolean isTrusting() {
return (Boolean) this.datawatcher.get(EntityOcelot.bx);
}
@@ -47,12 +64,14 @@ public class EntityOcelot extends EntityAnimal {
protected void initPathfinder() {
this.bz = new EntityOcelot.b(this, 0.6D, EntityOcelot.bw, true);
this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(1, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(3, this.bz);
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 net.pl3x.purpur.pathfinder.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.bw));
}
diff --git a/src/main/java/net/minecraft/server/EntityPanda.java b/src/main/java/net/minecraft/server/EntityPanda.java
index f50ed1908..87ed9a8ca 100644
--- a/src/main/java/net/minecraft/server/EntityPanda.java
+++ b/src/main/java/net/minecraft/server/EntityPanda.java
@@ -46,6 +46,23 @@ 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 boolean requireShiftToMount() {
+ return world.purpurConfig.pandaRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
public boolean e(ItemStack itemstack) {
EnumItemSlot enumitemslot = EntityInsentient.h(itemstack);
@@ -69,6 +86,7 @@ public class EntityPanda extends EntityAnimal {
return this.w(8);
}
+ public void setScared(boolean scared) { this.r(scared); } // Purpur - OBFHELPER
public void r(boolean flag) {
this.d(8, flag);
}
@@ -77,6 +95,7 @@ public class EntityPanda extends EntityAnimal {
return this.w(16);
}
+ public void setLayingOnBack(boolean layingOnBack) { this.s(layingOnBack); } // Purpur - OBFHELPER
public void s(boolean flag) {
this.d(16, flag);
}
@@ -85,6 +104,7 @@ public class EntityPanda extends EntityAnimal {
return (Integer) this.datawatcher.get(EntityPanda.bz) > 0;
}
+ public void setEating(boolean eating) { this.t(eating); } // Purpur - OBFHELPER
public void t(boolean flag) {
this.datawatcher.set(EntityPanda.bz, flag ? 1 : 0);
}
@@ -201,6 +221,7 @@ public class EntityPanda extends EntityAnimal {
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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 +237,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 net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, (new EntityPanda.e(this, new Class[0])).a(new Class[0]));
}
@@ -541,7 +563,7 @@ public class EntityPanda extends EntityAnimal {
if (itemstack.getItem() instanceof ItemMonsterEgg) {
return super.a(entityhuman, enumhand);
} else if (this.eJ()) {
- return false;
+ return tryRide(entityhuman, enumhand); // Purpur;
} else if (this.et()) {
this.s(false);
return true;
@@ -558,7 +580,7 @@ public class EntityPanda extends EntityAnimal {
this.f(entityhuman);
} else {
if (this.world.isClientSide || this.es() || this.isInWater()) {
- return false;
+ return tryRide(entityhuman, enumhand); // Purpur;
}
this.eX();
@@ -576,10 +598,21 @@ public class EntityPanda extends EntityAnimal {
entityhuman.a(enumhand, true);
return true;
} else {
- return false;
+ return tryRide(entityhuman, enumhand); // Purpur
}
}
+ // Purpur start
+ @Override
+ public void onMount(EntityHuman entityhuman) {
+ super.onMount(entityhuman);
+ this.setForwardSpeed(0.0F);
+ this.setScared(false);
+ this.setEating(false);
+ this.setLayingOnBack(false);
+ }
+ // Purpur end
+
@Nullable
@Override
protected SoundEffect getSoundAmbient() {
@@ -689,6 +722,7 @@ public class EntityPanda extends EntityAnimal {
public f(EntityPanda entitypanda) {
this.a = entitypanda;
+ this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); // Purpur - lay on back
}
@Override
@@ -852,6 +886,7 @@ public class EntityPanda extends EntityAnimal {
public l(EntityPanda entitypanda) {
this.a = entitypanda;
+ this.a(EnumSet.of(PathfinderGoal.Type.MOVE)); // Purpur - sneeze
}
@Override
@@ -981,7 +1016,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;
@@ -991,9 +1026,9 @@ public class EntityPanda extends EntityAnimal {
}
@Override
- public void a() {
+ public void tick() { // Purpur
if (this.i.eL()) {
- 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 94e57a2d8..7ba2f3a35 100644
--- a/src/main/java/net/minecraft/server/EntityParrot.java
+++ b/src/main/java/net/minecraft/server/EntityParrot.java
@@ -62,12 +62,83 @@ 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
+ this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar(this, 0.3F) {
+ @Override
+ protected void tick() {
+ // flying controller (from ControllerMoveFlying)
+ if (this.h == Operation.MOVE_TO) {
+ this.h = Operation.WAIT;
+ this.a.setNoGravity(true);
+ double var0 = this.b - this.a.locX();
+ double var2 = this.c - this.a.locY();
+ double var4 = this.d - this.a.locZ();
+ double var6 = var0 * var0 + var2 * var2 + var4 * var4;
+ if (var6 < 2.500000277905201E-7D) {
+ this.a.s(0.0F);
+ this.a.r(0.0F);
+ return;
+ }
+ float var8 = (float)(MathHelper.d(var4, var0) * 57.2957763671875D) - 90.0F;
+ this.a.yaw = this.a(this.a.yaw, var8, 90.0F);
+ float var9;
+ if (this.a.onGround) {
+ var9 = (float)(this.e * this.a.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue());
+ } else {
+ var9 = (float)(this.e * this.a.getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue());
+ }
+ this.a.o(var9);
+ double var10 = (double)MathHelper.sqrt(var0 * var0 + var4 * var4);
+ float var12 = (float)(-(MathHelper.d(var2, var10) * 57.2957763671875D));
+ this.a.pitch = this.a(this.a.pitch, var12, 10);
+ this.a.s(var2 > 0.0D ? var9 : -var9);
+ } else {
+ this.a.setNoGravity(false);
+ this.a.s(0.0F);
+ this.a.r(0.0F);
+ }
+ }
+ };
+ // 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 boolean requireShiftToMount() {
+ return world.purpurConfig.parrotRequireShiftToMount;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.parrotMaxY;
+ }
+
+ @Override
+ public void e(Vec3D vec3d) {
+ super.e(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
+
@Nullable
@Override
public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) {
@@ -83,8 +154,10 @@ public class EntityParrot extends EntityPerchable implements EntityBird {
@Override
protected void initPathfinder() {
this.goalSit = new PathfinderGoalSit(this);
- 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 net.pl3x.purpur.pathfinder.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, this.goalSit);
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 90eeddb1a..c392085d0 100644
--- a/src/main/java/net/minecraft/server/EntityPhantom.java
+++ b/src/main/java/net/minecraft/server/EntityPhantom.java
@@ -22,6 +22,40 @@ 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 boolean requireShiftToMount() {
+ return world.purpurConfig.phantomRequireShiftToMount;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.phantomMaxY;
+ }
+
+ @Override
+ public void e(Vec3D vec3d) {
+ super.e(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));
+ }
+ }
+ // Purpur end
+
@Override
protected EntityAIBodyControl o() {
return new EntityPhantom.d(this);
@@ -29,9 +63,11 @@ public class EntityPhantom extends EntityFlying implements IMonster {
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new EntityPhantom.c());
this.goalSelector.a(2, new EntityPhantom.i());
this.goalSelector.a(3, new EntityPhantom.e());
+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new EntityPhantom.b());
}
@@ -39,6 +75,12 @@ public class EntityPhantom extends EntityFlying implements IMonster {
protected void initAttributes() {
super.initAttributes();
this.getAttributeMap().b(GenericAttributes.ATTACK_DAMAGE);
+ // Purpur start
+ if (world != null && world.purpurConfig.phantomRidable) {
+ this.getAttributeMap().b(GenericAttributes.FLYING_SPEED);
+ this.getAttributeInstance(GenericAttributes.FLYING_SPEED).setValue(3.0D);
+ }
+ // Purpur end
}
@Override
@@ -103,7 +145,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
@Override
public void movementTick() {
- if (this.isAlive() && this.en()) {
+ if (this.isAlive() && !hasRider() && this.isInDaylight()) { // Purpur - do not burn from daylight if has rider
this.setOnFire(8);
}
@@ -115,6 +157,27 @@ public class EntityPhantom extends EntityFlying implements IMonster {
super.mobTick();
}
+ // Purpur start
+ @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
public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) {
this.d = (new BlockPosition(this)).up(5);
@@ -215,6 +278,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
@Override
public boolean a() {
+ if (getRider() != null) return false; // Purpur - pathfinder does not have a flag
if (this.c > 0) {
--this.c;
return false;
@@ -244,6 +308,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
@Override
public boolean b() {
+ if (getRider() != null) return false; // Purpur - pathfinder does not have a flag
EntityLiving entityliving = EntityPhantom.this.getGoalTarget();
return entityliving != null ? EntityPhantom.this.a(entityliving, PathfinderTargetCondition.a) : false;
@@ -258,6 +323,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
@Override
public boolean a() {
+ if (getRider() != null) 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;
@@ -447,14 +513,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 {
@@ -470,7 +545,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;
@@ -479,7 +554,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 8d277566e..e6a7f8ef3 100644
--- a/src/main/java/net/minecraft/server/EntityPig.java
+++ b/src/main/java/net/minecraft/server/EntityPig.java
@@ -19,9 +19,27 @@ public class EntityPig extends EntityAnimal {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.pigRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.pigRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return false;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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));
@@ -110,24 +128,22 @@ public class EntityPig extends EntityAnimal {
@Override
public boolean a(EntityHuman entityhuman, EnumHand enumhand) {
- if (super.a(entityhuman, enumhand)) {
+ // Purpur start - reorder logic so super is last (so tryRide is last)
+ ItemStack itemstack = entityhuman.b(enumhand);
+ if (itemstack.getItem() == Items.NAME_TAG) {
+ itemstack.a(entityhuman, this, enumhand);
+ return true;
+ }
+ if (hasSaddle() && !isVehicle()) {
+ entityhuman.startRiding(this);
+ return true;
+ }
+ if (itemstack.getItem() == Items.SADDLE) {
+ itemstack.a(entityhuman, this, enumhand);
return true;
- } else {
- ItemStack itemstack = entityhuman.b(enumhand);
-
- if (itemstack.getItem() == Items.NAME_TAG) {
- itemstack.a(entityhuman, (EntityLiving) this, enumhand);
- return true;
- } else if (this.hasSaddle() && !this.isVehicle()) {
- if (!this.world.isClientSide) {
- entityhuman.startRiding(this);
- }
-
- return true;
- } else {
- return itemstack.getItem() == Items.SADDLE && itemstack.a(entityhuman, (EntityLiving) this, enumhand);
- }
}
+ return super.a(entityhuman, enumhand);
+ // Purpur end
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityPigZombie.java b/src/main/java/net/minecraft/server/EntityPigZombie.java
index 9dd028b55..fb9ef88ea 100644
--- a/src/main/java/net/minecraft/server/EntityPigZombie.java
+++ b/src/main/java/net/minecraft/server/EntityPigZombie.java
@@ -17,6 +17,23 @@ public class EntityPigZombie extends EntityZombie {
this.a(PathType.LAVA, 8.0F);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.zombiePigmanRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.zombiePigmanRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.zombiePigmanRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
public void setLastDamager(@Nullable EntityLiving entityliving) {
super.setLastDamager(entityliving);
diff --git a/src/main/java/net/minecraft/server/EntityPillager.java b/src/main/java/net/minecraft/server/EntityPillager.java
index 0357c9da9..98a657cec 100644
--- a/src/main/java/net/minecraft/server/EntityPillager.java
+++ b/src/main/java/net/minecraft/server/EntityPillager.java
@@ -13,15 +13,34 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.pillagerRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
super.initPathfinder();
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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 net.pl3x.purpur.pathfinder.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 edccd632b..3edba1e5a 100644
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
@@ -1292,6 +1292,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
public void a(float f, float f1, boolean flag, boolean flag1) {
+ if (aZ != f || bb != f1 || jumping != flag || isSneaking() != flag1) resetIdleTimer(); // Purpur
if (this.isPassenger()) {
if (f >= -1.0F && f <= 1.0F) {
this.aZ = f;
@@ -1304,7 +1305,6 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
this.jumping = flag;
this.setSneaking(flag1);
}
-
}
@Override
diff --git a/src/main/java/net/minecraft/server/EntityPolarBear.java b/src/main/java/net/minecraft/server/EntityPolarBear.java
index f8e29a02d..0a3906bde 100644
--- a/src/main/java/net/minecraft/server/EntityPolarBear.java
+++ b/src/main/java/net/minecraft/server/EntityPolarBear.java
@@ -17,6 +17,23 @@ public class EntityPolarBear extends EntityAnimal {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.polarBearRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.polarBearRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.polarBearRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
public EntityAgeable createChild(EntityAgeable entityageable) {
return (EntityAgeable) EntityTypes.POLAR_BEAR.a(this.world);
@@ -31,12 +48,14 @@ public class EntityPolarBear extends EntityAnimal {
protected void initPathfinder() {
super.initPathfinder();
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new EntityPolarBear.c());
this.goalSelector.a(1, new EntityPolarBear.d());
this.goalSelector.a(4, new PathfinderGoalFollowParent(this, 1.25D));
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 net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new EntityPolarBear.b());
this.targetSelector.a(2, new EntityPolarBear.a());
this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityFox.class, 10, true, true, (Predicate) null));
@@ -112,6 +131,11 @@ public class EntityPolarBear extends EntityAnimal {
--this.bz;
}
+ // Purpur start
+ if (isStanding() && --standTimer <= 0) {
+ setStanding(false);
+ }
+ // Purpur end
}
@Override
@@ -137,11 +161,14 @@ public class EntityPolarBear extends EntityAnimal {
return flag;
}
+ public boolean isStanding() { return er(); } // Purpur - OBFHELPER
public boolean er() {
return (Boolean) this.datawatcher.get(EntityPolarBear.bw);
}
+ public void setStanding(boolean standing) { r(standing); } // Purpur - OBFHELPER
public void r(boolean flag) {
+ standTimer = flag ? 20 : -1; // Purpur
this.datawatcher.set(EntityPolarBear.bw, flag);
}
@@ -160,6 +187,21 @@ public class EntityPolarBear extends EntityAnimal {
return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, (GroupDataEntity) groupdataentity, nbttagcompound);
}
+ // Purpur start
+ private int standTimer = 0;
+
+ @Override
+ public boolean onSpacebar() {
+ if (!isStanding()) {
+ if (hasRider() && getRider().getForward() == 0 && getRider().getStrafe() == 0) {
+ setStanding(true);
+ a(SoundEffects.ENTITY_POLAR_BEAR_WARNING, 1.0F, 1.0F); // playSound
+ }
+ }
+ return false;
+ }
+ // Purpur end
+
class d extends PathfinderGoalPanic {
public d() {
diff --git a/src/main/java/net/minecraft/server/EntityPufferFish.java b/src/main/java/net/minecraft/server/EntityPufferFish.java
index 98af9a223..d0e3e251e 100644
--- a/src/main/java/net/minecraft/server/EntityPufferFish.java
+++ b/src/main/java/net/minecraft/server/EntityPufferFish.java
@@ -17,6 +17,23 @@ public class EntityPufferFish extends EntityFish {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.pufferfishRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.pufferfishRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.pufferfishRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initDatawatcher() {
super.initDatawatcher();
@@ -60,7 +77,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 2ed2d0b6b..9040ab1c5 100644
--- a/src/main/java/net/minecraft/server/EntityRabbit.java
+++ b/src/main/java/net/minecraft/server/EntityRabbit.java
@@ -26,9 +26,27 @@ public class EntityRabbit extends EntityAnimal {
}
// CraftBukkit end
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.rabbitRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.rabbitRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.rabbitRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
- this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalFloat(this)); // Purpur
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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 +59,15 @@ public class EntityRabbit extends EntityAnimal {
}
@Override
- protected float dp() {
+ // 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();
@@ -92,6 +118,7 @@ public class EntityRabbit extends EntityAnimal {
}
+ public void startJumping() { eq(); } // Purpur - OBFHELPER
public void eq() {
this.setJumping(true);
this.bz = 10;
@@ -106,6 +133,12 @@ public class EntityRabbit extends EntityAnimal {
@Override
public void mobTick() {
+ // Purpur start
+ if (hasRider()) {
+ handleJumping();
+ return;
+ }
+ // Purpur end
if (this.bB > 0) {
--this.bB;
}
@@ -156,6 +189,39 @@ public class EntityRabbit extends EntityAnimal {
this.bA = 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 void aE() {}
@@ -472,7 +538,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;
@@ -483,14 +549,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.bq).c()) {
this.i.i(0.0D);
} else if (this.b()) {
this.i.i(this.j);
}
- super.a();
+ super.tick(); // Purpur
}
@Override
@@ -517,14 +583,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 fd25ce102..98d182a4c 100644
--- a/src/main/java/net/minecraft/server/EntityRavager.java
+++ b/src/main/java/net/minecraft/server/EntityRavager.java
@@ -20,14 +20,33 @@ 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 boolean requireShiftToMount() {
+ return world.purpurConfig.ravagerRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
super.initPathfinder();
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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 net.pl3x.purpur.pathfinder.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));
diff --git a/src/main/java/net/minecraft/server/EntitySalmon.java b/src/main/java/net/minecraft/server/EntitySalmon.java
index 6be29f307..189515b0f 100644
--- a/src/main/java/net/minecraft/server/EntitySalmon.java
+++ b/src/main/java/net/minecraft/server/EntitySalmon.java
@@ -6,6 +6,23 @@ public class EntitySalmon extends EntityFishSchool {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.salmonRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.salmonRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.salmonRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
public int es() {
return 5;
diff --git a/src/main/java/net/minecraft/server/EntitySheep.java b/src/main/java/net/minecraft/server/EntitySheep.java
index d5ffdc110..d4f2642d3 100644
--- a/src/main/java/net/minecraft/server/EntitySheep.java
+++ b/src/main/java/net/minecraft/server/EntitySheep.java
@@ -55,10 +55,28 @@ public class EntitySheep extends EntityAnimal {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.sheepRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.sheepRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.sheepRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.bA = new PathfinderGoalEatTile(this);
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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 0d2ceff6f..46379588c 100644
--- a/src/main/java/net/minecraft/server/EntityShulker.java
+++ b/src/main/java/net/minecraft/server/EntityShulker.java
@@ -32,6 +32,23 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.shulkerRequireShiftToMount;
+ }
+ // Purpur end
+
@Nullable
@Override
public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) {
@@ -46,10 +63,12 @@ public class EntityShulker extends EntityGolem implements IMonster {
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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 net.pl3x.purpur.pathfinder.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));
@@ -543,7 +562,7 @@ public class EntityShulker extends EntityGolem implements IMonster {
private int b;
- private e() {}
+ private e() { this.a(EnumSet.of(PathfinderGoal.Type.LOOK)); } // 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 08c2a22f7..dff20567b 100644
--- a/src/main/java/net/minecraft/server/EntitySilverfish.java
+++ b/src/main/java/net/minecraft/server/EntitySilverfish.java
@@ -11,13 +11,32 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.silverfishRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.b = new EntitySilverfish.PathfinderGoalSilverfishWakeOthers(this);
this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(1, new net.pl3x.purpur.pathfinder.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 net.pl3x.purpur.pathfinder.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));
}
@@ -181,6 +200,7 @@ public class EntitySilverfish extends EntityMonster {
public PathfinderGoalSilverfishWakeOthers(EntitySilverfish entitysilverfish) {
this.silverfish = entitysilverfish;
+ this.a(EnumSet.of(PathfinderGoal.Type.TARGET)); // 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 0e78d5c62..8e6efeb7b 100644
--- a/src/main/java/net/minecraft/server/EntitySkeleton.java
+++ b/src/main/java/net/minecraft/server/EntitySkeleton.java
@@ -6,6 +6,23 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.skeletonRequireShiftToMount;
+ }
+ // 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 3c95c0428..8bc4e8515 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 net.pl3x.purpur.pathfinder.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 net.pl3x.purpur.pathfinder.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 2eb53864f..a930fb840 100644
--- a/src/main/java/net/minecraft/server/EntitySkeletonStray.java
+++ b/src/main/java/net/minecraft/server/EntitySkeletonStray.java
@@ -8,6 +8,23 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.strayRequireShiftToMount;
+ }
+ // Purpur end
+
public static boolean b(EntityTypes<EntitySkeletonStray> entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) {
return c(entitytypes, generatoraccess, enummobspawn, blockposition, random) && (enummobspawn == EnumMobSpawn.SPAWNER || generatoraccess.f(blockposition));
}
diff --git a/src/main/java/net/minecraft/server/EntitySkeletonWither.java b/src/main/java/net/minecraft/server/EntitySkeletonWither.java
index 98e042424..8aa0a6699 100644
--- a/src/main/java/net/minecraft/server/EntitySkeletonWither.java
+++ b/src/main/java/net/minecraft/server/EntitySkeletonWither.java
@@ -9,6 +9,23 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.witherSkeletonRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected SoundEffect getSoundAmbient() {
return SoundEffects.ENTITY_WITHER_SKELETON_AMBIENT;
diff --git a/src/main/java/net/minecraft/server/EntitySlime.java b/src/main/java/net/minecraft/server/EntitySlime.java
index 2efc18df9..1469e3b23 100644
--- a/src/main/java/net/minecraft/server/EntitySlime.java
+++ b/src/main/java/net/minecraft/server/EntitySlime.java
@@ -32,12 +32,31 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.slimeRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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 net.pl3x.purpur.pathfinder.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;
}));
@@ -496,10 +515,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;
@@ -521,10 +540,23 @@ public class EntitySlime extends EntityInsentient implements IMonster {
@Override
public void a() {
- this.a.yaw = this.a(this.a.yaw, this.i, 90.0F);
- this.a.aK = this.a.yaw;
- this.a.aI = this.a.yaw;
- if (this.h != ControllerMove.Operation.MOVE_TO) {
+ // Purpur start
+ if (entity.hasRider()) {
+ tick(entity.getRider());
+ if (entity.getForward() != 0 || entity.getStrafe() != 0) {
+ if (getJumpDelay() > 10) {
+ setJumpDelay(6);
+ }
+ } else {
+ setJumpDelay(20);
+ }
+ } else {
+ this.a.yaw = this.a(this.a.yaw, this.i, 90.0F);
+ this.a.aK = this.a.yaw;
+ this.a.aI = this.a.yaw;
+ }
+ if (!entity.hasRider() && this.h != ControllerMove.Operation.MOVE_TO) {
+ // Purpur end
this.a.r(0.0F);
} else {
this.h = ControllerMove.Operation.WAIT;
diff --git a/src/main/java/net/minecraft/server/EntitySnowman.java b/src/main/java/net/minecraft/server/EntitySnowman.java
index 07ca1a498..941873513 100644
--- a/src/main/java/net/minecraft/server/EntitySnowman.java
+++ b/src/main/java/net/minecraft/server/EntitySnowman.java
@@ -14,12 +14,31 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.snowGolemRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.snowGolemRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.snowGolemRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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 net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityInsentient.class, 10, true, false, (entityliving) -> {
return entityliving instanceof IMonster;
}));
@@ -73,6 +92,7 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity {
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) {
@@ -119,7 +139,7 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity {
this.world.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
- return false;
+ return tryRide(entityhuman, enumhand); // Purpur;
}
// CraftBukkit end
this.setHasPumpkin(false);
@@ -130,7 +150,7 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity {
return true;
} else {
- return false;
+ 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 d02db5659..d3708a7b0 100644
--- a/src/main/java/net/minecraft/server/EntitySpider.java
+++ b/src/main/java/net/minecraft/server/EntitySpider.java
@@ -11,14 +11,33 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.spiderRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(1, new net.pl3x.purpur.pathfinder.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 net.pl3x.purpur.pathfinder.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 92efe4e7f..b967135ac 100644
--- a/src/main/java/net/minecraft/server/EntitySquid.java
+++ b/src/main/java/net/minecraft/server/EntitySquid.java
@@ -25,10 +25,28 @@ public class EntitySquid extends EntityWaterAnimal {
this.bC = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.squidRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.squidRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.squidRequireShiftToMount;
+ }
+ // 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 net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
+ this.goalSelector.a(2, new EntitySquid.a()); // Purpur
}
@Override
@@ -175,6 +193,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.bE = f;
this.bF = f1;
@@ -246,7 +265,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;
@@ -259,6 +278,39 @@ 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() * 5F;
+ 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.cL();
if (i > 100) {
@@ -273,5 +325,17 @@ public class EntitySquid extends EntityWaterAnimal {
}
}
+
+ // Purpur start
+ 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
}
}
diff --git a/src/main/java/net/minecraft/server/EntityTameableAnimal.java b/src/main/java/net/minecraft/server/EntityTameableAnimal.java
index 9b2eea71c..d55c6cb33 100644
--- a/src/main/java/net/minecraft/server/EntityTameableAnimal.java
+++ b/src/main/java/net/minecraft/server/EntityTameableAnimal.java
@@ -135,6 +135,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 ef8f373be..992978463 100644
--- a/src/main/java/net/minecraft/server/EntityTropicalFish.java
+++ b/src/main/java/net/minecraft/server/EntityTropicalFish.java
@@ -19,6 +19,23 @@ public class EntityTropicalFish extends EntityFishSchool {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.tropicalFishRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.tropicalFishRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.tropicalFishRequireShiftToMount;
+ }
+ // 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 b24a5100b..469549206 100644
--- a/src/main/java/net/minecraft/server/EntityTurtle.java
+++ b/src/main/java/net/minecraft/server/EntityTurtle.java
@@ -27,6 +27,23 @@ public class EntityTurtle extends EntityAnimal {
this.H = 1.0F;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.turtleRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.turtleRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.turtleRequireShiftToMount;
+ }
+ // Purpur end
+
public final void setHome(BlockPosition pos) { g(pos); } // Paper - OBFHELPER
public void g(BlockPosition blockposition) {
this.datawatcher.set(EntityTurtle.bx, blockposition.immutableCopy()); // Paper - make sure home position can't change
@@ -141,12 +158,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 net.pl3x.purpur.pathfinder.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));
@@ -332,9 +350,9 @@ 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
e(EntityTurtle entityturtle) {
super(entityturtle);
@@ -358,7 +376,86 @@ public class EntityTurtle extends EntityAnimal {
}
@Override
- public void a() {
+ // Purpur start
+ public void tick(EntityHuman rider) {
+ if (getTurtle().isInWater()) {
+ // water controls (from ControllerMoveWASDWater)
+ float forward = rider.getForward() * 0.5F;
+ float strafe = rider.getStrafe() * 0.25F; // 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) {
+ entity.onSpacebar();
+ }
+
+ setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue());
+ entity.setSpeed((float) getSpeed() * 0.1F);
+
+ entity.setForward(forward);
+ entity.setStrafe(strafe);
+ entity.setVertical(vertical * 2F);
+
+ setForward(entity.getForward());
+ setStrafe(entity.getStrafe());
+ } else {
+ // land controls (from ControllerMoveWASD)
+ 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;
+ }
+
+ ((net.pl3x.purpur.controller.ControllerLookWASD) entity.getControllerLook()).setOffsets(yawOffset, 0);
+
+ if (rider.jumping) {
+ //RidableSpacebarEvent event = new RidableSpacebarEvent(entity);
+ if (/*event.callEvent() && !event.isHandled() &&*/ !entity.onSpacebar() && entity.onGround) {
+ entity.jump();
+ }
+ }
+
+ setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue());
+ entity.setSpeed((float) getSpeed() * 0.1F);
+ entity.setForward(forward);
+
+ setForward(entity.getForward());
+ setStrafe(entity.getStrafe());
+ }
+ }
+
+ @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/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java
index 0f04bcc8b..5a7494947 100644
--- a/src/main/java/net/minecraft/server/EntityTypes.java
+++ b/src/main/java/net/minecraft/server/EntityTypes.java
@@ -259,6 +259,12 @@ public class EntityTypes<T extends Entity> {
return this.bb;
}
+ // Purpur start
+ public String getName() {
+ return IRegistry.ENTITY_TYPE.getKey(this).getKey();
+ }
+ // Purpur end
+
public String f() {
if (this.bg == null) {
this.bg = SystemUtils.a("entity", IRegistry.ENTITY_TYPE.getKey(this));
diff --git a/src/main/java/net/minecraft/server/EntityVex.java b/src/main/java/net/minecraft/server/EntityVex.java
index cf274666c..d919f44ab 100644
--- a/src/main/java/net/minecraft/server/EntityVex.java
+++ b/src/main/java/net/minecraft/server/EntityVex.java
@@ -19,6 +19,50 @@ 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 boolean requireShiftToMount() {
+ return world.purpurConfig.vexRequireShiftToMount;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.vexMaxY;
+ }
+
+ @Override
+ public void e(Vec3D vec3d) {
+ super.e(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 +71,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,10 +86,12 @@ public class EntityVex extends EntityMonster {
protected void initPathfinder() {
super.initPathfinder();
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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 net.pl3x.purpur.pathfinder.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));
@@ -56,6 +102,12 @@ public class EntityVex extends EntityMonster {
super.initAttributes();
this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue(14.0D);
this.getAttributeInstance(GenericAttributes.ATTACK_DAMAGE).setValue(4.0D);
+ // Purpur start
+ if (world != null && world.purpurConfig.vexRidable) {
+ this.getAttributeMap().b(GenericAttributes.FLYING_SPEED);
+ this.getAttributeInstance(GenericAttributes.FLYING_SPEED).setValue(0.6000000238418579D);
+ }
+ // Purpur end
}
@Override
@@ -287,14 +339,21 @@ 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() {
+ // Purpur start
+ public void tick(EntityHuman rider) {
+ super.tick(rider);
+ }
+
+ @Override
+ public void tick() {
+ // Purpur end
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 6e0020ae0..3eaac031f 100644
--- a/src/main/java/net/minecraft/server/EntityVillager.java
+++ b/src/main/java/net/minecraft/server/EntityVillager.java
@@ -68,6 +68,28 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
this.bo = this.a(new Dynamic(DynamicOpsNBT.a, new NBTTagCompound()));
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.villagerRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.villagerRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.villagerRequireShiftToMount;
+ }
+
+ @Override
+ protected void initPathfinder() {
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
+ }
+ // Purpur end
+
@Override
public BehaviorController<EntityVillager> getBehaviorController() {
return (BehaviorController<EntityVillager>) super.getBehaviorController(); // CraftBukkit - decompile error
diff --git a/src/main/java/net/minecraft/server/EntityVillagerTrader.java b/src/main/java/net/minecraft/server/EntityVillagerTrader.java
index 2ad8dba5c..4e9c5e84a 100644
--- a/src/main/java/net/minecraft/server/EntityVillagerTrader.java
+++ b/src/main/java/net/minecraft/server/EntityVillagerTrader.java
@@ -20,6 +20,23 @@ public class EntityVillagerTrader extends EntityVillagerAbstract {
this.attachedToPlayer = true;
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.villagerTraderRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.villagerTraderRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.villagerTraderRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.goalSelector.a(0, new PathfinderGoalFloat(this));
@@ -29,6 +46,7 @@ public class EntityVillagerTrader extends EntityVillagerAbstract {
this.goalSelector.a(0, new PathfinderGoalUseItem<>(this, new ItemStack(Items.MILK_BUCKET), SoundEffects.ENTITY_WANDERING_TRADER_REAPPEARED, (entityvillagertrader) -> {
return this.world.isDay() && entityvillagertrader.isInvisible();
}));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(1, new PathfinderGoalTradeWithPlayer(this));
this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityZombie.class, 8.0F, 0.5D, 0.5D));
this.goalSelector.a(1, new PathfinderGoalAvoidTarget<>(this, EntityEvoker.class, 12.0F, 0.5D, 0.5D));
diff --git a/src/main/java/net/minecraft/server/EntityVindicator.java b/src/main/java/net/minecraft/server/EntityVindicator.java
index c974c02e9..6ba920134 100644
--- a/src/main/java/net/minecraft/server/EntityVindicator.java
+++ b/src/main/java/net/minecraft/server/EntityVindicator.java
@@ -17,14 +17,33 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.vindicatorRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
super.initPathfinder();
this.goalSelector.a(0, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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 net.pl3x.purpur.pathfinder.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 1432d3f6b..447387bd7 100644
--- a/src/main/java/net/minecraft/server/EntityWitch.java
+++ b/src/main/java/net/minecraft/server/EntityWitch.java
@@ -24,6 +24,23 @@ 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;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.witchRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
super.initPathfinder();
@@ -31,11 +48,13 @@ public class EntityWitch extends EntityRaider implements IRangedEntity {
return entityliving != null && this.eF() && entityliving.getEntityType() != EntityTypes.WITCH;
});
this.bA = new PathfinderGoalNearestAttackableTargetWitch<>(this, EntityHuman.class, 10, true, false, null); // Purpur - decompile error
- this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(0, new PathfinderGoalFloat(this)); // Purpur
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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 net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, EntityRaider.class)); // Purpur - decompile error
this.targetSelector.a(2, this.bz);
this.targetSelector.a(3, this.bA);
diff --git a/src/main/java/net/minecraft/server/EntityWither.java b/src/main/java/net/minecraft/server/EntityWither.java
index 8977c3516..ad97fe7ea 100644
--- a/src/main/java/net/minecraft/server/EntityWither.java
+++ b/src/main/java/net/minecraft/server/EntityWither.java
@@ -18,7 +18,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
private static final DataWatcherObject<Integer> b = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b);
private static final DataWatcherObject<Integer> c = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b);
private static final DataWatcherObject<Integer> d = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b);
- private static final List<DataWatcherObject<Integer>> bw = ImmutableList.of(EntityWither.b, EntityWither.c, EntityWither.d);
+ private static final List<DataWatcherObject<Integer>> bw = ImmutableList.of(EntityWither.b, EntityWither.c, EntityWither.d); private static List<DataWatcherObject<Integer>> targetList() { return bw; } // Purpur - OBFHELPER
private static final DataWatcherObject<Integer> bx = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b);
private final float[] by = new float[2];
private final float[] bz = new float[2];
@@ -39,15 +39,59 @@ 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 start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.witherRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.witherRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.witherRequireShiftToMount;
+ }
+
+ @Override
+ public double getMaxY() {
+ return world.purpurConfig.witherMaxY;
+ }
+
+ @Override
+ public void e(Vec3D vec3d) {
+ super.e(vec3d);
+ if (hasRider() && !onGround) {
+ float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue();
+ 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) {
+ this.datawatcher.set(targetList().get(0), 0);
+ this.datawatcher.set(targetList().get(1), 0);
+ this.datawatcher.set(targetList().get(2), 0);
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
- this.goalSelector.a(0, new EntityWither.a());
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.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 net.pl3x.purpur.pathfinder.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.bG));
}
@@ -125,7 +169,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
}
this.setMot(vec3d);
- if (b(vec3d) > 0.05D) {
+ if (!hasRider() && b(vec3d) > 0.05D) { // Purpur
this.yaw = (float) MathHelper.d(vec3d.z, vec3d.x) * 57.295776F - 90.0F;
}
@@ -189,6 +233,13 @@ 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);
+ }
+ // Purpur end
+
int i;
if (this.eq() > 0) {
@@ -512,6 +563,12 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.6000000238418579D);
this.getAttributeInstance(GenericAttributes.FOLLOW_RANGE).setValue(40.0D);
this.getAttributeInstance(GenericAttributes.ARMOR).setValue(4.0D);
+ // Purpur start
+ if (world != null && world.purpurConfig.witherRidable) {
+ this.getAttributeMap().b(GenericAttributes.FLYING_SPEED);
+ this.getAttributeInstance(GenericAttributes.FLYING_SPEED).setValue(0.6000000238418579D);
+ }
+ // Purpur end
}
public int eq() {
@@ -523,11 +580,11 @@ public class EntityWither extends EntityMonster implements IRangedEntity {
}
public int getHeadTarget(int i) {
- return (Integer) this.datawatcher.get((DataWatcherObject) EntityWither.bw.get(i));
+ return hasRider() ? 0 : this.datawatcher.get(EntityWither.bw.get(i)); // Purpur
}
public void setHeadTarget(int i, int j) {
- this.datawatcher.set((DataWatcherObject) EntityWither.bw.get(i), j);
+ if (!hasRider()) this.datawatcher.set(EntityWither.bw.get(i), j); // Purpur
}
public boolean J_() {
@@ -541,7 +598,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 eec1e26b6..47f0b2df6 100644
--- a/src/main/java/net/minecraft/server/EntityWolf.java
+++ b/src/main/java/net/minecraft/server/EntityWolf.java
@@ -30,10 +30,28 @@ public class EntityWolf extends EntityTameableAnimal {
this.setTamed(false);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.wolfRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.wolfRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.wolfRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
this.goalSit = new PathfinderGoalSit(this);
this.goalSelector.a(1, new PathfinderGoalFloat(this));
+ this.goalSelector.a(1, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(2, this.goalSit);
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));
@@ -44,6 +62,7 @@ public class EntityWolf extends EntityTameableAnimal {
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 net.pl3x.purpur.pathfinder.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
@@ -274,85 +293,56 @@ public class EntityWolf extends EntityTameableAnimal {
@Override
public boolean a(EntityHuman entityhuman, EnumHand enumhand) {
- ItemStack itemstack = entityhuman.b(enumhand);
+ // Purpur start - rebuild entire method back to 1.14 standards
+ ItemStack itemstack = entityhuman.getItemInHand(enumhand);
Item item = itemstack.getItem();
- if (itemstack.getItem() instanceof ItemMonsterEgg) {
- return super.a(entityhuman, enumhand);
- } else if (this.world.isClientSide) {
- return this.i((EntityLiving) entityhuman) || item == Items.BONE && !this.isAngry();
- } else {
- if (this.isTamed()) {
- if (item.isFood() && item.getFoodInfo().c() && this.getHealth() < this.getMaxHealth()) {
+ if (isTamed()) {
+ if (item.isFood()) {
+ if (item.getFoodInfo().isMeat() && getHealth() < getMaxHealth()) {
if (!entityhuman.abilities.canInstantlyBuild) {
itemstack.subtract(1);
}
-
- this.heal((float) item.getFoodInfo().getNutrition(), org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.EATING); // CraftBukkit
+ heal((float) item.getFoodInfo().getNutrition(), org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.EATING); // CraftBukkit
return true;
}
-
- if (!(item instanceof ItemDye)) {
- boolean flag = super.a(entityhuman, enumhand);
-
- if (!flag || this.isBaby()) {
- //this.goalSit.setSitting(!this.isSitting()); // Paper start - copied from below
- if (this.i((EntityLiving) entityhuman) && !this.i(itemstack)) {
- this.goalSit.setSitting(!this.isSitting());
- this.jumping = false;
- this.navigation.o();
- this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason
- }
- // Paper end - copied from below
- }
-
- return flag;
- }
-
- EnumColor enumcolor = ((ItemDye) item).d();
-
- if (enumcolor != this.getCollarColor()) {
- this.setCollarColor(enumcolor);
+ } else if (item instanceof ItemDye) {
+ EnumColor color = ((ItemDye) item).getDyeColor();
+ if (color != getCollarColor()) {
if (!entityhuman.abilities.canInstantlyBuild) {
itemstack.subtract(1);
}
-
+ setCollarColor(color);
return true;
}
-
- /* Paper start - Move into above
- if (this.i((EntityLiving) entityhuman) && !this.i(itemstack)) {
- this.goalSit.setSitting(!this.isSitting());
- this.jumping = false;
- this.navigation.o();
- this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason
- }
- */ // Paper end
- } else if (item == Items.BONE && !this.isAngry()) {
- if (!entityhuman.abilities.canInstantlyBuild) {
- itemstack.subtract(1);
- }
-
- // CraftBukkit - added event call and isCancelled check.
- if (this.random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) {
- this.tame(entityhuman);
- this.navigation.o();
- this.setGoalTarget((EntityLiving) null);
- this.goalSit.setSitting(true);
- this.world.broadcastEntityEffect(this, (byte) 7);
- } else {
- this.world.broadcastEntityEffect(this, (byte) 6);
- }
-
- return true;
}
-
- return super.a(entityhuman, enumhand);
+ if (isOwner(entityhuman) && !isFood(itemstack)) {
+ goalSit.setSitting(!isSitting());
+ jumping = false;
+ navigation.stopPathfinding();
+ setGoalTarget(null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason
+ }
+ } else if (item == Items.BONE && !isAngry()) {
+ if (!entityhuman.abilities.canInstantlyBuild) {
+ itemstack.subtract(1);
+ }
+ if (random.nextInt(3) == 0 && !CraftEventFactory.callEntityTameEvent(this, entityhuman).isCancelled()) { // CraftBukkit - added event call and isCancelled check.
+ tame(entityhuman);
+ navigation.stopPathfinding();
+ setGoalTarget(null);
+ goalSit.setSitting(true);
+ world.broadcastEntityEffect(this, (byte) 7);
+ } else {
+ world.broadcastEntityEffect(this, (byte) 6);
+ }
+ return true;
}
+ return super.a(entityhuman, enumhand);
+ // Purpur end
}
@Override
- public boolean i(ItemStack itemstack) {
+ public boolean i(ItemStack itemstack) { return isFood(itemstack); } public boolean isFood(ItemStack itemstack) { // Purpur - OBFHELPER
Item item = itemstack.getItem();
return item.isFood() && item.getFoodInfo().c();
@@ -442,6 +432,13 @@ public class EntityWolf extends EntityTameableAnimal {
return !this.isAngry() && super.a(entityhuman);
}
+ // Purpur start
+ public void onMount(EntityHuman entityhuman) {
+ super.onMount(entityhuman);
+ setSitting(false);
+ }
+ // Purpur end
+
class a<T extends EntityLiving> extends PathfinderGoalAvoidTarget<T> {
private final EntityWolf j;
diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java
index 07ebc1d81..8d1f04415 100644
--- a/src/main/java/net/minecraft/server/EntityZombie.java
+++ b/src/main/java/net/minecraft/server/EntityZombie.java
@@ -44,11 +44,30 @@ public class EntityZombie extends EntityMonster {
this(EntityTypes.ZOMBIE, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.zombieRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.zombieRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.zombieRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
+ this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.goalSelector.a(4, new EntityZombie.a(this, 1.0D, 3));
this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F));
this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this));
+ this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur
this.l();
}
diff --git a/src/main/java/net/minecraft/server/EntityZombieHusk.java b/src/main/java/net/minecraft/server/EntityZombieHusk.java
index da8446d05..db252ba4e 100644
--- a/src/main/java/net/minecraft/server/EntityZombieHusk.java
+++ b/src/main/java/net/minecraft/server/EntityZombieHusk.java
@@ -8,6 +8,23 @@ public class EntityZombieHusk extends EntityZombie {
super(entitytypes, world);
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.huskRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.huskRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.huskRequireShiftToMount;
+ }
+ // Purpur end
+
public static boolean b(EntityTypes<EntityZombieHusk> entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) {
return c(entitytypes, generatoraccess, enummobspawn, blockposition, random) && (enummobspawn == EnumMobSpawn.SPAWNER || generatoraccess.f(blockposition));
}
diff --git a/src/main/java/net/minecraft/server/EntityZombieVillager.java b/src/main/java/net/minecraft/server/EntityZombieVillager.java
index 8082fa617..ebbfcb75a 100644
--- a/src/main/java/net/minecraft/server/EntityZombieVillager.java
+++ b/src/main/java/net/minecraft/server/EntityZombieVillager.java
@@ -25,6 +25,23 @@ public class EntityZombieVillager extends EntityZombie implements VillagerDataHo
this.setVillagerData(this.getVillagerData().withProfession((VillagerProfession) IRegistry.VILLAGER_PROFESSION.a(this.random)));
}
+ // Purpur start
+ @Override
+ public boolean isRidable() {
+ return world.purpurConfig.zombieVillagerRidable;
+ }
+
+ @Override
+ public boolean isRidableInWater() {
+ return world.purpurConfig.zombieVillagerRidableInWater;
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return world.purpurConfig.zombieVillagerRequireShiftToMount;
+ }
+ // Purpur end
+
@Override
protected void initDatawatcher() {
super.initDatawatcher();
diff --git a/src/main/java/net/minecraft/server/FoodInfo.java b/src/main/java/net/minecraft/server/FoodInfo.java
index b35fe21a6..5b0f35c73 100644
--- a/src/main/java/net/minecraft/server/FoodInfo.java
+++ b/src/main/java/net/minecraft/server/FoodInfo.java
@@ -30,6 +30,7 @@ public class FoodInfo {
return this.b;
}
+ public boolean isMeat() { return c(); } // Purpur - OBFHELPER
public boolean c() {
return this.c;
}
diff --git a/src/main/java/net/minecraft/server/ItemDye.java b/src/main/java/net/minecraft/server/ItemDye.java
index da49f6e5a..7b5d60264 100644
--- a/src/main/java/net/minecraft/server/ItemDye.java
+++ b/src/main/java/net/minecraft/server/ItemDye.java
@@ -42,6 +42,7 @@ public class ItemDye extends Item {
}
}
+ public EnumColor getDyeColor() { return d(); } // Purpur - OBFHELPER
public EnumColor d() {
return this.b;
}
diff --git a/src/main/java/net/minecraft/server/MathHelper.java b/src/main/java/net/minecraft/server/MathHelper.java
index c4aa38ddf..3d52a396e 100644
--- a/src/main/java/net/minecraft/server/MathHelper.java
+++ b/src/main/java/net/minecraft/server/MathHelper.java
@@ -263,6 +263,7 @@ public class MathHelper {
return (d0 - d1) / (d2 - d1);
}
+ public static double atan2(double d0, double d1) { return d(d0, d1); } // Purpur - OBFHELPER
public static double d(double d0, double d1) {
double d2 = d1 * d1 + d0 * d0;
@@ -407,6 +408,7 @@ public class MathHelper {
return i;
}
+ public static float lerp(float f, float f1, float f2) { return g(f, f1, f2); } // Purpur - OBFHELPER
public static float g(float f, float f1, float f2) {
return f1 + f * (f2 - f1);
}
diff --git a/src/main/java/net/minecraft/server/PathfinderGoal.java b/src/main/java/net/minecraft/server/PathfinderGoal.java
index 134f7d001..d65979673 100644
--- a/src/main/java/net/minecraft/server/PathfinderGoal.java
+++ b/src/main/java/net/minecraft/server/PathfinderGoal.java
@@ -28,6 +28,7 @@ public abstract class PathfinderGoal {
public void e() {}
+ public void setTypes(EnumSet<PathfinderGoal.Type> types) { this.a(types); } // Purpur - OBFHELPER
public void a(EnumSet<PathfinderGoal.Type> enumset) {
// Paper start - remove streams from pathfindergoalselector
this.goalTypes.clear();
diff --git a/src/main/java/net/minecraft/server/PathfinderGoalSwell.java b/src/main/java/net/minecraft/server/PathfinderGoalSwell.java
index e07c7674a..3c077b687 100644
--- a/src/main/java/net/minecraft/server/PathfinderGoalSwell.java
+++ b/src/main/java/net/minecraft/server/PathfinderGoalSwell.java
@@ -4,8 +4,8 @@ import java.util.EnumSet;
public class PathfinderGoalSwell extends PathfinderGoal {
- private final EntityCreeper a;
- private EntityLiving b;
+ private final EntityCreeper a; public EntityCreeper getCreeper() { return a; } // Purpur - OBFHELPER
+ private EntityLiving b; public void setTarget(EntityLiving target) { b = target; } // Purpur - OBFHELPER
public PathfinderGoalSwell(EntityCreeper entitycreeper) {
this.a = entitycreeper;
@@ -32,6 +32,7 @@ public class PathfinderGoalSwell extends PathfinderGoal {
@Override
public void e() {
+ setTarget(getCreeper().getGoalTarget()); // Purpur
if (this.b == null) {
this.a.a(-1);
} else if (this.a.h((Entity) this.b) > 49.0D) {
diff --git a/src/main/java/net/minecraft/server/ProjectileHelper.java b/src/main/java/net/minecraft/server/ProjectileHelper.java
index 1b796ba5b..7dbe3500e 100644
--- a/src/main/java/net/minecraft/server/ProjectileHelper.java
+++ b/src/main/java/net/minecraft/server/ProjectileHelper.java
@@ -15,6 +15,7 @@ public final class ProjectileHelper {
}, entity.getBoundingBox().a(entity.getMot()).g(1.0D));
}
+ public static MovingObjectPosition getHitResult(Entity entity, AxisAlignedBB aabb, Predicate<Entity> predicate, RayTrace.BlockCollisionOption option, boolean flag) { return a(entity, aabb, predicate, option, flag); } // Purpur - OBFHELPER
public static MovingObjectPosition a(Entity entity, AxisAlignedBB axisalignedbb, Predicate<Entity> predicate, RayTrace.BlockCollisionOption raytrace_blockcollisionoption, boolean flag) {
return a(entity, flag, false, (Entity) null, raytrace_blockcollisionoption, false, predicate, axisalignedbb);
}
diff --git a/src/main/java/net/minecraft/server/Vec3D.java b/src/main/java/net/minecraft/server/Vec3D.java
index 0c7f094e5..62a081006 100644
--- a/src/main/java/net/minecraft/server/Vec3D.java
+++ b/src/main/java/net/minecraft/server/Vec3D.java
@@ -27,6 +27,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);
@@ -81,6 +82,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);
}
@@ -89,6 +91,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 67e46376a..d1e316cc4 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -975,6 +975,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
}
}
+ public boolean containsMaterial(AxisAlignedBB aabb, Material mat) { return a(aabb, mat); } // Purpur - OBFHELPER
public boolean a(AxisAlignedBB axisalignedbb, Material material) {
int i = MathHelper.floor(axisalignedbb.minX);
int j = MathHelper.f(axisalignedbb.maxX);
@@ -1610,4 +1611,10 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
@Override public BiomeManager d() {
return this.biomeManager;
}
+
+ // 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/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index eda37fa43..69f99a993 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -64,4 +64,603 @@ public class PurpurWorldConfig {
PurpurConfig.config.addDefault("world-settings.default." + path, def);
return PurpurConfig.config.getString("world-settings." + worldName + "." + path, PurpurConfig.config.getString("world-settings.default." + path));
}
+
+ public boolean batRidable = false;
+ public boolean batRidableInWater = false;
+ public boolean batRequireShiftToMount = true;
+ public double batMaxY = 256D;
+ private void batSettings() {
+ batRidable = getBoolean("mobs.bat.ridable", batRidable);
+ batRidableInWater = getBoolean("mobs.bat.ridable-in-water", batRidableInWater);
+ batRequireShiftToMount = getBoolean("mobs.bat.require-shift-to-mount", batRequireShiftToMount);
+ batMaxY = getDouble("mobs.bat.ridable-max-y", batMaxY);
+ }
+
+ public boolean beeRidable = false;
+ public boolean beeRidableInWater = false;
+ public boolean beeRequireShiftToMount = true;
+ public double beeMaxY = 256D;
+ private void beeSettings() {
+ beeRidable = getBoolean("mobs.bee.ridable", beeRidable);
+ beeRidableInWater = getBoolean("mobs.bee.ridable-in-water", beeRidableInWater);
+ beeRequireShiftToMount = getBoolean("mobs.bee.require-shift-to-mount", beeRequireShiftToMount);
+ beeMaxY = getDouble("mobs.bee.ridable-max-y", beeMaxY);
+ }
+
+ public boolean blazeRidable = false;
+ public boolean blazeRidableInWater = false;
+ public boolean blazeRequireShiftToMount = true;
+ public double blazeMaxY = 256D;
+ private void blazeSettings() {
+ blazeRidable = getBoolean("mobs.blaze.ridable", blazeRidable);
+ blazeRidableInWater = getBoolean("mobs.blaze.ridable-in-water", blazeRidableInWater);
+ blazeRequireShiftToMount = getBoolean("mobs.blaze.require-shift-to-mount", blazeRequireShiftToMount);
+ blazeMaxY = getDouble("mobs.blaze.ridable-max-y", blazeMaxY);
+ }
+
+ public boolean catRidable = false;
+ public boolean catRidableInWater = false;
+ public boolean catRequireShiftToMount = true;
+ private void catSettings() {
+ catRidable = getBoolean("mobs.cat.ridable", catRidable);
+ catRidableInWater = getBoolean("mobs.cat.ridable-in-water", catRidableInWater);
+ catRequireShiftToMount = getBoolean("mobs.cat.require-shift-to-mount", catRequireShiftToMount);
+ }
+
+ public boolean caveSpiderRidable = false;
+ public boolean caveSpiderRidableInWater = false;
+ public boolean caveSpiderRequireShiftToMount = true;
+ private void caveSpiderSettings() {
+ caveSpiderRidable = getBoolean("mobs.cave_spider.ridable", caveSpiderRidable);
+ caveSpiderRidableInWater = getBoolean("mobs.cave_spider.ridable-in-water", caveSpiderRidableInWater);
+ caveSpiderRequireShiftToMount = getBoolean("mobs.cave_spider.require-shift-to-mount", caveSpiderRequireShiftToMount);
+ }
+
+ public boolean chickenRidable = false;
+ public boolean chickenRidableInWater = false;
+ public boolean chickenRequireShiftToMount = true;
+ public boolean chickenDontLayEggsWhenRidden = false;
+ private void chickenSettings() {
+ chickenRidable = getBoolean("mobs.chicken.ridable", chickenRidable);
+ chickenRidableInWater = getBoolean("mobs.chicken.ridable-in-water", chickenRidableInWater);
+ chickenRequireShiftToMount = getBoolean("mobs.chicken.require-shift-to-mount", chickenRequireShiftToMount);
+ chickenDontLayEggsWhenRidden = getBoolean("mobs.chicken.dont-lay-eggs-when-ridden", chickenDontLayEggsWhenRidden);
+ }
+
+ public boolean codRidable = false;
+ public boolean codRidableInWater = false;
+ public boolean codRequireShiftToMount = true;
+ private void codSettings() {
+ codRidable = getBoolean("mobs.cod.ridable", codRidable);
+ codRidableInWater = getBoolean("mobs.cod.ridable-in-water", codRidableInWater);
+ codRequireShiftToMount = getBoolean("mobs.cod.require-shift-to-mount", codRequireShiftToMount);
+ }
+
+ public boolean cowRidable = false;
+ public boolean cowRidableInWater = false;
+ public boolean cowRequireShiftToMount = true;
+ private void cowSettings() {
+ cowRidable = getBoolean("mobs.cow.ridable", cowRidable);
+ cowRidableInWater = getBoolean("mobs.cow.ridable-in-water", cowRidableInWater);
+ cowRequireShiftToMount = getBoolean("mobs.cow.require-shift-to-mount", cowRequireShiftToMount);
+ }
+
+ public boolean creeperRidable = false;
+ public boolean creeperRidableInWater = false;
+ public boolean creeperRequireShiftToMount = true;
+ private void creeperSettings() {
+ creeperRidable = getBoolean("mobs.creeper.ridable", creeperRidable);
+ creeperRidableInWater = getBoolean("mobs.creeper.ridable-in-water", creeperRidableInWater);
+ creeperRequireShiftToMount = getBoolean("mobs.creeper.require-shift-to-mount", creeperRequireShiftToMount);
+ }
+
+ public boolean dolphinRidable = false;
+ public boolean dolphinRidableInWater = false;
+ public boolean dolphinRequireShiftToMount = true;
+ public int dolphinSpitCooldown = 20;
+ public float dolphinSpitSpeed = 1.0F;
+ public float dolphinSpitDamage = 2.0F;
+ private void dolphinSettings() {
+ dolphinRidable = getBoolean("mobs.dolphin.ridable", dolphinRidable);
+ dolphinRidableInWater = getBoolean("mobs.dolphin.ridable-in-water", dolphinRidableInWater);
+ dolphinRequireShiftToMount = getBoolean("mobs.dolphin.require-shift-to-mount", dolphinRequireShiftToMount);
+ dolphinSpitCooldown = getInt("mobs.dolphin.spit.cooldown", dolphinSpitCooldown);
+ dolphinSpitSpeed = (float) getDouble("mobs.dolphin.spit.speed", dolphinSpitSpeed);
+ dolphinSpitDamage = (float) getDouble("mobs.dolphin.spit.damage", dolphinSpitDamage);
+ }
+
+ public boolean donkeyRidableInWater = false;
+ private void donkeySettings() {
+ donkeyRidableInWater = getBoolean("mobs.donkey.ridable-in-water", donkeyRidableInWater);
+ }
+
+ public boolean drownedRidable = false;
+ public boolean drownedRidableInWater = false;
+ public boolean drownedRequireShiftToMount = true;
+ private void drownedSettings() {
+ drownedRidable = getBoolean("mobs.drowned.ridable", drownedRidable);
+ drownedRidableInWater = getBoolean("mobs.drowned.ridable-in-water", drownedRidableInWater);
+ drownedRequireShiftToMount = getBoolean("mobs.drowned.require-shift-to-mount", drownedRequireShiftToMount);
+ }
+
+ public boolean elderGuardianRidable = false;
+ public boolean elderGuardianRidableInWater = false;
+ public boolean elderGuardianRequireShiftToMount = true;
+ private void elderGuardianSettings() {
+ elderGuardianRidable = getBoolean("mobs.elder_guardian.ridable", elderGuardianRidable);
+ elderGuardianRidableInWater = getBoolean("mobs.elder_guardian.ridable-in-water", elderGuardianRidableInWater);
+ elderGuardianRequireShiftToMount = getBoolean("mobs.elder_guardian.require-shift-to-mount", elderGuardianRequireShiftToMount);
+ }
+
+ public boolean enderDragonRidable = false;
+ public boolean enderDragonRidableInWater = false;
+ public boolean enderDragonRequireShiftToMount = true;
+ public double enderDragonMaxY = 256D;
+ private void enderDragonSettings() {
+ enderDragonRidable = getBoolean("mobs.ender_dragon.ridable", enderDragonRidable);
+ enderDragonRidableInWater = getBoolean("mobs.ender_dragon.ridable-in-water", enderDragonRidableInWater);
+ enderDragonRequireShiftToMount = getBoolean("mobs.ender_dragon.require-shift-to-mount", enderDragonRequireShiftToMount);
+ enderDragonMaxY = getDouble("mobs.ender_dragon.ridable-max-y", enderDragonMaxY);
+ }
+
+ public boolean endermanRidable = false;
+ public boolean endermanRidableInWater = false;
+ public boolean endermanRequireShiftToMount = true;
+ private void endermanSettings() {
+ endermanRidable = getBoolean("mobs.enderman.ridable", endermanRidable);
+ endermanRidableInWater = getBoolean("mobs.enderman.ridable-in-water", endermanRidableInWater);
+ endermanRequireShiftToMount = getBoolean("mobs.enderman.require-shift-to-mount", endermanRequireShiftToMount);
+ }
+
+ public boolean endermiteRidable = false;
+ public boolean endermiteRidableInWater = false;
+ public boolean endermiteRequireShiftToMount = true;
+ private void endermiteSettings() {
+ endermiteRidable = getBoolean("mobs.endermite.ridable", endermiteRidable);
+ endermiteRidableInWater = getBoolean("mobs.endermite.ridable-in-water", endermiteRidableInWater);
+ endermiteRequireShiftToMount = getBoolean("mobs.endermite.require-shift-to-mount", endermiteRequireShiftToMount);
+ }
+
+ public boolean evokerRidable = false;
+ public boolean evokerRidableInWater = false;
+ public boolean evokerRequireShiftToMount = true;
+ private void evokerSettings() {
+ evokerRidable = getBoolean("mobs.evoker.ridable", evokerRidable);
+ evokerRidableInWater = getBoolean("mobs.evoker.ridable-in-water", evokerRidableInWater);
+ evokerRequireShiftToMount = getBoolean("mobs.evoker.require-shift-to-mount", evokerRequireShiftToMount);
+ }
+
+ public boolean foxRidable = false;
+ public boolean foxRidableInWater = false;
+ public boolean foxRequireShiftToMount = true;
+ private void foxSettings() {
+ foxRidable = getBoolean("mobs.fox.ridable", foxRidable);
+ foxRidableInWater = getBoolean("mobs.fox.ridable-in-water", foxRidableInWater);
+ foxRequireShiftToMount = getBoolean("mobs.fox.require-shift-to-mount", foxRequireShiftToMount);
+ }
+
+ public boolean ghastRidable = false;
+ public boolean ghastRidableInWater = false;
+ public boolean ghastRequireShiftToMount = true;
+ public double ghastMaxY = 256D;
+ private void ghastSettings() {
+ ghastRidable = getBoolean("mobs.ghast.ridable", ghastRidable);
+ ghastRidableInWater = getBoolean("mobs.ghast.ridable-in-water", ghastRidableInWater);
+ ghastRequireShiftToMount = getBoolean("mobs.ghast.require-shift-to-mount", ghastRequireShiftToMount);
+ ghastMaxY = getDouble("mobs.ghast.ridable-max-y", ghastMaxY);
+ }
+
+ public boolean giantRidable = false;
+ public boolean giantRidableInWater = false;
+ public boolean giantRequireShiftToMount = true;
+ public float giantStepHeight = 2.0F;
+ public float giantJumpHeight = 1.0F;
+ private void giantSettings() {
+ giantRidable = getBoolean("mobs.giant.ridable", giantRidable);
+ giantRidableInWater = getBoolean("mobs.giant.ridable-in-water", giantRidableInWater);
+ giantRequireShiftToMount = getBoolean("mobs.giant.require-shift-to-mount", giantRequireShiftToMount);
+ giantStepHeight = (float) getDouble("mobs.giant.step-height", giantStepHeight);
+ giantJumpHeight = (float) getDouble("mobs.giant.jump-height", giantJumpHeight);
+ }
+
+ public boolean guardianRidable = false;
+ public boolean guardianRidableInWater = false;
+ public boolean guardianRequireShiftToMount = true;
+ private void guardianSettings() {
+ guardianRidable = getBoolean("mobs.guardian.ridable", guardianRidable);
+ guardianRidableInWater = getBoolean("mobs.guardian.ridable-in-water", guardianRidableInWater);
+ guardianRequireShiftToMount = getBoolean("mobs.guardian.require-shift-to-mount", guardianRequireShiftToMount);
+ }
+
+ public boolean huskRidable = false;
+ public boolean huskRidableInWater = false;
+ public boolean huskRequireShiftToMount = true;
+ private void huskSettings() {
+ huskRidable = getBoolean("mobs.husk.ridable", huskRidable);
+ huskRidableInWater = getBoolean("mobs.husk.ridable-in-water", huskRidableInWater);
+ huskRequireShiftToMount = getBoolean("mobs.husk.require-shift-to-mount", huskRequireShiftToMount);
+ }
+
+ public boolean horseRidableInWater = false;
+ private void horseSettings() {
+ horseRidableInWater = getBoolean("mobs.horse.ridable-in-water", horseRidableInWater);
+ }
+
+ public boolean illusionerRidable = false;
+ public boolean illusionerRidableInWater = false;
+ public boolean illusionerRequireShiftToMount = true;
+ private void illusionerSettings() {
+ illusionerRidable = getBoolean("mobs.illusioner.ridable", illusionerRidable);
+ illusionerRidableInWater = getBoolean("mobs.illusioner.ridable-in-water", illusionerRidableInWater);
+ illusionerRequireShiftToMount = getBoolean("mobs.illusioner.require-shift-to-mount", illusionerRequireShiftToMount);
+ }
+
+ public boolean ironGolemRidable = false;
+ public boolean ironGolemRidableInWater = false;
+ public boolean ironGolemRequireShiftToMount = true;
+ private void ironGolemSettings() {
+ ironGolemRidable = getBoolean("mobs.iron_golem.ridable", ironGolemRidable);
+ ironGolemRidableInWater = getBoolean("mobs.iron_golem.ridable-in-water", ironGolemRidableInWater);
+ ironGolemRequireShiftToMount = getBoolean("mobs.iron_golem.require-shift-to-mount", ironGolemRequireShiftToMount);
+ }
+
+ 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;
+ public boolean magmaCubeRequireShiftToMount = true;
+ private void magmaCubeSettings() {
+ magmaCubeRidable = getBoolean("mobs.magma_cube.ridable", magmaCubeRidable);
+ magmaCubeRidableInWater = getBoolean("mobs.magma_cube.ridable-in-water", magmaCubeRidableInWater);
+ magmaCubeRequireShiftToMount = getBoolean("mobs.magma_cube.require-shift-to-mount", magmaCubeRequireShiftToMount);
+ }
+
+ public boolean mooshroomRidable = false;
+ public boolean mooshroomRidableInWater = false;
+ public boolean mooshroomRequireShiftToMount = true;
+ private void mooshroomSettings() {
+ mooshroomRidable = getBoolean("mobs.mooshroom.ridable", mooshroomRidable);
+ mooshroomRidableInWater = getBoolean("mobs.mooshroom.ridable-in-water", mooshroomRidableInWater);
+ mooshroomRequireShiftToMount = getBoolean("mobs.mooshroom.require-shift-to-mount", mooshroomRequireShiftToMount);
+ }
+
+ public boolean muleRidableInWater = false;
+ private void muleSettings() {
+ muleRidableInWater = getBoolean("mobs.mule.ridable-in-water", muleRidableInWater);
+ }
+
+ public boolean ocelotRidable = false;
+ public boolean ocelotRidableInWater = false;
+ public boolean ocelotRequireShiftToMount = true;
+ private void ocelotSettings() {
+ ocelotRidable = getBoolean("mobs.ocelot.ridable", ocelotRidable);
+ ocelotRidableInWater = getBoolean("mobs.ocelot.ridable-in-water", ocelotRidableInWater);
+ ocelotRequireShiftToMount = getBoolean("mobs.ocelot.require-shift-to-mount", ocelotRequireShiftToMount);
+ }
+
+ public boolean pandaRidable = false;
+ public boolean pandaRidableInWater = false;
+ public boolean pandaRequireShiftToMount = true;
+ private void pandaSettings() {
+ pandaRidable = getBoolean("mobs.panda.ridable", pandaRidable);
+ pandaRidableInWater = getBoolean("mobs.panda.ridable-in-water", pandaRidableInWater);
+ pandaRequireShiftToMount = getBoolean("mobs.panda.require-shift-to-mount", pandaRequireShiftToMount);
+ }
+
+ public boolean parrotRidable = false;
+ public boolean parrotRidableInWater = false;
+ public boolean parrotRequireShiftToMount = true;
+ public double parrotMaxY = 256D;
+ private void parrotSettings() {
+ parrotRidable = getBoolean("mobs.parrot.ridable", parrotRidable);
+ parrotRidableInWater = getBoolean("mobs.parrot.ridable-in-water", parrotRidableInWater);
+ parrotRequireShiftToMount = getBoolean("mobs.parrot.require-shift-to-mount", parrotRequireShiftToMount);
+ parrotMaxY = getDouble("mobs.parrot.ridable-max-y", parrotMaxY);
+ }
+
+ public boolean phantomRidable = false;
+ public boolean phantomRidableInWater = false;
+ public boolean phantomRequireShiftToMount = true;
+ public double phantomMaxY = 256D;
+ public float phantomFlameDamage = 1.0F;
+ public int phantomFlameFireTime = 8;
+ private void phantomSettings() {
+ phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable);
+ phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater);
+ phantomRequireShiftToMount = getBoolean("mobs.phantom.require-shift-to-mount", phantomRequireShiftToMount);
+ phantomMaxY = getDouble("mobs.phantom.ridable-max-y", phantomMaxY);
+ phantomFlameDamage = (float) getDouble("mobs.phantom.flames.damage", phantomFlameDamage);
+ phantomFlameFireTime = getInt("mobs.phantom.flames.fire-time", phantomFlameFireTime);
+ }
+
+ public boolean pigRidable = false;
+ public boolean pigRidableInWater = false;
+ private void pigSettings() {
+ pigRidable = getBoolean("mobs.pig.ridable", pigRidable);
+ pigRidableInWater = getBoolean("mobs.pig.ridable-in-water", pigRidableInWater);
+ }
+
+ public boolean pillagerRidable = false;
+ public boolean pillagerRidableInWater = false;
+ public boolean pillagerRequireShiftToMount = true;
+ private void pillagerSettings() {
+ pillagerRidable = getBoolean("mobs.pillager.ridable", pillagerRidable);
+ pillagerRidableInWater = getBoolean("mobs.pillager.ridable-in-water", pillagerRidableInWater);
+ pillagerRequireShiftToMount = getBoolean("mobs.pillager.require-shift-to-mount", pillagerRequireShiftToMount);
+ }
+
+ public boolean polarBearRidable = false;
+ public boolean polarBearRidableInWater = false;
+ public boolean polarBearRequireShiftToMount = true;
+ private void polarBearSettings() {
+ polarBearRidable = getBoolean("mobs.polar_bear.ridable", polarBearRidable);
+ polarBearRidableInWater = getBoolean("mobs.polar_bear.ridable-in-water", polarBearRidableInWater);
+ polarBearRequireShiftToMount = getBoolean("mobs.polar_bear.require-shift-to-mount", polarBearRequireShiftToMount);
+ }
+
+ public boolean pufferfishRidable = false;
+ public boolean pufferfishRidableInWater = false;
+ public boolean pufferfishRequireShiftToMount = true;
+ private void pufferfishSettings() {
+ pufferfishRidable = getBoolean("mobs.pufferfish.ridable", pufferfishRidable);
+ pufferfishRidableInWater = getBoolean("mobs.pufferfish.ridable-in-water", pufferfishRidableInWater);
+ pufferfishRequireShiftToMount = getBoolean("mobs.pufferfish.require-shift-to-mount", pufferfishRequireShiftToMount);
+ }
+
+ public boolean rabbitRidable = false;
+ public boolean rabbitRidableInWater = false;
+ public boolean rabbitRequireShiftToMount = true;
+ private void rabbitSettings() {
+ rabbitRidable = getBoolean("mobs.rabbit.ridable", rabbitRidable);
+ rabbitRidableInWater = getBoolean("mobs.rabbit.ridable-in-water", rabbitRidableInWater);
+ rabbitRequireShiftToMount = getBoolean("mobs.rabbit.require-shift-to-mount", rabbitRequireShiftToMount);
+ }
+
+ public boolean ravagerRidable = false;
+ public boolean ravagerRidableInWater = false;
+ public boolean ravagerRequireShiftToMount = true;
+ private void ravagerSettings() {
+ ravagerRidable = getBoolean("mobs.ravager.ridable", ravagerRidable);
+ ravagerRidableInWater = getBoolean("mobs.ravager.ridable-in-water", ravagerRidableInWater);
+ ravagerRequireShiftToMount = getBoolean("mobs.ravager.require-shift-to-mount", ravagerRequireShiftToMount);
+ }
+
+ public boolean salmonRidable = false;
+ public boolean salmonRidableInWater = false;
+ public boolean salmonRequireShiftToMount = true;
+ private void salmonSettings() {
+ salmonRidable = getBoolean("mobs.salmon.ridable", salmonRidable);
+ salmonRidableInWater = getBoolean("mobs.salmon.ridable-in-water", salmonRidableInWater);
+ salmonRequireShiftToMount = getBoolean("mobs.salmon.require-shift-to-mount", salmonRequireShiftToMount);
+ }
+
+ public boolean sheepRidable = false;
+ public boolean sheepRidableInWater = false;
+ public boolean sheepRequireShiftToMount = true;
+ private void sheepSettings() {
+ sheepRidable = getBoolean("mobs.sheep.ridable", sheepRidable);
+ sheepRidableInWater = getBoolean("mobs.sheep.ridable-in-water", sheepRidableInWater);
+ sheepRequireShiftToMount = getBoolean("mobs.sheep.require-shift-to-mount", sheepRequireShiftToMount);
+ }
+
+ public boolean shulkerRidable = false;
+ public boolean shulkerRidableInWater = false;
+ public boolean shulkerRequireShiftToMount = true;
+ private void shulkerSettings() {
+ shulkerRidable = getBoolean("mobs.shulker.ridable", shulkerRidable);
+ shulkerRidableInWater = getBoolean("mobs.shulker.ridable-in-water", shulkerRidableInWater);
+ shulkerRequireShiftToMount = getBoolean("mobs.shulker.require-shift-to-mount", shulkerRequireShiftToMount);
+ }
+
+ public boolean silverfishRidable = false;
+ public boolean silverfishRidableInWater = false;
+ public boolean silverfishRequireShiftToMount = true;
+ private void silverfishSettings() {
+ silverfishRidable = getBoolean("mobs.silverfish.ridable", silverfishRidable);
+ silverfishRidableInWater = getBoolean("mobs.silverfish.ridable-in-water", silverfishRidableInWater);
+ silverfishRequireShiftToMount = getBoolean("mobs.silverfish.require-shift-to-mount", silverfishRequireShiftToMount);
+ }
+
+ public boolean skeletonRidable = false;
+ public boolean skeletonRidableInWater = false;
+ public boolean skeletonRequireShiftToMount = true;
+ private void skeletonSettings() {
+ skeletonRidable = getBoolean("mobs.skeleton.ridable", skeletonRidable);
+ skeletonRidableInWater = getBoolean("mobs.skeleton.ridable-in-water", skeletonRidableInWater);
+ skeletonRequireShiftToMount = getBoolean("mobs.skeleton.require-shift-to-mount", skeletonRequireShiftToMount);
+ }
+
+ 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;
+ public boolean slimeRequireShiftToMount = true;
+ private void slimeSettings() {
+ slimeRidable = getBoolean("mobs.slime.ridable", slimeRidable);
+ slimeRidableInWater = getBoolean("mobs.slime.ridable-in-water", slimeRidableInWater);
+ slimeRequireShiftToMount = getBoolean("mobs.slime.require-shift-to-mount", slimeRequireShiftToMount);
+ }
+
+ public boolean snowGolemRidable = false;
+ public boolean snowGolemRidableInWater = false;
+ public boolean snowGolemRequireShiftToMount = true;
+ public boolean snowGolemLeaveTrailWhenRidden = false;
+ private void snowGolemSettings() {
+ snowGolemRidable = getBoolean("mobs.snow_golem.ridable", snowGolemRidable);
+ snowGolemRidableInWater = getBoolean("mobs.snow_golem.ridable-in-water", snowGolemRidableInWater);
+ snowGolemRequireShiftToMount = getBoolean("mobs.snow_golem.require-shift-to-mount", snowGolemRequireShiftToMount);
+ snowGolemLeaveTrailWhenRidden = getBoolean("mobs.snow_golem.leave-trail-when-ridden", snowGolemLeaveTrailWhenRidden);
+ }
+
+ public boolean spiderRidable = false;
+ public boolean spiderRidableInWater = false;
+ public boolean spiderRequireShiftToMount = true;
+ private void spiderSettings() {
+ spiderRidable = getBoolean("mobs.spider.ridable", spiderRidable);
+ spiderRidableInWater = getBoolean("mobs.spider.ridable-in-water", spiderRidableInWater);
+ spiderRequireShiftToMount = getBoolean("mobs.spider.require-shift-to-mount", spiderRequireShiftToMount);
+ }
+
+ public boolean squidRidable = false;
+ public boolean squidRidableInWater = false;
+ public boolean squidRequireShiftToMount = true;
+ private void squidSettings() {
+ squidRidable = getBoolean("mobs.squid.ridable", squidRidable);
+ squidRidableInWater = getBoolean("mobs.squid.ridable-in-water", squidRidableInWater);
+ squidRequireShiftToMount = getBoolean("mobs.squid.require-shift-to-mount", squidRequireShiftToMount);
+ }
+
+ public boolean strayRidable = false;
+ public boolean strayRidableInWater = false;
+ public boolean strayRequireShiftToMount = true;
+ private void straySettings() {
+ strayRidable = getBoolean("mobs.stray.ridable", strayRidable);
+ strayRidableInWater = getBoolean("mobs.stray.ridable-in-water", strayRidableInWater);
+ strayRequireShiftToMount = getBoolean("mobs.stray.require-shift-to-mount", strayRequireShiftToMount);
+ }
+
+ public boolean tropicalFishRidable = false;
+ public boolean tropicalFishRidableInWater = false;
+ public boolean tropicalFishRequireShiftToMount = true;
+ private void tropicalFishSettings() {
+ tropicalFishRidable = getBoolean("mobs.tropical_fish.ridable", tropicalFishRidable);
+ tropicalFishRidableInWater = getBoolean("mobs.tropical_fish.ridable-in-water", tropicalFishRidableInWater);
+ tropicalFishRequireShiftToMount = getBoolean("mobs.tropical_fish.require-shift-to-mount", tropicalFishRequireShiftToMount);
+ }
+
+ public boolean turtleRidable = false;
+ public boolean turtleRidableInWater = false;
+ public boolean turtleRequireShiftToMount = true;
+ private void turtleSettings() {
+ turtleRidable = getBoolean("mobs.turtle.ridable", turtleRidable);
+ turtleRidableInWater = getBoolean("mobs.turtle.ridable-in-water", turtleRidableInWater);
+ turtleRequireShiftToMount = getBoolean("mobs.turtle.require-shift-to-mount", turtleRequireShiftToMount);
+ }
+
+ public boolean vexRidable = false;
+ public boolean vexRidableInWater = false;
+ public boolean vexRequireShiftToMount = true;
+ public double vexMaxY = 256D;
+ private void vexSettings() {
+ vexRidable = getBoolean("mobs.vex.ridable", vexRidable);
+ vexRidableInWater = getBoolean("mobs.vex.ridable-in-water", vexRidableInWater);
+ vexRequireShiftToMount = getBoolean("mobs.vex.require-shift-to-mount", vexRequireShiftToMount);
+ vexMaxY = getDouble("mobs.vex.ridable-max-y", vexMaxY);
+ }
+
+ public boolean villagerRidable = false;
+ public boolean villagerRidableInWater = false;
+ public boolean villagerRequireShiftToMount = true;
+ private void villagerSettings() {
+ villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable);
+ villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater);
+ villagerRequireShiftToMount = getBoolean("mobs.villager.require-shift-to-mount", villagerRequireShiftToMount);
+ }
+
+ public boolean villagerTraderRidable = false;
+ public boolean villagerTraderRidableInWater = false;
+ public boolean villagerTraderRequireShiftToMount = true;
+ private void villagerTraderSettings() {
+ villagerTraderRidable = getBoolean("mobs.wandering_trader.ridable", villagerTraderRidable);
+ villagerTraderRidableInWater = getBoolean("mobs.wandering_trader.ridable-in-water", villagerTraderRidableInWater);
+ villagerTraderRequireShiftToMount = getBoolean("mobs.wandering_trader.require-shift-to-mount", villagerTraderRequireShiftToMount);
+ }
+
+ public boolean vindicatorRidable = false;
+ public boolean vindicatorRidableInWater = false;
+ public boolean vindicatorRequireShiftToMount = true;
+ private void vindicatorSettings() {
+ vindicatorRidable = getBoolean("mobs.vindicator.ridable", vindicatorRidable);
+ vindicatorRidableInWater = getBoolean("mobs.vindicator.ridable-in-water", vindicatorRidableInWater);
+ vindicatorRequireShiftToMount = getBoolean("mobs.vindicator.require-shift-to-mount", vindicatorRequireShiftToMount);
+ }
+
+ public boolean witchRidable = false;
+ public boolean witchRidableInWater = false;
+ public boolean witchRequireShiftToMount = true;
+ private void witchSettings() {
+ witchRidable = getBoolean("mobs.witch.ridable", witchRidable);
+ witchRidableInWater = getBoolean("mobs.witch.ridable-in-water", witchRidableInWater);
+ witchRequireShiftToMount = getBoolean("mobs.witch.require-shift-to-mount", witchRequireShiftToMount);
+ }
+
+ public boolean witherRidable = false;
+ public boolean witherRidableInWater = false;
+ public boolean witherRequireShiftToMount = true;
+ public double witherMaxY = 256D;
+ private void witherSettings() {
+ witherRidable = getBoolean("mobs.wither.ridable", witherRidable);
+ witherRidableInWater = getBoolean("mobs.wither.ridable-in-water", witherRidableInWater);
+ witherRequireShiftToMount = getBoolean("mobs.wither.require-shift-to-mount", witherRequireShiftToMount);
+ witherMaxY = getDouble("mobs.wither.ridable-max-y", witherMaxY);
+ }
+
+ public boolean witherSkeletonRidable = false;
+ public boolean witherSkeletonRidableInWater = false;
+ public boolean witherSkeletonRequireShiftToMount = true;
+ private void witherSkeletonSettings() {
+ witherSkeletonRidable = getBoolean("mobs.wither_skeleton.ridable", witherSkeletonRidable);
+ witherSkeletonRidableInWater = getBoolean("mobs.wither_skeleton.ridable-in-water", witherSkeletonRidableInWater);
+ witherSkeletonRequireShiftToMount = getBoolean("mobs.wither_skeleton.require-shift-to-mount", witherSkeletonRequireShiftToMount);
+ }
+
+ public boolean wolfRidable = false;
+ public boolean wolfRidableInWater = false;
+ public boolean wolfRequireShiftToMount = true;
+ private void wolfSettings() {
+ wolfRidable = getBoolean("mobs.wolf.ridable", wolfRidable);
+ wolfRidableInWater = getBoolean("mobs.wolf.ridable-in-water", wolfRidableInWater);
+ wolfRequireShiftToMount = getBoolean("mobs.wolf.require-shift-to-mount", wolfRequireShiftToMount);
+ }
+
+ public boolean zombieRidable = false;
+ public boolean zombieRidableInWater = false;
+ public boolean zombieRequireShiftToMount = true;
+ private void zombieSettings() {
+ zombieRidable = getBoolean("mobs.zombie.ridable", zombieRidable);
+ zombieRidableInWater = getBoolean("mobs.zombie.ridable-in-water", zombieRidableInWater);
+ zombieRequireShiftToMount = getBoolean("mobs.zombie.require-shift-to-mount", zombieRequireShiftToMount);
+ }
+
+ public boolean zombieHorseCanSwim = false;
+ public boolean zombieHorseRidableInWater = false;
+ private void zombieHorseSettings() {
+ zombieHorseCanSwim = getBoolean("mobs.zombie_horse.can-swim", zombieHorseCanSwim);
+ zombieHorseRidableInWater = getBoolean("mobs.zombie_horse.ridable-in-water", zombieHorseRidableInWater);
+ }
+
+ public boolean zombiePigmanRidable = false;
+ public boolean zombiePigmanRidableInWater = false;
+ public boolean zombiePigmanRequireShiftToMount = true;
+ private void zombiePigmanSettings() {
+ zombiePigmanRidable = getBoolean("mobs.zombie_pigman.ridable", zombiePigmanRidable);
+ zombiePigmanRidableInWater = getBoolean("mobs.zombie_pigman.ridable-in-water", zombiePigmanRidableInWater);
+ zombiePigmanRequireShiftToMount = getBoolean("mobs.zombie_pigman.require-shift-to-mount", zombiePigmanRequireShiftToMount);
+ }
+
+ public boolean zombieVillagerRidable = false;
+ public boolean zombieVillagerRidableInWater = false;
+ public boolean zombieVillagerRequireShiftToMount = true;
+ private void zombieVillagerSettings() {
+ zombieVillagerRidable = getBoolean("mobs.zombie_villager.ridable", zombieVillagerRidable);
+ zombieVillagerRidableInWater = getBoolean("mobs.zombie_villager.ridable-in-water", zombieVillagerRidableInWater);
+ zombieVillagerRequireShiftToMount = getBoolean("mobs.zombie_villager.require-shift-to-mount", zombieVillagerRequireShiftToMount);
+ }
}
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 000000000..828e1b873
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/controller/ControllerLookWASD.java
@@ -0,0 +1,75 @@
+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.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 000000000..0a5d6d46c
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASD.java
@@ -0,0 +1,86 @@
+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;
+
+ public ControllerMoveWASD(EntityInsentient entity) {
+ super(entity);
+ this.entity = entity;
+ }
+
+ // 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();
+ }
+ }
+
+ protected void tick() {
+ super.a(); // tick
+ }
+
+ protected 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.doJump();
+ }
+
+ setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue());
+
+ 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 000000000..349125070
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlying.java
@@ -0,0 +1,53 @@
+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;
+
+ public ControllerMoveWASDFlying(EntityInsentient entity) {
+ this(entity, 1.0F);
+ }
+
+ public ControllerMoveWASDFlying(EntityInsentient entity, float groundSpeedModifier) {
+ super(entity);
+ this.groundSpeedModifier = groundSpeedModifier;
+ }
+
+ @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!
+ }
+
+ 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 000000000..f75375936
--- /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 000000000..e75e58067
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java
@@ -0,0 +1,43 @@
+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 {
+ public ControllerMoveWASDWater(EntityInsentient entity) {
+ super(entity);
+ }
+
+ @Override
+ protected 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());
+ entity.setSpeed((float) getSpeed() * 0.1F);
+
+ entity.setForward(forward);
+ entity.setStrafe(strafe);
+ entity.setVertical(vertical);
+
+ 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 000000000..7189cc569
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/entity/DolphinSpit.java
@@ -0,0 +1,119 @@
+package net.pl3x.purpur.entity;
+
+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.IProjectile;
+import net.minecraft.server.Material;
+import net.minecraft.server.MathHelper;
+import net.minecraft.server.MovingObjectPosition;
+import net.minecraft.server.MovingObjectPositionEntity;
+import net.minecraft.server.NBTTagCompound;
+import net.minecraft.server.Packet;
+import net.minecraft.server.PacketPlayOutSpawnEntity;
+import net.minecraft.server.Particles;
+import net.minecraft.server.ProjectileHelper;
+import net.minecraft.server.RayTrace;
+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 implements IProjectile {
+ 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);
+ this.dolphin = dolphin;
+
+ setPosition(dolphin.locX() - (double) (dolphin.getWidth() + 1.0F) * 0.5D * (double) MathHelper.sin(dolphin.getBodyRotation() * ((float) Math.PI / 180F)), dolphin.getHeadY() - (double) 0.1F, dolphin.locZ() + (double) (dolphin.getWidth() + 1.0F) * 0.5D * (double) MathHelper.cos(dolphin.getBodyRotation() * ((float) Math.PI / 180F)));
+ }
+
+ @Override
+ public boolean canSaveToDisk() {
+ return false;
+ }
+
+ @Override
+ public void tick() {
+ setFlag(6, isGlowing());
+ entityBaseTick();
+
+ Vec3D mot = getMot();
+
+ MovingObjectPosition hitResult = ProjectileHelper.getHitResult(this, getBoundingBox().expandTowards(mot).expand(1.0D), (entity) -> !entity.isSpectator() && entity != dolphin && entity != dolphin.getRider(), RayTrace.BlockCollisionOption.OUTLINE, true);
+ if (hitResult != null) {
+ onHit(hitResult);
+ }
+
+ mot = mot.scale(0.99F);
+ setMot(mot);
+ setPosition(locX() + mot.x, locY() + mot.y, locZ() + mot.z);
+
+ 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,
+ 1, 0, 0, 0, 0, true);
+ }
+
+ if (++ticksLived > 20) {
+ die();
+ }
+ }
+
+ @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);
+
+ switch (rayTrace.getType()) {
+ case BLOCK:
+ die();
+ break;
+ case ENTITY:
+ if (dolphin != null) {
+ Entity entity = ((MovingObjectPositionEntity) rayTrace).getEntity();
+ entity.damageEntity(DamageSource.indirectMobAttack(this, dolphin).setProjectile(), world.purpurConfig.dolphinSpitDamage);
+ }
+ die();
+ }
+ }
+
+ @Override
+ public void a(MovingObjectPosition movingobjectposition) {
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ }
+
+ @Override
+ protected void a(NBTTagCompound nbttagcompound) {
+ }
+
+ @Override
+ protected void b(NBTTagCompound nbttagcompound) {
+ }
+
+ @Override
+ public Packet<?> L() {
+ return new PacketPlayOutSpawnEntity(this);
+ }
+}
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 000000000..f9e680efd
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/entity/PhantomFlames.java
@@ -0,0 +1,126 @@
+package net.pl3x.purpur.entity;
+
+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.IProjectile;
+import net.minecraft.server.Material;
+import net.minecraft.server.MathHelper;
+import net.minecraft.server.MovingObjectPosition;
+import net.minecraft.server.MovingObjectPositionEntity;
+import net.minecraft.server.NBTTagCompound;
+import net.minecraft.server.Packet;
+import net.minecraft.server.PacketPlayOutSpawnEntity;
+import net.minecraft.server.Particles;
+import net.minecraft.server.ProjectileHelper;
+import net.minecraft.server.RayTrace;
+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 implements IProjectile {
+ public EntityLiving 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);
+ this.phantom = phantom;
+
+ setPosition(phantom.locX() - (double) (phantom.getWidth() + 1.0F) * 0.5D * (double) MathHelper.sin(phantom.getBodyRotation() * ((float) Math.PI / 180F)), phantom.getHeadY() - (double) 0.1F, phantom.locZ() + (double) (phantom.getWidth() + 1.0F) * 0.5D * (double) MathHelper.cos(phantom.getBodyRotation() * ((float) Math.PI / 180F)));
+ }
+
+ @Override
+ public boolean canSaveToDisk() {
+ return false;
+ }
+
+ @Override
+ public void tick() {
+ setFlag(6, isGlowing());
+ entityBaseTick();
+
+ Vec3D mot = getMot();
+
+ MovingObjectPosition hitResult = ProjectileHelper.getHitResult(this, getBoundingBox().expandTowards(mot).expand(1.0D), (entity) -> !entity.isSpectator() && entity != phantom && entity != phantom.getRider(), RayTrace.BlockCollisionOption.OUTLINE, true);
+ if (hitResult != null) {
+ onHit(hitResult);
+ }
+
+ mot = mot.scale(0.99F);
+ setMot(mot);
+ setPosition(locX() + mot.x, locY() + mot.y, locZ() + mot.z);
+
+ Vec3D m = 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, m.getX(), m.getY(), m.getZ(), 0.1, true);
+ }
+
+ if (!world.containsMaterial(getBoundingBox(), Material.AIR)) {
+ die();
+ }
+ if (++ticksLived > 20) {
+ die();
+ }
+ }
+
+ @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);
+
+ switch (rayTrace.getType()) {
+ case BLOCK:
+ die();
+ break;
+ case ENTITY:
+ if (phantom != null) {
+ Entity entity = ((MovingObjectPositionEntity) rayTrace).getEntity();
+ entity.damageEntity(DamageSource.indirectMobAttack(this, phantom).setProjectile(), world.purpurConfig.phantomFlameDamage);
+ if (world.purpurConfig.phantomFlameFireTime > 0) {
+ entity.setOnFire(world.purpurConfig.phantomFlameFireTime);
+ }
+ }
+ die();
+ }
+ }
+
+ @Override
+ public void a(MovingObjectPosition movingobjectposition) {
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ }
+
+ @Override
+ protected void a(NBTTagCompound nbttagcompound) {
+ }
+
+ @Override
+ protected void b(NBTTagCompound nbttagcompound) {
+ }
+
+ @Override
+ public Packet<?> L() {
+ return new PacketPlayOutSpawnEntity(this);
+ }
+}
diff --git a/src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHasRider.java b/src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHasRider.java
new file mode 100644
index 000000000..6e50344c0
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHasRider.java
@@ -0,0 +1,21 @@
+package net.pl3x.purpur.pathfinder;
+
+import net.minecraft.server.Entity;
+import net.minecraft.server.PathfinderGoal;
+
+import java.util.EnumSet;
+
+public class PathfinderGoalHasRider extends PathfinderGoal {
+ public final Entity entity;
+
+ public PathfinderGoalHasRider(Entity entity) {
+ this.entity = entity;
+ setTypes(EnumSet.of(Type.JUMP, Type.MOVE, Type.LOOK, Type.TARGET));
+ }
+
+ // shouldExecute
+ @Override
+ public boolean a() {
+ return entity.hasRider();
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index dfa15372b..350aa6754 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1057,4 +1057,31 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return getHandle().spawnReason;
}
// 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();
+ }
+
+ @Override
+ public boolean requireShiftToMount() {
+ return getHandle().requireShiftToMount();
+ }
+ // Purpur end
}
diff --git a/src/main/resources/purpur.lang b/src/main/resources/purpur.lang
index 0967ef424..7125c0477 100644
--- a/src/main/resources/purpur.lang
+++ b/src/main/resources/purpur.lang
@@ -1 +1,3 @@
-{}
+{
+ "cannot.ride.mob": "You cannot mount that mob"
+}
--
2.25.0.windows.1