From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Encode42 Date: Tue, 8 Dec 2020 17:15:15 -0500 Subject: [PATCH] Configurable chance for wolves to spawn rabid Configurable chance to spawn a wolf that is rabid. Rabid wolves attack all players, mobs, and animals. diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java index f730fa484b770eb41ce1fe4f7765b77866472798..e3ac6ebfd488e8ee94eb47c224e53f05eff9c563 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -2085,6 +2085,7 @@ public abstract class EntityLiving extends Entity { } } + public final void setItemInHand(EnumHand enumHand, ItemStack itemStack) { this.a(enumHand, itemStack); } // Purpur - OBFHELPER public void a(EnumHand enumhand, ItemStack itemstack) { if (enumhand == EnumHand.MAIN_HAND) { this.setSlot(EnumItemSlot.MAINHAND, itemstack); diff --git a/src/main/java/net/minecraft/server/EntityWolf.java b/src/main/java/net/minecraft/server/EntityWolf.java index 6c25f667eecdf345289a0dbf885c9d71c6a26958..5fe2e9f4bfbdc08690eacd6196e59529dc7953e8 100644 --- a/src/main/java/net/minecraft/server/EntityWolf.java +++ b/src/main/java/net/minecraft/server/EntityWolf.java @@ -14,11 +14,42 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable private static final DataWatcherObject br = DataWatcher.a(EntityWolf.class, DataWatcherRegistry.i); private static final DataWatcherObject bs = DataWatcher.a(EntityWolf.class, DataWatcherRegistry.b); private static final DataWatcherObject bt = DataWatcher.a(EntityWolf.class, DataWatcherRegistry.b); - public static final Predicate bq = (entityliving) -> { + public static Predicate vanillaPredicate() { return bq; } public static final Predicate bq = (entityliving) -> { // Purpur - OBFHELPER EntityTypes entitytypes = entityliving.getEntityType(); return entitytypes == EntityTypes.SHEEP || entitytypes == EntityTypes.RABBIT || entitytypes == EntityTypes.FOX; }; + // Purpur start - rabid wolf spawn chance + private boolean isRabid = false; + private static final Predicate RABID_PREDICATE = e -> e instanceof EntityPlayer || e instanceof EntityInsentient; + private final PathfinderGoal PATHFINDER_VANILLA = new PathfinderGoalRandomTargetNonTamed<>(this, EntityAnimal.class, false, vanillaPredicate()); + private final PathfinderGoal PATHFINDER_RABID = new PathfinderGoalRandomTargetNonTamed<>(this, EntityLiving.class, false, RABID_PREDICATE); + private static final class PathfinderGoalAvoidRabidWolves extends PathfinderGoalAvoidTarget { + private final EntityWolf wolf; + + public PathfinderGoalAvoidRabidWolves(EntityWolf wolf, float distance, double minSpeed, double maxSpeed) { + super(wolf, EntityWolf.class, distance, minSpeed, maxSpeed); + this.wolf = wolf; + } + + @Override + public boolean a() { // shouldExecute + return super.a() && !this.wolf.isRabid() && this.getTarget() != null && this.getTarget().isRabid(); // wolves which are not rabid run away from rabid wolves + } + + @Override + public void c() { // startExecuting + this.wolf.setGoalTarget(null); + super.c(); + } + + @Override + public void e() { // tick + this.wolf.setGoalTarget(null); + super.e(); + } + } + // Purpur end private float bu; private float bv; private boolean bw; @@ -53,6 +84,37 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable int getPurpurBreedTime() { return this.world.purpurConfig.wolfBreedingTicks; } + + public boolean isRabid() { + return this.isRabid; + } + + public void setRabid(boolean isRabid) { + this.isRabid = isRabid; + updatePathfinders(true); + } + + public void updatePathfinders(boolean modifyEffects) { + this.targetSelector.removeGoal(PATHFINDER_VANILLA); + this.targetSelector.removeGoal(PATHFINDER_RABID); + if (this.isRabid) { + setTamed(false); + setOwnerUUID(null); + this.targetSelector.addGoal(5, PATHFINDER_RABID); + if (modifyEffects) this.addEffect(new MobEffect(MobEffects.CONFUSION, 1200)); + } else { + this.targetSelector.addGoal(5, PATHFINDER_VANILLA); + this.pacify(); + if (modifyEffects) this.removeEffect(MobEffects.CONFUSION); + } + } + + @Override + public GroupDataEntity prepare(WorldAccess worldaccess, DifficultyDamageScaler difficultydamagescaler, EnumMobSpawn enummobspawn, @Nullable GroupDataEntity groupdataentity, @Nullable NBTTagCompound nbttagcompound) { + this.isRabid = world.purpurConfig.wolfNaturalRabid > 0.0D && random.nextDouble() <= world.purpurConfig.wolfNaturalRabid; + this.updatePathfinders(false); + return super.prepare(worldaccess, difficultydamagescaler, enummobspawn, groupdataentity, nbttagcompound); + } // Purpur end @Override @@ -61,6 +123,7 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable 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.addGoal(3, new PathfinderGoalAvoidRabidWolves(this, 24.0F, 1.5D, 1.5D)); // Purpur this.goalSelector.a(4, new PathfinderGoalLeapAtTarget(this, 0.4F)); this.goalSelector.a(5, new PathfinderGoalMeleeAttack(this, 1.0D, true)); this.goalSelector.a(6, new PathfinderGoalFollowOwner(this, 1.0D, 10.0F, 2.0F, false)); @@ -74,7 +137,7 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable this.targetSelector.a(2, new PathfinderGoalOwnerHurtTarget(this)); this.targetSelector.a(3, (new PathfinderGoalHurtByTarget(this, new Class[0])).a(new Class[0])); // CraftBukkit - decompile error this.targetSelector.a(4, new PathfinderGoalNearestAttackableTarget<>(this, EntityHuman.class, 10, true, false, this::a_)); - this.targetSelector.a(5, new PathfinderGoalRandomTargetNonTamed<>(this, EntityAnimal.class, false, EntityWolf.bq)); + //this.targetSelector.a(5, new PathfinderGoalRandomTargetNonTamed<>(this, EntityAnimal.class, false, EntityWolf.bq)); // Purpur - moved to updatePathfinders() this.targetSelector.a(6, new PathfinderGoalRandomTargetNonTamed<>(this, EntityTurtle.class, false, EntityTurtle.bo)); this.targetSelector.a(7, new PathfinderGoalNearestAttackableTarget<>(this, EntitySkeletonAbstract.class, false)); this.targetSelector.a(8, new PathfinderGoalUniversalAngerReset<>(this, true)); @@ -119,6 +182,7 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable public void saveData(NBTTagCompound nbttagcompound) { super.saveData(nbttagcompound); nbttagcompound.setByte("CollarColor", (byte) this.getCollarColor().getColorIndex()); + nbttagcompound.setBoolean("Purpur.IsRabid", this.isRabid); // Purpur this.c(nbttagcompound); } @@ -128,6 +192,10 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable if (nbttagcompound.hasKeyOfType("CollarColor", 99)) { this.setCollarColor(EnumColor.fromColorIndex(nbttagcompound.getInt("CollarColor"))); } + // Purpur start + this.isRabid = nbttagcompound.getBoolean("Purpur.IsRabid"); + this.updatePathfinders(false); + // Purpur end this.a((WorldServer) this.world, nbttagcompound); } @@ -172,6 +240,11 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable public void tick() { super.tick(); if (this.isAlive()) { + // Purpur start + if (this.ticksLived % 300 == 0 && this.isRabid()) { + this.addEffect(new MobEffect(MobEffects.CONFUSION, 400)); + } + // Purpur end this.bv = this.bu; if (this.eY()) { this.bu += (1.0F - this.bu) * 0.4F; @@ -343,6 +416,20 @@ public class EntityWolf extends EntityTameableAnimal implements IEntityAngerable return EnumInteractionResult.SUCCESS; } + // Purpur start + else if (this.world.purpurConfig.wolfMilkCuresRabies && itemstack.getItem() == Items.MILK_BUCKET && this.isRabid()) { + if (!entityhuman.isCreative()) { + entityhuman.setItemInHand(enumhand, new ItemStack(Items.BUCKET)); + } + this.setRabid(false); + for (int i = 0; i < 10; ++i) { + ((WorldServer) world).sendParticles(((WorldServer) world).players, null, Particles.HAPPY_VILLAGER, + locX() + random.nextFloat(), locY() + (random.nextFloat() * 1.5), locZ() + random.nextFloat(), 1, + random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, random.nextGaussian() * 0.05D, 0, true); + } + return EnumInteractionResult.SUCCESS; + } + // Purpur end return super.b(entityhuman, enumhand); } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalAvoidTarget.java b/src/main/java/net/minecraft/server/PathfinderGoalAvoidTarget.java index 9a4819815c7a4bf2fd4a92c4169ace35f2261704..da29898574d30d5fecc5a44ad7b365564fa686e1 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalAvoidTarget.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalAvoidTarget.java @@ -8,7 +8,7 @@ public class PathfinderGoalAvoidTarget extends Pathfinde protected final EntityCreature a; private final double i; private final double j; - protected T b; + protected T b; protected T getTarget() { return this.b; } // Purpur - OBFHELPER protected final float c; protected PathEntity d; protected final NavigationAbstract e; @@ -18,12 +18,7 @@ public class PathfinderGoalAvoidTarget extends Pathfinde private final PathfinderTargetCondition k; public PathfinderGoalAvoidTarget(EntityCreature entitycreature, Class oclass, float f, double d0, double d1) { - Predicate predicate = (entityliving) -> { - return true; - }; - Predicate predicate1 = IEntitySelector.e; - - this(entitycreature, oclass, predicate, f, d0, d1, predicate1::test); + this(entitycreature, oclass, entityliving -> true, f, d0, d1, IEntitySelector.e::test); // Purpur - decompile fix } public PathfinderGoalAvoidTarget(EntityCreature entitycreature, Class oclass, Predicate predicate, float f, double d0, double d1, Predicate predicate1) { diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java index ed39dad5707add6392042073998e8ce08a887d1e..fb936cfac0155f800036685ba7cc3615b1474a44 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java @@ -1148,10 +1148,14 @@ public class PurpurWorldConfig { public boolean wolfRidable = false; public boolean wolfRidableInWater = false; + public boolean wolfMilkCuresRabies = true; + public double wolfNaturalRabid = 0.0D; public int wolfBreedingTicks = 6000; private void wolfSettings() { wolfRidable = getBoolean("mobs.wolf.ridable", wolfRidable); wolfRidableInWater = getBoolean("mobs.wolf.ridable-in-water", wolfRidableInWater); + wolfMilkCuresRabies = getBoolean("mobs.wolf.milk-cures-rabid-wolves", wolfMilkCuresRabies); + wolfNaturalRabid = getDouble("mobs.wolf.spawn-rabid-chance", wolfNaturalRabid); wolfBreedingTicks = getInt("mobs.wolf.breeding-delay-ticks", wolfBreedingTicks); } diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java index 5f3314febb2300a9b4f3a7c143cb65811e1d5320..507857ba247d0988e0011d215ea38a3622e78e05 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java @@ -45,4 +45,16 @@ public class CraftWolf extends CraftTameableAnimal implements Wolf { public void setCollarColor(DyeColor color) { getHandle().setCollarColor(EnumColor.fromColorIndex(color.getWoolData())); } + + // Purpur start + @Override + public boolean isRabid() { + return getHandle().isRabid(); + } + + @Override + public void setRabid(boolean isRabid) { + getHandle().setRabid(isRabid); + } + // Purpur end }