its 3 patches this time

This commit is contained in:
Ben Kerllenevich
2021-06-16 12:06:52 -04:00
parent 3369c2c1a6
commit 4a18cb965b
8 changed files with 313 additions and 1164 deletions

View File

@@ -1,212 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Sat, 22 Feb 2020 15:54:08 -0600
Subject: [PATCH] Item entity immunities
diff --git a/src/main/java/net/minecraft/server/level/EntityTrackerEntry.java b/src/main/java/net/minecraft/server/level/EntityTrackerEntry.java
index eaa68fb865dd23af20a05b567aad231dd8fa469c..7d76cb3951fe4ce68292a120c36af4a5fd63f4a8 100644
--- a/src/main/java/net/minecraft/server/level/EntityTrackerEntry.java
+++ b/src/main/java/net/minecraft/server/level/EntityTrackerEntry.java
@@ -67,7 +67,7 @@ public class EntityTrackerEntry {
private boolean q;
private boolean r;
// CraftBukkit start
- final Set<EntityPlayer> trackedPlayers; // Paper - private -> package
+ public final Set<EntityPlayer> trackedPlayers; // Paper - private -> public
// Paper start
private java.util.Map<EntityPlayer, Boolean> trackedPlayerMap = null;
diff --git a/src/main/java/net/minecraft/server/level/PlayerChunkMap.java b/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
index 6835401bd7863bbd655502547a9fd4ae0f298da1..1f4ef4f556ce31581819ca82ec81691025d0f7a5 100644
--- a/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/PlayerChunkMap.java
@@ -2357,7 +2357,7 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially
public class EntityTracker {
- final EntityTrackerEntry trackerEntry; // Paper - private -> package private
+ public final EntityTrackerEntry trackerEntry; // Paper - private -> package private // Purpur -> public
private final Entity tracker;
private final int trackingDistance;
private SectionPosition e;
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 9b739a7ed9761c045ba23b065bd8548ef0b81130..e433ca9305ced694a3dbb9fc8a1c5eddb7e6b431 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -1364,6 +1364,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
}
+ public boolean isInLiquid(Tag<FluidType> tag) { return a(tag); } // Purpur - OBFHELPER
public boolean a(Tag<FluidType> tag) {
return this.O == tag;
}
diff --git a/src/main/java/net/minecraft/world/entity/item/EntityItem.java b/src/main/java/net/minecraft/world/entity/item/EntityItem.java
index 8b79220c27292f9b92d9884bbbe4b16d7762343c..cd711fa6f4d8e98fbfa9e3956d9fb1d36e6bb2d9 100644
--- a/src/main/java/net/minecraft/world/entity/item/EntityItem.java
+++ b/src/main/java/net/minecraft/world/entity/item/EntityItem.java
@@ -50,6 +50,12 @@ public class EntityItem extends Entity {
public final float b;
private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit
public boolean canMobPickup = true; // Paper
+ // Purpur start
+ public boolean immuneToCactus = false;
+ public boolean immuneToExplosion = false;
+ public boolean immuneToFire = false;
+ public boolean immuneToLightning = false;
+ // Purpur end
public EntityItem(EntityTypes<? extends EntityItem> entitytypes, World world) {
super(entitytypes, world);
@@ -309,6 +315,16 @@ public class EntityItem extends Entity {
return false;
} else if (!this.getItemStack().getItem().a(damagesource)) {
return false;
+ // Purpur start
+ } else if (
+ (immuneToCactus && damagesource == DamageSource.CACTUS) ||
+ (immuneToFire && (damagesource.isFire() || damagesource == DamageSource.FIRE)) ||
+ (immuneToLightning && damagesource == DamageSource.LIGHTNING) ||
+ (immuneToExplosion && damagesource.isExplosion())
+ ) {
+ respawnOnClient();
+ return false;
+ // Purpur end
} else {
// CraftBukkit start
if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, damagesource, f)) {
@@ -489,6 +505,12 @@ public class EntityItem extends Entity {
com.google.common.base.Preconditions.checkArgument(!itemstack.isEmpty(), "Cannot drop air"); // CraftBukkit
this.getDataWatcher().set(EntityItem.ITEM, itemstack);
this.getDataWatcher().markDirty(EntityItem.ITEM); // CraftBukkit - SPIGOT-4591, must mark dirty
+ // Purpur start
+ if (world.purpurConfig.itemImmuneToCactus.contains(itemstack.getItem())) immuneToCactus = true;
+ if (world.purpurConfig.itemImmuneToExplosion.contains(itemstack.getItem())) immuneToExplosion = true;
+ if (world.purpurConfig.itemImmuneToFire.contains(itemstack.getItem())) immuneToFire = true;
+ if (world.purpurConfig.itemImmuneToLightning.contains(itemstack.getItem())) immuneToLightning = true;
+ // Purpur end
}
@Override
@@ -570,4 +592,15 @@ public class EntityItem extends Entity {
super.setPositionRaw(x, y, z);
}
// Paper end - fix MC-4
+
+ // Purpur start
+ public void respawnOnClient() {
+ Packet<?> spawnPacket = new PacketPlayOutSpawnEntity(this);
+ Packet<?> metadataPacket = new net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata(getId(), getDataWatcher(), true);
+ for (net.minecraft.server.level.EntityPlayer entityplayer : this.tracker.trackerEntry.trackedPlayers) {
+ entityplayer.playerConnection.sendPacket(spawnPacket);
+ entityplayer.playerConnection.sendPacket(metadataPacket);
+ }
+ }
+ // Purpur end
}
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index 5e577cd97df14463f590919b2931a5065ac37033..dfcceebc9fbfa62fc14f3c53217af8e39025307d 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -135,6 +135,49 @@ public class PurpurWorldConfig {
}
}
+ public List<Item> itemImmuneToCactus = new ArrayList<>();
+ public List<Item> itemImmuneToExplosion = new ArrayList<>();
+ public List<Item> itemImmuneToFire = new ArrayList<>();
+ public List<Item> itemImmuneToLightning = new ArrayList<>();
+ private void itemSettings() {
+ itemImmuneToCactus.clear();
+ getList("gameplay-mechanics.item.immune.cactus", new ArrayList<>()).forEach(key -> {
+ if (key.toString().equals("*")) {
+ IRegistry.ITEM.g().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToCactus.add(item));
+ return;
+ }
+ Item item = IRegistry.ITEM.get(new MinecraftKey(key.toString()));
+ if (item != Items.AIR) itemImmuneToCactus.add(item);
+ });
+ itemImmuneToExplosion.clear();
+ getList("gameplay-mechanics.item.immune.explosion", new ArrayList<>()).forEach(key -> {
+ if (key.toString().equals("*")) {
+ IRegistry.ITEM.g().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToExplosion.add(item));
+ return;
+ }
+ Item item = IRegistry.ITEM.get(new MinecraftKey(key.toString()));
+ if (item != Items.AIR) itemImmuneToExplosion.add(item);
+ });
+ itemImmuneToFire.clear();
+ getList("gameplay-mechanics.item.immune.fire", new ArrayList<>()).forEach(key -> {
+ if (key.toString().equals("*")) {
+ IRegistry.ITEM.g().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToFire.add(item));
+ return;
+ }
+ Item item = IRegistry.ITEM.get(new MinecraftKey(key.toString()));
+ if (item != Items.AIR) itemImmuneToFire.add(item);
+ });
+ itemImmuneToLightning.clear();
+ getList("gameplay-mechanics.item.immune.lightning", new ArrayList<>()).forEach(key -> {
+ if (key.toString().equals("*")) {
+ IRegistry.ITEM.g().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToLightning.add(item));
+ return;
+ }
+ Item item = IRegistry.ITEM.get(new MinecraftKey(key.toString()));
+ if (item != Items.AIR) itemImmuneToLightning.add(item);
+ });
+ }
+
public boolean idleTimeoutKick = true;
public boolean idleTimeoutTickNearbyEntities = true;
public boolean idleTimeoutCountAsSleeping = false;
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
index 7a78ef2f6f673568c0528fa46168c69d21f51a66..f91a04abe39f9a75530a213cd84e5024059752d1 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
@@ -114,4 +114,46 @@ public class CraftItem extends CraftEntity implements Item {
public EntityType getType() {
return EntityType.DROPPED_ITEM;
}
+
+ // Purpur start
+ @Override
+ public void setImmuneToCactus(boolean immuneToCactus) {
+ item.immuneToCactus = immuneToCactus;
+ }
+
+ @Override
+ public boolean isImmuneToCactus() {
+ return item.immuneToCactus;
+ }
+
+ @Override
+ public void setImmuneToExplosion(boolean immuneToExplosion) {
+ item.immuneToExplosion = immuneToExplosion;
+ }
+
+ @Override
+ public boolean isImmuneToExplosion() {
+ return item.immuneToExplosion;
+ }
+
+ @Override
+ public void setImmuneToFire(boolean immuneToFire) {
+ item.immuneToFire = immuneToFire;
+ }
+
+ @Override
+ public boolean isImmuneToFire() {
+ return item.immuneToFire;
+ }
+
+ @Override
+ public void setImmuneToLightning(boolean immuneToLightning) {
+ item.immuneToLightning = immuneToLightning;
+ }
+
+ @Override
+ public boolean isImmuneToLightning() {
+ return item.immuneToLightning;
+ }
+ // Purpur end
}

