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/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index b268068b5d2bc5f0d032e11ac38bf011a32df01c..ad4e1d5154bebf7458c38bed7380f12d06c3eaaf 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -1541,6 +1541,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant 0; // Paper worldserver.hasEntityMoveEvent = EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper + worldserver.hasRidableMoveEvent = net.pl3x.purpur.event.entity.RidableMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Purpur TileEntityHopper.skipHopperEvents = worldserver.paperConfig.disableHopperMoveEvents || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper this.methodProfiler.a(() -> { diff --git a/src/main/java/net/minecraft/server/PathfinderGoalHasRider.java b/src/main/java/net/minecraft/server/PathfinderGoalHasRider.java new file mode 100644 index 0000000000000000000000000000000000000000..4c5dd9431b9afb2f110228d058d2b0f0808f0ab9 --- /dev/null +++ b/src/main/java/net/minecraft/server/PathfinderGoalHasRider.java @@ -0,0 +1,21 @@ +package net.minecraft.server; + +import net.minecraft.world.entity.EntityInsentient; +import net.minecraft.world.entity.ai.goal.PathfinderGoal; + +import java.util.EnumSet; + +public class PathfinderGoalHasRider extends PathfinderGoal { + public final EntityInsentient entity; + + public PathfinderGoalHasRider(EntityInsentient entity) { + this.entity = entity; + setTypes(EnumSet.of(Type.JUMP, Type.MOVE, Type.LOOK, Type.TARGET, Type.UNKNOWN_BEHAVIOR)); + } + + // shouldExecute + @Override + public boolean a() { + return entity.hasPurpurRider(); + } +} diff --git a/src/main/java/net/minecraft/server/PathfinderGoalHorseHasRider.java b/src/main/java/net/minecraft/server/PathfinderGoalHorseHasRider.java new file mode 100644 index 0000000000000000000000000000000000000000..8b66d1215a6eef1302b5ecb46a4b3d502846fef8 --- /dev/null +++ b/src/main/java/net/minecraft/server/PathfinderGoalHorseHasRider.java @@ -0,0 +1,18 @@ +package net.minecraft.server; + +import net.minecraft.world.entity.animal.horse.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/net/minecraft/server/level/EntityPlayer.java b/src/main/java/net/minecraft/server/level/EntityPlayer.java index b3d12463fbeb2045860c6b933da74980f778472e..d06bae9d71f23fccbfaf65c0fd9e9a550549432e 100644 --- a/src/main/java/net/minecraft/server/level/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/level/EntityPlayer.java @@ -80,7 +80,6 @@ import net.minecraft.server.network.PlayerConnection; import net.minecraft.server.players.PlayerList; import net.minecraft.sounds.SoundCategory; import net.minecraft.sounds.SoundEffect; -import net.minecraft.stats.RecipeBook; import net.minecraft.stats.RecipeBookServer; import net.minecraft.stats.ServerStatisticManager; import net.minecraft.stats.Statistic; @@ -132,7 +131,6 @@ import net.minecraft.world.level.block.entity.TileEntityCommand; import net.minecraft.world.level.block.entity.TileEntitySign; import net.minecraft.world.level.block.state.IBlockData; import net.minecraft.world.level.portal.ShapeDetectorShape; -import net.minecraft.world.level.storage.WorldData; import net.minecraft.world.phys.AxisAlignedBB; import net.minecraft.world.phys.Vec3D; import net.minecraft.world.scores.ScoreboardScore; @@ -652,6 +650,15 @@ public class EntityPlayer extends EntityHuman implements ICrafting { } this.advancementDataPlayer.b(this); + + // Purpur start + if (this.world.purpurConfig.useNightVisionWhenRiding && this.getVehicle() != null && this.getVehicle().getPurpurRider() == this && world.getTime() % 100 == 0) { // 5 seconds + MobEffect nightVision = this.getEffect(MobEffects.NIGHT_VISION); + if (nightVision == null || nightVision.getDuration() <= 300) { // 15 seconds + this.addEffect(new MobEffect(MobEffects.NIGHT_VISION, 400, 0)); // 20 seconds + } + } + // Purpur end } public void playerTick() { diff --git a/src/main/java/net/minecraft/server/level/WorldServer.java b/src/main/java/net/minecraft/server/level/WorldServer.java index ff704bc64146584d3e8085b332bada39912f71f3..faf6140085454b4e29869d6abe08353b7a301287 100644 --- a/src/main/java/net/minecraft/server/level/WorldServer.java +++ b/src/main/java/net/minecraft/server/level/WorldServer.java @@ -216,6 +216,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { public final UUID uuid; public boolean hasPhysicsEvent = true; // Paper public boolean hasEntityMoveEvent = false; // Paper + public boolean hasRidableMoveEvent = false; // Purpur private static Throwable getAddToWorldStackTrace(Entity entity) { return new Throwable(entity + " Added to world at " + new java.util.Date()); } diff --git a/src/main/java/net/minecraft/server/network/PlayerConnection.java b/src/main/java/net/minecraft/server/network/PlayerConnection.java index fb19b16e452571a4199b5cd152642fc01bb476ed..e1c42de5d1e3ddbdf8530a79e5eb9d4ac2c96236 100644 --- a/src/main/java/net/minecraft/server/network/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/network/PlayerConnection.java @@ -2472,6 +2472,8 @@ public class PlayerConnection implements PacketListenerPlayIn { } this.server.getPluginManager().callEvent(event); + player.processClick(enumhand); // Purpur + // Fish bucket - SPIGOT-4048 if ((entity instanceof EntityFish && origItem != null && origItem.getItem() == Items.WATER_BUCKET) && (event.isCancelled() || this.player.inventory.getItemInHand() == null || this.player.inventory.getItemInHand().getItem() != origItem)) { this.sendPacket(new PacketPlayOutSpawnEntityLiving((EntityFish) entity)); diff --git a/src/main/java/net/minecraft/world/damagesource/DamageSource.java b/src/main/java/net/minecraft/world/damagesource/DamageSource.java index 6ba14f603b8ec69597c70677cc317f802d6afae9..24fd920394774bf38d2818a4cd013670f7b20ba9 100644 --- a/src/main/java/net/minecraft/world/damagesource/DamageSource.java +++ b/src/main/java/net/minecraft/world/damagesource/DamageSource.java @@ -67,6 +67,7 @@ public class DamageSource { return new EntityDamageSource("mob", entityliving); } + public static DamageSource indirectMobAttack(Entity entity, EntityLiving entityliving) { return a(entity, entityliving); } // Purpur - OBFHELPER public static DamageSource a(Entity entity, EntityLiving entityliving) { return new EntityDamageSourceIndirect("mob", entity, entityliving); } @@ -128,6 +129,7 @@ public class DamageSource { return this.B; } + public DamageSource setProjectile() { return c(); } // Purpur - OBFHELPER public DamageSource c() { this.B = true; return this; diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java index 4e084e26e0430422b0348a0a91f0e412ff3a9eff..2fed41af0416174a6e23282e3931f0b7d4f6f29f 100644 --- a/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java @@ -22,6 +22,7 @@ import net.minecraft.BlockUtil; import net.minecraft.CrashReport; import net.minecraft.CrashReportSystemDetails; import net.minecraft.ReportedException; +import net.minecraft.SystemUtils; import net.minecraft.advancements.CriterionTriggers; import net.minecraft.commands.CommandListenerWrapper; import net.minecraft.commands.ICommandListener; @@ -104,7 +105,6 @@ import net.minecraft.world.phys.AxisAlignedBB; import net.minecraft.world.phys.MovingObjectPosition; import net.minecraft.world.phys.Vec2F; import net.minecraft.world.phys.Vec3D; -import net.minecraft.world.phys.shapes.OperatorBoolean; import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShapeCollision; import net.minecraft.world.phys.shapes.VoxelShapes; @@ -197,7 +197,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne private int id; public boolean i; public final boolean blocksEntitySpawning() { return this.i; } // Paper - OBFHELPER public final List passengers; - protected int j; + protected int j; public int getRideCooldown() { return j; } // Purpur - OBFHELPER @Nullable private Entity vehicle; public boolean attachedToPlayer; @@ -213,7 +213,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne 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; @@ -269,7 +269,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne private boolean az; private final double[] aA; private long aB; - private EntitySize size; + protected EntitySize size; // Purpur - private -> protected private float headHeight; // CraftBukkit start public boolean persist = true; @@ -1621,6 +1621,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne return !this.justCreated && this.M.getDouble(TagsFluid.LAVA) > 0.0D; } + public void moveRelative(float speed, Vec3D motion) { this.a(speed, motion); } // Purpur - OBFHELPER public void a(float f, Vec3D vec3d) { Vec3D vec3d1 = a(vec3d, f, this.yaw); @@ -2377,6 +2378,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne 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) { @@ -2472,6 +2474,13 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne this.passengers.add(entity); } + // Purpur start + if (isRidable() && passengers.get(0) == entity && entity instanceof EntityHuman) { + EntityHuman entityhuman = (EntityHuman) entity; + onMount(entityhuman); + this.purpurRider = entityhuman; + } + // Purpur end } return true; // CraftBukkit } @@ -2512,6 +2521,12 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne return false; } // Spigot end + // Purpur start + if (purpurRider != null && passengers.get(0) == purpurRider) { + onDismount(purpurRider); + this.purpurRider = null; + } + // Purpur end this.passengers.remove(entity); entity.j = 60; } @@ -2677,6 +2692,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne this.setFlag(4, flag); } + public boolean isGlowing() { return bE(); } // Purpur - OBFHELPER public boolean bE() { return this.glowing || this.world.isClientSide && this.getFlag(6); } @@ -2899,6 +2915,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne public void setHeadRotation(float f) {} + public void setBodyYaw(float yaw) { n(yaw); } // Purpur - OBFHELPER public void n(float f) {} public boolean bL() { @@ -3340,6 +3357,18 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne 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) {} @@ -3792,4 +3821,47 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne return ((ChunkProviderServer) world.getChunkProvider()).isInEntityTickingChunk(this); } // Paper end + + // Purpur start + private EntityHuman purpurRider; + + public EntityHuman getPurpurRider() { + return purpurRider; + } + + public boolean hasPurpurRider() { + return purpurRider != null; + } + + public boolean isRidable() { + return false; + } + + public boolean isRidableInWater() { + return false; + } + + public void onMount(EntityHuman entityhuman) { + if (this instanceof EntityInsentient) { + ((EntityInsentient) this).setGoalTarget(null, null, false); + ((EntityInsentient) this).getNavigation().stopPathfinding(); + } + entityhuman.setJumping(false); // fixes jump on mount + } + + public void onDismount(EntityHuman entityhuman) { + } + + public boolean onSpacebar() { + return false; + } + + public boolean onClick(EnumHand hand) { + return false; + } + + public boolean processClick(EnumHand hand) { + return false; + } + // Purpur end } diff --git a/src/main/java/net/minecraft/world/entity/EntityInsentient.java b/src/main/java/net/minecraft/world/entity/EntityInsentient.java index e10377b379079bc467a60abe719075c5ef73e858..a5e3809d60a78d4638c81a2279ce15e6a66fd336 100644 --- a/src/main/java/net/minecraft/world/entity/EntityInsentient.java +++ b/src/main/java/net/minecraft/world/entity/EntityInsentient.java @@ -46,8 +46,6 @@ import net.minecraft.world.entity.ai.sensing.EntitySenses; import net.minecraft.world.entity.decoration.EntityHanging; import net.minecraft.world.entity.decoration.EntityLeash; import net.minecraft.world.entity.item.EntityItem; -import net.minecraft.world.entity.monster.EntityBlaze; -import net.minecraft.world.entity.monster.EntityEnderman; import net.minecraft.world.entity.monster.IMonster; import net.minecraft.world.entity.npc.EntityVillagerAbstract; import net.minecraft.world.entity.player.EntityHuman; @@ -100,7 +98,7 @@ public abstract class EntityInsentient extends EntityLiving { protected int f; protected ControllerLook lookController; protected ControllerMove moveController; - protected ControllerJump bi; + protected ControllerJump bi; public ControllerJump getJumpController() { return bi; } // Purpur - OBFHELPER private final EntityAIBodyControl c; protected NavigationAbstract navigation; public PathfinderGoalSelector goalSelector; @@ -138,8 +136,8 @@ public abstract class EntityInsentient extends EntityLiving { this.bA = -1.0F; this.goalSelector = new PathfinderGoalSelector(world.getMethodProfilerSupplier()); this.targetSelector = new PathfinderGoalSelector(world.getMethodProfilerSupplier()); - this.lookController = new ControllerLook(this); - this.moveController = new ControllerMove(this); + this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this); // Purpur + this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASD(this); // Purpur this.bi = new ControllerJump(this); this.c = this.r(); this.navigation = this.b(world); @@ -328,10 +326,10 @@ public abstract class EntityInsentient extends EntityLiving { // Purpur start private void incrementTicksSinceLastInteraction() { ++ticksSinceLastInteraction; - //if (hasRider()) { - // ticksSinceLastInteraction = 0; - // return; - //} + if (hasPurpurRider()) { + ticksSinceLastInteraction = 0; + return; + } if (world.purpurConfig.entityLifeSpan <= 0) { return; // feature disabled } @@ -626,14 +624,17 @@ public abstract class EntityInsentient extends EntityLiving { return super.dp(); } + public void setForwardSpeed(float speed) { this.t(speed); } // Purpur - OBFHELPER public void t(float f) { this.aT = f; } + public void setVerticalSpeed(float speed) { this.u(speed); } // Purpur - OBFHELPER public void u(float f) { this.aS = f; } + public void setStrafeSpeed(float speed) { this.v(speed); } // Purpur - OBFHELPER public void v(float f) { this.aR = f; } @@ -1332,7 +1333,7 @@ public abstract class EntityInsentient extends EntityLiving { protected void a(EntityHuman entityhuman, EntityInsentient entityinsentient) {} protected EnumInteractionResult b(EntityHuman entityhuman, EnumHand enumhand) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } public boolean ev() { @@ -1713,4 +1714,54 @@ public abstract class EntityInsentient extends EntityLiving { this.unleash(true, event.isDropLeash()); // Paper end } + + // Purpur start + public double getMaxY() { + return world.getHeight(); + } + + public EnumInteractionResult tryRide(EntityHuman entityhuman, EnumHand enumhand) { + if (!isRidable()) { + return EnumInteractionResult.PASS; + } + if (enumhand != EnumHand.MAIN_HAND) { + return EnumInteractionResult.PASS; + } + if (entityhuman.isSneaking()) { + return EnumInteractionResult.PASS; + } + if (!entityhuman.getItemInHand(enumhand).isEmpty()) { + return EnumInteractionResult.PASS; + } + if (!passengers.isEmpty() || entityhuman.isPassenger()) { + return EnumInteractionResult.PASS; + } + if (this instanceof EntityTameableAnimal) { + EntityTameableAnimal tameable = (EntityTameableAnimal) this; + if (tameable.isTamed() && !tameable.isOwner(entityhuman)) { + return EnumInteractionResult.PASS; + } + if (!tameable.isTamed() && !world.purpurConfig.untamedTamablesAreRidable) { + return EnumInteractionResult.PASS; + } + } + if (this instanceof EntityAgeable) { + EntityAgeable ageable = (EntityAgeable) this; + if (ageable.isBaby() && !world.purpurConfig.babiesAreRidable) { + return EnumInteractionResult.PASS; + } + } + if (!entityhuman.getBukkitEntity().hasPermission("allow.ride." + getEntityType().getName())) { + entityhuman.sendMessage(net.pl3x.purpur.PurpurConfig.cannotRideMob); + return EnumInteractionResult.PASS; + } + entityhuman.yaw = this.yaw; + entityhuman.pitch = this.pitch; + if (entityhuman.startRiding(this)) { + return EnumInteractionResult.SUCCESS; + } else { + return EnumInteractionResult.PASS; + } + } + // Purpur end } diff --git a/src/main/java/net/minecraft/world/entity/EntityLiving.java b/src/main/java/net/minecraft/world/entity/EntityLiving.java index c9caa6919d47283331a9e0c79b22590b80293693..8b7a2eaa4f73b72f9022dbf58a46239541c81ff7 100644 --- a/src/main/java/net/minecraft/world/entity/EntityLiving.java +++ b/src/main/java/net/minecraft/world/entity/EntityLiving.java @@ -559,7 +559,7 @@ public abstract class EntityLiving extends Entity { @Override public boolean bt() { - return false; + return isRidableInWater(); // Purpur } protected void cU() { @@ -2313,7 +2313,7 @@ public abstract class EntityLiving extends Entity { return 0.42F * this.getBlockJumpFactor(); } - protected void jump() { + public void jump() { // Purpur - protected -> public float f = this.dJ(); if (this.hasEffect(MobEffects.JUMP)) { @@ -2562,10 +2562,12 @@ public abstract class EntityLiving extends Entity { return this.onGround ? this.dN() * (0.21600002F / (f * f * f)) : this.aE; } + public float getSpeed() { return dN(); } // Purpur - OBFHELPER public float dN() { return this.bu; } + public void setSpeed(float speed) { q(speed); } // Purpur - OBFHELPER public void q(float f) { this.bu = f; } @@ -2951,8 +2953,10 @@ public abstract class EntityLiving extends Entity { this.collideNearby(); this.world.getMethodProfiler().exit(); // Paper start - if (((WorldServer) world).hasEntityMoveEvent) { - if (lastX != locX() || lastY != locY() || lastZ != locZ() || lastYaw != yaw || lastPitch != pitch) { + // Purpur start + if (lastX != locX() || lastY != locY() || lastZ != locZ() || lastYaw != yaw || lastPitch != pitch) { + if (((WorldServer) world).hasEntityMoveEvent) { + // Purpur end Location from = new Location(world.getWorld(), lastX, lastY, lastZ, lastYaw, lastPitch); Location to = new Location (world.getWorld(), locX(), locY(), locZ(), yaw, pitch); EntityMoveEvent event = new EntityMoveEvent(getBukkitLivingEntity(), from, to.clone()); @@ -2962,6 +2966,21 @@ public abstract class EntityLiving extends Entity { setLocation(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ(), event.getTo().getYaw(), event.getTo().getPitch()); } } + // Purpur start + if (hasPurpurRider()) { + getPurpurRider().resetIdleTimer(); + if (((WorldServer) world).hasRidableMoveEvent && this instanceof EntityInsentient) { + Location from = new Location(world.getWorld(), lastX, lastY, lastZ, lastYaw, lastPitch); + Location to = new Location(world.getWorld(), locX(), locY(), locZ(), yaw, pitch); + net.pl3x.purpur.event.entity.RidableMoveEvent event = new net.pl3x.purpur.event.entity.RidableMoveEvent((org.bukkit.entity.Mob) getBukkitLivingEntity(), (Player) getPurpurRider().getBukkitEntity(), from, to.clone()); + if (!event.callEvent()) { + setLocation(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch()); + } else if (!to.equals(event.getTo())) { + setLocation(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch()); + } + } + } + // Purpur end } // Paper end if (!this.world.isClientSide && this.dO() && this.aG()) { diff --git a/src/main/java/net/minecraft/world/entity/EntityTameableAnimal.java b/src/main/java/net/minecraft/world/entity/EntityTameableAnimal.java index 74636c4c0851da1cd5732daa0a2d1a4edda2050f..cdb56555889d17913d7b0c03d5ba23408a500f26 100644 --- a/src/main/java/net/minecraft/world/entity/EntityTameableAnimal.java +++ b/src/main/java/net/minecraft/world/entity/EntityTameableAnimal.java @@ -144,6 +144,7 @@ public abstract class EntityTameableAnimal extends EntityAnimal { return this.i(entityliving) ? false : super.c(entityliving); } + public boolean isOwner(EntityLiving entityLiving) { return i(entityLiving); } // Purpur - OBFHELPER public boolean i(EntityLiving entityliving) { return entityliving == this.getOwner(); } diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeDefaults.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeDefaults.java index 1b9cf77aa5d73b4834e5260a91d338620e0bb6b3..b6cc0e1286294e64568d11c452684071d4c5b636 100644 --- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeDefaults.java +++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeDefaults.java @@ -50,6 +50,7 @@ import net.minecraft.world.entity.monster.EntityGuardianElder; import net.minecraft.world.entity.monster.EntityIllagerIllusioner; import net.minecraft.world.entity.monster.EntityMagmaCube; import net.minecraft.world.entity.monster.EntityMonster; +import net.minecraft.world.entity.monster.EntityPhantom; import net.minecraft.world.entity.monster.EntityPigZombie; import net.minecraft.world.entity.monster.EntityPillager; import net.minecraft.world.entity.monster.EntityRavager; @@ -74,7 +75,80 @@ import org.apache.logging.log4j.Logger; public class AttributeDefaults { private static final Logger LOGGER = LogManager.getLogger(); - private static final Map, AttributeProvider> b = ImmutableMap.builder().put(EntityTypes.ARMOR_STAND, EntityLiving.cL().a()).put(EntityTypes.BAT, EntityBat.m().a()).put(EntityTypes.BEE, EntityBee.eZ().a()).put(EntityTypes.BLAZE, EntityBlaze.m().a()).put(EntityTypes.CAT, EntityCat.fa().a()).put(EntityTypes.CAVE_SPIDER, EntityCaveSpider.m().a()).put(EntityTypes.CHICKEN, EntityChicken.eK().a()).put(EntityTypes.COD, EntityFish.m().a()).put(EntityTypes.COW, EntityCow.eK().a()).put(EntityTypes.CREEPER, EntityCreeper.m().a()).put(EntityTypes.DOLPHIN, EntityDolphin.eM().a()).put(EntityTypes.DONKEY, EntityHorseChestedAbstract.eL().a()).put(EntityTypes.DROWNED, EntityZombie.eS().a()).put(EntityTypes.ELDER_GUARDIAN, EntityGuardianElder.m().a()).put(EntityTypes.ENDERMAN, EntityEnderman.m().a()).put(EntityTypes.ENDERMITE, EntityEndermite.m().a()).put(EntityTypes.ENDER_DRAGON, EntityEnderDragon.m().a()).put(EntityTypes.EVOKER, EntityEvoker.eK().a()).put(EntityTypes.FOX, EntityFox.eK().a()).put(EntityTypes.GHAST, EntityGhast.eJ().a()).put(EntityTypes.GIANT, EntityGiantZombie.m().a()).put(EntityTypes.GUARDIAN, EntityGuardian.eM().a()).put(EntityTypes.HOGLIN, EntityHoglin.eK().a()).put(EntityTypes.HORSE, EntityHorseAbstract.fi().a()).put(EntityTypes.HUSK, EntityZombie.eS().a()).put(EntityTypes.ILLUSIONER, EntityIllagerIllusioner.eK().a()).put(EntityTypes.IRON_GOLEM, EntityIronGolem.m().a()).put(EntityTypes.LLAMA, EntityLlama.fw().a()).put(EntityTypes.MAGMA_CUBE, EntityMagmaCube.m().a()).put(EntityTypes.MOOSHROOM, EntityCow.eK().a()).put(EntityTypes.MULE, EntityHorseChestedAbstract.eL().a()).put(EntityTypes.OCELOT, EntityOcelot.eK().a()).put(EntityTypes.PANDA, EntityPanda.eY().a()).put(EntityTypes.PARROT, EntityParrot.eU().a()).put(EntityTypes.PHANTOM, EntityMonster.eR().a()).put(EntityTypes.PIG, EntityPig.eK().a()).put(EntityTypes.PIGLIN, EntityPiglin.eT().a()).put(EntityTypes.PIGLIN_BRUTE, EntityPiglinBrute.eS().a()).put(EntityTypes.PILLAGER, EntityPillager.eK().a()).put(EntityTypes.PLAYER, EntityHuman.ep().a()).put(EntityTypes.POLAR_BEAR, EntityPolarBear.eK().a()).put(EntityTypes.PUFFERFISH, EntityFish.m().a()).put(EntityTypes.RABBIT, EntityRabbit.eL().a()).put(EntityTypes.RAVAGER, EntityRavager.m().a()).put(EntityTypes.SALMON, EntityFish.m().a()).put(EntityTypes.SHEEP, EntitySheep.eK().a()).put(EntityTypes.SHULKER, EntityShulker.m().a()).put(EntityTypes.SILVERFISH, EntitySilverfish.m().a()).put(EntityTypes.SKELETON, EntitySkeletonAbstract.m().a()).put(EntityTypes.SKELETON_HORSE, EntityHorseSkeleton.eL().a()).put(EntityTypes.SLIME, EntityMonster.eR().a()).put(EntityTypes.SNOW_GOLEM, EntitySnowman.m().a()).put(EntityTypes.SPIDER, EntitySpider.eK().a()).put(EntityTypes.SQUID, EntitySquid.m().a()).put(EntityTypes.STRAY, EntitySkeletonAbstract.m().a()).put(EntityTypes.STRIDER, EntityStrider.eM().a()).put(EntityTypes.TRADER_LLAMA, EntityLlama.fw().a()).put(EntityTypes.TROPICAL_FISH, EntityFish.m().a()).put(EntityTypes.TURTLE, EntityTurtle.eM().a()).put(EntityTypes.VEX, EntityVex.m().a()).put(EntityTypes.VILLAGER, EntityVillager.eY().a()).put(EntityTypes.VINDICATOR, EntityVindicator.eK().a()).put(EntityTypes.WANDERING_TRADER, EntityInsentient.p().a()).put(EntityTypes.WITCH, EntityWitch.eK().a()).put(EntityTypes.WITHER, EntityWither.eK().a()).put(EntityTypes.WITHER_SKELETON, EntitySkeletonAbstract.m().a()).put(EntityTypes.WOLF, EntityWolf.eU().a()).put(EntityTypes.ZOGLIN, EntityZoglin.m().a()).put(EntityTypes.ZOMBIE, EntityZombie.eS().a()).put(EntityTypes.ZOMBIE_HORSE, EntityHorseZombie.eL().a()).put(EntityTypes.ZOMBIE_VILLAGER, EntityZombie.eS().a()).put(EntityTypes.ZOMBIFIED_PIGLIN, EntityPigZombie.eW().a()).build(); + private static final Map, AttributeProvider> b = ImmutableMap., AttributeProvider>builder() // Purpur decompile error + .put(EntityTypes.ARMOR_STAND, EntityLiving.cL().a()) + .put(EntityTypes.BAT, EntityBat.m().a()) + .put(EntityTypes.BEE, EntityBee.eZ().a()) + .put(EntityTypes.BLAZE, EntityBlaze.m().a()) + .put(EntityTypes.CAT, EntityCat.fa().a()) + .put(EntityTypes.CAVE_SPIDER, EntityCaveSpider.m().a()) + .put(EntityTypes.CHICKEN, EntityChicken.eK().a()) + .put(EntityTypes.COD, EntityFish.m().a()) + .put(EntityTypes.COW, EntityCow.eK().a()) + .put(EntityTypes.CREEPER, EntityCreeper.m().a()) + .put(EntityTypes.DOLPHIN, EntityDolphin.eM().a()) + .put(EntityTypes.DONKEY, EntityHorseChestedAbstract.eL().a()) + .put(EntityTypes.DROWNED, EntityZombie.eS().a()) + .put(EntityTypes.ELDER_GUARDIAN, EntityGuardianElder.m().a()) + .put(EntityTypes.ENDERMAN, EntityEnderman.m().a()) + .put(EntityTypes.ENDERMITE, EntityEndermite.m().a()) + .put(EntityTypes.ENDER_DRAGON, EntityEnderDragon.m().a()) + .put(EntityTypes.EVOKER, EntityEvoker.eK().a()) + .put(EntityTypes.FOX, EntityFox.eK().a()) + .put(EntityTypes.GHAST, EntityGhast.eJ().a()) + .put(EntityTypes.GIANT, EntityGiantZombie.m().a()) + .put(EntityTypes.GUARDIAN, EntityGuardian.eM().a()) + .put(EntityTypes.HOGLIN, EntityHoglin.eK().a()) + .put(EntityTypes.HORSE, EntityHorseAbstract.fi().a()) + .put(EntityTypes.HUSK, EntityZombie.eS().a()) + .put(EntityTypes.ILLUSIONER, EntityIllagerIllusioner.eK().a()) + .put(EntityTypes.IRON_GOLEM, EntityIronGolem.m().a()) + .put(EntityTypes.LLAMA, EntityLlama.fw().a()) + .put(EntityTypes.MAGMA_CUBE, EntityMagmaCube.m().a()) + .put(EntityTypes.MOOSHROOM, EntityCow.eK().a()) + .put(EntityTypes.MULE, EntityHorseChestedAbstract.eL().a()) + .put(EntityTypes.OCELOT, EntityOcelot.eK().a()) + .put(EntityTypes.PANDA, EntityPanda.eY().a()) + .put(EntityTypes.PARROT, EntityParrot.eU().a()) + .put(EntityTypes.PHANTOM, EntityPhantom.defaultAttributes().build()) // Purpur + .put(EntityTypes.PIG, EntityPig.eK().a()) + .put(EntityTypes.PIGLIN, EntityPiglin.eT().a()) + .put(EntityTypes.PIGLIN_BRUTE, EntityPiglinBrute.eS().a()) + .put(EntityTypes.PILLAGER, EntityPillager.eK().a()) + .put(EntityTypes.PLAYER, EntityHuman.ep().a()) + .put(EntityTypes.POLAR_BEAR, EntityPolarBear.eK().a()) + .put(EntityTypes.PUFFERFISH, EntityFish.m().a()) + .put(EntityTypes.RABBIT, EntityRabbit.eL().a()) + .put(EntityTypes.RAVAGER, EntityRavager.m().a()) + .put(EntityTypes.SALMON, EntityFish.m().a()) + .put(EntityTypes.SHEEP, EntitySheep.eK().a()) + .put(EntityTypes.SHULKER, EntityShulker.m().a()) + .put(EntityTypes.SILVERFISH, EntitySilverfish.m().a()) + .put(EntityTypes.SKELETON, EntitySkeletonAbstract.m().a()) + .put(EntityTypes.SKELETON_HORSE, EntityHorseSkeleton.eL().a()) + .put(EntityTypes.SLIME, EntityMonster.eR().a()) + .put(EntityTypes.SNOW_GOLEM, EntitySnowman.m().a()) + .put(EntityTypes.SPIDER, EntitySpider.eK().a()) + .put(EntityTypes.SQUID, EntitySquid.m().a()) + .put(EntityTypes.STRAY, EntitySkeletonAbstract.m().a()) + .put(EntityTypes.STRIDER, EntityStrider.eM().a()) + .put(EntityTypes.TRADER_LLAMA, EntityLlama.fw().a()) + .put(EntityTypes.TROPICAL_FISH, EntityFish.m().a()) + .put(EntityTypes.TURTLE, EntityTurtle.eM().a()) + .put(EntityTypes.VEX, EntityVex.m().a()) + .put(EntityTypes.VILLAGER, EntityVillager.eY().a()) + .put(EntityTypes.VINDICATOR, EntityVindicator.eK().a()) + .put(EntityTypes.WANDERING_TRADER, EntityInsentient.p().a()) + .put(EntityTypes.WITCH, EntityWitch.eK().a()) + .put(EntityTypes.WITHER, EntityWither.eK().a()) + .put(EntityTypes.WITHER_SKELETON, EntitySkeletonAbstract.m().a()) + .put(EntityTypes.WOLF, EntityWolf.eU().a()) + .put(EntityTypes.ZOGLIN, EntityZoglin.m().a()) + .put(EntityTypes.ZOMBIE, EntityZombie.eS().a()) + .put(EntityTypes.ZOMBIE_HORSE, EntityHorseZombie.eL().a()) + .put(EntityTypes.ZOMBIE_VILLAGER, EntityZombie.eS().a()) + .put(EntityTypes.ZOMBIFIED_PIGLIN, EntityPigZombie.eW().a()) + .build(); public static AttributeProvider a(EntityTypes entitytypes) { return (AttributeProvider) AttributeDefaults.b.get(entitytypes); diff --git a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeProvider.java b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeProvider.java index c75659d0f2a6a198f338c38b600e639a4cb3d9ee..5edad3ee07cc0357442ede3a1e14e8d5c121e530 100644 --- a/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeProvider.java +++ b/src/main/java/net/minecraft/world/entity/ai/attributes/AttributeProvider.java @@ -102,6 +102,7 @@ public class AttributeProvider { return this; } + public AttributeProvider build() { return a(); } // Purpur - OBFHELPER public AttributeProvider a() { this.b = true; return new AttributeProvider(this.a); diff --git a/src/main/java/net/minecraft/world/entity/ai/control/ControllerLookDolphin.java b/src/main/java/net/minecraft/world/entity/ai/control/ControllerLookDolphin.java index bf059f201c662d6492b093184e7feec711b846e8..1b472a659c140b368173237d54633f0dfbeb7419 100644 --- a/src/main/java/net/minecraft/world/entity/ai/control/ControllerLookDolphin.java +++ b/src/main/java/net/minecraft/world/entity/ai/control/ControllerLookDolphin.java @@ -3,7 +3,7 @@ package net.minecraft.world.entity.ai.control; import net.minecraft.util.MathHelper; import net.minecraft.world.entity.EntityInsentient; -public class ControllerLookDolphin extends ControllerLook { +public class ControllerLookDolphin extends net.pl3x.purpur.controller.ControllerLookWASD { // Purpur private final int h; @@ -13,7 +13,7 @@ public class ControllerLookDolphin extends ControllerLook { } @Override - public void a() { + public void tick() { // Purpur if (this.d) { this.d = false; this.a.aC = this.a(this.a.aC, this.h() + 20.0F, this.b); diff --git a/src/main/java/net/minecraft/world/entity/ai/control/ControllerMove.java b/src/main/java/net/minecraft/world/entity/ai/control/ControllerMove.java index 2aa5789437ba7eb20579da238c407a65a25b1d44..434229b146978ba7dc08a83ea55fdb3ab743fbf8 100644 --- a/src/main/java/net/minecraft/world/entity/ai/control/ControllerMove.java +++ b/src/main/java/net/minecraft/world/entity/ai/control/ControllerMove.java @@ -20,9 +20,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/world/entity/ambient/EntityBat.java b/src/main/java/net/minecraft/world/entity/ambient/EntityBat.java index 341b95f73a839a548b202e7bf97fd18760c71fd8..a99c2b4281196ad3b93292da52fc4c6bf4207181 100644 --- a/src/main/java/net/minecraft/world/entity/ambient/EntityBat.java +++ b/src/main/java/net/minecraft/world/entity/ambient/EntityBat.java @@ -22,6 +22,7 @@ import net.minecraft.world.entity.EntityPose; import net.minecraft.world.entity.EntitySize; import net.minecraft.world.entity.EntityTypes; import net.minecraft.world.entity.EnumMobSpawn; +import net.minecraft.world.entity.EnumMoveType; import net.minecraft.world.entity.ai.attributes.AttributeProvider; import net.minecraft.world.entity.ai.attributes.GenericAttributes; import net.minecraft.world.entity.ai.targeting.PathfinderTargetCondition; @@ -41,9 +42,48 @@ public class EntityBat extends EntityAmbient { public EntityBat(EntityTypes entitytypes, World world) { super(entitytypes, world); + this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar(this, 0.075F); // Purpur this.setAsleep(true); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.batRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.batRidableInWater; + } + + @Override + public double getMaxY() { + return world.purpurConfig.batMaxY; + } + + @Override + public void onMount(EntityHuman entityhuman) { + super.onMount(entityhuman); + if (isAsleep()) { + setAsleep(false); + world.playEffect(null, 1025, new BlockPosition(this).up(), 0); + } + } + + @Override + public void g(Vec3D vec3d) { + super.g(vec3d); + if (hasPurpurRider() && !onGround) { + float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue() * 2; + setSpeed(speed); + Vec3D mot = getMot(); + move(EnumMoveType.SELF, mot.multiply(speed, 0.25, speed)); + setMot(mot.a(0.9D)); + } + } + // Purpur end + @Override protected void initDatawatcher() { super.initDatawatcher(); @@ -88,7 +128,7 @@ public class EntityBat extends EntityAmbient { protected void collideNearby() {} public static AttributeProvider.Builder m() { - return EntityInsentient.p().a(GenericAttributes.MAX_HEALTH, 6.0D); + return EntityInsentient.p().a(GenericAttributes.MAX_HEALTH, 6.0D).a(GenericAttributes.FLYING_SPEED, 0.6D); // Purpur } public boolean isAsleep() { @@ -120,6 +160,13 @@ public class EntityBat extends EntityAmbient { @Override protected void mobTick() { + // Purpur start + if (hasPurpurRider()) { + Vec3D mot = getMot(); + setMot(mot.x, mot.y + (getVertical() > 0 ? 0.07D : 0.0D), mot.z); + return; + } + // Purpur end super.mobTick(); BlockPosition blockposition = this.getChunkCoordinates(); BlockPosition blockposition1 = blockposition.up(); diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityBee.java b/src/main/java/net/minecraft/world/entity/animal/EntityBee.java index 1d1f71a995a99b2101891a7a5bda7bec5d67f118..bcd510e0bf647a240edfaac1348119c5e1d7dc42 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityBee.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityBee.java @@ -22,6 +22,7 @@ import net.minecraft.network.protocol.game.PacketDebug; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -44,10 +45,10 @@ import net.minecraft.world.entity.EntityPose; import net.minecraft.world.entity.EntitySize; import net.minecraft.world.entity.EntityTypes; import net.minecraft.world.entity.EnumMonsterType; +import net.minecraft.world.entity.EnumMoveType; import net.minecraft.world.entity.IEntityAngerable; import net.minecraft.world.entity.ai.attributes.AttributeProvider; import net.minecraft.world.entity.ai.attributes.GenericAttributes; -import net.minecraft.world.entity.ai.control.ControllerLook; import net.minecraft.world.entity.ai.control.ControllerMoveFlying; import net.minecraft.world.entity.ai.goal.PathfinderGoal; import net.minecraft.world.entity.ai.goal.PathfinderGoalBreed; @@ -111,6 +112,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB public EntityBee(EntityTypes entitytypes, World world) { super(entitytypes, world); + final net.pl3x.purpur.controller.ControllerMoveWASDFlying flyingController = new net.pl3x.purpur.controller.ControllerMoveWASDFlying(this, 0.25F, false); // Purpur // Paper start - apply gravity to bees when they get stuck in the void, fixes MC-167279 this.moveController = new ControllerMoveFlying(this, 20, true) { @Override @@ -120,6 +122,22 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB } super.tick(); } + + // Purpur start + @Override + public void a() { // tick + if (getEntity().hasPurpurRider()) { + flyingController.tick(getEntity().getPurpurRider()); + } else { + tick(); + } + } + + @Override + public boolean b() { // isUpdating + return getEntity().hasPurpurRider() || super.b(); + } + // Purpur end }; // Paper end this.lookController = new EntityBee.j(this); @@ -130,6 +148,35 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB this.a(PathType.FENCE, -1.0F); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.beeRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.beeRidableInWater; + } + + @Override + public double getMaxY() { + return world.purpurConfig.beeMaxY; + } + + @Override + public void g(Vec3D vec3d) { + super.g(vec3d); + if (hasPurpurRider() && !onGround) { + float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue() * 2; + setSpeed(speed); + Vec3D mot = getMot(); + move(EnumMoveType.SELF, mot.multiply(speed, speed, speed)); + setMot(mot.a(0.9D)); + } + } + // Purpur end + @Override protected void initDatawatcher() { super.initDatawatcher(); @@ -144,6 +191,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB @Override protected void initPathfinder() { + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(0, new EntityBee.b(this, 1.399999976158142D, true)); this.goalSelector.a(1, new EntityBee.d()); this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); @@ -159,6 +207,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB this.goalSelector.a(7, new EntityBee.g()); this.goalSelector.a(8, new EntityBee.l()); this.goalSelector.a(9, new PathfinderGoalFloat(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, (new EntityBee.h(this)).a(new Class[0])); this.targetSelector.a(2, new EntityBee.c(this)); this.targetSelector.a(3, new PathfinderGoalUniversalAngerReset<>(this, true)); @@ -629,6 +678,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB private d() { super(); // CraftBukkit - decompile error + this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - enter hive } @Override @@ -691,6 +741,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB private g() { super(); // CraftBukkit - decompile error + this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - grow crop } @Override @@ -755,6 +806,7 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB private i() { super(); // CraftBukkit - decompile error + this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - go to hive } @Override @@ -978,16 +1030,16 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB } } - class j extends ControllerLook { + class j extends net.pl3x.purpur.controller.ControllerLookWASD { // Purpur j(EntityInsentient entityinsentient) { super(entityinsentient); } @Override - public void a() { + public void tick() { // Purpur if (!EntityBee.this.isAngry()) { - super.a(); + super.tick(); // Purpur } } diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityCat.java b/src/main/java/net/minecraft/world/entity/animal/EntityCat.java index c8f529b3fd227ce3354f442038b27cd716f57254..bac3035e2382df2d79e592b02395753eee08fa4b 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityCat.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityCat.java @@ -14,6 +14,7 @@ import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; import net.minecraft.resources.MinecraftKey; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -104,6 +105,25 @@ public class EntityCat extends EntityTameableAnimal { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.catRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.catRidableInWater; + } + + public void onMount(EntityHuman entityhuman) { + super.onMount(entityhuman); + setSitting(false); + setSleepingWithOwner(false); + setHeadDown(false); + } + // Purpur end + public MinecraftKey eU() { return (MinecraftKey) EntityCat.bq.getOrDefault(this.getCatType(), EntityCat.bq.get(0)); } @@ -111,7 +131,8 @@ public class EntityCat extends EntityTameableAnimal { @Override protected void initPathfinder() { this.bx = new EntityCat.PathfinderGoalTemptChance(this, 0.6D, EntityCat.br, true); - this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalFloat(this)); // Purpur + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new PathfinderGoalSit(this)); this.goalSelector.a(2, new EntityCat.b(this)); this.goalSelector.a(3, this.bx); @@ -123,6 +144,7 @@ public class EntityCat extends EntityTameableAnimal { this.goalSelector.a(10, new PathfinderGoalBreed(this, 0.8D)); this.goalSelector.a(11, new PathfinderGoalRandomStrollLand(this, 0.8D, 1.0000001E-5F)); this.goalSelector.a(12, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 10.0F)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalRandomTargetNonTamed<>(this, EntityRabbit.class, false, (Predicate) null)); this.targetSelector.a(1, new PathfinderGoalRandomTargetNonTamed<>(this, EntityTurtle.class, false, EntityTurtle.bo)); } @@ -139,6 +161,7 @@ public class EntityCat extends EntityTameableAnimal { this.datawatcher.set(EntityCat.bs, i); } + public void setSleepingWithOwner(boolean flag) { x(flag); } // Purpur - OBFHELPER public void x(boolean flag) { this.datawatcher.set(EntityCat.bt, flag); } @@ -147,6 +170,7 @@ public class EntityCat extends EntityTameableAnimal { return (Boolean) this.datawatcher.get(EntityCat.bt); } + public void setHeadDown(boolean flag) { y(flag); } // Purpur - OBFHELPER public void y(boolean flag) { this.datawatcher.set(EntityCat.bu, flag); } @@ -365,6 +389,7 @@ public class EntityCat extends EntityTameableAnimal { @Override public EnumInteractionResult b(EntityHuman entityhuman, EnumHand enumhand) { + if (hasPurpurRider()) return EnumInteractionResult.PASS; // Purpur ItemStack itemstack = entityhuman.b(enumhand); Item item = itemstack.getItem(); @@ -462,6 +487,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/world/entity/animal/EntityChicken.java b/src/main/java/net/minecraft/world/entity/animal/EntityChicken.java index 600d6ebdf554dbaa8ca46a22a12d8b4e3255d987..5c744f1eac19e144c39a2c146d312f0547d6e589 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityChicken.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityChicken.java @@ -2,6 +2,7 @@ package net.minecraft.world.entity.animal; import net.minecraft.core.BlockPosition; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -54,6 +55,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() { if (world.purpurConfig.chickenRetaliate) { @@ -65,6 +76,7 @@ public class EntityChicken extends EntityAnimal { @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur //this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D)); // Purpur - moved down this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, EntityChicken.bv)); @@ -75,6 +87,7 @@ public class EntityChicken extends EntityAnimal { // Purpur start if (world.purpurConfig.chickenRetaliate) { this.goalSelector.a(1, new PathfinderGoalMeleeAttack(this, 1.0D, false)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this)); } else { this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.4D)); diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityCod.java b/src/main/java/net/minecraft/world/entity/animal/EntityCod.java index aac7992a30a0b69cb34097aeb0fe021f54a3cdac..897e0d5ca44a0c475634f08e7d4fcf129ee197ab 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityCod.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityCod.java @@ -14,6 +14,18 @@ public class EntityCod extends EntityFishSchool { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.codRidable; + } + + @Override + public boolean isRidableInWater() { + return true; + } + // Purpur end + @Override protected ItemStack eK() { return new ItemStack(Items.COD_BUCKET); diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityCow.java b/src/main/java/net/minecraft/world/entity/animal/EntityCow.java index 962dde5fcc617bc39b7d06a1e295370b9d60696c..b2d3fc3151a952ac783101443772736a206a6a3b 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityCow.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityCow.java @@ -2,6 +2,7 @@ package net.minecraft.world.entity.animal; import net.minecraft.core.BlockPosition; import net.minecraft.core.particles.Particles; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -43,9 +44,22 @@ public class EntityCow extends EntityAnimal { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.cowRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.cowRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new PathfinderGoalPanic(this, 2.0D)); this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); if (world.purpurConfig.cowFeedMushrooms > 0) this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.25D, RecipeItemStack.a(Items.WHEAT, Blocks.RED_MUSHROOM.getItem(), Blocks.BROWN_MUSHROOM.getItem()), false)); else // Purpur @@ -87,6 +101,7 @@ public class EntityCow extends EntityAnimal { @Override public EnumInteractionResult b(EntityHuman entityhuman, EnumHand enumhand) { + if (hasPurpurRider()) return EnumInteractionResult.PASS; // Purpur ItemStack itemstack = entityhuman.b(enumhand); if (itemstack.getItem() == Items.BUCKET && !this.isBaby()) { @@ -94,7 +109,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 @@ -105,7 +120,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); @@ -128,7 +143,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) { @@ -139,7 +154,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); @@ -158,10 +173,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/world/entity/animal/EntityDolphin.java b/src/main/java/net/minecraft/world/entity/animal/EntityDolphin.java index e0a9b931c26dbd4e7739d09ae45e1cee72ab210c..e4442716b329f3101bfd39fc7ce13d5419b427bf 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityDolphin.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityDolphin.java @@ -16,6 +16,7 @@ import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; import net.minecraft.resources.ResourceKey; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -81,6 +82,7 @@ public class EntityDolphin extends EntityWaterAnimal { public static final Predicate b = (entityitem) -> { return !entityitem.p() && entityitem.isAlive() && entityitem.isInWater(); }; + private int spitCooldown; // Purpur public EntityDolphin(EntityTypes entitytypes, World world) { super(entitytypes, world); @@ -89,6 +91,45 @@ public class EntityDolphin extends EntityWaterAnimal { this.setCanPickupLoot(true); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.dolphinRidable; + } + + @Override + public boolean isRidableInWater() { + return true; + } + + @Override + public boolean onSpacebar() { + if (spitCooldown == 0 && hasPurpurRider()) { + spitCooldown = world.purpurConfig.dolphinSpitCooldown; + if (!hasPurpurRider()) { + return false; + } + + org.bukkit.craftbukkit.entity.CraftPlayer player = (org.bukkit.craftbukkit.entity.CraftPlayer) getPurpurRider().getBukkitEntity(); + if (!player.hasPermission("allow.special.dolphin")) { + return false; + } + + org.bukkit.Location loc = player.getEyeLocation(); + loc.setPitch(loc.getPitch() - 10); + org.bukkit.util.Vector target = loc.getDirection().normalize().multiply(10).add(loc.toVector()); + + net.pl3x.purpur.entity.DolphinSpit spit = new net.pl3x.purpur.entity.DolphinSpit(world, this); + spit.shoot(target.getX() - locX(), target.getY() - locY(), target.getZ() - locZ(), world.purpurConfig.dolphinSpitSpeed, 5.0F); + + world.addEntity(spit); + playSound(SoundEffects.ENTITY_DOLPHIN_ATTACK, 1.0F, 1.0F + (random.nextFloat() - random.nextFloat()) * 0.2F); + return true; + } + return false; + } + // Purpur end + @Nullable @Override public GroupDataEntity prepare(WorldAccess worldaccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { @@ -163,6 +204,7 @@ public class EntityDolphin extends EntityWaterAnimal { protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalBreath(this)); this.goalSelector.a(0, new PathfinderGoalWater(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new EntityDolphin.b(this)); this.goalSelector.a(2, new EntityDolphin.c(this, 4.0D)); this.goalSelector.a(4, new PathfinderGoalRandomSwim(this, 1.0D, 10)); @@ -173,6 +215,7 @@ public class EntityDolphin extends EntityWaterAnimal { this.goalSelector.a(8, new EntityDolphin.d()); this.goalSelector.a(8, new PathfinderGoalFollowBoat(this)); this.goalSelector.a(9, new PathfinderGoalAvoidTarget<>(this, EntityGuardian.class, 8.0F, 1.0D, 1.0D)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityGuardian.class})).a(new Class[0])); // CraftBukkit - decompile error } @@ -224,7 +267,7 @@ public class EntityDolphin extends EntityWaterAnimal { @Override protected boolean n(Entity entity) { - return true; + return getRideCooldown() <= 0; // Purpur - make dolphin honor ride cooldown like all other non-boss mobs } @Override @@ -259,6 +302,9 @@ public class EntityDolphin extends EntityWaterAnimal { @Override public void tick() { super.tick(); + if (spitCooldown > 0) { + spitCooldown--; + } if (this.isNoAI()) { this.setAirTicks(this.bH()); } else { @@ -532,7 +578,7 @@ public class EntityDolphin extends EntityWaterAnimal { private int b; - private d() {} + private d() { this.a(java.util.EnumSet.of(PathfinderGoal.Type.MOVE)); } // Purpur - play with item @Override public boolean a() { @@ -600,7 +646,7 @@ public class EntityDolphin extends EntityWaterAnimal { } } - static class a extends ControllerMove { + static class a extends net.pl3x.purpur.controller.ControllerMoveWASDWater { // Purpur private final EntityDolphin i; @@ -610,7 +656,20 @@ public class EntityDolphin extends EntityWaterAnimal { } @Override - public void a() { + // Purpur start + public void tick(EntityHuman rider) { + if (this.i.getAirTicks() < 150) { + // if drowning override player WASD controls to find air + tick(); + } else { + super.tick(rider); + this.i.setMot(this.i.getMot().add(0.0D, 0.005D, 0.0D)); + } + } + + @Override + public void tick() { + // Purpur end if (this.i.isInWater()) { this.i.setMot(this.i.getMot().add(0.0D, 0.005D, 0.0D)); } diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityFish.java b/src/main/java/net/minecraft/world/entity/animal/EntityFish.java index cbd7c37cd1d6f5dddcbc515ecc2d9df46e109bfa..d9a5d5fb718f8c3d66844279622eae44fe826fff 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityFish.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityFish.java @@ -1,13 +1,14 @@ package net.minecraft.world.entity.animal; import java.util.Random; -import java.util.function.Predicate; + import net.minecraft.advancements.CriterionTriggers; import net.minecraft.core.BlockPosition; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.EntityPlayer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -29,7 +30,6 @@ import net.minecraft.world.entity.ai.control.ControllerMove; import net.minecraft.world.entity.ai.goal.PathfinderGoalAvoidTarget; import net.minecraft.world.entity.ai.goal.PathfinderGoalPanic; import net.minecraft.world.entity.ai.goal.PathfinderGoalRandomSwim; -import net.minecraft.world.entity.ai.goal.PathfinderGoalSelector; import net.minecraft.world.entity.ai.navigation.NavigationAbstract; import net.minecraft.world.entity.ai.navigation.NavigationGuardian; import net.minecraft.world.entity.player.EntityHuman; @@ -116,13 +116,12 @@ public abstract class EntityFish extends EntityWaterAnimal { @Override protected void initPathfinder() { super.initPathfinder(); - this.goalSelector.a(0, new PathfinderGoalPanic(this, 1.25D)); - PathfinderGoalSelector pathfindergoalselector = this.goalSelector; - Predicate predicate = IEntitySelector.g; - - predicate.getClass(); - pathfindergoalselector.a(2, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 1.6D, 1.4D, predicate::test)); - this.goalSelector.a(4, new EntityFish.b(this)); + // Purpur start + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur + this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D)); + this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 1.6D, 1.4D, IEntitySelector.g::test)); // Purpur - decompile error + this.goalSelector.a(5, new EntityFish.b(this)); + // Purpur end } @Override @@ -133,7 +132,7 @@ public abstract class EntityFish extends EntityWaterAnimal { @Override public void g(Vec3D vec3d) { if (this.doAITick() && this.isInWater()) { - this.a(0.01F, vec3d); + this.a(hasPurpurRider() ? getSpeed() : 0.01F, vec3d); // Purpur this.move(EnumMoveType.SELF, this.getMot()); this.setMot(this.getMot().a(0.9D)); if (this.getGoalTarget() == null) { @@ -220,9 +219,9 @@ public abstract class EntityFish extends EntityWaterAnimal { @Override protected void b(BlockPosition blockposition, IBlockData iblockdata) {} - static class a extends ControllerMove { + static class a extends net.pl3x.purpur.controller.ControllerMoveWASDWater { // Purpur - private final EntityFish i; + private final EntityFish i; public EntityFish getFish() { return i; } // Purpur - OBFHELPER a(EntityFish entityfish) { super(entityfish); @@ -230,7 +229,15 @@ public abstract class EntityFish extends EntityWaterAnimal { } @Override - public void a() { + // Purpur start + public void tick(EntityHuman rider) { + super.tick(rider); + getFish().setMot(getFish().getMot().add(0.0D, 0.005D, 0.0D)); + } + + @Override + public void tick() { + // Purpur end if (this.i.a((Tag) TagsFluid.WATER)) { this.i.setMot(this.i.getMot().add(0.0D, 0.005D, 0.0D)); } diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityFishSchool.java b/src/main/java/net/minecraft/world/entity/animal/EntityFishSchool.java index 21780f5dbcd4384649f08161f0812202ee94c96d..a03b0ed0a3f74ccb7572e1c4fa8e345a9e9bc49f 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityFishSchool.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityFishSchool.java @@ -25,7 +25,7 @@ public abstract class EntityFishSchool extends EntityFish { @Override protected void initPathfinder() { super.initPathfinder(); - this.goalSelector.a(5, new PathfinderGoalFishSchool(this)); + this.goalSelector.a(6, new PathfinderGoalFishSchool(this)); // Purpur } @Override diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityFox.java b/src/main/java/net/minecraft/world/entity/animal/EntityFox.java index 19a9affdaba52d8e7dc1c4c20d5c0d52829f4989..7b1a6d846f25d8bc659a541fce59df79347ba9bc 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityFox.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityFox.java @@ -21,6 +21,7 @@ import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; import net.minecraft.resources.ResourceKey; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.EntityPlayer; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; @@ -48,8 +49,6 @@ import net.minecraft.world.entity.GroupDataEntity; import net.minecraft.world.entity.IEntitySelector; import net.minecraft.world.entity.ai.attributes.AttributeProvider; import net.minecraft.world.entity.ai.attributes.GenericAttributes; -import net.minecraft.world.entity.ai.control.ControllerLook; -import net.minecraft.world.entity.ai.control.ControllerMove; import net.minecraft.world.entity.ai.goal.PathfinderGoal; import net.minecraft.world.entity.ai.goal.PathfinderGoalAvoidTarget; import net.minecraft.world.entity.ai.goal.PathfinderGoalBreed; @@ -127,6 +126,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 !hasPurpurRider() ? 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(); @@ -146,6 +178,7 @@ public class EntityFox extends EntityAnimal { return entityliving instanceof EntityFishSchool; }); this.goalSelector.a(0, new EntityFox.g()); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new EntityFox.b()); this.goalSelector.a(2, new EntityFox.n(2.2D)); this.goalSelector.a(3, new EntityFox.e(1.0D)); @@ -171,6 +204,7 @@ public class EntityFox extends EntityAnimal { this.goalSelector.a(11, new EntityFox.p()); this.goalSelector.a(12, new EntityFox.j(this, EntityHuman.class, 24.0F)); this.goalSelector.a(13, new EntityFox.r()); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(3, new EntityFox.a(EntityLiving.class, false, false, (entityliving) -> { return EntityFox.bt.test(entityliving) && !this.c(entityliving.getUniqueID()); })); @@ -458,6 +492,7 @@ public class EntityFox extends EntityAnimal { return itemstack1.isEmpty() || this.bD > 0 && item.isFood() && !itemstack1.getItem().isFood(); } + public void spit(ItemStack itemstack) { m(itemstack); } // Purpur - OBFHELPER private void m(ItemStack itemstack) { if (!itemstack.isEmpty() && !this.world.isClientSide) { EntityItem entityitem = new EntityItem(this.world, this.locX() + this.getLookDirection().x, this.locY() + 1.0D, this.locZ() + this.getLookDirection().z, itemstack); @@ -553,6 +588,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); } @@ -595,6 +631,7 @@ public class EntityFox extends EntityAnimal { this.setSleeping(false); } + public void stopActions() { fd(); } // Purpur - OBFHELPER private void fd() { this.w(false); this.setCrouching(false); @@ -760,16 +797,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 } } @@ -1439,16 +1476,16 @@ public class EntityFox extends EntityAnimal { } } - class m extends ControllerMove { + class m extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur public m() { super(EntityFox.this); } @Override - public void a() { + public void tick() { // Purpur if (EntityFox.this.fe()) { - super.a(); + super.tick(); // Purpur } } diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityIronGolem.java b/src/main/java/net/minecraft/world/entity/animal/EntityIronGolem.java index 62cff5faafa076d05ebc59ad5c4fb020bea0509e..23e614f0c3cf1178acff8e72e0441c42c658e76b 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityIronGolem.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityIronGolem.java @@ -14,6 +14,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -69,9 +70,22 @@ public class EntityIronGolem extends EntityGolem implements IEntityAngerable { this.G = 1.0F; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.ironGolemRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.ironGolemRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { if (world.purpurConfig.ironGolemCanSwim) this.goalSelector.a(0, new PathfinderGoalFloat(this)); // Purpur + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new PathfinderGoalMeleeAttack(this, 1.0D, true)); this.goalSelector.a(2, new PathfinderGoalMoveTowardsTarget(this, 0.9D, 32.0F)); this.goalSelector.a(2, new PathfinderGoalStrollVillage(this, 0.6D, false)); @@ -79,6 +93,7 @@ public class EntityIronGolem extends EntityGolem implements IEntityAngerable { this.goalSelector.a(5, new PathfinderGoalOfferFlower(this)); this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalDefendVillage(this)); this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, new Class[0])); this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, this::a_)); @@ -248,13 +263,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/world/entity/animal/EntityMushroomCow.java b/src/main/java/net/minecraft/world/entity/animal/EntityMushroomCow.java index d28d4d2c1eff2c130f49c2bce3c19da212dba5dc..815e907e8db721f2a6f0f831b69c44a9573b5c9b 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityMushroomCow.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityMushroomCow.java @@ -57,6 +57,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; @@ -118,7 +130,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); @@ -138,7 +150,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/world/entity/animal/EntityOcelot.java b/src/main/java/net/minecraft/world/entity/animal/EntityOcelot.java index f3e9c73f28584bcccd6f82d8974eabe4b4a892fa..d7938ff0dca305f1d47fdfdbc57648892debe367 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityOcelot.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityOcelot.java @@ -10,6 +10,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -63,6 +64,18 @@ public class EntityOcelot extends EntityAnimal { this.eL(); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.ocelotRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.ocelotRidableInWater; + } + // Purpur end + private boolean isTrusting() { return (Boolean) this.datawatcher.get(EntityOcelot.bp); } @@ -94,12 +107,14 @@ public class EntityOcelot extends EntityAnimal { protected void initPathfinder() { this.br = new EntityOcelot.b(this, 0.6D, EntityOcelot.bo, true); this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(3, this.br); this.goalSelector.a(7, new PathfinderGoalLeapAtTarget(this, 0.3F)); this.goalSelector.a(8, new PathfinderGoalOcelotAttack(this)); this.goalSelector.a(9, new PathfinderGoalBreed(this, 0.8D)); this.goalSelector.a(10, new PathfinderGoalRandomStrollLand(this, 0.8D, 1.0000001E-5F)); this.goalSelector.a(11, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 10.0F)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityChicken.class, false)); this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityTurtle.class, 10, false, false, EntityTurtle.bo)); } diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityPanda.java b/src/main/java/net/minecraft/world/entity/animal/EntityPanda.java index 711b322007a0973ff0aebf3c25efbae8fc7741d0..0d912399e1975d9c0d5525f5b89049f40e7efcc0 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityPanda.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityPanda.java @@ -16,6 +16,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -101,6 +102,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); @@ -124,6 +146,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); } @@ -132,6 +155,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); } @@ -148,6 +172,7 @@ public class EntityPanda extends EntityAnimal { return (Integer) this.datawatcher.get(EntityPanda.br); } + public void setEating(boolean eating) { this.v(eating); } // Purpur - OBFHELPER private void v(int i) { this.datawatcher.set(EntityPanda.br, i); } @@ -256,6 +281,7 @@ public class EntityPanda extends EntityAnimal { @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(2, new EntityPanda.i(this, 2.0D)); this.goalSelector.a(2, new EntityPanda.d(this, 1.0D)); this.goalSelector.a(3, new EntityPanda.b(this, 1.2000000476837158D, true)); @@ -271,6 +297,7 @@ public class EntityPanda extends EntityAnimal { this.goalSelector.a(12, new EntityPanda.j(this)); this.goalSelector.a(13, new PathfinderGoalFollowParent(this, 1.25D)); this.goalSelector.a(14, new PathfinderGoalRandomStrollLand(this, 1.0D)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, (new EntityPanda.e(this, new Class[0])).a(new Class[0])); } @@ -591,7 +618,7 @@ public class EntityPanda extends EntityAnimal { ItemStack itemstack = entityhuman.b(enumhand); if (this.ff()) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } else if (this.eN()) { this.u(false); return EnumInteractionResult.a(this.world.isClientSide); @@ -608,7 +635,7 @@ public class EntityPanda extends EntityAnimal { this.g(entityhuman); } else { if (this.world.isClientSide || this.eM() || this.isInWater()) { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } this.ft(); @@ -625,7 +652,7 @@ public class EntityPanda extends EntityAnimal { return EnumInteractionResult.SUCCESS; } else { - return EnumInteractionResult.PASS; + return tryRide(entityhuman, enumhand); // Purpur } } @@ -738,6 +765,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 @@ -901,6 +929,7 @@ public class EntityPanda extends EntityAnimal { public l(EntityPanda entitypanda) { this.a = entitypanda; + this.a(EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - sneeze } @Override @@ -1030,7 +1059,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; @@ -1040,9 +1069,9 @@ public class EntityPanda extends EntityAnimal { } @Override - public void a() { + public void tick() { // Purpur if (this.i.fh()) { - super.a(); + super.tick(); // Purpur } } } diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityParrot.java b/src/main/java/net/minecraft/world/entity/animal/EntityParrot.java index 699dd0ac1f8d0d340ab1a560106336fc7cc95d5b..9f705b75a14ba456808485ce4ddef9550aac3fe9 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityParrot.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityParrot.java @@ -16,6 +16,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundCategory; import net.minecraft.sounds.SoundEffect; @@ -38,6 +39,7 @@ import net.minecraft.world.entity.EntityPose; import net.minecraft.world.entity.EntitySize; import net.minecraft.world.entity.EntityTypes; import net.minecraft.world.entity.EnumMobSpawn; +import net.minecraft.world.entity.EnumMoveType; import net.minecraft.world.entity.GroupDataEntity; import net.minecraft.world.entity.ai.attributes.AttributeProvider; import net.minecraft.world.entity.ai.attributes.GenericAttributes; @@ -119,12 +121,58 @@ public class EntityParrot extends EntityPerchable implements EntityBird { public EntityParrot(EntityTypes entitytypes, World world) { super(entitytypes, world); - this.moveController = new ControllerMoveFlying(this, 10, false); + // Purpur start + final net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar flyingController = new net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar(this, 0.3F); + this.moveController = new ControllerMoveFlying(this, 10, false) { + @Override + public void a() { // tick + if (getEntity().hasPurpurRider()) { + flyingController.tick(getEntity().getPurpurRider()); + } else { + tick(); + } + } + + @Override + public boolean b() { // isUpdating + return getEntity().hasPurpurRider() ? getForward() != 0 || getStrafe() != 0 : super.b(); + } + }; + // Purpur end this.a(PathType.DANGER_FIRE, -1.0F); this.a(PathType.DAMAGE_FIRE, -1.0F); this.a(PathType.COCOA, -1.0F); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.parrotRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.parrotRidableInWater; + } + + @Override + public double getMaxY() { + return world.purpurConfig.parrotMaxY; + } + + @Override + public void g(Vec3D vec3d) { + super.g(vec3d); + if (hasPurpurRider() && !onGround) { + float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue() * 2; + setSpeed(speed); + Vec3D mot = getMot(); + move(EnumMoveType.SELF, mot.multiply(speed, 0.25, speed)); + setMot(mot.a(0.9D)); + } + } + // Purpur end + @Nullable @Override public GroupDataEntity prepare(WorldAccess worldaccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { @@ -143,8 +191,10 @@ public class EntityParrot extends EntityPerchable implements EntityBird { @Override protected void initPathfinder() { - this.goalSelector.a(0, new PathfinderGoalPanic(this, 1.25D)); + // this.goalSelector.a(0, new PathfinderGoalPanic(this, 1.25D)); // Purpur - move down this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur + this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D)); // Purpur this.goalSelector.a(1, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(2, new PathfinderGoalSit(this)); this.goalSelector.a(2, new PathfinderGoalFollowOwner(this, 1.0D, 5.0F, 1.0F, true)); diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityPig.java b/src/main/java/net/minecraft/world/entity/animal/EntityPig.java index 1a540e41e6161d011ca4ed30c68ae9df4567b8db..cef69f99d7bc9b6605b9654c50f43a1ebc1a8509 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityPig.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityPig.java @@ -9,6 +9,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundCategory; import net.minecraft.sounds.SoundEffect; @@ -66,9 +67,22 @@ public class EntityPig extends EntityAnimal implements ISteerable, ISaddleable { this.saddleStorage = new SaddleStorage(this.datawatcher, EntityPig.bp, EntityPig.bo); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.pigRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.pigRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D)); this.goalSelector.a(3, new PathfinderGoalBreed(this, 1.0D)); this.goalSelector.a(4, new PathfinderGoalTempt(this, 1.2D, RecipeItemStack.a(Items.CARROT_ON_A_STICK), false)); diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityPolarBear.java b/src/main/java/net/minecraft/world/entity/animal/EntityPolarBear.java index f25f5ced218555af0d62844a78842cfc7599d608..b46315700b8857318b03b83097fcf829047f8ca4 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityPolarBear.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityPolarBear.java @@ -14,6 +14,7 @@ import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; import net.minecraft.resources.ResourceKey; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -66,12 +67,34 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable { private static final IntRange bs = TimeRange.a(20, 39); private int bt; private UUID bu; + private int standTimer = 0; // Purpur public EntityPolarBear(EntityTypes 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 (hasPurpurRider() && getPurpurRider().getForward() == 0 && getPurpurRider().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) { @@ -109,6 +132,7 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable { protected void initPathfinder() { super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new EntityPolarBear.c()); this.goalSelector.a(1, new EntityPolarBear.d()); // Purpur start @@ -121,6 +145,7 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable { this.goalSelector.a(5, new PathfinderGoalRandomStroll(this, 1.0D)); this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new EntityPolarBear.b()); this.targetSelector.a(2, new EntityPolarBear.a()); this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, this::a_)); @@ -233,6 +258,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 @@ -266,6 +296,7 @@ public class EntityPolarBear extends EntityAnimal implements IEntityAngerable { public void setStanding(boolean standing) { t(standing); } // Purpur - OBFHELPER public void t(boolean flag) { this.datawatcher.set(EntityPolarBear.bo, flag); + standTimer = flag ? 20 : -1; // Purpur } @Override diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityPufferFish.java b/src/main/java/net/minecraft/world/entity/animal/EntityPufferFish.java index e9f20d387ccdacfbb1a48dc31e2a6cd4843a0d7b..38fe79872b4b7f4ad4a030fbdf505efbc0352fc0 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityPufferFish.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityPufferFish.java @@ -39,6 +39,18 @@ public class EntityPufferFish extends EntityFish { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.pufferfishRidable; + } + + @Override + public boolean isRidableInWater() { + return true; + } + // Purpur end + @Override protected void initDatawatcher() { super.initDatawatcher(); @@ -82,7 +94,7 @@ public class EntityPufferFish extends EntityFish { @Override protected void initPathfinder() { super.initPathfinder(); - this.goalSelector.a(1, new EntityPufferFish.a(this)); + this.goalSelector.a(2, new EntityPufferFish.a(this)); // Purpur } @Override diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityRabbit.java b/src/main/java/net/minecraft/world/entity/animal/EntityRabbit.java index 180fc927074dc683ad4d482a00dd4e04ff7923d0..4660f37bc89418e0c3767305d390a53f5c0d3c55 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityRabbit.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityRabbit.java @@ -10,6 +10,7 @@ import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; import net.minecraft.resources.MinecraftKey; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundCategory; import net.minecraft.sounds.SoundEffect; @@ -27,7 +28,6 @@ import net.minecraft.world.entity.GroupDataEntity; import net.minecraft.world.entity.ai.attributes.AttributeProvider; import net.minecraft.world.entity.ai.attributes.GenericAttributes; import net.minecraft.world.entity.ai.control.ControllerJump; -import net.minecraft.world.entity.ai.control.ControllerMove; import net.minecraft.world.entity.ai.goal.PathfinderGoalAvoidTarget; import net.minecraft.world.entity.ai.goal.PathfinderGoalBreed; import net.minecraft.world.entity.ai.goal.PathfinderGoalFloat; @@ -75,6 +75,18 @@ public class EntityRabbit extends EntityAnimal { this.initializePathFinderGoals(); // CraftBukkit - moved code } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.rabbitRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.rabbitRidableInWater; + } + // Purpur end + // CraftBukkit start - code from constructor public void initializePathFinderGoals(){ this.i(0.0D); @@ -83,7 +95,8 @@ public class EntityRabbit extends EntityAnimal { @Override public void initPathfinder() { - this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalFloat(this)); // Purpur + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new EntityRabbit.PathfinderGoalRabbitPanic(this, 2.2D)); this.goalSelector.a(2, new PathfinderGoalBreed(this, 0.8D)); this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, RecipeItemStack.a(Items.CARROT, Items.GOLDEN_CARROT, Blocks.DANDELION), false)); @@ -96,7 +109,15 @@ public class EntityRabbit extends EntityAnimal { } @Override - protected float dJ() { + // Purpur start + public float getJumpHeight() { + if (hasPurpurRider()) { + if (getForward() < 0) { + setSpeed(getForward() * 2F); + } + return actualJump ? 0.5F : 0.3F; + } + // Purpur end if (!this.positionChanged && (!this.moveController.b() || this.moveController.e() <= this.locY() + 0.5D)) { PathEntity pathentity = this.navigation.k(); @@ -115,7 +136,7 @@ public class EntityRabbit extends EntityAnimal { } @Override - protected void jump() { + public void jump() { // Purpur - protected -> public super.jump(); double d0 = this.moveController.c(); @@ -147,6 +168,7 @@ public class EntityRabbit extends EntityAnimal { } + public void startJumping() { eK(); } // Purpur - OBFHELPER public void eK() { this.setJumping(true); this.br = 10; @@ -161,6 +183,13 @@ public class EntityRabbit extends EntityAnimal { @Override public void mobTick() { + // Purpur start + if (hasPurpurRider()) { + handleJumping(); + return; + } + // Purpur end + if (this.bt > 0) { --this.bt; } @@ -211,6 +240,39 @@ public class EntityRabbit extends EntityAnimal { this.bs = this.onGround; } + // Purpur start + private boolean wasOnGround; + private boolean actualJump; + + private void handleJumping() { + if (onGround) { + ControllerJumpRabbit jumpController = (ControllerJumpRabbit) getJumpController(); + if (!wasOnGround) { + setJumping(false); + jumpController.setCanJump(false); + } + if (!jumpController.isJumping()) { + if (moveController.b()) { // isUpdating + startJumping(); + } + } else if (!jumpController.canJump()) { + jumpController.setCanJump(true); + } + } + wasOnGround = onGround; + } + + @Override + public boolean onSpacebar() { + if (onGround) { + actualJump = true; + jump(); + actualJump = false; + } + return true; + } + // Purpur end + @Override public boolean aO() { return false; @@ -540,7 +602,7 @@ public class EntityRabbit extends EntityAnimal { } } - static class ControllerMoveRabbit extends ControllerMove { + static class ControllerMoveRabbit extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur private final EntityRabbit i; private double j; @@ -551,14 +613,14 @@ public class EntityRabbit extends EntityAnimal { } @Override - public void a() { + public void tick() { // Purpur if (this.i.onGround && !this.i.jumping && !((EntityRabbit.ControllerJumpRabbit) this.i.bi).c()) { this.i.i(0.0D); } else if (this.b()) { this.i.i(this.j); } - super.a(); + super.tick(); // Purpur } @Override @@ -585,14 +647,17 @@ public class EntityRabbit extends EntityAnimal { this.c = entityrabbit; } + public boolean isJumping() { return c(); } // Purpur - OBFHELPER public boolean c() { return this.a; } + public boolean canJump() { return d(); } // Purpur - OBFHELPER public boolean d() { return this.d; } + public void setCanJump(boolean canJump) { a(canJump); } // Purpur - OBFHELPER public void a(boolean flag) { this.d = flag; } diff --git a/src/main/java/net/minecraft/world/entity/animal/EntitySalmon.java b/src/main/java/net/minecraft/world/entity/animal/EntitySalmon.java index ca125342f189d5db95ebd04043a2d11e5fbfd3fd..bf565671c167162b3d935447961f0d44ed4a2779 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntitySalmon.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntitySalmon.java @@ -14,6 +14,18 @@ public class EntitySalmon extends EntityFishSchool { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.salmonRidable; + } + + @Override + public boolean isRidableInWater() { + return true; + } + // Purpur end + @Override public int eN() { return 5; diff --git a/src/main/java/net/minecraft/world/entity/animal/EntitySheep.java b/src/main/java/net/minecraft/world/entity/animal/EntitySheep.java index 88bed962bc17242ee6a9c93b7e0fec8bc578b35f..8f3296031f220dd7bb3ae9fe2443e479954ebad3 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntitySheep.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntitySheep.java @@ -14,6 +14,7 @@ import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; import net.minecraft.resources.MinecraftKey; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundCategory; import net.minecraft.sounds.SoundEffect; @@ -110,10 +111,23 @@ public class EntitySheep extends EntityAnimal implements IShearable { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.sheepRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.sheepRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.bs = new PathfinderGoalEatTile(this); this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new PathfinderGoalPanic(this, 1.25D)); this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.1D, RecipeItemStack.a(Items.WHEAT), false)); diff --git a/src/main/java/net/minecraft/world/entity/animal/EntitySnowman.java b/src/main/java/net/minecraft/world/entity/animal/EntitySnowman.java index 44119f52a4f169ffcea53fb69393bfedfd1a62a7..a692b973717ecc56d808039418599a11aedc2c5a 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntitySnowman.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntitySnowman.java @@ -6,6 +6,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundCategory; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -50,12 +51,26 @@ public class EntitySnowman extends EntityGolem implements IShearable, IRangedEnt super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.snowGolemRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.snowGolemRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new PathfinderGoalArrowAttack(this, 1.25D, 20, 10.0F)); this.goalSelector.a(2, new PathfinderGoalRandomStrollLand(this, 1.0D, 1.0000001E-5F)); this.goalSelector.a(3, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(4, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityInsentient.class, 10, true, false, (entityliving) -> { return entityliving instanceof IMonster; })); @@ -107,6 +122,7 @@ public class EntitySnowman extends EntityGolem implements IShearable, IRangedEnt return; } + if (hasPurpurRider() && !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) { @@ -149,7 +165,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); @@ -169,7 +185,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/world/entity/animal/EntitySquid.java b/src/main/java/net/minecraft/world/entity/animal/EntitySquid.java index e6757b22497c6e274c3999d58671653e931ebe2b..777c3bcf267d6cf31300588826d3af6b55cab350 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntitySquid.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntitySquid.java @@ -4,6 +4,7 @@ package net.minecraft.world.entity.animal; import java.util.Random; import net.minecraft.core.BlockPosition; import net.minecraft.core.particles.Particles; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -23,6 +24,7 @@ import net.minecraft.world.entity.EnumMoveType; import net.minecraft.world.entity.ai.attributes.AttributeProvider; import net.minecraft.world.entity.ai.attributes.GenericAttributes; import net.minecraft.world.entity.ai.goal.PathfinderGoal; +import net.minecraft.world.entity.player.EntityHuman; import net.minecraft.world.level.GeneratorAccess; import net.minecraft.world.level.World; import net.minecraft.world.level.block.state.IBlockData; @@ -54,17 +56,38 @@ public class EntitySquid extends EntityWaterAnimal { } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.squidRidable; + } + + @Override + public boolean isRidableInWater() { + return true; + } + @Override public AxisAlignedBB getAxisForFluidCheck() { // Stops squids from floating just over the water return this.getBoundingBox().shrink(0.001D).offsetY(world.purpurConfig.squidOffsetWaterCheck); } + + private void rotateVectorAroundY(org.bukkit.util.Vector vector, double degrees) { + double rad = Math.toRadians(degrees); + double cos = Math.cos(rad); + double sine = Math.sin(rad); + double x = vector.getX(); + double z = vector.getZ(); + vector.setX(cos * x - sine * z); + vector.setZ(sine * x + cos * z); + } // Purpur end @Override protected void initPathfinder() { this.goalSelector.a(0, new EntitySquid.PathfinderGoalSquid(this)); - this.goalSelector.a(1, new EntitySquid.a()); + this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur + this.goalSelector.a(2, new EntitySquid.a()); // Purpur } public static AttributeProvider.Builder m() { @@ -209,6 +232,7 @@ public class EntitySquid extends EntityWaterAnimal { return blockposition.getY() > generatoraccess.getMinecraftWorld().spigotConfig.squidSpawnRangeMin && blockposition.getY() < maxHeight; // Spigot // Paper } + public void setMovementVector(float x, float y, float z) { a(x, y, z); } // Purpur - OBFHELPER public void a(float f, float f1, float f2) { this.bw = f; this.bx = f1; @@ -280,7 +304,7 @@ public class EntitySquid extends EntityWaterAnimal { class PathfinderGoalSquid extends PathfinderGoal { - private final EntitySquid b; + private final EntitySquid b; public EntitySquid getSquid() { return b; } // Purpur - OBFHELPER public PathfinderGoalSquid(EntitySquid entitysquid) { this.b = entitysquid; @@ -293,6 +317,38 @@ public class EntitySquid extends EntityWaterAnimal { @Override public void e() { + // Purpur start + EntitySquid squid = getSquid(); + EntityHuman rider = squid.getPurpurRider(); + if (rider != null) { + if (rider.jumping) { + squid.onSpacebar(); + } + float forward = rider.getForward(); + float strafe = rider.getStrafe(); + float speed = (float) squid.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * 10F; + if (forward < 0.0F) { + speed *= -0.5; + } + org.bukkit.util.Vector dir = rider.getBukkitEntity().getEyeLocation().getDirection().normalize().multiply(speed / 20.0F); + if (strafe != 0.0F) { + if (forward == 0.0F) { + dir.setY(0); + rotateVectorAroundY(dir, strafe > 0.0F ? -90 : 90); + } else if (forward < 0.0F) { + rotateVectorAroundY(dir, strafe > 0.0F ? 45 : -45); + } else { + rotateVectorAroundY(dir, strafe > 0.0F ? -45 : 45); + } + } + if (forward != 0.0F || strafe != 0.0F) { + squid.setMovementVector((float) dir.getX(), (float) dir.getY(), (float) dir.getZ()); + } else { + squid.setMovementVector(0.0F, 0.0F, 0.0F); + } + return; + } + // Purpur end int i = this.b.dd(); if (i > 100) { diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityTropicalFish.java b/src/main/java/net/minecraft/world/entity/animal/EntityTropicalFish.java index 29f6835da58c73a99fe620d6de7d86fede6ac893..478e55475ccc1410a442f4e30a1cbc08f479dbda 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityTropicalFish.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityTropicalFish.java @@ -37,6 +37,18 @@ public class EntityTropicalFish extends EntityFishSchool { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.tropicalFishRidable; + } + + @Override + public boolean isRidableInWater() { + return true; + } + // Purpur end + @Override protected void initDatawatcher() { super.initDatawatcher(); diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityTurtle.java b/src/main/java/net/minecraft/world/entity/animal/EntityTurtle.java index ecec8a3c4d4b5d491f79ad60d7ce5a118f30b3db..28d6e673f55fc8fae40dff4a96ac2c2b5eeab9d6 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityTurtle.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityTurtle.java @@ -15,6 +15,7 @@ import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; import net.minecraft.server.MCUtil; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.EntityPlayer; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundCategory; @@ -90,6 +91,18 @@ public class EntityTurtle extends EntityAnimal { this.G = 1.0F; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.turtleRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.turtleRidableInWater; + } + // Purpur end + public void setHomePos(BlockPosition blockposition) { this.datawatcher.set(EntityTurtle.bp, blockposition.immutableCopy()); // Paper - called with mutablepos... } @@ -198,12 +211,13 @@ public class EntityTurtle extends EntityAnimal { @Override protected void initPathfinder() { - this.goalSelector.a(0, new EntityTurtle.f(this, 1.2D)); - this.goalSelector.a(1, new EntityTurtle.a(this, 1.0D)); - this.goalSelector.a(1, new EntityTurtle.d(this, 1.0D)); - this.goalSelector.a(2, new EntityTurtle.i(this, 1.1D, Blocks.SEAGRASS.getItem())); - this.goalSelector.a(3, new EntityTurtle.c(this, 1.0D)); - this.goalSelector.a(4, new EntityTurtle.b(this, 1.0D)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur + this.goalSelector.a(1, new EntityTurtle.f(this, 1.2D)); // Purpur + this.goalSelector.a(2, new EntityTurtle.a(this, 1.0D)); // Purpur + this.goalSelector.a(2, new EntityTurtle.d(this, 1.0D)); // Purpur + this.goalSelector.a(3, new EntityTurtle.i(this, 1.1D, Blocks.SEAGRASS.getItem())); // Purpur + this.goalSelector.a(4, new EntityTurtle.c(this, 1.0D)); // Purpur + this.goalSelector.a(5, new EntityTurtle.b(this, 1.0D)); // Purpur this.goalSelector.a(7, new EntityTurtle.j(this, 1.0D)); this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(9, new EntityTurtle.h(this, 1.0D, 100)); @@ -386,13 +400,15 @@ public class EntityTurtle extends EntityAnimal { } } - static class e extends ControllerMove { + static class e extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur - private final EntityTurtle i; + private final EntityTurtle i; public EntityTurtle getTurtle() { return i; } // Purpur - OBFHELPER + private final net.pl3x.purpur.controller.ControllerMoveWASDWater waterController; // Purpur e(EntityTurtle entityturtle) { - super(entityturtle); + super(entityturtle, 0.1D); // Purpur this.i = entityturtle; + waterController = new net.pl3x.purpur.controller.ControllerMoveWASDWater(entityturtle, 0.25D); // Purpur } private void g() { @@ -412,7 +428,18 @@ public class EntityTurtle extends EntityAnimal { } @Override - public void a() { + // Purpur start + public void tick(EntityHuman rider) { + if (getTurtle().isInWater()) { + waterController.tick(rider); + } else { + super.tick(rider); + } + } + + @Override + public void tick() { + // Purpur end this.g(); if (this.h == ControllerMove.Operation.MOVE_TO && !this.i.getNavigation().m()) { double d0 = this.b - this.i.locX(); diff --git a/src/main/java/net/minecraft/world/entity/animal/EntityWolf.java b/src/main/java/net/minecraft/world/entity/animal/EntityWolf.java index b44b1544f401c1a5127bed3239bfd60420d17329..3fbd8f9122d7a5ac23af4d872f877030644ef86a 100644 --- a/src/main/java/net/minecraft/world/entity/animal/EntityWolf.java +++ b/src/main/java/net/minecraft/world/entity/animal/EntityWolf.java @@ -9,6 +9,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -91,9 +92,27 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable this.setTamed(false); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.wolfRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.wolfRidableInWater; + } + + public void onMount(EntityHuman entityhuman) { + super.onMount(entityhuman); + setSitting(false); + } + // Purpur end + @Override protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(2, new PathfinderGoalSit(this)); this.goalSelector.a(3, new EntityWolf.a<>(this, EntityLlama.class, 24.0F, 1.5D, 1.5D)); this.goalSelector.a(4, new PathfinderGoalLeapAtTarget(this, 0.4F)); @@ -104,6 +123,7 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable this.goalSelector.a(9, new PathfinderGoalBeg(this, 8.0F)); this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(10, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalOwnerHurtByTarget(this)); this.targetSelector.a(2, new PathfinderGoalOwnerHurtTarget(this)); this.targetSelector.a(3, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorse.java index 48f67652a0a6797e217ce1f6040b5dc0f7a74938..650f13b1133e4c61f71b36f3f91a9d2913996435 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorse.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorse.java @@ -41,6 +41,13 @@ public class EntityHorse extends EntityHorseAbstract { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidableInWater() { + return world.purpurConfig.horseRidableInWater; + } + // Purpur end + @Override protected void eK() { this.getAttributeInstance(GenericAttributes.MAX_HEALTH).setValue((double) this.fp()); diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseAbstract.java b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseAbstract.java index cb6e2053d1315b65812e7bff8a17988b5b8ab0e4..d4556fa190c754406d0c65baae941fb23af3f81f 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseAbstract.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseAbstract.java @@ -14,6 +14,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHorseHasRider; import net.minecraft.server.level.EntityPlayer; import net.minecraft.server.level.WorldServer; import net.minecraft.server.players.NameReferencingFileConverter; @@ -43,6 +44,8 @@ import net.minecraft.world.entity.IJumpable; import net.minecraft.world.entity.ISaddleable; import net.minecraft.world.entity.ai.attributes.AttributeProvider; import net.minecraft.world.entity.ai.attributes.GenericAttributes; +import net.minecraft.world.entity.ai.control.ControllerLook; +import net.minecraft.world.entity.ai.control.ControllerMove; import net.minecraft.world.entity.ai.goal.PathfinderGoalBreed; import net.minecraft.world.entity.ai.goal.PathfinderGoalFloat; import net.minecraft.world.entity.ai.goal.PathfinderGoalFollowParent; @@ -101,12 +104,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 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)); @@ -114,6 +132,7 @@ public abstract class EntityHorseAbstract extends EntityAnimal implements IInven this.goalSelector.a(6, new PathfinderGoalRandomStrollLand(this, 0.7D)); this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new PathfinderGoalHorseHasRider(this)); // Purpur this.eV(); } diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseDonkey.java b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseDonkey.java index d9c87411f5c636bee3f28b724abf665826788be4..50700bf85a296b87fe3155651f869e2bbdb0875d 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseDonkey.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseDonkey.java @@ -16,6 +16,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/world/entity/animal/horse/EntityHorseMule.java b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseMule.java index 7a5c14c1e80bde623473a39acb01b78b79d593e4..b6385a23050296611dbc8864b92d2cdd8321a1d0 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseMule.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseMule.java @@ -15,6 +15,12 @@ public class EntityHorseMule extends EntityHorseChestedAbstract { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidableInWater() { + return world.purpurConfig.muleRidableInWater; + } + // Purpur end @Override protected SoundEffect getSoundAmbient() { super.getSoundAmbient(); diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseSkeleton.java b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseSkeleton.java index da5365372e89b847d626e52c5541544467f14702..d21399fbb6ddc4f26a7509ce547f8c4ad6458089 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseSkeleton.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseSkeleton.java @@ -17,6 +17,7 @@ import net.minecraft.world.entity.EnumMonsterType; import net.minecraft.world.entity.ai.attributes.AttributeProvider; import net.minecraft.world.entity.ai.attributes.GenericAttributes; import net.minecraft.world.entity.ai.goal.PathfinderGoal; +import net.minecraft.world.entity.ai.goal.PathfinderGoalFloat; import net.minecraft.world.entity.player.EntityHuman; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; @@ -32,6 +33,18 @@ public class EntityHorseSkeleton extends EntityHorseAbstract { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidableInWater() { + return world.purpurConfig.skeletonHorseRidableInWater; + } + + @Override + public boolean isTamed() { + return true; + } + // Purpur end + public static AttributeProvider.Builder eL() { return fi().a(GenericAttributes.MAX_HEALTH, 15.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.20000000298023224D); } @@ -42,7 +55,7 @@ public class EntityHorseSkeleton extends EntityHorseAbstract { } @Override - protected void eV() {} + protected void eV() { if (world.purpurConfig.skeletonHorseCanSwim) goalSelector.a(0, new PathfinderGoalFloat(this)); } // Purpur @Override protected SoundEffect getSoundAmbient() { @@ -137,7 +150,7 @@ public class EntityHorseSkeleton extends EntityHorseAbstract { @Override public boolean bt() { - return true; + return super.bt(); // Purpur } @Override diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseZombie.java b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseZombie.java index 2e448a40dbf2fa5b4df4493f14738210615bab38..d57e7c02268e5d8a00b0b5897fa03dcee10cd2e0 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseZombie.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/EntityHorseZombie.java @@ -13,6 +13,7 @@ import net.minecraft.world.entity.EntityTypes; import net.minecraft.world.entity.EnumMonsterType; import net.minecraft.world.entity.ai.attributes.AttributeProvider; import net.minecraft.world.entity.ai.attributes.GenericAttributes; +import net.minecraft.world.entity.ai.goal.PathfinderGoalFloat; import net.minecraft.world.entity.player.EntityHuman; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; @@ -24,6 +25,18 @@ public class EntityHorseZombie extends EntityHorseAbstract { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidableInWater() { + return world.purpurConfig.zombieHorseRidableInWater; + } + + @Override + public boolean isTamed() { + return true; + } + // Purpur end + public static AttributeProvider.Builder eL() { return fi().a(GenericAttributes.MAX_HEALTH, 15.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.20000000298023224D); } @@ -95,5 +108,5 @@ public class EntityHorseZombie extends EntityHorseAbstract { } @Override - protected void eV() {} + protected void eV() { if (world.purpurConfig.zombieHorseCanSwim) goalSelector.a(0, new PathfinderGoalFloat(this)); } // Purpur } diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/EntityLlama.java b/src/main/java/net/minecraft/world/entity/animal/horse/EntityLlama.java index 1c6435bf2cd870b795f87368057d8dfc1e1c938a..d25177f9500a084e0f18a20b1eb1c4ac170048ec 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/EntityLlama.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/EntityLlama.java @@ -8,6 +8,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHorseHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -68,7 +69,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.hasPurpurRider() && hasSaddle()) { + tick(entity.getPurpurRider()); + } else { + tick(); + } + } + }; + this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this) { + @Override + public void a() { // tick + if (entity.hasPurpurRider() && hasSaddle()) { + tick(entity.getPurpurRider()); + } else { + tick(); + } + } + }; + // Purpur end + } + + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.llamaRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.llamaRidableInWater; + } + + @Override + public boolean hasSaddle() { + return super.hasSaddle() || (isTamed() && getColor() != null); } + // Purpur end public void setStrength(int i) { this.datawatcher.set(EntityLlama.bx, Math.max(1, Math.min(5, i))); @@ -116,6 +156,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHorseHasRider(this)); // Purpur this.goalSelector.a(1, new PathfinderGoalTame(this, 1.2D)); this.goalSelector.a(2, new PathfinderGoalLlamaFollow(this, 2.0999999046325684D)); this.goalSelector.a(3, new PathfinderGoalArrowAttack(this, 1.25D, 40, 20.0F)); @@ -125,6 +166,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn this.goalSelector.a(6, new PathfinderGoalRandomStrollLand(this, 0.7D)); this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new PathfinderGoalHorseHasRider(this)); // Purpur this.targetSelector.a(1, new EntityLlama.c(this)); this.targetSelector.a(2, new EntityLlama.a(this)); } @@ -362,7 +404,7 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn } @Nullable - public EnumColor fy() { + public EnumColor fy() { return getColor(); } public EnumColor getColor() { // Purpur - OBFHELPER int i = (Integer) this.datawatcher.get(EntityLlama.by); return i == -1 ? null : EnumColor.fromColorIndex(i); diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/EntityLlamaTrader.java b/src/main/java/net/minecraft/world/entity/animal/horse/EntityLlamaTrader.java index f761e37f7329342f01f04df5602573a51c0aca4e..0fb651bcde1109b0eb30b60226d3512648dceb41 100644 --- a/src/main/java/net/minecraft/world/entity/animal/horse/EntityLlamaTrader.java +++ b/src/main/java/net/minecraft/world/entity/animal/horse/EntityLlamaTrader.java @@ -27,6 +27,23 @@ public class EntityLlamaTrader extends EntityLlama { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.llamaTraderRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.llamaTraderRidableInWater; + } + + @Override + public boolean hasSaddle() { + return super.hasSaddle() || isTamed(); + } + // Purpur end + @Override protected EntityLlama fz() { return (EntityLlama) EntityTypes.TRADER_LLAMA.a(this.world); diff --git a/src/main/java/net/minecraft/world/entity/boss/EntityComplexPart.java b/src/main/java/net/minecraft/world/entity/boss/EntityComplexPart.java index f1065c2a37835d760fb57194f7edfd029f426b48..3f2065e2939be54639f44501f7aa8ee5500dfc84 100644 --- a/src/main/java/net/minecraft/world/entity/boss/EntityComplexPart.java +++ b/src/main/java/net/minecraft/world/entity/boss/EntityComplexPart.java @@ -2,11 +2,14 @@ package net.minecraft.world.entity.boss; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.protocol.Packet; +import net.minecraft.world.EnumHand; +import net.minecraft.world.EnumInteractionResult; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityPose; import net.minecraft.world.entity.EntitySize; import net.minecraft.world.entity.boss.enderdragon.EntityEnderDragon; +import net.minecraft.world.entity.player.EntityHuman; public class EntityComplexPart extends Entity { @@ -55,4 +58,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/world/entity/boss/enderdragon/EntityEnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.java index 3fff101637708a1a12f9a457bd3512ae94a8f884..b2d1a0144353a1da61221b59a0acc028b0cf746e 100644 --- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.java +++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EntityEnderDragon.java @@ -23,6 +23,7 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityExperienceOrb; import net.minecraft.world.entity.EntityInsentient; import net.minecraft.world.entity.EntityLiving; +import net.minecraft.world.entity.EntitySize; import net.minecraft.world.entity.EntityTypes; import net.minecraft.world.entity.EnumMoveType; import net.minecraft.world.entity.IEntitySelector; @@ -95,6 +96,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { private final int[] bK = new int[24]; private final Path bL = new Path(); private Explosion explosionSource = new Explosion(null, this, null, null, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, Explosion.Effect.DESTROY); // CraftBukkit - reusable source for CraftTNTPrimed.getSource() + private boolean hadRider; // Purpur public EntityEnderDragon(EntityTypes entitytypes, World world) { super(EntityTypes.ENDER_DRAGON, world); @@ -109,8 +111,44 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { } this.bG = new DragonControllerManager(this); + // Purpur start + this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASDFlying(this) { + @Override + public void tick() { + // dragon doesn't use the controller. do nothing + } + }; + this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this) { + @Override + public void tick() { + // dragon doesn't use the controller. do nothing + } + + @Override + public void tick(EntityHuman rider) { + setYawPitch(rider.yaw - 180F, rider.pitch * 0.5F); + } + }; + // Purpur end + } + + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.enderDragonRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.enderDragonRidableInWater; } + @Override + public double getMaxY() { + return world.purpurConfig.enderDragonMaxY; + } + // Purpur end + public static AttributeProvider.Builder m() { return EntityInsentient.p().a(GenericAttributes.MAX_HEALTH, 200.0D); } @@ -143,6 +181,37 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { @Override public void movementTick() { + // Purpur start + boolean hasRider = getPurpurRider() != null; + if (hasRider) { + if (!hadRider) { + hadRider = true; + noclip = false; + this.size = EntitySize.b(4.0F, 2.0F); + } + + // dragon doesn't use controllers, so must tick manually + moveController.a(); + lookController.a(); + + moveRelative((float) getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * 0.1F, new Vec3D(-getStrafe(), getVertical(), -getForward())); + Vec3D mot = getMot(); + setMot(mot); + move(EnumMoveType.PLAYER, mot); + + mot = mot.multiply(0.9F, 0.9F, 0.9F); + setMot(mot); + + // control wing flap speed on client + getDragonControllerManager().setControllerPhase(mot.getX() * mot.getX() + mot.getZ() * mot.getZ() < 0.005F ? DragonControllerPhase.HOVER : DragonControllerPhase.HOLDING_PATTERN); + } else if (hadRider) { + hadRider = false; + noclip = true; + this.size = EntitySize.b(16.0F, 8.0F); + getDragonControllerManager().setControllerPhase(DragonControllerPhase.HOLDING_PATTERN); // HoldingPattern + } + // Purpur end + float f; float f1; @@ -164,6 +233,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { this.bp = this.bq; if (this.dl()) { + if (hasRider) ejectPassengers(); // Purpur f = (this.random.nextFloat() - 0.5F) * 8.0F; f1 = (this.random.nextFloat() - 0.5F) * 4.0F; float f2 = (this.random.nextFloat() - 0.5F) * 8.0F; @@ -175,9 +245,9 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { f1 = 0.2F / (MathHelper.sqrt(c(vec3d)) * 10.0F + 1.0F); f1 *= (float) Math.pow(2.0D, vec3d.y); - if (this.bG.a().a()) { + if (!hasRider && this.bG.a().a()) { // Purpur this.bq += 0.1F; - } else if (this.br) { + } else if (!hasRider && this.br) { // Purpur this.bq += f1 * 0.5F; } else { this.bq += f1; @@ -221,7 +291,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { } this.bG.a().b(); - } else { + } else if (!hasRider) { // Purpur IDragonController idragoncontroller = this.bG.a(); idragoncontroller.c(); @@ -288,7 +358,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { this.a(this.bz, (double) (f11 * 0.5F), 0.0D, (double) (-f12 * 0.5F)); this.a(this.bD, (double) (f12 * 4.5F), 2.0D, (double) (f11 * 4.5F)); this.a(this.bE, (double) (f12 * -4.5F), 2.0D, (double) (f11 * -4.5F)); - if (!this.world.isClientSide && this.hurtTicks == 0) { + if (!hasRider && !this.world.isClientSide && this.hurtTicks == 0) { // Purpur this.a(this.world.getEntities(this, this.bD.getBoundingBox().grow(4.0D, 2.0D, 4.0D).d(0.0D, -2.0D, 0.0D), IEntitySelector.e)); this.a(this.world.getEntities(this, this.bE.getBoundingBox().grow(4.0D, 2.0D, 4.0D).d(0.0D, -2.0D, 0.0D), IEntitySelector.e)); this.b(this.world.getEntities(this, this.bo.getBoundingBox().g(1.0D), IEntitySelector.e)); @@ -331,7 +401,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { } if (!this.world.isClientSide) { - this.br = this.b(this.bo.getBoundingBox()) | this.b(this.by.getBoundingBox()) | this.b(this.bz.getBoundingBox()); + this.br = !hasRider && this.b(this.bo.getBoundingBox()) | this.b(this.by.getBoundingBox()) | this.b(this.bz.getBoundingBox()); // Purpur if (this.bF != null) { this.bF.b(this); } diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java b/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java index 930fc752ec0a988b17bc556cd428161638a14f27..73875b925cbf527f91a7c0ec09d350a7a2ec1260 100644 --- a/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java +++ b/src/main/java/net/minecraft/world/entity/boss/wither/EntityWither.java @@ -12,6 +12,7 @@ import net.minecraft.network.chat.IChatBaseComponent; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.BossBattleServer; import net.minecraft.server.level.EntityPlayer; import net.minecraft.sounds.SoundEffect; @@ -20,6 +21,7 @@ import net.minecraft.tags.TagsBlock; import net.minecraft.util.MathHelper; import net.minecraft.world.BossBattle; import net.minecraft.world.EnumDifficulty; +import net.minecraft.world.EnumHand; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffects; @@ -28,6 +30,7 @@ import net.minecraft.world.entity.EntityInsentient; import net.minecraft.world.entity.EntityLiving; import net.minecraft.world.entity.EntityTypes; import net.minecraft.world.entity.EnumMonsterType; +import net.minecraft.world.entity.EnumMoveType; import net.minecraft.world.entity.ai.attributes.AttributeProvider; import net.minecraft.world.entity.ai.attributes.GenericAttributes; import net.minecraft.world.entity.ai.goal.PathfinderGoal; @@ -48,14 +51,16 @@ import net.minecraft.world.item.Items; import net.minecraft.world.level.Explosion; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.IMaterial; +import net.minecraft.world.level.RayTrace; import net.minecraft.world.level.World; import net.minecraft.world.level.block.state.IBlockData; +import net.minecraft.world.phys.MovingObjectPosition; +import net.minecraft.world.phys.MovingObjectPositionBlock; +import net.minecraft.world.phys.MovingObjectPositionEntity; import net.minecraft.world.phys.Vec3D; // CraftBukkit start import net.minecraft.network.protocol.game.PacketPlayOutWorldEvent; -import net.minecraft.server.MinecraftServer; -import net.minecraft.server.level.WorldServer; import net.minecraft.world.level.block.Blocks; import org.bukkit.craftbukkit.event.CraftEventFactory; import org.bukkit.event.entity.EntityRegainHealthEvent; @@ -82,6 +87,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity { return entityliving.getMonsterType() != EnumMonsterType.UNDEAD && entityliving.ei(); }; private static final PathfinderTargetCondition bz = (new PathfinderTargetCondition()).a(20.0D).a(EntityWither.by); + private int shootCooldown = 0; // Purpur // Paper start private boolean canPortal = false; @@ -94,15 +100,122 @@ public class EntityWither extends EntityMonster implements IRangedEntity { this.setHealth(this.getMaxHealth()); this.getNavigation().d(true); this.f = 50; + this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar(this, 0.1F); // Purpur } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.witherRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.witherRidableInWater; + } + + @Override + public double getMaxY() { + return world.purpurConfig.witherMaxY; + } + + @Override + public void g(Vec3D vec3d) { + super.g(vec3d); + if (hasPurpurRider() && !onGround) { + float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue() * 5F; + setSpeed(speed); + Vec3D mot = getMot(); + move(EnumMoveType.SELF, mot.multiply(speed, 0.5, speed)); + setMot(mot.a(0.9D)); + } + } + + @Override + public void onMount(EntityHuman entityhuman) { + super.onMount(entityhuman); + this.datawatcher.set(bo.get(0), 0); + this.datawatcher.set(bo.get(1), 0); + this.datawatcher.set(bo.get(2), 0); + getNavigation().stopPathfinding(); + shootCooldown = 20; + } + + @Override + public boolean onClick(EnumHand hand) { + return shoot(getPurpurRider(), hand == EnumHand.MAIN_HAND ? new int[]{1} : new int[]{2}); + } + + public boolean shoot(EntityHuman rider, int[] heads) { + if (shootCooldown > 0) { + return false; + } + + shootCooldown = 20; + if (rider == null) { + return false; + } + + org.bukkit.craftbukkit.entity.CraftHumanEntity player = rider.getBukkitEntity(); + if (!player.hasPermission("allow.special.wither")) { + return false; + } + + MovingObjectPosition rayTrace = getRayTrace(120, RayTrace.FluidCollisionOption.NONE); + if (rayTrace == null) { + return false; + } + + Vec3D loc; + if (rayTrace.getType() == MovingObjectPosition.EnumMovingObjectType.BLOCK) { + BlockPosition pos = ((MovingObjectPositionBlock) rayTrace).getBlockPosition(); + loc = new Vec3D(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D); + } else if (rayTrace.getType() == MovingObjectPosition.EnumMovingObjectType.ENTITY) { + Entity target = ((MovingObjectPositionEntity) rayTrace).getEntity(); + loc = new Vec3D(target.locX(), target.locY() + (target.getHeadHeight() / 2), target.locZ()); + } else { + org.bukkit.block.Block block = player.getTargetBlock(null, 120); + loc = new Vec3D(block.getX() + 0.5D, block.getY() + 0.5D, block.getZ() + 0.5D); + } + + for (int head : heads) { + shoot(head, loc.getX(), loc.getY(), loc.getZ(), rider); + } + + return true; // handled + } + + public void shoot(int head, double x, double y, double z, EntityHuman rider) { + world.playEvent(null, 1024, getChunkCoordinates(), 0); + double headX = getHeadX(head); + double headY = getHeadY(head); + double headZ = getHeadZ(head); + EntityWitherSkull skull = new EntityWitherSkull(world, this, x - headX, y - headY, z - headZ) { + @Override + public boolean canSaveToDisk() { + return false; + } + + @Override + public boolean hitPredicate(Entity target) { + // do not hit rider + return target != rider && super.hitPredicate(target); + } + }; + skull.setPositionRaw(headX, headY, headZ); + world.addEntity(skull); + } + // Purpur end + @Override protected void initPathfinder() { - this.goalSelector.a(0, new EntityWither.a()); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur + this.goalSelector.a(1, new EntityWither.a()); // Purpur this.goalSelector.a(2, new PathfinderGoalArrowAttack(this, 1.0D, 40, 20.0F)); this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 1.0D)); this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(7, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[0])); if(this.world.paperConfig.fixWitherTargetingBug) this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 0, false, false, null)); // Paper - Fix MC-29274 this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityInsentient.class, 0, false, false, EntityWither.by)); @@ -245,6 +358,16 @@ public class EntityWither extends EntityMonster implements IRangedEntity { @Override protected void mobTick() { + // Purpur start + if (hasPurpurRider()) { + Vec3D mot = getMot(); + setMot(mot.x, mot.y + (getVertical() > 0 ? 0.07D : 0.0D), mot.z); + } + if (shootCooldown > 0) { + shootCooldown--; + } + // Purpur end + int i; if (this.getInvul() > 0) { @@ -428,7 +551,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity { this.bossBattle.removePlayer(entityplayer); } - private double u(int i) { + private double u(int i) { return getHeadX(i); } private double getHeadX(int i) { // Purpur - OBFHELPER if (i <= 0) { return this.locX(); } else { @@ -439,11 +562,11 @@ public class EntityWither extends EntityMonster implements IRangedEntity { } } - private double v(int i) { + private double v(int i) { return getHeadY(i); } private double getHeadY(int i) { // Purpur - OBFHELPER return i <= 0 ? this.locY() + 3.0D : this.locY() + 2.2D; } - private double w(int i) { + private double w(int i) { return getHeadZ(i); } private double getHeadZ(int i) { // Purpur - OBFHELPER if (i <= 0) { return this.locZ(); } else { @@ -567,7 +690,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity { } public static AttributeProvider.Builder eK() { - return EntityMonster.eR().a(GenericAttributes.MAX_HEALTH, 300.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.6000000238418579D).a(GenericAttributes.FOLLOW_RANGE, 40.0D).a(GenericAttributes.ARMOR, 4.0D); + return EntityMonster.eR().a(GenericAttributes.MAX_HEALTH, 300.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.6000000238418579D).a(GenericAttributes.FOLLOW_RANGE, 40.0D).a(GenericAttributes.ARMOR, 4.0D).a(GenericAttributes.FLYING_SPEED, 0.6D); // Purpur } public int getInvul() { @@ -579,11 +702,11 @@ public class EntityWither extends EntityMonster implements IRangedEntity { } public int getHeadTarget(int i) { - return (Integer) this.datawatcher.get((DataWatcherObject) EntityWither.bo.get(i)); + return hasPurpurRider() ? 0 : this.datawatcher.get(EntityWither.bo.get(i)); // Purpur } public void setHeadTarget(int i, int j) { - this.datawatcher.set((DataWatcherObject) EntityWither.bo.get(i), j); + if (!hasPurpurRider()) this.datawatcher.set(EntityWither.bo.get(i), j); // Purpur } public final boolean isPowered() { return this.S_(); } // Paper - OBFHELPER diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityBlaze.java b/src/main/java/net/minecraft/world/entity/monster/EntityBlaze.java index 88a4dcf9feaa5f66da1394c139b795582c00a8ac..6553fd92c26d71ac0a60bd046c7f968f2dfe6667 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityBlaze.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityBlaze.java @@ -5,6 +5,7 @@ import net.minecraft.core.particles.Particles; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; import net.minecraft.util.MathHelper; @@ -12,6 +13,7 @@ import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityLiving; import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.entity.EnumMoveType; import net.minecraft.world.entity.ai.attributes.AttributeProvider; import net.minecraft.world.entity.ai.attributes.GenericAttributes; import net.minecraft.world.entity.ai.goal.PathfinderGoal; @@ -35,6 +37,7 @@ public class EntityBlaze extends EntityMonster { public EntityBlaze(EntityTypes entitytypes, World world) { super(entitytypes, world); + this.moveController = new net.pl3x.purpur.controller.ControllerMoveWASDFlyingWithSpacebar(this, 0.3F); // Purpur this.a(PathType.WATER, -1.0F); this.a(PathType.LAVA, 8.0F); this.a(PathType.DANGER_FIRE, 0.0F); @@ -42,19 +45,50 @@ public class EntityBlaze extends EntityMonster { this.f = 10; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.blazeRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.blazeRidableInWater; + } + + @Override + public double getMaxY() { + return world.purpurConfig.blazeMaxY; + } + + @Override + public void g(Vec3D vec3d) { + super.g(vec3d); + if (hasPurpurRider() && !onGround) { + float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue(); + setSpeed(speed); + Vec3D mot = getMot(); + move(EnumMoveType.SELF, mot.multiply(speed, 1.0, speed)); + setMot(mot.a(0.9D)); + } + } + // Purpur end + @Override protected void initPathfinder() { + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(4, new EntityBlaze.PathfinderGoalBlazeFireball(this)); this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0D)); this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D, 0.0F)); this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); - this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a()); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur + this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // Purpur - decompile error this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); } public static AttributeProvider.Builder m() { - return EntityMonster.eR().a(GenericAttributes.ATTACK_DAMAGE, 6.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.23000000417232513D).a(GenericAttributes.FOLLOW_RANGE, 48.0D); + return EntityMonster.eR().a(GenericAttributes.ATTACK_DAMAGE, 6.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.23000000417232513D).a(GenericAttributes.FOLLOW_RANGE, 48.0D).a(GenericAttributes.FLYING_SPEED, 0.6D); // Purpur } @Override @@ -109,6 +143,14 @@ public class EntityBlaze extends EntityMonster { @Override protected void mobTick() { + // Purpur start + if (hasPurpurRider()) { + Vec3D mot = getMot(); + setMot(mot.x, getVertical() > 0 ? 0.07D : -0.07D, mot.z); + return; + } + // Purpur end + --this.c; if (this.c <= 0) { this.c = 100; diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityCaveSpider.java b/src/main/java/net/minecraft/world/entity/monster/EntityCaveSpider.java index 65d0027186f19f10292ea64976ebb93c12b98394..27baf5cde99d8f25b1e7583c30339fcc71a3786f 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityCaveSpider.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityCaveSpider.java @@ -24,6 +24,18 @@ public class EntityCaveSpider extends EntitySpider { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.caveSpiderRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.caveSpiderRidableInWater; + } + // Purpur end + public static AttributeProvider.Builder m() { return EntitySpider.eK().a(GenericAttributes.MAX_HEALTH, 12.0D); } diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityCreeper.java b/src/main/java/net/minecraft/world/entity/monster/EntityCreeper.java index 09df2bd3b523072de0e9858e6e707e3721474422..1daacdd75c709cd5508434b41589bd57032de27c 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityCreeper.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityCreeper.java @@ -6,6 +6,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -58,12 +59,27 @@ public class EntityCreeper extends EntityMonster { public int maxFuseTicks = 30; public int explosionRadius = 3; private int bs; + // Purpur start + private int spacebarCharge = 0; + private int prevSpacebarCharge = 0; + private int powerToggleDelay = 0; + // Purpur end public EntityCreeper(EntityTypes entitytypes, World world) { super(entitytypes, world); } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.creeperRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.creeperRidableInWater; + } + @Override public GroupDataEntity prepare(WorldAccess worldaccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @javax.annotation.Nullable GroupDataEntity groupdataentity, @javax.annotation.Nullable NBTTagCompound nbttagcompound) { double chance = worldaccess.getMinecraftWorld().purpurConfig.creeperChargedChance; @@ -72,18 +88,69 @@ public class EntityCreeper extends EntityMonster { } return super.prepare(worldaccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); } + + @Override + protected void mobTick() { + if (powerToggleDelay > 0) { + powerToggleDelay--; + } + if (hasPurpurRider()) { + if (getPurpurRider().getForward() != 0 || getPurpurRider().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 (getPurpurRider().getBukkitEntity().hasPermission("allow.powered.creeper")) { + powerToggleDelay = 20; + setPowered(!isPowered()); + setIgnited(false); + return true; + } + } + if (!isIgnited()) { + if (hasPurpurRider() && getPurpurRider().getForward() == 0 && getPurpurRider().getStrafe() == 0 && + getPurpurRider().getBukkitEntity().hasPermission("allow.special.creeper")) { + setIgnited(true); + return true; + } + } + return getForward() == 0 && getStrafe() == 0; // do not jump if standing still + } // Purpur end @Override protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalFloat(this)); this.goalSelector.a(2, new PathfinderGoalSwell(this)); + this.goalSelector.a(3, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityOcelot.class, 6.0F, 1.0D, 1.2D)); this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityCat.class, 6.0F, 1.0D, 1.2D)); this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, 1.0D, false)); this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 0.8D)); this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, new Class[0])); } @@ -214,6 +281,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); } @@ -314,6 +382,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/world/entity/monster/EntityDrowned.java b/src/main/java/net/minecraft/world/entity/monster/EntityDrowned.java index ea776755767f29e49de2792afa30f79420d0fa4c..1d4039d61a2c77a38a31947010cee26f41c0becd 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityDrowned.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityDrowned.java @@ -73,6 +73,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; @@ -270,7 +280,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; @@ -280,7 +290,7 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity { } @Override - public void a() { + public void tick() { // Purpur EntityLiving entityliving = this.i.getGoalTarget(); if (this.i.eW() && this.i.isInWater()) { @@ -313,7 +323,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 } } @@ -452,6 +462,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/world/entity/monster/EntityEnderman.java b/src/main/java/net/minecraft/world/entity/monster/EntityEnderman.java index 52aa47036acee2ec21ae2d6f4df634ecbf04b3b0..32ed22dbaaed536dd3df0fb59e3c19431ee42540 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityEnderman.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityEnderman.java @@ -16,6 +16,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -85,9 +86,22 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { this.a(PathType.WATER, -1.0F); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.endermanRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.endermanRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new EntityEnderman.a(this)); this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0D, false)); this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D, 0.0F)); @@ -95,6 +109,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); this.goalSelector.a(10, new EntityEnderman.PathfinderGoalEndermanPlaceBlock(this)); this.goalSelector.a(11, new EntityEnderman.PathfinderGoalEndermanPickupBlock(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new EntityEnderman.PathfinderGoalPlayerWhoLookedAtTarget(this, this::a_)); this.targetSelector.a(2, new PathfinderGoalHurtByTarget(this, new Class[0])); this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityEndermite.class, 10, true, false, EntityEnderman.bq)); @@ -275,7 +290,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { @Override protected void mobTick() { - if (this.world.isDay() && this.ticksLived >= this.bs + 600) { + if (!hasPurpurRider() && this.world.isDay() && this.ticksLived >= this.bs + 600) { // Purpur - no random teleporting float f = this.aR(); if (f > 0.5F && this.world.e(this.getChunkCoordinates()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper @@ -384,6 +399,7 @@ public class EntityEnderman extends EntityMonster implements IEntityAngerable { if (this.isInvulnerable(damagesource)) { return false; } else if (net.pl3x.purpur.PurpurConfig.endermanShortHeight && damagesource == DamageSource.STUCK) { return false; // Purpur - no suffocation damage if short height + } else if (hasPurpurRider()) { 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) { @@ -428,6 +444,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 @@ -470,6 +487,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/world/entity/monster/EntityEndermite.java b/src/main/java/net/minecraft/world/entity/monster/EntityEndermite.java index 906ac1f861241a184819b4b113abe56625ff5e60..1c87bea9de812e57f8ccd3c9aa85330af87ed240 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityEndermite.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityEndermite.java @@ -4,6 +4,7 @@ import java.util.Random; import net.minecraft.core.BlockPosition; import net.minecraft.core.particles.Particles; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; import net.minecraft.world.damagesource.DamageSource; @@ -36,14 +37,28 @@ public class EntityEndermite extends EntityMonster { this.f = 3; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.endermiteRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.endermiteRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0D, false)); this.goalSelector.a(3, new PathfinderGoalRandomStrollLand(this, 1.0D)); this.goalSelector.a(7, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); - this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a()); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur + this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // Purpur - decompile error this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); } diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityEvoker.java b/src/main/java/net/minecraft/world/entity/monster/EntityEvoker.java index 2aa6b6ca93c25c59ad224348aad1bb34d9bbc6a3..55607910183155080e3d96296421438d17f19c8f 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityEvoker.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityEvoker.java @@ -5,6 +5,7 @@ import javax.annotation.Nullable; import net.minecraft.core.BlockPosition; import net.minecraft.core.EnumDirection; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -19,6 +20,7 @@ import net.minecraft.world.entity.EnumMonsterType; import net.minecraft.world.entity.GroupDataEntity; import net.minecraft.world.entity.ai.attributes.AttributeProvider; import net.minecraft.world.entity.ai.attributes.GenericAttributes; +import net.minecraft.world.entity.ai.goal.PathfinderGoal; import net.minecraft.world.entity.ai.goal.PathfinderGoalAvoidTarget; import net.minecraft.world.entity.ai.goal.PathfinderGoalFloat; import net.minecraft.world.entity.ai.goal.PathfinderGoalLookAtPlayer; @@ -47,10 +49,23 @@ public class EntityEvoker extends EntityIllagerWizard { this.f = 10; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.evokerRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.evokerRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new EntityEvoker.b()); this.goalSelector.a(2, new PathfinderGoalAvoidTarget<>(this, EntityHuman.class, 8.0F, 0.6D, 1.0D)); this.goalSelector.a(4, new EntityEvoker.c()); @@ -59,6 +74,7 @@ public class EntityEvoker extends EntityIllagerWizard { this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D)); this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F)); this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // Paper - decompile fix this.targetSelector.a(2, (new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)).a(300)); this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)).a(300)); @@ -139,6 +155,7 @@ public class EntityEvoker extends EntityIllagerWizard { public d() { super(); + this.a(java.util.EnumSet.of(PathfinderGoal.Type.UNKNOWN_BEHAVIOR)); // Purpur - wolololo spell } @Override @@ -217,6 +234,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 @@ -273,6 +291,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/world/entity/monster/EntityGhast.java b/src/main/java/net/minecraft/world/entity/monster/EntityGhast.java index a3e3f6e07674c54c2d2a02661ce4342b43aafe44..b6d49740a1c8dfa19e871869b92b307fc8397588 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityGhast.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityGhast.java @@ -7,6 +7,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundCategory; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -21,6 +22,7 @@ import net.minecraft.world.entity.EntityPose; import net.minecraft.world.entity.EntitySize; import net.minecraft.world.entity.EntityTypes; import net.minecraft.world.entity.EnumMobSpawn; +import net.minecraft.world.entity.EnumMoveType; import net.minecraft.world.entity.ai.attributes.AttributeProvider; import net.minecraft.world.entity.ai.attributes.GenericAttributes; import net.minecraft.world.entity.ai.control.ControllerMove; @@ -44,11 +46,42 @@ public class EntityGhast extends EntityFlying implements IMonster { this.moveController = new EntityGhast.ControllerGhast(this); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.ghastRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.ghastRidableInWater; + } + + @Override + public double getMaxY() { + return world.purpurConfig.ghastMaxY; + } + + @Override + public void g(Vec3D vec3d) { + super.g(vec3d); + if (hasPurpurRider() && !onGround) { + float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue(); + setSpeed(speed); + Vec3D mot = getMot(); + move(EnumMoveType.SELF, mot.multiply(speed, 1.0, speed)); + setMot(mot.a(0.9D)); + } + } + // Purpur end + @Override protected void initPathfinder() { + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(5, new EntityGhast.PathfinderGoalGhastIdleMove(this)); this.goalSelector.a(7, new EntityGhast.PathfinderGoalGhastMoveTowardsTarget(this)); this.goalSelector.a(7, new EntityGhast.PathfinderGoalGhastAttackTarget(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, (entityliving) -> { return Math.abs(entityliving.locY() - this.locY()) <= 4.0D; })); @@ -86,7 +119,7 @@ public class EntityGhast extends EntityFlying implements IMonster { } public static AttributeProvider.Builder eJ() { - return EntityInsentient.p().a(GenericAttributes.MAX_HEALTH, 10.0D).a(GenericAttributes.FOLLOW_RANGE, 100.0D); + return EntityInsentient.p().a(GenericAttributes.MAX_HEALTH, 10.0D).a(GenericAttributes.FOLLOW_RANGE, 100.0D).a(GenericAttributes.FLYING_SPEED, 0.6D); // Purpur } @Override @@ -285,7 +318,7 @@ public class EntityGhast extends EntityFlying implements IMonster { } } - static class ControllerGhast extends ControllerMove { + static class ControllerGhast extends net.pl3x.purpur.controller.ControllerMoveWASDFlying { // Purpur private final EntityGhast i; private int j; @@ -296,7 +329,7 @@ public class EntityGhast extends EntityFlying implements IMonster { } @Override - public void a() { + public void tick() { // Purpur if (this.h == ControllerMove.Operation.MOVE_TO) { if (this.j-- <= 0) { this.j += this.i.getRandom().nextInt(5) + 2; diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityGiantZombie.java b/src/main/java/net/minecraft/world/entity/monster/EntityGiantZombie.java index a188a89143cb1b0243dacdec33c446ca4120219f..7395fa90198a9138b2c33273d8f3540355300029 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityGiantZombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityGiantZombie.java @@ -2,6 +2,7 @@ package net.minecraft.world.entity.monster; import net.minecraft.core.BlockPosition; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.world.DifficultyDamageScaler; import net.minecraft.world.EnumDifficulty; import net.minecraft.world.entity.EntityPose; @@ -41,16 +42,28 @@ public class EntityGiantZombie extends EntityMonster { } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.giantRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.giantRidableInWater; + } + @Override protected void initPathfinder() { if (world.purpurConfig.giantHaveAI) { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(7, new PathfinderGoalRandomStrollLand(this, 1.0D)); this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 16.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); this.goalSelector.a(5, new PathfinderGoalMoveTowardsRestriction(this, 1.0D)); if (world.purpurConfig.giantHaveHostileAI) { this.goalSelector.a(2, new PathfinderGoalMeleeAttack(this, 1.0D, false)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this).a(EntityPigZombie.class)); this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillager.class, false)); diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityGuardian.java b/src/main/java/net/minecraft/world/entity/monster/EntityGuardian.java index d53e2a9d27f9976d1fd8ea30b88a0da089aec7b6..66ae664add95f4441724b49a470a2fef569042d6 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityGuardian.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityGuardian.java @@ -9,6 +9,7 @@ import net.minecraft.core.particles.Particles; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; import net.minecraft.tags.Tag; @@ -63,15 +64,36 @@ public class EntityGuardian extends EntityMonster { this.f = 10; this.a(PathType.WATER, 0.0F); this.moveController = new EntityGuardian.ControllerMoveGuardian(this); + // Purpur start + this.lookController = new net.pl3x.purpur.controller.ControllerLookWASD(this) { + @Override + public void setYawPitch(float yaw, float pitch) { + super.setYawPitch(yaw, pitch * 0.35F); + } + }; + // Purpur end this.bo = this.random.nextFloat(); this.bp = this.bo; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.guardianRidable; + } + + @Override + public boolean isRidableInWater() { + return true; + } + // Purpur end + @Override protected void initPathfinder() { PathfinderGoalMoveTowardsRestriction pathfindergoalmovetowardsrestriction = new PathfinderGoalMoveTowardsRestriction(this, 1.0D); this.goalRandomStroll = new PathfinderGoalRandomStroll(this, 1.0D, 80); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(4, new EntityGuardian.PathfinderGoalGuardianAttack(this)); this.goalSelector.a(5, pathfindergoalmovetowardsrestriction); this.goalSelector.a(7, this.goalRandomStroll); @@ -80,6 +102,7 @@ public class EntityGuardian extends EntityMonster { this.goalSelector.a(9, new PathfinderGoalRandomLookaround(this)); this.goalRandomStroll.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK)); pathfindergoalmovetowardsrestriction.a(EnumSet.of(PathfinderGoal.Type.MOVE, PathfinderGoal.Type.LOOK)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityLiving.class, 10, true, false, new EntityGuardian.EntitySelectorGuardianTargetHumanSquid(this))); } @@ -113,6 +136,7 @@ public class EntityGuardian extends EntityMonster { return (Boolean) this.datawatcher.get(EntityGuardian.b); } + private void setMovingFlag(boolean movingFlag) { t(movingFlag); } // Purpur - OBFHELPER private void t(boolean flag) { this.datawatcher.set(EntityGuardian.b, flag); } @@ -327,7 +351,7 @@ public class EntityGuardian extends EntityMonster { @Override public void g(Vec3D vec3d) { if (this.doAITick() && this.isInWater()) { - this.a(0.1F, vec3d); + this.a(hasPurpurRider() ? getSpeed() : 0.1F, vec3d); // Purpur this.move(EnumMoveType.SELF, this.getMot()); this.setMot(this.getMot().a(0.9D)); if (!this.eN() && this.getGoalTarget() == null) { @@ -339,17 +363,26 @@ public class EntityGuardian extends EntityMonster { } - static class ControllerMoveGuardian extends ControllerMove { + static class ControllerMoveGuardian extends net.pl3x.purpur.controller.ControllerMoveWASDWater { // Purpur - private final EntityGuardian i; + private final EntityGuardian i; private EntityGuardian getGuardian() { return i; } // Purpur - OBFHELPER public ControllerMoveGuardian(EntityGuardian entityguardian) { super(entityguardian); this.i = entityguardian; } + // Purpur start + @Override + public void tick(EntityHuman rider) { + super.tick(rider); + getGuardian().setMot(getGuardian().getMot().add(0.0D, 0.005D, 0.0D)); + getGuardian().setMovingFlag(getGuardian().getForward() > 0.0F); // control tail speed + } + // Purpur end + @Override - public void a() { + public void tick() { // Purpur if (this.h == ControllerMove.Operation.MOVE_TO && !this.i.getNavigation().m()) { Vec3D vec3d = new Vec3D(this.b - this.i.locX(), this.c - this.i.locY(), this.d - this.i.locZ()); double d0 = vec3d.f(); diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityGuardianElder.java b/src/main/java/net/minecraft/world/entity/monster/EntityGuardianElder.java index 9bd6f5d988c1e50e1bb729c407178b9cbcc62115..16b8606be2835dccdfa75f29827be4b88aaa1810 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityGuardianElder.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityGuardianElder.java @@ -30,6 +30,18 @@ public class EntityGuardianElder extends EntityGuardian { } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.elderGuardianRidable; + } + + @Override + public boolean isRidableInWater() { + return true; + } + // Purpur end + public static AttributeProvider.Builder m() { return EntityGuardian.eM().a(GenericAttributes.MOVEMENT_SPEED, 0.30000001192092896D).a(GenericAttributes.ATTACK_DAMAGE, 8.0D).a(GenericAttributes.MAX_HEALTH, 80.0D); } diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityIllagerIllusioner.java b/src/main/java/net/minecraft/world/entity/monster/EntityIllagerIllusioner.java index cb092bee9d6827d4b0276bfa9b033cf7ca86ead4..5186d9957c94be359da5b08fd821e9471c159f03 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityIllagerIllusioner.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityIllagerIllusioner.java @@ -3,6 +3,7 @@ package net.minecraft.world.entity.monster; import javax.annotation.Nullable; import net.minecraft.core.particles.Particles; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; import net.minecraft.util.MathHelper; @@ -57,6 +58,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() { this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(this.world.purpurConfig.illusionerMovementSpeed); @@ -69,6 +80,7 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan protected void initPathfinder() { super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new EntityIllagerWizard.b()); this.goalSelector.a(4, new EntityIllagerIllusioner.b()); this.goalSelector.a(5, new EntityIllagerIllusioner.a()); @@ -76,6 +88,7 @@ public class EntityIllagerIllusioner extends EntityIllagerWizard implements IRan this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D)); this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F)); this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error this.targetSelector.a(2, (new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)).a(300)); this.targetSelector.a(3, (new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)).a(300)); diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityMagmaCube.java b/src/main/java/net/minecraft/world/entity/monster/EntityMagmaCube.java index fe80e93b00f3bb2f297c6528c3951313fa3c08c7..15ed51a2746c09538a425fce25fa25f2619b7033 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityMagmaCube.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityMagmaCube.java @@ -29,6 +29,23 @@ public class EntityMagmaCube extends EntitySlime { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.magmaCubeRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.magmaCubeRidableInWater; + } + + @Override + public float getJumpHeight() { + return 0.42F * this.getBlockJumpFactor(); // from EntityLiving + } + // Purpur end + public static AttributeProvider.Builder m() { return EntityMonster.eR().a(GenericAttributes.MOVEMENT_SPEED, 0.20000000298023224D); } @@ -79,11 +96,12 @@ public class EntityMagmaCube extends EntitySlime { } @Override - protected void jump() { + public void jump() { // Purpur - protected -> public Vec3D vec3d = this.getMot(); this.setMot(vec3d.x, (double) (this.dJ() + (float) this.getSize() * 0.1F), vec3d.z); this.impulse = true; + this.actualJump = false; // Purpur } @Override diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityPhantom.java b/src/main/java/net/minecraft/world/entity/monster/EntityPhantom.java index fd2e3a4abcfedaf04db4277291983627c097b545..1ea3054cebbf32588219f8915f9fb496495e3a10 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityPhantom.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityPhantom.java @@ -13,6 +13,7 @@ import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; import net.minecraft.server.level.WorldServer; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundCategory; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -29,11 +30,11 @@ import net.minecraft.world.entity.EntitySize; import net.minecraft.world.entity.EntityTypes; import net.minecraft.world.entity.EnumMobSpawn; import net.minecraft.world.entity.EnumMonsterType; +import net.minecraft.world.entity.EnumMoveType; import net.minecraft.world.entity.GroupDataEntity; import net.minecraft.world.entity.IEntitySelector; +import net.minecraft.world.entity.ai.attributes.AttributeProvider; import net.minecraft.world.entity.ai.attributes.GenericAttributes; -import net.minecraft.world.entity.ai.control.ControllerLook; -import net.minecraft.world.entity.ai.control.ControllerMove; import net.minecraft.world.entity.ai.control.EntityAIBodyControl; import net.minecraft.world.entity.ai.goal.PathfinderGoal; import net.minecraft.world.entity.ai.targeting.PathfinderTargetCondition; @@ -68,6 +69,59 @@ public class EntityPhantom extends EntityFlying implements IMonster { this.lookController = new EntityPhantom.f(this); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.phantomRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.phantomRidableInWater; + } + + @Override + public double getMaxY() { + return world.purpurConfig.phantomMaxY; + } + + @Override + public void g(Vec3D vec3d) { + super.g(vec3d); + if (hasPurpurRider() && !onGround) { + float speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue(); + setSpeed(speed); + Vec3D mot = getMot(); + move(EnumMoveType.SELF, mot.multiply(speed, speed, speed)); + setMot(mot.a(0.9D)); + } + } + + public static AttributeProvider.Builder defaultAttributes() { + return EntityMonster.eR().a(GenericAttributes.FLYING_SPEED, 3.0D); + } + + @Override + public boolean onSpacebar() { + if (hasPurpurRider() && getPurpurRider().getBukkitEntity().hasPermission("allow.special.phantom")) { + shoot(); + } + return false; + } + + public boolean shoot() { + org.bukkit.Location loc = ((org.bukkit.entity.LivingEntity) getBukkitEntity()).getEyeLocation(); + loc.setPitch(-loc.getPitch()); + org.bukkit.util.Vector target = loc.getDirection().normalize().multiply(100).add(loc.toVector()); + + net.pl3x.purpur.entity.PhantomFlames flames = new net.pl3x.purpur.entity.PhantomFlames(world, this); + flames.canGrief = world.purpurConfig.phantomAllowGriefing; + flames.shoot(target.getX() - locX(), target.getY() - locY(), target.getZ() - locZ(), 1.0F, 5.0F); + world.addEntity(flames); + return true; + } + // Purpur end + @Override protected EntityAIBodyControl r() { return new EntityPhantom.d(this); @@ -76,6 +130,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { @Override protected void initPathfinder() { // Purpur start + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); if (world.purpurConfig.phantomOrbitCrystalRadius > 0) { this.goalSelector.a(1, new FindCrystalGoal(this)); this.goalSelector.a(2, new OrbitCrystalGoal(this)); @@ -83,6 +138,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { this.goalSelector.a(3, new EntityPhantom.c()); // PickAttackGoal this.goalSelector.a(4, new EntityPhantom.i()); // SweepAttackGoal this.goalSelector.a(5, new EntityPhantom.e()); // OrbitPointGoal + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); this.targetSelector.a(1, new EntityPhantom.b()); // AttackPlayer Goal // Purpur end } @@ -169,7 +225,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { @Override public void movementTick() { - if (this.isAlive() && (((shouldBurnInDay || world.purpurConfig.phantomBurnInDaylight) && this.isInDaylight()) || (world.purpurConfig.phantomBurnInLight > 0 && world.getLightLevel(new BlockPosition(this)) >= world.purpurConfig.phantomBurnInLight))) { // Paper - Configurable Burning // Purpur + if (this.isAlive() && !hasPurpurRider() && (((shouldBurnInDay || world.purpurConfig.phantomBurnInDaylight) && this.isInDaylight()) || (world.purpurConfig.phantomBurnInLight > 0 && world.getLightLevel(new BlockPosition(this)) >= world.purpurConfig.phantomBurnInLight))) { // Paper - Configurable Burning // Purpur this.setOnFire(8); } @@ -418,7 +474,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { @Override public boolean a() { - if (isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag + if (getPurpurRider() != null || isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag if (this.c > 0) { --this.c; return false; @@ -447,7 +503,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { @Override public boolean b() { - if (isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag + if (getPurpurRider() != null || isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag EntityLiving entityliving = EntityPhantom.this.getGoalTarget(); return entityliving != null ? EntityPhantom.this.a(entityliving, PathfinderTargetCondition.a) : false; @@ -462,7 +518,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { @Override public boolean a() { - if (isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag + if (getPurpurRider() != null || isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag EntityLiving entityliving = EntityPhantom.this.getGoalTarget(); return entityliving != null ? EntityPhantom.this.a(EntityPhantom.this.getGoalTarget(), PathfinderTargetCondition.a) : false; @@ -660,14 +716,23 @@ public class EntityPhantom extends EntityFlying implements IMonster { } } - class f extends ControllerLook { + class f extends net.pl3x.purpur.controller.ControllerLookWASD { // Purpur public f(EntityInsentient entityinsentient) { super(entityinsentient); } @Override - public void a() {} + // Purpur start + public void tick(EntityHuman rider) { + setYawPitch(rider.yaw, -rider.pitch * 0.75F); + } + + @Override + public void tick() { + // do nothing + } + // Purpur end } class d extends EntityAIBodyControl { @@ -683,7 +748,7 @@ public class EntityPhantom extends EntityFlying implements IMonster { } } - class g extends ControllerMove { + class g extends net.pl3x.purpur.controller.ControllerMoveWASDFlying { // Purpur private float j = 0.1F; @@ -692,7 +757,19 @@ public class EntityPhantom extends EntityFlying implements IMonster { } @Override - public void a() { + // Purpur start + public void tick(EntityHuman rider) { + if (!EntityPhantom.this.onGround) { + // phantom is always in motion when flying + // TODO - FIX THIS + // rider.setForward(1.0F); + } + super.tick(rider); + } + + @Override + public void tick() { + // Purpur end if (EntityPhantom.this.positionChanged) { EntityPhantom.this.yaw += 180.0F; this.j = 0.1F; diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityPigZombie.java b/src/main/java/net/minecraft/world/entity/monster/EntityPigZombie.java index ee17e62d996d81ea149a5c0eae2e29404e363dcf..9f50054211db48e7fe764434e8d71aab0995e57a 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityPigZombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityPigZombie.java @@ -57,6 +57,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/world/entity/monster/EntityPillager.java b/src/main/java/net/minecraft/world/entity/monster/EntityPillager.java index ea105fb86553f5212d616c976eaf2a16bf5b6561..2a4ac6e608650d56cc2b564e715b7b685e7f3f62 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityPillager.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityPillager.java @@ -9,6 +9,7 @@ import net.minecraft.nbt.NBTTagList; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; import net.minecraft.world.DifficultyDamageScaler; @@ -61,15 +62,29 @@ public class EntityPillager extends EntityIllagerAbstract implements ICrossbow { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.pillagerRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.pillagerRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(2, new EntityRaider.a(this, 10.0F)); this.goalSelector.a(3, new PathfinderGoalCrossbowAttack<>(this, 1.0D, 8.0F)); this.goalSelector.a(8, new PathfinderGoalRandomStroll(this, 0.6D)); this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 15.0F, 1.0F)); this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 15.0F)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, false)); diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityRavager.java b/src/main/java/net/minecraft/world/entity/monster/EntityRavager.java index 16d5cae64887b82e67eeb61ccb714e6125ff0c09..cc37e545ece89803fad91801775470df4620bd62 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityRavager.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityRavager.java @@ -7,6 +7,7 @@ import javax.annotation.Nullable; import net.minecraft.core.BlockPosition; import net.minecraft.core.particles.Particles; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; import net.minecraft.tags.Tag; @@ -38,7 +39,6 @@ import net.minecraft.world.level.IBlockAccess; import net.minecraft.world.level.IWorldReader; import net.minecraft.world.level.World; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.BlockLeaves; import net.minecraft.world.level.block.state.IBlockData; import net.minecraft.world.level.pathfinder.PathType; import net.minecraft.world.level.pathfinder.Pathfinder; @@ -61,14 +61,37 @@ public class EntityRavager extends EntityRaider { this.f = 20; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.ravagerRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.ravagerRidableInWater; + } + + @Override + public void onMount(EntityHuman entityhuman) { + super.onMount(entityhuman); + getNavigation().stopPathfinding(); + + double speed = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getBaseValue(); + getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(speed); + } + // Purpur end + @Override protected void initPathfinder() { super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(4, new EntityRavager.a()); this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 0.4D)); this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 6.0F)); this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(2, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); this.targetSelector.a(4, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, true)); @@ -140,7 +163,7 @@ public class EntityRavager extends EntityRaider { @Override public void movementTick() { super.movementTick(); - if (this.isAlive()) { + if (this.isAlive() && !hasPurpurRider()) { if (this.isFrozen()) { this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.0D); } else { diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityShulker.java b/src/main/java/net/minecraft/world/entity/monster/EntityShulker.java index 49523302dd72a3dafab23c047412a2e77b6247ed..4b5c1691664f16594f316e55576086f2ae54e59e 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityShulker.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityShulker.java @@ -12,6 +12,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundCategory; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -71,12 +72,26 @@ public class EntityShulker extends EntityGolem implements IMonster { this.f = 5; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.shulkerRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.shulkerRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(4, new EntityShulker.a()); this.goalSelector.a(7, new EntityShulker.e()); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error this.targetSelector.a(2, new EntityShulker.d(this)); this.targetSelector.a(3, new EntityShulker.c(this)); @@ -560,7 +575,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/world/entity/monster/EntitySilverfish.java b/src/main/java/net/minecraft/world/entity/monster/EntitySilverfish.java index e1fcb1be102822e87eaf7757fbd64a516b2f58ac..c0601af022d85c7b03463f0df975d713c0366b2c 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntitySilverfish.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntitySilverfish.java @@ -4,6 +4,7 @@ import java.util.EnumSet; import java.util.Random; import net.minecraft.core.BlockPosition; import net.minecraft.core.EnumDirection; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; import net.minecraft.world.damagesource.DamageSource; @@ -38,13 +39,27 @@ public class EntitySilverfish extends EntityMonster { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.silverfishRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.silverfishRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.b = new EntitySilverfish.PathfinderGoalSilverfishWakeOthers(this); this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(3, this.b); this.goalSelector.a(4, new PathfinderGoalMeleeAttack(this, 1.0D, false)); this.goalSelector.a(5, new EntitySilverfish.PathfinderGoalSilverfishHideInBlock(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); } @@ -204,6 +219,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/world/entity/monster/EntitySkeleton.java b/src/main/java/net/minecraft/world/entity/monster/EntitySkeleton.java index 342bc9b586ef835e865d6f84bf66f1069ab10f00..0b8517d4e83d14ddf8b6d1f1cf4c538f9e4cc68f 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntitySkeleton.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntitySkeleton.java @@ -15,6 +15,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/world/entity/monster/EntitySkeletonAbstract.java b/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonAbstract.java index f8358e40c42f219232bf928f4e0073339a5e19d5..81059fc3fc22f251b5b08f0cd6814a992cff6b1e 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonAbstract.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonAbstract.java @@ -5,6 +5,7 @@ import java.time.temporal.ChronoField; import javax.annotation.Nullable; import net.minecraft.core.BlockPosition; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; import net.minecraft.util.MathHelper; @@ -70,12 +71,14 @@ public abstract class EntitySkeletonAbstract extends EntityMonster implements IR @Override protected void initPathfinder() { + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(2, new PathfinderGoalRestrictSun(this)); this.goalSelector.a(3, new PathfinderGoalFleeSun(this, 1.0D)); this.goalSelector.a(3, new PathfinderGoalAvoidTarget<>(this, EntityWolf.class, 6.0F, 1.0D, 1.2D)); this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 1.0D)); this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[0])); this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityIronGolem.class, true)); diff --git a/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonStray.java b/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonStray.java index 8481b8fffed3f1f60e2e72e115e79e9ae1aaa635..8484000a1b0d9c252d6fab205b1e316e3f6f33bd 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonStray.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonStray.java @@ -21,6 +21,18 @@ public class EntitySkeletonStray extends EntitySkeletonAbstract { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.strayRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.strayRidableInWater; + } + // Purpur end + public static boolean a(EntityTypes entitytypes, WorldAccess worldaccess, EnumMobSpawn enummobspawn, BlockPosition blockposition, Random random) { return b(entitytypes, worldaccess, enummobspawn, blockposition, random) && (enummobspawn == EnumMobSpawn.SPAWNER || worldaccess.e(blockposition)); } diff --git a/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonWither.java b/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonWither.java index a90ac635ef7aef5289d21f948db7b170b23160d3..cb52c4e63ac487d55dc16accca6976f44f904112 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonWither.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntitySkeletonWither.java @@ -34,6 +34,18 @@ public class EntitySkeletonWither extends EntitySkeletonAbstract { this.a(PathType.LAVA, 8.0F); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.witherSkeletonRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.witherSkeletonRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityPiglinAbstract.class, true)); diff --git a/src/main/java/net/minecraft/world/entity/monster/EntitySlime.java b/src/main/java/net/minecraft/world/entity/monster/EntitySlime.java index 0af0b232ff1b6f1d58cf3fb543d32bd108be0af7..feb40c2ca8e8f3fae5665b2d71296a6b811b11f6 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntitySlime.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntitySlime.java @@ -14,6 +14,7 @@ import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; import net.minecraft.resources.MinecraftKey; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; import net.minecraft.util.MathHelper; @@ -74,12 +75,45 @@ public class EntitySlime extends EntityInsentient implements IMonster { this.moveController = new EntitySlime.ControllerMoveSlime(this); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.slimeRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.slimeRidableInWater; + } + + protected boolean actualJump; + + @Override + public float getJumpHeight() { + float height = super.getJumpHeight(); + return hasPurpurRider() && actualJump ? height * 1.5F : height; + } + + @Override + public boolean onSpacebar() { + if (onGround && hasPurpurRider()) { + actualJump = true; + if (getPurpurRider().getForward() == 0 || getPurpurRider().getStrafe() == 0) { + jump(); // jump() here if not moving + } + } + return true; // do not jump() in wasd controller, let vanilla controller handle + } + // Purpur end + @Override protected void initPathfinder() { + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new EntitySlime.PathfinderGoalSlimeRandomJump(this)); this.goalSelector.a(2, new EntitySlime.PathfinderGoalSlimeNearestPlayer(this)); this.goalSelector.a(3, new EntitySlime.PathfinderGoalSlimeRandomDirection(this)); this.goalSelector.a(5, new EntitySlime.PathfinderGoalSlimeIdle(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, (entityliving) -> { return Math.abs(entityliving.locY() - this.locY()) <= 4.0D; })); @@ -365,11 +399,12 @@ public class EntitySlime extends EntityInsentient implements IMonster { } @Override - protected void jump() { + public void jump() { // Purpur - protected -> public Vec3D vec3d = this.getMot(); this.setMot(vec3d.x, (double) this.dJ(), vec3d.z); this.impulse = true; + this.actualJump = false; // Purpur } @Nullable @@ -538,10 +573,10 @@ public class EntitySlime extends EntityInsentient implements IMonster { // Paper end } - static class ControllerMoveSlime extends ControllerMove { + static class ControllerMoveSlime extends net.pl3x.purpur.controller.ControllerMoveWASD { // Purpur private float i; - private int j; + private int j; private int getJumpDelay() { return j; } private void setJumpDelay(int delay) { j = delay; } // Purpur - OBFHELPER private final EntitySlime k; private boolean l; @@ -563,15 +598,27 @@ public class EntitySlime extends EntityInsentient implements IMonster { @Override public void a() { + // Purpur start + if (entity.hasPurpurRider()) { + tick(entity.getPurpurRider()); + if (entity.getForward() != 0 || entity.getStrafe() != 0) { + if (getJumpDelay() > 10) { + setJumpDelay(6); + } + } else { + setJumpDelay(20); + } + } else { + // Purpur end this.a.yaw = this.a(this.a.yaw, this.i, 90.0F); this.a.aC = this.a.yaw; this.a.aA = this.a.yaw; - if (this.h != ControllerMove.Operation.MOVE_TO) { + } if (!entity.hasPurpurRider() && this.h != ControllerMove.Operation.MOVE_TO) { // Purpur this.a.t(0.0F); } else { this.h = ControllerMove.Operation.WAIT; if (this.a.isOnGround()) { - this.a.q((float) (this.e * this.a.b(GenericAttributes.MOVEMENT_SPEED))); + this.a.q((float) (this.e * this.a.b(GenericAttributes.MOVEMENT_SPEED) * (entity.hasPurpurRider() && (entity.getPurpurRider().getForward() != 0 || entity.getPurpurRider().getStrafe() != 0) ? 2.0D : 1.0D))); // Purpur if (this.j-- <= 0) { this.j = this.k.eJ(); if (this.l) { @@ -588,7 +635,7 @@ public class EntitySlime extends EntityInsentient implements IMonster { this.a.q(0.0F); } } else { - this.a.q((float) (this.e * this.a.b(GenericAttributes.MOVEMENT_SPEED))); + this.a.q((float) (this.e * this.a.b(GenericAttributes.MOVEMENT_SPEED) * (entity.hasPurpurRider() && (entity.getPurpurRider().getForward() != 0 || entity.getPurpurRider().getStrafe() != 0) ? 2.0D : 1.0D))); // Purpur } } diff --git a/src/main/java/net/minecraft/world/entity/monster/EntitySpider.java b/src/main/java/net/minecraft/world/entity/monster/EntitySpider.java index c7b443623f3dd90741e52216199d8ed90bcea6b3..fbf7c31f57f6dbfac997480eb7db55efc15ef4cc 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntitySpider.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntitySpider.java @@ -7,6 +7,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; import net.minecraft.world.DifficultyDamageScaler; @@ -50,14 +51,28 @@ public class EntitySpider extends EntityMonster { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.spiderRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.spiderRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(3, new PathfinderGoalLeapAtTarget(this, 0.4F)); this.goalSelector.a(4, new EntitySpider.PathfinderGoalSpiderMeleeAttack(this)); this.goalSelector.a(5, new PathfinderGoalRandomStrollLand(this, 0.8D)); this.goalSelector.a(6, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(6, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[0])); this.targetSelector.a(2, new EntitySpider.PathfinderGoalSpiderNearestAttackableTarget<>(this, EntityHuman.class)); this.targetSelector.a(3, new EntitySpider.PathfinderGoalSpiderNearestAttackableTarget<>(this, EntityIronGolem.class)); diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityStrider.java b/src/main/java/net/minecraft/world/entity/monster/EntityStrider.java index 5ce50c6fe788fbd6db95f6406bacbf218b7e691c..14dda6743ed9e6f4880bc560f7ba8892d8e84afe 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityStrider.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityStrider.java @@ -13,6 +13,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundCategory; import net.minecraft.sounds.SoundEffect; @@ -94,6 +95,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(); @@ -155,6 +168,7 @@ public class EntityStrider extends EntityAnimal implements ISteerable, ISaddleab @Override protected void initPathfinder() { this.bv = new PathfinderGoalPanic(this, 1.65D); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, this.bv); this.goalSelector.a(2, new PathfinderGoalBreed(this, 1.0D)); this.bu = new PathfinderGoalTempt(this, 1.4D, false, EntityStrider.bp); @@ -434,7 +448,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/world/entity/monster/EntityVex.java b/src/main/java/net/minecraft/world/entity/monster/EntityVex.java index 9645d052069957311478a1ceca42ad52f7a9aa0b..5e2114d2321c1542dc892bc7aed07080008cfd20 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityVex.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityVex.java @@ -7,6 +7,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; import net.minecraft.util.MathHelper; @@ -54,6 +55,45 @@ public class EntityVex extends EntityMonster { this.f = 3; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.vexRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.vexRidableInWater; + } + + @Override + public double getMaxY() { + return world.purpurConfig.vexMaxY; + } + + @Override + public void g(Vec3D vec3d) { + super.g(vec3d); + if (hasPurpurRider()) { + float speed; + if (onGround) { + speed = (float) getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * 0.1F; + } else { + speed = (float) getAttributeInstance(GenericAttributes.FLYING_SPEED).getValue(); + } + setSpeed(speed); + Vec3D mot = getMot(); + move(EnumMoveType.SELF, mot.multiply(speed, 1.0, speed)); + setMot(mot.a(0.9D)); + } + } + + @Override + public boolean b(float f, float f1) { + return false; // no fall damage please + } + // Purpur end + @Override public void move(EnumMoveType enummovetype, Vec3D vec3d) { super.move(enummovetype, vec3d); @@ -62,7 +102,7 @@ public class EntityVex extends EntityMonster { @Override public void tick() { - this.noclip = true; + this.noclip = !hasPurpurRider(); // Purpur super.tick(); this.noclip = false; this.setNoGravity(true); @@ -77,17 +117,19 @@ public class EntityVex extends EntityMonster { protected void initPathfinder() { super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(4, new EntityVex.a()); this.goalSelector.a(8, new EntityVex.d()); this.goalSelector.a(9, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 3.0F, 1.0F)); this.goalSelector.a(10, new PathfinderGoalLookAtPlayer(this, EntityInsentient.class, 8.0F)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // CraftBukkit - decompile error this.targetSelector.a(2, new EntityVex.b(this)); this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); } public static AttributeProvider.Builder m() { - return EntityMonster.eR().a(GenericAttributes.MAX_HEALTH, 14.0D).a(GenericAttributes.ATTACK_DAMAGE, 4.0D); + return EntityMonster.eR().a(GenericAttributes.MAX_HEALTH, 14.0D).a(GenericAttributes.ATTACK_DAMAGE, 4.0D).a(GenericAttributes.FLYING_SPEED, 0.6D); // Purpur } @Override @@ -319,14 +361,14 @@ public class EntityVex extends EntityMonster { } } - class c extends ControllerMove { + class c extends net.pl3x.purpur.controller.ControllerMoveWASDFlying { // Purpur public c(EntityVex entityvex) { super(entityvex); } @Override - public void a() { + public void tick() { // Purpur if (this.h == ControllerMove.Operation.MOVE_TO) { Vec3D vec3d = new Vec3D(this.b - EntityVex.this.locX(), this.c - EntityVex.this.locY(), this.d - EntityVex.this.locZ()); double d0 = vec3d.f(); diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityVindicator.java b/src/main/java/net/minecraft/world/entity/monster/EntityVindicator.java index fe84d6d2b74b6ae00c4c66682107296a40b69adc..28d345e87f45fa839bc3bd758f79f34aba546db7 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityVindicator.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityVindicator.java @@ -8,6 +8,7 @@ import javax.annotation.Nullable; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.chat.ChatMessage; import net.minecraft.network.chat.IChatBaseComponent; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -59,14 +60,28 @@ public class EntityVindicator extends EntityIllagerAbstract { super(entitytypes, world); } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.vindicatorRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.vindicatorRidableInWater; + } + // Purpur end + @Override protected void initPathfinder() { super.initPathfinder(); this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(1, new EntityVindicator.a(this)); this.goalSelector.a(2, new EntityIllagerAbstract.b(this)); this.goalSelector.a(3, new EntityRaider.a(this, 10.0F)); this.goalSelector.a(4, new EntityVindicator.c(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, (new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})).a(new Class[0])); // Paper - decompile fix this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, true)); this.targetSelector.a(3, new PathfinderGoalNearestAttackableTarget<>(this, EntityVillagerAbstract.class, true)); diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityWitch.java b/src/main/java/net/minecraft/world/entity/monster/EntityWitch.java index 63fb08e7b4290353e5148d1acb58f091dc5b08be..c4663c5b02363bd1499ce1f3b50027f8aa7c68e7 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityWitch.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityWitch.java @@ -2,6 +2,7 @@ package net.minecraft.world.entity.monster; // Paper start import com.destroystokyo.paper.event.entity.WitchReadyPotionEvent; +import net.minecraft.server.PathfinderGoalHasRider; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.Witch; // Paper end @@ -63,6 +64,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(); @@ -71,10 +84,12 @@ public class EntityWitch extends EntityRaider implements IRangedEntity { }); this.bs = new PathfinderGoalNearestAttackableTargetWitch<>(this, EntityHuman.class, 10, true, false, (Predicate) null); this.goalSelector.a(1, new PathfinderGoalFloat(this)); + this.goalSelector.a(1, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(2, new PathfinderGoalArrowAttack(this, 1.0D, 60, 10.0F)); this.goalSelector.a(2, new PathfinderGoalRandomStrollLand(this, 1.0D)); this.goalSelector.a(3, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(3, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, new Class[]{EntityRaider.class})); this.targetSelector.a(2, this.br); this.targetSelector.a(3, this.bs); diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityZoglin.java b/src/main/java/net/minecraft/world/entity/monster/EntityZoglin.java index aed585e2c1c88a4d09318c6be7ebe7168eac3631..249fb9cf43527af5c7818ce6b07487ad446811b7 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityZoglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityZoglin.java @@ -62,6 +62,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 cK() { return BehaviorController.a((Collection) EntityZoglin.c, (Collection) EntityZoglin.b); @@ -93,10 +105,10 @@ public class EntityZoglin extends EntityMonster implements IMonster, IOglin { } private Optional eO() { - return ((List) this.getBehaviorController().getMemory(MemoryModuleType.VISIBLE_MOBS).orElse(ImmutableList.of())).stream().filter(EntityZoglin::i).findFirst(); + return (this.getBehaviorController().getMemory(MemoryModuleType.VISIBLE_MOBS).orElse(ImmutableList.of())).stream().filter(EntityZoglin::predicate).findFirst(); // Purpur - decompile error } - private static boolean i(EntityLiving entityliving) { + private static boolean predicate(EntityLiving entityliving) { // Purpur - decompile error EntityTypes entitytypes = entityliving.getEntityType(); return entitytypes != EntityTypes.ZOGLIN && entitytypes != EntityTypes.CREEPER && IEntitySelector.f.test(entityliving); @@ -181,14 +193,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 eL() { - Activity activity = (Activity) this.bg.f().orElse((Object) null); + Activity activity = (Activity) this.bg.f().orElse(null); // Purpur - decompile error this.bg.a((List) ImmutableList.of(Activity.FLIGHT, Activity.IDLE)); - Activity activity1 = (Activity) this.bg.f().orElse((Object) null); + Activity activity1 = (Activity) this.bg.f().orElse(null); // Purpur - decompile error if (activity1 == Activity.FLIGHT && activity != Activity.FLIGHT) { this.eN(); @@ -200,7 +212,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 (getPurpurRider() == null) // Purpur - only use brain if no rider + this.getBehaviorController().a((WorldServer) this.world, this); // Purpur - decompile error this.world.getMethodProfiler().exit(); this.eL(); } diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityZombie.java b/src/main/java/net/minecraft/world/entity/monster/EntityZombie.java index 5ac950614fc90d02a568bb38f71faee124584c16..901fe8d224130c67bad00636b065bc798859a18e 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityZombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityZombie.java @@ -16,6 +16,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.syncher.DataWatcher; import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundCategory; import net.minecraft.sounds.SoundEffect; @@ -108,6 +109,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; } @@ -123,9 +134,11 @@ public class EntityZombie extends EntityMonster { @Override protected void initPathfinder() { + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur if (world.paperConfig.zombiesTargetTurtleEggs) this.goalSelector.a(4, new EntityZombie.a(this, 1.0D, 3)); // Paper this.goalSelector.a(8, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); this.goalSelector.a(8, new PathfinderGoalRandomLookaround(this)); + this.targetSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.m(); } diff --git a/src/main/java/net/minecraft/world/entity/monster/EntityZombieHusk.java b/src/main/java/net/minecraft/world/entity/monster/EntityZombieHusk.java index 5d3e5873f19aaf8389eb5525693b9378ea9f94ee..ad801fc394fbb83cf280ee96f962e7f311615d72 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityZombieHusk.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityZombieHusk.java @@ -23,6 +23,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/world/entity/monster/EntityZombieVillager.java b/src/main/java/net/minecraft/world/entity/monster/EntityZombieVillager.java index 99d0932e5352589cfbcc48a5e789651d0d77edde..b8395c7317494adf36010080931a1c8635ab6cfa 100644 --- a/src/main/java/net/minecraft/world/entity/monster/EntityZombieVillager.java +++ b/src/main/java/net/minecraft/world/entity/monster/EntityZombieVillager.java @@ -71,6 +71,16 @@ public class EntityZombieVillager extends EntityZombie implements VillagerDataHo } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.zombieVillagerRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.zombieVillagerRidableInWater; + } + @Override public boolean jockeyOnlyBaby() { return world.purpurConfig.zombieVillagerJockeyOnlyBaby; diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/EntityHoglin.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/EntityHoglin.java index 9aa4850e021076fde306eea7eec104c31086c57f..c2e32121f693a6207e6239c26a1fd6e60d0ce434 100644 --- a/src/main/java/net/minecraft/world/entity/monster/hoglin/EntityHoglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/EntityHoglin.java @@ -61,6 +61,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(); @@ -127,6 +139,7 @@ public class EntityHoglin extends EntityAnimal implements IMonster, IOglin { // Airplane - dynamic tick if (!gg.airplane.AirplaneConfig.dynamicHoglinBehavior || this.behaviorTick++ % this.activatedPriority == 0) { this.world.getMethodProfiler().enter("hoglinBrain"); + if (getPurpurRider() == null) // Purpur - only use brain if no rider this.getBehaviorController().a((WorldServer) this.world, (EntityHoglin) this); // Airplane - decompile error this.world.getMethodProfiler().exit(); HoglinAI.a(this); diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/EntityPiglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/EntityPiglin.java index 48acef830eb1d919499e9b79dc6a9af4bdf8a17b..2311d82824314a9feede9c3c106b0e1b24ac1b7a 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/EntityPiglin.java +++ b/src/main/java/net/minecraft/world/entity/monster/piglin/EntityPiglin.java @@ -70,6 +70,18 @@ public class EntityPiglin extends EntityPiglinAbstract implements ICrossbow { this.f = 5; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.piglinRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.piglinRidableInWater; + } + // Purpur end + @Override public void saveData(NBTTagCompound nbttagcompound) { super.saveData(nbttagcompound); @@ -250,6 +262,7 @@ public class EntityPiglin extends EntityPiglinAbstract implements ICrossbow { // Airplane - dynamic tick if (!gg.airplane.AirplaneConfig.dynamicPiglinBehavior || this.behaviorTick++ % this.activatedPriority == 0) { this.world.getMethodProfiler().enter("piglinBrain"); + if (getPurpurRider() == null) // Purpur - only use brain if no rider this.getBehaviorController().a((WorldServer) this.world, (EntityPiglin) this); // Airplane - compile error this.world.getMethodProfiler().exit(); PiglinAI.b(this); diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/EntityPiglinBrute.java b/src/main/java/net/minecraft/world/entity/monster/piglin/EntityPiglinBrute.java index 3d85501791fce621335f34bf508becb74b80210d..1370d2d8568a4ed62f2ec3d54abc7d2bebc48f75 100644 --- a/src/main/java/net/minecraft/world/entity/monster/piglin/EntityPiglinBrute.java +++ b/src/main/java/net/minecraft/world/entity/monster/piglin/EntityPiglinBrute.java @@ -39,6 +39,18 @@ public class EntityPiglinBrute extends EntityPiglinAbstract { this.f = 20; } + // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.piglinBruteRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.piglinBruteRidableInWater; + } + // Purpur end + public static AttributeProvider.Builder eS() { return EntityMonster.eR().a(GenericAttributes.MAX_HEALTH, 50.0D).a(GenericAttributes.MOVEMENT_SPEED, 0.3499999940395355D).a(GenericAttributes.ATTACK_DAMAGE, 7.0D); } @@ -68,7 +80,7 @@ public class EntityPiglinBrute extends EntityPiglinAbstract { @Override public BehaviorController getBehaviorController() { - return super.getBehaviorController(); + return (BehaviorController) super.getBehaviorController(); // Purpur - decompile error } @Override @@ -84,7 +96,8 @@ public class EntityPiglinBrute extends EntityPiglinAbstract { @Override protected void mobTick() { this.world.getMethodProfiler().enter("piglinBruteBrain"); - this.getBehaviorController().a((WorldServer) this.world, (EntityLiving) this); + if (getPurpurRider() == null) // Purpur - only use brain if no rider + this.getBehaviorController().a((WorldServer) this.world, this); // Purpur - decompile error this.world.getMethodProfiler().exit(); PiglinBruteAI.b(this); PiglinBruteAI.c(this); diff --git a/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java b/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java index e2779521977716aa58bb713de67cb2d9fa8cbe5f..bd56b7a009a8bcbdd353d7bdcb2a2a7310ab45cc 100644 --- a/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java +++ b/src/main/java/net/minecraft/world/entity/npc/EntityVillager.java @@ -32,6 +32,7 @@ import net.minecraft.network.syncher.DataWatcherObject; import net.minecraft.network.syncher.DataWatcherRegistry; import net.minecraft.server.MCUtil; import net.minecraft.server.MinecraftServer; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -145,8 +146,19 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation } // Purpur start + @Override + public boolean isRidable() { + return world.purpurConfig.villagerRidable; + } + + @Override + public boolean isRidableInWater() { + return world.purpurConfig.villagerRidableInWater; + } + @Override protected void initPathfinder() { + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur if (world.purpurConfig.villagerFollowEmeraldBlock) this.goalSelector.a(3, new PathfinderGoalTempt(this, 1.0D, false, TEMPT_ITEMS)); } @@ -317,7 +329,7 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation if (itemstack.getItem() != Items.VILLAGER_SPAWN_EGG && this.isAlive() && !this.eN() && !this.isSleeping()) { if (this.isBaby()) { this.fk(); - return EnumInteractionResult.a(this.world.isClientSide); + return super.b(entityhuman, enumhand); // Purpur } else { boolean flag = this.getOffers().isEmpty(); @@ -330,8 +342,9 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation } if (flag) { - return EnumInteractionResult.a(this.world.isClientSide); + return tryRide(entityhuman, enumhand); // Purpur } else { + if (world.purpurConfig.villagerRidable && itemstack.isEmpty()) return tryRide(entityhuman, enumhand); // Purpur if (!this.world.isClientSide && !this.trades.isEmpty()) { this.h(entityhuman); } diff --git a/src/main/java/net/minecraft/world/entity/npc/EntityVillagerTrader.java b/src/main/java/net/minecraft/world/entity/npc/EntityVillagerTrader.java index 8df4d985e3124ddc1643da8385b15348937bc320..6c390fb20c7f29133a60780a75676d8d3d6eab29 100644 --- a/src/main/java/net/minecraft/world/entity/npc/EntityVillagerTrader.java +++ b/src/main/java/net/minecraft/world/entity/npc/EntityVillagerTrader.java @@ -6,6 +6,7 @@ import net.minecraft.core.BlockPosition; import net.minecraft.core.IPosition; import net.minecraft.nbt.GameProfileSerializer; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.PathfinderGoalHasRider; import net.minecraft.server.level.WorldServer; import net.minecraft.sounds.SoundEffect; import net.minecraft.sounds.SoundEffects; @@ -73,6 +74,7 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { @Override protected void initPathfinder() { this.goalSelector.a(0, new PathfinderGoalFloat(this)); + this.goalSelector.a(0, new PathfinderGoalHasRider(this)); // Purpur this.goalSelector.a(0, new PathfinderGoalUseItem<>(this, PotionUtil.a(new ItemStack(Items.POTION), Potions.INVISIBILITY), SoundEffects.ENTITY_WANDERING_TRADER_DISAPPEARED, (entityvillagertrader) -> { return canDrinkPotion && this.world.isNight() && !entityvillagertrader.isInvisible(); // Paper - Add more WanderingTrader API })); @@ -98,6 +100,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(); @@ -125,8 +137,9 @@ public class EntityVillagerTrader extends EntityVillagerAbstract { } if (this.getOffers().isEmpty()) { - return EnumInteractionResult.a(this.world.isClientSide); + return tryRide(entityhuman, enumhand); // Purpur } else { + if (world.purpurConfig.villagerTraderRidable && itemstack.isEmpty()) return tryRide(entityhuman, enumhand); // Purpur if (!this.world.isClientSide) { this.setTradingPlayer(entityhuman); this.openTrade(entityhuman, this.getScoreboardDisplayName(), 1); diff --git a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java index 1b130b50888113d515ce1e200a157c3bbff3b625..a70c557de56c5ba04cb520108cdb037eb9cad8a9 100644 --- a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java +++ b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java @@ -111,7 +111,6 @@ import net.minecraft.world.phys.AxisAlignedBB; import net.minecraft.world.phys.Vec3D; import net.minecraft.world.scores.Scoreboard; import net.minecraft.world.scores.ScoreboardTeam; -import net.minecraft.world.scores.ScoreboardTeamBase; // CraftBukkit start import org.bukkit.craftbukkit.entity.CraftHumanEntity; @@ -183,6 +182,8 @@ public abstract class EntityHuman extends EntityLiving { // CraftBukkit end // Purpur start + public abstract void resetIdleTimer(); + private javax.script.ScriptEngine scriptEngine = new javax.script.ScriptEngineManager().getEngineByName("rhino"); public void setAfk(boolean setAfk){ @@ -2271,4 +2272,15 @@ public abstract class EntityHuman extends EntityLiving { return this.g; } } + + // Purpur start + @Override + public boolean processClick(EnumHand hand) { + Entity vehicle = getRootVehicle(); + if (vehicle != null && vehicle.getPurpurRider() == this) { + return vehicle.onClick(hand); + } + return false; + } + // Purpur end } diff --git a/src/main/java/net/minecraft/world/entity/projectile/IProjectile.java b/src/main/java/net/minecraft/world/entity/projectile/IProjectile.java index 8fe98404ebb8b3b5d1fdac0896b27da10736026d..390023a7a825eed850a13572b719f47ed534c003 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/IProjectile.java +++ b/src/main/java/net/minecraft/world/entity/projectile/IProjectile.java @@ -24,7 +24,7 @@ public abstract class IProjectile extends Entity { private UUID shooter; private int c; - private boolean d; + private boolean d; public boolean leftOwner() { return d; } public void setLeftOwner(boolean leftOwner) { this.d = leftOwner; } // Purpur - OBFHELPER // CraftBukkit start private boolean hitCancelled = false; @@ -90,6 +90,7 @@ public abstract class IProjectile extends Entity { super.tick(); } + public boolean checkIfLeftOwner() { return this.h(); } // Purpur - OBFHELPER private boolean h() { Entity entity = this.getShooter(); @@ -167,7 +168,7 @@ public abstract class IProjectile extends Entity { iblockdata.a(this.world, iblockdata, movingobjectpositionblock, this); } - protected boolean a(Entity entity) { + protected boolean a(Entity entity) { return hitPredicate(entity); } public boolean hitPredicate(Entity entity) { // Purpur - OBFHELPER if (!entity.isSpectator() && entity.isAlive() && entity.isInteractable()) { Entity entity1 = this.getShooter(); // Paper start - Cancel hit for vanished players diff --git a/src/main/java/net/minecraft/world/entity/projectile/ProjectileHelper.java b/src/main/java/net/minecraft/world/entity/projectile/ProjectileHelper.java index 75889ac851d1c2b26c0b57bea6b75c1b65c2309f..80834537eba8bd33a0688e19d0aa9b963de4398a 100644 --- a/src/main/java/net/minecraft/world/entity/projectile/ProjectileHelper.java +++ b/src/main/java/net/minecraft/world/entity/projectile/ProjectileHelper.java @@ -21,6 +21,7 @@ import net.minecraft.world.phys.Vec3D; public final class ProjectileHelper { + public static MovingObjectPosition getHitResult(Entity entity, Predicate predicate) { return a(entity, predicate); } // Purpur - OBFHELPER public static MovingObjectPosition a(Entity entity, Predicate predicate) { Vec3D vec3d = entity.getMot(); World world = entity.world; diff --git a/src/main/java/net/minecraft/world/level/GeneratorAccess.java b/src/main/java/net/minecraft/world/level/GeneratorAccess.java index 96efd974f1eb9c1e7c70e576e51ed69e15aacb99..fc86ef53c48503139667f7703019a07c40814fd4 100644 --- a/src/main/java/net/minecraft/world/level/GeneratorAccess.java +++ b/src/main/java/net/minecraft/world/level/GeneratorAccess.java @@ -48,6 +48,7 @@ public interface GeneratorAccess extends ICombinedAccess, IWorldTime { void addParticle(ParticleParam particleparam, double d0, double d1, double d2, double d3, double d4, double d5); + default void playEvent(@Nullable EntityHuman entityhuman, int i, BlockPosition blockposition, int j) { a(entityhuman, i, blockposition, j); } // Purpur - OBFHELPER void a(@Nullable EntityHuman entityhuman, int i, BlockPosition blockposition, int j); default int getHeight() { diff --git a/src/main/java/net/minecraft/world/level/World.java b/src/main/java/net/minecraft/world/level/World.java index 056d827a2115370c01d0f2a98039f727b4c674d5..36b416636b4ded816701a065ff2ff0c3890e0987 100644 --- a/src/main/java/net/minecraft/world/level/World.java +++ b/src/main/java/net/minecraft/world/level/World.java @@ -1833,5 +1833,10 @@ public abstract class World implements GeneratorAccess, AutoCloseable { public boolean isTheEnd() { return getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END; } + + // Purpur start + public void playEffect(@Nullable EntityHuman entityhuman, int i, BlockPosition blockposition, int j) { + this.a(entityhuman, i, blockposition, j); + } // Purpur end } diff --git a/src/main/java/net/minecraft/world/phys/Vec3D.java b/src/main/java/net/minecraft/world/phys/Vec3D.java index a19a26a88f247d359354902efeece9923f3e0e0b..1119f60890784d953c2cd4e0078af4d04d10d557 100644 --- a/src/main/java/net/minecraft/world/phys/Vec3D.java +++ b/src/main/java/net/minecraft/world/phys/Vec3D.java @@ -50,6 +50,7 @@ public class Vec3D implements IPosition { return new Vec3D(vec3d.x - this.x, vec3d.y - this.y, vec3d.z - this.z); } + public Vec3D normalize() { return d(); } // Purpur - OBFHELPER public Vec3D d() { double d0 = (double) MathHelper.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); @@ -109,6 +110,7 @@ public class Vec3D implements IPosition { return d3 * d3 + d4 * d4 + d5 * d5; } + public Vec3D scale(double scale) { return a(scale); } // Purpur - OBFHELPER public Vec3D a(double d0) { return this.d(d0, d0, d0); } @@ -117,6 +119,7 @@ public class Vec3D implements IPosition { return this.d(vec3d.x, vec3d.y, vec3d.z); } + public Vec3D multiply (double x, double y, double z) { return d(x, y, z); } // Purpur - OBFHELPER public Vec3D d(double d0, double d1, double d2) { return new Vec3D(this.x * d0, this.y * d1, this.z * d2); } diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java index 3b20793e3eb4349f8a4ce724f8fc0d6366bb28c2..9789d0f9f73540a486befcdd4901014efeed8403 100644 --- a/src/main/java/net/pl3x/purpur/PurpurConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java @@ -137,11 +137,13 @@ public class PurpurConfig { public static String afkBroadcastBack = "§e§o%s is no longer AFK"; public static String afkTabListPrefix = "[AFK] "; public static String pingCommandOutput = "§a%s's ping is %sms"; + public static String cannotRideMob = "§cYou cannot mount that mob"; private static void messages() { afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway); afkBroadcastBack = getString("settings.messages.afk-broadcast-back", afkBroadcastBack); afkTabListPrefix = getString("settings.messages.afk-tab-list-prefix", afkTabListPrefix); pingCommandOutput = getString("settings.messages.ping-command-output", pingCommandOutput); + cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob); } public static int dungeonSeed = -1; diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java index f16f99517999ccbb0b5a678ffcb3befc93a3ae45..9fcc63a2f4a4c363ace85087665bf3a978d3d648 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java @@ -42,11 +42,6 @@ public class PurpurWorldConfig { } } - public double vindicatorJohnnySpawnChance = 0D; - private void vindicatorSettings() { - vindicatorJohnnySpawnChance = getDouble("mobs.vindicator.johnny.spawn-chance", vindicatorJohnnySpawnChance); - } - private ConfigurationSection getConfigurationSection(String path) { ConfigurationSection section = PurpurConfig.config.getConfigurationSection("world-settings." + worldName + "." + path); return section != null ? section : PurpurConfig.config.getConfigurationSection("world-settings.default." + path); @@ -385,61 +380,186 @@ public class PurpurWorldConfig { turtleEggsBreakFromMinecarts = getBoolean("blocks.turtle_egg.break-from-minecarts", turtleEggsBreakFromMinecarts); } + public boolean babiesAreRidable = true; + public boolean untamedTamablesAreRidable = true; + public boolean useNightVisionWhenRiding = false; + private void ridableSettings() { + babiesAreRidable = getBoolean("ridable-settings.babies-are-ridable", babiesAreRidable); + untamedTamablesAreRidable = getBoolean("ridable-settings.untamed-tamables-are-ridable", untamedTamablesAreRidable); + useNightVisionWhenRiding = getBoolean("ridable-settings.use-night-vision", useNightVisionWhenRiding); + } + + public boolean batRidable = false; + public boolean batRidableInWater = false; + public double batMaxY = 256D; + private void batSettings() { + batRidable = getBoolean("mobs.bat.ridable", batRidable); + batRidableInWater = getBoolean("mobs.bat.ridable-in-water", batRidableInWater); + batMaxY = getDouble("mobs.bat.ridable-max-y", batMaxY); + } + + public boolean beeRidable = false; + public boolean beeRidableInWater = false; + public double beeMaxY = 256D; + private void beeSettings() { + beeRidable = getBoolean("mobs.bee.ridable", beeRidable); + beeRidableInWater = getBoolean("mobs.bee.ridable-in-water", beeRidableInWater); + beeMaxY = getDouble("mobs.bee.ridable-max-y", beeMaxY); + } + + public boolean blazeRidable = false; + public boolean blazeRidableInWater = false; + public double blazeMaxY = 256D; + private void blazeSettings() { + blazeRidable = getBoolean("mobs.blaze.ridable", blazeRidable); + blazeRidableInWater = getBoolean("mobs.blaze.ridable-in-water", blazeRidableInWater); + blazeMaxY = getDouble("mobs.blaze.ridable-max-y", blazeMaxY); + } + + public boolean catRidable = false; + public boolean catRidableInWater = false; public int catSpawnDelay = 1200; public int catSpawnSwampHutScanRange = 16; public int catSpawnVillageScanRange = 48; private void catSettings() { + catRidable = getBoolean("mobs.cat.ridable", catRidable); + catRidableInWater = getBoolean("mobs.cat.ridable-in-water", catRidableInWater); catSpawnDelay = getInt("mobs.cat.spawn-delay", catSpawnDelay); catSpawnSwampHutScanRange = getInt("mobs.cat.scan-range-for-other-cats.swamp-hut", catSpawnSwampHutScanRange); catSpawnVillageScanRange = getInt("mobs.cat.scan-range-for-other-cats.village", catSpawnVillageScanRange); } + public boolean caveSpiderRidable = false; + public boolean caveSpiderRidableInWater = false; + private void caveSpiderSettings() { + caveSpiderRidable = getBoolean("mobs.cave_spider.ridable", caveSpiderRidable); + caveSpiderRidableInWater = getBoolean("mobs.cave_spider.ridable-in-water", caveSpiderRidableInWater); + } + + public boolean chickenRidable = false; + public boolean chickenRidableInWater = false; public boolean chickenRetaliate = false; private void chickenSettings() { + chickenRidable = getBoolean("mobs.chicken.ridable", chickenRidable); + chickenRidableInWater = getBoolean("mobs.chicken.ridable-in-water", chickenRidableInWater); chickenRetaliate = getBoolean("mobs.chicken.retaliate", chickenRetaliate); } + public boolean codRidable = false; + private void codSettings() { + codRidable = getBoolean("mobs.cod.ridable", codRidable); + } + + public boolean cowRidable = false; + public boolean cowRidableInWater = false; public int cowFeedMushrooms = 0; private void cowSettings() { + cowRidable = getBoolean("mobs.cow.ridable", cowRidable); + cowRidableInWater = getBoolean("mobs.cow.ridable-in-water", cowRidableInWater); cowFeedMushrooms = getInt("mobs.cow.feed-mushrooms-for-mooshroom", cowFeedMushrooms); } + public boolean creeperRidable = false; + public boolean creeperRidableInWater = false; public boolean creeperAllowGriefing = true; public double creeperChargedChance = 0.0D; private void creeperSettings() { + creeperRidable = getBoolean("mobs.creeper.ridable", creeperRidable); + creeperRidableInWater = getBoolean("mobs.creeper.ridable-in-water", creeperRidableInWater); creeperAllowGriefing = getBoolean("mobs.creeper.allow-griefing", creeperAllowGriefing); creeperChargedChance = getDouble("mobs.creeper.naturally-charged-chance", creeperChargedChance); } + public boolean dolphinRidable = false; + public int dolphinSpitCooldown = 20; + public float dolphinSpitSpeed = 1.0F; + public float dolphinSpitDamage = 2.0F; public boolean dolphinDisableTreasureSearching = false; private void dolphinSettings() { + dolphinRidable = getBoolean("mobs.dolphin.ridable", dolphinRidable); + dolphinSpitCooldown = getInt("mobs.dolphin.spit.cooldown", dolphinSpitCooldown); + dolphinSpitSpeed = (float) getDouble("mobs.dolphin.spit.speed", dolphinSpitSpeed); + dolphinSpitDamage = (float) getDouble("mobs.dolphin.spit.damage", dolphinSpitDamage); dolphinDisableTreasureSearching = getBoolean("mobs.dolphin.disable-treasure-searching", dolphinDisableTreasureSearching); } + public boolean donkeyRidableInWater = false; + private void donkeySettings() { + donkeyRidableInWater = getBoolean("mobs.donkey.ridable-in-water", donkeyRidableInWater); + } + + public boolean drownedRidable = false; + public boolean drownedRidableInWater = false; public boolean drownedJockeyOnlyBaby = true; public double drownedJockeyChance = 0.05D; public boolean drownedJockeyTryExistingChickens = true; private void drownedSettings() { + drownedRidable = getBoolean("mobs.drowned.ridable", drownedRidable); + drownedRidableInWater = getBoolean("mobs.drowned.ridable-in-water", drownedRidableInWater); drownedJockeyOnlyBaby = getBoolean("mobs.drowned.jockey.only-babies", drownedJockeyOnlyBaby); drownedJockeyChance = getDouble("mobs.drowned.jockey.chance", drownedJockeyChance); drownedJockeyTryExistingChickens = getBoolean("mobs.drowned.jockey.try-existing-chickens", drownedJockeyTryExistingChickens); } + public boolean elderGuardianRidable = false; + private void elderGuardianSettings() { + elderGuardianRidable = getBoolean("mobs.elder_guardian.ridable", elderGuardianRidable); + } + + public boolean enderDragonRidable = false; + public boolean enderDragonRidableInWater = false; + public double enderDragonMaxY = 256D; public boolean enderDragonAlwaysDropsFullExp = false; private void enderDragonSettings() { + enderDragonRidable = getBoolean("mobs.ender_dragon.ridable", enderDragonRidable); + enderDragonRidableInWater = getBoolean("mobs.ender_dragon.ridable-in-water", enderDragonRidableInWater); + enderDragonMaxY = getDouble("mobs.ender_dragon.ridable-max-y", enderDragonMaxY); enderDragonAlwaysDropsFullExp = getBoolean("mobs.ender_dragon.always-drop-full-exp", enderDragonAlwaysDropsFullExp); } + public boolean endermanRidable = false; + public boolean endermanRidableInWater = false; public boolean endermanAllowGriefing = true; private void endermanSettings() { + endermanRidable = getBoolean("mobs.enderman.ridable", endermanRidable); + endermanRidableInWater = getBoolean("mobs.enderman.ridable-in-water", endermanRidableInWater); endermanAllowGriefing = getBoolean("mobs.enderman.allow-griefing", endermanAllowGriefing); } + public boolean endermiteRidable = false; + public boolean endermiteRidableInWater = false; + private void endermiteSettings() { + endermiteRidable = getBoolean("mobs.endermite.ridable", endermiteRidable); + endermiteRidableInWater = getBoolean("mobs.endermite.ridable-in-water", endermiteRidableInWater); + } + + public boolean evokerRidable = false; + public boolean evokerRidableInWater = false; + private void evokerSettings() { + evokerRidable = getBoolean("mobs.evoker.ridable", evokerRidable); + evokerRidableInWater = getBoolean("mobs.evoker.ridable-in-water", evokerRidableInWater); + } + + public boolean foxRidable = false; + public boolean foxRidableInWater = false; public boolean foxTypeChangesWithTulips = false; private void foxSettings() { + foxRidable = getBoolean("mobs.fox.ridable", foxRidable); + foxRidableInWater = getBoolean("mobs.fox.ridable-in-water", foxRidableInWater); foxTypeChangesWithTulips = getBoolean("mobs.fox.tulips-change-type", foxTypeChangesWithTulips); } + public boolean ghastRidable = false; + public boolean ghastRidableInWater = false; + public double ghastMaxY = 256D; + private void ghastSettings() { + ghastRidable = getBoolean("mobs.ghast.ridable", ghastRidable); + ghastRidableInWater = getBoolean("mobs.ghast.ridable-in-water", ghastRidableInWater); + ghastMaxY = getDouble("mobs.ghast.ridable-max-y", ghastMaxY); + } + + public boolean giantRidable = false; + public boolean giantRidableInWater = false; public float giantStepHeight = 2.0F; public float giantJumpHeight = 1.0F; public double giantMovementSpeed = 0.5D; @@ -448,6 +568,8 @@ public class PurpurWorldConfig { public boolean giantHaveHostileAI = false; public double giantMaxHealth = 100.0D; 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); giantMovementSpeed = getDouble("mobs.giant.movement-speed", giantMovementSpeed); @@ -462,19 +584,44 @@ public class PurpurWorldConfig { giantMaxHealth = getDouble("mobs.giant.attributes.max-health", giantMaxHealth); } + public boolean guardianRidable = false; + private void guardianSettings() { + guardianRidable = getBoolean("mobs.guardian.ridable", guardianRidable); + } + + public boolean hoglinRidable = false; + public boolean hoglinRidableInWater = false; + private void hoglinSettings() { + hoglinRidable = getBoolean("mobs.hoglin.ridable", hoglinRidable); + hoglinRidableInWater = getBoolean("mobs.hoglin.ridable-in-water", hoglinRidableInWater); + } + + public boolean horseRidableInWater = false; + private void horseSettings() { + horseRidableInWater = getBoolean("mobs.horse.ridable-in-water", horseRidableInWater); + } + + public boolean huskRidable = false; + public boolean huskRidableInWater = false; public boolean huskJockeyOnlyBaby = true; public double huskJockeyChance = 0.05D; public boolean huskJockeyTryExistingChickens = true; private void huskSettings() { + huskRidable = getBoolean("mobs.husk.ridable", huskRidable); + huskRidableInWater = getBoolean("mobs.husk.ridable-in-water", huskRidableInWater); huskJockeyOnlyBaby = getBoolean("mobs.husk.jockey.only-babies", huskJockeyOnlyBaby); huskJockeyChance = getDouble("mobs.husk.jockey.chance", huskJockeyChance); huskJockeyTryExistingChickens = getBoolean("mobs.husk.jockey.try-existing-chickens", huskJockeyTryExistingChickens); } + public boolean illusionerRidable = false; + public boolean illusionerRidableInWater = false; public double illusionerMovementSpeed = 0.5D; public double illusionerFollowRange = 18.0D; public double illusionerMaxHealth = 32.0D; private void illusionerSettings() { + illusionerRidable = getBoolean("mobs.illusioner.ridable", illusionerRidable); + illusionerRidableInWater = getBoolean("mobs.illusioner.ridable-in-water", illusionerRidableInWater); illusionerMovementSpeed = getDouble("mobs.illusioner.movement-speed", illusionerMovementSpeed); illusionerFollowRange = getDouble("mobs.illusioner.follow-range", illusionerFollowRange); if (PurpurConfig.version < 8) { @@ -485,11 +632,76 @@ public class PurpurWorldConfig { illusionerMaxHealth = getDouble("mobs.illusioner.attributes.max-health", illusionerMaxHealth); } + public boolean ironGolemRidable = false; + public boolean ironGolemRidableInWater = false; public boolean ironGolemCanSwim = false; private void ironGolemSettings() { + ironGolemRidable = getBoolean("mobs.iron_golem.ridable", ironGolemRidable); + ironGolemRidableInWater = getBoolean("mobs.iron_golem.ridable-in-water", ironGolemRidableInWater); ironGolemCanSwim = getBoolean("mobs.iron_golem.can-swim", ironGolemCanSwim); } + public boolean llamaRidable = false; + public boolean llamaRidableInWater = false; + private void llamaSettings() { + llamaRidable = getBoolean("mobs.llama.ridable", llamaRidable); + llamaRidableInWater = getBoolean("mobs.llama.ridable-in-water", llamaRidableInWater); + } + + public boolean llamaTraderRidable = false; + public boolean llamaTraderRidableInWater = false; + private void llamaTraderSettings() { + llamaTraderRidable = getBoolean("mobs.trader_llama.ridable", llamaTraderRidable); + llamaTraderRidableInWater = getBoolean("mobs.trader_llama.ridable-in-water", llamaTraderRidableInWater); + } + + public boolean magmaCubeRidable = false; + public boolean magmaCubeRidableInWater = false; + private void magmaCubeSettings() { + magmaCubeRidable = getBoolean("mobs.magma_cube.ridable", magmaCubeRidable); + magmaCubeRidableInWater = getBoolean("mobs.magma_cube.ridable-in-water", magmaCubeRidableInWater); + } + + public boolean mooshroomRidable = false; + public boolean mooshroomRidableInWater = false; + private void mooshroomSettings() { + mooshroomRidable = getBoolean("mobs.mooshroom.ridable", mooshroomRidable); + mooshroomRidableInWater = getBoolean("mobs.mooshroom.ridable-in-water", mooshroomRidableInWater); + } + + public boolean muleRidableInWater = false; + private void muleSettings() { + muleRidableInWater = getBoolean("mobs.mule.ridable-in-water", muleRidableInWater); + } + + public boolean ocelotRidable = false; + public boolean ocelotRidableInWater = false; + private void ocelotSettings() { + ocelotRidable = getBoolean("mobs.ocelot.ridable", ocelotRidable); + ocelotRidableInWater = getBoolean("mobs.ocelot.ridable-in-water", ocelotRidableInWater); + } + + public boolean pandaRidable = false; + public boolean pandaRidableInWater = false; + private void pandaSettings() { + pandaRidable = getBoolean("mobs.panda.ridable", pandaRidable); + pandaRidableInWater = getBoolean("mobs.panda.ridable-in-water", pandaRidableInWater); + } + + public boolean parrotRidable = false; + public boolean parrotRidableInWater = false; + public double parrotMaxY = 256D; + private void parrotSettings() { + parrotRidable = getBoolean("mobs.parrot.ridable", parrotRidable); + parrotRidableInWater = getBoolean("mobs.parrot.ridable-in-water", parrotRidableInWater); + parrotMaxY = getDouble("mobs.parrot.ridable-max-y", parrotMaxY); + } + + public boolean phantomRidable = false; + public boolean phantomRidableInWater = false; + public double phantomMaxY = 256D; + public float phantomFlameDamage = 1.0F; + public int phantomFlameFireTime = 8; public double phantomAttackedByCrystalRadius = 0.0D; public float phantomAttackedByCrystalDamage = 1.0F; public double phantomOrbitCrystalRadius = 0.0D; @@ -508,7 +720,13 @@ public class PurpurWorldConfig { public int phantomBurnInLight = 0; public boolean phantomIgnorePlayersWithTorch = false; public boolean phantomBurnInDaylight = true; + public boolean phantomAllowGriefing = false; private void phantomSettings() { + phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable); + phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater); + phantomMaxY = getDouble("mobs.phantom.ridable-max-y", phantomMaxY); + phantomFlameDamage = (float) getDouble("mobs.phantom.flames.damage", phantomFlameDamage); + phantomFlameFireTime = getInt("mobs.phantom.flames.fire-time", phantomFlameFireTime); phantomAttackedByCrystalRadius = getDouble("mobs.phantom.attacked-by-crystal-range", phantomAttackedByCrystalRadius); phantomAttackedByCrystalDamage = (float) getDouble("mobs.phantom.attacked-by-crystal-damage", phantomAttackedByCrystalDamage); phantomOrbitCrystalRadius = getDouble("mobs.phantom.orbit-crystal-radius", phantomOrbitCrystalRadius); @@ -527,42 +745,187 @@ public class PurpurWorldConfig { phantomBurnInLight = getInt("mobs.phantom.burn-in-light", phantomBurnInLight); phantomBurnInDaylight = getBoolean("mobs.phantom.burn-in-daylight", phantomBurnInDaylight); phantomIgnorePlayersWithTorch = getBoolean("mobs.phantom.ignore-players-with-torch", phantomIgnorePlayersWithTorch); + phantomAllowGriefing = getBoolean("mobs.phantom.allow-griefing", phantomAllowGriefing); } + public boolean pigRidable = false; + public boolean pigRidableInWater = false; public boolean pigGiveSaddleBack = false; private void pigSettings() { + pigRidable = getBoolean("mobs.pig.ridable", pigRidable); + pigRidableInWater = getBoolean("mobs.pig.ridable-in-water", pigRidableInWater); pigGiveSaddleBack = getBoolean("mobs.pig.give-saddle-back", pigGiveSaddleBack); } + public boolean piglinRidable = false; + public boolean piglinRidableInWater = false; + private void piglinSettings() { + piglinRidable = getBoolean("mobs.piglin.ridable", piglinRidable); + piglinRidableInWater = getBoolean("mobs.piglin.ridable-in-water", piglinRidableInWater); + } + + public boolean piglinBruteRidable = false; + public boolean piglinBruteRidableInWater = false; + private void piglinBruteSettings() { + piglinBruteRidable = getBoolean("mobs.piglin_brute.ridable", piglinBruteRidable); + piglinBruteRidableInWater = getBoolean("mobs.piglin_brute.ridable-in-water", piglinBruteRidableInWater); + } + + public boolean pillagerRidable = false; + public boolean pillagerRidableInWater = false; + private void pillagerSettings() { + pillagerRidable = getBoolean("mobs.pillager.ridable", pillagerRidable); + pillagerRidableInWater = getBoolean("mobs.pillager.ridable-in-water", pillagerRidableInWater); + } + + public boolean polarBearRidable = false; + public boolean polarBearRidableInWater = false; public String polarBearBreedableItemString = ""; public Item polarBearBreedableItem = null; private void polarBearSettings() { + polarBearRidable = getBoolean("mobs.polar_bear.ridable", polarBearRidable); + polarBearRidableInWater = getBoolean("mobs.polar_bear.ridable-in-water", polarBearRidableInWater); polarBearBreedableItemString = getString("mobs.polar_bear.breedable-item", polarBearBreedableItemString); Item item = IRegistry.ITEM.get(new MinecraftKey(polarBearBreedableItemString)); if (item != Items.AIR) polarBearBreedableItem = item; } + public boolean pufferfishRidable = false; + private void pufferfishSettings() { + pufferfishRidable = getBoolean("mobs.pufferfish.ridable", pufferfishRidable); + } + + public boolean rabbitRidable = false; + public boolean rabbitRidableInWater = false; public double rabbitNaturalToast = 0.0D; public double rabbitNaturalKiller = 0.0D; private void rabbitSettings() { + rabbitRidable = getBoolean("mobs.rabbit.ridable", rabbitRidable); + rabbitRidableInWater = getBoolean("mobs.rabbit.ridable-in-water", rabbitRidableInWater); rabbitNaturalToast = getDouble("mobs.rabbit.spawn-toast-chance", rabbitNaturalToast); rabbitNaturalKiller = getDouble("mobs.rabbit.spawn-killer-rabbit-chance", rabbitNaturalKiller); } + public boolean ravagerRidable = false; + public boolean ravagerRidableInWater = false; + private void ravagerSettings() { + ravagerRidable = getBoolean("mobs.ravager.ridable", ravagerRidable); + ravagerRidableInWater = getBoolean("mobs.ravager.ridable-in-water", ravagerRidableInWater); + } + + public boolean salmonRidable = false; + private void salmonSettings() { + salmonRidable = getBoolean("mobs.salmon.ridable", salmonRidable); + } + + public boolean sheepRidable = false; + public boolean sheepRidableInWater = false; + private void sheepSettings() { + sheepRidable = getBoolean("mobs.sheep.ridable", sheepRidable); + sheepRidableInWater = getBoolean("mobs.sheep.ridable-in-water", sheepRidableInWater); + } + + public boolean shulkerRidable = false; + public boolean shulkerRidableInWater = false; + private void shulkerSettings() { + shulkerRidable = getBoolean("mobs.shulker.ridable", shulkerRidable); + shulkerRidableInWater = getBoolean("mobs.shulker.ridable-in-water", shulkerRidableInWater); + } + + public boolean silverfishRidable = false; + public boolean silverfishRidableInWater = false; + private void silverfishSettings() { + silverfishRidable = getBoolean("mobs.silverfish.ridable", silverfishRidable); + silverfishRidableInWater = getBoolean("mobs.silverfish.ridable-in-water", silverfishRidableInWater); + } + + public boolean skeletonRidable = false; + public boolean skeletonRidableInWater = false; + private void skeletonSettings() { + skeletonRidable = getBoolean("mobs.skeleton.ridable", skeletonRidable); + skeletonRidableInWater = getBoolean("mobs.skeleton.ridable-in-water", skeletonRidableInWater); + } + + public boolean skeletonHorseCanSwim = false; + public boolean skeletonHorseRidableInWater = true; + private void skeletonHorseSettings() { + skeletonHorseCanSwim = getBoolean("mobs.skeleton_horse.can-swim", skeletonHorseCanSwim); + skeletonHorseRidableInWater = getBoolean("mobs.skeleton_horse.ridable-in-water", skeletonHorseRidableInWater); + } + + public boolean slimeRidable = false; + public boolean slimeRidableInWater = false; + private void slimeSettings() { + slimeRidable = getBoolean("mobs.slime.ridable", slimeRidable); + slimeRidableInWater = getBoolean("mobs.slime.ridable-in-water", slimeRidableInWater); + } + + public boolean snowGolemRidable = false; + public boolean snowGolemRidableInWater = false; + public boolean snowGolemLeaveTrailWhenRidden = false; public boolean snowGolemDropsPumpkin = true; public boolean snowGolemPutPumpkinBack = false; private void snowGolemSettings() { + snowGolemRidable = getBoolean("mobs.snow_golem.ridable", snowGolemRidable); + snowGolemRidableInWater = getBoolean("mobs.snow_golem.ridable-in-water", snowGolemRidableInWater); + snowGolemLeaveTrailWhenRidden = getBoolean("mobs.snow_golem.leave-trail-when-ridden", snowGolemLeaveTrailWhenRidden); snowGolemDropsPumpkin = getBoolean("mobs.snow_golem.drop-pumpkin-when-sheared", snowGolemDropsPumpkin); snowGolemPutPumpkinBack = getBoolean("mobs.snow_golem.pumpkin-can-be-added-back", snowGolemPutPumpkinBack); } + public boolean squidRidable = false; public boolean squidImmuneToEAR = true; public double squidOffsetWaterCheck = 0.0D; private void squidSettings() { + squidRidable = getBoolean("mobs.squid.ridable", squidRidable); squidImmuneToEAR = getBoolean("mobs.squid.immune-to-EAR", squidImmuneToEAR); squidOffsetWaterCheck = getDouble("mobs.squid.water-offset-check", squidOffsetWaterCheck); } + public boolean spiderRidable = false; + public boolean spiderRidableInWater = false; + private void spiderSettings() { + spiderRidable = getBoolean("mobs.spider.ridable", spiderRidable); + spiderRidableInWater = getBoolean("mobs.spider.ridable-in-water", spiderRidableInWater); + } + + public boolean strayRidable = false; + public boolean strayRidableInWater = false; + private void straySettings() { + strayRidable = getBoolean("mobs.stray.ridable", strayRidable); + strayRidableInWater = getBoolean("mobs.stray.ridable-in-water", strayRidableInWater); + } + + public boolean striderRidable = false; + public boolean striderRidableInWater = false; + private void striderSettings() { + striderRidable = getBoolean("mobs.strider.ridable", striderRidable); + striderRidableInWater = getBoolean("mobs.strider.ridable-in-water", striderRidableInWater); + } + + public boolean tropicalFishRidable = false; + private void tropicalFishSettings() { + tropicalFishRidable = getBoolean("mobs.tropical_fish.ridable", tropicalFishRidable); + } + + public boolean turtleRidable = false; + public boolean turtleRidableInWater = false; + private void turtleSettings() { + turtleRidable = getBoolean("mobs.turtle.ridable", turtleRidable); + turtleRidableInWater = getBoolean("mobs.turtle.ridable-in-water", turtleRidableInWater); + } + + public boolean vexRidable = false; + public boolean vexRidableInWater = false; + public double vexMaxY = 256D; + private void vexSettings() { + vexRidable = getBoolean("mobs.vex.ridable", vexRidable); + vexRidableInWater = getBoolean("mobs.vex.ridable-in-water", vexRidableInWater); + vexMaxY = getDouble("mobs.vex.ridable-max-y", vexMaxY); + } + + public boolean villagerRidable = false; + public boolean villagerRidableInWater = false; public int villagerBrainTicks = 1; public boolean villagerUseBrainTicksOnlyWhenLagging = true; public boolean villagerCanBeLeashed = false; @@ -572,6 +935,8 @@ public class PurpurWorldConfig { public int villagerSpawnIronGolemLimit = 0; public boolean villagerCanBreed = true; private void villagerSettings() { + villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable); + villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater); villagerBrainTicks = getInt("mobs.villager.brain-ticks", villagerBrainTicks); villagerUseBrainTicksOnlyWhenLagging = getBoolean("mobs.villager.use-brain-ticks-only-when-lagging", villagerUseBrainTicksOnlyWhenLagging); villagerCanBeLeashed = getBoolean("mobs.villager.can-be-leashed", villagerCanBeLeashed); @@ -582,45 +947,108 @@ public class PurpurWorldConfig { villagerCanBreed = getBoolean("mobs.villager.can-breed", villagerCanBreed); } + public boolean villagerTraderRidable = false; + public boolean villagerTraderRidableInWater = false; public boolean villagerTraderCanBeLeashed = false; public boolean villagerTraderFollowEmeraldBlock = false; private void villagerTraderSettings() { + villagerTraderRidable = getBoolean("mobs.wandering_trader.ridable", villagerTraderRidable); + villagerTraderRidableInWater = getBoolean("mobs.wandering_trader.ridable-in-water", villagerTraderRidableInWater); villagerTraderCanBeLeashed = getBoolean("mobs.wandering_trader.can-be-leashed", villagerTraderCanBeLeashed); villagerTraderFollowEmeraldBlock = getBoolean("mobs.wandering_trader.follow-emerald-blocks", villagerTraderFollowEmeraldBlock); } + public boolean vindicatorRidable = false; + public boolean vindicatorRidableInWater = false; + public double vindicatorJohnnySpawnChance = 0D; + private void vindicatorSettings() { + vindicatorRidable = getBoolean("mobs.vindicator.ridable", vindicatorRidable); + vindicatorRidableInWater = getBoolean("mobs.vindicator.ridable-in-water", vindicatorRidableInWater); + vindicatorJohnnySpawnChance = getDouble("mobs.vindicator.johnny.spawn-chance", vindicatorJohnnySpawnChance); + } + + public boolean witchRidable = false; + public boolean witchRidableInWater = false; + private void witchSettings() { + witchRidable = getBoolean("mobs.witch.ridable", witchRidable); + witchRidableInWater = getBoolean("mobs.witch.ridable-in-water", witchRidableInWater); + } + + public boolean witherRidable = false; + public boolean witherRidableInWater = false; + public double witherMaxY = 256D; + private void witherSettings() { + witherRidable = getBoolean("mobs.wither.ridable", witherRidable); + witherRidableInWater = getBoolean("mobs.wither.ridable-in-water", witherRidableInWater); + witherMaxY = getDouble("mobs.wither.ridable-max-y", witherMaxY); + } + + public boolean witherSkeletonRidable = false; + public boolean witherSkeletonRidableInWater = false; public boolean witherSkeletonTakesWitherDamage = false; private void witherSkeletonSettings() { + witherSkeletonRidable = getBoolean("mobs.wither_skeleton.ridable", witherSkeletonRidable); + witherSkeletonRidableInWater = getBoolean("mobs.wither_skeleton.ridable-in-water", witherSkeletonRidableInWater); witherSkeletonTakesWitherDamage = getBoolean("mobs.wither_skeleton.takes-wither-damage", witherSkeletonTakesWitherDamage); } + public boolean wolfRidable = false; + public boolean wolfRidableInWater = false; + private void wolfSettings() { + wolfRidable = getBoolean("mobs.wolf.ridable", wolfRidable); + wolfRidableInWater = getBoolean("mobs.wolf.ridable-in-water", wolfRidableInWater); + } + + public boolean zoglinRidable = false; + public boolean zoglinRidableInWater = false; + private void zoglinSettings() { + zoglinRidable = getBoolean("mobs.zoglin.ridable", zoglinRidable); + zoglinRidableInWater = getBoolean("mobs.zoglin.ridable-in-water", zoglinRidableInWater); + } + + public boolean zombieRidable = false; + public boolean zombieRidableInWater = false; public boolean zombieJockeyOnlyBaby = true; public double zombieJockeyChance = 0.05D; public boolean zombieJockeyTryExistingChickens = true; private void zombieSettings() { + zombieRidable = getBoolean("mobs.zombie.ridable", zombieRidable); + zombieRidableInWater = getBoolean("mobs.zombie.ridable-in-water", zombieRidableInWater); zombieJockeyOnlyBaby = getBoolean("mobs.zombie.jockey.only-babies", zombieJockeyOnlyBaby); zombieJockeyChance = getDouble("mobs.zombie.jockey.chance", zombieJockeyChance); zombieJockeyTryExistingChickens = getBoolean("mobs.zombie.jockey.try-existing-chickens", zombieJockeyTryExistingChickens); } + public boolean zombieHorseCanSwim = false; + public boolean zombieHorseRidableInWater = false; public double zombieHorseSpawnChance = 0.0D; private void zombieHorseSettings() { + zombieHorseCanSwim = getBoolean("mobs.zombie_horse.can-swim", zombieHorseCanSwim); + zombieHorseRidableInWater = getBoolean("mobs.zombie_horse.ridable-in-water", zombieHorseRidableInWater); zombieHorseSpawnChance = getDouble("mobs.zombie_horse.spawn-chance", zombieHorseSpawnChance); } + public boolean zombifiedPiglinRidable = false; + public boolean zombifiedPiglinRidableInWater = false; public boolean zombifiedPiglinJockeyOnlyBaby = true; public double zombifiedPiglinJockeyChance = 0.05D; public boolean zombifiedPiglinJockeyTryExistingChickens = true; private void zombifiedPiglinSettings() { + zombifiedPiglinRidable = getBoolean("mobs.zombified_piglin.ridable", zombifiedPiglinRidable); + zombifiedPiglinRidableInWater = getBoolean("mobs.zombified_piglin.ridable-in-water", zombifiedPiglinRidableInWater); zombifiedPiglinJockeyOnlyBaby = getBoolean("mobs.zombified_piglin.jockey.only-babies", zombifiedPiglinJockeyOnlyBaby); zombifiedPiglinJockeyChance = getDouble("mobs.zombified_piglin.jockey.chance", zombifiedPiglinJockeyChance); zombifiedPiglinJockeyTryExistingChickens = getBoolean("mobs.zombified_piglin.jockey.try-existing-chickens", zombifiedPiglinJockeyTryExistingChickens); } + public boolean zombieVillagerRidable = false; + public boolean zombieVillagerRidableInWater = false; public boolean zombieVillagerJockeyOnlyBaby = true; public double zombieVillagerJockeyChance = 0.05D; public boolean zombieVillagerJockeyTryExistingChickens = true; 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 0000000000000000000000000000000000000000..088c830471b796908781bc1aa0693355849754cd --- /dev/null +++ b/src/main/java/net/pl3x/purpur/controller/ControllerLookWASD.java @@ -0,0 +1,76 @@ +package net.pl3x.purpur.controller; + +import net.minecraft.network.protocol.game.PacketPlayOutEntity; +import net.minecraft.world.entity.ai.control.ControllerLook; +import net.minecraft.world.entity.EntityInsentient; +import net.minecraft.util.MathHelper; +import net.minecraft.world.entity.player.EntityHuman; + +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.hasPurpurRider()) { + tick(entity.getPurpurRider()); + } else { + tick(); + } + } + + protected void tick() { + super.a(); // tick + } + + protected void tick(EntityHuman rider) { + setYawPitch(rider.yaw, rider.pitch); + } + + public void setYawPitch(float yaw, float pitch) { + entity.yaw = normalizeYaw(yaw + yawOffset); + entity.lastYaw = entity.yaw; + entity.setBodyYaw(entity.yaw); + entity.setRenderYawOffset(entity.yaw); + entity.setHeadRotation(entity.yaw); + entity.pitch = normalizePitch(pitch + pitchOffset); + + entity.tracker.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 0000000000000000000000000000000000000000..6b1f37398ef6cf5935e7acb4295f9223a026226a --- /dev/null +++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASD.java @@ -0,0 +1,92 @@ +package net.pl3x.purpur.controller; + +import net.minecraft.world.entity.ai.control.ControllerMove; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityInsentient; +import net.minecraft.world.entity.ai.attributes.GenericAttributes; +import net.minecraft.world.entity.player.EntityHuman; +import net.pl3x.purpur.event.entity.RidableSpacebarEvent; + +public class ControllerMoveWASD extends ControllerMove { + protected final EntityInsentient entity; + private final double speedModifier; + + public ControllerMoveWASD(EntityInsentient entity) { + this(entity, 1.0D); + } + + public ControllerMoveWASD(EntityInsentient entity, double speedModifier) { + super(entity); + this.entity = entity; + this.speedModifier = speedModifier; + } + + // isUpdating + @Override + public boolean b() { + return entity.hasPurpurRider() ? getForward() != 0 || getStrafe() != 0 : super.b(); + } + + // tick + @Override + public void a() { + if (entity.hasPurpurRider()) { + tick(entity.getPurpurRider()); + } else { + tick(); + } + } + + public void tick() { + super.a(); // tick + } + + public void tick(EntityHuman rider) { + float forward = rider.getForward() * 0.5F; + float strafe = rider.getStrafe() * 0.25F; + + if (forward <= 0.0F) { + forward *= 0.5F; + } + + float yawOffset = 0; + if (strafe != 0) { + if (forward == 0) { + yawOffset += strafe > 0 ? -90 : 90; + forward = Math.abs(strafe * 2); + } else { + yawOffset += strafe > 0 ? -30 : 30; + strafe /= 2; + if (forward < 0) { + yawOffset += strafe > 0 ? -110 : 110; + forward *= -1; + } + } + } else if (forward < 0) { + yawOffset -= 180; + forward *= -1; + } + + ((ControllerLookWASD) entity.getControllerLook()).setOffsets(yawOffset, 0); + + if (rider.jumping && spacebarEvent(entity) && !entity.onSpacebar() && entity.onGround) { + entity.jump(); + } + + setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * speedModifier); + + entity.setSpeed((float) getSpeed()); + entity.setForward(forward); + + setForward(entity.getForward()); + setStrafe(entity.getStrafe()); + } + + public static boolean spacebarEvent(Entity entity) { + if (RidableSpacebarEvent.getHandlerList().getRegisteredListeners().length > 0) { + return new RidableSpacebarEvent(entity.getBukkitEntity()).callEvent(); + } else { + return true; + } + } +} diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlying.java b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlying.java new file mode 100644 index 0000000000000000000000000000000000000000..7737e87048e88b40c0b6b4a1093e2256ae252802 --- /dev/null +++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlying.java @@ -0,0 +1,61 @@ +package net.pl3x.purpur.controller; + +import net.minecraft.world.entity.EntityInsentient; +import net.minecraft.world.entity.ai.attributes.GenericAttributes; +import net.minecraft.world.entity.player.EntityHuman; + +public class ControllerMoveWASDFlying extends ControllerMoveWASD { + protected final float groundSpeedModifier; + protected int tooHighCooldown = 0; + protected boolean setGravityFlag = true; + + public ControllerMoveWASDFlying(EntityInsentient entity) { + this(entity, 1.0F); + } + + public ControllerMoveWASDFlying(EntityInsentient entity, float groundSpeedModifier) { + this(entity, groundSpeedModifier, true); + } + + public ControllerMoveWASDFlying(EntityInsentient entity, float groundSpeedModifier, boolean setGravityFlag) { + super(entity); + this.groundSpeedModifier = groundSpeedModifier; + this.setGravityFlag = setGravityFlag; + } + + @Override + public void tick(EntityHuman rider) { + float forward = Math.max(0.0F, rider.getForward()); + float vertical = forward == 0.0F ? 0.0F : -(rider.pitch / 45.0F); + float strafe = rider.getStrafe(); + + if (rider.jumping && spacebarEvent(entity)) { + entity.onSpacebar(); + } + + if (entity.locY() >= entity.getMaxY() || --tooHighCooldown > 0) { + tooHighCooldown = 60; + entity.setMot(entity.getMot().add(0.0D, -0.05D, 0.0D)); + vertical = 0.0F; + } + + setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue()); + float speed = (float) getSpeed(); + + if (entity.onGround) { + speed *= groundSpeedModifier; // TODO = fix this! + } + + if (setGravityFlag) { + entity.setNoGravity(forward > 0); + } + + entity.setSpeed(speed); + entity.setVertical(vertical); + entity.setStrafe(strafe); + entity.setForward(forward); + + setForward(entity.getForward()); + setStrafe(entity.getStrafe()); + } +} diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlyingWithSpacebar.java b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlyingWithSpacebar.java new file mode 100644 index 0000000000000000000000000000000000000000..cdd32aa66b6bd9c01854e3d9baf25757c7e2a707 --- /dev/null +++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDFlyingWithSpacebar.java @@ -0,0 +1,61 @@ +package net.pl3x.purpur.controller; + +import net.minecraft.world.entity.EntityInsentient; +import net.minecraft.world.entity.ai.attributes.GenericAttributes; +import net.minecraft.world.entity.player.EntityHuman; +import net.minecraft.world.phys.Vec3D; + +public class ControllerMoveWASDFlyingWithSpacebar extends ControllerMoveWASDFlying { + public ControllerMoveWASDFlyingWithSpacebar(EntityInsentient entity) { + super(entity); + } + + public ControllerMoveWASDFlyingWithSpacebar(EntityInsentient entity, float groundSpeedModifier) { + super(entity, groundSpeedModifier); + } + + @Override + public void tick(EntityHuman rider) { + float forward = rider.getForward(); + float strafe = rider.getStrafe() * 0.5F; + float vertical = 0; + + if (forward < 0.0F) { + forward *= 0.5F; + strafe *= 0.5F; + } + + float speed = (float) entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue(); + + if (entity.onGround) { + speed *= groundSpeedModifier; + } + + if (rider.jumping && spacebarEvent(entity) && !entity.onSpacebar()) { + entity.setNoGravity(true); + vertical = 1.0F; + } else { + entity.setNoGravity(false); + } + + if (entity.locY() >= entity.getMaxY() || --tooHighCooldown > 0) { + tooHighCooldown = 60; + entity.setMot(entity.getMot().add(0.0D, -0.2D, 0.0D)); + vertical = 0.0F; + } + + setSpeed(speed); + entity.setSpeed((float) getSpeed()); + entity.setVertical(vertical); + entity.setStrafe(strafe); + entity.setForward(forward); + + setForward(entity.getForward()); + setStrafe(entity.getStrafe()); + + Vec3D mot = entity.getMot(); + if (mot.y > 0.2D) { + entity.setMot(mot.x, 0.2D, mot.z); + } + } +} diff --git a/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java new file mode 100644 index 0000000000000000000000000000000000000000..aa7eb0b3bd7be8d1992e99bf156dbad167e571aa --- /dev/null +++ b/src/main/java/net/pl3x/purpur/controller/ControllerMoveWASDWater.java @@ -0,0 +1,50 @@ +package net.pl3x.purpur.controller; + +import net.minecraft.world.entity.EntityInsentient; +import net.minecraft.world.entity.ai.attributes.GenericAttributes; +import net.minecraft.world.entity.player.EntityHuman; + +public class ControllerMoveWASDWater extends ControllerMoveWASD { + private final double speedModifier; + + public ControllerMoveWASDWater(EntityInsentient entity) { + this(entity, 1.0D); + } + + public ControllerMoveWASDWater(EntityInsentient entity, double speedModifier) { + super(entity); + this.speedModifier = speedModifier; + } + + @Override + public void tick(EntityHuman rider) { + float forward = rider.getForward(); + float strafe = rider.getStrafe() * 0.5F; // strafe slower by default + float vertical = -(rider.pitch / 90); + + if (forward == 0.0F) { + // strafe slower if not moving forward + strafe *= 0.5F; + // do not move vertically if not moving forward + vertical = 0.0F; + } else if (forward < 0.0F) { + // water animals can't swim backwards + forward = 0.0F; + vertical = 0.0F; + } + + if (rider.jumping && spacebarEvent(entity)) { + entity.onSpacebar(); + } + + setSpeed(entity.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).getValue() * speedModifier); + entity.setSpeed((float) getSpeed() * 0.1F); + + entity.setForward(forward * (float) speedModifier); + entity.setStrafe(strafe * (float) speedModifier); + entity.setVertical(vertical * (float) speedModifier); + + setForward(entity.getForward()); + setStrafe(entity.getStrafe()); + } +} diff --git a/src/main/java/net/pl3x/purpur/entity/DolphinSpit.java b/src/main/java/net/pl3x/purpur/entity/DolphinSpit.java new file mode 100644 index 0000000000000000000000000000000000000000..621e4d0af89e78404e79a92ba717392e4cf4f82b --- /dev/null +++ b/src/main/java/net/pl3x/purpur/entity/DolphinSpit.java @@ -0,0 +1,119 @@ +package net.pl3x.purpur.entity; + +import net.minecraft.world.entity.animal.EntityDolphin; +import net.minecraft.world.entity.projectile.EntityLlamaSpit; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityLiving; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.level.block.state.IBlockData; +import net.minecraft.util.MathHelper; +import net.minecraft.world.phys.MovingObjectPosition; +import net.minecraft.world.phys.MovingObjectPositionBlock; +import net.minecraft.world.phys.MovingObjectPositionEntity; +import net.minecraft.core.particles.Particles; +import net.minecraft.world.entity.projectile.ProjectileHelper; +import net.minecraft.world.phys.Vec3D; +import net.minecraft.world.level.World; +import net.minecraft.server.level.WorldServer; +import org.bukkit.craftbukkit.event.CraftEventFactory; + +public class DolphinSpit extends EntityLlamaSpit { + public EntityLiving dolphin; + public int ticksLived; + + public DolphinSpit(EntityTypes entitytypes, World world) { + super(entitytypes, world); + } + + public DolphinSpit(World world, EntityDolphin dolphin) { + this(EntityTypes.LLAMA_SPIT, world); + setShooter(dolphin.hasPurpurRider() ? dolphin.getPurpurRider() : dolphin); + this.dolphin = dolphin; + this.setPosition( + dolphin.locX() - (double) (dolphin.getWidth() + 1.0F) * 0.5D * (double) MathHelper.sin(dolphin.getRenderYawOffset() * 0.017453292F), + dolphin.getHeadY() - 0.10000000149011612D, + dolphin.locZ() + (double) (dolphin.getWidth() + 1.0F) * 0.5D * (double) MathHelper.cos(dolphin.getRenderYawOffset() * 0.017453292F)); + } + + @Override + public boolean canSaveToDisk() { + return false; + } + + public void tick() { + if (dead || !valid) { + return; + } + + if (!leftOwner()) { + setLeftOwner(checkIfLeftOwner()); + } + + setFlag(6, isGlowing()); + entityBaseTick(); + + Vec3D mot = getMot(); + + MovingObjectPosition hitResult = ProjectileHelper.getHitResult(this, this::hitPredicate); + if (hitResult != null) { + onHit(hitResult); + } + + double x = this.locX() + mot.x; + double y = this.locY() + mot.y; + double z = this.locZ() + mot.z; + setMot(mot.scale(0.99D)); + + Vec3D motDouble = mot.scale(2.0); + for (int i = 0; i < 5; i++) { + ((WorldServer) world).sendParticles(null, Particles.BUBBLE, + locX() + random.nextFloat() / 2 - 0.25F, + locY() + random.nextFloat() / 2 - 0.25F, + locZ() + random.nextFloat() / 2 - 0.25F, + 0, motDouble.getX(), motDouble.getY(), motDouble.getZ(), 0.1, true); + } + + if (++ticksLived > 20) { + die(); + } else { + setMot(mot.scale(0.99D)); + if (!isNoGravity()) { + setMot(getMot().add(0.0D, -0.06D, 0.0D)); + } + setPosition(x, y, z); + } + } + + @Override + public void shoot(double x, double y, double z, float speed, float inaccuracy) { + setMot(new Vec3D(x, y, z).normalize().add( + random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, + random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, + random.nextGaussian() * (double) 0.0075F * (double) inaccuracy) + .scale(speed)); + } + + public void onHit(MovingObjectPosition rayTrace) { + CraftEventFactory.callProjectileHitEvent(this, rayTrace); + MovingObjectPosition.EnumMovingObjectType type = rayTrace.getType(); + if (type == MovingObjectPosition.EnumMovingObjectType.ENTITY) { + onHit((MovingObjectPositionEntity) rayTrace); + } else if (type == MovingObjectPosition.EnumMovingObjectType.BLOCK) { + onHit((MovingObjectPositionBlock) rayTrace); + } + } + + protected void onHit(MovingObjectPositionEntity rayTrace) { + Entity shooter = getShooter(); + if (shooter instanceof EntityLiving) { + rayTrace.getEntity().damageEntity(DamageSource.indirectMobAttack(this, (EntityLiving) shooter).setProjectile(), world.purpurConfig.dolphinSpitDamage); + } + } + + protected void onHit(MovingObjectPositionBlock rayTrace) { + IBlockData iblockdata = world.getType(rayTrace.getBlockPosition()); + iblockdata.a(world, iblockdata, rayTrace, this); + die(); + } +} diff --git a/src/main/java/net/pl3x/purpur/entity/PhantomFlames.java b/src/main/java/net/pl3x/purpur/entity/PhantomFlames.java new file mode 100644 index 0000000000000000000000000000000000000000..c7cd0327084943dcb6339998805e6b7db1d87bba --- /dev/null +++ b/src/main/java/net/pl3x/purpur/entity/PhantomFlames.java @@ -0,0 +1,140 @@ +package net.pl3x.purpur.entity; + +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityLiving; +import net.minecraft.world.entity.EntityTypes; +import net.minecraft.world.entity.decoration.EntityArmorStand; +import net.minecraft.world.entity.monster.EntityPhantom; +import net.minecraft.world.entity.projectile.EntityLlamaSpit; +import net.minecraft.world.level.block.state.BlockBase; +import net.minecraft.world.level.block.state.IBlockData; +import net.minecraft.util.MathHelper; +import net.minecraft.world.phys.MovingObjectPosition; +import net.minecraft.world.phys.MovingObjectPositionBlock; +import net.minecraft.world.phys.MovingObjectPositionEntity; +import net.minecraft.core.particles.Particles; +import net.minecraft.world.entity.projectile.ProjectileHelper; +import net.minecraft.world.phys.Vec3D; +import net.minecraft.world.level.World; +import net.minecraft.server.level.WorldServer; +import org.bukkit.craftbukkit.event.CraftEventFactory; + +public class PhantomFlames extends EntityLlamaSpit { + public EntityPhantom phantom; + public int ticksLived; + public boolean canGrief = false; + + public PhantomFlames(EntityTypes entitytypes, World world) { + super(entitytypes, world); + } + + public PhantomFlames(World world, EntityPhantom phantom) { + this(EntityTypes.LLAMA_SPIT, world); + setShooter(phantom.hasPurpurRider() ? phantom.getPurpurRider() : phantom); + this.phantom = phantom; + this.setPosition( + phantom.locX() - (double) (phantom.getWidth() + 1.0F) * 0.5D * (double) MathHelper.sin(phantom.getRenderYawOffset() * 0.017453292F), + phantom.getHeadY() - 0.10000000149011612D, + phantom.locZ() + (double) (phantom.getWidth() + 1.0F) * 0.5D * (double) MathHelper.cos(phantom.getRenderYawOffset() * 0.017453292F)); + } + + @Override + public boolean canSaveToDisk() { + return false; + } + + @Override + public void tick() { + if (dead || !valid) { + return; + } + + if (!leftOwner()) { + setLeftOwner(checkIfLeftOwner()); + } + + setFlag(6, isGlowing()); + entityBaseTick(); + + Vec3D mot = getMot(); + + MovingObjectPosition hitResult = ProjectileHelper.getHitResult(this, this::hitPredicate); + if (hitResult != null) { + onHit(hitResult); + } + + if (dead) { + return; + } + + double x = this.locX() + mot.x; + double y = this.locY() + mot.y; + double z = this.locZ() + mot.z; + setMot(mot.scale(0.99D)); + + Vec3D motDouble = mot.scale(2.0); + for (int i = 0; i < 5; i++) { + ((WorldServer) world).sendParticles(null, Particles.FLAME, + locX() + random.nextFloat() / 2 - 0.25F, + locY() + random.nextFloat() / 2 - 0.25F, + locZ() + random.nextFloat() / 2 - 0.25F, + 0, motDouble.getX(), motDouble.getY(), motDouble.getZ(), 0.1, true); + } + + if (world.a(getBoundingBox()).noneMatch(BlockBase.BlockData::isAir)) { + die(); + } else if (isInWaterOrBubbleColumn()) { + die(); + } else if (++ticksLived > 20) { + die(); + } else { + setMot(mot.scale(0.99D)); + if (!isNoGravity()) { + setMot(getMot().add(0.0D, -0.06D, 0.0D)); + } + setPosition(x, y, z); + } + } + + @Override + public void shoot(double x, double y, double z, float speed, float inaccuracy) { + setMot(new Vec3D(x, y, z).normalize().add( + random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, + random.nextGaussian() * (double) 0.0075F * (double) inaccuracy, + random.nextGaussian() * (double) 0.0075F * (double) inaccuracy) + .scale(speed)); + } + + public void onHit(MovingObjectPosition rayTrace) { + CraftEventFactory.callProjectileHitEvent(this, rayTrace); + MovingObjectPosition.EnumMovingObjectType type = rayTrace.getType(); + if (type == MovingObjectPosition.EnumMovingObjectType.ENTITY) { + onHit((MovingObjectPositionEntity) rayTrace); + } else if (type == MovingObjectPosition.EnumMovingObjectType.BLOCK) { + onHit((MovingObjectPositionBlock) rayTrace); + } + } + + protected void onHit(MovingObjectPositionEntity rayTrace) { + Entity shooter = getShooter(); + if (shooter instanceof EntityLiving) { + Entity target = rayTrace.getEntity(); + if (canGrief || (target instanceof EntityLiving && !(target instanceof EntityArmorStand))) { + target.damageEntity(DamageSource.indirectMobAttack(this, (EntityLiving) shooter).setProjectile(), world.purpurConfig.phantomFlameDamage); + if (world.purpurConfig.phantomFlameFireTime > 0) { + target.setOnFire(world.purpurConfig.phantomFlameFireTime); + } + } + } + die(); + } + + protected void onHit(MovingObjectPositionBlock rayTrace) { + if (canGrief) { + IBlockData iblockdata = world.getType(rayTrace.getBlockPosition()); + iblockdata.a(world, iblockdata, rayTrace, this); + } + die(); + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index dee4d12a49468d38f077784b219199f0070786f2..dcdc82b42689b4962323938a62cf7ded49afd6f4 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -12,9 +12,6 @@ import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.chat.IChatBaseComponent; import net.minecraft.server.level.EntityPlayer; -import net.minecraft.server.level.PlayerChunk; -import net.minecraft.server.level.PlayerChunkMap; -import net.minecraft.server.level.TicketType; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityAreaEffectCloud; @@ -147,7 +144,6 @@ import net.minecraft.world.entity.vehicle.EntityMinecartHopper; import net.minecraft.world.entity.vehicle.EntityMinecartMobSpawner; import net.minecraft.world.entity.vehicle.EntityMinecartRideable; import net.minecraft.world.entity.vehicle.EntityMinecartTNT; -import net.minecraft.world.level.ChunkCoordIntPair; import net.minecraft.world.phys.AxisAlignedBB; import org.bukkit.Chunk; // Paper import org.bukkit.EntityEffect; @@ -1175,4 +1171,26 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { return getHandle().isTicking(); } // Paper end + + // Purpur start + @Override + public org.bukkit.entity.Player getRider() { + return hasRider() ? (org.bukkit.entity.Player) getHandle().getPurpurRider().getBukkitEntity() : null; + } + + @Override + public boolean hasRider() { + return getHandle().hasPurpurRider(); + } + + @Override + public boolean isRidable() { + return getHandle().isRidable(); + } + + @Override + public boolean isRidableInWater() { + return getHandle().isRidableInWater(); + } + // Purpur end } diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index b14cec316b16e46d54d389650372c5c9ce1e5a4d..81ea6ffb6be8a7aed281c6538f0535bbaf00b068 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -545,6 +545,18 @@ public class CraftEventFactory { } craftServer.getPluginManager().callEvent(event); + // Purpur start + switch (action) { + case LEFT_CLICK_BLOCK: + case LEFT_CLICK_AIR: + who.processClick(EnumHand.MAIN_HAND); + break; + case RIGHT_CLICK_BLOCK: + case RIGHT_CLICK_AIR: + who.processClick(EnumHand.OFF_HAND); + } + // Purpur end + return event; } @@ -948,6 +960,7 @@ public class CraftEventFactory { damageCause = DamageCause.ENTITY_EXPLOSION; } event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), entity.getBukkitEntity(), damageCause, modifiers, modifierFunctions); + damager.processClick(EnumHand.MAIN_HAND); // Purpur } event.setCancelled(cancelled); @@ -1032,6 +1045,7 @@ public class CraftEventFactory { if (!event.isCancelled()) { event.getEntity().setLastDamageCause(event); } + damager.getHandle().processClick(EnumHand.MAIN_HAND); // Purpur return event; } @@ -1081,6 +1095,7 @@ public class CraftEventFactory { EntityDamageEvent event; if (damager != null) { event = new EntityDamageByEntityEvent(damager.getBukkitEntity(), damagee.getBukkitEntity(), cause, modifiers, modifierFunctions); + damager.processClick(EnumHand.MAIN_HAND); // Purpur } else { event = new EntityDamageEvent(damagee.getBukkitEntity(), cause, modifiers, modifierFunctions); }