Purpur/patches/server/0262-Lobotomize-stuck-villagers.patch

144 lines
6.9 KiB
Diff
Raw Normal View History

2022-01-28 00:27:23 +08:00
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Thu, 3 Dec 2020 17:56:18 -0600
Subject: [PATCH] Lobotomize stuck villagers
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
2022-06-11 15:20:41 +08:00
index c985f302812be364c07866727c9d2c2714bec249..ace39b0585c67b2764d75ff9e64d132347157a51 100644
2022-01-28 00:27:23 +08:00
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
2022-03-02 07:27:08 +08:00
@@ -140,6 +140,8 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
2022-06-09 00:14:02 +08:00
return holder.is(PoiTypes.MEETING);
2022-01-28 00:27:23 +08:00
});
private final int brainTickOffset; // Purpur
+ private boolean isLobotomized = false; public boolean isLobotomized() { return this.isLobotomized; } // Purpur
+ private int notLobotomizedCount = 0; // Purpur
2022-06-11 14:25:34 +08:00
public long nextGolemPanic = -1; // Pufferfish
@@ -198,6 +200,47 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
2022-01-28 00:27:23 +08:00
protected boolean isAlwaysExperienceDropper() {
return this.level.purpurConfig.villagerAlwaysDropExp;
}
+
+ private boolean checkLobotomized() {
+ int interval = this.level.purpurConfig.villagerLobotomizeCheckInterval;
+ if (this.notLobotomizedCount > 3) {
+ // check half as often if not lobotomized for the last 3+ consecutive checks
+ interval *= 2;
+ }
+ if ((this.level.getGameTime() + brainTickOffset) % interval == 0) {
+ // offset Y for short blocks like dirt_path/farmland
+ this.isLobotomized = !canTravelFrom(new BlockPos(getX(), getY() + 0.0625D, getZ()));
+
+ if (this.isLobotomized) {
+ this.notLobotomizedCount = 0;
+ } else {
+ this.notLobotomizedCount++;
+ }
+ }
+ return this.isLobotomized;
+ }
+
+ private boolean canTravelFrom(BlockPos pos) {
+ return canTravelTo(pos.east()) || canTravelTo(pos.west()) || canTravelTo(pos.north()) || canTravelTo(pos.south());
+ }
+
+ private boolean canTravelTo(BlockPos pos) {
2022-06-11 15:20:41 +08:00
+ net.minecraft.world.level.block.state.BlockState state = this.level.getBlockStateIfLoaded(pos);
2022-01-28 00:27:23 +08:00
+ if (state == null) {
+ // chunk not loaded
+ return false;
+ }
+ net.minecraft.world.level.block.Block bottom = state.getBlock();
+ if (bottom instanceof net.minecraft.world.level.block.FenceBlock ||
+ bottom instanceof net.minecraft.world.level.block.FenceGateBlock ||
+ bottom instanceof net.minecraft.world.level.block.WallBlock) {
+ // bottom block is too tall to get over
+ return false;
+ }
+ net.minecraft.world.level.block.Block top = level.getBlockState(pos.above()).getBlock();
+ // only if both blocks have no collision
+ return !bottom.hasCollision && !top.hasCollision;
+ }
// Purpur end
@Override
2022-06-11 14:25:34 +08:00
@@ -295,6 +338,15 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
protected void customServerAiStep() { mobTick(false); }
2022-01-28 00:27:23 +08:00
protected void mobTick(boolean inactive) {
this.level.getProfiler().push("villagerBrain");
2022-06-11 14:25:34 +08:00
+ // Purpur start
2022-01-28 00:27:23 +08:00
+ if (this.level.purpurConfig.villagerLobotomizeEnabled) {
+ // treat as inactive if lobotomized
+ inactive = inactive || checkLobotomized();
+ } else {
+ // clean up state for API
+ this.isLobotomized = false;
+ }
2022-06-11 14:25:34 +08:00
+ // Purpur end
// Pufferfish start
if (!inactive) {
// Purpur start
@@ -305,6 +357,12 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
this.getBrain().tick((ServerLevel) this.level, this); // Paper
}
// Pufferfish end
2022-01-28 00:27:23 +08:00
+ // Purpur start
+ else if (this.isLobotomized && shouldRestock()) {
+ // make sure we restock if needed when lobotomized
+ restock();
+ }
+ // Purpur end
this.level.getProfiler().pop();
if (this.assignProfessionWhenSpawned) {
this.assignProfessionWhenSpawned = false;
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
index f0b910df1ee471b4d72d97c6197ab14f2854976e..6ce32a52d621a0c2629568ea07e445f50160d97d 100644
2022-01-28 00:27:23 +08:00
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java
@@ -194,4 +194,11 @@ public class CraftVillager extends CraftAbstractVillager implements Villager {
2022-01-28 00:27:23 +08:00
getHandle().getGossips().getReputations().clear();
}
// Paper end
+
+ // Purpur start
+ @Override
+ public boolean isLobotomized() {
+ return getHandle().isLobotomized();
+ }
+ // Purpur end
}
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index e66f169b4355ef537dbde2c3aaf85e7b58cfe523..53903df5f2fd434b4abc7b66c97046ef850a6e8a 100644
2022-01-28 00:27:23 +08:00
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -2699,6 +2699,8 @@ public class PurpurWorldConfig {
2022-01-28 00:27:23 +08:00
public boolean villagerAllowTrading = true;
public boolean villagerAlwaysDropExp = false;
public int villagerMinimumDemand = 0;
+ public boolean villagerLobotomizeEnabled = false;
+ public int villagerLobotomizeCheckInterval = 100;
private void villagerSettings() {
villagerRidable = getBoolean("mobs.villager.ridable", villagerRidable);
villagerRidableInWater = getBoolean("mobs.villager.ridable-in-water", villagerRidableInWater);
@@ -2722,6 +2724,17 @@ public class PurpurWorldConfig {
2022-01-28 00:27:23 +08:00
villagerAllowTrading = getBoolean("mobs.villager.allow-trading", villagerAllowTrading);
villagerAlwaysDropExp = getBoolean("mobs.villager.always-drop-exp", villagerAlwaysDropExp);
villagerMinimumDemand = getInt("mobs.villager.minimum-demand", villagerMinimumDemand);
+ if (PurpurConfig.version < 9) {
+ boolean oldValue = getBoolean("mobs.villager.lobotomize-1x1", villagerLobotomizeEnabled);
+ set("mobs.villager.lobotomize.enabled", oldValue);
+ set("mobs.villager.lobotomize-1x1", null);
+ }
+ if (PurpurConfig.version < 27) {
+ int oldValue = getInt("mobs.villager.lobotomize.check-interval", villagerLobotomizeCheckInterval);
+ set("mobs.villager.lobotomize.check-interval", oldValue == 60 ? 100 : oldValue);
+ }
+ villagerLobotomizeEnabled = getBoolean("mobs.villager.lobotomize.enabled", villagerLobotomizeEnabled);
+ villagerLobotomizeCheckInterval = getInt("mobs.villager.lobotomize.check-interval", villagerLobotomizeCheckInterval);
}
public boolean vindicatorRidable = false;