Make phantoms ridable. Make phantoms attracted to end crstals. Make end crystals shoot phantoms

This commit is contained in:
William Blake Galbreath
2019-05-05 19:50:13 -05:00
parent 17ece600dc
commit a4bfd94c63

View File

@@ -1,56 +1,60 @@
From e60b8c7f853e7a4708358f16fc60548e3c542318 Mon Sep 17 00:00:00 2001 From 06a7a4326ebb2250a3adac29b758fcf3bdd8da76 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com> From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Tue, 30 Apr 2019 19:17:21 -0500 Date: Tue, 30 Apr 2019 19:17:21 -0500
Subject: [PATCH] Integrate ridables Subject: [PATCH] Integrate ridables
--- ---
.../java/net/minecraft/server/BiomeBase.java | 26 ++++++- .../java/net/minecraft/server/BiomeBase.java | 26 ++-
.../net/minecraft/server/ControllerJump.java | 1 + .../net/minecraft/server/ControllerJump.java | 1 +
.../server/ControllerLookDolphin.java | 4 +- .../server/ControllerLookDolphin.java | 4 +-
.../java/net/minecraft/server/Entity.java | 16 +++- .../java/net/minecraft/server/Entity.java | 16 +-
.../net/minecraft/server/EntityChicken.java | 17 +++- .../net/minecraft/server/EntityChicken.java | 17 +-
.../java/net/minecraft/server/EntityCow.java | 14 ++++ .../java/net/minecraft/server/EntityCow.java | 14 ++
.../net/minecraft/server/EntityCreeper.java | 14 ++++ .../net/minecraft/server/EntityCreeper.java | 14 ++
.../net/minecraft/server/EntityDolphin.java | 28 ++++++- .../net/minecraft/server/EntityDolphin.java | 28 ++-
.../net/minecraft/server/EntityDrowned.java | 38 ++++++++- .../net/minecraft/server/EntityDrowned.java | 38 +++-
.../net/minecraft/server/EntityEnderman.java | 15 ++++ .../minecraft/server/EntityEnderCrystal.java | 49 +++++
.../net/minecraft/server/EntityEndermite.java | 15 ++++ .../net/minecraft/server/EntityEnderman.java | 15 ++
.../java/net/minecraft/server/EntityFish.java | 28 ++++++- .../net/minecraft/server/EntityEndermite.java | 15 ++
.../minecraft/server/EntityGiantZombie.java | 36 ++++++++- .../java/net/minecraft/server/EntityFish.java | 28 ++-
.../net/minecraft/server/EntityGuardian.java | 36 ++++++++- .../minecraft/server/EntityGiantZombie.java | 36 +++-
.../net/minecraft/server/EntityHorse.java | 10 ++- .../net/minecraft/server/EntityGuardian.java | 36 +++-
.../minecraft/server/EntityHorseAbstract.java | 4 +- .../net/minecraft/server/EntityHorse.java | 10 +-
.../server/EntityHorseChestedAbstract.java | 18 +++-- .../minecraft/server/EntityHorseAbstract.java | 4 +-
.../minecraft/server/EntityHorseDonkey.java | 3 + .../server/EntityHorseChestedAbstract.java | 18 +-
.../net/minecraft/server/EntityHorseMule.java | 3 + .../minecraft/server/EntityHorseDonkey.java | 3 +
.../minecraft/server/EntityHorseSkeleton.java | 15 ++-- .../net/minecraft/server/EntityHorseMule.java | 3 +
.../minecraft/server/EntityHorseZombie.java | 12 +-- .../minecraft/server/EntityHorseSkeleton.java | 15 +-
.../net/minecraft/server/EntityHuman.java | 14 +++- .../minecraft/server/EntityHorseZombie.java | 12 +-
.../minecraft/server/EntityInsentient.java | 39 ++++++++++ .../net/minecraft/server/EntityHuman.java | 14 +-
.../net/minecraft/server/EntityIronGolem.java | 15 ++++ .../minecraft/server/EntityInsentient.java | 39 ++++
.../net/minecraft/server/EntityLiving.java | 21 ++++- .../net/minecraft/server/EntityIronGolem.java | 15 ++
.../net/minecraft/server/EntityLlama.java | 37 ++++++++- .../net/minecraft/server/EntityLiving.java | 21 +-
.../minecraft/server/EntityMushroomCow.java | 14 ++++ .../net/minecraft/server/EntityLlama.java | 37 +++-
.../net/minecraft/server/EntityOcelot.java | 14 ++++ .../minecraft/server/EntityMushroomCow.java | 14 ++
.../java/net/minecraft/server/EntityPig.java | 25 ++++++ .../net/minecraft/server/EntityOcelot.java | 14 ++
.../net/minecraft/server/EntityPolarBear.java | 15 ++++ .../net/minecraft/server/EntityPhantom.java | 203 ++++++++++++++++--
.../net/minecraft/server/EntitySheep.java | 14 ++++ .../java/net/minecraft/server/EntityPig.java | 25 +++
.../minecraft/server/EntitySilverfish.java | 15 ++++ .../net/minecraft/server/EntityPolarBear.java | 15 ++
.../server/EntitySkeletonAbstract.java | 15 ++++ .../net/minecraft/server/EntitySheep.java | 14 ++
.../net/minecraft/server/EntitySnowman.java | 15 ++++ .../minecraft/server/EntitySilverfish.java | 15 ++
.../net/minecraft/server/EntitySpider.java | 15 ++++ .../server/EntitySkeletonAbstract.java | 15 ++
.../net/minecraft/server/EntitySquid.java | 57 ++++++++++++++ .../net/minecraft/server/EntitySnowman.java | 15 ++
.../server/EntityTameableAnimal.java | 6 ++ .../net/minecraft/server/EntitySpider.java | 15 ++
.../net/minecraft/server/EntityTypes.java | 6 ++ .../net/minecraft/server/EntitySquid.java | 57 +++++
.../java/net/minecraft/server/EntityWolf.java | 14 ++++ .../server/EntityTameableAnimal.java | 6 +
.../net/minecraft/server/EntityZombie.java | 15 ++++ .../net/minecraft/server/EntityTypes.java | 6 +
.../purpur/controller/ControllerLookWASD.java | 46 +++++++++++ .../java/net/minecraft/server/EntityWolf.java | 14 ++
.../purpur/controller/ControllerMoveWASD.java | 77 +++++++++++++++++++ .../net/minecraft/server/EntityZombie.java | 15 ++
.../controller/ControllerMoveWASDWater.java | 42 ++++++++++ .../purpur/controller/ControllerLookWASD.java | 46 ++++
.../craftbukkit/entity/CraftLivingEntity.java | 10 +++ .../purpur/controller/ControllerMoveWASD.java | 77 +++++++
44 files changed, 851 insertions(+), 43 deletions(-) .../controller/ControllerMoveWASDFlying.java | 58 +++++
.../controller/ControllerMoveWASDWater.java | 42 ++++
.../craftbukkit/entity/CraftLivingEntity.java | 10 +
47 files changed, 1149 insertions(+), 55 deletions(-)
create mode 100644 src/main/java/net/pl3x/purpur/controller/ControllerLookWASD.java 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/ControllerMoveWASD.java
create mode 100644 src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlying.java
create mode 100644 src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java create mode 100644 src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java
diff --git a/src/main/java/net/minecraft/server/BiomeBase.java b/src/main/java/net/minecraft/server/BiomeBase.java diff --git a/src/main/java/net/minecraft/server/BiomeBase.java b/src/main/java/net/minecraft/server/BiomeBase.java
@@ -420,6 +424,74 @@ index 0e2b5ee7..522f7d61 100644
private boolean dI() { private boolean dI() {
if (this.bC) { if (this.bC) {
return true; return true;
diff --git a/src/main/java/net/minecraft/server/EntityEnderCrystal.java b/src/main/java/net/minecraft/server/EntityEnderCrystal.java
index 79bdb82b..020a0f2d 100644
--- a/src/main/java/net/minecraft/server/EntityEnderCrystal.java
+++ b/src/main/java/net/minecraft/server/EntityEnderCrystal.java
@@ -13,6 +13,12 @@ public class EntityEnderCrystal extends Entity {
private static final DataWatcherObject<Optional<BlockPosition>> b = DataWatcher.a(EntityEnderCrystal.class, DataWatcherRegistry.m);
private static final DataWatcherObject<Boolean> c = DataWatcher.a(EntityEnderCrystal.class, DataWatcherRegistry.i);
public int a;
+ // Purpur start
+ private EntityPhantom targetPhantom;
+ private int phantomBeamTicks = 0;
+ private int phantomDamageCooldown = 0;
+ private int idleCooldown = 0;
+ // Purpur end
public EntityEnderCrystal(World world) {
super(EntityTypes.END_CRYSTAL, world);
@@ -52,7 +58,50 @@ public class EntityEnderCrystal extends Entity {
}
}
+ // Purpur start
+ if (--idleCooldown > 0) {
+ return; // on cooldown
+ }
+
+ if (targetPhantom == null) {
+ for (EntityPhantom phantom : world.a(EntityPhantom.class, getBoundingBox().grow(16, 16, 16))) {
+ if (phantom.hasLineOfSight(this)) {
+ attackPhantom(phantom);
+ break;
+ }
+ }
+ } else {
+ setBeamTarget(new BlockPosition(targetPhantom).add(0, -2, 0));
+ if (--phantomBeamTicks > 0 && targetPhantom.isAlive()) {
+ phantomDamageCooldown--;
+ if (targetPhantom.hasLineOfSight(this)) {
+ if (phantomDamageCooldown <= 0) {
+ phantomDamageCooldown = 20;
+ targetPhantom.damageEntity(DamageSource.c(this, this), 1.0F);
+ }
+ } else {
+ forgetPhantom(); // no longer in sight
+ }
+ } else {
+ forgetPhantom(); // attacked long enough
+ }
+ }
+ }
+
+ private void attackPhantom(EntityPhantom phantom) {
+ phantomDamageCooldown = 0;
+ phantomBeamTicks = 60;
+ targetPhantom = phantom;
+ }
+
+ private void forgetPhantom() {
+ targetPhantom = null;
+ setBeamTarget(null);
+ phantomBeamTicks = 0;
+ phantomDamageCooldown = 0;
+ idleCooldown = 60;
}
+ // Purpur end
protected void b(NBTTagCompound nbttagcompound) {
if (this.getBeamTarget() != null) {
diff --git a/src/main/java/net/minecraft/server/EntityEnderman.java b/src/main/java/net/minecraft/server/EntityEnderman.java diff --git a/src/main/java/net/minecraft/server/EntityEnderman.java b/src/main/java/net/minecraft/server/EntityEnderman.java
index 94504044..7ac728ba 100644 index 94504044..7ac728ba 100644
--- a/src/main/java/net/minecraft/server/EntityEnderman.java --- a/src/main/java/net/minecraft/server/EntityEnderman.java
@@ -1176,6 +1248,315 @@ index 13c84bda..bee1532a 100644
ItemStack itemstack = entityhuman.b(enumhand); ItemStack itemstack = entityhuman.b(enumhand);
if (this.isTamed()) { if (this.isTamed()) {
diff --git a/src/main/java/net/minecraft/server/EntityPhantom.java b/src/main/java/net/minecraft/server/EntityPhantom.java
index f576264a..8a5aed24 100644
--- a/src/main/java/net/minecraft/server/EntityPhantom.java
+++ b/src/main/java/net/minecraft/server/EntityPhantom.java
@@ -1,5 +1,7 @@
package net.minecraft.server;
+import net.pl3x.purpur.controller.ControllerLookWASD;
+
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nullable;
@@ -7,9 +9,10 @@ import javax.annotation.Nullable;
public class EntityPhantom extends EntityFlying implements IMonster {
private static final DataWatcherObject<Integer> a = DataWatcher.a(EntityPhantom.class, DataWatcherRegistry.b);
- private Vec3D b;
- private BlockPosition c;
- private EntityPhantom.AttackPhase bC;
+ private Vec3D b; public Vec3D getOrbitOffset() { return this.b; } public void setOrbitOffset(Vec3D offset) { this.b = offset; } // Purpur - OBFHELPER
+ private BlockPosition c; public BlockPosition getOrbitPosition() { return this.c; } public void setOrbitPosition(BlockPosition position) { this.c = position; } // Purpur - OBFHELPER
+ private EntityPhantom.AttackPhase bC; public AttackPhase getPhase() { return this.bC; } public void setPhase(AttackPhase phase) { this.bC = phase; } // Purpur - OBFHELPER
+ private BlockPosition totemPosition; public BlockPosition getTotemPosition() { return this.totemPosition; } public void setTotemPosition(BlockPosition position) { this.totemPosition = position; } // Purpur
public EntityPhantom(World world) {
super(EntityTypes.PHANTOM, world);
@@ -20,6 +23,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
this.setSize(0.9F, 0.5F);
this.moveController = new EntityPhantom.g(this);
this.lookController = new EntityPhantom.f(this);
+ this.canBeRiddenInWater = false; // Purpur
}
protected EntityAIBodyControl o() {
@@ -27,8 +31,10 @@ public class EntityPhantom extends EntityFlying implements IMonster {
}
protected void n() {
+ this.goalSelector.a(0, new FindTotemGoal(this)); // Purpur
this.goalSelector.a(1, new EntityPhantom.c());
this.goalSelector.a(2, new EntityPhantom.i());
+ this.goalSelector.a(3, new OrbitTotemGoal(this)); // Purpur
this.goalSelector.a(3, new EntityPhantom.e());
this.targetSelector.a(1, new EntityPhantom.b());
}
@@ -103,7 +109,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
}
public void movementTick() {
- if (this.dq()) {
+ if (getRider() == null && this.dq()) { // Purpur - do not set fire if being ridden
this.setOnFire(8);
}
@@ -114,6 +120,25 @@ public class EntityPhantom extends EntityFlying implements IMonster {
super.mobTick();
}
+ // Purpur start
+ @Override
+ protected void a(boolean wasRecentlyHit, int lootingModifier, DamageSource damagesource) { // dropLoot
+ boolean dropped = false;
+ if (killer == null && damagesource.getEntity() instanceof EntityEnderCrystal) {
+ if (random.nextInt(5) < 1) { // 1 out of 5 chance (20%)
+ dropped = a_(new ItemStack(Items.PHANTOM_MEMBRANE)) != null;
+ }
+ }
+ if (!dropped) {
+ super.a(wasRecentlyHit, lootingModifier, damagesource); // dropLoot
+ }
+ }
+
+ public boolean isCirclingTotem() {
+ return totemPosition != null;
+ }
+ // Purpur end
+
public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) {
this.c = (new BlockPosition(this)).up(5);
this.setSize(0);
@@ -188,6 +213,138 @@ public class EntityPhantom extends EntityFlying implements IMonster {
}
// Paper end
+ // Purpur start - processInteract
+ @Override
+ public boolean a(EntityHuman entityhuman, EnumHand enumhand) {
+ if (super.a(entityhuman, enumhand)) {
+ return true; // vanilla action handled
+ }
+ return tryRide(entityhuman, enumhand);
+ }
+
+ class FindTotemGoal extends PathfinderGoal {
+ private final EntityPhantom phantom;
+ private EntityEnderCrystal totem;
+ private PathfinderGoalNearestAttackableTarget.DistanceComparator comparator;
+
+ FindTotemGoal(EntityPhantom phantom) {
+ this.phantom = phantom;
+ comparator = new PathfinderGoalNearestAttackableTarget.DistanceComparator(phantom);
+ }
+
+ @Override
+ public boolean a() { // shouldExecute
+ if (phantom.getRider() != null) {
+ return false;
+ }
+ double range = maxTargetRange();
+ List<EntityEnderCrystal> crystals = world.a(EntityEnderCrystal.class, phantom.getBoundingBox().grow(range, range, range));
+ if (crystals.isEmpty()) {
+ return false;
+ }
+ crystals.sort(comparator);
+ totem = crystals.get(0);
+ if (phantom.h(totem) > range * range) {
+ totem = null;
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean b() { // shouldContinueExecuting
+ if (phantom.getRider() != null) {
+ return false;
+ }
+ if (totem == null || !totem.isAlive()) {
+ return false;
+ }
+ double range = maxTargetRange();
+ return phantom.h(totem) <= (range * range) * 2;
+ }
+
+ @Override
+ public void c() { // startExecuting
+ phantom.setTotemPosition(new BlockPosition(totem).add(0, phantom.getRandom().nextInt(10) + 10, 0));
+ }
+
+ @Override
+ public void d() { // resetTask
+ totem = null;
+ phantom.setTotemPosition(null);
+ super.d();
+ }
+
+ private double maxTargetRange() {
+ AttributeInstance range = phantom.getAttributeInstance(GenericAttributes.FOLLOW_RANGE);
+ return range == null ? 16.0D : range.getValue();
+ }
+ }
+
+ class OrbitTotemGoal extends PathfinderGoal {
+ private final EntityPhantom phantom;
+ private float c;
+ private float radius;
+ private float verticalChange;
+ private float direction;
+
+ OrbitTotemGoal(EntityPhantom phantom) {
+ this.phantom = phantom;
+ a(1);
+ }
+
+ @Override
+ public boolean a() { // shouldExecute
+ return phantom.getRider() == null && phantom.isCirclingTotem();
+ }
+
+ @Override
+ public void c() { // startExecuting
+ this.radius = 5.0F + phantom.random.nextFloat() * 10.0F;
+ this.verticalChange = -4.0F + phantom.random.nextFloat() * 9.0F;
+ this.direction = phantom.random.nextBoolean() ? 1.0F : -1.0F;
+ updateOffset();
+ }
+
+ @Override
+ public void e() { // tick
+ if (phantom.random.nextInt(350) == 0) {
+ this.verticalChange = -4.0F + phantom.random.nextFloat() * 9.0F;
+ }
+ if (phantom.random.nextInt(250) == 0) {
+ ++this.radius;
+ if (this.radius > 15.0F) {
+ this.radius = 5.0F;
+ this.direction = -this.direction;
+ }
+ }
+ if (phantom.random.nextInt(450) == 0) {
+ this.c = phantom.random.nextFloat() * 2.0F * 3.1415927F;
+ updateOffset();
+ }
+ if (phantom.b.c(phantom.locX, phantom.locY, phantom.locZ) < 4.0D) {
+ updateOffset();
+ }
+ if (phantom.b.y < phantom.locY && !phantom.world.isEmpty((new BlockPosition(phantom)).down(1))) {
+ this.verticalChange = Math.max(1.0F, this.verticalChange);
+ updateOffset();
+ }
+ if (phantom.b.y > phantom.locY && !phantom.world.isEmpty((new BlockPosition(phantom)).up(1))) {
+ this.verticalChange = Math.min(-1.0F, this.verticalChange);
+ updateOffset();
+ }
+ }
+
+ private void updateOffset() {
+ this.c += this.direction * 15.0F * 0.017453292F;
+ phantom.setOrbitOffset(new Vec3D(phantom.totemPosition).add(
+ (double) (this.radius * MathHelper.cos(this.c)),
+ (double) (-4.0F + this.verticalChange),
+ (double) (this.radius * MathHelper.sin(this.c))));
+ }
+ }
+ // Purpur end
+
class b extends PathfinderGoal {
private int b;
@@ -237,7 +394,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
private c() {}
public boolean a() {
- return PathfinderGoalTarget.a(EntityPhantom.this, EntityPhantom.this.getGoalTarget(), false, false);
+ return !isCirclingTotem() && PathfinderGoalTarget.a(EntityPhantom.this, EntityPhantom.this.getGoalTarget(), false, false); // Purpur
}
public void c() {
@@ -279,13 +436,13 @@ public class EntityPhantom extends EntityFlying implements IMonster {
}
public boolean a() {
- return EntityPhantom.this.getGoalTarget() != null && EntityPhantom.this.bC == EntityPhantom.AttackPhase.SWOOP;
+ return !isCirclingTotem() && EntityPhantom.this.getGoalTarget() != null && EntityPhantom.this.bC == EntityPhantom.AttackPhase.SWOOP; // Purpur
}
public boolean b() {
EntityLiving entityliving = EntityPhantom.this.getGoalTarget();
- return entityliving == null ? false : (!entityliving.isAlive() ? false : (entityliving instanceof EntityHuman && (((EntityHuman) entityliving).isSpectator() || ((EntityHuman) entityliving).u()) ? false : this.a()));
+ return !isCirclingTotem() && entityliving == null ? false : (!entityliving.isAlive() ? false : (entityliving instanceof EntityHuman && (((EntityHuman) entityliving).isSpectator() || ((EntityHuman) entityliving).u()) ? false : this.a())); // Purpur
}
public void c() {}
@@ -322,7 +479,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
}
public boolean a() {
- return EntityPhantom.this.getGoalTarget() == null || EntityPhantom.this.bC == EntityPhantom.AttackPhase.CIRCLE;
+ return !isCirclingTotem() && (EntityPhantom.this.getGoalTarget() == null || EntityPhantom.this.bC == EntityPhantom.AttackPhase.CIRCLE); // Purpur
}
public void c() {
@@ -387,13 +544,23 @@ public class EntityPhantom extends EntityFlying implements IMonster {
}
}
- class f extends ControllerLook {
+ class f extends ControllerLookWASD { // Purpur
public f(EntityInsentient entityinsentient) {
super(entityinsentient);
}
- public void a() {}
+ // Purpur start
+ @Override
+ public void tick(EntityHuman rider) {
+ setYawPitch(rider.yaw, -rider.pitch * 0.75F);
+ }
+
+ @Override
+ public void tick() {
+ // do nothing
+ }
+ // Purpur end
}
class d extends EntityAIBodyControl {
@@ -408,7 +575,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;
@@ -416,7 +583,19 @@ public class EntityPhantom extends EntityFlying implements IMonster {
super(entityinsentient);
}
- public void a() {
+ // Purpur start
+ @Override
+ 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 diff --git a/src/main/java/net/minecraft/server/EntityPig.java b/src/main/java/net/minecraft/server/EntityPig.java
index d1689dc3..50efffcf 100644 index d1689dc3..50efffcf 100644
--- a/src/main/java/net/minecraft/server/EntityPig.java --- a/src/main/java/net/minecraft/server/EntityPig.java
@@ -1757,6 +2138,70 @@ index 00000000..4f7dec9b
+ g = entity.getStrafe(); + g = entity.getStrafe();
+ } + }
+} +}
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 00000000..197b4951
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlying.java
@@ -0,0 +1,58 @@
+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;
+ private final double maxY;
+ private int tooHighCooldown = 0;
+
+ public ControllerMoveWASDFlying(EntityInsentient entity) {
+ this(entity, 1.0F, 256D);
+ }
+
+ public ControllerMoveWASDFlying(EntityInsentient entity, float groundSpeedModifier, double maxY) {
+ super(entity);
+ this.groundSpeedModifier = groundSpeedModifier;
+ this.maxY = maxY;
+ }
+
+ @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.isJumping()) {
+ //RidableSpacebarEvent event = new RidableSpacebarEvent(ridable);
+ //Bukkit.getPluginManager().callEvent(event);
+ //if (!event.isCancelled() && !event.isHandled()) {
+ entity.onSpacebar();
+ //}
+ }
+
+ if (entity.locY >= maxY || --tooHighCooldown > 0) {
+ tooHighCooldown = 60;
+ entity.motY = -0.05F;
+ vertical = 0.0F;
+ }
+
+ float speed = (float) (e = entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue());
+
+ if (entity.onGround) {
+ speed *= groundSpeedModifier; // TODO = fix this!
+ }
+
+ entity.setNoGravity(forward > 0);
+
+ entity.setSpeed(speed);
+ entity.setVertical(vertical);
+ entity.setStrafe(strafe);
+ entity.setForward(forward);
+
+ f = entity.getForward();
+ g = entity.getStrafe();
+ }
+}
diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java 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 new file mode 100644
index 00000000..74ff4825 index 00000000..74ff4825