From e9e36c5f91db8a630a6e784ddc8f33d8df885405 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath 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 | 22 +- .../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 | 50 +- .../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 + .../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 + .../PathfinderGoalHorseHasRider.java | 21 + .../craftbukkit/entity/CraftEntity.java | 27 + src/main/resources/purpur.lang | 4 +- 100 files changed, 3622 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 create mode 100644 src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHorseHasRider.java diff --git a/src/main/java/net/minecraft/server/AxisAlignedBB.java b/src/main/java/net/minecraft/server/AxisAlignedBB.java index 1a466e929..203c8fe8c 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 cd2c18382..418126197 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 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; @@ -872,6 +872,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; } @@ -1199,6 +1200,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; } @@ -1212,8 +1214,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() { @@ -1344,6 +1347,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); @@ -2179,7 +2183,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 } @@ -2214,6 +2224,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; } @@ -2382,6 +2398,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); } @@ -2600,6 +2617,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() { @@ -3454,4 +3472,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 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 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 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 b = (entityitem) -> { return !entityitem.p() && entityitem.isAlive() && entityitem.isInWater(); }; + private int spitCooldown; // Purpur public EntityDolphin(EntityTypes 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 aecdaacfc..ab1747198 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 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 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..f31cb0554 100644 --- a/src/main/java/net/minecraft/server/EntityHorseAbstract.java +++ b/src/main/java/net/minecraft/server/EntityHorseAbstract.java @@ -38,12 +38,32 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven protected EntityHorseAbstract(EntityTypes 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() { + this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHorseHasRider(this)); // Purpur this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.2D)); this.goalSelector.a(1, new PathfinderGoalTame(this, 1.2D)); this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D, EntityHorseAbstract.class)); @@ -281,7 +301,7 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven return true; } - public boolean eL() { + public boolean eL() { return isSaddled(); } public 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 7df24be46..27cfc6654 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 5aca7a913..cbbbc875b 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 3fc2360a1..58aa2a9a3 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 - 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() { @@ -2098,12 +2098,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); @@ -2111,6 +2111,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; @@ -2329,11 +2330,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..c5f87cbdd 100644 --- a/src/main/java/net/minecraft/server/EntityLlama.java +++ b/src/main/java/net/minecraft/server/EntityLlama.java @@ -16,7 +16,46 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn public EntityLlama(EntityTypes 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,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHorseHasRider(this)); // Purpur this.goalSelector.a(1, new PathfinderGoalTame(this, 1.2D)); this.goalSelector.a(2, new PathfinderGoalLlamaFollow(this, 2.0999999046325684D)); this.goalSelector.a(3, new PathfinderGoalArrowAttack(this, 1.25D, 40, 20.0F)); @@ -67,6 +107,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn this.goalSelector.a(6, new PathfinderGoalRandomStrollLand(this, 0.7D)); this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHorseHasRider(this)); // Purpur this.targetSelector.a(1, new EntityLlama.c(this)); this.targetSelector.a(2, new EntityLlama.a(this)); } @@ -253,6 +294,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 +334,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 8b199971b..53bc31287 100644 --- a/src/main/java/net/minecraft/server/EntityMushroomCow.java +++ b/src/main/java/net/minecraft/server/EntityMushroomCow.java @@ -19,6 +19,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 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 96b4912c4..777bc95ee 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; @@ -245,6 +309,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; @@ -259,6 +324,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; @@ -448,14 +514,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 { @@ -471,7 +546,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; @@ -480,7 +555,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 b37301598..6a7a9dc3d 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -1291,6 +1291,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; @@ -1303,7 +1304,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 f63528ca3..43eefa46c 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 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 dee55c5de..65d746899 100644 --- a/src/main/java/net/minecraft/server/EntitySnowman.java +++ b/src/main/java/net/minecraft/server/EntitySnowman.java @@ -13,12 +13,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; })); @@ -72,6 +91,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) { @@ -115,7 +135,7 @@ public class EntitySnowman extends EntityGolem implements IRangedEntity { if (!this.world.isClientSide) { // CraftBukkit start if (!CraftEventFactory.handlePlayerShearEntityEvent(entityhuman, this, itemstack, enumhand)) { - return false; + return tryRide(entityhuman, enumhand); // Purpur } // CraftBukkit end this.setHasPumpkin(false); @@ -126,7 +146,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 { 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 1094324d0..ee6b133d1 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 getBehaviorController() { return (BehaviorController) 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 2f466af4d..8c1fa3717 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 b = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b); private static final DataWatcherObject c = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b); private static final DataWatcherObject d = DataWatcher.a(EntityWither.class, DataWatcherRegistry.b); - private static final List> bw = ImmutableList.of(EntityWither.b, EntityWither.c, EntityWither.d); + private static final List> bw = ImmutableList.of(EntityWither.b, EntityWither.c, EntityWither.d); private static List> targetList() { return bw; } // Purpur - OBFHELPER private static final DataWatcherObject 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 extends PathfinderGoalAvoidTarget { 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 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/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 predicate, RayTrace.BlockCollisionOption option, boolean flag) { return a(entity, aabb, predicate, option, flag); } // Purpur - OBFHELPER public static MovingObjectPosition a(Entity entity, AxisAlignedBB axisalignedbb, Predicate 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 352cbe6c0..4442f5cc0 100644 --- a/src/main/java/net/minecraft/server/World.java +++ b/src/main/java/net/minecraft/server/World.java @@ -990,6 +990,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); @@ -1625,4 +1626,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 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 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/net/pl3x/purpur/pathfinder/PathfinderGoalHorseHasRider.java b/src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHorseHasRider.java new file mode 100644 index 000000000..9bb9da22a --- /dev/null +++ b/src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHorseHasRider.java @@ -0,0 +1,21 @@ +package net.pl3x.purpur.pathfinder; + +import net.minecraft.server.EntityHorseAbstract; +import net.minecraft.server.PathfinderGoal; + +import java.util.EnumSet; + +public class PathfinderGoalHorseHasRider extends PathfinderGoal { + public final EntityHorseAbstract entity; + + public PathfinderGoalHorseHasRider(EntityHorseAbstract entity) { + this.entity = entity; + setTypes(EnumSet.of(Type.JUMP, Type.MOVE, Type.LOOK, Type.TARGET)); + } + + // shouldExecute + @Override + public boolean a() { + return super.a() && entity.isSaddled(); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index ff60568ce..ef64cfade 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -1059,4 +1059,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.24.0