View File

@@ -1,128 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Fri, 13 Mar 2020 22:29:10 -0500
Subject: [PATCH] Add /ping command
diff --git a/src/main/java/net/minecraft/commands/CommandDispatcher.java b/src/main/java/net/minecraft/commands/CommandDispatcher.java
index b1bfc42b4153b225243ba65e7f937c0314cb39a5..185dee82b86aa3abb04809ddcf31c81e29664c62 100644
--- a/src/main/java/net/minecraft/commands/CommandDispatcher.java
+++ b/src/main/java/net/minecraft/commands/CommandDispatcher.java
@@ -191,6 +191,7 @@ public class CommandDispatcher {
CommandIdleTimeout.a(this.b);
CommandStop.a(this.b);
CommandWhitelist.a(this.b);
+ net.pl3x.purpur.command.PingCommand.register(getDispatcher()); // Purpur
}
if (commanddispatcher_servertype.d) {
@@ -428,10 +429,12 @@ public class CommandDispatcher {
}
+ public static LiteralArgumentBuilder<CommandListenerWrapper> literal(String s) { return a(s); } // Purpur - OBFHELPER
public static LiteralArgumentBuilder<CommandListenerWrapper> a(String s) {
return LiteralArgumentBuilder.literal(s);
}
+ public static <T> RequiredArgumentBuilder<CommandListenerWrapper, T> argument(String s, ArgumentType<T> argumenttype) { return a(s, argumenttype); } // Purpur - OBFHELPER
public static <T> RequiredArgumentBuilder<CommandListenerWrapper, T> a(String s, ArgumentType<T> argumenttype) {
return RequiredArgumentBuilder.argument(s, argumenttype);
}
@@ -447,6 +450,7 @@ public class CommandDispatcher {
};
}
+ public com.mojang.brigadier.CommandDispatcher<CommandListenerWrapper> getDispatcher() { return a(); } // Purpur - OBFHELPER
public com.mojang.brigadier.CommandDispatcher<CommandListenerWrapper> a() { return this.dispatcher(); } public com.mojang.brigadier.CommandDispatcher<CommandListenerWrapper> dispatcher() { // Paper - OBFHELPER
return this.b;
}
diff --git a/src/main/java/net/minecraft/commands/CommandListenerWrapper.java b/src/main/java/net/minecraft/commands/CommandListenerWrapper.java
index 8402af32cc476d7f468842eb4f34c7521d72bcc8..4480fe75cfad35a5104b5116c5ec2c80d18f15f5 100644
--- a/src/main/java/net/minecraft/commands/CommandListenerWrapper.java
+++ b/src/main/java/net/minecraft/commands/CommandListenerWrapper.java
@@ -211,6 +211,7 @@ public class CommandListenerWrapper implements ICompletionProvider, com.destroys
}
}
+ public EntityPlayer getPlayerOrException() throws CommandSyntaxException { return h(); } // Purpur - OBFHELPER
public EntityPlayer h() throws CommandSyntaxException {
if (!(this.k instanceof EntityPlayer)) {
throw CommandListenerWrapper.a.create();
diff --git a/src/main/java/net/minecraft/commands/arguments/ArgumentEntity.java b/src/main/java/net/minecraft/commands/arguments/ArgumentEntity.java
index bbad2b1399d9d2e16bfa77563bd564f7c6f640d7..a85c4525335fa46bc23a6dd57cfaea1f697b3daa 100644
--- a/src/main/java/net/minecraft/commands/arguments/ArgumentEntity.java
+++ b/src/main/java/net/minecraft/commands/arguments/ArgumentEntity.java
@@ -78,10 +78,12 @@ public class ArgumentEntity implements ArgumentType<EntitySelector> {
return ((EntitySelector) commandcontext.getArgument(s, EntitySelector.class)).c((CommandListenerWrapper) commandcontext.getSource());
}
+ public static ArgumentEntity players() { return d(); } // Purpur - OBFHELPER
public static ArgumentEntity d() {
return new ArgumentEntity(false, true);
}
+ public static Collection<EntityPlayer> getPlayers(CommandContext<CommandListenerWrapper> commandcontext, String s) throws CommandSyntaxException { return f(commandcontext, s); } // Purpur - OBFHELPER
public static Collection<EntityPlayer> f(CommandContext<CommandListenerWrapper> commandcontext, String s) throws CommandSyntaxException {
List<EntityPlayer> list = ((EntitySelector) commandcontext.getArgument(s, EntitySelector.class)).d((CommandListenerWrapper) commandcontext.getSource());
diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java
index 8d27fff773b74014351bfbfeed0197272234be4a..b1b12a46f0b662aff24357b407b65124428ecfaa 100644
--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java
@@ -133,10 +133,12 @@ public class PurpurConfig {
public static String afkBroadcastAway = "§e§o%s is now AFK";
public static String afkBroadcastBack = "§e§o%s is no longer AFK";
public static String afkTabListPrefix = "[AFK] ";
+ public static String pingCommandOutput = "§a%s's ping is %sms";
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);
}
public static String serverModName = "Purpur";
diff --git a/src/main/java/net/pl3x/purpur/command/PingCommand.java b/src/main/java/net/pl3x/purpur/command/PingCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..1d636d7c541d127a473d5be2509e5db29936e8ad
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/command/PingCommand.java
@@ -0,0 +1,37 @@
+package net.pl3x.purpur.command;
+
+import net.minecraft.commands.arguments.ArgumentEntity;
+import net.minecraft.commands.CommandDispatcher;
+import net.minecraft.commands.CommandListenerWrapper;
+import net.minecraft.server.level.EntityPlayer;
+import net.pl3x.purpur.PurpurConfig;
+import org.bukkit.craftbukkit.util.CraftChatMessage;
+
+import java.util.Collection;
+import java.util.Collections;
+
+public class PingCommand {
+ public static void register(com.mojang.brigadier.CommandDispatcher<CommandListenerWrapper> dispatcher) {
+ dispatcher.register(CommandDispatcher.literal("ping")
+ .requires((listener) -> {
+ return listener.hasPermission(2);
+ })
+ .executes((context) -> {
+ return execute(context.getSource(), Collections.singleton(context.getSource().getPlayerOrException()));
+ })
+ .then(CommandDispatcher.argument("targets", ArgumentEntity.players())
+ .executes((context) -> {
+ return execute(context.getSource(), ArgumentEntity.getPlayers(context, "targets"));
+ })
+ )
+ ).setPermission("bukkit.command.ping");
+ }
+
+ private static int execute(CommandListenerWrapper sender, Collection<EntityPlayer> targets) {
+ for (EntityPlayer player : targets) {
+ String output = String.format(PurpurConfig.pingCommandOutput, player.getProfile().getName(), player.ping);
+ sender.sendMessage(CraftChatMessage.fromStringOrNull(output), false);
+ }
+ return targets.size();
+ }
+}

View File

@@ -1,359 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 9 May 2019 18:26:06 -0500
Subject: [PATCH] Phantoms attracted to crystals and crystals shoot phantoms
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index e433ca9305ced694a3dbb9fc8a1c5eddb7e6b431..ff07ab36b0e4565ddcaf672e503c2a5740670c2a 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2034,8 +2034,8 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
return this.a(new ItemStack(imaterial), (float) i);
}
- @Nullable
- public EntityItem a(ItemStack itemstack) {
+ @Nullable public EntityItem dropItem(ItemStack itemstack) { return this.a(itemstack); } // Purpur - OBFHELPER
+ @Nullable public EntityItem a(ItemStack itemstack) {
return this.a(itemstack, 0.0F);
}
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EntityEnderCrystal.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EntityEnderCrystal.java
index 5d48c2640f776c9e29598e19afe779ed6997acfc..4cd5d2de76e785e839c3b3a78d55f2304d9aa4c3 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EntityEnderCrystal.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EntityEnderCrystal.java
@@ -14,6 +14,7 @@ import net.minecraft.server.level.WorldServer;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityTypes;
+import net.minecraft.world.entity.monster.EntityPhantom;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.IBlockAccess;
import net.minecraft.world.level.World;
@@ -31,6 +32,12 @@ public class EntityEnderCrystal extends Entity {
private static final DataWatcherObject<Boolean> d = DataWatcher.a(EntityEnderCrystal.class, DataWatcherRegistry.i);
public int b;
public boolean generatedByDragonFight = false; // Paper - Fix invulnerable end crystals
+ // Purpur start
+ private EntityPhantom targetPhantom;
+ private int phantomBeamTicks = 0;
+ private int phantomDamageCooldown = 0;
+ private int idleCooldown = 0;
+ // Purpur end
public EntityEnderCrystal(EntityTypes<? extends EntityEnderCrystal> entitytypes, World world) {
super(entitytypes, world);
@@ -80,7 +87,50 @@ public class EntityEnderCrystal extends Entity {
// Paper end
}
+ // Purpur start
+ if (world.purpurConfig.phantomAttackedByCrystalRadius <= 0 || --idleCooldown > 0) {
+ return; // on cooldown
+ }
+
+ if (targetPhantom == null) {
+ for (EntityPhantom phantom : world.getEntitiesInAABB(EntityPhantom.class, getBoundingBox().grow(world.purpurConfig.phantomAttackedByCrystalRadius))) {
+ if (phantom.hasLineOfSight(this)) {
+ attackPhantom(phantom);
+ break;
+ }
+ }
+ } else {
+ setBeamTarget(new BlockPosition(targetPhantom).add(0, -2, 0));
+ if (--phantomBeamTicks > 0 && targetPhantom.isAlive()) {
+ phantomDamageCooldown--;
+ if (targetPhantom.hasLineOfSight(this)) {
+ if (phantomDamageCooldown <= 0) {
+ phantomDamageCooldown = 20;
+ targetPhantom.damageEntity(DamageSource.indirectMagic(this, this), world.purpurConfig.phantomAttackedByCrystalDamage);
+ }
+ } else {
+ forgetPhantom(); // no longer in sight
+ }
+ } else {
+ forgetPhantom(); // attacked long enough
+ }
+ }
+ }
+
+ private void attackPhantom(EntityPhantom phantom) {
+ phantomDamageCooldown = 0;
+ phantomBeamTicks = 60;
+ targetPhantom = phantom;
+ }
+
+ private void forgetPhantom() {
+ targetPhantom = null;
+ setBeamTarget(null);
+ phantomBeamTicks = 0;
+ phantomDamageCooldown = 0;
+ idleCooldown = 60;
}
+ // Purpur end
@Override
protected void saveData(NBTTagCompound nbttagcompound) {
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 16c0c960aa1e4d35093b810c7648b5638175e106..e20b26ae0435c593218541eba6c68ef297fea7c8 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EntityPhantom.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EntityPhantom.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.level.WorldServer;
import net.minecraft.sounds.SoundCategory;
import net.minecraft.sounds.SoundEffect;
import net.minecraft.sounds.SoundEffects;
@@ -36,18 +37,23 @@ import net.minecraft.world.entity.ai.control.EntityAIBodyControl;
import net.minecraft.world.entity.ai.goal.PathfinderGoal;
import net.minecraft.world.entity.ai.targeting.PathfinderTargetCondition;
import net.minecraft.world.entity.animal.EntityCat;
+import net.minecraft.world.entity.boss.enderdragon.EntityEnderCrystal;
import net.minecraft.world.entity.player.EntityHuman;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.Items;
import net.minecraft.world.level.World;
import net.minecraft.world.level.WorldAccess;
import net.minecraft.world.level.levelgen.HeightMap;
+import net.minecraft.world.level.storage.loot.LootTableInfo;
import net.minecraft.world.phys.Vec3D;
public class EntityPhantom extends EntityFlying implements IMonster {
private static final DataWatcherObject<Integer> b = DataWatcher.a(EntityPhantom.class, DataWatcherRegistry.b);
- private Vec3D c;
- private BlockPosition d;
- private EntityPhantom.AttackPhase bo;
+ private Vec3D c; public void setHomeOffset(Vec3D offset) { this.c = offset; } public Vec3D getHomeOffset() { return this.c; } // Purpur - OBFHELPER
+ private BlockPosition d; public void setHome(BlockPosition home) { this.d = home; } public BlockPosition getHome() { return this.d; } // Purpur - OBFHELPER
+ private EntityPhantom.AttackPhase bo; public AttackPhase getAttackPhase() { return this.bo; } // Purpur - OBFHELPER
+ private Vec3D crystalPosition; // Purpur
public EntityPhantom(EntityTypes<? extends EntityPhantom> entitytypes, World world) {
super(entitytypes, world);
@@ -66,11 +72,37 @@ public class EntityPhantom extends EntityFlying implements IMonster {
@Override
protected void initPathfinder() {
- this.goalSelector.a(1, new EntityPhantom.c());
- this.goalSelector.a(2, new EntityPhantom.i());
- this.goalSelector.a(3, new EntityPhantom.e());
- this.targetSelector.a(1, new EntityPhantom.b());
+ // Purpur start
+ if (world.purpurConfig.phantomOrbitCrystalRadius > 0) {
+ this.goalSelector.a(1, new FindCrystalGoal(this));
+ this.goalSelector.a(2, new OrbitCrystalGoal(this));
+ }
+ 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(1, new EntityPhantom.b()); // AttackPlayer Goal
+ // Purpur end
+ }
+
+ // Purpur start
+ @Override
+ protected LootTableInfo.Builder a(boolean wasRecentlyHit, DamageSource damagesource) { // dropLoot
+ boolean dropped = false;
+ if (killer == null && damagesource.getEntity() instanceof EntityEnderCrystal) {
+ if (random.nextInt(5) < 1) { // 1 out of 5 chance (20%)
+ dropped = dropItem(new ItemStack(Items.PHANTOM_MEMBRANE)) != null;
+ }
+ }
+ if (!dropped) {
+ return super.a(wasRecentlyHit, damagesource); // dropLoot
+ }
+ return new LootTableInfo.Builder((WorldServer) world);
+ }
+
+ public boolean isCirclingCrystal() {
+ return crystalPosition != null;
}
+ // Purpur end
@Override
protected void initDatawatcher() {
@@ -241,6 +273,136 @@ public class EntityPhantom extends EntityFlying implements IMonster {
public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; }
// Paper end
+ // Purpur start
+ class FindCrystalGoal extends PathfinderGoal {
+ private final EntityPhantom phantom;
+ private EntityEnderCrystal crystal;
+ private java.util.Comparator<EntityEnderCrystal> comparator;
+
+ FindCrystalGoal(EntityPhantom phantom) {
+ this.phantom = phantom;
+ comparator = java.util.Comparator.comparingDouble(phantom::h);
+ this.a(EnumSet.of(PathfinderGoal.Type.LOOK));
+ }
+
+ @Override
+ public boolean a() { // shouldExecute
+ double range = maxTargetRange();
+ List<EntityEnderCrystal> crystals = world.getEntitiesInAABB(EntityEnderCrystal.class, phantom.getBoundingBox().grow(range));
+ if (crystals.isEmpty()) {
+ return false;
+ }
+ crystals.sort(comparator);
+ crystal = crystals.get(0);
+ if (phantom.getDistanceSquared(crystal) > range * range) {
+ crystal = null;
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean b() { // shouldContinueExecuting
+ if (crystal == null || !crystal.isAlive()) {
+ return false;
+ }
+ double range = maxTargetRange();
+ return phantom.getDistanceSquared(crystal) <= (range * range) * 2;
+ }
+
+ @Override
+ public void c() { // startExecuting
+ phantom.crystalPosition = new Vec3D(crystal.locX(), crystal.locY() + (phantom.getRandom().nextInt(10) + 10), crystal.locZ());
+ }
+
+ @Override
+ public void d() { // resetTask
+ crystal = null;
+ phantom.crystalPosition = null;
+ super.d();
+ }
+
+ private double maxTargetRange() {
+ return phantom.world.purpurConfig.phantomOrbitCrystalRadius;
+ }
+
+ class DistanceComparator implements java.util.Comparator<Entity> {
+ private final Entity entity;
+
+ public DistanceComparator(Entity entity) {
+ this.entity = entity;
+ }
+
+ public int compare(Entity entity1, Entity entity2) {
+ return Double.compare(entity.getDistanceSquared(entity1), entity.getDistanceSquared(entity2));
+ }
+ }
+ }
+
+ class OrbitCrystalGoal extends PathfinderGoal {
+ private final EntityPhantom phantom;
+ private float offset;
+ private float radius;
+ private float verticalChange;
+ private float direction;
+
+ OrbitCrystalGoal(EntityPhantom phantom) {
+ this.phantom = phantom;
+ this.a(EnumSet.of(PathfinderGoal.Type.MOVE));
+ }
+
+ @Override
+ public boolean a() { // shouldExecute
+ return phantom.isCirclingCrystal();
+ }
+
+ @Override
+ public void c() { // startExecuting
+ this.radius = 5.0F + phantom.random.nextFloat() * 10.0F;
+ this.verticalChange = -4.0F + phantom.random.nextFloat() * 9.0F;
+ this.direction = phantom.random.nextBoolean() ? 1.0F : -1.0F;
+ updateOffset();
+ }
+
+ @Override
+ public void e() { // tick
+ if (phantom.random.nextInt(350) == 0) {
+ this.verticalChange = -4.0F + phantom.random.nextFloat() * 9.0F;
+ }
+ if (phantom.random.nextInt(250) == 0) {
+ ++this.radius;
+ if (this.radius > 15.0F) {
+ this.radius = 5.0F;
+ this.direction = -this.direction;
+ }
+ }
+ if (phantom.random.nextInt(450) == 0) {
+ this.offset = phantom.random.nextFloat() * 2.0F * 3.1415927F;
+ updateOffset();
+ }
+ if (phantom.getHomeOffset().c(phantom.locX(), phantom.locY(), phantom.locZ()) < 4.0D) {
+ updateOffset();
+ }
+ if (phantom.getHomeOffset().y < phantom.locY() && !phantom.world.isEmpty((new BlockPosition(phantom)).down(1))) {
+ this.verticalChange = Math.max(1.0F, this.verticalChange);
+ updateOffset();
+ }
+ if (phantom.getHomeOffset().y > phantom.locY() && !phantom.world.isEmpty((new BlockPosition(phantom)).up(1))) {
+ this.verticalChange = Math.min(-1.0F, this.verticalChange);
+ updateOffset();
+ }
+ }
+
+ private void updateOffset() {
+ this.offset += this.direction * 15.0F * 0.017453292F;
+ phantom.setHomeOffset(phantom.crystalPosition.add(
+ this.radius * MathHelper.cos(this.offset),
+ -4.0F + this.verticalChange,
+ this.radius * MathHelper.sin(this.offset)));
+ }
+ }
+ // Purpur end
+
class b extends PathfinderGoal {
private final PathfinderTargetCondition b;
@@ -253,6 +415,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
@Override
public boolean a() {
+ if (isCirclingCrystal()) return false; // Purpur - pathfinder does not have a flag
if (this.c > 0) {
--this.c;
return false;
@@ -281,6 +444,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
@Override
public boolean b() {
+ if (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;
@@ -295,6 +459,7 @@ public class EntityPhantom extends EntityFlying implements IMonster {
@Override
public boolean a() {
+ if (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;
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index a12c2ae8291114f17bbb05761272bf724f848b1c..3aec221db2cd425bc5188979bb0fc0625ca40f4a 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -395,6 +395,15 @@ public class PurpurWorldConfig {
ironGolemCanSwim = getBoolean("mobs.iron_golem.can-swim", ironGolemCanSwim);
}
+ public double phantomAttackedByCrystalRadius = 0.0D;
+ public float phantomAttackedByCrystalDamage = 1.0F;
+ public double phantomOrbitCrystalRadius = 0.0D;
+ private void phantomSettings() {
+ 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);
+ }
+
public boolean pigGiveSaddleBack = false;
private void pigSettings() {
pigGiveSaddleBack = getBoolean("mobs.pig.give-saddle-back", pigGiveSaddleBack);

View File

@@ -1,302 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Fri, 3 Jul 2020 00:03:52 -0500
Subject: [PATCH] Add phantom spawning options
diff --git a/src/main/java/net/minecraft/world/DifficultyDamageScaler.java b/src/main/java/net/minecraft/world/DifficultyDamageScaler.java
index c2fe4329576e6dcd5df435bc580d79a2b6db1fcd..44f19d8c8f5d344b2659cf01eb4be40f5510a2c2 100644
--- a/src/main/java/net/minecraft/world/DifficultyDamageScaler.java
+++ b/src/main/java/net/minecraft/world/DifficultyDamageScaler.java
@@ -14,6 +14,7 @@ public class DifficultyDamageScaler {
this.b = this.a(enumdifficulty, i, j, f);
}
+ public EnumDifficulty getGlobalDifficulty() { return a(); } // Purpur - OBFHELPER
public EnumDifficulty a() {
return this.a;
}
@@ -22,6 +23,7 @@ public class DifficultyDamageScaler {
return this.b;
}
+ public boolean isHarderThan(float f) { return a(f); } // Purpur - OBFHELPER
public boolean a(float f) {
return this.b > f;
}
diff --git a/src/main/java/net/minecraft/world/EnumDifficulty.java b/src/main/java/net/minecraft/world/EnumDifficulty.java
index 53fac6aa71938805264b7cc4769e63a9d4a66114..a1a80aab7ef6fdb2a35082fa452d0b46c1fcdcbe 100644
--- a/src/main/java/net/minecraft/world/EnumDifficulty.java
+++ b/src/main/java/net/minecraft/world/EnumDifficulty.java
@@ -21,6 +21,7 @@ public enum EnumDifficulty {
this.g = s;
}
+ public int getId() { return a(); } // Purpur - OBFHELPER
public int a() {
return this.f;
}
diff --git a/src/main/java/net/minecraft/world/level/IBlockLightAccess.java b/src/main/java/net/minecraft/world/level/IBlockLightAccess.java
index 8b2e57c833c03940f2e0727e00decce59f263269..642bf019d32a2fdc18718337ecfe45d24022f8bd 100644
--- a/src/main/java/net/minecraft/world/level/IBlockLightAccess.java
+++ b/src/main/java/net/minecraft/world/level/IBlockLightAccess.java
@@ -15,6 +15,7 @@ public interface IBlockLightAccess extends IBlockAccess {
return this.e().b(blockposition, i);
}
+ default boolean isSkyVisible(BlockPosition blockposition) { return e(blockposition); } // Purpur - OBFHELPER
default boolean e(BlockPosition blockposition) {
return this.getBrightness(EnumSkyBlock.SKY, blockposition) >= this.K();
}
diff --git a/src/main/java/net/minecraft/world/level/SpawnerCreature.java b/src/main/java/net/minecraft/world/level/SpawnerCreature.java
index 24771c3522ea74ac12058591137eafc21adf3762..943de7e98bcd3b9418c1bdc5fd277059cb1206d8 100644
--- a/src/main/java/net/minecraft/world/level/SpawnerCreature.java
+++ b/src/main/java/net/minecraft/world/level/SpawnerCreature.java
@@ -419,6 +419,7 @@ public final class SpawnerCreature {
return new BlockPosition(i, l, j);
}
+ public static boolean canSpawn(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, Fluid fluid, EntityTypes entitytypes) { return a(iblockaccess, blockposition, iblockdata, fluid, entitytypes); } // Purpur - OBFHELPER
public static boolean a(IBlockAccess iblockaccess, BlockPosition blockposition, IBlockData iblockdata, Fluid fluid, EntityTypes<?> entitytypes) {
return iblockdata.r(iblockaccess, blockposition) ? false : (iblockdata.isPowerSource() ? false : (!fluid.isEmpty() ? false : (iblockdata.a((Tag) TagsBlock.PREVENT_MOB_SPAWNING_INSIDE) ? false : !entitytypes.a(iblockdata))));
}
diff --git a/src/main/java/net/minecraft/world/level/World.java b/src/main/java/net/minecraft/world/level/World.java
index bb01bbee04caafbe41435835e79bc699c3d96d46..be4c1786d46046dd7ce583cad8207db57a558947 100644
--- a/src/main/java/net/minecraft/world/level/World.java
+++ b/src/main/java/net/minecraft/world/level/World.java
@@ -1463,6 +1463,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
return new DifficultyDamageScaler(this.getDifficulty(), this.getDayTime(), i, f);
}
+ public int getSkyDarkness() { return c(); } // Purpur - OBFHELPER
@Override
public int c() {
return this.d;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/MobSpawnerPhantom.java b/src/main/java/net/minecraft/world/level/levelgen/MobSpawnerPhantom.java
index e4f5e570636862481aac92ec9b74d6cf5723eb6e..e954adeff4fbfc1aa85ac3785c0c4c86bde24cdb 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/MobSpawnerPhantom.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/MobSpawnerPhantom.java
@@ -1,9 +1,6 @@
package net.minecraft.world.level.levelgen;
-import java.util.Iterator;
-import java.util.Random;
import net.minecraft.core.BlockPosition;
-import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.MCUtil;
import net.minecraft.server.level.EntityPlayer;
import net.minecraft.server.level.WorldServer;
@@ -15,92 +12,103 @@ import net.minecraft.world.entity.EntityTypes;
import net.minecraft.world.entity.EnumMobSpawn;
import net.minecraft.world.entity.GroupDataEntity;
import net.minecraft.world.entity.monster.EntityPhantom;
-import net.minecraft.world.entity.player.EntityHuman;
import net.minecraft.world.level.GameRules;
-import net.minecraft.world.level.IBlockAccess;
import net.minecraft.world.level.MobSpawner;
import net.minecraft.world.level.SpawnerCreature;
-import net.minecraft.world.level.World;
-import net.minecraft.world.level.block.state.IBlockData;
-import net.minecraft.world.level.material.Fluid;
+import com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent;
+import org.bukkit.event.entity.CreatureSpawnEvent;
public class MobSpawnerPhantom implements MobSpawner {
-
- private int a;
+ private int spawnDelay;
public MobSpawnerPhantom() {}
@Override
- public int a(WorldServer worldserver, boolean flag, boolean flag1) {
- if (!flag) {
+ public int a(WorldServer world, boolean allowMonsters, boolean allowAnimals) {
+ // Purpur start - rewrite entire thing
+ if (!allowMonsters) {
+ return 0;
+ }
+
+ if (!world.getGameRules().getBoolean(GameRules.DO_INSOMNIA)) {
return 0;
- } else if (!worldserver.getGameRules().getBoolean(GameRules.DO_INSOMNIA)) {
+ }
+
+ --this.spawnDelay;
+ if (this.spawnDelay > 0) {
return 0;
- } else {
- Random random = worldserver.random;
-
- --this.a;
- if (this.a > 0) {
- return 0;
- } else {
- this.a += (60 + random.nextInt(60)) * 20;
- if (worldserver.c() < 5 && worldserver.getDimensionManager().hasSkyLight()) {
- return 0;
- } else {
- int i = 0;
- Iterator iterator = worldserver.getPlayers().iterator();
-
- while (iterator.hasNext()) {
- EntityHuman entityhuman = (EntityHuman) iterator.next();
-
- if (!entityhuman.isSpectator() && (!worldserver.paperConfig.phantomIgnoreCreative || !entityhuman.isCreative())) { // Paper
- BlockPosition blockposition = entityhuman.getChunkCoordinates();
-
- if (!worldserver.getDimensionManager().hasSkyLight() || blockposition.getY() >= worldserver.getSeaLevel() && worldserver.e(blockposition)) {
- DifficultyDamageScaler difficultydamagescaler = worldserver.getDamageScaler(blockposition);
-
- if (difficultydamagescaler.a(random.nextFloat() * 3.0F)) {
- ServerStatisticManager serverstatisticmanager = ((EntityPlayer) entityhuman).getStatisticManager();
- int j = MathHelper.clamp(serverstatisticmanager.getStatisticValue(StatisticList.CUSTOM.b(StatisticList.TIME_SINCE_REST)), 1, Integer.MAX_VALUE);
- boolean flag2 = true;
-
- if (random.nextInt(j) >= 72000) {
- BlockPosition blockposition1 = blockposition.up(20 + random.nextInt(15)).east(-10 + random.nextInt(21)).south(-10 + random.nextInt(21));
- IBlockData iblockdata = worldserver.getType(blockposition1);
- Fluid fluid = worldserver.getFluid(blockposition1);
-
- if (SpawnerCreature.a((IBlockAccess) worldserver, blockposition1, iblockdata, fluid, EntityTypes.PHANTOM)) {
- GroupDataEntity groupdataentity = null;
- int k = 1 + random.nextInt(difficultydamagescaler.a().a() + 1);
-
- for (int l = 0; l < k; ++l) {
- // Paper start
- com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent event = new com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent(MCUtil.toLocation(worldserver, blockposition1), ((EntityPlayer) entityhuman).getBukkitEntity(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL);
- if (!event.callEvent()) {
- if (event.shouldAbortSpawn()) {
- break;
- }
- continue;
- }
- // Paper end
- EntityPhantom entityphantom = (EntityPhantom) EntityTypes.PHANTOM.a((World) worldserver);
- entityphantom.setSpawningEntity(entityhuman.getUniqueID()); // Paper
- entityphantom.setPositionRotation(blockposition1, 0.0F, 0.0F);
- groupdataentity = entityphantom.prepare(worldserver, difficultydamagescaler, EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null);
- worldserver.addAllEntities(entityphantom, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit
- }
-
- i += k;
- }
- }
- }
- }
- }
+ }
+ this.spawnDelay += world.purpurConfig.phantomSpawnDelayMin + world.random.nextInt(world.purpurConfig.phantomSpawnDelayMax - world.purpurConfig.phantomSpawnDelayMin);
+
+ if (!world.getDimensionManager().hasSkyLight() || world.getSkyDarkness() < world.purpurConfig.phantomSpawnMinSkyDarkness) {
+ return 0;
+ }
+
+ int numberSpawnsAttempted = 0;
+ for (EntityPlayer player : world.getPlayers()) {
+ if (player.isSpectator() || (player.isCreative() && world.paperConfig.phantomIgnoreCreative)) { // Paper
+ continue;
+ }
+
+ BlockPosition playerPos = player.getChunkCoordinates();
+ if (playerPos.getY() < world.getSeaLevel() && world.purpurConfig.phantomSpawnOnlyAboveSeaLevel) {
+ continue;
+ }
+
+ if (!world.isSkyVisible(playerPos) && world.purpurConfig.phantomSpawnOnlyWithVisibleSky) {
+ continue;
+ }
+
+ DifficultyDamageScaler dmgScaler = world.getDamageScaler(playerPos);
+ if (!dmgScaler.isHarderThan(world.random.nextFloat() * (float) world.purpurConfig.phantomSpawnLocalDifficultyChance)) {
+ continue;
+ }
+
+ ServerStatisticManager stats = player.getStatisticManager();
+ int timeSinceRest = MathHelper.clamp(stats.getStatisticValue(StatisticList.CUSTOM.get(StatisticList.TIME_SINCE_REST)), 1, Integer.MAX_VALUE);
+ if (world.random.nextInt(timeSinceRest) < world.purpurConfig.phantomSpawnMinTimeSinceSlept) {
+ continue;
+ }
+
+ BlockPosition spawnPos = playerPos
+ .up(world.purpurConfig.phantomSpawnMinOverhead + world.random.nextInt(world.purpurConfig.phantomSpawnMaxOverhead - world.purpurConfig.phantomSpawnMinOverhead))
+ .east(-world.purpurConfig.phantomSpawnOverheadRadius + world.random.nextInt(world.purpurConfig.phantomSpawnOverheadRadius + 1))
+ .south(-world.purpurConfig.phantomSpawnOverheadRadius + world.random.nextInt(world.purpurConfig.phantomSpawnOverheadRadius + 1));
+
+ if (!SpawnerCreature.canSpawn(world, spawnPos, world.getType(spawnPos), world.getFluid(spawnPos), EntityTypes.PHANTOM)) {
+ continue;
+ }
+
+ int difficulty = dmgScaler.getGlobalDifficulty().getId();
+ int spawnAttempts = world.purpurConfig.phantomSpawnMinPerAttempt + world.random.nextInt((world.purpurConfig.phantomSpawnMaxPerAttempt < 0 ? difficulty : world.purpurConfig.phantomSpawnMaxPerAttempt) + world.purpurConfig.phantomSpawnMinPerAttempt);
+
+ GroupDataEntity groupData = null;
+ for (int count = 0; count < spawnAttempts; ++count) {
+ // Paper start
+ PhantomPreSpawnEvent event = new PhantomPreSpawnEvent(MCUtil.toLocation(world, spawnPos), player.getBukkitEntity(), CreatureSpawnEvent.SpawnReason.NATURAL);
+ if (!event.callEvent()) {
+ if (event.shouldAbortSpawn()) {
+ break;
}
+ continue;
+ }
+ // Paper end
- return i;
+ EntityPhantom phantom = EntityTypes.PHANTOM.create(world);
+ if (phantom == null) {
+ continue;
}
+
+ phantom.setSpawningEntity(player.getUniqueID()); // Paper
+ phantom.setPositionRotation(spawnPos, 0.0F, 0.0F);
+ groupData = phantom.prepare(world, dmgScaler, EnumMobSpawn.NATURAL, groupData, null);
+ world.addEntity(phantom, CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit
}
+
+ numberSpawnsAttempted += spawnAttempts;
}
+
+ return numberSpawnsAttempted;
+ // Purpur end - rewrite entire thing
}
}
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index 3aec221db2cd425bc5188979bb0fc0625ca40f4a..d957ee4c10fde8596442f2f05f0347994df7bae5 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -398,10 +398,34 @@ public class PurpurWorldConfig {
public double phantomAttackedByCrystalRadius = 0.0D;
public float phantomAttackedByCrystalDamage = 1.0F;
public double phantomOrbitCrystalRadius = 0.0D;
+ public int phantomSpawnDelayMin = 1200;
+ public int phantomSpawnDelayMax = 2400;
+ public int phantomSpawnMinSkyDarkness = 5;
+ public boolean phantomSpawnOnlyAboveSeaLevel = true;
+ public boolean phantomSpawnOnlyWithVisibleSky = true;
+ public double phantomSpawnLocalDifficultyChance = 3.0D;
+ public int phantomSpawnMinTimeSinceSlept = 72000;
+ public int phantomSpawnMinOverhead = 20;
+ public int phantomSpawnMaxOverhead = 35;
+ public int phantomSpawnOverheadRadius = 10;
+ public int phantomSpawnMinPerAttempt = 1;
+ public int phantomSpawnMaxPerAttempt = -1;
private void phantomSettings() {
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);
+ phantomSpawnDelayMin = getInt("mobs.phantom.spawn.delay.min", phantomSpawnDelayMin);
+ phantomSpawnDelayMax = getInt("mobs.phantom.spawn.delay.max", phantomSpawnDelayMax);
+ phantomSpawnMinSkyDarkness = getInt("mobs.phantom.spawn.min-sky-darkness", phantomSpawnMinSkyDarkness);
+ phantomSpawnOnlyAboveSeaLevel = getBoolean("mobs.phantom.spawn.only-above-sea-level", phantomSpawnOnlyAboveSeaLevel);
+ phantomSpawnOnlyWithVisibleSky = getBoolean("mobs.phantom.spawn.only-with-visible-sky", phantomSpawnOnlyWithVisibleSky);
+ phantomSpawnLocalDifficultyChance = getDouble("mobs.phantom.spawn.local-difficulty-chance", phantomSpawnLocalDifficultyChance);
+ phantomSpawnMinTimeSinceSlept = getInt("mobs.phantom.spawn.min-time-since-slept", phantomSpawnMinTimeSinceSlept);
+ phantomSpawnMinOverhead = getInt("mobs.phantom.spawn.overhead.min", phantomSpawnMinOverhead);
+ phantomSpawnMaxOverhead = getInt("mobs.phantom.spawn.overhead.max", phantomSpawnMaxOverhead);
+ phantomSpawnOverheadRadius = getInt("mobs.phantom.spawn.overhead.radius", phantomSpawnOverheadRadius);
+ phantomSpawnMinPerAttempt = getInt("mobs.phantom.spawn.per-attempt.min", phantomSpawnMinPerAttempt);
+ phantomSpawnMaxPerAttempt = getInt("mobs.phantom.spawn.per-attempt.max", phantomSpawnMaxPerAttempt);
}
public boolean pigGiveSaddleBack = false;

View File

@@ -1,62 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Sat, 4 Jul 2020 13:12:43 -0500
Subject: [PATCH] Implement bed explosion options
diff --git a/src/main/java/net/minecraft/world/level/block/BlockBed.java b/src/main/java/net/minecraft/world/level/block/BlockBed.java
index 00a01a157deec004bcf2f8587723a0ecd0bfef85..d42a3e73c6e4e65f023fa5af65a26acbf2f01281 100644
--- a/src/main/java/net/minecraft/world/level/block/BlockBed.java
+++ b/src/main/java/net/minecraft/world/level/block/BlockBed.java
@@ -138,7 +138,7 @@ public class BlockBed extends BlockFacingHorizontal implements ITileEntity {
world.a(blockposition1, false);
}
- world.createExplosion((Entity) null, DamageSource.a(), (ExplosionDamageCalculator) null, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, 5.0F, true, Explosion.Effect.DESTROY);
+ if (world.purpurConfig.bedExplode) world.createExplosion(null, DamageSource.a(), null, (double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D, (float) world.purpurConfig.bedExplosionPower, world.purpurConfig.bedExplosionFire, world.purpurConfig.bedExplosionEffect); // Purpur
return EnumInteractionResult.SUCCESS;
}
}
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index d957ee4c10fde8596442f2f05f0347994df7bae5..83f43b44946a9e5aeecacae776684934685d79ac 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -1,6 +1,7 @@
package net.pl3x.purpur;
import net.minecraft.core.IRegistry;
+import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.item.Item;
@@ -12,6 +13,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.logging.Level;
import static net.pl3x.purpur.PurpurConfig.log;
@@ -258,6 +260,22 @@ public class PurpurWorldConfig {
});
}
+ public boolean bedExplode = true;
+ public double bedExplosionPower = 5.0D;
+ public boolean bedExplosionFire = true;
+ public Explosion.Effect bedExplosionEffect = Explosion.Effect.DESTROY;
+ private void bedSettings() {
+ bedExplode = getBoolean("blocks.bed.explode", bedExplode);
+ bedExplosionPower = getDouble("blocks.bed.explosion-power", bedExplosionPower);
+ bedExplosionFire = getBoolean("blocks.bed.explosion-fire", bedExplosionFire);
+ try {
+ bedExplosionEffect = Explosion.Effect.valueOf(getString("blocks.bed.explosion-effect", bedExplosionEffect.name()));
+ } catch (IllegalArgumentException e) {
+ log(Level.SEVERE, "Unknown value for `blocks.bed.explosion-effect`! Using default of `DESTROY`");
+ bedExplosionEffect = Explosion.Effect.DESTROY;
+ }
+ }
+
public boolean dispenserApplyCursedArmor = true;
private void dispenserSettings() {
dispenserApplyCursedArmor = getBoolean("blocks.dispenser.apply-cursed-to-armor-slots", dispenserApplyCursedArmor);

View File

@@ -0,0 +1,148 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 22 Feb 2020 15:54:08 -0600
Subject: [PATCH] Item entity immunities
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index b9049dd6e5f254289f20aefefaf68e2ef5adac1b..52bdfb437ae5e200cb0d5001948a8f5e3abbd89c 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -2046,7 +2046,7 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially
public class TrackedEntity {
- final ServerEntity serverEntity;
+ public final ServerEntity serverEntity; // Purpur -> package -> public
final Entity entity;
private final int range;
SectionPos lastSectionPos;
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index d19a025337c4b0a2965184b4c872f23d15a4a60b..28f20150eaa0c00f83a3639c2a4194ecb32a0b8d 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -68,7 +68,7 @@ public class ServerEntity {
private boolean wasRiding;
private boolean wasOnGround;
// CraftBukkit start
- final Set<ServerPlayerConnection> trackedPlayers; // Paper - private -> package
+ public final Set<ServerPlayerConnection> trackedPlayers; // Paper - private -> package // Purpur - package -> public
public ServerEntity(ServerLevel worldserver, Entity entity, int i, boolean flag, Consumer<Packet<?>> consumer, Set<ServerPlayerConnection> trackedPlayers) {
this.trackedPlayers = trackedPlayers;
diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
index 158719d46c96bb733a00e08c8285f41a48406abf..623a8b38b9d0ccbfe807afe328495b19ead4d5a6 100644
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
@@ -53,6 +53,12 @@ public class ItemEntity extends Entity {
public final float bobOffs;
private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit
public boolean canMobPickup = true; // Paper
+ // Purpur start
+ public boolean immuneToCactus = false;
+ public boolean immuneToExplosion = false;
+ public boolean immuneToFire = false;
+ public boolean immuneToLightning = false;
+ // Purpur end
public ItemEntity(EntityType<? extends ItemEntity> type, Level world) {
super(type, world);
@@ -322,6 +328,15 @@ public class ItemEntity extends Entity {
return false;
} else if (!this.getItem().getItem().canBeHurtBy(source)) {
return false;
+ // Purpur start
+ } else if (
+ (immuneToCactus && source == DamageSource.CACTUS) ||
+ (immuneToFire && (source.isFire() || source == DamageSource.IN_FIRE)) ||
+ (immuneToLightning && source == DamageSource.LIGHTNING_BOLT) ||
+ (immuneToExplosion && source.isExplosion())
+ ) {
+ respawnOnClient();
+ return false;
} else {
// CraftBukkit start
if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, source, amount)) {
@@ -504,6 +519,12 @@ public class ItemEntity extends Entity {
com.google.common.base.Preconditions.checkArgument(!stack.isEmpty(), "Cannot drop air"); // CraftBukkit
this.getEntityData().set(ItemEntity.DATA_ITEM, stack);
this.getEntityData().markDirty(ItemEntity.DATA_ITEM); // CraftBukkit - SPIGOT-4591, must mark dirty
+ // Purpur start
+ if (level.purpurConfig.itemImmuneToCactus.contains(stack.getItem())) immuneToCactus = true;
+ if (level.purpurConfig.itemImmuneToExplosion.contains(stack.getItem())) immuneToExplosion = true;
+ if (level.purpurConfig.itemImmuneToFire.contains(stack.getItem())) immuneToFire = true;
+ if (level.purpurConfig.itemImmuneToLightning.contains(stack.getItem())) immuneToLightning = true;
+ // level end
}
@Override
@@ -594,4 +615,15 @@ public class ItemEntity extends Entity {
public SoundSource getSoundSource() {
return SoundSource.AMBIENT;
}
+
+ // Purpur start
+ public void respawnOnClient() {
+ Packet<?> spawnPacket = new ClientboundAddEntityPacket(this);
+ Packet<?> metadataPacket = new net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket(getId(), getEntityData(), true);
+ for (net.minecraft.server.network.ServerPlayerConnection connection : this.tracker.serverEntity.trackedPlayers) {
+ connection.send(spawnPacket);
+ connection.send(metadataPacket);
+ }
+ }
+ // Purpur end
}
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index 8306dc47d15492a5a7ad357c6c9073874b231394..983598f6f51d1754dabd86c18368ec3bcaa97e99 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -135,6 +135,49 @@ public class PurpurWorldConfig {
}
}
+ public List<Item> itemImmuneToCactus = new ArrayList<>();
+ public List<Item> itemImmuneToExplosion = new ArrayList<>();
+ public List<Item> itemImmuneToFire = new ArrayList<>();
+ public List<Item> itemImmuneToLightning = new ArrayList<>();
+ private void itemSettings() {
+ itemImmuneToCactus.clear();
+ getList("gameplay-mechanics.item.immune.cactus", new ArrayList<>()).forEach(key -> {
+ if (key.toString().equals("*")) {
+ Registry.ITEM.stream().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToCactus.add(item));
+ return;
+ }
+ Item item = Registry.ITEM.get(new ResourceLocation(key.toString()));
+ if (item != Items.AIR) itemImmuneToCactus.add(item);
+ });
+ itemImmuneToExplosion.clear();
+ getList("gameplay-mechanics.item.immune.explosion", new ArrayList<>()).forEach(key -> {
+ if (key.toString().equals("*")) {
+ Registry.ITEM.stream().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToExplosion.add(item));
+ return;
+ }
+ Item item = Registry.ITEM.get(new ResourceLocation(key.toString()));
+ if (item != Items.AIR) itemImmuneToExplosion.add(item);
+ });
+ itemImmuneToFire.clear();
+ getList("gameplay-mechanics.item.immune.fire", new ArrayList<>()).forEach(key -> {
+ if (key.toString().equals("*")) {
+ Registry.ITEM.stream().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToFire.add(item));
+ return;
+ }
+ Item item = Registry.ITEM.get(new ResourceLocation(key.toString()));
+ if (item != Items.AIR) itemImmuneToFire.add(item);
+ });
+ itemImmuneToLightning.clear();
+ getList("gameplay-mechanics.item.immune.lightning", new ArrayList<>()).forEach(key -> {
+ if (key.toString().equals("*")) {
+ Registry.ITEM.stream().filter(item -> item != Items.AIR).forEach((item) -> itemImmuneToLightning.add(item));
+ return;
+ }
+ Item item = Registry.ITEM.get(new ResourceLocation(key.toString()));
+ if (item != Items.AIR) itemImmuneToLightning.add(item);
+ });
+ }
+
public boolean idleTimeoutKick = true;
public boolean idleTimeoutTickNearbyEntities = true;
public boolean idleTimeoutCountAsSleeping = false;

View File

@@ -0,0 +1,73 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Fri, 13 Mar 2020 22:29:10 -0500
Subject: [PATCH] Add /ping command
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
index d478627dcd2b6e3d3d95b3fa224a25d44e6bbafb..158fc5748f175708a0c3415a2217663f77271bc7 100644
--- a/src/main/java/net/minecraft/commands/Commands.java
+++ b/src/main/java/net/minecraft/commands/Commands.java
@@ -198,6 +198,7 @@ public class Commands {
SetPlayerIdleTimeoutCommand.register(this.dispatcher);
StopCommand.register(this.dispatcher);
WhitelistCommand.register(this.dispatcher);
+ net.pl3x.purpur.command.PingCommand.register(this.dispatcher); // Purpur
}
if (environment.includeIntegrated) {
diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java
index 3e70e16c5d1e515295efe7cbe6b718e388c01903..95bbde3892de77bff6181250812290cfbf5104d1 100644
--- a/src/main/java/net/pl3x/purpur/PurpurConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java
@@ -131,10 +131,12 @@ public class PurpurConfig {
public static String afkBroadcastAway = "§e§o%s is now AFK";
public static String afkBroadcastBack = "§e§o%s is no longer AFK";
public static String afkTabListPrefix = "[AFK] ";
+ public static String pingCommandOutput = "§a%s's ping is %sms";
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);
}
public static String serverModName = "Purpur";
diff --git a/src/main/java/net/pl3x/purpur/command/PingCommand.java b/src/main/java/net/pl3x/purpur/command/PingCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..c1d69aa60fa89730cb6e70ec50ba728ee7980053
--- /dev/null
+++ b/src/main/java/net/pl3x/purpur/command/PingCommand.java
@@ -0,0 +1,32 @@
+package net.pl3x.purpur.command;
+
+import com.mojang.brigadier.CommandDispatcher;
+import net.minecraft.commands.CommandSourceStack;
+import net.minecraft.commands.Commands;
+import net.minecraft.commands.arguments.EntityArgument;
+import net.minecraft.server.level.ServerPlayer;
+import net.pl3x.purpur.PurpurConfig;
+import org.bukkit.craftbukkit.util.CraftChatMessage;
+
+import java.util.Collection;
+import java.util.Collections;
+
+public class PingCommand {
+ public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
+ dispatcher.register(Commands.literal("ping")
+ .requires((listener) -> listener.hasPermission(2))
+ .executes((context) -> execute(context.getSource(), Collections.singleton(context.getSource().getPlayerOrException())))
+ .then(Commands.argument("targets", EntityArgument.players())
+ .executes((context) -> execute(context.getSource(), EntityArgument.getPlayers(context, "targets")))
+ )
+ ).setPermission("bukkit.command.ping");
+ }
+
+ private static int execute(CommandSourceStack sender, Collection<ServerPlayer> targets) {
+ for (ServerPlayer player : targets) {
+ String output = String.format(PurpurConfig.pingCommandOutput, player.getGameProfile().getName(), player.latency);
+ sender.sendSuccess(CraftChatMessage.fromStringOrNull(output), false);
+ }
+ return targets.size();
+ }
+}

View File

@@ -1,69 +1,69 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 26 Mar 2020 21:39:32 -0500
Subject: [PATCH] Configurable jockey options
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 e4794760fc918cccbdc3f8d10ab21dd9b6f29e8e..ea776755767f29e49de2792afa30f79420d0fa4c 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EntityDrowned.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EntityDrowned.java
@@ -72,6 +72,23 @@ public class EntityDrowned extends EntityZombie implements IRangedEntity {
this.navigationLand = new Navigation(this, world);
diff --git a/src/main/java/net/minecraft/world/entity/monster/Drowned.java b/src/main/java/net/minecraft/world/entity/monster/Drowned.java
index 50228e59d629e75e97d23bd3ec92088f75480827..2758a312a002d8752d79fd297bc25853621c2171 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Drowned.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Drowned.java
@@ -69,6 +69,23 @@ public class Drowned extends Zombie implements RangedAttackMob {
this.groundNavigation = new GroundPathNavigation(this, world);
}
+ // Purpur start
+ @Override
+ public boolean jockeyOnlyBaby() {
+ return world.purpurConfig.drownedJockeyOnlyBaby;
+ return level.purpurConfig.drownedJockeyOnlyBaby;
+ }
+
+ @Override
+ public double jockeyChance() {
+ return world.purpurConfig.drownedJockeyChance;
+ return level.purpurConfig.drownedJockeyChance;
+ }
+
+ @Override
+ public boolean jockeyTryExistingChickens() {
+ return world.purpurConfig.drownedJockeyTryExistingChickens;
+ return level.purpurConfig.drownedJockeyTryExistingChickens;
+ }
+ // Purpur end
+
@Override
protected void m() {
this.goalSelector.a(1, new EntityDrowned.c(this, 1.0D));
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 d10d1b768601236b9892461ee41d61c7239d1a07..ee17e62d996d81ea149a5c0eae2e29404e363dcf 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EntityPigZombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EntityPigZombie.java
@@ -56,6 +56,23 @@ public class EntityPigZombie extends EntityZombie implements IEntityAngerable {
this.a(PathType.LAVA, 8.0F);
protected void addBehaviourGoals() {
this.goalSelector.addGoal(1, new Drowned.DrownedGoToWaterGoal(this, 1.0D));
diff --git a/src/main/java/net/minecraft/world/entity/monster/Husk.java b/src/main/java/net/minecraft/world/entity/monster/Husk.java
index 28fb67c0a5992cbd77c5d3c6efa0f0493466d81c..26ce4223cdb00acf7aa21f14c4ea6e426692b536 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Husk.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Husk.java
@@ -22,6 +22,23 @@ public class Husk extends Zombie {
super(type, world);
}
+ // Purpur start
+ @Override
+ public boolean jockeyOnlyBaby() {
+ return world.purpurConfig.zombifiedPiglinJockeyOnlyBaby;
+ return level.purpurConfig.huskJockeyOnlyBaby;
+ }
+
+ @Override
+ public double jockeyChance() {
+ return world.purpurConfig.zombifiedPiglinJockeyChance;
+ return level.purpurConfig.huskJockeyChance;
+ }
+
+ @Override
+ public boolean jockeyTryExistingChickens() {
+ return world.purpurConfig.zombifiedPiglinJockeyTryExistingChickens;
+ return level.purpurConfig.huskJockeyTryExistingChickens;
+ }
+ // Purpur end
+
@Override
public void setAngerTarget(@Nullable UUID uuid) {
this.br = uuid;
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 634416c354184bc6a2348c27c55e9868009ccd28..5ac950614fc90d02a568bb38f71faee124584c16 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EntityZombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EntityZombie.java
public static boolean checkHuskSpawnRules(EntityType<Husk> type, ServerLevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random) {
return checkMonsterSpawnRules(type, world, spawnReason, pos, random) && (spawnReason == MobSpawnType.SPAWNER || world.canSeeSky(pos));
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
index bb3b932c57fd1e5b1517940c7602c7f4aeeaf17e..747f872e0c9eef620f7713e674304e8f47738b1c 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
@@ -3,6 +3,7 @@ package net.minecraft.world.entity.monster;
import com.mojang.serialization.DynamicOps;
import java.time.LocalDate;
@@ -72,128 +72,119 @@ index 634416c354184bc6a2348c27c55e9868009ccd28..5ac950614fc90d02a568bb38f71faee1
import java.util.List;
import java.util.Random;
import java.util.UUID;
@@ -106,6 +107,20 @@ public class EntityZombie extends EntityMonster {
this(EntityTypes.ZOMBIE, world);
@@ -107,6 +108,20 @@ public class Zombie extends Monster {
this(EntityType.ZOMBIE, world);
}
+ // Purpur start
+ public boolean jockeyOnlyBaby() {
+ return world.purpurConfig.zombieJockeyOnlyBaby;
+ return level.purpurConfig.zombieJockeyOnlyBaby;
+ }
+
+ public double jockeyChance() {
+ return world.purpurConfig.zombieJockeyChance;
+ return level.purpurConfig.zombieJockeyChance;
+ }
+
+ public boolean jockeyTryExistingChickens() {
+ return world.purpurConfig.zombieJockeyTryExistingChickens;
+ return level.purpurConfig.zombieJockeyTryExistingChickens;
+ }
+ // Purpur end
+
@Override
protected void initPathfinder() {
if (world.paperConfig.zombiesTargetTurtleEggs) this.goalSelector.a(4, new EntityZombie.a(this, 1.0D, 3)); // Paper
@@ -506,19 +521,19 @@ public class EntityZombie extends EntityMonster {
if (object instanceof EntityZombie.GroupDataZombie) {
EntityZombie.GroupDataZombie entityzombie_groupdatazombie = (EntityZombie.GroupDataZombie) object;
protected void registerGoals() {
if (level.paperConfig.zombiesTargetTurtleEggs) this.goalSelector.addGoal(4, new Zombie.ZombieAttackTurtleEggGoal(this, 1.0D, 3)); // Paper
@@ -504,19 +519,19 @@ public class Zombie extends Monster {
if (object instanceof Zombie.ZombieGroupData) {
Zombie.ZombieGroupData entityzombie_groupdatazombie = (Zombie.ZombieGroupData) object;
- if (entityzombie_groupdatazombie.a) {
- if (entityzombie_groupdatazombie.isBaby) {
- this.setBaby(true);
+ // Purpur start
+ if (!jockeyOnlyBaby() || entityzombie_groupdatazombie.isBaby()) {
+ this.setBaby(entityzombie_groupdatazombie.isBaby());
if (entityzombie_groupdatazombie.b) {
- if ((double) worldaccess.getRandom().nextFloat() < 0.05D) {
- List<EntityChicken> list = worldaccess.a(EntityChicken.class, this.getBoundingBox().grow(5.0D, 3.0D, 5.0D), IEntitySelector.c);
+ if ((double) worldaccess.getRandom().nextFloat() < jockeyChance()) {
+ List<EntityChicken> list = jockeyTryExistingChickens() ? worldaccess.a(EntityChicken.class, this.getBoundingBox().grow(5.0D, 3.0D, 5.0D), IEntitySelector.c) : Collections.emptyList();
+ if (!jockeyOnlyBaby() || entityzombie_groupdatazombie.isBaby) {
+ this.setBaby(entityzombie_groupdatazombie.isBaby);
if (entityzombie_groupdatazombie.canSpawnJockey) {
- if ((double) world.getRandom().nextFloat() < 0.05D) {
- List<Chicken> list = world.getEntitiesOfClass(Chicken.class, this.getBoundingBox().inflate(5.0D, 3.0D, 5.0D), EntitySelector.ENTITY_NOT_BEING_RIDDEN);
+ if ((double) world.getRandom().nextFloat() < jockeyChance()) {
+ List<Chicken> list = jockeyTryExistingChickens() ? world.getEntitiesOfClass(Chicken.class, this.getBoundingBox().inflate(5.0D, 3.0D, 5.0D), EntitySelector.ENTITY_NOT_BEING_RIDDEN) : Collections.emptyList();
if (!list.isEmpty()) {
EntityChicken entitychicken = (EntityChicken) list.get(0);
Chicken entitychicken = (Chicken) list.get(0);
entitychicken.setChickenJockey(true);
this.startRiding(entitychicken);
- }
- } else if ((double) worldaccess.getRandom().nextFloat() < 0.05D) {
- } else if ((double) world.getRandom().nextFloat() < 0.05D) {
+ } else { // Purpur
EntityChicken entitychicken1 = (EntityChicken) EntityTypes.CHICKEN.a(this.world);
Chicken entitychicken1 = (Chicken) EntityType.CHICKEN.create(this.level);
entitychicken1.setPositionRotation(this.locX(), this.locY(), this.locZ(), this.yaw, 0.0F);
@@ -526,6 +541,7 @@ public class EntityZombie extends EntityMonster {
entitychicken1.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0F);
@@ -524,6 +539,7 @@ public class Zombie extends Monster {
entitychicken1.setChickenJockey(true);
this.startRiding(entitychicken1);
worldaccess.addEntity(entitychicken1, CreatureSpawnEvent.SpawnReason.MOUNT); // CraftBukkit
world.addEntity(entitychicken1, CreatureSpawnEvent.SpawnReason.MOUNT); // CraftBukkit
+ } // Purpur
}
}
}
@@ -628,7 +644,7 @@ public class EntityZombie extends EntityMonster {
public static class GroupDataZombie implements GroupDataEntity {
- public final boolean a;
+ public final boolean a; public boolean isBaby() { return a; } // Purpur - OBFHELPER
public final boolean b;
public GroupDataZombie(boolean flag, boolean flag1) {
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 ce08413134de6101420ccb957da925ea1e3b0884..5d3e5873f19aaf8389eb5525693b9378ea9f94ee 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EntityZombieHusk.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EntityZombieHusk.java
@@ -22,6 +22,23 @@ public class EntityZombieHusk extends EntityZombie {
super(entitytypes, world);
diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
index a2fbab27980d7f52033fd542220d534cefcc4747..c4a653f9b593654a831905ba5f39c4125f1683ea 100644
--- a/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
+++ b/src/main/java/net/minecraft/world/entity/monster/ZombieVillager.java
@@ -74,6 +74,23 @@ public class ZombieVillager extends Zombie implements VillagerDataHolder {
this.setVillagerData(this.getVillagerData().setProfession((VillagerProfession) Registry.VILLAGER_PROFESSION.getRandom(this.random)));
}
+ // Purpur start
+ @Override
+ public boolean jockeyOnlyBaby() {
+ return world.purpurConfig.huskJockeyOnlyBaby;
+ return level.purpurConfig.zombieVillagerJockeyOnlyBaby;
+ }
+
+ @Override
+ public double jockeyChance() {
+ return world.purpurConfig.huskJockeyChance;
+ return level.purpurConfig.zombieVillagerJockeyChance;
+ }
+
+ @Override
+ public boolean jockeyTryExistingChickens() {
+ return world.purpurConfig.huskJockeyTryExistingChickens;
+ }
+ // Purpur end
+
public static boolean a(EntityTypes<EntityZombieHusk> 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/EntityZombieVillager.java b/src/main/java/net/minecraft/world/entity/monster/EntityZombieVillager.java
index f341759f6110b51c856de09248d2f523c58aa712..99d0932e5352589cfbcc48a5e789651d0d77edde 100644
--- a/src/main/java/net/minecraft/world/entity/monster/EntityZombieVillager.java
+++ b/src/main/java/net/minecraft/world/entity/monster/EntityZombieVillager.java
@@ -70,6 +70,23 @@ public class EntityZombieVillager extends EntityZombie implements VillagerDataHo
this.setVillagerData(this.getVillagerData().withProfession((VillagerProfession) IRegistry.VILLAGER_PROFESSION.a(this.random)));
}
+ // Purpur start
+ @Override
+ public boolean jockeyOnlyBaby() {
+ return world.purpurConfig.zombieVillagerJockeyOnlyBaby;
+ }
+
+ @Override
+ public double jockeyChance() {
+ return world.purpurConfig.zombieVillagerJockeyChance;
+ }
+
+ @Override
+ public boolean jockeyTryExistingChickens() {
+ return world.purpurConfig.zombieVillagerJockeyTryExistingChickens;
+ return level.purpurConfig.zombieVillagerJockeyTryExistingChickens;
+ }
+ // Purpur end
+
@Override
protected void initDatawatcher() {
super.initDatawatcher();
protected void defineSynchedData() {
super.defineSynchedData();
diff --git a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java
index 233b390541acddcf815db4a8f299496eaea4f758..a50191aac887dffd3a7930455cb222fa0dc4e91a 100644
--- a/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/ZombifiedPiglin.java
@@ -58,6 +58,23 @@ public class ZombifiedPiglin extends Zombie implements NeutralMob {
this.setPathfindingMalus(BlockPathTypes.LAVA, 8.0F);
}
+ // Purpur start
+ @Override
+ public boolean jockeyOnlyBaby() {
+ return level.purpurConfig.zombifiedPiglinJockeyOnlyBaby;
+ }
+
+ @Override
+ public double jockeyChance() {
+ return level.purpurConfig.zombifiedPiglinJockeyChance;
+ }
+
+ @Override
+ public boolean jockeyTryExistingChickens() {
+ return level.purpurConfig.zombifiedPiglinJockeyTryExistingChickens;
+ }
+ // Purpur end
+
@Override
public void setPersistentAngerTarget(@Nullable UUID uuid) {
this.persistentAngerTarget = uuid;
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index dfcceebc9fbfa62fc14f3c53217af8e39025307d..a12c2ae8291114f17bbb05761272bf724f848b1c 100644
index 983598f6f51d1754dabd86c18368ec3bcaa97e99..d504e6b4fa0749ac268d0ab59084ff5fbc11f7ff 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -321,6 +321,15 @@ public class PurpurWorldConfig {