From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Sun, 5 Jul 2020 22:19:49 -0500 Subject: [PATCH] Ridables diff --git a/src/main/java/net/minecraft/server/ControllerMove.java b/src/main/java/net/minecraft/server/ControllerMove.java index ac6f9d9e5..d874b177b 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/Entity.java b/src/main/java/net/minecraft/server/Entity.java index 2d4981631..d14e4b1ee 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -80,7 +80,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper private CraftEntity bukkitEntity; - PlayerChunkMap.EntityTracker tracker; // Paper + PlayerChunkMap.EntityTracker tracker; public PlayerChunkMap.EntityTracker getTracker() { return tracker; } // Paper // Purpur boolean collisionLoadChunks = false; // Paper Throwable addedToWorldStack; // Paper - entity debug public CraftEntity getBukkitEntity() { @@ -121,7 +121,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke public float lastYaw; public float lastPitch; private AxisAlignedBB boundingBox; - protected boolean onGround; + public boolean onGround; // Purpur - protected -> public public boolean positionChanged; public boolean v; public boolean velocityChanged; @@ -2202,6 +2202,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return this.a(entity, false); } + public boolean startRiding(Entity entity, boolean flag) { return a(entity, flag); } // Purpur - OBFHELPER public boolean a(Entity entity, boolean flag) { for (Entity entity1 = entity; entity1.vehicle != null; entity1 = entity1.vehicle) { if (entity1.vehicle == this) { @@ -2296,7 +2297,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 } @@ -2337,6 +2344,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; } @@ -2728,6 +2741,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 bH() { @@ -3141,6 +3155,18 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return false; } + // Purpur Start + public void sendMessage(String str) { + sendMessage(org.bukkit.craftbukkit.util.CraftChatMessage.fromStringOrNull(str)); + } + + public void sendMessage(IChatBaseComponent ichatbasecomponent) { + if (ichatbasecomponent != null) { + sendMessage(ichatbasecomponent, SystemUtils.getNullUUID()); + } + } + // Purpur end + @Override public void sendMessage(IChatBaseComponent ichatbasecomponent, UUID uuid) {} @@ -3580,4 +3606,39 @@ 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 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/EntityCat.java b/src/main/java/net/minecraft/server/EntityCat.java index 20497c396..cef2787eb 100644 --- a/src/main/java/net/minecraft/server/EntityCat.java +++ b/src/main/java/net/minecraft/server/EntityCat.java @@ -41,6 +41,25 @@ public class EntityCat extends EntityTameableAnimal { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.catRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.catRidableInWater; + } + + public void onMount(EntityHuman entityhuman) { + super.onMount(entityhuman); + setSitting(false); + setSleepingWithOwner(false); + setHeadDown(false); + } + // Purpur end + public MinecraftKey eV() { return (MinecraftKey) EntityCat.bx.getOrDefault(this.getCatType(), EntityCat.bx.get(0)); } @@ -48,7 +67,8 @@ public class EntityCat extends EntityTameableAnimal { @Override protected void initPathfinder() { this.bE = new EntityCat.PathfinderGoalTemptChance(this, 0.6D, EntityCat.by, 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 PathfinderGoalSit(this)); this.goalSelector.a(2, new EntityCat.b(this)); this.goalSelector.a(3, this.bE); @@ -60,6 +80,7 @@ public class EntityCat extends EntityTameableAnimal { this.goalSelector.a(10, new PathfinderGoalBreed(this, 0.8D)); this.goalSelector.a(11, new PathfinderGoalRandomStrollLand(this, 0.8D, 1.0000001E-5F)); this.goalSelector.a(12, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 10.0F)); + this.targetSelector.a(0, new 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.bv)); } @@ -76,6 +97,7 @@ public class EntityCat extends EntityTameableAnimal { this.datawatcher.set(EntityCat.bz, i); } + public void setSleepingWithOwner(boolean flag) { x(flag); } // Purpur - OBFHELPER public void x(boolean flag) { this.datawatcher.set(EntityCat.bA, flag); } @@ -84,6 +106,7 @@ public class EntityCat extends EntityTameableAnimal { return (Boolean) this.datawatcher.get(EntityCat.bA); } + public void setHeadDown(boolean flag) { y(flag); } // Purpur - OBFHELPER public void y(boolean flag) { this.datawatcher.set(EntityCat.bB, flag); } @@ -302,6 +325,7 @@ public class EntityCat extends EntityTameableAnimal { @Override public EnumInteractionResult b(EntityHuman entityhuman, EnumHand enumhand) { + if (hasRider()) return EnumInteractionResult.PASS; // Purpur ItemStack itemstack = entityhuman.b(enumhand); Item item = itemstack.getItem(); @@ -399,6 +423,7 @@ public class EntityCat extends EntityTameableAnimal { public b(EntityCat entitycat) { this.a = entitycat; + this.a(java.util.EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - lay on owner } @Override diff --git a/src/main/java/net/minecraft/server/EntityCaveSpider.java b/src/main/java/net/minecraft/server/EntityCaveSpider.java index 346b77083..eca1cbd7f 100644 --- a/src/main/java/net/minecraft/server/EntityCaveSpider.java +++ b/src/main/java/net/minecraft/server/EntityCaveSpider.java @@ -8,6 +8,18 @@ public class EntityCaveSpider extends EntitySpider { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.caveSpiderRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.caveSpiderRidableInWater; + } + // Purpur end + public static AttributeProvider.Builder m() { return EntitySpider.eL().a(GenericAttributes.MAX_HEALTH, 12.0D); } diff --git a/src/main/java/net/minecraft/server/EntityChicken.java b/src/main/java/net/minecraft/server/EntityChicken.java index 137eada65..e772d90ae 100644 --- a/src/main/java/net/minecraft/server/EntityChicken.java +++ b/src/main/java/net/minecraft/server/EntityChicken.java @@ -18,6 +18,16 @@ public class EntityChicken extends EntityAnimal { } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.chickenRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.chickenRidableInWater; + } + @Override protected void initAttributes(World world) { if (world != null) { @@ -31,6 +41,7 @@ public class EntityChicken extends EntityAnimal { @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur //this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D)); // Purpur - moved down this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, EntityChicken.bC)); @@ -41,6 +52,7 @@ public class EntityChicken extends EntityAnimal { // Purpur start if (world.purpurConfig.chickenRetaliate) { this.goalSelector.a(1, new PathfinderGoalMeleeAttack(this, 1.0D, false)); + this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this)); } else { this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D)); diff --git a/src/main/java/net/minecraft/server/EntityComplexPart.java b/src/main/java/net/minecraft/server/EntityComplexPart.java index 920f4c767..7fec83387 100644 --- a/src/main/java/net/minecraft/server/EntityComplexPart.java +++ b/src/main/java/net/minecraft/server/EntityComplexPart.java @@ -47,4 +47,11 @@ public class EntityComplexPart extends Entity { public EntitySize a(EntityPose entitypose) { return this.d; } + + // Purpur start + @Override + public EnumInteractionResult a(EntityHuman entityhuman, EnumHand enumhand) { + return owner.isAlive() ? owner.tryRide(entityhuman, enumhand) : EnumInteractionResult.PASS; + } + // Purpur end } diff --git a/src/main/java/net/minecraft/server/EntityCow.java b/src/main/java/net/minecraft/server/EntityCow.java index d6baddb9d..69537c627 100644 --- a/src/main/java/net/minecraft/server/EntityCow.java +++ b/src/main/java/net/minecraft/server/EntityCow.java @@ -11,9 +11,22 @@ public class EntityCow extends EntityAnimal { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.cowRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.cowRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new 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)); if (world.purpurConfig.cowFeedMushrooms > 0) this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.25D, RecipeItemStack.a(Items.WHEAT, Blocks.RED_MUSHROOM.getItem(), Blocks.BROWN_MUSHROOM.getItem()), false)); else // Purpur @@ -55,6 +68,7 @@ public class EntityCow extends EntityAnimal { @Override public EnumInteractionResult b(EntityHuman entityhuman, EnumHand enumhand) { + if (hasRider()) return EnumInteractionResult.PASS; // Purpur ItemStack itemstack = entityhuman.b(enumhand); if (itemstack.getItem() == Items.BUCKET && !this.isBaby()) { @@ -62,7 +76,7 @@ public class EntityCow extends EntityAnimal { org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((WorldServer) entityhuman.world, entityhuman, this.getChunkCoordinates(), this.getChunkCoordinates(), null, itemstack, Items.MILK_BUCKET, enumhand); // Paper - add enumHand if (event.isCancelled()) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } // CraftBukkit end @@ -73,7 +87,7 @@ public class EntityCow extends EntityAnimal { return EnumInteractionResult.a(this.world.isClientSide); // Purpur start - feed mushroom to change to mooshroom } else if (world.purpurConfig.cowFeedMushrooms > 0 && getEntityType() != EntityTypes.MOOSHROOM && isMushroom(itemstack)) { - return feedMushroom(entityhuman, itemstack); + return feedMushroom(entityhuman, enumhand, itemstack); // Purpur end } else { return super.b(entityhuman, enumhand); @@ -96,7 +110,7 @@ public class EntityCow extends EntityAnimal { } } - private EnumInteractionResult feedMushroom(EntityHuman entityhuman, ItemStack itemstack) { + private EnumInteractionResult feedMushroom(EntityHuman entityhuman, EnumHand enumhand, ItemStack itemstack) { world.broadcastEntityEffect(this, (byte) 18); // hearts playSound(SoundEffects.ENTITY_COW_MILK, 1.0F, 1.0F); if (incrementFeedCount(itemstack) < world.purpurConfig.cowFeedMushrooms) { @@ -107,7 +121,7 @@ public class EntityCow extends EntityAnimal { } EntityMushroomCow mooshroom = EntityTypes.MOOSHROOM.create(world); if (mooshroom == null) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); } if (itemstack.getItem() == Blocks.BROWN_MUSHROOM.getItem()) { mooshroom.setVariant(EntityMushroomCow.Type.BROWN); @@ -126,10 +140,10 @@ public class EntityCow extends EntityAnimal { mooshroom.setCustomName(this.getCustomName()); } if (CraftEventFactory.callEntityTransformEvent(this, mooshroom, org.bukkit.event.entity.EntityTransformEvent.TransformReason.INFECTION).isCancelled()) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); } if (!new com.destroystokyo.paper.event.entity.EntityTransformedEvent(this.getBukkitEntity(), mooshroom.getBukkitEntity(), com.destroystokyo.paper.event.entity.EntityTransformedEvent.TransformedReason.INFECTED).callEvent()) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); } this.world.addEntity(mooshroom); this.die(); diff --git a/src/main/java/net/minecraft/server/EntityCreeper.java b/src/main/java/net/minecraft/server/EntityCreeper.java index 2d5aab9e2..c387b3f56 100644 --- a/src/main/java/net/minecraft/server/EntityCreeper.java +++ b/src/main/java/net/minecraft/server/EntityCreeper.java @@ -18,12 +18,27 @@ public class EntityCreeper extends EntityMonster { public int maxFuseTicks = 30; public int explosionRadius = 3; private int bz; + // Purpur start + private int spacebarCharge = 0; + private int prevSpacebarCharge = 0; + private int powerToggleDelay = 0; + // Purpur end public EntityCreeper(EntityTypes entitytypes, World world) { super(entitytypes, world); } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.creeperRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.creeperRidableInWater; + } + @Override public GroupDataEntity prepare(GeneratorAccess generatoraccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, GroupDataEntity groupdataentity, NBTTagCompound nbttagcompound) { double chance = generatoraccess.getMinecraftWorld().purpurConfig.creeperChargedChance; @@ -32,18 +47,69 @@ public class EntityCreeper extends EntityMonster { } return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); } + + @Override + protected void mobTick() { + if (powerToggleDelay > 0) { + powerToggleDelay--; + } + if (hasRider()) { + if (getRider().getForward() != 0 || getRider().getStrafe() != 0) { + spacebarCharge = 0; + setIgnited(false); + } + if (spacebarCharge == prevSpacebarCharge) { + spacebarCharge = 0; + } + prevSpacebarCharge = spacebarCharge; + } + super.mobTick(); + } + + @Override + public void onMount(EntityHuman entityhuman) { + super.onMount(entityhuman); + setIgnited(false); + } + + @Override + public boolean onSpacebar() { + if (powerToggleDelay > 0) { + return true; // just toggled power, do not jump or ignite + } + spacebarCharge++; + if (spacebarCharge > maxFuseTicks - 2) { + spacebarCharge = 0; + if (getRider().getBukkitEntity().hasPermission("allow.powered.creeper")) { + powerToggleDelay = 20; + setPowered(!isPowered()); + setIgnited(false); + return true; + } + } + if (!isIgnited()) { + if (hasRider() && getRider().getForward() == 0 && getRider().getStrafe() == 0 && + getRider().getBukkitEntity().hasPermission("allow.special.creeper")) { + setIgnited(true); + return true; + } + } + return getForward() == 0 && getStrafe() == 0; // do not jump if standing still + } // Purpur end @Override protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalFloat(this)); this.goalSelector.a(2, new PathfinderGoalSwell(this)); + this.goalSelector.a(3, new 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])); } @@ -174,6 +240,7 @@ public class EntityCreeper extends EntityMonster { return (Integer) this.datawatcher.get(EntityCreeper.b); } + public void setSwellDirection(int i) { a(i); } // Purpur - OBFHELPER public void a(int i) { this.datawatcher.set(EntityCreeper.b, i); } @@ -274,6 +341,7 @@ public class EntityCreeper extends EntityMonster { com.destroystokyo.paper.event.entity.CreeperIgniteEvent event = new com.destroystokyo.paper.event.entity.CreeperIgniteEvent((org.bukkit.entity.Creeper) getBukkitEntity(), ignited); if (event.callEvent()) { this.datawatcher.set(EntityCreeper.d, event.isIgnited()); + if (!event.isIgnited()) setSwellDirection(-1); // Purpur } } // Paper end diff --git a/src/main/java/net/minecraft/server/EntityDrowned.java b/src/main/java/net/minecraft/server/EntityDrowned.java index 6fc8d1213..7879b70c5 100644 --- a/src/main/java/net/minecraft/server/EntityDrowned.java +++ b/src/main/java/net/minecraft/server/EntityDrowned.java @@ -20,6 +20,16 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.drownedRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.drownedRidableInWater; + } + @Override public boolean jockeyOnlyBaby() { return world.purpurConfig.drownedJockeyOnlyBaby; @@ -217,7 +227,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { this.d = flag; } - static class d extends ControllerMove { + static class d extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur private final EntityDrowned i; @@ -227,7 +237,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { } @Override - public void a() { + public void tick() { // Purpur EntityLiving entityliving = this.i.getGoalTarget(); if (this.i.eX() && this.i.isInWater()) { @@ -260,7 +270,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 } } @@ -399,6 +409,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { this.a = entitydrowned; this.b = d0; this.c = i; + this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - swim up } @Override diff --git a/src/main/java/net/minecraft/server/EntityEnderman.java b/src/main/java/net/minecraft/server/EntityEnderman.java index 245fc38de..a1c6679f0 100644 --- a/src/main/java/net/minecraft/server/EntityEnderman.java +++ b/src/main/java/net/minecraft/server/EntityEnderman.java @@ -30,9 +30,22 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { this.a(PathType.WATER, -1.0F); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.endermanRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.endermanRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new 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)); @@ -40,6 +53,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); this.goalSelector.a(10, new EntityEnderman.PathfinderGoalEndermanPlaceBlock(this)); this.goalSelector.a(11, new EntityEnderman.PathfinderGoalEndermanPickupBlock(this)); + this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, this::b)); this.targetSelector.a(2, new EntityEnderman.PathfinderGoalPlayerWhoLookedAtTarget(this)); this.targetSelector.a(3, new PathfinderGoalHurtByTarget(this, new Class[0])); @@ -221,7 +235,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { @Override protected void mobTick() { - if (this.world.isDay() && this.ticksLived >= this.bz + 600) { + if (!hasRider() && this.world.isDay() && this.ticksLived >= this.bz + 600) { // Purpur - no random teleporting float f = this.aO(); if (f > 0.5F && this.world.f(this.getChunkCoordinates()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper @@ -322,6 +336,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { 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) { if (this.tryEscape(EndermanEscapeEvent.Reason.INDIRECT)) { // Paper start for (int i = 0; i < 64; ++i) { @@ -366,6 +381,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { public PathfinderGoalEndermanPickupBlock(EntityEnderman entityenderman) { this.enderman = entityenderman; + this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur } @Override @@ -410,6 +426,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { public PathfinderGoalEndermanPlaceBlock(EntityEnderman entityenderman) { this.a = entityenderman; + this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur } @Override diff --git a/src/main/java/net/minecraft/server/EntityEndermite.java b/src/main/java/net/minecraft/server/EntityEndermite.java index a85489d56..24d68bbb5 100644 --- a/src/main/java/net/minecraft/server/EntityEndermite.java +++ b/src/main/java/net/minecraft/server/EntityEndermite.java @@ -12,14 +12,28 @@ public class EntityEndermite extends EntityMonster { this.f = 3; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.endermiteRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.endermiteRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new 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(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a()); + 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])); // 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 c37c2930e..843e39239 100644 --- a/src/main/java/net/minecraft/server/EntityEvoker.java +++ b/src/main/java/net/minecraft/server/EntityEvoker.java @@ -12,10 +12,23 @@ public class EntityEvoker extends EntityIllagerWizard { this.f = 10; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.evokerRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.evokerRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new 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 +37,7 @@ public class EntityEvoker extends EntityIllagerWizard { this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D)); this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F)); this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); + this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{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)); @@ -105,6 +119,7 @@ public class EntityEvoker extends EntityIllagerWizard { public d() { super(); + this.a(java.util.EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - wolololo spell } @Override @@ -183,6 +198,7 @@ public class EntityEvoker extends EntityIllagerWizard { private c() { super(); this.e = (new PathfinderTargetCondition()).a(16.0D).c().e().a().b(); + this.a(java.util.EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - summon spell } @Override @@ -237,6 +253,7 @@ public class EntityEvoker extends EntityIllagerWizard { private a() { super(); + this.a(java.util.EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - attack with spell } @Override diff --git a/src/main/java/net/minecraft/server/EntityFish.java b/src/main/java/net/minecraft/server/EntityFish.java index db1ede61c..d1803eca2 100644 --- a/src/main/java/net/minecraft/server/EntityFish.java +++ b/src/main/java/net/minecraft/server/EntityFish.java @@ -75,7 +75,7 @@ public abstract class EntityFish extends EntityWaterAnimal { Predicate predicate = IEntitySelector.g; predicate.getClass(); - pathfindergoalselector.a(2, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 1.6D, 1.4D, predicate::test)); + pathfindergoalselector.a(2, new PathfinderGoalAvoidTarget(this, EntityHuman.class, 8.0F, 1.6D, 1.4D, predicate::test)); // Purpur - decompile error this.goalSelector.a(4, new EntityFish.b(this)); } diff --git a/src/main/java/net/minecraft/server/EntityFox.java b/src/main/java/net/minecraft/server/EntityFox.java index 90b01adbe..26de8c3ad 100644 --- a/src/main/java/net/minecraft/server/EntityFox.java +++ b/src/main/java/net/minecraft/server/EntityFox.java @@ -55,6 +55,39 @@ public class EntityFox extends EntityAnimal { this.setCanPickupLoot(true); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.foxRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.foxRidableInWater; + } + + @Override + public float getJumpHeight() { + return !hasRider() ? super.getJumpHeight() : 0.5F; + } + + @Override + public void onMount(EntityHuman entityhuman) { + super.onMount(entityhuman); + setCanPickupLoot(false); + stopActions(); + setChasing(false); + spit(getEquipment(EnumItemSlot.MAINHAND)); + setSlot(EnumItemSlot.MAINHAND, ItemStack.NULL_ITEM); + } + + @Override + public void onDismount(EntityHuman entityhuman) { + super.onDismount(entityhuman); + setCanPickupLoot(true); + } + // Purpur end + @Override protected void initDatawatcher() { super.initDatawatcher(); @@ -74,6 +107,7 @@ public class EntityFox extends EntityAnimal { return entityliving instanceof EntityFishSchool; }); this.goalSelector.a(0, new EntityFox.g()); + this.goalSelector.a(0, new 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)); @@ -99,6 +133,7 @@ public class EntityFox extends EntityAnimal { this.goalSelector.a(11, new EntityFox.p()); this.goalSelector.a(12, new EntityFox.j(this, EntityHuman.class, 24.0F)); this.goalSelector.a(13, new EntityFox.r()); + this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(3, new EntityFox.a(EntityLiving.class, false, false, (entityliving) -> { return EntityFox.bA.test(entityliving) && !this.c(entityliving.getUniqueID()); })); @@ -386,6 +421,7 @@ public class EntityFox extends EntityAnimal { return itemstack1.isEmpty() || this.bK > 0 && item.isFood() && !itemstack1.getItem().isFood(); } + public void spit(ItemStack itemstack) { m(itemstack); } // Purpur - OBFHELPER private void m(ItemStack itemstack) { if (!itemstack.isEmpty() && !this.world.isClientSide) { EntityItem entityitem = new EntityItem(this.world, this.locX() + this.getLookDirection().x, this.locY() + 1.0D, this.locZ() + this.getLookDirection().z, itemstack); @@ -480,6 +516,7 @@ public class EntityFox extends EntityAnimal { return this.t(16); } + public void setChasing(boolean flag) { u(flag); } // Purpur - OBFHELPER public void u(boolean flag) { this.d(16, flag); } @@ -522,6 +559,7 @@ public class EntityFox extends EntityAnimal { this.setSleeping(false); } + public void stopActions() { fe(); } // Purpur - OBFHELPER private void fe() { this.w(false); this.setCrouching(false); @@ -687,16 +725,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 } } @@ -1365,16 +1403,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.ff()) { - super.a(); + super.tick(); // Purpur } } diff --git a/src/main/java/net/minecraft/server/EntityGiantZombie.java b/src/main/java/net/minecraft/server/EntityGiantZombie.java index 143041003..d7c5a3153 100644 --- a/src/main/java/net/minecraft/server/EntityGiantZombie.java +++ b/src/main/java/net/minecraft/server/EntityGiantZombie.java @@ -11,16 +11,28 @@ public class EntityGiantZombie extends EntityMonster { } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.giantRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.giantRidableInWater; + } + @Override protected void initPathfinder() { if (world.purpurConfig.giantHaveAI) { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D)); this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 16.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0D)); if (world.purpurConfig.giantHaveHostileAI) { this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0D, false)); + this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this).a(EntityPigZombie.class)); this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false)); diff --git a/src/main/java/net/minecraft/server/EntityHoglin.java b/src/main/java/net/minecraft/server/EntityHoglin.java index be8b07a7d..4f98c1d2a 100644 --- a/src/main/java/net/minecraft/server/EntityHoglin.java +++ b/src/main/java/net/minecraft/server/EntityHoglin.java @@ -21,6 +21,18 @@ public class EntityHoglin extends EntityAnimal implements IMonster, IOglin { this.f = 5; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.hoglinRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.hoglinRidableInWater; + } + // Purpur end + @Override public boolean a(EntityHuman entityhuman) { return !this.isLeashed(); @@ -84,6 +96,7 @@ public class EntityHoglin extends EntityAnimal implements IMonster, IOglin { @Override protected void mobTick() { this.world.getMethodProfiler().enter("hoglinBrain"); + if (getRider() == null) // Purpur - only use brain if no rider this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error this.world.getMethodProfiler().exit(); HoglinAI.a(this); diff --git a/src/main/java/net/minecraft/server/EntityHorse.java b/src/main/java/net/minecraft/server/EntityHorse.java index adf414b47..a6c2119be 100644 --- a/src/main/java/net/minecraft/server/EntityHorse.java +++ b/src/main/java/net/minecraft/server/EntityHorse.java @@ -12,6 +12,13 @@ public class EntityHorse extends EntityHorseAbstract { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidableInWater() { + return world.purpurConfig.horseRidableInWater; + } + // Purpur end + @Override protected void eL() { this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue((double) this.fq()); diff --git a/src/main/java/net/minecraft/server/EntityHorseAbstract.java b/src/main/java/net/minecraft/server/EntityHorseAbstract.java index c9ab80ccd..2fa462855 100644 --- a/src/main/java/net/minecraft/server/EntityHorseAbstract.java +++ b/src/main/java/net/minecraft/server/EntityHorseAbstract.java @@ -39,12 +39,27 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven protected EntityHorseAbstract(EntityTypes entitytypes, World world) { super(entitytypes, world); + this.moveController = new ControllerMove(this); // Purpur - use vanilla controller + this.lookController = new ControllerLook(this); // Purpur - use vanilla controller this.G = 1.0F; this.loadChest(); } + // Purpur start + @Override + public boolean isRidable() { + return false; // vanilla handles + } + + @Override + public boolean isRidableInWater() { + return false; + } + // Purpur end + @Override protected void initPathfinder() { + this.goalSelector.a(0, new 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)); @@ -52,6 +67,7 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven this.goalSelector.a(6, new PathfinderGoalRandomStrollLand(this, 0.7D)); this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHorseHasRider(this)); // Purpur this.eW(); } diff --git a/src/main/java/net/minecraft/server/EntityHorseDonkey.java b/src/main/java/net/minecraft/server/EntityHorseDonkey.java index d349e8a34..01672ed63 100644 --- a/src/main/java/net/minecraft/server/EntityHorseDonkey.java +++ b/src/main/java/net/minecraft/server/EntityHorseDonkey.java @@ -8,6 +8,13 @@ public class EntityHorseDonkey extends EntityHorseChestedAbstract { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidableInWater() { + return world.purpurConfig.donkeyRidableInWater; + } + // Purpur end + @Override protected SoundEffect getSoundAmbient() { super.getSoundAmbient(); diff --git a/src/main/java/net/minecraft/server/EntityHorseMule.java b/src/main/java/net/minecraft/server/EntityHorseMule.java index 5105418c4..4d45976d7 100644 --- a/src/main/java/net/minecraft/server/EntityHorseMule.java +++ b/src/main/java/net/minecraft/server/EntityHorseMule.java @@ -8,6 +8,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 43e605f68..ca8f73c75 100644 --- a/src/main/java/net/minecraft/server/EntityHorseSkeleton.java +++ b/src/main/java/net/minecraft/server/EntityHorseSkeleton.java @@ -12,6 +12,18 @@ public class EntityHorseSkeleton extends EntityHorseAbstract { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidableInWater() { + return world.purpurConfig.skeletonHorseRidableInWater; + } + + @Override + public boolean isTamed() { + return true; + } + // Purpur end + public static AttributeProvider.Builder eM() { return fj().a(GenericAttributes.MAX_HEALTH, 15.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.20000000298023224D); } @@ -22,7 +34,7 @@ public class EntityHorseSkeleton extends EntityHorseAbstract { } @Override - protected void eW() {} + protected void eW() { if (world.purpurConfig.skeletonHorseCanSwim) goalSelector.a(0, new PathfinderGoalFloat(this)); } // Purpur @Override protected SoundEffect getSoundAmbient() { @@ -117,7 +129,7 @@ public class EntityHorseSkeleton extends EntityHorseAbstract { @Override public boolean bp() { - return true; + return super.bp(); // Purpur } @Override diff --git a/src/main/java/net/minecraft/server/EntityHorseZombie.java b/src/main/java/net/minecraft/server/EntityHorseZombie.java index 0cbdccf4c..19a21ff98 100644 --- a/src/main/java/net/minecraft/server/EntityHorseZombie.java +++ b/src/main/java/net/minecraft/server/EntityHorseZombie.java @@ -8,6 +8,18 @@ public class EntityHorseZombie extends EntityHorseAbstract { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidableInWater() { + return world.purpurConfig.zombieHorseRidableInWater; + } + + @Override + public boolean isTamed() { + return true; + } + // Purpur end + public static AttributeProvider.Builder eM() { return fj().a(GenericAttributes.MAX_HEALTH, 15.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.20000000298023224D); } @@ -79,5 +91,5 @@ public class EntityHorseZombie extends EntityHorseAbstract { } @Override - protected void eW() {} + protected void eW() { if (world.purpurConfig.zombieHorseCanSwim) goalSelector.a(0, new PathfinderGoalFloat(this)); } // Purpur } diff --git a/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java b/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java index 0e23aa91d..892ba2e59 100644 --- a/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java +++ b/src/main/java/net/minecraft/server/EntityIllagerIllusioner.java @@ -20,6 +20,16 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.illusionerRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.illusionerRidableInWater; + } + @Override protected void initAttributes(World world) { if (world != null) { @@ -34,6 +44,7 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan protected void initPathfinder() { super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new 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()); @@ -41,6 +52,7 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D)); this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F)); this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); + this.targetSelector.a(0, new 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 8def5fbfb..fe6ff7793 100644 --- a/src/main/java/net/minecraft/server/EntityInsentient.java +++ b/src/main/java/net/minecraft/server/EntityInsentient.java @@ -67,8 +67,8 @@ public abstract class EntityInsentient extends EntityLiving { this.bH = -1.0F; this.goalSelector = new PathfinderGoalSelector(world.getMethodProfilerSupplier()); this.targetSelector = new PathfinderGoalSelector(world.getMethodProfilerSupplier()); - this.lookController = new ControllerLook(this); - this.moveController = new ControllerMove(this); + this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASD(this); // Purpur + this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this); // Purpur this.bp = new ControllerJump(this); this.c = this.r(); this.navigation = this.b(world); @@ -520,18 +520,22 @@ public abstract class EntityInsentient extends EntityLiving { return super.do_(); } + public void setForwardSpeed(float speed) { this.q(speed); } // Purpur - OBFHELPER public void q(float f) { this.ba = f; } + public void setVerticalSpeed(float speed) { this.r(speed); } // Purpur - OBFHELPER public void r(float f) { this.aZ = f; } + public void setStrafeSpeed(float speed) { this.s(speed); } // Purpur - OBFHELPER public void s(float f) { this.aY = f; } + public void setSpeed(float speed) { n(speed); } // Purpur - OBFHELPER @Override public void n(float f) { super.n(f); @@ -1200,7 +1204,7 @@ public abstract class EntityInsentient extends EntityLiving { protected void a(EntityHuman entityhuman, EntityInsentient entityinsentient) {} protected EnumInteractionResult b(EntityHuman entityhuman, EnumHand enumhand) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } public boolean ew() { @@ -1559,4 +1563,42 @@ public abstract class EntityInsentient extends EntityLiving { this.world.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit this.unleash(true, false); } + + // Purpur start + public double getMaxY() { + return world.getHeight(); + } + + public EnumInteractionResult tryRide(EntityHuman entityhuman, EnumHand enumhand) { + if (!isRidable()) { + return EnumInteractionResult.PASS; + } + if (enumhand != EnumHand.MAIN_HAND) { + return EnumInteractionResult.PASS; + } + if (entityhuman.isSneaking()) { + return EnumInteractionResult.PASS; + } + if (!passengers.isEmpty() || entityhuman.isPassenger()) { + return EnumInteractionResult.PASS; + } + if (this instanceof EntityTameableAnimal) { + EntityTameableAnimal tameable = (EntityTameableAnimal) this; + if (tameable.isTamed() && !tameable.isOwner(entityhuman)) { + return EnumInteractionResult.PASS; + } + } + if (!entityhuman.getBukkitEntity().hasPermission("allow.ride." + getEntityType().getName())) { + entityhuman.sendMessage(net.pl3x.purpur.PurpurConfig.cannotRideMob); + return EnumInteractionResult.PASS; + } + entityhuman.yaw = this.yaw; + entityhuman.pitch = this.pitch; + if (entityhuman.startRiding(this)) { + return EnumInteractionResult.SUCCESS; + } else { + return EnumInteractionResult.PASS; + } + } + // Purpur end } diff --git a/src/main/java/net/minecraft/server/EntityIronGolem.java b/src/main/java/net/minecraft/server/EntityIronGolem.java index ab0731c2a..2da50ef49 100644 --- a/src/main/java/net/minecraft/server/EntityIronGolem.java +++ b/src/main/java/net/minecraft/server/EntityIronGolem.java @@ -22,9 +22,22 @@ public class EntityIronGolem extends EntityGolem implements IEntityAngerable { this.G = 1.0F; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.ironGolemRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.ironGolemRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { if (world.purpurConfig.ironGolemCanSwim) this.goalSelector.a(0, new PathfinderGoalFloat(this)); // Purpur + this.goalSelector.a(0, new 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, false)); @@ -32,6 +45,7 @@ public class EntityIronGolem extends EntityGolem implements IEntityAngerable { this.goalSelector.a(5, new PathfinderGoalOfferFlower(this)); this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new 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, EntityHuman.class, 10, true, false, this::b)); @@ -201,13 +215,13 @@ public class EntityIronGolem extends EntityGolem implements IEntityAngerable { Item item = itemstack.getItem(); if (item != Items.IRON_INGOT) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } else { float f = this.getHealth(); this.heal(25.0F); if (this.getHealth() == f) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } else { float f1 = 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F; diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java index cb9fdfd11..22b13896d 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -458,7 +458,7 @@ public abstract class EntityLiving extends Entity { @Override public boolean bp() { - return false; + return isRidableInWater(); // Purpur } protected void cT() { @@ -2156,7 +2156,7 @@ public abstract class EntityLiving extends Entity { return 0.42F * this.getBlockJumpFactor(); } - protected void jump() { + public void jump() { // Purpur - protected -> public float f = this.dI(); if (this.hasEffect(MobEffects.JUMP)) { diff --git a/src/main/java/net/minecraft/server/EntityLlama.java b/src/main/java/net/minecraft/server/EntityLlama.java index cf3192085..15efaffe2 100644 --- a/src/main/java/net/minecraft/server/EntityLlama.java +++ b/src/main/java/net/minecraft/server/EntityLlama.java @@ -18,7 +18,46 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn public EntityLlama(EntityTypes entitytypes, World world) { super(entitytypes, world); + // Purpur start + this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASD(this) { + @Override + public void a() { // tick + if (entity.hasRider() && hasSaddle()) { + tick(entity.getRider()); + } else { + tick(); + } + } + }; + this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this) { + @Override + public void a() { // tick + if (entity.hasRider() && hasSaddle()) { + tick(entity.getRider()); + } else { + tick(); + } + } + }; + // Purpur end + } + + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.llamaRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.llamaRidableInWater; + } + + @Override + public boolean hasSaddle() { + return super.hasSaddle() || (isTamed() && getColor() != null); } + // Purpur end public void setStrength(int i) { this.datawatcher.set(EntityLlama.bE, Math.max(1, Math.min(5, i))); @@ -64,6 +103,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)); @@ -73,6 +113,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)); } @@ -310,7 +351,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn } @Nullable - public EnumColor fz() { + public EnumColor fz() { return getColor(); } public EnumColor getColor() { // Purpur - OBFHELPER int i = (Integer) this.datawatcher.get(EntityLlama.bF); 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 11008c432..de8ce2fd3 100644 --- a/src/main/java/net/minecraft/server/EntityLlamaTrader.java +++ b/src/main/java/net/minecraft/server/EntityLlamaTrader.java @@ -11,6 +11,23 @@ public class EntityLlamaTrader extends EntityLlama { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.llamaTraderRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.llamaTraderRidableInWater; + } + + @Override + public boolean hasSaddle() { + return super.hasSaddle() || isTamed(); + } + // Purpur end + @Override protected EntityLlama fA() { return (EntityLlama) EntityTypes.TRADER_LLAMA.a(this.world); diff --git a/src/main/java/net/minecraft/server/EntityMushroomCow.java b/src/main/java/net/minecraft/server/EntityMushroomCow.java index ecbdc65ec..a36e7d182 100644 --- a/src/main/java/net/minecraft/server/EntityMushroomCow.java +++ b/src/main/java/net/minecraft/server/EntityMushroomCow.java @@ -20,6 +20,18 @@ public class EntityMushroomCow extends EntityCow implements IShearable { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.mooshroomRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.mooshroomRidableInWater; + } + // Purpur end + @Override public float a(BlockPosition blockposition, IWorldReader iworldreader) { return iworldreader.getType(blockposition.down()).a(Blocks.MYCELIUM) ? 10.0F : iworldreader.y(blockposition) - 0.5F; @@ -81,7 +93,7 @@ public class EntityMushroomCow extends EntityCow implements IShearable { } else if (itemstack.getItem() == Items.SHEARS && this.canShear()) { // CraftBukkit start if (!CraftEventFactory.handlePlayerShearEntityEvent(entityhuman, this, itemstack, enumhand)) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } // CraftBukkit end this.shear(SoundCategory.PLAYERS); @@ -101,7 +113,7 @@ public class EntityMushroomCow extends EntityCow implements IShearable { Optional> optional = this.l(itemstack); if (!optional.isPresent()) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } Pair pair = (Pair) optional.get(); diff --git a/src/main/java/net/minecraft/server/EntityOcelot.java b/src/main/java/net/minecraft/server/EntityOcelot.java index 9c1f019f9..366acbfd9 100644 --- a/src/main/java/net/minecraft/server/EntityOcelot.java +++ b/src/main/java/net/minecraft/server/EntityOcelot.java @@ -16,6 +16,18 @@ public class EntityOcelot extends EntityAnimal { this.eM(); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.ocelotRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.ocelotRidableInWater; + } + // Purpur end + private boolean isTrusting() { return (Boolean) this.datawatcher.get(EntityOcelot.bw); } @@ -47,12 +59,14 @@ public class EntityOcelot extends EntityAnimal { protected void initPathfinder() { this.by = new EntityOcelot.b(this, 0.6D, EntityOcelot.bv, 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.by); 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.bv)); } diff --git a/src/main/java/net/minecraft/server/EntityPanda.java b/src/main/java/net/minecraft/server/EntityPanda.java index 42df0d74e..a0d00288f 100644 --- a/src/main/java/net/minecraft/server/EntityPanda.java +++ b/src/main/java/net/minecraft/server/EntityPanda.java @@ -46,6 +46,27 @@ public class EntityPanda extends EntityAnimal { } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.pandaRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.pandaRidableInWater; + } + + @Override + public void onMount(EntityHuman entityhuman) { + super.onMount(entityhuman); + this.setForwardSpeed(0.0F); + this.setScared(false); + this.setEating(false); + this.setLayingOnBack(false); + } + // Purpur end + @Override public boolean e(ItemStack itemstack) { EnumItemSlot enumitemslot = EntityInsentient.j(itemstack); @@ -69,6 +90,7 @@ public class EntityPanda extends EntityAnimal { return this.w(8); } + public void setScared(boolean scared) { this.t(scared); } // Purpur - OBFHELPER public void t(boolean flag) { this.d(8, flag); } @@ -77,6 +99,7 @@ public class EntityPanda extends EntityAnimal { return this.w(16); } + public void setLayingOnBack(boolean layingOnBack) { this.u(layingOnBack); } // Purpur - OBFHELPER public void u(boolean flag) { this.d(16, flag); } @@ -85,6 +108,7 @@ public class EntityPanda extends EntityAnimal { return (Integer) this.datawatcher.get(EntityPanda.by) > 0; } + public void setEating(boolean eating) { this.v(eating); } // Purpur - OBFHELPER public void v(boolean flag) { this.datawatcher.set(EntityPanda.by, flag ? 1 : 0); } @@ -201,6 +225,7 @@ public class EntityPanda extends EntityAnimal { @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new 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 +241,7 @@ public class EntityPanda extends EntityAnimal { this.goalSelector.a(12, new EntityPanda.j(this)); this.goalSelector.a(13, new PathfinderGoalFollowParent(this, 1.25D)); this.goalSelector.a(14, new PathfinderGoalRandomStrollLand(this, 1.0D)); + this.targetSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, (new EntityPanda.e(this, new Class[0])).a(new Class[0])); } @@ -537,7 +563,7 @@ public class EntityPanda extends EntityAnimal { ItemStack itemstack = entityhuman.b(enumhand); if (this.fg()) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } else if (this.eO()) { this.u(false); return EnumInteractionResult.a(this.world.isClientSide); @@ -554,7 +580,7 @@ public class EntityPanda extends EntityAnimal { this.g(entityhuman); } else { if (this.world.isClientSide || this.eN() || this.isInWater()) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } this.fu(); @@ -571,7 +597,7 @@ public class EntityPanda extends EntityAnimal { return EnumInteractionResult.SUCCESS; } else { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } } @@ -684,6 +710,7 @@ public class EntityPanda extends EntityAnimal { public f(EntityPanda entitypanda) { this.a = entitypanda; + this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - lay on back } @Override @@ -847,6 +874,7 @@ public class EntityPanda extends EntityAnimal { public l(EntityPanda entitypanda) { this.a = entitypanda; + this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - sneeze } @Override @@ -976,7 +1004,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; @@ -986,9 +1014,9 @@ public class EntityPanda extends EntityAnimal { } @Override - public void a() { + public void tick() { // Purpur if (this.i.fi()) { - super.a(); + super.tick(); // Purpur } } } diff --git a/src/main/java/net/minecraft/server/EntityPig.java b/src/main/java/net/minecraft/server/EntityPig.java index cf2df391a..9bd4cdf13 100644 --- a/src/main/java/net/minecraft/server/EntityPig.java +++ b/src/main/java/net/minecraft/server/EntityPig.java @@ -19,9 +19,22 @@ public class EntityPig extends EntityAnimal implements ISteerable, ISaddleable { this.saddleStorage = new SaddleStorage(this.datawatcher, EntityPig.bw, EntityPig.bv); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.pigRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.pigRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new 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)); diff --git a/src/main/java/net/minecraft/server/EntityPigZombie.java b/src/main/java/net/minecraft/server/EntityPigZombie.java index fdd13b2ba..7f378df36 100644 --- a/src/main/java/net/minecraft/server/EntityPigZombie.java +++ b/src/main/java/net/minecraft/server/EntityPigZombie.java @@ -22,6 +22,16 @@ public class EntityPigZombie extends EntityZombie implements IEntityAngerable { } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.zombifiedPiglinRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.zombifiedPiglinRidableInWater; + } + @Override public boolean jockeyOnlyBaby() { return world.purpurConfig.zombifiedPiglinJockeyOnlyBaby; diff --git a/src/main/java/net/minecraft/server/EntityPiglin.java b/src/main/java/net/minecraft/server/EntityPiglin.java index 63fa1581e..4809a8dce 100644 --- a/src/main/java/net/minecraft/server/EntityPiglin.java +++ b/src/main/java/net/minecraft/server/EntityPiglin.java @@ -31,6 +31,18 @@ public class EntityPiglin extends EntityMonster implements ICrossbow { this.a(PathType.DAMAGE_FIRE, -1.0F); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.piglinRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.piglinRidableInWater; + } + // Purpur end + @Override public void saveData(NBTTagCompound nbttagcompound) { super.saveData(nbttagcompound); @@ -236,6 +248,7 @@ public class EntityPiglin extends EntityMonster implements ICrossbow { @Override protected void mobTick() { this.world.getMethodProfiler().enter("piglinBrain"); + if (getRider() == null) // Purpur - only use brain if no rider this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error this.world.getMethodProfiler().exit(); PiglinAI.b(this); diff --git a/src/main/java/net/minecraft/server/EntityPillager.java b/src/main/java/net/minecraft/server/EntityPillager.java index f73c30ae4..537f09465 100644 --- a/src/main/java/net/minecraft/server/EntityPillager.java +++ b/src/main/java/net/minecraft/server/EntityPillager.java @@ -13,15 +13,29 @@ public class EntityPillager extends EntityIllagerAbstract implements ICrossbow { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.pillagerRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.pillagerRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new 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/EntityPolarBear.java b/src/main/java/net/minecraft/server/EntityPolarBear.java index c26fd0e18..395b39826 100644 --- a/src/main/java/net/minecraft/server/EntityPolarBear.java +++ b/src/main/java/net/minecraft/server/EntityPolarBear.java @@ -16,12 +16,34 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable { private static final IntRange bz = TimeRange.a(20, 39); private int bA; private UUID bB; + private int standTimer = 0; // Purpur public EntityPolarBear(EntityTypes entitytypes, World world) { super(entitytypes, world); } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.polarBearRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.polarBearRidableInWater; + } + + @Override + public boolean onSpacebar() { + if (!isStanding()) { + if (hasRider() && getRider().getForward() == 0 && getRider().getStrafe() == 0) { + setStanding(true); + playSound(SoundEffects.ENTITY_POLAR_BEAR_WARNING, 1.0F, 1.0F); + } + } + return false; + } + @Override public boolean mate(EntityAnimal entityanimal) { if (entityanimal == this) { @@ -59,6 +81,7 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable { protected void initPathfinder() { super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new EntityPolarBear.c()); this.goalSelector.a(1, new EntityPolarBear.d()); // Purpur start @@ -71,6 +94,7 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable { this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 1.0D)); this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new 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, EntityHuman.class, 10, true, false, this::b)); @@ -183,6 +207,11 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable { this.a((WorldServer) this.world, true); } + // Purpur start + if (isStanding() && --standTimer <= 0) { + setStanding(false); + } + // Purpur end } @Override @@ -215,6 +244,7 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable { public void setStanding(boolean standing) { t(standing); } // Purpur - OBFHELPER public void t(boolean flag) { + standTimer = flag ? 20 : -1; // Purpur this.datawatcher.set(EntityPolarBear.bv, flag); } diff --git a/src/main/java/net/minecraft/server/EntityRabbit.java b/src/main/java/net/minecraft/server/EntityRabbit.java index 42145a89c..572ddd663 100644 --- a/src/main/java/net/minecraft/server/EntityRabbit.java +++ b/src/main/java/net/minecraft/server/EntityRabbit.java @@ -60,7 +60,7 @@ public class EntityRabbit extends EntityAnimal { } @Override - protected void jump() { + public void jump() { // Purpur - protected -> public super.jump(); double d0 = this.moveController.c(); diff --git a/src/main/java/net/minecraft/server/EntityRavager.java b/src/main/java/net/minecraft/server/EntityRavager.java index 9734845c1..1e1615d9f 100644 --- a/src/main/java/net/minecraft/server/EntityRavager.java +++ b/src/main/java/net/minecraft/server/EntityRavager.java @@ -20,14 +20,28 @@ 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; + } + // 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/EntitySheep.java b/src/main/java/net/minecraft/server/EntitySheep.java index a5532e49e..e785087d7 100644 --- a/src/main/java/net/minecraft/server/EntitySheep.java +++ b/src/main/java/net/minecraft/server/EntitySheep.java @@ -56,10 +56,23 @@ public class EntitySheep extends EntityAnimal implements IShearable { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.sheepRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.sheepRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.bz = 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 afc4cf496..0456236b4 100644 --- a/src/main/java/net/minecraft/server/EntityShulker.java +++ b/src/main/java/net/minecraft/server/EntityShulker.java @@ -29,12 +29,26 @@ public class EntityShulker extends EntityGolem implements IMonster { this.f = 5; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.shulkerRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.shulkerRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { + this.goalSelector.a(0, new 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)); @@ -519,7 +533,7 @@ public class EntityShulker extends EntityGolem implements IMonster { private int b; - private e() {} + private e() { this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); } // Purpur - peek @Override public boolean a() { diff --git a/src/main/java/net/minecraft/server/EntitySilverfish.java b/src/main/java/net/minecraft/server/EntitySilverfish.java index 29c0a9c36..730b2eb33 100644 --- a/src/main/java/net/minecraft/server/EntitySilverfish.java +++ b/src/main/java/net/minecraft/server/EntitySilverfish.java @@ -11,13 +11,27 @@ public class EntitySilverfish extends EntityMonster { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.silverfishRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.silverfishRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.b = new EntitySilverfish.PathfinderGoalSilverfishWakeOthers(this); this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new 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)); } @@ -177,6 +191,7 @@ public class EntitySilverfish extends EntityMonster { public PathfinderGoalSilverfishWakeOthers(EntitySilverfish entitysilverfish) { this.silverfish = entitysilverfish; + this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur } public void g() { diff --git a/src/main/java/net/minecraft/server/EntitySkeleton.java b/src/main/java/net/minecraft/server/EntitySkeleton.java index 104f594cd..9f665cf72 100644 --- a/src/main/java/net/minecraft/server/EntitySkeleton.java +++ b/src/main/java/net/minecraft/server/EntitySkeleton.java @@ -6,6 +6,18 @@ public class EntitySkeleton extends EntitySkeletonAbstract { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.skeletonRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.skeletonRidableInWater; + } + // Purpur end + @Override protected SoundEffect getSoundAmbient() { return SoundEffects.ENTITY_SKELETON_AMBIENT; diff --git a/src/main/java/net/minecraft/server/EntitySkeletonAbstract.java b/src/main/java/net/minecraft/server/EntitySkeletonAbstract.java index 84f83d48a..e2aa9e96c 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 6cfc0ece3..c0ca1c76c 100644 --- a/src/main/java/net/minecraft/server/EntitySkeletonStray.java +++ b/src/main/java/net/minecraft/server/EntitySkeletonStray.java @@ -8,6 +8,18 @@ public class EntitySkeletonStray extends EntitySkeletonAbstract { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.strayRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.strayRidableInWater; + } + // Purpur end + public static boolean 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 f415775ea..a8e76d49e 100644 --- a/src/main/java/net/minecraft/server/EntitySkeletonWither.java +++ b/src/main/java/net/minecraft/server/EntitySkeletonWither.java @@ -9,6 +9,18 @@ public class EntitySkeletonWither extends EntitySkeletonAbstract { this.a(PathType.LAVA, 8.0F); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.witherSkeletonRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.witherSkeletonRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityPiglin.class, true)); diff --git a/src/main/java/net/minecraft/server/EntitySlime.java b/src/main/java/net/minecraft/server/EntitySlime.java index a4642cc73..ecf2059b0 100644 --- a/src/main/java/net/minecraft/server/EntitySlime.java +++ b/src/main/java/net/minecraft/server/EntitySlime.java @@ -324,7 +324,7 @@ public class EntitySlime extends EntityInsentient implements IMonster { } @Override - protected void jump() { + public void jump() { // Purpur - protected -> public Vec3D vec3d = this.getMot(); this.setMot(vec3d.x, (double) this.dI(), vec3d.z); diff --git a/src/main/java/net/minecraft/server/EntitySnowman.java b/src/main/java/net/minecraft/server/EntitySnowman.java index dfe615814..a9c44967b 100644 --- a/src/main/java/net/minecraft/server/EntitySnowman.java +++ b/src/main/java/net/minecraft/server/EntitySnowman.java @@ -13,13 +13,27 @@ public class EntitySnowman extends EntityGolem implements IShearable, IRangedEnt public EntitySnowman(EntityTypes entitytypes, World world) { super(entitytypes, world); } + + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.snowGolemRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.snowGolemRidableInWater; + } + // Purpur end @Override protected void initPathfinder() { + this.goalSelector.a(0, new 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; })); @@ -71,6 +85,8 @@ public class EntitySnowman extends EntityGolem implements IShearable, IRangedEnt return; } + if (hasRider() && !world.purpurConfig.snowGolemLeaveTrailWhenRidden) return; // Purpur - don't leave snow trail when being ridden + IBlockData iblockdata = Blocks.SNOW.getBlockData(); for (int l = 0; l < 4; ++l) { @@ -113,7 +129,7 @@ public class EntitySnowman extends EntityGolem implements IShearable, IRangedEnt if (itemstack.getItem() == Items.SHEARS && this.canShear()) { // CraftBukkit start if (!CraftEventFactory.handlePlayerShearEntityEvent(entityhuman, this, itemstack, enumhand)) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } // CraftBukkit end this.shear(SoundCategory.PLAYERS); @@ -141,7 +157,7 @@ public class EntitySnowman extends EntityGolem implements IShearable, IRangedEnt return EnumInteractionResult.SUCCESS; // Purpur end } else { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } } diff --git a/src/main/java/net/minecraft/server/EntitySpider.java b/src/main/java/net/minecraft/server/EntitySpider.java index f6a677200..be1189d57 100644 --- a/src/main/java/net/minecraft/server/EntitySpider.java +++ b/src/main/java/net/minecraft/server/EntitySpider.java @@ -11,14 +11,28 @@ public class EntitySpider extends EntityMonster { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.spiderRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.spiderRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new 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/EntityStrider.java b/src/main/java/net/minecraft/server/EntityStrider.java index c123e9fe9..4cb4f60fd 100644 --- a/src/main/java/net/minecraft/server/EntityStrider.java +++ b/src/main/java/net/minecraft/server/EntityStrider.java @@ -28,6 +28,18 @@ public class EntityStrider extends EntityAnimal implements ISteerable, ISaddleab this.a(PathType.DAMAGE_FIRE, 0.0F); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.striderRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.striderRidableInWater; + } + // Purpur end + public static boolean c(EntityTypes entitytypes, GeneratorAccess generatoraccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { BlockPosition.MutableBlockPosition blockposition_mutableblockposition = blockposition.i(); @@ -89,6 +101,7 @@ public class EntityStrider extends EntityAnimal implements ISteerable, ISaddleab @Override protected void initPathfinder() { this.bC = new PathfinderGoalPanic(this, 1.65D); + this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, this.bC); this.goalSelector.a(3, new PathfinderGoalBreed(this, 1.0D)); this.bB = new PathfinderGoalTempt(this, 1.4D, false, EntityStrider.bw); @@ -380,7 +393,7 @@ public class EntityStrider extends EntityAnimal implements ISteerable, ISaddleab if (!enuminteractionresult.a()) { ItemStack itemstack = entityhuman.b(enumhand); - return itemstack.getItem() == Items.SADDLE ? itemstack.a(entityhuman, (EntityLiving) this, enumhand) : EnumInteractionResult.PASS; + return itemstack.getItem() == Items.SADDLE ? itemstack.a(entityhuman, (EntityLiving) this, enumhand) : tryRide(entityhuman, enumhand); // Purpur } else { if (flag && !this.isSilent()) { this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_STRIDER_EAT, this.getSoundCategory(), 1.0F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.2F); diff --git a/src/main/java/net/minecraft/server/EntityTameableAnimal.java b/src/main/java/net/minecraft/server/EntityTameableAnimal.java index 9b0d937f0..0b0cca4e3 100644 --- a/src/main/java/net/minecraft/server/EntityTameableAnimal.java +++ b/src/main/java/net/minecraft/server/EntityTameableAnimal.java @@ -130,6 +130,7 @@ public abstract class EntityTameableAnimal extends EntityAnimal { return this.j(entityliving) ? false : super.d(entityliving); } + public boolean isOwner(EntityLiving entityLiving) { return j(entityLiving); } // Purpur - OBFHELPER public boolean j(EntityLiving entityliving) { return entityliving == this.getOwner(); } diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java index 86de40d15..903940feb 100644 --- a/src/main/java/net/minecraft/server/EntityVillager.java +++ b/src/main/java/net/minecraft/server/EntityVillager.java @@ -75,8 +75,19 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.villagerRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.villagerRidableInWater; + } + @Override protected void initPathfinder() { + this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur if (world.purpurConfig.villagerFollowEmeraldBlock) this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, TEMPT_ITEMS)); } diff --git a/src/main/java/net/minecraft/server/EntityVillagerTrader.java b/src/main/java/net/minecraft/server/EntityVillagerTrader.java index 9985afb12..2f59c1c91 100644 --- a/src/main/java/net/minecraft/server/EntityVillagerTrader.java +++ b/src/main/java/net/minecraft/server/EntityVillagerTrader.java @@ -23,6 +23,7 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(0, new PathfinderGoalUseItem<>(this, PotionUtil.a(new ItemStack(Items.POTION), Potions.INVISIBILITY), SoundEffects.ENTITY_WANDERING_TRADER_DISAPPEARED, (entityvillagertrader) -> { return !this.world.isDay() && !entityvillagertrader.isInvisible(); })); @@ -48,6 +49,16 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { } // Purpur - start + @Override + public boolean isRidable() { + return world.purpurConfig.villagerTraderRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.villagerTraderRidableInWater; + } + @Override public boolean a(EntityHuman entityhuman) { return world.purpurConfig.villagerTraderCanBeLeashed && !this.isLeashed(); diff --git a/src/main/java/net/minecraft/server/EntityVindicator.java b/src/main/java/net/minecraft/server/EntityVindicator.java index 58315906b..958f86481 100644 --- a/src/main/java/net/minecraft/server/EntityVindicator.java +++ b/src/main/java/net/minecraft/server/EntityVindicator.java @@ -17,14 +17,28 @@ public class EntityVindicator extends EntityIllagerAbstract { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.vindicatorRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.vindicatorRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new 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 e8d8935b8..0f6ec6bc6 100644 --- a/src/main/java/net/minecraft/server/EntityWitch.java +++ b/src/main/java/net/minecraft/server/EntityWitch.java @@ -24,6 +24,18 @@ public class EntityWitch extends EntityRaider implements IRangedEntity { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.witchRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.witchRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { super.initPathfinder(); @@ -32,10 +44,12 @@ public class EntityWitch extends EntityRaider implements IRangedEntity { }); this.bz = new PathfinderGoalNearestAttackableTargetWitch<>(this, EntityHuman.class, 10, true, false, (Predicate) null); this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, 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, new Class[]{EntityRaider.class})); this.targetSelector.a(2, this.by); this.targetSelector.a(3, this.bz); diff --git a/src/main/java/net/minecraft/server/EntityWolf.java b/src/main/java/net/minecraft/server/EntityWolf.java index 5b519fa39..927d30825 100644 --- a/src/main/java/net/minecraft/server/EntityWolf.java +++ b/src/main/java/net/minecraft/server/EntityWolf.java @@ -33,9 +33,27 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable this.setTamed(false); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.wolfRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.wolfRidableInWater; + } + + public void onMount(EntityHuman entityhuman) { + super.onMount(entityhuman); + setSitting(false); + } + // Purpur end + @Override protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(2, new PathfinderGoalSit(this)); this.goalSelector.a(3, new EntityWolf.a<>(this, EntityLlama.class, 24.0F, 1.5D, 1.5D)); this.goalSelector.a(4, new PathfinderGoalLeapAtTarget(this, 0.4F)); @@ -46,6 +64,7 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable this.goalSelector.a(9, new PathfinderGoalBeg(this, 8.0F)); this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(10, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new 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 diff --git a/src/main/java/net/minecraft/server/EntityZoglin.java b/src/main/java/net/minecraft/server/EntityZoglin.java index 28adbbebd..c0b5476ff 100644 --- a/src/main/java/net/minecraft/server/EntityZoglin.java +++ b/src/main/java/net/minecraft/server/EntityZoglin.java @@ -21,6 +21,18 @@ public class EntityZoglin extends EntityMonster implements IMonster, IOglin { this.f = 5; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.zoglinRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.zoglinRidableInWater; + } + // Purpur end + @Override protected BehaviorController.b cJ() { return BehaviorController.a((Collection) EntityZoglin.c, (Collection) EntityZoglin.b); @@ -52,10 +64,10 @@ public class EntityZoglin extends EntityMonster implements IMonster, IOglin { } private Optional eP() { - return ((List) this.getBehaviorController().getMemory(MemoryModuleType.VISIBLE_MOBS).orElse(ImmutableList.of())).stream().filter(EntityZoglin::j).findFirst(); + return (this.getBehaviorController().getMemory(MemoryModuleType.VISIBLE_MOBS).orElse(ImmutableList.of())).stream().filter(EntityZoglin::predicate).findFirst(); // Purpur - decompile error } - private static boolean j(EntityLiving entityliving) { + private static boolean predicate(EntityLiving entityliving) { // Purpur - decompile error EntityTypes entitytypes = entityliving.getEntityType(); return entitytypes != EntityTypes.ZOGLIN && entitytypes != EntityTypes.CREEPER && IEntitySelector.f.test(entityliving); @@ -130,14 +142,14 @@ public class EntityZoglin extends EntityMonster implements IMonster, IOglin { @Override public BehaviorController getBehaviorController() { - return super.getBehaviorController(); + return (BehaviorController) super.getBehaviorController(); // Purpur decompile error } protected void eM() { - Activity activity = (Activity) this.bn.f().orElse((Object) null); + Activity activity = this.bn.f().orElse(null); // Purpur - decompile error - this.bn.a((List) ImmutableList.of(Activity.FLIGHT, Activity.IDLE)); - Activity activity1 = (Activity) this.bn.f().orElse((Object) null); + this.bn.a(ImmutableList.of(Activity.FLIGHT, Activity.IDLE)); // Purpur - decompile error + Activity activity1 = this.bn.f().orElse(null); // Purpur - decompile error if (activity1 == Activity.FLIGHT && activity != Activity.FLIGHT) { this.eO(); @@ -149,7 +161,8 @@ public class EntityZoglin extends EntityMonster implements IMonster, IOglin { @Override protected void mobTick() { this.world.getMethodProfiler().enter("zoglinBrain"); - this.getBehaviorController().a((WorldServer) this.world, (EntityLiving) this); + if (getRider() == null) // Purpur - only use brain if no rider + this.getBehaviorController().a((WorldServer) this.world, this); // Purpur - decompile error this.world.getMethodProfiler().exit(); this.eM(); } diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java index 9f117b20e..5189795ce 100644 --- a/src/main/java/net/minecraft/server/EntityZombie.java +++ b/src/main/java/net/minecraft/server/EntityZombie.java @@ -46,6 +46,16 @@ public class EntityZombie extends EntityMonster { } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.zombieRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.zombieRidableInWater; + } + public boolean jockeyOnlyBaby() { return world.purpurConfig.zombieJockeyOnlyBaby; } @@ -61,9 +71,11 @@ public class EntityZombie extends EntityMonster { @Override protected void initPathfinder() { + this.goalSelector.a(0, new net.pl3x.purpur.pathfinder.PathfinderGoalHasRider(this)); // Purpur if (world.purpurConfig.zombieTargetTurtleEggs) this.goalSelector.a(4, new EntityZombie.a(this, 1.0D, 3)); // Purpur 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.m(); } diff --git a/src/main/java/net/minecraft/server/EntityZombieHusk.java b/src/main/java/net/minecraft/server/EntityZombieHusk.java index 2daff8562..1130a7712 100644 --- a/src/main/java/net/minecraft/server/EntityZombieHusk.java +++ b/src/main/java/net/minecraft/server/EntityZombieHusk.java @@ -9,6 +9,16 @@ public class EntityZombieHusk extends EntityZombie { } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.huskRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.huskRidableInWater; + } + @Override public boolean jockeyOnlyBaby() { return world.purpurConfig.huskJockeyOnlyBaby; diff --git a/src/main/java/net/minecraft/server/EntityZombieVillager.java b/src/main/java/net/minecraft/server/EntityZombieVillager.java index cd796f5b8..cd12e5c74 100644 --- a/src/main/java/net/minecraft/server/EntityZombieVillager.java +++ b/src/main/java/net/minecraft/server/EntityZombieVillager.java @@ -28,6 +28,16 @@ public class EntityZombieVillager extends EntityZombie implements VillagerDataHo } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.zombieVillagerRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.zombieVillagerRidableInWater; + } + @Override public boolean jockeyOnlyBaby() { return world.purpurConfig.zombieVillagerJockeyOnlyBaby; diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java index 494d36085..9cde3693c 100644 --- a/src/main/java/net/pl3x/purpur/PurpurConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java @@ -132,10 +132,12 @@ public class PurpurConfig { public static String afkBroadcastAway = "§e§o%s is now AFK"; public static String afkBroadcastBack = "§e§o%s is no longer AFK"; public static String pingCommandOutput = "§a%s's ping is %sms"; + public static String cannotRideMob = "§cYou cannot mount that mob"; private static void messages() { afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway); afkBroadcastBack = getString("settings.messages.afk-broadcast-back", afkBroadcastBack); pingCommandOutput = getString("settings.messages.ping-command-output", pingCommandOutput); + cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob); } public static String serverModName = "Purpur"; diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java index 2f5bc77e0..103c494a9 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java @@ -266,36 +266,68 @@ public class PurpurWorldConfig { turtleEggsBreakFromMinecarts = getBoolean("blocks.turtle_egg.break-from-minecarts", turtleEggsBreakFromMinecarts); } + public boolean catRidable = false; + public boolean catRidableInWater = false; public int catSpawnDelay = 1200; public int catSpawnSwampHutScanRange = 16; public int catSpawnVillageScanRange = 48; private void catSettings() { + catRidable = getBoolean("mobs.cat.ridable", catRidable); + catRidableInWater = getBoolean("mobs.cat.ridable-in-water", catRidableInWater); catSpawnDelay = getInt("mobs.cat.spawn-delay", catSpawnDelay); catSpawnSwampHutScanRange = getInt("mobs.cat.scan-range-for-other-cats.swamp-hut", catSpawnSwampHutScanRange); catSpawnVillageScanRange = getInt("mobs.cat.scan-range-for-other-cats.village", catSpawnVillageScanRange); } + public boolean caveSpiderRidable = false; + public boolean caveSpiderRidableInWater = false; + private void caveSpiderSettings() { + caveSpiderRidable = getBoolean("mobs.cave_spider.ridable", caveSpiderRidable); + caveSpiderRidableInWater = getBoolean("mobs.cave_spider.ridable-in-water", caveSpiderRidableInWater); + } + + public boolean chickenRidable = false; + public boolean chickenRidableInWater = false; public boolean chickenRetaliate = false; private void chickenSettings() { + chickenRidable = getBoolean("mobs.chicken.ridable", chickenRidable); + chickenRidableInWater = getBoolean("mobs.chicken.ridable-in-water", chickenRidableInWater); chickenRetaliate = getBoolean("mobs.chicken.retaliate", chickenRetaliate); } + public boolean cowRidable = false; + public boolean cowRidableInWater = false; public int cowFeedMushrooms = 0; private void cowSettings() { + cowRidable = getBoolean("mobs.cow.ridable", cowRidable); + cowRidableInWater = getBoolean("mobs.cow.ridable-in-water", cowRidableInWater); cowFeedMushrooms = getInt("mobs.cow.feed-mushrooms-for-mooshroom", cowFeedMushrooms); } + public boolean creeperRidable = false; + public boolean creeperRidableInWater = false; public boolean creeperAllowGriefing = true; public double creeperChargedChance = 0.0D; private void creeperSettings() { + creeperRidable = getBoolean("mobs.creeper.ridable", creeperRidable); + creeperRidableInWater = getBoolean("mobs.creeper.ridable-in-water", creeperRidableInWater); creeperAllowGriefing = getBoolean("mobs.creeper.allow-griefing", creeperAllowGriefing); creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); } + public boolean donkeyRidableInWater = false; + private void donkeySettings() { + donkeyRidableInWater = getBoolean("mobs.donkey.ridable-in-water", donkeyRidableInWater); + } + + public boolean drownedRidable = false; + public boolean drownedRidableInWater = false; public boolean drownedJockeyOnlyBaby = true; public double drownedJockeyChance = 0.05D; public boolean drownedJockeyTryExistingChickens = true; private void drownedSettings() { + drownedRidable = getBoolean("mobs.drowned.ridable", drownedRidable); + drownedRidableInWater = getBoolean("mobs.drowned.ridable-in-water", drownedRidableInWater); drownedJockeyOnlyBaby = getBoolean("mobs.drowned.jockey.only-babies", drownedJockeyOnlyBaby); drownedJockeyChance = getDouble("mobs.drowned.jockey.chance", drownedJockeyChance); drownedJockeyTryExistingChickens = getBoolean("mobs.drowned.jockey.try-existing-chickens", drownedJockeyTryExistingChickens); @@ -310,16 +342,40 @@ public class PurpurWorldConfig { enderDragonMaxHealth = getDouble("mobs.ender_dragon.max-health", enderDragonMaxHealth); } + public boolean endermanRidable = false; + public boolean endermanRidableInWater = false; public boolean endermanAllowGriefing = true; private void endermanSettings() { + endermanRidable = getBoolean("mobs.enderman.ridable", endermanRidable); + endermanRidableInWater = getBoolean("mobs.enderman.ridable-in-water", endermanRidableInWater); endermanAllowGriefing = getBoolean("mobs.enderman.allow-griefing", endermanAllowGriefing); } + public boolean endermiteRidable = false; + public boolean endermiteRidableInWater = false; + private void endermiteSettings() { + endermiteRidable = getBoolean("mobs.endermite.ridable", endermiteRidable); + endermiteRidableInWater = getBoolean("mobs.endermite.ridable-in-water", endermiteRidableInWater); + } + + public boolean evokerRidable = false; + public boolean evokerRidableInWater = false; + private void evokerSettings() { + evokerRidable = getBoolean("mobs.evoker.ridable", evokerRidable); + evokerRidableInWater = getBoolean("mobs.evoker.ridable-in-water", evokerRidableInWater); + } + + public boolean foxRidable = false; + public boolean foxRidableInWater = false; public boolean foxTypeChangesWithTulips = false; private void foxSettings() { + foxRidable = getBoolean("mobs.fox.ridable", foxRidable); + foxRidableInWater = getBoolean("mobs.fox.ridable-in-water", foxRidableInWater); foxTypeChangesWithTulips = getBoolean("mobs.fox.tulips-change-type", foxTypeChangesWithTulips); } + public boolean giantRidable = false; + public boolean giantRidableInWater = false; public float giantStepHeight = 2.0F; public float giantJumpHeight = 1.0F; public double giantMaxHealth = 100.0D; @@ -328,6 +384,8 @@ public class PurpurWorldConfig { public boolean giantHaveAI = false; public boolean giantHaveHostileAI = false; private void giantSettings() { + giantRidable = getBoolean("mobs.giant.ridable", giantRidable); + giantRidableInWater = getBoolean("mobs.giant.ridable-in-water", giantRidableInWater); giantStepHeight = (float) getDouble("mobs.giant.step-height", giantStepHeight); giantJumpHeight = (float) getDouble("mobs.giant.jump-height", giantJumpHeight); giantMaxHealth = getDouble("mobs.giant.max-health", giantMaxHealth); @@ -337,29 +395,93 @@ public class PurpurWorldConfig { giantHaveHostileAI = getBoolean("mobs.giant.have-hostile-ai", giantHaveHostileAI); } + public boolean hoglinRidable = false; + public boolean hoglinRidableInWater = false; + private void hoglinSettings() { + hoglinRidable = getBoolean("mobs.hoglin.ridable", hoglinRidable); + hoglinRidableInWater = getBoolean("mobs.hoglin.ridable-in-water", hoglinRidableInWater); + } + + public boolean horseRidableInWater = false; + private void horseSettings() { + horseRidableInWater = getBoolean("mobs.horse.ridable-in-water", horseRidableInWater); + } + + public boolean huskRidable = false; + public boolean huskRidableInWater = false; public boolean huskJockeyOnlyBaby = true; public double huskJockeyChance = 0.05D; public boolean huskJockeyTryExistingChickens = true; private void huskSettings() { + huskRidable = getBoolean("mobs.husk.ridable", huskRidable); + huskRidableInWater = getBoolean("mobs.husk.ridable-in-water", huskRidableInWater); huskJockeyOnlyBaby = getBoolean("mobs.husk.jockey.only-babies", huskJockeyOnlyBaby); huskJockeyChance = getDouble("mobs.husk.jockey.chance", huskJockeyChance); huskJockeyTryExistingChickens = getBoolean("mobs.husk.jockey.try-existing-chickens", huskJockeyTryExistingChickens); } + public boolean illusionerRidable = false; + public boolean illusionerRidableInWater = false; public double illusionerMaxHealth = 32.0D; public double illusionerMovementSpeed = 0.5D; public double illusionerFollowRange = 18.0D; private void illusionerSettings() { + illusionerRidable = getBoolean("mobs.illusioner.ridable", illusionerRidable); + illusionerRidableInWater = getBoolean("mobs.illusioner.ridable-in-water", illusionerRidableInWater); illusionerMaxHealth = getDouble("mobs.illusioner.max-health", illusionerMaxHealth); illusionerMovementSpeed = getDouble("mobs.illusioner.movement-speed", illusionerMovementSpeed); illusionerFollowRange = getDouble("mobs.illusioner.follow-range", illusionerFollowRange); } + public boolean ironGolemRidable = false; + public boolean ironGolemRidableInWater = false; public boolean ironGolemCanSwim = false; private void ironGolemSettings() { + ironGolemRidable = getBoolean("mobs.iron_golem.ridable", ironGolemRidable); + ironGolemRidableInWater = getBoolean("mobs.iron_golem.ridable-in-water", ironGolemRidableInWater); ironGolemCanSwim = getBoolean("mobs.iron_golem.can-swim", ironGolemCanSwim); } + public boolean llamaRidable = false; + public boolean llamaRidableInWater = false; + private void llamaSettings() { + llamaRidable = getBoolean("mobs.llama.ridable", llamaRidable); + llamaRidableInWater = getBoolean("mobs.llama.ridable-in-water", llamaRidableInWater); + } + + public boolean llamaTraderRidable = false; + public boolean llamaTraderRidableInWater = false; + private void llamaTraderSettings() { + llamaTraderRidable = getBoolean("mobs.trader_llama.ridable", llamaTraderRidable); + llamaTraderRidableInWater = getBoolean("mobs.trader_llama.ridable-in-water", llamaTraderRidableInWater); + } + + public boolean mooshroomRidable = false; + public boolean mooshroomRidableInWater = false; + private void mooshroomSettings() { + mooshroomRidable = getBoolean("mobs.mooshroom.ridable", mooshroomRidable); + mooshroomRidableInWater = getBoolean("mobs.mooshroom.ridable-in-water", mooshroomRidableInWater); + } + + public boolean muleRidableInWater = false; + private void muleSettings() { + muleRidableInWater = getBoolean("mobs.mule.ridable-in-water", muleRidableInWater); + } + + public boolean ocelotRidable = false; + public boolean ocelotRidableInWater = false; + private void ocelotSettings() { + ocelotRidable = getBoolean("mobs.ocelot.ridable", ocelotRidable); + ocelotRidableInWater = getBoolean("mobs.ocelot.ridable-in-water", ocelotRidableInWater); + } + + public boolean pandaRidable = false; + public boolean pandaRidableInWater = false; + private void pandaSettings() { + pandaRidable = getBoolean("mobs.panda.ridable", pandaRidable); + pandaRidableInWater = getBoolean("mobs.panda.ridable-in-water", pandaRidableInWater); + } + public double phantomAttackedByCrystalRadius = 0.0D; public float phantomAttackedByCrystalDamage = 1.0F; public double phantomOrbitCrystalRadius = 0.0D; @@ -393,14 +515,36 @@ public class PurpurWorldConfig { phantomSpawnMaxPerAttempt = getInt("mobs.phantom.spawn.per-attempt.max", phantomSpawnMaxPerAttempt); } + public boolean pigRidable = false; + public boolean pigRidableInWater = false; public boolean pigGiveSaddleBack = false; private void pigSettings() { + pigRidable = getBoolean("mobs.pig.ridable", pigRidable); + pigRidableInWater = getBoolean("mobs.pig.ridable-in-water", pigRidableInWater); pigGiveSaddleBack = getBoolean("mobs.pig.give-saddle-back", pigGiveSaddleBack); } + public boolean piglinRidable = false; + public boolean piglinRidableInWater = false; + private void piglinSettings() { + piglinRidable = getBoolean("mobs.piglin.ridable", piglinRidable); + piglinRidableInWater = getBoolean("mobs.piglin.ridable-in-water", piglinRidableInWater); + } + + public boolean pillagerRidable = false; + public boolean pillagerRidableInWater = false; + private void pillagerSettings() { + pillagerRidable = getBoolean("mobs.pillager.ridable", pillagerRidable); + pillagerRidableInWater = getBoolean("mobs.pillager.ridable-in-water", pillagerRidableInWater); + } + + public boolean polarBearRidable = false; + public boolean polarBearRidableInWater = false; public String polarBearBreedableItemString = ""; public Item polarBearBreedableItem = null; private void polarBearSettings() { + polarBearRidable = getBoolean("mobs.polar_bear.ridable", polarBearRidable); + polarBearRidableInWater = getBoolean("mobs.polar_bear.ridable-in-water", polarBearRidableInWater); polarBearBreedableItemString = getString("mobs.polar_bear.breedable-item", polarBearBreedableItemString); Item item = IRegistry.ITEM.get(new MinecraftKey(polarBearBreedableItemString)); if (item != Items.AIR) polarBearBreedableItem = item; @@ -413,13 +557,84 @@ public class PurpurWorldConfig { rabbitNaturalKiller = getDouble("mobs.rabbit.spawn-killer-rabbit-chance", rabbitNaturalKiller); } + public boolean ravagerRidable = false; + public boolean ravagerRidableInWater = false; + private void ravagerSettings() { + ravagerRidable = getBoolean("mobs.ravager.ridable", ravagerRidable); + ravagerRidableInWater = getBoolean("mobs.ravager.ridable-in-water", ravagerRidableInWater); + } + + public boolean sheepRidable = false; + public boolean sheepRidableInWater = false; + private void sheepSettings() { + sheepRidable = getBoolean("mobs.sheep.ridable", sheepRidable); + sheepRidableInWater = getBoolean("mobs.sheep.ridable-in-water", sheepRidableInWater); + } + + public boolean shulkerRidable = false; + public boolean shulkerRidableInWater = false; + private void shulkerSettings() { + shulkerRidable = getBoolean("mobs.shulker.ridable", shulkerRidable); + shulkerRidableInWater = getBoolean("mobs.shulker.ridable-in-water", shulkerRidableInWater); + } + + public boolean silverfishRidable = false; + public boolean silverfishRidableInWater = false; + private void silverfishSettings() { + silverfishRidable = getBoolean("mobs.silverfish.ridable", silverfishRidable); + silverfishRidableInWater = getBoolean("mobs.silverfish.ridable-in-water", silverfishRidableInWater); + } + + public boolean skeletonRidable = false; + public boolean skeletonRidableInWater = false; + private void skeletonSettings() { + skeletonRidable = getBoolean("mobs.skeleton.ridable", skeletonRidable); + skeletonRidableInWater = getBoolean("mobs.skeleton.ridable-in-water", skeletonRidableInWater); + } + + public boolean skeletonHorseCanSwim = false; + public boolean skeletonHorseRidableInWater = true; + private void skeletonHorseSettings() { + skeletonHorseCanSwim = getBoolean("mobs.skeleton_horse.can-swim", skeletonHorseCanSwim); + skeletonHorseRidableInWater = getBoolean("mobs.skeleton_horse.ridable-in-water", skeletonHorseRidableInWater); + } + + public boolean snowGolemRidable = false; + public boolean snowGolemRidableInWater = false; + public boolean snowGolemLeaveTrailWhenRidden = false; public boolean snowGolemDropsPumpkin = false; public boolean snowGolemPutPumpkinBack = false; private void snowGolemSettings() { + snowGolemRidable = getBoolean("mobs.snow_golem.ridable", snowGolemRidable); + snowGolemRidableInWater = getBoolean("mobs.snow_golem.ridable-in-water", snowGolemRidableInWater); + snowGolemLeaveTrailWhenRidden = getBoolean("mobs.snow_golem.leave-trail-when-ridden", snowGolemLeaveTrailWhenRidden); snowGolemDropsPumpkin = getBoolean("mobs.snow_golem.drop-pumpkin-when-sheared", snowGolemDropsPumpkin); snowGolemPutPumpkinBack = getBoolean("mobs.snow_golem.pumpkin-can-be-added-back", snowGolemPutPumpkinBack); } + public boolean spiderRidable = false; + public boolean spiderRidableInWater = false; + private void spiderSettings() { + spiderRidable = getBoolean("mobs.spider.ridable", spiderRidable); + spiderRidableInWater = getBoolean("mobs.spider.ridable-in-water", spiderRidableInWater); + } + + public boolean strayRidable = false; + public boolean strayRidableInWater = false; + private void straySettings() { + strayRidable = getBoolean("mobs.stray.ridable", strayRidable); + strayRidableInWater = getBoolean("mobs.stray.ridable-in-water", strayRidableInWater); + } + + public boolean striderRidable = false; + public boolean striderRidableInWater = false; + private void striderSettings() { + striderRidable = getBoolean("mobs.strider.ridable", striderRidable); + striderRidableInWater = getBoolean("mobs.strider.ridable-in-water", striderRidableInWater); + } + + public boolean villagerRidable = false; + public boolean villagerRidableInWater = false; public int villagerBrainTicks = 1; public boolean villagerUseBrainTicksOnlyWhenLagging = true; public boolean villagerCanBeLeashed = false; @@ -428,6 +643,8 @@ public class PurpurWorldConfig { public int villagerSpawnIronGolemRadius = 0; public int villagerSpawnIronGolemLimit = 0; private void villagerSettings() { + villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); + villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks); villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); villagerCanBeLeashed = getBoolean("mobs.villager.can-be-leashed", villagerCanBeLeashed); @@ -437,47 +654,99 @@ public class PurpurWorldConfig { villagerSpawnIronGolemLimit = getInt("mobs.villager.spawn-iron-golem.limit", villagerSpawnIronGolemLimit); } + public boolean villagerTraderRidable = false; + public boolean villagerTraderRidableInWater = false; public boolean villagerTraderCanBeLeashed = false; public boolean villagerTraderFollowEmeraldBlock = false; private void villagerTraderSettings() { + villagerTraderRidable = getBoolean("mobs.wandering_trader.ridable", villagerTraderRidable); + villagerTraderRidableInWater = getBoolean("mobs.wandering_trader.ridable-in-water", villagerTraderRidableInWater); villagerTraderCanBeLeashed = getBoolean("mobs.wandering_trader.can-be-leashed", villagerTraderCanBeLeashed); villagerTraderFollowEmeraldBlock = getBoolean("mobs.wandering_trader.follow-emerald-blocks", villagerTraderFollowEmeraldBlock); } + public boolean vindicatorRidable = false; + public boolean vindicatorRidableInWater = false; + private void vindicatorSettings() { + vindicatorRidable = getBoolean("mobs.vindicator.ridable", vindicatorRidable); + vindicatorRidableInWater = getBoolean("mobs.vindicator.ridable-in-water", vindicatorRidableInWater); + } + + public boolean witchRidable = false; + public boolean witchRidableInWater = false; + private void witchSettings() { + witchRidable = getBoolean("mobs.witch.ridable", witchRidable); + witchRidableInWater = getBoolean("mobs.witch.ridable-in-water", witchRidableInWater); + } + + public boolean witherSkeletonRidable = false; + public boolean witherSkeletonRidableInWater = false; public boolean witherSkeletonTakesWitherDamage = false; private void witherSkeletonSettings() { + witherSkeletonRidable = getBoolean("mobs.wither_skeleton.ridable", witherSkeletonRidable); + witherSkeletonRidableInWater = getBoolean("mobs.wither_skeleton.ridable-in-water", witherSkeletonRidableInWater); witherSkeletonTakesWitherDamage = getBoolean("mobs.wither_skeleton.takes-wither-damage", witherSkeletonTakesWitherDamage); } + public boolean wolfRidable = false; + public boolean wolfRidableInWater = false; + private void wolfSettings() { + wolfRidable = getBoolean("mobs.wolf.ridable", wolfRidable); + wolfRidableInWater = getBoolean("mobs.wolf.ridable-in-water", wolfRidableInWater); + } + + public boolean zoglinRidable = false; + public boolean zoglinRidableInWater = false; + private void zoglinSettings() { + zoglinRidable = getBoolean("mobs.zoglin.ridable", zoglinRidable); + zoglinRidableInWater = getBoolean("mobs.zoglin.ridable-in-water", zoglinRidableInWater); + } + + public boolean zombieRidable = false; + public boolean zombieRidableInWater = false; public boolean zombieTargetTurtleEggs = true; public boolean zombieJockeyOnlyBaby = true; public double zombieJockeyChance = 0.05D; public boolean zombieJockeyTryExistingChickens = true; private void zombieSettings() { + zombieRidable = getBoolean("mobs.zombie.ridable", zombieRidable); + zombieRidableInWater = getBoolean("mobs.zombie.ridable-in-water", zombieRidableInWater); zombieTargetTurtleEggs = getBoolean("mobs.zombie.target-turtle-eggs", zombieTargetTurtleEggs); zombieJockeyOnlyBaby = getBoolean("mobs.zombie.jockey.only-babies", zombieJockeyOnlyBaby); zombieJockeyChance = getDouble("mobs.zombie.jockey.chance", zombieJockeyChance); zombieJockeyTryExistingChickens = getBoolean("mobs.zombie.jockey.try-existing-chickens", zombieJockeyTryExistingChickens); } + public boolean zombieHorseCanSwim = false; + public boolean zombieHorseRidableInWater = false; public double zombieHorseSpawnChance = 0.0D; private void zombieHorseSettings() { + zombieHorseCanSwim = getBoolean("mobs.zombie_horse.can-swim", zombieHorseCanSwim); + zombieHorseRidableInWater = getBoolean("mobs.zombie_horse.ridable-in-water", zombieHorseRidableInWater); zombieHorseSpawnChance = getDouble("mobs.zombie_horse.spawn-chance", zombieHorseSpawnChance); } + public boolean zombifiedPiglinRidable = false; + public boolean zombifiedPiglinRidableInWater = false; public boolean zombifiedPiglinJockeyOnlyBaby = true; public double zombifiedPiglinJockeyChance = 0.05D; public boolean zombifiedPiglinJockeyTryExistingChickens = true; private void zombifiedPiglinSettings() { + zombifiedPiglinRidable = getBoolean("mobs.zombified_piglin.ridable", zombifiedPiglinRidable); + zombifiedPiglinRidableInWater = getBoolean("mobs.zombified_piglin.ridable-in-water", zombifiedPiglinRidableInWater); zombifiedPiglinJockeyOnlyBaby = getBoolean("mobs.zombified_piglin.jockey.only-babies", zombifiedPiglinJockeyOnlyBaby); zombifiedPiglinJockeyChance = getDouble("mobs.zombified_piglin.jockey.chance", zombifiedPiglinJockeyChance); zombifiedPiglinJockeyTryExistingChickens = getBoolean("mobs.zombified_piglin.jockey.try-existing-chickens", zombifiedPiglinJockeyTryExistingChickens); } + public boolean zombieVillagerRidable = false; + public boolean zombieVillagerRidableInWater = false; public boolean zombieVillagerJockeyOnlyBaby = true; public double zombieVillagerJockeyChance = 0.05D; public boolean zombieVillagerJockeyTryExistingChickens = true; private void zombieVillagerSettings() { + zombieVillagerRidable = getBoolean("mobs.zombie_villager.ridable", zombieVillagerRidable); + zombieVillagerRidableInWater = getBoolean("mobs.zombie_villager.ridable-in-water", zombieVillagerRidableInWater); zombieVillagerJockeyOnlyBaby = getBoolean("mobs.zombie_villager.jockey.only-babies", zombieVillagerJockeyOnlyBaby); zombieVillagerJockeyChance = getDouble("mobs.zombie_villager.jockey.chance", zombieVillagerJockeyChance); zombieVillagerJockeyTryExistingChickens = getBoolean("mobs.zombie_villager.jockey.try-existing-chickens", zombieVillagerJockeyTryExistingChickens); diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerLookWASD.java b/src/main/java/net/pl3x/purpur/controller/ControllerLookWASD.java new file mode 100644 index 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..6086f6311 --- /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.jump(); + } + + 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/pathfinder/PathfinderGoalHasRider.java b/src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHasRider.java new file mode 100644 index 000000000..68acd09a6 --- /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, Type.UNKNOWN_BEHAVIOR)); + } + + // 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..c0ead608e --- /dev/null +++ b/src/main/java/net/pl3x/purpur/pathfinder/PathfinderGoalHorseHasRider.java @@ -0,0 +1,18 @@ +package net.pl3x.purpur.pathfinder; + +import net.minecraft.server.EntityHorseAbstract; + +public class PathfinderGoalHorseHasRider extends PathfinderGoalHasRider { + private final EntityHorseAbstract horse; + + public PathfinderGoalHorseHasRider(EntityHorseAbstract entity) { + super(entity); + this.horse = entity; + } + + // shouldExecute + @Override + public boolean a() { + return super.a() && horse.hasSaddle(); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index 309e7f6ee..2d9320b05 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -1125,4 +1125,26 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return getHandle().isInLava(); } // Paper end + + // Purpur start + @Override + public org.bukkit.entity.Player getRider() { + return hasRider() ? (org.bukkit.entity.Player) getHandle().getRider().getBukkitEntity() : null; + } + + @Override + public boolean hasRider() { + return getHandle().hasRider(); + } + + @Override + public boolean isRidable() { + return getHandle().isRidable(); + } + + @Override + public boolean isRidableInWater() { + return getHandle().isRidableInWater(); + } + // Purpur end }