mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-22 10:57:43 +01:00
hardfork from paper 😊
This commit is contained in:
@@ -62,11 +62,9 @@
|
||||
+
|
||||
+ // Purpur start - Component related conveniences
|
||||
+ public Component getLocalizedDeathMessage(String str, LivingEntity entity) {
|
||||
+ net.kyori.adventure.text.Component name = io.papermc.paper.adventure.PaperAdventure.asAdventure(entity.getDisplayName());
|
||||
+ net.kyori.adventure.text.minimessage.tag.resolver.TagResolver template = net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.component("player", name);
|
||||
+ net.kyori.adventure.text.Component name = + net.kyori.adventure.text.minimessage.tag.resolver.TagResolver template = net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.component("player", name);
|
||||
+ net.kyori.adventure.text.Component component = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(str, template);
|
||||
+ return io.papermc.paper.adventure.PaperAdventure.asVanilla(component);
|
||||
+ }
|
||||
+ return + }
|
||||
+ // Purpur end - Component related conveniences
|
||||
|
||||
public String getMsgId() {
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
public double zOld;
|
||||
+ public float maxUpStep; // Purpur - Add option to set armorstand step height
|
||||
public boolean noPhysics;
|
||||
- public final RandomSource random = SHARED_RANDOM; // Paper - Share random for entities to make them more random
|
||||
+ public final RandomSource random; // Paper - Share random for entities to make them more random // Add toggle for RNG manipulation
|
||||
public int tickCount;
|
||||
private int remainingFireTicks = -this.getFireImmuneTicks();
|
||||
public boolean wasTouchingWater;
|
||||
@@ -28,8 +26,7 @@
|
||||
+ protected UUID uuid; // Purpur - Add toggle for RNG manipulation
|
||||
+ protected String stringUUID; // Purpur - Add toggle for RNG manipulation
|
||||
private boolean hasGlowingTag;
|
||||
private final Set<String> tags = new io.papermc.paper.util.SizeLimitedSet<>(new it.unimi.dsi.fastutil.objects.ObjectOpenHashSet<>(), MAX_ENTITY_TAG_COUNT); // Paper - fully limit tag size - replace set impl
|
||||
private final double[] pistonDeltas = new double[]{0.0, 0.0, 0.0};
|
||||
private final Set<String> tags = new private final double[] pistonDeltas = new double[]{0.0, 0.0, 0.0};
|
||||
@@ -394,6 +_,7 @@
|
||||
public long activatedTick = Integer.MIN_VALUE;
|
||||
public boolean isTemporarilyActive;
|
||||
@@ -40,7 +37,6 @@
|
||||
}
|
||||
@@ -406,10 +_,21 @@
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Purpur start - Add canSaveToDisk to Entity
|
||||
+ public boolean canSaveToDisk() {
|
||||
@@ -61,9 +57,7 @@
|
||||
this.blockPosition = BlockPos.ZERO;
|
||||
this.chunkPosition = ChunkPos.ZERO;
|
||||
@@ -779,6 +_,7 @@
|
||||
&& this.level.paperConfig().environment.netherCeilingVoidDamageHeight.test(v -> this.getY() >= v)
|
||||
&& (!(this instanceof Player player) || !player.getAbilities().invulnerable))) {
|
||||
// Paper end - Configurable nether ceiling damage
|
||||
+ if (this.level.purpurConfig.teleportOnNetherCeilingDamage && this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER && this instanceof ServerPlayer player) player.teleport(org.bukkit.craftbukkit.util.CraftLocation.toBukkit(this.level.getSharedSpawnPos(), this.level)); else // Purpur - Add option to teleport to spawn on nether ceiling damage
|
||||
this.onBelowWorld();
|
||||
}
|
||||
@@ -87,9 +81,7 @@
|
||||
this.wasTouchingWater = false;
|
||||
} else if (this.updateFluidHeightAndDoFluidPushing(FluidTags.WATER, 0.014)) {
|
||||
@@ -2364,6 +_,13 @@
|
||||
compound.putBoolean("Paper.FreezeLock", true);
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start - Fire immune API
|
||||
+ if (immuneToFire != null) {
|
||||
@@ -101,9 +93,7 @@
|
||||
} catch (Throwable var8) {
|
||||
CrashReport crashReport = CrashReport.forThrowable(var8, "Saving entity NBT");
|
||||
@@ -2481,6 +_,13 @@
|
||||
freezeLocked = compound.getBooleanOr("Paper.FreezeLock", false);
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start - Fire immune API
|
||||
+ if (compound.contains("Purpur.FireImmune")) {
|
||||
@@ -120,7 +110,6 @@
|
||||
if (!this.level().isClientSide()) {
|
||||
+ if (hand == InteractionHand.OFF_HAND && (level().purpurConfig.villagerCanBeLeashed || level().purpurConfig.wanderingTraderCanBeLeashed) && this instanceof net.minecraft.world.entity.npc.AbstractVillager) return InteractionResult.CONSUME; // Purpur - Allow leashing villagers
|
||||
// CraftBukkit start - fire PlayerUnleashEntityEvent
|
||||
// Paper start - Expand EntityUnleashEvent
|
||||
org.bukkit.event.player.PlayerUnleashEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand, !player.hasInfiniteMaterials());
|
||||
@@ -2936,15 +_,18 @@
|
||||
return Vec3.directionFromRotation(this.getRotationVector());
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
@@ -28,6 +_,8 @@
|
||||
return net.minecraft.util.Mth.clamp(serverPlayer.getStats().getValue(net.minecraft.stats.Stats.CUSTOM.get(net.minecraft.stats.Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= playerInsomniaTicks;
|
||||
};
|
||||
// Paper end - Ability to control player's insomnia and phantoms
|
||||
+ public static Predicate<Player> notAfk = (player) -> !player.isAfk(); // Purpur - AFK API
|
||||
+
|
||||
// Paper start - Affects Spawning API
|
||||
public static final Predicate<Entity> PLAYER_AFFECTS_SPAWNING = (entity) -> {
|
||||
return !entity.isSpectator() && entity.isAlive() && entity instanceof Player player && player.affectsSpawning;
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
@@ -1384,7 +_,11 @@
|
||||
entity.load(tag);
|
||||
},
|
||||
// Paper end - Don't fire sync event during generation
|
||||
- () -> LOGGER.warn("Skipping Entity with id {}", tag.getStringOr("id", "[invalid]"))
|
||||
+ // Purpur start - log skipped entity's position
|
||||
+ () -> {LOGGER.warn("Skipping Entity with id {}", tag.getStringOr("id", "[invalid]"));
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
@@ -328,7 +_,7 @@
|
||||
public void playerTouch(Player entity) {
|
||||
if (entity instanceof ServerPlayer serverPlayer) {
|
||||
if (entity.takeXpDelay == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(serverPlayer.getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper - PlayerPickupExperienceEvent
|
||||
- entity.takeXpDelay = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerXpCooldownEvent(entity, 2, org.bukkit.event.player.PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entityhuman.takeXpDelay = 2;
|
||||
+ entity.takeXpDelay = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerXpCooldownEvent(entity, this.level().purpurConfig.playerExpPickupDelay, org.bukkit.event.player.PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entityhuman.takeXpDelay = 2; // Purpur - Configurable player pickup exp delay
|
||||
entity.take(this, 1);
|
||||
|
||||
@@ -138,16 +138,12 @@
|
||||
if (this.shouldDropLoot() && level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
|
||||
+ if (!(damageSource.is(net.minecraft.world.damagesource.DamageTypes.CRAMMING) && level().purpurConfig.disableDropsOnCrammingDeath)) { // Purpur - Disable loot drops on death by cramming
|
||||
this.dropFromLootTable(level, damageSource, flag);
|
||||
// Paper start
|
||||
final boolean prev = this.clearEquipmentSlots;
|
||||
@@ -1883,6 +_,7 @@
|
||||
// Paper end
|
||||
this.dropCustomDeathLoot(level, damageSource, flag);
|
||||
this.clearEquipmentSlots = prev; // Paper
|
||||
+ } // Purpur - Disable loot drops on death by cramming
|
||||
}
|
||||
|
||||
// CraftBukkit start - Call death event // Paper start - call advancement triggers with correct entity equipment
|
||||
@@ -3057,6 +_,7 @@
|
||||
float f = (float)(d * 10.0 - 3.0);
|
||||
if (f > 0.0F) {
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
int age = this.getAge();
|
||||
- if (!this.level().isClientSide && age == 0 && this.canFallInLove()) {
|
||||
+ if (!this.level().isClientSide && age == 0 && this.canFallInLove() && (this.level().purpurConfig.animalBreedingCooldownSeconds <= 0 || !this.level().hasBreedingCooldown(player.getUUID(), this.getClass()))) { // Purpur - Add adjustable breeding cooldown to config
|
||||
final ItemStack breedCopy = itemInHand.copy(); // Paper - Fix EntityBreedEvent copying
|
||||
this.usePlayerItem(player, hand, itemInHand);
|
||||
this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying
|
||||
@@ -239,10 +_,20 @@
|
||||
public void spawnChildFromBreeding(ServerLevel level, Animal mate) {
|
||||
AgeableMob breedOffspring = this.getBreedOffspring(level, mate);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/animal/Bee.java
|
||||
+++ b/net/minecraft/world/entity/animal/Bee.java
|
||||
@@ -167,7 +_,7 @@
|
||||
// Paper end - Fix MC-167279
|
||||
this.lookControl = new Bee.BeeLookControl(this);
|
||||
this.setPathfindingMalus(PathType.DANGER_FIRE, -1.0F);
|
||||
- this.setPathfindingMalus(PathType.WATER, -1.0F);
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
@@ -705,6 +_,29 @@
|
||||
return slot == EquipmentSlot.MAINHAND;
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start - Tulips change fox type
|
||||
+ @Override
|
||||
@@ -49,4 +48,3 @@
|
||||
+ // Purpur end - Tulips change fox type
|
||||
|
||||
@Override
|
||||
// Paper start - Cancellable death event
|
||||
|
||||
@@ -11,6 +11,5 @@
|
||||
+ cow.yRotO = this.yRotO;
|
||||
+ cow.xRotO = this.xRotO;
|
||||
+ // Purpur end - Fix cow rotation when shearing mooshroom
|
||||
// Paper start - custom shear drops; moved drop generation to separate method
|
||||
drops.forEach(drop -> {
|
||||
this.spawnAtLocation(level, new ItemEntity(this.level(), this.getX(), this.getY(1.0), this.getZ(), drop));
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
public Squid(EntityType<? extends Squid> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
- //this.random.setSeed(this.getId()); // Paper - Share random for entities to make them more random
|
||||
+ if (!level.purpurConfig.entitySharedRandom) this.random.setSeed(this.getId()); // Paper - Share random for entities to make them more random // Purpur - Add toggle for RNG manipulation
|
||||
this.tentacleSpeed = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/animal/WaterAnimal.java
|
||||
+++ b/net/minecraft/world/entity/animal/WaterAnimal.java
|
||||
@@ -76,8 +_,7 @@
|
||||
seaLevel = level.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.maximum.or(seaLevel);
|
||||
i = level.getMinecraftWorld().paperConfig().entities.spawning.wateranimalSpawnHeight.minimum.or(i);
|
||||
// Paper end - Make water animal spawn height configurable
|
||||
- return pos.getY() >= i
|
||||
- && pos.getY() <= seaLevel
|
||||
+ return ((spawnReason == EntitySpawnReason.SPAWNER && level.getMinecraftWorld().purpurConfig.spawnerFixMC238526) || (pos.getY() >= i && pos.getY() <= seaLevel)) // Purpur - MC-238526 - Fix spawner not spawning water animals correctly
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
+++ b/net/minecraft/world/entity/animal/goat/Goat.java
|
||||
@@ -395,6 +_,7 @@
|
||||
|
||||
// Paper start - Goat ram API
|
||||
public void ram(net.minecraft.world.entity.LivingEntity entity) {
|
||||
+ if(!new org.purpurmc.purpur.event.entity.GoatRamEntityEvent((org.bukkit.entity.Goat) getBukkitEntity(), entity.getBukkitLivingEntity()).callEvent()) return; // Purpur - Added goat ram event
|
||||
Brain<Goat> brain = this.getBrain();
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
@@ -77,6 +_,7 @@
|
||||
private Llama caravanHead;
|
||||
@Nullable
|
||||
public Llama caravanTail; // Paper
|
||||
+ public boolean shouldJoinCaravan = true; // Purpur - Llama API
|
||||
|
||||
public Llama(EntityType<? extends Llama> entityType, Level level) {
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
@@ -74,6 +_,8 @@
|
||||
}
|
||||
}
|
||||
// Paper end - Fix invulnerable end crystals
|
||||
+ if (this.level().purpurConfig.endCrystalCramming > 0 && this.level().getEntitiesOfClass(EndCrystal.class, getBoundingBox()).size() > this.level().purpurConfig.endCrystalCramming) this.hurt(this.damageSources().cramming(), 6.0F); // Purpur - End Crystal Cramming
|
||||
+
|
||||
}
|
||||
@@ -47,10 +46,8 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
this.remove(Entity.RemovalReason.KILLED, org.bukkit.event.entity.EntityRemoveEvent.Cause.EXPLODE); // Paper - add Bukkit remove cause
|
||||
- level.explode(this, damageSource1, null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.BLOCK);
|
||||
+ level.explode(this, damageSource1, null, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), getExplosionEffect()); // Purpur - End crystal explosion options
|
||||
+ } else this.unsetRemoved(); // Purpur - End crystal explosion options
|
||||
} else {
|
||||
this.remove(Entity.RemovalReason.KILLED, org.bukkit.event.entity.EntityRemoveEvent.Cause.DEATH); // Paper - add Bukkit remove cause
|
||||
// CraftBukkit end
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
@@ -95,10 +_,13 @@
|
||||
private boolean noTickPoseDirty = false;
|
||||
private boolean noTickEquipmentDirty = false;
|
||||
// Paper end - Allow ArmorStands not to tick
|
||||
+ public boolean canMovementTick = true; // Purpur - Movement options for armor stands
|
||||
|
||||
public ArmorStand(EntityType<? extends ArmorStand> entityType, Level level) {
|
||||
super(entityType, level);
|
||||
if (level != null) this.canTick = level.paperConfig().entities.armorStands.tick; // Paper - Allow ArmorStands not to tick
|
||||
+ if (level != null) this.canMovementTick = level.purpurConfig.armorstandMovement; // Purpur - Movement options for armor stands
|
||||
+ this.setShowArms(level != null && level.purpurConfig.armorstandPlaceWithArms); // Purpur - Config to show Armor Stand arms on spawn
|
||||
}
|
||||
@@ -19,13 +17,11 @@
|
||||
@Override
|
||||
public void tick() {
|
||||
+ maxUpStep = level().purpurConfig.armorstandStepHeight; // Purpur - Add option to set armorstand step height
|
||||
// Paper start - Allow ArmorStands not to tick
|
||||
if (!this.canTick) {
|
||||
if (this.noTickPoseDirty) {
|
||||
@@ -867,4 +_,18 @@
|
||||
}
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Purpur start - Movement options for armor stands
|
||||
+ @Override
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
--- a/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -59,6 +_,12 @@
|
||||
public boolean canMobPickup = true; // Paper - Item#canEntityPickup
|
||||
private int despawnRate = -1; // Paper - Alternative item-despawn-rate
|
||||
public net.kyori.adventure.util.TriState frictionState = net.kyori.adventure.util.TriState.NOT_SET; // Paper - Friction API
|
||||
+ // Purpur start - Item entity immunities
|
||||
+ public boolean immuneToCactus = false;
|
||||
+ public boolean immuneToExplosion = false;
|
||||
@@ -34,7 +31,6 @@
|
||||
@@ -528,6 +_,12 @@
|
||||
public void setItem(ItemStack stack) {
|
||||
this.getEntityData().set(DATA_ITEM, stack);
|
||||
this.despawnRate = this.level().paperConfig().entities.spawning.altItemDespawnRate.enabled ? this.level().paperConfig().entities.spawning.altItemDespawnRate.items.getOrDefault(stack.getItem(), this.level().spigotConfig.itemDespawnRate) : this.level().spigotConfig.itemDespawnRate; // Paper - Alternative item-despawn-rate
|
||||
+ // Purpur start - Item entity immunities
|
||||
+ if (level().purpurConfig.itemImmuneToCactus.contains(stack.getItem())) immuneToCactus = true;
|
||||
+ if (level().purpurConfig.itemImmuneToExplosion.contains(stack.getItem())) immuneToExplosion = true;
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
--- a/net/minecraft/world/entity/item/PrimedTnt.java
|
||||
+++ b/net/minecraft/world/entity/item/PrimedTnt.java
|
||||
@@ -253,4 +_,32 @@
|
||||
return !this.level().paperConfig().fixes.preventTntFromMovingInWater && super.isPushedByFluid();
|
||||
}
|
||||
// Paper end - Option to prevent TNT from moving in water
|
||||
+
|
||||
+ // Purpur start - Shears can defuse TNT
|
||||
+ @Override
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
+++ b/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
@@ -158,10 +_,7 @@
|
||||
this.reassessWeaponGoal();
|
||||
this.setCanPickUpLoot(this.level().paperConfig().entities.behavior.mobsCanAlwaysPickUpLoot.skeletons || random.nextFloat() < 0.55F * difficulty.getSpecialMultiplier()); // Paper - Add world settings for mobs picking up loot
|
||||
if (this.getItemBySlot(EquipmentSlot.HEAD).isEmpty()) {
|
||||
- LocalDate localDate = LocalDate.now();
|
||||
- int i = localDate.get(ChronoField.DAY_OF_MONTH);
|
||||
|
||||
@@ -50,8 +50,6 @@
|
||||
if (!event.isCancelled()) {
|
||||
// CraftBukkit end
|
||||
this.dead = true;
|
||||
- serverLevel.explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), Level.ExplosionInteraction.MOB); // CraftBukkit // Paper - fix DamageSource API (revert to vanilla, no, just no, don't change this)
|
||||
+ serverLevel.explode(this, this.getX(), this.getY(), this.getZ(), event.getRadius(), event.getFire(), serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING) && level().purpurConfig.creeperAllowGriefing ? Level.ExplosionInteraction.MOB : Level.ExplosionInteraction.NONE); // CraftBukkit // Paper - fix DamageSource API (revert to vanilla, no, just no, don't change this) // Purpur - Add enderman and creeper griefing controls
|
||||
this.spawnLingeringCloud();
|
||||
this.triggerOnDeathMobEffects(serverLevel, Entity.RemovalReason.KILLED);
|
||||
this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.EXPLODE); // CraftBukkit - add Bukkit remove cause
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
this.goalSelector.addGoal(7, new RandomStrollGoal(this, 1.0));
|
||||
this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Drowned.class).setAlertOthers(ZombifiedPiglin.class));
|
||||
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entity, level) -> this.okTarget(entity)));
|
||||
- if (this.level().spigotConfig.zombieAggressiveTowardsVillager) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); // Paper - Check drowned for villager aggression config
|
||||
+ // Purpur start - Add option to disable zombie aggressiveness towards villagers
|
||||
+ if (this.level().spigotConfig.zombieAggressiveTowardsVillager) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false) { // Paper - Check drowned for villager aggression config
|
||||
+ @Override
|
||||
+ public boolean canUse() {
|
||||
+ return (level().purpurConfig.zombieAggressiveTowardsVillagerWhenLagging || !level().getServer().server.isLagging()) && super.canUse();
|
||||
|
||||
@@ -12,10 +12,8 @@
|
||||
@@ -220,7 +_,7 @@
|
||||
|
||||
boolean isBeingStaredBy(Player player) {
|
||||
// Paper start - EndermanAttackPlayerEvent
|
||||
- final boolean shouldAttack = this.isBeingStaredBy0(player);
|
||||
+ final boolean shouldAttack = !this.level().purpurConfig.endermanDisableStareAggro && this.isBeingStaredBy0(player); // Purpur - Config to ignore Dragon Head wearers and stare aggro
|
||||
final com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent event = new com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent((org.bukkit.entity.Enderman) getBukkitEntity(), (org.bukkit.entity.Player) player.getBukkitEntity());
|
||||
event.setCancelled(!shouldAttack);
|
||||
return event.callEvent();
|
||||
@@ -376,6 +_,7 @@
|
||||
@@ -31,7 +29,6 @@
|
||||
boolean flag = abstractThrownPotion1 != null && this.hurtWithCleanWater(level, damageSource, abstractThrownPotion1, amount);
|
||||
|
||||
+ if (!flag && level.purpurConfig.endermanIgnoreProjectiles) return super.hurtServer(level, damageSource, amount); // Purpur - Config to disable Enderman teleport on projectile hit
|
||||
if (this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper - EndermanEscapeEvent
|
||||
for (int i = 0; i < 64; i++) {
|
||||
if (this.teleport()) {
|
||||
@@ -433,7 +_,7 @@
|
||||
|
||||
@@ -15,5 +15,4 @@
|
||||
- if (block instanceof LeavesBlock) {
|
||||
+ if (this.level().purpurConfig.ravagerGriefableBlocks.contains(block)) { // Purpur - Configurable ravager griefable blocks list
|
||||
// CraftBukkit start
|
||||
if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this, blockPos, blockState.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state
|
||||
continue;
|
||||
|
||||
@@ -68,15 +68,12 @@
|
||||
public Brain<Villager> getBrain() {
|
||||
return (Brain<Villager>)super.getBrain();
|
||||
@@ -292,11 +_,24 @@
|
||||
// Paper start - EAR 2
|
||||
this.customServerAiStep(level, false);
|
||||
}
|
||||
- protected void customServerAiStep(ServerLevel level, final boolean inactive) {
|
||||
+ protected void customServerAiStep(ServerLevel level, boolean inactive) { // Purpur - Lobotomize stuck villagers - not final
|
||||
// Paper end - EAR 2
|
||||
ProfilerFiller profilerFiller = Profiler.get();
|
||||
profilerFiller.push("villagerBrain");
|
||||
- if (!inactive) this.getBrain().tick(level, this); // Paper - EAR 2
|
||||
+ // Purpur start - Lobotomize stuck villagers
|
||||
+ if (this.level().purpurConfig.villagerLobotomizeEnabled) {
|
||||
+ // treat as inactive if lobotomized
|
||||
@@ -87,7 +84,6 @@
|
||||
+ // Purpur end - Lobotomize stuck villagers
|
||||
+ // Pufferfish start
|
||||
+ if (!inactive /*&& this.behaviorTick++ % this.activatedPriority == 0*/) {
|
||||
+ this.getBrain().tick(level, this); // Paper - EAR 2
|
||||
+ }
|
||||
+ else if (this.isLobotomized && shouldRestock()) restock(); // Purpur - Lobotomize stuck villagers
|
||||
+ // Pufferfish end
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
this,
|
||||
new ItemStack(Items.MILK_BUCKET),
|
||||
SoundEvents.WANDERING_TRADER_REAPPEARED,
|
||||
- wanderingTrader -> this.canDrinkMilk && this.level().isBrightOutside() && wanderingTrader.isInvisible() // Paper - Add more WanderingTrader API
|
||||
+ wanderingTrader -> level().purpurConfig.milkClearsBeneficialEffects && this.canDrinkMilk && this.level().isBrightOutside() && wanderingTrader.isInvisible() // Paper - Add more WanderingTrader API // // Purpur - Milk Keeps Beneficial Effects
|
||||
)
|
||||
);
|
||||
this.goalSelector.addGoal(1, new TradeWithPlayerGoal(this));
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
+++ b/net/minecraft/world/entity/player/Player.java
|
||||
@@ -210,11 +_,20 @@
|
||||
private int currentImpulseContextResetGraceTime = 0;
|
||||
public boolean affectsSpawning = true; // Paper - Affects Spawning API
|
||||
public net.kyori.adventure.util.TriState flyingFallDamage = net.kyori.adventure.util.TriState.NOT_SET; // Paper - flying fall damage
|
||||
+ public int burpDelay = 0; // Purpur - Burp delay
|
||||
+ public boolean canPortalInstant = false; // Purpur - Add portal permission bypass
|
||||
|
||||
@@ -62,9 +60,7 @@
|
||||
} else if (!entity.isRemoved()) {
|
||||
this.touch(entity);
|
||||
@@ -1214,7 +_,7 @@
|
||||
flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper - Toggleable player crits
|
||||
if (flag2) {
|
||||
damageSource = damageSource.critical(); // Paper - critical damage API
|
||||
- f *= 1.5F;
|
||||
+ f *= (float) this.level().purpurConfig.playerCriticalDamageMultiplier; // Purpur - Add config change multiplier critical damage value
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
if (serverPlayer1 != null) {
|
||||
serverPlayer1.resetFallDistance();
|
||||
serverPlayer1.resetCurrentImpulseContext();
|
||||
- serverPlayer1.hurtServer(serverPlayer.serverLevel(), this.damageSources().enderPearl().eventEntityDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API
|
||||
+ serverPlayer1.hurtServer(serverPlayer.serverLevel(), this.damageSources().enderPearl().eventEntityDamager(this), this.level().purpurConfig.enderPearlDamage); // CraftBukkit // Paper - fix DamageSource API // Purpur - Configurable Ender Pearl damage
|
||||
}
|
||||
|
||||
this.playSound(serverLevel, vec3);
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
@@ -49,6 +_,10 @@
|
||||
private org.bukkit.craftbukkit.inventory.view.CraftAnvilView bukkitEntity;
|
||||
// CraftBukkit end
|
||||
public boolean bypassEnchantmentLevelRestriction = false; // Paper - bypass anvil level restrictions
|
||||
+ // Purpur start - Anvil API
|
||||
+ public boolean bypassCost = false;
|
||||
+ public boolean canDoUnsafeEnchants = false;
|
||||
@@ -98,8 +97,6 @@
|
||||
flag1 = true;
|
||||
} else {
|
||||
flag = true;
|
||||
- if (intValue > enchantment.getMaxLevel() && !this.bypassEnchantmentLevelRestriction) { // Paper - bypass anvil level restrictions
|
||||
+ if (!org.purpurmc.purpur.PurpurConfig.allowHigherEnchantsLevels && intValue > enchantment.getMaxLevel() && !this.bypassEnchantmentLevelRestriction) { // Paper - bypass anvil level restrictions // Purpur - Config to allow unsafe enchants
|
||||
intValue = enchantment.getMaxLevel();
|
||||
}
|
||||
|
||||
@@ -151,8 +148,7 @@
|
||||
+ if (removeItalics) {
|
||||
+ component = component.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false);
|
||||
+ }
|
||||
+ itemStack.set(DataComponents.CUSTOM_NAME, io.papermc.paper.adventure.PaperAdventure.asVanilla(component));
|
||||
+ }
|
||||
+ itemStack.set(DataComponents.CUSTOM_NAME, + }
|
||||
+ else
|
||||
+ // Purpur end - Allow anvil colors
|
||||
itemStack.set(DataComponents.CUSTOM_NAME, Component.literal(this.itemName));
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
+ }
|
||||
+ // Purpur end - Enchantment Table Persists Lapis
|
||||
};
|
||||
// Paper end - Add missing InventoryHolders
|
||||
this.access = access;
|
||||
@@ -83,6 +_,16 @@
|
||||
return EnchantmentMenu.EMPTY_SLOT_LAPIS_LAZULI;
|
||||
|
||||
@@ -6,13 +6,11 @@
|
||||
access.execute((level, blockPos) -> {
|
||||
+ ItemStack itemstack = activeQuickItem == null ? stack : activeQuickItem; // Purpur - Grindstone API
|
||||
if (level instanceof ServerLevel) {
|
||||
// Paper start - Fire BlockExpEvent on grindstone use
|
||||
org.bukkit.event.block.BlockExpEvent event = new org.bukkit.event.block.BlockExpEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, blockPos), this.getExperienceAmount(level));
|
||||
event.callEvent();
|
||||
- ExperienceOrb.award((ServerLevel) level, Vec3.atCenterOf(blockPos), event.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, player);
|
||||
+ org.purpurmc.purpur.event.inventory.GrindstoneTakeResultEvent grindstoneTakeResultEvent = new org.purpurmc.purpur.event.inventory.GrindstoneTakeResultEvent(player.getBukkitEntity(), getBukkitView(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), event.getExpToDrop()); grindstoneTakeResultEvent.callEvent(); // Purpur - Grindstone API
|
||||
+ ExperienceOrb.award((ServerLevel) level, Vec3.atCenterOf(blockPos), grindstoneTakeResultEvent.getExperienceAmount(), org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, player); // Purpur - Grindstone API
|
||||
// Paper end - Fire BlockExpEvent on grindstone use
|
||||
}
|
||||
|
||||
@@ -124,7 +_,7 @@
|
||||
|
||||
@@ -12,12 +12,10 @@
|
||||
+ org.purpurmc.purpur.tool.Actionable actionable = optional.get(); // Purpur - Tool actionable options
|
||||
+ BlockState state = actionable.into().withPropertiesOf(level.getBlockState(clickedPos)); // Purpur - Tool actionable options
|
||||
ItemStack itemInHand = context.getItemInHand();
|
||||
// Paper start - EntityChangeBlockEvent
|
||||
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, clickedPos, optional.get())) {
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, clickedPos, state)) { // Purpur - Tool actionable options
|
||||
return InteractionResult.PASS;
|
||||
}
|
||||
// Paper end
|
||||
@@ -76,8 +_,15 @@
|
||||
CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, clickedPos, itemInHand);
|
||||
}
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
@@ -24,7 +_,7 @@
|
||||
public InteractionResult use(Level level, Player player, InteractionHand hand) {
|
||||
ItemStack itemInHand = player.getItemInHand(hand);
|
||||
// Paper start
|
||||
- final Projectile.Delayed<ThrownEgg> thrownEgg = Projectile.spawnProjectileFromRotationDelayed(ThrownEgg::new, (ServerLevel) level, itemInHand, player, 0.0F, EggItem.PROJECTILE_SHOOT_POWER, 1.0F);
|
||||
+ final Projectile.Delayed<ThrownEgg> thrownEgg = Projectile.spawnProjectileFromRotationDelayed(ThrownEgg::new, (ServerLevel) level, itemInHand, player, 0.0F, EggItem.PROJECTILE_SHOOT_POWER, (float) level.purpurConfig.eggProjectileOffset); // Purpur - Projectile offset config
|
||||
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) thrownEgg.projectile().getBukkitEntity());
|
||||
if (event.callEvent() && thrownEgg.attemptSpawn()) {
|
||||
if (event.shouldConsume()) {
|
||||
|
||||
@@ -8,4 +8,3 @@
|
||||
+ if (!level.purpurConfig.endCrystalPlaceAnywhere && !blockState.is(Blocks.OBSIDIAN) && !blockState.is(Blocks.BEDROCK)) { // Purpur - place end crystal on any block
|
||||
return InteractionResult.FAIL;
|
||||
} else {
|
||||
BlockPos blockPos = clickedPos.above(); final BlockPos aboveBlockPos = blockPos; // Paper - OBFHELPER
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
@@ -24,7 +_,7 @@
|
||||
if (level instanceof ServerLevel serverLevel) {
|
||||
// CraftBukkit start
|
||||
// Paper start - PlayerLaunchProjectileEvent
|
||||
- final Projectile.Delayed<ThrownEnderpearl> thrownEnderpearl = Projectile.spawnProjectileFromRotationDelayed(ThrownEnderpearl::new, serverLevel, itemInHand, player, 0.0F, EnderpearlItem.PROJECTILE_SHOOT_POWER, 1.0F);
|
||||
+ final Projectile.Delayed<ThrownEnderpearl> thrownEnderpearl = Projectile.spawnProjectileFromRotationDelayed(ThrownEnderpearl::new, serverLevel, itemInHand, player, 0.0F, EnderpearlItem.PROJECTILE_SHOOT_POWER, (float) serverLevel.purpurConfig.enderPearlProjectileOffset); // Purpur - Projectile offset config
|
||||
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) thrownEnderpearl.projectile().getBukkitEntity());
|
||||
if (event.callEvent() && thrownEnderpearl.attemptSpawn()) {
|
||||
if (event.shouldConsume()) {
|
||||
@@ -44,6 +_,7 @@
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
@@ -24,6 +_,7 @@
|
||||
|
||||
LivingEntity newEntity = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getEntity()).getHandle();
|
||||
newEntity.setCustomName(event.getName() != null ? io.papermc.paper.adventure.PaperAdventure.asVanilla(event.getName()) : null);
|
||||
+ if (player.level().purpurConfig.armorstandFixNametags && target instanceof net.minecraft.world.entity.decoration.ArmorStand) target.setCustomNameVisible(true); // Purpur - Set name visible when using a Name Tag on an Armor Stand
|
||||
newEntity.setCustomName(event.getName() != null ? + if (player.level().purpurConfig.armorstandFixNametags && target instanceof net.minecraft.world.entity.decoration.ArmorStand) target.setCustomNameVisible(true); // Purpur - Set name visible when using a Name Tag on an Armor Stand
|
||||
if (event.isPersistent() && newEntity instanceof Mob mob) {
|
||||
// Paper end - Add PlayerNameEntityEvent
|
||||
mob.setPersistenceRequired();
|
||||
|
||||
@@ -3,15 +3,11 @@
|
||||
@@ -46,9 +_,12 @@
|
||||
BlockState blockState1 = FLATTENABLES.get(blockState.getBlock());
|
||||
BlockState blockState2 = null;
|
||||
Runnable afterAction = null; // Paper
|
||||
+ org.purpurmc.purpur.tool.Flattenable flattenable = level.purpurConfig.shovelFlattenables.get(blockState.getBlock()); // Purpur - Tool actionable options
|
||||
if (blockState1 != null && level.getBlockState(clickedPos.above()).isAir()) {
|
||||
- afterAction = () -> level.playSound(player, clickedPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); // Paper
|
||||
- blockState2 = blockState1;
|
||||
+ // Purpur start - Tool actionable options
|
||||
+ afterAction = () -> {if (!FLATTENABLES.containsKey(blockState.getBlock())) level.playSound(player, clickedPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F);}; // Paper
|
||||
+ blockState2 = flattenable.into().defaultBlockState();
|
||||
+ // Purpur end - Tool actionable options
|
||||
} else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) {
|
||||
afterAction = () -> { // Paper
|
||||
if (!level.isClientSide()) {
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
@@ -26,7 +_,7 @@
|
||||
// CraftBukkit start - moved down
|
||||
if (level instanceof ServerLevel serverLevel) {
|
||||
// Paper start - PlayerLaunchProjectileEvent
|
||||
- final Projectile.Delayed<Snowball> snowball = Projectile.spawnProjectileFromRotationDelayed(Snowball::new, serverLevel, itemInHand, player, 0.0F, SnowballItem.PROJECTILE_SHOOT_POWER, 1.0F);
|
||||
+ final Projectile.Delayed<Snowball> snowball = Projectile.spawnProjectileFromRotationDelayed(Snowball::new, serverLevel, itemInHand, player, 0.0F, SnowballItem.PROJECTILE_SHOOT_POWER, (float) serverLevel.purpurConfig.snowballProjectileOffset); // Purpur - Projectile offset config
|
||||
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) snowball.projectile().getBukkitEntity());
|
||||
if (event.callEvent() && snowball.attemptSpawn()) {
|
||||
player.awardStat(Stats.ITEM_USED.get(this));
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
+++ b/net/minecraft/world/item/SpawnEggItem.java
|
||||
@@ -57,6 +_,23 @@
|
||||
if (level.getBlockEntity(clickedPos) instanceof Spawner spawner) {
|
||||
if (level.paperConfig().entities.spawning.disableMobSpawnerSpawnEggTransformation) return InteractionResult.FAIL; // Paper - Allow disabling mob spawner spawn egg transformation
|
||||
EntityType<?> type = this.getType(level.registryAccess(), itemInHand);
|
||||
+ // Purpur start - PlayerSetSpawnerTypeWithEggEvent
|
||||
+ if (spawner instanceof net.minecraft.world.level.block.entity.SpawnerBlockEntity) {
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
@@ -24,7 +_,7 @@
|
||||
ItemStack itemInHand = player.getItemInHand(hand);
|
||||
if (level instanceof ServerLevel serverLevel) {
|
||||
// Paper start - PlayerLaunchProjectileEvent
|
||||
- final Projectile.Delayed<AbstractThrownPotion> thrownPotion = Projectile.spawnProjectileFromRotationDelayed(this::createPotion, serverLevel, itemInHand, player, -20.0F, PROJECTILE_SHOOT_POWER, 1.0F);
|
||||
+ final Projectile.Delayed<AbstractThrownPotion> thrownPotion = Projectile.spawnProjectileFromRotationDelayed(this::createPotion, serverLevel, itemInHand, player, -20.0F, PROJECTILE_SHOOT_POWER, (float) serverLevel.purpurConfig.throwablePotionProjectileOffset); // Purpur - Projectile offset config
|
||||
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) thrownPotion.projectile().getBukkitEntity());
|
||||
if (event.callEvent() && thrownPotion.attemptSpawn()) {
|
||||
if (event.shouldConsume()) {
|
||||
|
||||
@@ -2,18 +2,12 @@
|
||||
+++ b/net/minecraft/world/item/TridentItem.java
|
||||
@@ -83,7 +_,7 @@
|
||||
if (tridentSpinAttackStrength == 0.0F) {
|
||||
ItemStack itemStack = stack.copyWithCount(1); // Paper
|
||||
Projectile.Delayed<ThrownTrident> tridentDelayed = Projectile.spawnProjectileFromRotationDelayed( // Paper - PlayerLaunchProjectileEvent(
|
||||
- ThrownTrident::new, serverLevel, itemStack, player, 0.0F, 2.5F, 1.0F
|
||||
+ ThrownTrident::new, serverLevel, itemStack, player, 0.0F, 2.5F, (float) serverLevel.purpurConfig.tridentProjectileOffset // Purpur - Projectile offset config
|
||||
);
|
||||
// Paper start - PlayerLaunchProjectileEvent
|
||||
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), (org.bukkit.entity.Projectile) tridentDelayed.projectile().getBukkitEntity());
|
||||
@@ -94,6 +_,7 @@
|
||||
return false;
|
||||
}
|
||||
ThrownTrident thrownTrident = tridentDelayed.projectile(); // Paper - PlayerLaunchProjectileEvent
|
||||
+ thrownTrident.setActualEnchantments(stack.getEnchantments()); // Purpur - Add an option to fix MC-3304 projectile looting
|
||||
if (event.shouldConsume()) {
|
||||
stack.hurtWithoutBreaking(1, player); // Paper - PlayerLaunchProjectileEvent
|
||||
}
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
@@ -32,7 +_,7 @@
|
||||
private static final java.util.Comparator<Holder<Enchantment>> ENCHANTMENT_ORDER = java.util.Comparator.comparing(Holder::getRegisteredName);
|
||||
public static final ItemEnchantments EMPTY = new ItemEnchantments(new it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<>(ENCHANTMENT_ORDER));
|
||||
// Paper end - sort enchantments
|
||||
- private static final Codec<Integer> LEVEL_CODEC = Codec.intRange(1, 255);
|
||||
+ private static final Codec<Integer> LEVEL_CODEC = Codec.intRange(1, (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels ? 255 : 32767)); // Purpur - Add toggle for enchant level clamping
|
||||
public static final Codec<ItemEnchantments> CODEC = Codec.unboundedMap(Enchantment.CODEC, LEVEL_CODEC)
|
||||
.xmap(
|
||||
map -> new net.minecraft.world.item.enchantment.ItemEnchantments(net.minecraft.Util.make(new it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<>(ENCHANTMENT_ORDER), m -> m.putAll(map))), // Paper - sort enchantments
|
||||
@@ -50,7 +_,7 @@
|
||||
|
||||
for (Entry<Holder<Enchantment>> entry : enchantments.object2IntEntrySet()) {
|
||||
|
||||
@@ -4,12 +4,10 @@
|
||||
}
|
||||
|
||||
public void updateDemand() {
|
||||
- this.demand = Math.max(0, this.demand + this.uses - (this.maxUses - this.uses)); // Paper - Fix MC-163962
|
||||
+ // Purpur start - Configurable minimum demand for trades
|
||||
+ this.updateDemand(0);
|
||||
+ }
|
||||
+ public void updateDemand(int minimumDemand) {
|
||||
+ this.demand = Math.max(minimumDemand, this.demand + this.uses - (this.maxUses - this.uses)); // Paper - Fix MC-163962
|
||||
+ // Purpur end - Configurable minimum demand for trades
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,5 @@
|
||||
|
||||
public boolean isNearPlayer(Level level, BlockPos pos) {
|
||||
+ if (level.purpurConfig.spawnerDeactivateByRedstone && level.hasNeighborSignal(pos)) return false; // Purpur - Redstone deactivates spawners
|
||||
return level.hasNearbyAlivePlayerThatAffectsSpawning(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, this.requiredPlayerRange); // Paper - Affects Spawning API
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,10 @@
|
||||
+++ b/net/minecraft/world/level/Level.java
|
||||
@@ -158,11 +_,55 @@
|
||||
}
|
||||
// Paper end - add paper world config
|
||||
|
||||
+ public final org.purpurmc.purpur.PurpurWorldConfig purpurConfig; // Purpur - Purpur config files
|
||||
public static @Nullable BlockPos lastPhysicsProblem; // Spigot
|
||||
private int tileTickPosition;
|
||||
public final Map<ServerExplosion.CacheKey, Float> explosionDensityCache = new java.util.HashMap<>(); // Paper - Optimize explosions
|
||||
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Faster redstone torch rapid clock removal; Move from Map in BlockRedstoneTorch to here
|
||||
|
||||
+ // Purpur start - Add adjustable breeding cooldown to config
|
||||
+ private com.google.common.cache.Cache<BreedingCooldownPair, Object> playerBreedingCooldowns;
|
||||
@@ -59,7 +56,6 @@
|
||||
@@ -206,6 +_,8 @@
|
||||
) {
|
||||
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName()); // Spigot
|
||||
this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config
|
||||
+ this.purpurConfig = new org.purpurmc.purpur.PurpurWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName(), env); // Purpur - Purpur config files
|
||||
+ this.playerBreedingCooldowns = this.getNewBreedingCooldownCache(); // Purpur - Add adjustable breeding cooldown to config
|
||||
this.generator = gen;
|
||||
|
||||
@@ -8,4 +8,3 @@
|
||||
+ Player nearestPlayer = level.getNearestPlayer(d, y, d1, -1.0, level.purpurConfig.mobSpawningIgnoreCreativePlayers); // Purpur - mob spawning option to ignore creative players
|
||||
if (nearestPlayer != null) {
|
||||
double d2 = nearestPlayer.distanceToSqr(d, y, d1);
|
||||
if (level.isLoadedAndInBounds(mutableBlockPos) && isRightDistanceToPlayerAndSpawnPoint(level, chunk, mutableBlockPos, d2)) { // Paper - don't load chunks for mob spawn
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
+ if (level.purpurConfig.bedExplode) level.explode(null, level.damageSources().badRespawnPointExplosion(center), null, center, (float) level.purpurConfig.bedExplosionPower, level.purpurConfig.bedExplosionFire, level.purpurConfig.bedExplosionEffect); // Purpur - Implement bed explosion options
|
||||
return InteractionResult.SUCCESS_SERVER;
|
||||
} else if (state.getValue(OCCUPIED)) {
|
||||
if (!BedBlock.canSetSpawn(level)) return this.explodeBed(state, level, pos); // Paper - check explode first
|
||||
@@ -146,7 +_,7 @@
|
||||
}
|
||||
|
||||
|
||||
@@ -8,18 +8,13 @@
|
||||
+ public float fallDamageMultiplier = 1.0F;
|
||||
+ public float fallDistanceMultiplier = 1.0F;
|
||||
+ // Purpur end - Configurable block fall damage modifiers
|
||||
// Paper start - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
public final boolean isDestroyable() {
|
||||
return io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits ||
|
||||
@@ -345,7 +_,7 @@
|
||||
event.setExpToDrop(block.getExpDrop(state, serverLevel, pos, net.minecraft.world.item.ItemStack.EMPTY, true)); // Paper - Properly handle xp dropping
|
||||
return @@ -345,7 +_,7 @@
|
||||
event.callEvent();
|
||||
for (org.bukkit.inventory.ItemStack drop : event.getDrops()) {
|
||||
- popResource(serverLevel, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop));
|
||||
+ popResource(serverLevel, pos, applyLoreFromTile(org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop), blockEntity)); // Purpur - Persistent BlockEntity Lore and DisplayName
|
||||
}
|
||||
state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY, false); // Paper - Properly handle xp dropping
|
||||
block.popExperience(serverLevel, pos, event.getExpToDrop()); // Paper - Properly handle xp dropping
|
||||
@@ -363,7 +_,7 @@
|
||||
|
||||
public static void dropResources(BlockState state, LevelAccessor level, BlockPos pos, @Nullable BlockEntity blockEntity) {
|
||||
@@ -31,11 +26,9 @@
|
||||
}
|
||||
@@ -375,11 +_,30 @@
|
||||
public static void dropResources(BlockState state, Level level, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool, boolean dropExperience) {
|
||||
// Paper end - Properly handle xp dropping
|
||||
if (level instanceof ServerLevel) {
|
||||
- getDrops(state, (ServerLevel)level, pos, blockEntity, entity, tool).forEach(stack -> popResource(level, pos, stack));
|
||||
+ getDrops(state, (ServerLevel)level, pos, blockEntity, entity, tool).forEach(stack -> popResource(level, pos, applyLoreFromTile(stack, blockEntity))); // Purpur - Persistent BlockEntity Lore and DisplayName
|
||||
state.spawnAfterBreak((ServerLevel)level, pos, tool, dropExperience); // Paper - Properly handle xp dropping
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
+ cactusHeight++;
|
||||
+ }
|
||||
+
|
||||
+ return cactusHeight < ((Level) world).paperConfig().maxGrowthHeight.cactus;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
@@ -47,7 +46,6 @@
|
||||
+ while (world.getBlockState(pos.below(cactusHeight)).is(this)) {
|
||||
+ cactusHeight++;
|
||||
+ }
|
||||
+ for (int i = 0; i <= world.paperConfig().maxGrowthHeight.cactus - cactusHeight; i++) {
|
||||
+ world.setBlockAndUpdate(pos.above(i), state.setValue(CactusBlock.AGE, 0));
|
||||
+ }
|
||||
+ }
|
||||
|
||||
@@ -31,6 +31,4 @@
|
||||
+ ironGolem.setSummoner(placer == null ? null : placer.getUUID());
|
||||
+ }
|
||||
+ // Purpur end - Summoner API
|
||||
// clearPatternBlocks(level, patternMatch); // Paper - moved down
|
||||
golem.snapTo(pos.getX() + 0.5, pos.getY() + 0.05, pos.getZ() + 0.5, 0.0F, 0.0F);
|
||||
// Paper start
|
||||
|
||||
@@ -6,11 +6,9 @@
|
||||
if (levelValue < 8 && COMPOSTABLES.containsKey(stack.getItem())) {
|
||||
- if (levelValue < 7 && !level.isClientSide) {
|
||||
- BlockState blockState = addItem(player, state, level, pos, stack);
|
||||
- // Paper start - handle cancelled events
|
||||
- if (blockState == null) {
|
||||
- return InteractionResult.PASS;
|
||||
- }
|
||||
- // Paper end
|
||||
- level.levelEvent(1500, pos, state != blockState ? 1 : 0);
|
||||
- player.awardStat(Stats.ITEM_USED.get(stack.getItem()));
|
||||
- stack.consume(1, player);
|
||||
@@ -47,11 +45,9 @@
|
||||
+ private static @Nullable BlockState process(int levelValue, Player player, BlockState state, Level level, BlockPos pos, ItemStack stack) {
|
||||
+ if (levelValue < 7 && !level.isClientSide) {
|
||||
+ BlockState iblockdata1 = ComposterBlock.addItem(player, state, level, pos, stack);
|
||||
+ // Paper start - handle cancelled events
|
||||
+ if (iblockdata1 == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
+ level.levelEvent(1500, pos, state != iblockdata1 ? 1 : 0);
|
||||
+ player.awardStat(Stats.ITEM_USED.get(stack.getItem()));
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
@@ -169,7 +_,7 @@
|
||||
@Override
|
||||
protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) {
|
||||
if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent
|
||||
- if (level instanceof ServerLevel serverLevel && entity instanceof Ravager && org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit
|
||||
if (!new - if (level instanceof ServerLevel serverLevel && entity instanceof Ravager && org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit
|
||||
+ if (level instanceof ServerLevel serverLevel && entity instanceof Ravager && serverLevel.purpurConfig.ravagerGriefableBlocks.contains(serverLevel.getBlockState(pos).getBlock()) && org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit // Purpur - Configurable ravager griefable blocks list
|
||||
serverLevel.destroyBlock(pos, true, entity);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,5 @@
|
||||
|
||||
- return false;
|
||||
+ return ((ServerLevel) level).purpurConfig.farmlandGetsMoistFromBelow && level.getFluidState(pos.relative(Direction.DOWN)).is(FluidTags.WATER); // Purpur - Allow soil to moisten from water directly under it
|
||||
// Paper end - Perf: remove abstract block iteration
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
+++ b/net/minecraft/world/level/block/IceBlock.java
|
||||
@@ -40,7 +_,7 @@
|
||||
public void afterDestroy(Level level, BlockPos pos, ItemStack stack) {
|
||||
// Paper end - Improve Block#breakNaturally API
|
||||
if (!EnchantmentHelper.hasTag(stack, EnchantmentTags.PREVENTS_ICE_MELTING)) {
|
||||
- if (level.dimensionType().ultraWarm()) {
|
||||
+ if (level.isNether() || (level.isTheEnd() && !org.purpurmc.purpur.PurpurConfig.allowWaterPlacementInTheEnd)) { // Purpur - Add allow water in end world option
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||
- if (this.shouldSpreadLiquid(level, pos, state)) {
|
||||
+ if (level.purpurConfig.tickFluids && this.shouldSpreadLiquid(level, pos, state)) { // Purpur - Tick fluids config
|
||||
level.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(level, pos)); // Paper - Configurable speed for water flowing over lava
|
||||
}
|
||||
}
|
||||
@@ -169,7 +_,7 @@
|
||||
@@ -24,6 +23,5 @@
|
||||
protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) {
|
||||
- if (this.shouldSpreadLiquid(level, pos, state)) {
|
||||
+ if (level.purpurConfig.tickFluids && this.shouldSpreadLiquid(level, pos, state)) { // Purpur - Tick fluids config
|
||||
level.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(level, pos)); // Paper - Configurable speed for water flowing over lava
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,16 +18,14 @@
|
||||
+ }
|
||||
+
|
||||
+ if (type.isPresent()) {
|
||||
+ final net.kyori.adventure.text.Component mobName = io.papermc.paper.adventure.PaperAdventure.asAdventure(type.get().getDescription());
|
||||
+
|
||||
+ final net.kyori.adventure.text.Component mobName = +
|
||||
+ String name = level.purpurConfig.silkTouchSpawnerName;
|
||||
+ if (name != null && !name.isEmpty() && !name.equals("Monster Spawner")) {
|
||||
+ net.kyori.adventure.text.Component displayName = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(name, net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.component("mob", mobName));
|
||||
+ if (name.startsWith("<reset>")) {
|
||||
+ displayName = displayName.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false);
|
||||
+ }
|
||||
+ item.set(net.minecraft.core.component.DataComponents.CUSTOM_NAME, io.papermc.paper.adventure.PaperAdventure.asVanilla(displayName));
|
||||
+ }
|
||||
+ item.set(net.minecraft.core.component.DataComponents.CUSTOM_NAME, + }
|
||||
+
|
||||
+ java.util.List<String> lore = level.purpurConfig.silkTouchSpawnerLore;
|
||||
+ if (lore != null && !lore.isEmpty()) {
|
||||
@@ -38,8 +36,7 @@
|
||||
+ if (line.startsWith("<reset>")) {
|
||||
+ lineComponent = lineComponent.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false);
|
||||
+ }
|
||||
+ loreComponentList.add(io.papermc.paper.adventure.PaperAdventure.asVanilla(lineComponent));
|
||||
+ }
|
||||
+ loreComponentList.add(+ }
|
||||
+
|
||||
+ item.set(net.minecraft.core.component.DataComponents.LORE, new net.minecraft.world.item.component.ItemLore(loreComponentList, loreComponentList));
|
||||
+ }
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
+ reedHeight++;
|
||||
+ }
|
||||
+
|
||||
+ return reedHeight < ((net.minecraft.world.level.Level) world).paperConfig().maxGrowthHeight.reeds;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
@@ -38,7 +37,6 @@
|
||||
+ while (world.getBlockState(pos.below(reedHeight)).is(this)) {
|
||||
+ reedHeight++;
|
||||
+ }
|
||||
+ for (int i = 0; i <= world.paperConfig().maxGrowthHeight.reeds - reedHeight; i++) {
|
||||
+ world.setBlockAndUpdate(pos.above(i), state.setValue(SugarCaneBlock.AGE, 0));
|
||||
+ }
|
||||
+ }
|
||||
|
||||
@@ -39,6 +39,5 @@
|
||||
|
||||
- if (blockEntity.levels > 0 && !blockEntity.beamSections.isEmpty()) {
|
||||
+ if (blockEntity.levels > 0 && (!blockEntity.beamSections.isEmpty() || (level.purpurConfig.beaconAllowEffectsWithTintedGlass && isTintedGlass))) { // Purpur - allow beacon effects when covered by tinted glass
|
||||
applyEffects(level, pos, blockEntity.levels, blockEntity.primaryPower, blockEntity.secondaryPower, blockEntity); // Paper - Custom beacon ranges
|
||||
playSound(level, pos, SoundEvents.BEACON_AMBIENT);
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
+ }
|
||||
+ // Purpur end - Stored Bee API
|
||||
+
|
||||
// Paper start - Add EntityBlockStorage clearEntities
|
||||
public void clearBees() {
|
||||
this.stored.clear();
|
||||
@@ -389,8 +_,8 @@
|
||||
@@ -51,6 +50,5 @@
|
||||
- private final BeehiveBlockEntity.Occupant occupant;
|
||||
+ public static class BeeData { // Purpur - make public - Stored Bee API
|
||||
+ public final BeehiveBlockEntity.Occupant occupant; // Purpur - make public - Stored Bee API
|
||||
private int exitTickCounter; // Paper - Fix bees aging inside hives; separate counter for checking if bee should exit to reduce exit attempts
|
||||
private int ticksInHive;
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
@@ -104,6 +_,10 @@
|
||||
this.persistentDataContainer.putAll((CompoundTag) persistentDataTag);
|
||||
}
|
||||
// Paper end - read persistent data container
|
||||
+
|
||||
+
|
||||
+ this.persistentLore = tag.read("Purpur.persistentLore", net.minecraft.world.item.component.ItemLore.CODEC).orElse(null); // Purpur - Persistent BlockEntity Lore and DisplayName
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
+ if (player.hasPermission("purpur.sign.style")) line = line.replaceAll("(?i)&([l-or])", "\u00a7$1");
|
||||
+ if (player.hasPermission("purpur.sign.magic")) line = line.replaceAll("(?i)&([kr])", "\u00a7$1");
|
||||
+
|
||||
+ return io.papermc.paper.adventure.PaperAdventure.asVanilla(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(line));
|
||||
+ } else {
|
||||
+ return + } else {
|
||||
+ return Component.literal(line).setStyle(style);
|
||||
+ }
|
||||
+ }
|
||||
@@ -26,18 +25,13 @@
|
||||
+
|
||||
+ org.bukkit.entity.Player craftPlayer = (org.bukkit.craftbukkit.entity.CraftPlayer) player.getBukkitEntity(); // Purpur - Signs allow color codes
|
||||
if (player.isTextFilteringEnabled()) {
|
||||
- text = text.setMessage(i, Component.literal(net.minecraft.util.StringUtil.filterText(filteredText1.filteredOrEmpty())).setStyle(style)); // Paper - filter sign text to chat only
|
||||
+ text = text.setMessage(i, translateColors(craftPlayer, net.minecraft.util.StringUtil.filterText(filteredText1.filteredOrEmpty()), style)); // Paper - filter sign text to chat only // Purpur - Signs allow color codes
|
||||
} else {
|
||||
text = text.setMessage(
|
||||
- i, Component.literal(filteredText1.raw()).setStyle(style), Component.literal(net.minecraft.util.StringUtil.filterText(filteredText1.filteredOrEmpty())).setStyle(style) // Paper - filter sign text to chat only
|
||||
+ i, translateColors(craftPlayer, net.minecraft.util.StringUtil.filterText(filteredText1.raw()), style), translateColors(craftPlayer, net.minecraft.util.StringUtil.filterText(filteredText1.filteredOrEmpty()), style) // Paper - filter sign text to chat only // Purpur - Signs allow color codes
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -297,6 +_,26 @@
|
||||
// CraftBukkit - this
|
||||
return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel)level, 2, string, component, level.getServer(), player); // Paper - Fix commands from signs not firing command events
|
||||
}
|
||||
+
|
||||
+ // Purpur start - Signs allow color codes
|
||||
@@ -47,8 +41,7 @@
|
||||
+ final Component[] lines = front ? frontText.getMessages(filtered) : backText.getMessages(filtered);
|
||||
+ final String side = front ? "front_text" : "back_text";
|
||||
+ for (int i = 0; i < 4; i++) {
|
||||
+ final var component = io.papermc.paper.adventure.PaperAdventure.asAdventure(lines[i]);
|
||||
+ final String line = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacyAmpersand().serialize(component);
|
||||
+ final var component = + final String line = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacyAmpersand().serialize(component);
|
||||
+ final var text = net.kyori.adventure.text.Component.text(line);
|
||||
+ final String json = net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().serialize(text);
|
||||
+ final CompoundTag sideNbt = nbt.getCompoundOrEmpty(side);
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
+++ b/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
@@ -49,7 +_,7 @@
|
||||
|
||||
// Paper start
|
||||
private static void printOversizedLog(String msg, Path file, int x, int z) {
|
||||
- org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO PAPER - You may ask for help on Discord, but do not file an issue. These error messages can not be removed.");
|
||||
- org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO SPIGOT - You may ask for help on Discord, but do not file an issue. These error messages can not be removed.");
|
||||
+ org.apache.logging.log4j.LogManager.getLogger().fatal(msg + " (" + file.toString().replaceAll(".+[\\\\/]", "") + " - " + x + "," + z + ") Go clean it up to remove this message. /minecraft:tp " + (x<<4)+" 128 "+(z<<4) + " - DO NOT REPORT THIS TO PURPUR - You may ask for help on Discord, but do not file an issue. These error messages can not be removed."); // Purpur - Rebrand
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
--- a/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
+++ b/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
@@ -38,13 +_,13 @@
|
||||
int spawnAttemptMaxSeconds = level.paperConfig().entities.behavior.phantomsSpawnAttemptMaxSeconds;
|
||||
this.nextTick += (spawnAttemptMinSeconds + randomSource.nextInt(spawnAttemptMaxSeconds - spawnAttemptMinSeconds + 1)) * 20;
|
||||
// Paper end - Ability to control player's insomnia and phantoms
|
||||
- if (level.getSkyDarken() >= 5 || !level.dimensionType().hasSkyLight()) {
|
||||
+ if (level.getSkyDarken() >= level.purpurConfig.phantomSpawnMinSkyDarkness || !level.dimensionType().hasSkyLight()) { // Purpur - Add phantom spawning options
|
||||
for (ServerPlayer serverPlayer : level.players()) {
|
||||
if (!serverPlayer.isSpectator() && (!level.paperConfig().entities.behavior.phantomsDoNotSpawnOnCreativePlayers || !serverPlayer.isCreative())) { // Paper - Add phantom creative and insomniac controls
|
||||
BlockPos blockPos = serverPlayer.blockPosition();
|
||||
- if (!level.dimensionType().hasSkyLight() || blockPos.getY() >= level.getSeaLevel() && level.canSeeSky(blockPos)) {
|
||||
+ if (!level.dimensionType().hasSkyLight() || (!level.purpurConfig.phantomSpawnOnlyAboveSeaLevel || blockPos.getY() >= level.getSeaLevel()) && (!level.purpurConfig.phantomSpawnOnlyWithVisibleSky || level.canSeeSky(blockPos))) { // Purpur - Add phantom spawning options
|
||||
@@ -25,4 +22,3 @@
|
||||
+ int i2 = level.purpurConfig.phantomSpawnMinPerAttempt + randomSource.nextInt((level.purpurConfig.phantomSpawnMaxPerAttempt < 0 ? currentDifficultyAt.getDifficulty().getId() : level.purpurConfig.phantomSpawnMaxPerAttempt - level.purpurConfig.phantomSpawnMinPerAttempt) + 1); // Purpur - Add phantom spawning options
|
||||
|
||||
for (int i3 = 0; i3 < i2; i3++) {
|
||||
// Paper start - PhantomPreSpawnEvent
|
||||
|
||||
@@ -11,6 +11,5 @@
|
||||
+ }
|
||||
+ // Purpur end - Implement infinite liquids
|
||||
+
|
||||
// Paper start - Add BlockBreakBlockEvent
|
||||
@Override
|
||||
protected void beforeDestroyingBlock(LevelAccessor level, BlockPos pos, BlockState state, BlockPos source) {
|
||||
|
||||
Reference in New Issue
Block a user