3 more patches

This commit is contained in:
Ben Kerllenevich
2021-06-17 08:56:42 -04:00
parent 95510fad10
commit 8cdbb4d898
7 changed files with 628 additions and 1 deletions

View File

@@ -1,7 +1,7 @@
plugins {
java
id("com.github.johnrengelman.shadow") version "7.0.0" apply false
id("io.papermc.paperweight.patcher") version "1.0.4-SNAPSHOT"
id("io.papermc.paperweight.patcher") version "1.1.0-SNAPSHOT"
}
repositories {

View File

@@ -0,0 +1,333 @@
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/boss/enderdragon/EndCrystal.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
index b643a2449e329560c936c0a06fb4cc494d0737a7..c90c46e08bb3d664465b01616ae80c133bc3f733 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
@@ -14,6 +14,7 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
+import net.minecraft.world.entity.monster.Phantom;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.BlockGetter;
@@ -32,6 +33,12 @@ public class EndCrystal extends Entity {
private static final EntityDataAccessor<Boolean> DATA_SHOW_BOTTOM = SynchedEntityData.defineId(EndCrystal.class, EntityDataSerializers.BOOLEAN);
public int time;
public boolean generatedByDragonFight = false; // Paper - Fix invulnerable end crystals
+ // Purpur start
+ private Phantom targetPhantom;
+ private int phantomBeamTicks = 0;
+ private int phantomDamageCooldown = 0;
+ private int idleCooldown = 0;
+ // Purpur end
public EndCrystal(EntityType<? extends EndCrystal> type, Level world) {
super(type, world);
@@ -81,7 +88,50 @@ public class EndCrystal extends Entity {
// Paper end
}
+ // Purpur start
+ if (level.purpurConfig.phantomAttackedByCrystalRadius <= 0 || --idleCooldown > 0) {
+ return; // on cooldown
+ }
+
+ if (targetPhantom == null) {
+ for (Phantom phantom : level.getEntitiesOfClass(Phantom.class, getBoundingBox().inflate(level.purpurConfig.phantomAttackedByCrystalRadius))) {
+ if (phantom.hasLineOfSight(this)) {
+ attackPhantom(phantom);
+ break;
+ }
+ }
+ } else {
+ setBeamTarget(new BlockPos(targetPhantom).offset(0, -2, 0));
+ if (--phantomBeamTicks > 0 && targetPhantom.isAlive()) {
+ phantomDamageCooldown--;
+ if (targetPhantom.hasLineOfSight(this)) {
+ if (phantomDamageCooldown <= 0) {
+ phantomDamageCooldown = 20;
+ targetPhantom.hurt(DamageSource.indirectMagic(this, this), level.purpurConfig.phantomAttackedByCrystalDamage);
+ }
+ } else {
+ forgetPhantom(); // no longer in sight
+ }
+ } else {
+ forgetPhantom(); // attacked long enough
+ }
+ }
+ }
+
+ private void attackPhantom(Phantom 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 addAdditionalSaveData(CompoundTag nbt) {
diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
index 1ffe939bb66358391d92d3e5378865b1cc8690fd..6058fb62baa388febc8e36cb680ab2ddcd1306f4 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
@@ -12,6 +12,7 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
+import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
@@ -36,10 +37,15 @@ import net.minecraft.world.entity.ai.control.MoveControl;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.ai.targeting.TargetingConditions;
import net.minecraft.world.entity.animal.Cat;
+import net.minecraft.world.entity.boss.enderdragon.EndCrystal;
import net.minecraft.world.entity.player.Player;
+import net.minecraft.world.item.ItemStack;
+import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.ServerLevelAccessor;
import net.minecraft.world.level.levelgen.Heightmap;
+import net.minecraft.world.level.storage.loot.LootContext;
+import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.Vec3;
public class Phantom extends FlyingMob implements Enemy {
@@ -50,6 +56,7 @@ public class Phantom extends FlyingMob implements Enemy {
Vec3 moveTargetPoint;
BlockPos anchorPoint;
Phantom.AttackPhase attackPhase;
+ Vec3 crystalPosition; // Purpur
public Phantom(EntityType<? extends Phantom> type, Level world) {
super(type, world);
@@ -73,12 +80,38 @@ public class Phantom extends FlyingMob implements Enemy {
@Override
protected void registerGoals() {
- this.goalSelector.addGoal(1, new Phantom.PhantomAttackStrategyGoal());
- this.goalSelector.addGoal(2, new Phantom.PhantomSweepAttackGoal());
- this.goalSelector.addGoal(3, new Phantom.PhantomCircleAroundAnchorGoal());
+ // Purpur start
+ if (level.purpurConfig.phantomOrbitCrystalRadius > 0) {
+ this.goalSelector.addGoal(1, new FindCrystalGoal(this));
+ this.goalSelector.addGoal(2, new OrbitCrystalGoal(this));
+ }
+ this.goalSelector.addGoal(3, new Phantom.PhantomAttackStrategyGoal());
+ this.goalSelector.addGoal(4, new Phantom.PhantomSweepAttackGoal());
+ this.goalSelector.addGoal(5, new Phantom.PhantomCircleAroundAnchorGoal());
this.targetSelector.addGoal(1, new Phantom.PhantomAttackPlayerTargetGoal());
+ // Purpur end
}
+ // Purpur start
+ @Override
+ protected LootContext.Builder createLootContext(boolean causedByPlayer, DamageSource source) {
+ boolean dropped = false;
+ if (lastHurtByPlayer == null && source.getEntity() instanceof EndCrystal) {
+ if (random.nextInt(5) < 1) {
+ dropped = spawnAtLocation(new ItemStack(Items.PHANTOM_MEMBRANE)) != null;
+ }
+ }
+ if (!dropped) {
+ return super.createLootContext(causedByPlayer, source);
+ }
+ return new LootContext.Builder((ServerLevel) level);
+ }
+
+ public boolean isCirclingCrystal() {
+ return crystalPosition != null;
+ }
+ // Purpur end
+
@Override
protected void defineSynchedData() {
super.defineSynchedData();
@@ -263,6 +296,124 @@ public class Phantom extends FlyingMob implements Enemy {
private AttackPhase() {}
}
+ // Purpur start
+ class FindCrystalGoal extends Goal {
+ private final Phantom phantom;
+ private EndCrystal crystal;
+ private Comparator<EndCrystal> comparator;
+
+ FindCrystalGoal(Phantom phantom) {
+ this.phantom = phantom;
+ this.comparator = Comparator.comparingDouble(phantom::distanceToSqr);
+ this.setFlags(EnumSet.of(Flag.LOOK));
+ }
+
+ @Override
+ public boolean shouldActivate() {
+ double range = maxTargetRange();
+ List<EndCrystal> crystals = level.getEntitiesOfClass(EndCrystal.class, phantom.getBoundingBox().inflate(range));
+ if (crystals.isEmpty()) {
+ return false;
+ }
+ crystals.sort(comparator);
+ crystal = crystals.get(0);
+ if (phantom.distanceToSqr(crystal) > range * range) {
+ crystal = null;
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean shouldStayActive() {
+ if (crystal == null || !crystal.isAlive()) {
+ return false;
+ }
+ double range = maxTargetRange();
+ return phantom.distanceToSqr(crystal) <= (range * range) * 2;
+ }
+
+ @Override
+ public void start() {
+ phantom.crystalPosition = new Vec3(crystal.getX(), crystal.getY() + (phantom.random.nextInt(10) + 10), crystal.getZ());
+ }
+
+ @Override
+ public void stop() {
+ crystal = null;
+ phantom.crystalPosition = null;
+ super.stop();
+ }
+
+ private double maxTargetRange() {
+ return phantom.level.purpurConfig.phantomOrbitCrystalRadius;
+ }
+ }
+
+ class OrbitCrystalGoal extends Goal {
+ private final Phantom phantom;
+ private float offset;
+ private float radius;
+ private float verticalChange;
+ private float direction;
+
+ OrbitCrystalGoal(Phantom phantom) {
+ this.phantom = phantom;
+ this.setFlags(EnumSet.of(Flag.MOVE));
+ }
+
+ @Override
+ public boolean shouldActivate() {
+ return phantom.isCirclingCrystal();
+ }
+
+ @Override
+ public void start() {
+ 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 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.moveTargetPoint.distanceToSqr(phantom.getX(), phantom.getY(), phantom.getZ()) < 4.0D) {
+ updateOffset();
+ }
+ if (phantom.moveTargetPoint.y < phantom.getY() && !phantom.level.isEmptyBlock(new BlockPos(phantom).below(1))) {
+ this.verticalChange = Math.max(1.0F, this.verticalChange);
+ updateOffset();
+ }
+ if (phantom.moveTargetPoint.y > phantom.getY() && !phantom.level.isEmptyBlock(new BlockPos(phantom).above(1))) {
+ this.verticalChange = Math.min(-1.0F, this.verticalChange);
+ updateOffset();
+ }
+ }
+
+ private void updateOffset() {
+ this.offset += this.direction * 15.0F * 0.017453292F;
+ phantom.moveTargetPoint = phantom.crystalPosition.add(
+ this.radius * Mth.cos(this.offset),
+ -4.0F + this.verticalChange,
+ this.radius * Mth.sin(this.offset));
+ }
+ }
+ // Purpur end
+
private class PhantomMoveControl extends MoveControl {
private float speed = 0.1F;
@@ -349,6 +500,7 @@ public class Phantom extends FlyingMob implements Enemy {
@Override
public boolean canUse() {
+ if (isCirclingCrystal()) return false;
LivingEntity entityliving = Phantom.this.getTarget();
return entityliving != null ? Phantom.this.canAttack(Phantom.this.getTarget(), TargetingConditions.DEFAULT) : false;
@@ -538,6 +690,7 @@ public class Phantom extends FlyingMob implements Enemy {
@Override
public boolean canUse() {
+ if (isCirclingCrystal()) return false;
if (this.nextScanTick > 0) {
--this.nextScanTick;
return false;
@@ -566,6 +719,7 @@ public class Phantom extends FlyingMob implements Enemy {
@Override
public boolean canContinueToUse() {
+ if (isCirclingCrystal()) return false;
LivingEntity entityliving = Phantom.this.getTarget();
return entityliving != null ? Phantom.this.canAttack(entityliving, TargetingConditions.DEFAULT) : false;
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index e39e1ff19f49b093ae27a98cba280ad2643df7a2..8985cc0ca2e5f1f673ef6ae59976095993332559 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -617,6 +617,9 @@ public class PurpurWorldConfig {
public float phantomFlameDamage = 1.0F;
public int phantomFlameFireTime = 8;
public boolean phantomAllowGriefing = false;
+ public double phantomAttackedByCrystalRadius = 0.0D;
+ public float phantomAttackedByCrystalDamage = 1.0F;
+ public double phantomOrbitCrystalRadius = 0.0D;
private void phantomSettings() {
phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable);
phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater);
@@ -624,6 +627,9 @@ public class PurpurWorldConfig {
phantomFlameDamage = (float) getDouble("mobs.phantom.flames.damage", phantomFlameDamage);
phantomFlameFireTime = getInt("mobs.phantom.flames.fire-time", phantomFlameFireTime);
phantomAllowGriefing = getBoolean("mobs.phantom.allow-griefing", phantomAllowGriefing);
+ 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 pigRidable = false;

View File

@@ -0,0 +1,232 @@
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/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
index 79504dc3448402e73b09c4232b1fd0488872cf68..5c7683058b79953aa4f7427d7654b7e4823dbf09 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
@@ -2,12 +2,15 @@ package net.minecraft.world.level.levelgen;
import java.util.Iterator;
import java.util.Random;
+
+import com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.MCUtil;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.stats.ServerStatsCounter;
+import net.minecraft.stats.Stat;
import net.minecraft.stats.Stats;
import net.minecraft.util.Mth;
import net.minecraft.world.DifficultyInstance;
@@ -23,84 +26,100 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.NaturalSpawner;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FluidState;
+import org.bukkit.event.entity.CreatureSpawnEvent;
public class PhantomSpawner implements CustomSpawner {
- private int nextTick;
+ private int spawnDelay; // Purpur
public PhantomSpawner() {}
@Override
public int tick(ServerLevel world, boolean spawnMonsters, boolean spawnAnimals) {
+ // Purpur start - rewrite entire thing
if (!spawnMonsters) {
return 0;
- } else if (!world.getGameRules().getBoolean(GameRules.RULE_DOINSOMNIA)) {
+ }
+
+ if (!world.getGameRules().getBoolean(GameRules.RULE_DOINSOMNIA)) {
+ return 0;
+ }
+
+ --this.spawnDelay;
+ if (this.spawnDelay > 0) {
return 0;
- } else {
- Random random = world.random;
-
- --this.nextTick;
- if (this.nextTick > 0) {
- return 0;
- } else {
- this.nextTick += (60 + random.nextInt(60)) * 20;
- if (world.getSkyDarken() < 5 && world.dimensionType().hasSkyLight()) {
- return 0;
- } else {
- int i = 0;
- Iterator iterator = world.players().iterator();
-
- while (iterator.hasNext()) {
- Player entityhuman = (Player) iterator.next();
-
- if (!entityhuman.isSpectator() && (!world.paperConfig.phantomIgnoreCreative || !entityhuman.isCreative())) { // Paper
- BlockPos blockposition = entityhuman.blockPosition();
-
- if (!world.dimensionType().hasSkyLight() || blockposition.getY() >= world.getSeaLevel() && world.canSeeSky(blockposition)) {
- DifficultyInstance difficultydamagescaler = world.getCurrentDifficultyAt(blockposition);
-
- if (difficultydamagescaler.isHarderThan(random.nextFloat() * 3.0F)) {
- ServerStatsCounter serverstatisticmanager = ((ServerPlayer) entityhuman).getStats();
- int j = Mth.clamp(serverstatisticmanager.getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE);
- boolean flag2 = true;
-
- if (random.nextInt(j) >= 72000) {
- BlockPos blockposition1 = blockposition.above(20 + random.nextInt(15)).east(-10 + random.nextInt(21)).south(-10 + random.nextInt(21));
- BlockState iblockdata = world.getBlockState(blockposition1);
- FluidState fluid = world.getFluidState(blockposition1);
-
- if (NaturalSpawner.isValidEmptySpawnBlock((BlockGetter) world, blockposition1, iblockdata, fluid, EntityType.PHANTOM)) {
- SpawnGroupData groupdataentity = null;
- int k = 1 + random.nextInt(difficultydamagescaler.getDifficulty().getId() + 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(world, blockposition1), ((ServerPlayer) entityhuman).getBukkitEntity(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL);
- if (!event.callEvent()) {
- if (event.shouldAbortSpawn()) {
- break;
- }
- continue;
- }
- // Paper end
- Phantom entityphantom = (Phantom) EntityType.PHANTOM.create((Level) world);
- entityphantom.setSpawningEntity(entityhuman.getUUID()); // Paper
- entityphantom.moveTo(blockposition1, 0.0F, 0.0F);
- groupdataentity = entityphantom.finalizeSpawn(world, difficultydamagescaler, MobSpawnType.NATURAL, groupdataentity, (CompoundTag) null);
- world.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.dimensionType().hasSkyLight() || world.getSkyDarken() < world.purpurConfig.phantomSpawnMinSkyDarkness) {
+ return 0;
+ }
+
+ int numberSpawnsAttempted = 0;
+ for (ServerPlayer player : world.players()) {
+ if (player.isSpectator() || (player.isCreative() && world.paperConfig.phantomIgnoreCreative)) {
+ continue;
+ }
+
+ BlockPos playerPos = player.blockPosition();
+ if (playerPos.getY() < world.getSeaLevel() && world.purpurConfig.phantomSpawnOnlyAboveSeaLevel) {
+ continue;
+ }
+
+ if (!world.canSeeSky(playerPos) && world.purpurConfig.phantomSpawnOnlyWithVisibleSky) {
+ continue;
+ }
+
+ DifficultyInstance difficultyInstance = world.getCurrentDifficultyAt(playerPos);
+ if (!difficultyInstance.isHarderThan(world.random.nextFloat() * (float) world.purpurConfig.phantomSpawnLocalDifficultyChance)) {
+ continue;
+ }
+
+ ServerStatsCounter stats = player.getStats();
+ int timeSinceRest = Mth.clamp(stats.getValue(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)), 1, Integer.MAX_VALUE);
+ if (world.random.nextInt(timeSinceRest) < world.purpurConfig.phantomSpawnMinTimeSinceSlept) {
+ continue;
+ }
+
+ BlockPos spawnPos = playerPos
+ .above(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 (!NaturalSpawner.isValidEmptySpawnBlock(world, spawnPos, world.getTypeIfLoaded(spawnPos), world.getFluidState(spawnPos), EntityType.PHANTOM)) {
+ continue;
+ }
+
+ int difficulty = difficultyInstance.getDifficulty().getId();
+ int spawnAttempts = world.purpurConfig.phantomSpawnMinPerAttempt + world.random.nextInt((world.purpurConfig.phantomSpawnMaxPerAttempt < 0 ? difficulty : world.purpurConfig.phantomSpawnMaxPerAttempt) + world.purpurConfig.phantomSpawnMinPerAttempt);
+
+ SpawnGroupData 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;
+ Phantom phantom = EntityType.PHANTOM.create(world);
+ if (phantom == null) {
+ continue;
}
+
+ phantom.setSpawningEntity(player.getUUID());
+ phantom.moveTo(playerPos, 0.0F, 0.0F);
+ groupData = phantom.finalizeSpawn(world, difficultyInstance, MobSpawnType.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 8985cc0ca2e5f1f673ef6ae59976095993332559..891b0ef41e57e95ab3aa7b14891ba53abd135171 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -620,6 +620,18 @@ 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() {
phantomRidable = getBoolean("mobs.phantom.ridable", phantomRidable);
phantomRidableInWater = getBoolean("mobs.phantom.ridable-in-water", phantomRidableInWater);
@@ -630,6 +642,18 @@ public class PurpurWorldConfig {
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 pigRidable = false;

View File

@@ -0,0 +1,62 @@
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/BedBlock.java b/src/main/java/net/minecraft/world/level/block/BedBlock.java
index 163a7861f987c3832aac51cc6df950c768546731..cfe4cdbd28ff11ea2781d47fe6d8c2de7912a3f6 100644
--- a/src/main/java/net/minecraft/world/level/block/BedBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BedBlock.java
@@ -97,7 +97,7 @@ public class BedBlock extends HorizontalDirectionalBlock implements EntityBlock
world.removeBlock(blockposition1, false);
}
- world.explode((Entity) null, DamageSource.badRespawnPointExplosion(), (ExplosionDamageCalculator) null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, 5.0F, true, Explosion.BlockInteraction.DESTROY);
+ if (world.purpurConfig.bedExplode) world.explode((Entity) null, DamageSource.badRespawnPointExplosion(), null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, (float) world.purpurConfig.bedExplosionPower, world.purpurConfig.bedExplosionFire, world.purpurConfig.bedExplosionEffect); // Purpur
return InteractionResult.SUCCESS;
} else if ((Boolean) state.getValue(BedBlock.OCCUPIED)) {
if (!this.kickVillagerOutOfBed(world, pos)) {
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
index 891b0ef41e57e95ab3aa7b14891ba53abd135171..d232768e789ea6a7790cada4a4ad2624cd32e4b2 100644
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
@@ -4,6 +4,7 @@ import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items;
+import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import org.bukkit.configuration.ConfigurationSection;
@@ -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.BlockInteraction bedExplosionEffect = Explosion.BlockInteraction.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.BlockInteraction.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.BlockInteraction.DESTROY;
+ }
+ }
+
public boolean dispenserApplyCursedArmor = true;
private void dispenserSettings() {
dispenserApplyCursedArmor = getBoolean("blocks.dispenser.apply-cursed-to-armor-slots", dispenserApplyCursedArmor);