Compare commits

...

14 Commits

Author SHA1 Message Date
Helvetica Volubi b830c66be7 Update upstream(Luminol) & rename config names 2025-08-27 00:22:52 +08:00
Helvetica Volubi fc50c2ac44 Update gradle.properties 2025-08-26 14:08:25 +08:00
Helvetica Volubi f81cee2454 feat: add a config to revert MC-159283 2025-08-26 03:04:39 +08:00
Helvetica Volubi 049716a64c Update upstream(Luminol) 2025-08-25 22:31:49 +08:00
dependabot[bot] c7c37c5a95 build(deps): bump actions/setup-java from 4 to 5 (#52)
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 4 to 5.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-25 21:32:02 +08:00
Helvetica Volubi 4dea005c0d Update gradle.properties 2025-08-24 22:07:20 +08:00
Helvetica Volubi 074c5c9553 Update upstream(Luminol-lithium-sleeping-block-entity) 2025-08-24 03:55:44 +08:00
Helvetica Volubi f79cc86332 Update upstream(Luminol-lithium-sleeping-block-entity) 2025-08-22 20:55:59 +08:00
Helvetica Volubi e880fdecfa Update upstream(Luminol-lithium-sleeping-block-entity) 2025-08-22 02:18:26 +08:00
xiaoxijun dda45b510a update maven repo 2025-08-20 03:51:09 +08:00
Bacteriawa 6fec3a73ac update maven repo 2025-08-20 02:59:17 +08:00
Helvetica Volubi d22d5fdf5a Update upstream(Luminol-lithium-sleeping-block-entity) 2025-08-19 07:11:56 +08:00
Helvetica Volubi fcb90d468e Update upstream(Luminol-lithium-sleeping-block-entity) 2025-08-18 23:18:53 +08:00
dependabot[bot] 1094716d9d [ci skip]build(deps): bump actions/checkout from 4 to 5 (#49)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-08-18 19:22:24 +08:00
56 changed files with 1154 additions and 435 deletions
+2 -2
View File
@@ -16,10 +16,10 @@ jobs:
environment: default
steps:
- name: Checkout Git Repository
uses: actions/checkout@v4
uses: actions/checkout@v5
- name: Set up JDK
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: zulu
java-version: 21
+3 -3
View File
@@ -2,7 +2,7 @@
# Lophine
<h4>Lophine 是一个基于Luminol的分支,具有许多有用的优化和可配置的原版特性,目标是在Folia上实现更多生电的实现</h4>
<h4>Lophine 是一个基于Luminol的分支,具有许多有用的优化和可配置的原版特性,目标是在Folia上实现更多生电的内容(请注意,完整生电请使用Fabric)</h4>
![Created At](https://img.shields.io/github/created-at/LuminolMC/Lophine?style=flat-square)
[![License](https://img.shields.io/github/license/LuminolMC/Lophine?style=flat-square)](LICENSE.md)
@@ -42,7 +42,7 @@
```kotlin
repositories {
maven {
url = "https://repo.menthamc.com/repository/maven-public/"
url = "https://repo.menthamc.org/repository/maven-public/"
}
}
@@ -57,7 +57,7 @@ dependencies {
<repositories>
<repository>
<id>menthamc</id>
<url>https://repo.menthamc.com/repository/maven-public/</url>
<url>https://repo.menthamc.org/repository/maven-public/</url>
</repository>
</repositories>
+3 -3
View File
@@ -3,7 +3,7 @@
# Lophine
<h4>Lophine is a Luminol fork with many useful optimizations and configurable vanilla features, aims to provide
more function for survival-usable circuit on folia</h4>
more function for survival-usable circuit on folia (Please note that Fabric should be used for complete survival-usable)</h4>
![Created At](https://img.shields.io/github/created-at/LuminolMC/Lophine?style=flat-square)
[![License](https://img.shields.io/github/license/LuminolMC/Lophine?style=flat-square)](LICENSE.md)
@@ -43,7 +43,7 @@ For gradle:
```kotlin
repositories {
maven {
url = "https://repo.menthamc.com/repository/maven-public/"
url = "https://repo.menthamc.org/repository/maven-public/"
}
}
@@ -58,7 +58,7 @@ For maven
<repositories>
<repository>
<id>menthamc</id>
<url>https://repo.menthamc.com/repository/maven-public/</url>
<url>https://repo.menthamc.org/repository/maven-public/</url>
</repository>
</repositories>
+2 -2
View File
@@ -41,7 +41,7 @@ paperweight {
}
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
val menthaMavenPublicUrl = "https://repo.menthamc.com/repository/maven-public/";
val menthaMavenPublicUrl = "https://repo.menthamc.org/repository/maven-public/";
subprojects {
apply(plugin = "java-library")
@@ -88,7 +88,7 @@ subprojects {
extensions.configure<PublishingExtension> {
repositories {
maven("https://repo.menthamc.com/repository/maven-snapshots/") {
maven("https://repo.menthamc.org/repository/maven-snapshots/") {
name = "MenthaMC"
credentials(PasswordCredentials::class) {
username = System.getenv("PRIVATE_MAVEN_REPO_USERNAME")
+1 -1
View File
@@ -4,7 +4,7 @@ mcVersion=1.21.8
release=2
# 0 for skip release, 1 for pre-release, 2 for release
luminolRef=f8bd34a2dff31a137b0808b83b7503a22fcd0527
luminolRef=122e2025c83d4ff734f9c1923fa902191a400b84
org.gradle.configuration-cache=true
org.gradle.caching=true
@@ -5,7 +5,7 @@ Subject: [PATCH] Rebrand to Lophine
diff --git a/src/main/java/me/earthme/luminol/config/ConfigManager.java b/src/main/java/me/earthme/luminol/config/ConfigManager.java
index a67fc80eb3182415557b4bdf7f146aefb43103da..52fec4c88fee3c027c954365538516aaa8335c7f 100644
index 4be82092886728b7862b6e8951cf1c8ab917ca55..1b822e9576573c360b997e5cb4fa02278c88b74f 100644
--- a/src/main/java/me/earthme/luminol/config/ConfigManager.java
+++ b/src/main/java/me/earthme/luminol/config/ConfigManager.java
@@ -21,6 +21,7 @@ public class ConfigManager {
@@ -17,11 +17,11 @@ index a67fc80eb3182415557b4bdf7f146aefb43103da..52fec4c88fee3c027c954365538516aa
}
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
index ded1f0667327a70a923ebda55c41b1c9094d3e37..57ddc0832b919b115b85c81ac30f136e32f1e77e 100644
index f164e41975adee8b68dbcb400007681c0b66a4f8..4e76fb3b1274f2fde734089b20458f6561c39700 100644
--- a/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/ServerModNameConfig.java
@@ -6,7 +6,7 @@ import me.earthme.luminol.config.flags.ConfigInfo;
@@ -8,7 +8,7 @@ import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(configAttribution = EnumConfigCategory.MISC, mainName = "server_mod_name")
public class ServerModNameConfig implements IConfigModule {
@ConfigInfo(baseName = "name")
- public static String serverModName = "Luminol";
@@ -1,30 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
Date: Mon, 28 Jul 2025 23:02:47 +0800
Date: Tue, 26 Aug 2025 22:08:54 +0800
Subject: [PATCH] Transformed Configs
diff --git a/src/main/java/me/earthme/luminol/config/modules/experiment/CommandBlockExecutionConfig.java b/src/main/java/me/earthme/luminol/config/modules/experiment/CommandBlockExecutionConfig.java
index 531214d7ab28ece4bf84e82b39d1c9f983f0fb0c..b68fa0427bb975e91e76f73ab4cc089a424937a3 100644
--- a/src/main/java/me/earthme/luminol/config/modules/experiment/CommandBlockExecutionConfig.java
+++ b/src/main/java/me/earthme/luminol/config/modules/experiment/CommandBlockExecutionConfig.java
@@ -5,6 +5,7 @@ import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigInfo;
public class CommandBlockExecutionConfig implements IConfigModule {
+ @me.earthme.luminol.config.flags.TransformedConfig(name = "command_block_enabled", category = {"experiment", "command"}, originInstance = "lophine")
@ConfigInfo(baseName = "enabled")
public static boolean enabled = false;
diff --git a/src/main/java/me/earthme/luminol/config/modules/misc/PaperPacketLimiterConfig.java b/src/main/java/me/earthme/luminol/config/modules/misc/PaperPacketLimiterConfig.java
index c269446dda05cfc848407f80f53820c8fcd0c7b4..e69ffae53aa24496a29a4c4890cdcb366d2bec12 100644
--- a/src/main/java/me/earthme/luminol/config/modules/misc/PaperPacketLimiterConfig.java
+++ b/src/main/java/me/earthme/luminol/config/modules/misc/PaperPacketLimiterConfig.java
@@ -5,6 +5,7 @@ import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigInfo;
diff --git a/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java b/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java
index 4e906e8e0ebd57b9f7000e4194280e3e3636e52c..14eefd162c9facd54a53718a7a0b1b0266e1ada8 100644
--- a/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java
+++ b/src/main/java/me/earthme/luminol/config/modules/experiment/CommandConfig.java
@@ -11,6 +11,7 @@ public class CommandConfig implements IConfigModule {
@TransformedConfig(name = "enable", category = {"experiment", "force_the_data_command_to_be_enabled"})
@ConfigInfo(baseName = "enable_data_command")
public static boolean data = false;
+ @TransformedConfig(name = "command_block_enabled", category = {"experiment", "command"}, originInstance = "lophine")
@TransformedConfig(name = "enabled", category = {"experiment", "force_enable_command_block_command_execution"})
@ConfigInfo(baseName = "enable_command_block")
public static boolean commandBlock = false;
diff --git a/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java b/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java
index 192a67360db810934d02a15c955af3579e6f6b20..fbafc5a8aa2581301e62e12adb22169ab7fd8e19 100644
--- a/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java
+++ b/src/main/java/me/earthme/luminol/config/modules/optimizations/PaperPacketLimiterConfig.java
@@ -8,6 +8,7 @@ import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(configAttribution = EnumConfigCategory.OPTIMIZATIONS, mainName = "force_disable_packet_limiter_of_paper")
public class PaperPacketLimiterConfig implements IConfigModule {
+ @me.earthme.luminol.config.flags.TransformedConfig(name = "unlimit-packet", category = {"misc", "network"}, originInstance = "lophine")
+ @TransformedConfig(name = "unlimit-packet", category = {"misc", "network"}, originInstance = "lophine")
@TransformedConfig(name = "force_disable", category = {"misc", "force_disable_packet_limiter_of_paper"})
@ConfigInfo(baseName = "force_disable")
public static boolean forceDisable = false;
@@ -8,114 +8,181 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/d93e9766d3797d130
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java b/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java
index 5995c499298454a060433746c64be5fcc8d202e2..3452399de0fa464ce04a7cf1a05b440346bef662 100644
index 102de78be0eb82d6898b4104fad1bf5e8366f993..0f8c9d4932c8bbd619f21d4aa28b890e14439b46 100644
--- a/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java
+++ b/src/main/java/org/leavesmc/leaves/util/ItemOverstackUtils.java
@@ -17,29 +17,30 @@
@@ -17,12 +17,173 @@
package org.leavesmc.leaves.util;
+import fun.bm.lophine.config.modules.misc.ContainerExpansionConfig;
//import io.papermc.paper.datacomponent.DataComponentTypes;
//import io.papermc.paper.datacomponent.item.ItemEnchantments;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.item.ItemEntity;
-//import net.minecraft.world.item.BlockItem;
+import fun.bm.lophine.config.modules.function.ContainerExpansionConfig;
+import net.minecraft.core.component.DataComponents;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.world.entity.item.ItemEntity;
+import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.CustomData;
-//import net.minecraft.world.item.component.ItemContainerContents;
-//import net.minecraft.world.level.block.ShulkerBoxBlock;
+import net.minecraft.world.item.component.CustomData;
+import net.minecraft.world.item.component.ItemContainerContents;
+import net.minecraft.world.level.block.ShulkerBoxBlock;
//import org.bukkit.enchantments.Enchantment;
-//import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.NotNull;
//import org.leavesmc.leaves.LeavesConfig;
import java.util.List;
-//import java.util.Objects;
+
+import java.util.List;
+import java.util.Objects;
import java.util.Optional;
+import java.util.Optional;
// Only the used part is retained
public class ItemOverstackUtils {
private static final List<ItemUtil> overstackUtils = List.of(
-/* new ShulkerBox(),
- new CurseEnchantedBook()*/
+ private static final List<ItemUtil> overstackUtils = List.of(
+ new ShulkerBox()
+ // new CurseEnchantedBook() // only use shulker box part
);
public static int getItemStackMaxCount(ItemStack stack) {
@@ -109,6 +110,7 @@ public class ItemOverstackUtils {
+ );
+
+ public static int getItemStackMaxCount(ItemStack stack) {
+ int size;
+ for (ItemUtil util : overstackUtils) {
+ if ((size = util.getMaxServerStackCount(stack)) != -1) {
+ return size;
+ }
+ }
+ return stack.getMaxStackSize();
+ }
+
+ public static int getNetworkMaxCount(ItemStack stack) {
+ int size;
+ for (ItemUtil util : overstackUtils) {
+ if ((size = util.getMaxClientStackCount(stack)) != -1) {
+ return size;
+ }
+ }
+ return stack.getMaxStackSize();
+ }
+
+ public static boolean tryStackItems(ItemEntity self, ItemEntity other) {
+ for (ItemUtil util : overstackUtils) {
+ if (util.tryStackItems(self, other)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean hasOverstackingItem() {
+ return overstackUtils.stream().anyMatch(ItemUtil::isEnabled);
+ }
+
+ public static int getItemStackMaxCountReal(ItemStack stack) {
+ CompoundTag nbt = Optional.ofNullable(stack.get(DataComponents.CUSTOM_DATA)).orElse(CustomData.EMPTY).copyTag();
+ return nbt.getInt("Leaves.RealStackSize").orElse(stack.getMaxStackSize());
+ }
+
+ public static ItemStack encodeMaxStackSize(ItemStack itemStack) {
+ int realMaxStackSize = getItemStackMaxCountReal(itemStack);
+ int modifiedMaxStackSize = getNetworkMaxCount(itemStack);
+ if (itemStack.getMaxStackSize() != modifiedMaxStackSize) {
+ itemStack.set(DataComponents.MAX_STACK_SIZE, modifiedMaxStackSize);
+ CompoundTag nbt = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
+ nbt.putInt("Leaves.RealStackSize", realMaxStackSize);
+ itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(nbt));
+ }
+ return itemStack;
+ }
+
+ public static ItemStack decodeMaxStackSize(ItemStack itemStack) {
+ int realMaxStackSize = getItemStackMaxCountReal(itemStack);
+ if (itemStack.getMaxStackSize() != realMaxStackSize) {
+ itemStack.set(DataComponents.MAX_STACK_SIZE, realMaxStackSize);
+ CompoundTag nbt = itemStack.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).copyTag();
+ nbt.remove("Leaves.RealStackSize");
+ if (nbt.isEmpty()) {
+ itemStack.remove(DataComponents.CUSTOM_DATA);
+ } else {
+ itemStack.set(DataComponents.CUSTOM_DATA, CustomData.of(nbt));
+ }
+ }
+ return itemStack;
+ }
+
public static float getItemStackSignalStrength(int maxStackSize, ItemStack itemStack) {
float result = (float) itemStack.getCount() / Math.min(maxStackSize, itemStack.getMaxStackSize());
+ // only use shulker box part
/* if (LeavesConfig.modify.oldMC.allowGrindstoneOverstacking && CurseEnchantedBook.isCursedEnchantedBook(itemStack)) {
return result;
}*/
@@ -134,9 +136,9 @@ public class ItemOverstackUtils {
}
return Math.clamp(result, 0f, 1f);
}
-/* private static class ShulkerBox implements ItemUtil {
+
+ public static boolean isStackable(ItemStack itemStack) {
+ return getItemStackMaxCount(itemStack) > 1 && (!itemStack.isDamageableItem() || !itemStack.isDamaged());
+ }
+
+
+ private interface ItemUtil {
+ boolean isEnabled();
+
+ boolean tryStackItems(ItemEntity self, ItemEntity other);
+
+ // number -> modified count, -1 -> I don't care
+ int getMaxServerStackCount(ItemStack stack);
+
+ // number -> modified count, -1 -> I don't care
+ default int getMaxClientStackCount(ItemStack stack) {
+ return getMaxServerStackCount(stack);
+ }
+ }
+
+ private static class ShulkerBox implements ItemUtil {
public static boolean shulkerBoxCheck(@NotNull ItemStack stack1, @NotNull ItemStack stack2) {
- if (LeavesConfig.modify.shulkerBox.sameNbtStackable) {
+ public static boolean shulkerBoxCheck(@NotNull ItemStack stack1, @NotNull ItemStack stack2) {
+ if (ContainerExpansionConfig.nbtShulkerStackable) {
return Objects.equals(stack1.getComponents(), stack2.getComponents());
}
return shulkerBoxNoItem(stack1) && shulkerBoxNoItem(stack2) && Objects.equals(stack1.getComponents(), stack2.getComponents());
@@ -148,24 +150,24 @@ public class ItemOverstackUtils {
@Override
public boolean isEnabled() {
- return LeavesConfig.modify.shulkerBox.shulkerBoxStackSize > 1;
+ return Objects.equals(stack1.getComponents(), stack2.getComponents());
+ }
+ return shulkerBoxNoItem(stack1) && shulkerBoxNoItem(stack2) && Objects.equals(stack1.getComponents(), stack2.getComponents());
+ }
+
+ public static boolean shulkerBoxNoItem(@NotNull ItemStack stack) {
+ return stack.getComponents().getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).stream().findAny().isEmpty();
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return ContainerExpansionConfig.shulkerCount > 1;
}
@Override
public boolean tryStackItems(ItemEntity self, ItemEntity other) {
ItemStack selfStack = self.getItem();
if (!isEnabled() ||
- !(selfStack.getItem() instanceof BlockItem blockItem) ||
- !(blockItem.getBlock() instanceof ShulkerBoxBlock)
+ }
+
+ @Override
+ public boolean tryStackItems(ItemEntity self, ItemEntity other) {
+ ItemStack selfStack = self.getItem();
+ if (!isEnabled() ||
+ !(selfStack.getItem() instanceof BlockItem blockItem) ||
+ !(blockItem.getBlock() instanceof ShulkerBoxBlock)
) {
return false;
}
ItemStack otherStack = other.getItem();
if (selfStack.getItem() == otherStack.getItem()
- && shulkerBoxCheck(selfStack, otherStack)
- && selfStack.getCount() != org.leavesmc.leaves.LeavesConfig.modify.shulkerBox.shulkerBoxStackSize) {
- int amount = Math.min(otherStack.getCount(), org.leavesmc.leaves.LeavesConfig.modify.shulkerBox.shulkerBoxStackSize - selfStack.getCount());
+ ) {
+ return false;
+ }
+
+ ItemStack otherStack = other.getItem();
+ if (selfStack.getItem() == otherStack.getItem()
+ && shulkerBoxCheck(selfStack, otherStack)
+ && selfStack.getCount() != ContainerExpansionConfig.shulkerCount) {
+ int amount = Math.min(otherStack.getCount(), ContainerExpansionConfig.shulkerCount - selfStack.getCount());
selfStack.grow(amount);
self.setItem(selfStack);
@@ -187,14 +189,15 @@ public class ItemOverstackUtils {
@Override
public int getMaxServerStackCount(ItemStack stack) {
if (isEnabled() && stack.getItem() instanceof BlockItem bi &&
- bi.getBlock() instanceof ShulkerBoxBlock && (LeavesConfig.modify.shulkerBox.sameNbtStackable || shulkerBoxNoItem(stack))) {
- return LeavesConfig.modify.shulkerBox.shulkerBoxStackSize;
+
+ selfStack.grow(amount);
+ self.setItem(selfStack);
+
+ self.pickupDelay = Math.max(other.pickupDelay, self.pickupDelay);
+ self.age = Math.min(other.getAge(), self.age);
+
+ otherStack.shrink(amount);
+ if (otherStack.isEmpty()) {
+ other.discard();
+ } else {
+ other.setItem(otherStack);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public int getMaxServerStackCount(ItemStack stack) {
+ if (isEnabled() && stack.getItem() instanceof BlockItem bi &&
+ bi.getBlock() instanceof ShulkerBoxBlock && (ContainerExpansionConfig.nbtShulkerStackable || shulkerBoxNoItem(stack))) {
+ return ContainerExpansionConfig.shulkerCount;
}
return -1;
}
}
- public static class CurseEnchantedBook implements ItemUtil {
+// only use shulker box part
+/* public static class CurseEnchantedBook implements ItemUtil {
public static boolean isCursedEnchantedBook(ItemStack stack) {
ItemEnchantments enchantments = stack.getBukkitStack().getData(DataComponentTypes.STORED_ENCHANTMENTS);
if (enchantments == null || enchantments.enchantments().size() != 1) {
+ }
+ return -1;
+ }
+ }
}
\ No newline at end of file
@@ -5,7 +5,7 @@ Subject: [PATCH] Add config to allow infinite trade
diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java
index 79242037e868a140513f032e74e8594c0c6ff41c..8570c5089b605125680f8558ae201550df2d0a47 100644
index 79242037e868a140513f032e74e8594c0c6ff41c..050e89c3e95c7c3ef7ad98f8ef03ab206241a7e2 100644
--- a/net/minecraft/world/entity/npc/Villager.java
+++ b/net/minecraft/world/entity/npc/Villager.java
@@ -490,8 +490,15 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
@@ -16,7 +16,7 @@ index 79242037e868a140513f032e74e8594c0c6ff41c..8570c5089b605125680f8558ae201550
+ // Lophine start - infinite trade
+ MerchantOffers offers = this.getOffers().copy();
Player tradingPlayer = this.getTradingPlayer();
+ if (fun.bm.lophine.config.modules.misc.VillagerConfig.villagerInfiniteTrade) {
+ if (fun.bm.lophine.config.modules.function.VillagerConfig.villagerInfiniteTrade) {
+ for (MerchantOffer merchantOffer : offers) {
+ merchantOffer.maxUses = 524288;
+ }
@@ -26,7 +26,7 @@ index 79242037e868a140513f032e74e8594c0c6ff41c..8570c5089b605125680f8558ae201550
tradingPlayer.sendMerchantOffers(
tradingPlayer.containerMenu.containerId,
diff --git a/net/minecraft/world/item/trading/Merchant.java b/net/minecraft/world/item/trading/Merchant.java
index 6e2fa442ddcd4ef3c4fe789b9ebac9dd409c9de7..28d743cc7beeb92a33683b8eea84096f94d90fb2 100644
index 6e2fa442ddcd4ef3c4fe789b9ebac9dd409c9de7..0c7318a0ed214204f5493576c8a7b02fbe51c00b 100644
--- a/net/minecraft/world/item/trading/Merchant.java
+++ b/net/minecraft/world/item/trading/Merchant.java
@@ -42,7 +42,14 @@ public interface Merchant {
@@ -36,7 +36,7 @@ index 6e2fa442ddcd4ef3c4fe789b9ebac9dd409c9de7..28d743cc7beeb92a33683b8eea84096f
- MerchantOffers offers = this.getOffers();
+ // Lophine start - infinite trade
+ MerchantOffers offers = this.getOffers().copy();
+ if (fun.bm.lophine.config.modules.misc.VillagerConfig.villagerInfiniteTrade) {
+ if (fun.bm.lophine.config.modules.function.VillagerConfig.villagerInfiniteTrade) {
+ for (MerchantOffer merchantOffer : offers) {
+ merchantOffer.maxUses = 5242884;
+ }
@@ -46,7 +46,7 @@ index 6e2fa442ddcd4ef3c4fe789b9ebac9dd409c9de7..28d743cc7beeb92a33683b8eea84096f
player.sendMerchantOffers(optionalInt.getAsInt(), offers, level, this.getVillagerXp(), this.showProgressBar(), this.canRestock());
}
diff --git a/net/minecraft/world/item/trading/MerchantOffer.java b/net/minecraft/world/item/trading/MerchantOffer.java
index 64c99df8ff305fa28c75dc03fc5ef8c61634ad84..21ec77d5167cfdf05043ea474165148fb2b0c2d9 100644
index 64c99df8ff305fa28c75dc03fc5ef8c61634ad84..770f37d7158c7b4cec62783025f623a68c1f2457 100644
--- a/net/minecraft/world/item/trading/MerchantOffer.java
+++ b/net/minecraft/world/item/trading/MerchantOffer.java
@@ -196,7 +196,7 @@ public class MerchantOffer {
@@ -54,7 +54,7 @@ index 64c99df8ff305fa28c75dc03fc5ef8c61634ad84..21ec77d5167cfdf05043ea474165148f
public boolean isOutOfStock() {
- return this.uses >= this.maxUses;
+ return (this.uses >= this.maxUses && !fun.bm.lophine.config.modules.misc.VillagerConfig.villagerInfiniteTrade); // Lophine - infinite trade
+ return (this.uses >= this.maxUses && !fun.bm.lophine.config.modules.function.VillagerConfig.villagerInfiniteTrade); // Lophine - infinite trade
}
public void setToOutOfStock() {
@@ -0,0 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
Date: Tue, 26 Aug 2025 02:55:23 +0800
Subject: [PATCH] Add config to allow generation of end void rings
diff --git a/net/minecraft/world/level/levelgen/DensityFunctions.java b/net/minecraft/world/level/levelgen/DensityFunctions.java
index 04527a5c65ad630f794fed9071d485aedd02257a..b63661b313c04e2bd8981920972339470148a847 100644
--- a/net/minecraft/world/level/levelgen/DensityFunctions.java
+++ b/net/minecraft/world/level/levelgen/DensityFunctions.java
@@ -528,7 +528,7 @@ public final class DensityFunctions {
int i1 = z / 2;
int i2 = x % 2;
int i3 = z % 2;
- float f = 100.0F - Mth.sqrt((long)x * (long)x + (long)z * (long)z) * 8.0F; // Paper - cast ints to long to avoid integer overflow
+ float f = fun.bm.lophine.config.modules.fixes.EndVoidRingsConfig.enabled ? 100.0F - Mth.sqrt(x * x + z * z) * 8.0F : 100.0F - Mth.sqrt((long)x * (long)x + (long)z * (long)z) * 8.0F; // Paper - cast ints to long to avoid integer overflow // Lophine - optimize end void rings generation
f = Mth.clamp(f, -100.0F, 80.0F);
NoiseCache cache = noiseCache.get().computeIfAbsent(noise, noiseKey -> new NoiseCache()); // Paper - Perf: Optimize end generation
@@ -1,27 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Helvetica Volubi <suisuroru@blue-millennium.fun>
Date: Wed, 21 May 2025 13:04:00 +0800
Subject: [PATCH] Add config to disable end crystal check
diff --git a/net/minecraft/world/level/dimension/end/EndDragonFight.java b/net/minecraft/world/level/dimension/end/EndDragonFight.java
index 4fa8371c212dcc02b8cf5fd267b736e1cf3f50c1..3f1520bdd5ef708824712ea62974fedb35067f23 100644
--- a/net/minecraft/world/level/dimension/end/EndDragonFight.java
+++ b/net/minecraft/world/level/dimension/end/EndDragonFight.java
@@ -547,6 +547,8 @@ public class EndDragonFight {
blockPos = this.portalLocation;
}
+ // Luminol start - Disable end crystal check
+ if (!fun.bm.lophine.config.modules.fixes.DisableEndCrystalCheckConfig.disableCheck) {
// Paper start - Perf: Do crystal-portal proximity check before entity lookup
if (placedEndCrystalPos != null) {
// The end crystal must be 0 or 1 higher than the portal origin
@@ -562,6 +564,7 @@ public class EndDragonFight {
}
}
// Paper end - Perf: Do crystal-portal proximity check before entity lookup
+ } // Luminol end - Disable end crystal check
List<EndCrystal> list = Lists.newArrayList();
@@ -5,11 +5,11 @@ Subject: [PATCH] Add config to enable datapack command
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
index 8a90aa5c145f53afbb3f2371f97cb09974f30bbb..b6e10157c572dadb1bff18f8431166966eed46d9 100644
index e05f75b6bbd48d6fb7379926d68d5f8ed6014be9..af895859057ca303177ec3c8a07cf7534e62cca6 100644
--- a/net/minecraft/commands/Commands.java
+++ b/net/minecraft/commands/Commands.java
@@ -192,7 +192,9 @@ public class Commands {
if(me.earthme.luminol.config.modules.experiment.CommandDataConfig.enabled) {
if(me.earthme.luminol.config.modules.experiment.CommandConfig.data) {
DataCommands.register(this.dispatcher); // Folia - region threading - TODO
}
- //DataPackCommand.register(this.dispatcher, context); // Folia - region threading - TODO
@@ -18,7 +18,7 @@ index 6868b915bf3deb85783a638d4441a15fea6da2dc..70740381c6501c1a518c52b24381edd1
double rangeY = level.paperConfig().entities.trackingRangeY.get(this.entity, -1);
if (rangeY != -1) {
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 75f327fff68097c1c9f65767552f686421e1e397..ed7421895311d89ad9726804893eff423868d375 100644
index 8ec753fe9c84ffe1188f7e7ebb6895cf4bba9e39..ee4a459700d75676eae3422d4a0e10be73c45871 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -147,7 +147,7 @@ import net.minecraft.world.waypoints.WaypointTransmitter;
@@ -30,7 +30,7 @@ index 75f327fff68097c1c9f65767552f686421e1e397..ed7421895311d89ad9726804893eff42
// CraftBukkit start
private static final int CURRENT_LEVEL = 2;
public boolean preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; keep initial motion on first snapTo
@@ -6467,4 +6467,46 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -6472,4 +6472,46 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// Paper end - Expose entity id counter
public boolean shouldTickHot() { return this.tickCount > 20 * 10 && this.isAlive(); } // KioCG
@@ -44,7 +44,7 @@ index e1842ab8f20271a8b20ab8462b09a4745a612a9a..8405157ec35a443e238fa6866772c839
world.setDayTime(world.levelData.getDayTime() + (long)tickCount);
}
diff --git a/io/papermc/paper/threadedregions/TickRegionScheduler.java b/io/papermc/paper/threadedregions/TickRegionScheduler.java
index 0357792de0ed8ec9058d1847c8b45c33ff365af6..4945c11f573a53df2f5be4beb7af6a3f4d32f7d4 100644
index c485d5b3ba95f2a969bdf0dab9654ac284976f8d..b957585cf7cf7f845e20f59c7b355722880f3b4e 100644
--- a/io/papermc/paper/threadedregions/TickRegionScheduler.java
+++ b/io/papermc/paper/threadedregions/TickRegionScheduler.java
@@ -31,8 +31,8 @@ public final class TickRegionScheduler {
@@ -97,7 +97,7 @@ index 0357792de0ed8ec9058d1847c8b45c33ff365af6..4945c11f573a53df2f5be4beb7af6a3f
this.scheduler.regionFailed(this, false, thr);
// regionFailed will schedule a shutdown, so we should avoid letting this region tick further
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
index b6e10157c572dadb1bff18f8431166966eed46d9..e2fc15d84fafde6847ecead23c55169449275e1b 100644
index af895859057ca303177ec3c8a07cf7534e62cca6..94a3cea5d42b1f98bbde22ef514f8f7dbd64ba58 100644
--- a/net/minecraft/commands/Commands.java
+++ b/net/minecraft/commands/Commands.java
@@ -245,7 +245,11 @@ public class Commands {
@@ -5,7 +5,7 @@ Subject: [PATCH] Add config to enable unsafe waypoint bar
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
index e2fc15d84fafde6847ecead23c55169449275e1b..b0a06cdfaa49237f372ecd131d47289160476b07 100644
index 94a3cea5d42b1f98bbde22ef514f8f7dbd64ba58..e311977fca4d0ba6e3efd4a41b2732cf5e7b4b9c 100644
--- a/net/minecraft/commands/Commands.java
+++ b/net/minecraft/commands/Commands.java
@@ -253,7 +253,11 @@ public class Commands {
@@ -88,7 +88,7 @@ index a0f1db50adf5163a671d3d9e9df7adb7de4250c6..af13707933af14171447d5ab6faacb64
public int getSpawnProtectionRadius() {
return 16;
diff --git a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
index 714813cba67da4a737682fe9276cb0d96fea336d..9677a3d62de11dafc8b9debe7a18ee6d14c7a64d 100644
index 8150b16c196edcb226be9268ea6e0012e44517fa..c54bf0429c0ca3a35a730658c7b1b3ddc776bf9e 100644
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
@@ -57,6 +57,7 @@ public abstract class ServerCommonPacketListenerImpl implements ServerCommonPack
@@ -28,7 +28,7 @@ index 643797124fe5a4489d0b7419b7e600c04f283ef2..04b4100da96aad50f08e8c59200eec93
public String serialize(HolderLookup.Provider levelRegistry) {
diff --git a/net/minecraft/server/commands/GiveCommand.java b/net/minecraft/server/commands/GiveCommand.java
index f7002d6752aa03603eb06e298ba1d7130cf13826..72c87f7c0392d087440db9d267a608598f6feb6d 100644
index 7ef109cb9921c25987905149616eddbd0b2f9b9c..70fc9d6c5b226211ff5964464c37e11695d5f745 100644
--- a/net/minecraft/server/commands/GiveCommand.java
+++ b/net/minecraft/server/commands/GiveCommand.java
@@ -55,7 +55,7 @@ public class GiveCommand {
@@ -41,7 +41,7 @@ index f7002d6752aa03603eb06e298ba1d7130cf13826..72c87f7c0392d087440db9d267a60859
if (count > i) {
source.sendFailure(Component.translatable("commands.give.failed.toomanyitems", i, itemStack.getDisplayName()));
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index d74a05822c6c145971dc526a62d652d35b4f5d9d..d63d8f7523938088bf9efc1c1b8ad9f0583338bb 100644
index 74ec003486f9362d2bafbad8392b9bbdf0c15882..f06b9d8ad9512d35f3f460eb77c869690321c67f 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -3079,7 +3079,7 @@ public class ServerGamePacketListenerImpl
@@ -229,7 +229,7 @@ index 02d2efef2dc0f0e12eac0c71fa290af706f7694d..99f109e2653eff10c011f380694bd77a
default SlotAccess getChestVehicleSlot(final int index) {
diff --git a/net/minecraft/world/inventory/AbstractContainerMenu.java b/net/minecraft/world/inventory/AbstractContainerMenu.java
index fcb2e0a722ed94acf08da06f06b20f42652896bc..9489a50df2de3d641235153c5a0217d96c1f4fa9 100644
index 2d6acceffb2cb7e55dd504018a70b05afccd9c11..bdc0ca1f625dc264bef6e5722ec66121ba48625a 100644
--- a/net/minecraft/world/inventory/AbstractContainerMenu.java
+++ b/net/minecraft/world/inventory/AbstractContainerMenu.java
@@ -295,6 +295,13 @@ public abstract class AbstractContainerMenu {
@@ -273,7 +273,7 @@ index fcb2e0a722ed94acf08da06f06b20f42652896bc..9489a50df2de3d641235153c5a0217d9
}
} else if (clickType == ClickType.THROW && this.getCarried().isEmpty() && slotId >= 0) {
Slot slot2 = this.slots.get(slotId);
@@ -656,15 +663,15 @@ public abstract class AbstractContainerMenu {
@@ -660,15 +667,15 @@ public abstract class AbstractContainerMenu {
int maxStackSize = button == 0 ? 1 : -1;
for (int i3 = 0; i3 < 2; i3++) {
@@ -292,7 +292,7 @@ index fcb2e0a722ed94acf08da06f06b20f42652896bc..9489a50df2de3d641235153c5a0217d9
itemStack.grow(itemStack1.getCount());
}
}
@@ -766,7 +773,7 @@ public abstract class AbstractContainerMenu {
@@ -770,7 +777,7 @@ public abstract class AbstractContainerMenu {
i = endIndex - 1;
}
@@ -301,7 +301,7 @@ index fcb2e0a722ed94acf08da06f06b20f42652896bc..9489a50df2de3d641235153c5a0217d9
while (!stack.isEmpty() && (reverseDirection ? i >= startIndex : i < endIndex)) {
Slot slot = this.slots.get(i);
ItemStack item = slot.getItem();
@@ -867,7 +874,7 @@ public abstract class AbstractContainerMenu {
@@ -871,7 +878,7 @@ public abstract class AbstractContainerMenu {
public static boolean canItemQuickReplace(@Nullable Slot slot, ItemStack stack, boolean stackSizeMatters) {
boolean flag = slot == null || !slot.hasItem();
return !flag && ItemStack.isSameItemSameComponents(stack, slot.getItem())
@@ -310,7 +310,7 @@ index fcb2e0a722ed94acf08da06f06b20f42652896bc..9489a50df2de3d641235153c5a0217d9
: flag;
}
@@ -875,7 +882,7 @@ public abstract class AbstractContainerMenu {
@@ -879,7 +886,7 @@ public abstract class AbstractContainerMenu {
return switch (type) {
case 0 -> Mth.floor((float)stack.getCount() / slots.size());
case 1 -> 1;
@@ -319,7 +319,7 @@ index fcb2e0a722ed94acf08da06f06b20f42652896bc..9489a50df2de3d641235153c5a0217d9
default -> stack.getCount();
};
}
@@ -898,7 +905,7 @@ public abstract class AbstractContainerMenu {
@@ -902,7 +909,7 @@ public abstract class AbstractContainerMenu {
for (int i = 0; i < container.getContainerSize(); i++) {
ItemStack item = container.getItem(i);
if (!item.isEmpty()) {
@@ -446,7 +446,7 @@ index 10b2cc20bbf3b70e4e09dbbe14b90506e6366158..1535bb8cec8692e8d26eaff090288f1b
}
diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index 2f8128a11e316a6ee6b283f9a411096e582c03b7..5b93eeba6c03738011551ce18332cebe9e278a8e 100644
index b939c04e954e873cbf60fbe104a3b1ec963d1534..11519e11ffc8268ecd059bb8077600be8537a8e0 100644
--- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -145,7 +145,7 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -458,7 +458,7 @@ index 2f8128a11e316a6ee6b283f9a411096e582c03b7..5b93eeba6c03738011551ce18332cebe
}
@Override
@@ -742,9 +742,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -743,9 +743,9 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (item.isEmpty()) {
// Spigot start - SPIGOT-6693, SimpleContainer#setItem
ItemStack leftover = ItemStack.EMPTY; // Paper - Make hoppers respect inventory max stack size
@@ -8,14 +8,14 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/3e96b237749a960f2
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java
index b3e897a4afee742b5055d652ad7047a660d8ea04..cf8869fac003c73024634078b2f7b36cddda640e 100644
index b3e897a4afee742b5055d652ad7047a660d8ea04..33471f3d0e2cbd54eaf095c19555f8fdaeb55878 100644
--- a/net/minecraft/world/level/ServerExplosion.java
+++ b/net/minecraft/world/level/ServerExplosion.java
@@ -729,6 +729,7 @@ public class ServerExplosion implements Explosion {
public boolean shouldAffectBlocklikeEntities() {
boolean _boolean = this.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING);
boolean flag = this.source == null || this.source.getType() != EntityType.BREEZE_WIND_CHARGE && this.source.getType() != EntityType.WIND_CHARGE;
+ if (fun.bm.lophine.config.modules.misc.OldFeatureConfig.oldExplosionDamageCalculator) flag = flag && (this.source == null || !this.source.isInWater()); // Leaves - Old MC TNT wet explosion no item damage
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldExplosionDamageCalculator) flag = flag && (this.source == null || !this.source.isInWater()); // Leaves - Old MC TNT wet explosion no item damage
return _boolean ? flag : this.blockInteraction.shouldAffectBlocklikeEntities() && flag;
}
@@ -8,7 +8,7 @@ As a part of : Leaves (https://github.com/LeavesMC/Leaves/blob/79d9ef74c2684eb49
Licensed under: GPL-3.0 (https://www.gnu.org/licenses/gpl-3.0.html)
diff --git a/net/minecraft/world/effect/BadOmenMobEffect.java b/net/minecraft/world/effect/BadOmenMobEffect.java
index 80f17f33f670018240c854df589cf90cdeab6e70..cbfb4ae2dc30c2ee98ef37f44a95434a7968e320 100644
index 80f17f33f670018240c854df589cf90cdeab6e70..c9af615ff9120c07787f436dbb6024e54e3a498b 100644
--- a/net/minecraft/world/effect/BadOmenMobEffect.java
+++ b/net/minecraft/world/effect/BadOmenMobEffect.java
@@ -22,6 +22,11 @@ class BadOmenMobEffect extends MobEffect {
@@ -16,7 +16,7 @@ index 80f17f33f670018240c854df589cf90cdeab6e70..cbfb4ae2dc30c2ee98ef37f44a95434a
&& level.getDifficulty() != Difficulty.PEACEFUL
&& level.isVillage(serverPlayer.blockPosition())) {
+ // Leaves start - Revert raid changes
+ if (fun.bm.lophine.config.modules.misc.OldFeatureConfig.oldRaidBehavior) {
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) {
+ return level.getRaids().createOrExtendRaid(serverPlayer, serverPlayer.blockPosition()) == null;
+ }
+ // Leaves end - Revert raid changes
@@ -24,7 +24,7 @@ index 80f17f33f670018240c854df589cf90cdeab6e70..cbfb4ae2dc30c2ee98ef37f44a95434a
if (raidAt == null || raidAt.getRaidOmenLevel() < raidAt.getMaxRaidOmenLevel()) {
serverPlayer.addEffect(new MobEffectInstance(MobEffects.RAID_OMEN, 600, amplifier));
diff --git a/net/minecraft/world/entity/raid/Raid.java b/net/minecraft/world/entity/raid/Raid.java
index 1910bff3f08147bfd63703097e30b9f88c84e337..5188ae86aff3051d45fe5e7d2fcc51233b7074d4 100644
index 1910bff3f08147bfd63703097e30b9f88c84e337..f45aa44a7a17946aeb406a447f18de34320a4fa2 100644
--- a/net/minecraft/world/entity/raid/Raid.java
+++ b/net/minecraft/world/entity/raid/Raid.java
@@ -263,7 +263,7 @@ public class Raid {
@@ -32,7 +32,7 @@ index 1910bff3f08147bfd63703097e30b9f88c84e337..5188ae86aff3051d45fe5e7d2fcc5123
public boolean absorbRaidOmen(ServerPlayer player) {
- MobEffectInstance effect = player.getEffect(MobEffects.RAID_OMEN);
+ MobEffectInstance effect = player.getEffect(fun.bm.lophine.config.modules.misc.OldFeatureConfig.oldRaidBehavior ? MobEffects.BAD_OMEN : MobEffects.RAID_OMEN); // Leaves - old Raid Behavior
+ MobEffectInstance effect = player.getEffect(fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior ? MobEffects.BAD_OMEN : MobEffects.RAID_OMEN); // Leaves - old Raid Behavior
if (effect == null) {
return false;
} else {
@@ -42,7 +42,7 @@ index 1910bff3f08147bfd63703097e30b9f88c84e337..5188ae86aff3051d45fe5e7d2fcc5123
if (flag1) {
- this.waveSpawnPos = this.getValidSpawnPos(level);
+ // Leaves Start - old FindSpawnPosition
+ if (fun.bm.lophine.config.modules.misc.OldFeatureConfig.oldRaidBehavior) {
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) {
+ this.waveSpawnPos = this.preCalcRavagerSpawnLocation(level, this.raidCooldownTicks < 100 ? 1 : 0);
+ } else {
+ this.waveSpawnPos = this.getValidSpawnPos(level);
@@ -58,7 +58,7 @@ index 1910bff3f08147bfd63703097e30b9f88c84e337..5188ae86aff3051d45fe5e7d2fcc5123
- BlockPos blockPos = this.waveSpawnPos.orElseGet(() -> this.findRandomSpawnPos(level, 20));
+ // Leaves Start - old FindSpawnPosition
+ BlockPos blockPos;
+ if (fun.bm.lophine.config.modules.misc.OldFeatureConfig.oldRaidBehavior) {
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior) {
+ blockPos = this.getRavagerSpawnLocation(level, i, 20);
+ } else {
+ blockPos = this.waveSpawnPos.orElseGet(() -> this.findRandomSpawnPos(level, 20));
@@ -72,7 +72,7 @@ index 1910bff3f08147bfd63703097e30b9f88c84e337..5188ae86aff3051d45fe5e7d2fcc5123
}
- if (i > 5) {
+ if (i > (fun.bm.lophine.config.modules.misc.OldFeatureConfig.oldRaidBehavior ? 3 : 5)) { // Leaves - old FindSpawnPosition
+ if (i > (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior ? 3 : 5)) { // Leaves - old FindSpawnPosition
org.bukkit.craftbukkit.event.CraftEventFactory.callRaidStopEvent(level, this, org.bukkit.event.raid.RaidStopEvent.Reason.UNSPAWNABLE); // CraftBukkit
this.stop();
break;
@@ -81,7 +81,7 @@ index 1910bff3f08147bfd63703097e30b9f88c84e337..5188ae86aff3051d45fe5e7d2fcc5123
int i3 = this.center.getZ() + Mth.floor(Mth.sin(f2) * 32.0F * f) + level.random.nextInt(3) * Mth.floor(f);
int height = level.getHeight(Heightmap.Types.WORLD_SURFACE, i2, i3);
- if (Mth.abs(height - this.center.getY()) <= 96) {
+ if (fun.bm.lophine.config.modules.misc.OldFeatureConfig.oldRaidBehavior || Mth.abs(height - this.center.getY()) <= 96) { // Leaves - skippable
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior || Mth.abs(height - this.center.getY()) <= 96) { // Leaves - skippable
mutableBlockPos.set(i2, height, i3);
if (!level.isVillage(mutableBlockPos) || i <= 7) {
int i4 = 10;
@@ -167,7 +167,7 @@ index 1910bff3f08147bfd63703097e30b9f88c84e337..5188ae86aff3051d45fe5e7d2fcc5123
+ // Leaves end - old FindSpawnPosition
}
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
index 3e30989c99cd11c8c94d6fd194d2969e3a7efda6..b1f1bcf7f5ac002550077d5e1d4efd5c67d18063 100644
index 3e30989c99cd11c8c94d6fd194d2969e3a7efda6..2d163f3d5eb1af4d539d24c0256855bbec960de4 100644
--- a/net/minecraft/world/entity/raid/Raider.java
+++ b/net/minecraft/world/entity/raid/Raider.java
@@ -128,6 +128,43 @@ public abstract class Raider extends PatrollingMonster {
@@ -177,7 +177,7 @@ index 3e30989c99cd11c8c94d6fd194d2969e3a7efda6..b1f1bcf7f5ac002550077d5e1d4efd5c
+
+ // Leaves start - Revert raid changes
+ if (this.level() instanceof ServerLevel) {
+ if (fun.bm.lophine.config.modules.misc.OldFeatureConfig.oldRaidBehavior && !this.hasRaid()) {
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.oldRaidBehavior && !this.hasRaid()) {
+ ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
+ net.minecraft.world.entity.player.Player entityhuman = null;
+ if (entity instanceof net.minecraft.world.entity.player.Player player) {
@@ -8,7 +8,7 @@ As part of: Purpur (https://github.com/PurpurMC/Purpur/blob/09f547de09fc5d886f18
Licensed under: MIT (https://github.com/PurpurMC/Purpur/blob/09f547de09fc5d886f18f6d99ff389289766ec9d/LICENSE)
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 593dbcda4b497291eb1ecdc64b947a8d279f8be6..661f797b39853104b16d75ca7ba0eda156a74af3 100644
index 593dbcda4b497291eb1ecdc64b947a8d279f8be6..cb863a36fc67e993956ec3be655e6e4b9764c051 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -1087,6 +1087,10 @@ public abstract class PlayerList {
@@ -17,7 +17,7 @@ index 593dbcda4b497291eb1ecdc64b947a8d279f8be6..661f797b39853104b16d75ca7ba0eda1
} // Paper - Add sendOpLevel API
+
+ // Purpur start - Barrels and enderchests 6 rows
+ player.enderChestSlotCount = fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows < 7 && fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows > 0 ? 9 * fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows : 27;
+ player.enderChestSlotCount = fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows < 7 && fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows > 0 ? 9 * fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows : 27;
+ // Purpur end - Barrels and enderchests 6 rows
}
@@ -70,15 +70,15 @@ index 0fffa384f928ab84451331380968fb4650eafe26..d84a10396395939149da88bcb01be59e
return new ChestMenu(MenuType.GENERIC_9x6, containerId, playerInventory, container, 6);
}
diff --git a/net/minecraft/world/inventory/PlayerEnderChestContainer.java b/net/minecraft/world/inventory/PlayerEnderChestContainer.java
index beb74bc8398de8b48f41af7daef14d624826310e..5dd6e89931d397b8afdb84024ed46b0d06dcf347 100644
index 51148b7b95c93a9e25da70ac9275c63f1458d84c..dba8acfcacfe9a7b7e0fb9943fba49468214616e 100644
--- a/net/minecraft/world/inventory/PlayerEnderChestContainer.java
+++ b/net/minecraft/world/inventory/PlayerEnderChestContainer.java
@@ -25,11 +25,18 @@ public class PlayerEnderChestContainer extends SimpleContainer {
@@ -26,11 +26,18 @@ public class PlayerEnderChestContainer extends SimpleContainer {
}
public PlayerEnderChestContainer(Player owner) {
- super(27);
+ super(fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows < 7 && fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows > 0 ? 9 * fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows : 27);
+ super(fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows < 7 && fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows > 0 ? 9 * fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows : 27);
this.owner = owner;
// CraftBukkit end
}
@@ -94,7 +94,7 @@ index beb74bc8398de8b48f41af7daef14d624826310e..5dd6e89931d397b8afdb84024ed46b0d
this.activeChest = enderChestBlockEntity;
}
diff --git a/net/minecraft/world/level/block/EnderChestBlock.java b/net/minecraft/world/level/block/EnderChestBlock.java
index 5077a9ff7b78801bdc53536a37aee07b8d86ee4d..fe374f08b7829b846b2a1c2ac3ca500ca3e48684 100644
index 5077a9ff7b78801bdc53536a37aee07b8d86ee4d..cef29289b7bc7fdf9613c0cd52f2bf4f715f288d 100644
--- a/net/minecraft/world/level/block/EnderChestBlock.java
+++ b/net/minecraft/world/level/block/EnderChestBlock.java
@@ -85,8 +85,14 @@ public class EnderChestBlock extends AbstractChestBlock<EnderChestBlockEntity> i
@@ -103,7 +103,7 @@ index 5077a9ff7b78801bdc53536a37aee07b8d86ee4d..fe374f08b7829b846b2a1c2ac3ca500c
new SimpleMenuProvider(
- (containerId, playerInventory, player1) -> ChestMenu.threeRows(containerId, playerInventory, enderChestInventory), CONTAINER_TITLE
- )
+ (containerId, playerInventory, player1) -> switch (fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows) {
+ (containerId, playerInventory, player1) -> switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows) {
+ case 6 -> ChestMenu.sixRows(containerId, playerInventory, enderChestInventory);
+ case 5 -> ChestMenu.fiveRows(containerId, playerInventory, enderChestInventory);
+ case 4 -> ChestMenu.fourRows(containerId, playerInventory, enderChestInventory);
@@ -115,7 +115,7 @@ index 5077a9ff7b78801bdc53536a37aee07b8d86ee4d..fe374f08b7829b846b2a1c2ac3ca500c
// Paper end - Fix InventoryOpenEvent cancellation - moved up;
player.awardStat(Stats.OPEN_ENDERCHEST);
diff --git a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
index de99652629c7301a4bc0e9ec48bed9a26a338f0d..4383e87560bb05acf9c50758f38a3cb69ee5c5c7 100644
index de99652629c7301a4bc0e9ec48bed9a26a338f0d..b43445d8313c330a0376aaa4eb872495ebd87b5f 100644
--- a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
+++ b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
@@ -56,7 +56,17 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity implemen
@@ -124,7 +124,7 @@ index de99652629c7301a4bc0e9ec48bed9a26a338f0d..4383e87560bb05acf9c50758f38a3cb6
- private NonNullList<ItemStack> items = NonNullList.withSize(27, ItemStack.EMPTY);
+ // Purpur start - Barrels and enderchests 6 rows
+ private NonNullList<ItemStack> items = NonNullList.withSize(switch (fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.barrelRows) {
+ private NonNullList<ItemStack> items = NonNullList.withSize(switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.barrelRows) {
+ case 6 -> 54;
+ case 5 -> 45;
+ case 4 -> 36;
@@ -143,7 +143,7 @@ index de99652629c7301a4bc0e9ec48bed9a26a338f0d..4383e87560bb05acf9c50758f38a3cb6
public int getContainerSize() {
- return 27;
+ // Purpur start - Barrels and enderchests 6 rows
+ return switch (fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.barrelRows) {
+ return switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.barrelRows) {
+ case 6 -> 54;
+ case 5 -> 45;
+ case 4 -> 36;
@@ -161,7 +161,7 @@ index de99652629c7301a4bc0e9ec48bed9a26a338f0d..4383e87560bb05acf9c50758f38a3cb6
protected AbstractContainerMenu createMenu(int id, Inventory player) {
- return ChestMenu.threeRows(id, player, this);
+ // Purpur start - Barrels and enderchests 6 rows
+ return switch (fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.barrelRows) {
+ return switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.barrelRows) {
+ case 6 -> ChestMenu.sixRows(id, player, this);
+ case 5 -> ChestMenu.fiveRows(id, player, this);
+ case 4 -> ChestMenu.fourRows(id, player, this);
@@ -40,7 +40,7 @@ index 3f4b1c54f9207ba1854a8c8da965cbaca5ea517d..a8348a073682eec31990e9ab963b11ad
if (this.getType().is(EntityTypeTags.IMMUNE_TO_INFESTED)) {
return !effectInstance.is(MobEffects.INFESTED);
diff --git a/net/minecraft/world/entity/raid/Raider.java b/net/minecraft/world/entity/raid/Raider.java
index b1f1bcf7f5ac002550077d5e1d4efd5c67d18063..6120f7b970ff05867524ee9f1433d46843d57483 100644
index 2d163f3d5eb1af4d539d24c0256855bbec960de4..2cc0a7b5f088c29d9343b369b6e71c8a3ebdef75 100644
--- a/net/minecraft/world/entity/raid/Raider.java
+++ b/net/minecraft/world/entity/raid/Raider.java
@@ -158,7 +158,7 @@ public abstract class Raider extends PatrollingMonster {
@@ -5,7 +5,7 @@ Subject: [PATCH] Disable some check for operators
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index d63d8f7523938088bf9efc1c1b8ad9f0583338bb..b40059553089207ab1c6628beefadc674ec43d4e 100644
index f06b9d8ad9512d35f3f460eb77c869690321c67f..e17f9629369f8653b484b4cc71de4874b5faa4d6 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -367,7 +367,7 @@ public class ServerGamePacketListenerImpl
@@ -31,7 +31,7 @@ index cf72cb8b418239b56c755486b03a321672e16bc3..b69c06607ca900beeebf4892a978442d
String awtException = io.papermc.paper.util.ServerEnvironment.awtDependencyCheck();
if (awtException != null) {
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
index c6c6432c2efeb7b95c2894b188cd966321ae3186..1cd9af71ee66df5f277748c0a5a59a30bd57accc 100644
index c93feb64b6088a4878fcdb6e7c733a5f37e9385b..79c911003c7b1c3d94e7e9d3974eeadcc16bde3a 100644
--- a/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
@@ -172,6 +172,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
@@ -5,7 +5,7 @@ Subject: [PATCH] Old zombie reinforcement
diff --git a/net/minecraft/world/entity/monster/Zombie.java b/net/minecraft/world/entity/monster/Zombie.java
index 14d0758aca54d9a25e369dfa8c89c930f27946c9..6f1f26b7f759e56f843e674167470da943785728 100644
index 14d0758aca54d9a25e369dfa8c89c930f27946c9..1324f2c8c0d6571bac36855f08354a84e0f08b70 100644
--- a/net/minecraft/world/entity/monster/Zombie.java
+++ b/net/minecraft/world/entity/monster/Zombie.java
@@ -341,7 +341,7 @@ public class Zombie extends Monster {
@@ -13,7 +13,7 @@ index 14d0758aca54d9a25e369dfa8c89c930f27946c9..6f1f26b7f759e56f843e674167470da9
int floor1 = Mth.floor(this.getY());
int floor2 = Mth.floor(this.getZ());
- EntityType<? extends Zombie> type = this.getType();
+ EntityType<? extends Zombie> type = fun.bm.lophine.config.modules.misc.OldFeatureConfig.oldZombieReinforcement ? EntityType.ZOMBIE : this.getType(); // Lophine - old zombie reinforcement
+ EntityType<? extends Zombie> type = fun.bm.lophine.config.modules.function.OldFeatureConfig.oldZombieReinforcement ? EntityType.ZOMBIE : this.getType(); // Lophine - old zombie reinforcement
Zombie zombie = type.create(level, EntitySpawnReason.REINFORCEMENT);
if (zombie == null) {
return true;
@@ -5,7 +5,7 @@ Subject: [PATCH] Spawn invulnerable time
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index 6b7c92fdf562dfa46eee8e8acbc82b02fc3226c5..144b2c9396b8162f9cce8b343d998907bf7fb5aa 100644
index 6b7c92fdf562dfa46eee8e8acbc82b02fc3226c5..c29e9c6cb2513fe4b01a619e16433893efb44e6f 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -232,6 +232,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -29,7 +29,7 @@ index 6b7c92fdf562dfa46eee8e8acbc82b02fc3226c5..144b2c9396b8162f9cce8b343d998907
return false;
} else {
+ // Lophine start - spawn invulnerable time
+ if (fun.bm.lophine.config.modules.misc.OldFeatureConfig.spawnInvulnerableTime) {
+ if (fun.bm.lophine.config.modules.function.OldFeatureConfig.spawnInvulnerableTime) {
+ if (this.spawnInvulnerableTime > 0 && !damageSource.is(net.minecraft.tags.DamageTypeTags.BYPASSES_INVULNERABILITY)) {
+ return false;
+ }
@@ -8,7 +8,7 @@ As part of: Purpur (https://github.com/PurpurMC/Purpur/blob/09f547de09fc5d886f18
Licensed under: MIT (https://github.com/PurpurMC/Purpur/blob/09f547de09fc5d886f18f6d99ff389289766ec9d/LICENSE)
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
index 2f41a92465b9da28e026297cc3528898bb1c8412..fb5300ec1bd19b3dfd6a2b4106440b9f73c48205 100644
index 2f41a92465b9da28e026297cc3528898bb1c8412..168301a2f1c3081ae15d3695c2dcc72b4538cdfb 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
@@ -148,9 +148,26 @@ public class CraftContainer extends AbstractContainerMenu {
@@ -18,7 +18,7 @@ index 2f41a92465b9da28e026297cc3528898bb1c8412..fb5300ec1bd19b3dfd6a2b4106440b9f
- case BARREL:
- this.delegate = new ChestMenu(net.minecraft.world.inventory.MenuType.GENERIC_9x3, windowId, bottom, top, top.getContainerSize() / 9);
+ // Purpur start - Barrels and enderchests 6 rows
+ this.delegate = new ChestMenu(switch (fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.enderchestRows) {
+ this.delegate = new ChestMenu(switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.enderchestRows) {
+ case 6 -> net.minecraft.world.inventory.MenuType.GENERIC_9x6;
+ case 5 -> net.minecraft.world.inventory.MenuType.GENERIC_9x5;
+ case 4 -> net.minecraft.world.inventory.MenuType.GENERIC_9x4;
@@ -28,7 +28,7 @@ index 2f41a92465b9da28e026297cc3528898bb1c8412..fb5300ec1bd19b3dfd6a2b4106440b9f
+ }, windowId, bottom, top, top.getContainerSize() / 9);
break;
+ case BARREL:
+ this.delegate = new ChestMenu(switch (fun.bm.lophine.config.modules.misc.ContainerExpansionConfig.barrelRows) {
+ this.delegate = new ChestMenu(switch (fun.bm.lophine.config.modules.function.ContainerExpansionConfig.barrelRows) {
+ case 6 -> net.minecraft.world.inventory.MenuType.GENERIC_9x6;
+ case 5 -> net.minecraft.world.inventory.MenuType.GENERIC_9x5;
+ case 4 -> net.minecraft.world.inventory.MenuType.GENERIC_9x4;
@@ -0,0 +1,34 @@
package com.logisticscraft.occlusionculling;
import com.logisticscraft.occlusionculling.util.Vec3d;
public interface DataProvider {
/**
* Prepares the requested chunk. Returns true if the chunk is ready, false when
* not loaded. Should not reload the chunk when the x and y are the same as the
* last request!
*
* @param chunkX
* @param chunkZ
* @return
*/
boolean prepareChunk(int chunkX, int chunkZ);
/**
* Location is inside the chunk.
*
* @param x
* @param y
* @param z
* @return
*/
boolean isOpaqueFullCube(int x, int y, int z);
default void cleanup() {
}
default void checkingPosition(Vec3d[] targetPoints, int size, Vec3d viewerPosition) {
}
}
@@ -0,0 +1,515 @@
package com.logisticscraft.occlusionculling;
import com.logisticscraft.occlusionculling.cache.ArrayOcclusionCache;
import com.logisticscraft.occlusionculling.cache.OcclusionCache;
import com.logisticscraft.occlusionculling.util.MathUtilities;
import com.logisticscraft.occlusionculling.util.Vec3d;
import java.util.Arrays;
import java.util.BitSet;
public class OcclusionCullingInstance {
private static final int ON_MIN_X = 0x01;
private static final int ON_MAX_X = 0x02;
private static final int ON_MIN_Y = 0x04;
private static final int ON_MAX_Y = 0x08;
private static final int ON_MIN_Z = 0x10;
private static final int ON_MAX_Z = 0x20;
private final int reach;
private final double aabbExpansion;
private final DataProvider provider;
private final OcclusionCache cache;
// Reused allocated data structures
private final BitSet skipList = new BitSet(); // Grows bigger in case some mod introduces giant hitboxes
private final Vec3d[] targetPoints = new Vec3d[15];
private final Vec3d targetPos = new Vec3d(0, 0, 0);
private final int[] cameraPos = new int[3];
private final boolean[] dotselectors = new boolean[14];
private boolean allowRayChecks = false;
private final int[] lastHitBlock = new int[3];
private boolean allowWallClipping = false;
public OcclusionCullingInstance(int maxDistance, DataProvider provider) {
this(maxDistance, provider, new ArrayOcclusionCache(maxDistance), 0.5);
}
public OcclusionCullingInstance(int maxDistance, DataProvider provider, OcclusionCache cache, double aabbExpansion) {
this.reach = maxDistance;
this.provider = provider;
this.cache = cache;
this.aabbExpansion = aabbExpansion;
for (int i = 0; i < targetPoints.length; i++) {
targetPoints[i] = new Vec3d(0, 0, 0);
}
}
public boolean isAABBVisible(Vec3d aabbMin, Vec3d aabbMax, Vec3d viewerPosition) {
try {
int maxX = MathUtilities.floor(aabbMax.x
+ aabbExpansion);
int maxY = MathUtilities.floor(aabbMax.y
+ aabbExpansion);
int maxZ = MathUtilities.floor(aabbMax.z
+ aabbExpansion);
int minX = MathUtilities.floor(aabbMin.x
- aabbExpansion);
int minY = MathUtilities.floor(aabbMin.y
- aabbExpansion);
int minZ = MathUtilities.floor(aabbMin.z
- aabbExpansion);
cameraPos[0] = MathUtilities.floor(viewerPosition.x);
cameraPos[1] = MathUtilities.floor(viewerPosition.y);
cameraPos[2] = MathUtilities.floor(viewerPosition.z);
Relative relX = Relative.from(minX, maxX, cameraPos[0]);
Relative relY = Relative.from(minY, maxY, cameraPos[1]);
Relative relZ = Relative.from(minZ, maxZ, cameraPos[2]);
if (relX == Relative.INSIDE && relY == Relative.INSIDE && relZ == Relative.INSIDE) {
return true; // We are inside of the AABB, don't cull
}
skipList.clear();
// Just check the cache first
int id = 0;
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
for (int z = minZ; z <= maxZ; z++) {
int cachedValue = getCacheValue(x, y, z);
if (cachedValue == 1) {
// non-occluding
return true;
}
if (cachedValue != 0) {
// was checked and it wasn't visible
skipList.set(id);
}
id++;
}
}
}
// only after the first hit wall the cache becomes valid.
allowRayChecks = false;
// since the cache wasn't helpfull
id = 0;
for (int x = minX; x <= maxX; x++) {
byte visibleOnFaceX = 0;
byte faceEdgeDataX = 0;
faceEdgeDataX |= (x == minX) ? ON_MIN_X : 0;
faceEdgeDataX |= (x == maxX) ? ON_MAX_X : 0;
visibleOnFaceX |= (x == minX && relX == Relative.POSITIVE) ? ON_MIN_X : 0;
visibleOnFaceX |= (x == maxX && relX == Relative.NEGATIVE) ? ON_MAX_X : 0;
for (int y = minY; y <= maxY; y++) {
byte faceEdgeDataY = faceEdgeDataX;
byte visibleOnFaceY = visibleOnFaceX;
faceEdgeDataY |= (y == minY) ? ON_MIN_Y : 0;
faceEdgeDataY |= (y == maxY) ? ON_MAX_Y : 0;
visibleOnFaceY |= (y == minY && relY == Relative.POSITIVE) ? ON_MIN_Y : 0;
visibleOnFaceY |= (y == maxY && relY == Relative.NEGATIVE) ? ON_MAX_Y : 0;
for (int z = minZ; z <= maxZ; z++) {
byte faceEdgeData = faceEdgeDataY;
byte visibleOnFace = visibleOnFaceY;
faceEdgeData |= (z == minZ) ? ON_MIN_Z : 0;
faceEdgeData |= (z == maxZ) ? ON_MAX_Z : 0;
visibleOnFace |= (z == minZ && relZ == Relative.POSITIVE) ? ON_MIN_Z : 0;
visibleOnFace |= (z == maxZ && relZ == Relative.NEGATIVE) ? ON_MAX_Z : 0;
if (skipList.get(id)) { // was checked and it wasn't visible
id++;
continue;
}
if (visibleOnFace != 0) {
targetPos.set(x, y, z);
if (isVoxelVisible(viewerPosition, targetPos, faceEdgeData, visibleOnFace)) {
return true;
}
}
id++;
}
}
}
return false;
} catch (Throwable t) {
// Failsafe
t.printStackTrace();
}
return true;
}
/**
* @param viewerPosition
* @param position
* @param faceData contains rather this Block is on the outside for a given face
* @param visibleOnFace contains rather a face should be concidered
* @return
*/
private boolean isVoxelVisible(Vec3d viewerPosition, Vec3d position, byte faceData, byte visibleOnFace) {
int targetSize = 0;
Arrays.fill(dotselectors, false);
if ((visibleOnFace & ON_MIN_X) == ON_MIN_X) {
dotselectors[0] = true;
if ((faceData & ~ON_MIN_X) != 0) {
dotselectors[1] = true;
dotselectors[4] = true;
dotselectors[5] = true;
}
dotselectors[8] = true;
}
if ((visibleOnFace & ON_MIN_Y) == ON_MIN_Y) {
dotselectors[0] = true;
if ((faceData & ~ON_MIN_Y) != 0) {
dotselectors[3] = true;
dotselectors[4] = true;
dotselectors[7] = true;
}
dotselectors[9] = true;
}
if ((visibleOnFace & ON_MIN_Z) == ON_MIN_Z) {
dotselectors[0] = true;
if ((faceData & ~ON_MIN_Z) != 0) {
dotselectors[1] = true;
dotselectors[4] = true;
dotselectors[5] = true;
}
dotselectors[10] = true;
}
if ((visibleOnFace & ON_MAX_X) == ON_MAX_X) {
dotselectors[4] = true;
if ((faceData & ~ON_MAX_X) != 0) {
dotselectors[5] = true;
dotselectors[6] = true;
dotselectors[7] = true;
}
dotselectors[11] = true;
}
if ((visibleOnFace & ON_MAX_Y) == ON_MAX_Y) {
dotselectors[1] = true;
if ((faceData & ~ON_MAX_Y) != 0) {
dotselectors[2] = true;
dotselectors[5] = true;
dotselectors[6] = true;
}
dotselectors[12] = true;
}
if ((visibleOnFace & ON_MAX_Z) == ON_MAX_Z) {
dotselectors[2] = true;
if ((faceData & ~ON_MAX_Z) != 0) {
dotselectors[3] = true;
dotselectors[6] = true;
dotselectors[7] = true;
}
dotselectors[13] = true;
}
if (dotselectors[0]) targetPoints[targetSize++].setAdd(position, 0.05, 0.05, 0.05);
if (dotselectors[1]) targetPoints[targetSize++].setAdd(position, 0.05, 0.95, 0.05);
if (dotselectors[2]) targetPoints[targetSize++].setAdd(position, 0.05, 0.95, 0.95);
if (dotselectors[3]) targetPoints[targetSize++].setAdd(position, 0.05, 0.05, 0.95);
if (dotselectors[4]) targetPoints[targetSize++].setAdd(position, 0.95, 0.05, 0.05);
if (dotselectors[5]) targetPoints[targetSize++].setAdd(position, 0.95, 0.95, 0.05);
if (dotselectors[6]) targetPoints[targetSize++].setAdd(position, 0.95, 0.95, 0.95);
if (dotselectors[7]) targetPoints[targetSize++].setAdd(position, 0.95, 0.05, 0.95);
// middle points
if (dotselectors[8]) targetPoints[targetSize++].setAdd(position, 0.05, 0.5, 0.5);
if (dotselectors[9]) targetPoints[targetSize++].setAdd(position, 0.5, 0.05, 0.5);
if (dotselectors[10]) targetPoints[targetSize++].setAdd(position, 0.5, 0.5, 0.05);
if (dotselectors[11]) targetPoints[targetSize++].setAdd(position, 0.95, 0.5, 0.5);
if (dotselectors[12]) targetPoints[targetSize++].setAdd(position, 0.5, 0.95, 0.5);
if (dotselectors[13]) targetPoints[targetSize++].setAdd(position, 0.5, 0.5, 0.95);
return isVisible(viewerPosition, targetPoints, targetSize);
}
private boolean rayIntersection(int[] b, Vec3d rayOrigin, Vec3d rayDir) {
Vec3d rInv = new Vec3d(1, 1, 1).div(rayDir);
double t1 = (b[0] - rayOrigin.x) * rInv.x;
double t2 = (b[0] + 1 - rayOrigin.x) * rInv.x;
double t3 = (b[1] - rayOrigin.y) * rInv.y;
double t4 = (b[1] + 1 - rayOrigin.y) * rInv.y;
double t5 = (b[2] - rayOrigin.z) * rInv.z;
double t6 = (b[2] + 1 - rayOrigin.z) * rInv.z;
double tmin = Math.max(Math.max(Math.min(t1, t2), Math.min(t3, t4)), Math.min(t5, t6));
double tmax = Math.min(Math.min(Math.max(t1, t2), Math.max(t3, t4)), Math.max(t5, t6));
// if tmax > 0, ray (line) is intersecting AABB, but the whole AABB is behind us
if (tmax > 0) {
return false;
}
// if tmin > tmax, ray doesn't intersect AABB
if (tmin > tmax) {
return false;
}
return true;
}
/**
* returns the grid cells that intersect with this Vec3d<br>
* <a href=
* "http://playtechs.blogspot.de/2007/03/raytracing-on-grid.html">http://playtechs.blogspot.de/2007/03/raytracing-on-grid.html</a>
* <p>
* Caching assumes that all Vec3d's are inside the same block
*/
private boolean isVisible(Vec3d start, Vec3d[] targets, int size) {
// start cell coordinate
int x = cameraPos[0];
int y = cameraPos[1];
int z = cameraPos[2];
for (int v = 0; v < size; v++) {
// ray-casting target
Vec3d target = targets[v];
double relativeX = start.x - target.getX();
double relativeY = start.y - target.getY();
double relativeZ = start.z - target.getZ();
if (allowRayChecks && rayIntersection(lastHitBlock, start, new Vec3d(relativeX, relativeY, relativeZ).normalize())) {
continue;
}
// horizontal and vertical cell amount spanned
double dimensionX = Math.abs(relativeX);
double dimensionY = Math.abs(relativeY);
double dimensionZ = Math.abs(relativeZ);
// distance between horizontal intersection points with cell border as a
// fraction of the total Vec3d length
double dimFracX = 1f / dimensionX;
// distance between vertical intersection points with cell border as a fraction
// of the total Vec3d length
double dimFracY = 1f / dimensionY;
double dimFracZ = 1f / dimensionZ;
// total amount of intersected cells
int intersectCount = 1;
// 1, 0 or -1
// determines the direction of the next cell (horizontally / vertically)
int x_inc, y_inc, z_inc;
// the distance to the next horizontal / vertical intersection point with a cell
// border as a fraction of the total Vec3d length
double t_next_y, t_next_x, t_next_z;
if (dimensionX == 0f) {
x_inc = 0;
t_next_x = dimFracX; // don't increment horizontally because the Vec3d is perfectly vertical
} else if (target.x > start.x) {
x_inc = 1; // target point is horizontally greater than starting point so increment every
// step by 1
intersectCount += MathUtilities.floor(target.x) - x; // increment total amount of intersecting cells
t_next_x = (float) ((x + 1 - start.x) * dimFracX); // calculate the next horizontal
// intersection
// point based on the position inside
// the first cell
} else {
x_inc = -1; // target point is horizontally smaller than starting point so reduce every step
// by 1
intersectCount += x - MathUtilities.floor(target.x); // increment total amount of intersecting cells
t_next_x = (float) ((start.x - x)
* dimFracX); // calculate the next horizontal
// intersection point
// based on the position inside
// the first cell
}
if (dimensionY == 0f) {
y_inc = 0;
t_next_y = dimFracY; // don't increment vertically because the Vec3d is perfectly horizontal
} else if (target.y > start.y) {
y_inc = 1; // target point is vertically greater than starting point so increment every
// step by 1
intersectCount += MathUtilities.floor(target.y) - y; // increment total amount of intersecting cells
t_next_y = (float) ((y + 1 - start.y)
* dimFracY); // calculate the next vertical
// intersection
// point based on the position inside
// the first cell
} else {
y_inc = -1; // target point is vertically smaller than starting point so reduce every step
// by 1
intersectCount += y - MathUtilities.floor(target.y); // increment total amount of intersecting cells
t_next_y = (float) ((start.y - y)
* dimFracY); // calculate the next vertical intersection
// point
// based on the position inside
// the first cell
}
if (dimensionZ == 0f) {
z_inc = 0;
t_next_z = dimFracZ; // don't increment vertically because the Vec3d is perfectly horizontal
} else if (target.z > start.z) {
z_inc = 1; // target point is vertically greater than starting point so increment every
// step by 1
intersectCount += MathUtilities.floor(target.z) - z; // increment total amount of intersecting cells
t_next_z = (float) ((z + 1 - start.z)
* dimFracZ); // calculate the next vertical
// intersection
// point based on the position inside
// the first cell
} else {
z_inc = -1; // target point is vertically smaller than starting point so reduce every step
// by 1
intersectCount += z - MathUtilities.floor(target.z); // increment total amount of intersecting cells
t_next_z = (float) ((start.z - z)
* dimFracZ); // calculate the next vertical intersection
// point
// based on the position inside
// the first cell
}
boolean finished = stepRay(start, x, y, z,
dimFracX, dimFracY, dimFracZ, intersectCount, x_inc, y_inc,
z_inc, t_next_y, t_next_x, t_next_z);
provider.cleanup();
if (finished) {
cacheResult(targets[0], true);
return true;
} else {
allowRayChecks = true;
}
}
cacheResult(targets[0], false);
return false;
}
private boolean stepRay(Vec3d start, int currentX, int currentY,
int currentZ, double distInX, double distInY,
double distInZ, int n, int x_inc, int y_inc,
int z_inc, double t_next_y, double t_next_x,
double t_next_z) {
allowWallClipping = true; // initially allow rays to go through walls till they are on the outside
// iterate through all intersecting cells (n times)
for (; n > 1; n--) { // n-1 times because we don't want to check the last block
// towards - where from
// get cached value, 0 means uncached (default)
int cVal = getCacheValue(currentX, currentY, currentZ);
if (cVal == 2 && !allowWallClipping) {
// block cached as occluding, stop ray
lastHitBlock[0] = currentX;
lastHitBlock[1] = currentY;
lastHitBlock[2] = currentZ;
return false;
}
if (cVal == 0) {
// save current cell
int chunkX = currentX >> 4;
int chunkZ = currentZ >> 4;
if (!provider.prepareChunk(chunkX, chunkZ)) { // Chunk not ready
return false;
}
if (provider.isOpaqueFullCube(currentX, currentY, currentZ)) {
if (!allowWallClipping) {
cache.setLastHidden();
lastHitBlock[0] = currentX;
lastHitBlock[1] = currentY;
lastHitBlock[2] = currentZ;
return false;
}
} else {
// outside of wall, now clipping is not allowed
allowWallClipping = false;
cache.setLastVisible();
}
}
if (cVal == 1) {
// outside of wall, now clipping is not allowed
allowWallClipping = false;
}
if (t_next_y < t_next_x && t_next_y < t_next_z) { // next cell is upwards/downwards because the distance to
// the next vertical
// intersection point is smaller than to the next horizontal intersection point
currentY += y_inc; // move up/down
t_next_y += distInY; // update next vertical intersection point
} else if (t_next_x < t_next_y && t_next_x < t_next_z) { // next cell is right/left
currentX += x_inc; // move right/left
t_next_x += distInX; // update next horizontal intersection point
} else {
currentZ += z_inc; // move right/left
t_next_z += distInZ; // update next horizontal intersection point
}
}
return true;
}
// -1 = invalid location, 0 = not checked yet, 1 = visible, 2 = occluding
private int getCacheValue(int x, int y, int z) {
x -= cameraPos[0];
y -= cameraPos[1];
z -= cameraPos[2];
if (Math.abs(x) > reach - 2 || Math.abs(y) > reach - 2
|| Math.abs(z) > reach - 2) {
return -1;
}
// check if target is already known
return cache.getState(x + reach, y + reach, z + reach);
}
private void cacheResult(int x, int y, int z, boolean result) {
int cx = x - cameraPos[0] + reach;
int cy = y - cameraPos[1] + reach;
int cz = z - cameraPos[2] + reach;
if (result) {
cache.setVisible(cx, cy, cz);
} else {
cache.setHidden(cx, cy, cz);
}
}
private void cacheResult(Vec3d vector, boolean result) {
int cx = MathUtilities.floor(vector.x) - cameraPos[0] + reach;
int cy = MathUtilities.floor(vector.y) - cameraPos[1] + reach;
int cz = MathUtilities.floor(vector.z) - cameraPos[2] + reach;
if (result) {
cache.setVisible(cx, cy, cz);
} else {
cache.setHidden(cx, cy, cz);
}
}
public void resetCache() {
this.cache.resetCache();
}
private enum Relative {
INSIDE, POSITIVE, NEGATIVE;
public static Relative from(int min, int max, int pos) {
if (max > pos && min > pos) {
return POSITIVE;
} else if (min < pos && max < pos) {
return NEGATIVE;
}
return INSIDE;
}
}
}
@@ -0,0 +1,57 @@
package com.logisticscraft.occlusionculling.cache;
import java.util.Arrays;
public class ArrayOcclusionCache implements OcclusionCache {
private final int reachX2;
private final byte[] cache;
private int positionKey;
private int entry;
private int offset;
public ArrayOcclusionCache(int reach) {
this.reachX2 = reach * 2;
this.cache = new byte[(reachX2 * reachX2 * reachX2) / 4];
}
@Override
public void resetCache() {
Arrays.fill(cache, (byte) 0);
}
@Override
public void setVisible(int x, int y, int z) {
positionKey = x + y * reachX2 + z * reachX2 * reachX2;
entry = positionKey / 4;
offset = (positionKey % 4) * 2;
cache[entry] |= 1 << offset;
}
@Override
public void setHidden(int x, int y, int z) {
positionKey = x + y * reachX2 + z * reachX2 * reachX2;
entry = positionKey / 4;
offset = (positionKey % 4) * 2;
cache[entry] |= 1 << offset + 1;
}
@Override
public int getState(int x, int y, int z) {
positionKey = x + y * reachX2 + z * reachX2 * reachX2;
entry = positionKey / 4;
offset = (positionKey % 4) * 2;
return cache[entry] >> offset & 3;
}
@Override
public void setLastVisible() {
cache[entry] |= 1 << offset;
}
@Override
public void setLastHidden() {
cache[entry] |= 1 << offset + 1;
}
}
@@ -0,0 +1,17 @@
package com.logisticscraft.occlusionculling.cache;
public interface OcclusionCache {
void resetCache();
void setVisible(int x, int y, int z);
void setHidden(int x, int y, int z);
int getState(int x, int y, int z);
void setLastHidden();
void setLastVisible();
}
@@ -0,0 +1,25 @@
package com.logisticscraft.occlusionculling.util;
/**
* Contains MathHelper methods
*/
public final class MathUtilities {
private MathUtilities() {
}
public static int floor(double d) {
int i = (int) d;
return d < (double) i ? i - 1 : i;
}
public static int fastFloor(double d) {
return (int) (d + 1024.0) - 1024;
}
public static int ceil(double d) {
int i = (int) d;
return d > (double) i ? i + 1 : i;
}
}
@@ -0,0 +1,87 @@
package com.logisticscraft.occlusionculling.util;
public class Vec3d {
public double x;
public double y;
public double z;
public Vec3d(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getZ() {
return z;
}
public void set(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public void setAdd(Vec3d vec, double x, double y, double z) {
this.x = vec.x + x;
this.y = vec.y + y;
this.z = vec.z + z;
}
public Vec3d div(Vec3d rayDir) {
this.x /= rayDir.x;
this.z /= rayDir.z;
this.y /= rayDir.y;
return this;
}
public Vec3d normalize() {
double mag = Math.sqrt(x * x + y * y + z * z);
this.x /= mag;
this.y /= mag;
this.z /= mag;
return this;
}
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof Vec3d)) {
return false;
}
Vec3d vec3d = (Vec3d) other;
if (Double.compare(vec3d.x, x) != 0) {
return false;
}
if (Double.compare(vec3d.y, y) != 0) {
return false;
}
return Double.compare(vec3d.z, z) == 0;
}
@Override
public int hashCode() {
long l = Double.doubleToLongBits(x);
int i = (int) (l ^ l >>> 32);
l = Double.doubleToLongBits(y);
i = 31 * i + (int) (l ^ l >>> 32);
l = Double.doubleToLongBits(z);
i = 31 * i + (int) (l ^ l >>> 32);
return i;
}
@Override
public String toString() {
return "(" + x + ", " + y + ", " + z + ")";
}
}
@@ -1,9 +1,11 @@
package fun.bm.lophine.config.modules.experiment;
import me.earthme.luminol.config.EnumConfigCategory;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(configAttribution = EnumConfigCategory.EXPERIMENT, mainName = "command")
public class CommandConfig implements IConfigModule {
@ConfigInfo(baseName = "tick_command_enabled", comments =
"""
@@ -15,14 +17,4 @@ public class CommandConfig implements IConfigModule {
Allow to use datapack command
--- datapack hot-update unsupported, please restart server""")
public static boolean datapack = false;
@Override
public EnumConfigCategory getCategory() {
return EnumConfigCategory.EXPERIMENT;
}
@Override
public String getBaseName() {
return "command";
}
}
@@ -1,22 +1,14 @@
package fun.bm.lophine.config.modules.experiment;
import me.earthme.luminol.config.EnumConfigCategory;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(configAttribution = EnumConfigCategory.EXPERIMENT, mainName = "entity_damage_source_trace")
public class EntityDamageSourceTraceConfig implements IConfigModule {
@ConfigInfo(baseName = "enabled", comments =
"""
Allow trace damage source cross different Region Scheduler.""")
public static boolean enabled = false;
@Override
public EnumConfigCategory getCategory() {
return EnumConfigCategory.EXPERIMENT;
}
@Override
public String getBaseName() {
return "entity_damage_source_trace";
}
}
@@ -1,9 +1,11 @@
package fun.bm.lophine.config.modules.experiment;
import me.earthme.luminol.config.EnumConfigCategory;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(configAttribution = EnumConfigCategory.EXPERIMENT, mainName = "ray_tracking_entity_tracker")
public class RayTrackingEntityTrackerConfig implements IConfigModule {
@ConfigInfo(baseName = "enabled")
public static boolean enabled = false;
@@ -15,14 +17,4 @@ public class RayTrackingEntityTrackerConfig implements IConfigModule {
public static int tracingDistance = 48;
@ConfigInfo(baseName = "hitbox_limit")
public static int hitboxLimit = 50;
@Override
public EnumConfigCategory getCategory() {
return EnumConfigCategory.EXPERIMENT;
}
@Override
public String getBaseName() {
return "ray_tracking_entity_tracker";
}
}
@@ -1,24 +1,16 @@
package fun.bm.lophine.config.modules.experiment;
import me.earthme.luminol.config.EnumConfigCategory;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(configAttribution = EnumConfigCategory.EXPERIMENT, mainName = "waypoint_bar")
public class WaypointConfig implements IConfigModule {
@TransformedConfig(name = "enable-waypoint", category = {"experiment", "waypoint bar"})
@ConfigInfo(baseName = "enabled", comments =
"""
Enable waypoint bar unsafe""")
public static boolean forceEnableWaypointUnsafe = false;
@Override
public EnumConfigCategory getCategory() {
return EnumConfigCategory.EXPERIMENT;
}
@Override
public String getBaseName() {
return "waypoint_bar";
}
}
@@ -1,25 +0,0 @@
package fun.bm.lophine.config.modules.fixes;
import me.earthme.luminol.config.EnumConfigCategory;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
public class DisableEndCrystalCheckConfig implements IConfigModule {
@TransformedConfig(name = "disable_end_crystal_check", category = {"misc", "end_crystal"})
@ConfigInfo(baseName = "disable_end_crystal_check", comments =
"""
Disable paper's End Crystal position check.
It reverts to vanilla respawn dragon logic.""")
public static boolean disableCheck = false;
@Override
public EnumConfigCategory getCategory() {
return EnumConfigCategory.FIXES;
}
@Override
public String getBaseName() {
return "end_crystal";
}
}
@@ -0,0 +1,15 @@
package fun.bm.lophine.config.modules.fixes;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(configAttribution = EnumConfigCategory.FIXES, mainName = "end-void-ring")
public class EndVoidRingsConfig implements IConfigModule {
@TransformedConfig(name = "enabled", category = {"gameplay", "end_void_rings"})
@ConfigInfo(baseName = "enabled", comments = """
If enabled, it will generate end void rings, like MC-159283.""")
public static boolean enabled = false;
}
@@ -1,35 +1,32 @@
package fun.bm.lophine.config.modules.misc;
package fun.bm.lophine.config.modules.function;
import me.earthme.luminol.config.EnumConfigCategory;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "container_expansion")
public class ContainerExpansionConfig implements IConfigModule {
@TransformedConfig(name = "barrel_rows", category = {"misc", "container_expansion"})
@ConfigInfo(baseName = "barrel_rows", comments =
"""
range: 1~6""")
public static int barrelRows = 3;
@TransformedConfig(name = "enderchest_rows", category = {"misc", "container_expansion"})
@ConfigInfo(baseName = "enderchest_rows", comments =
"""
range: 1~6""")
public static int enderchestRows = 3;
@TransformedConfig(name = "shulker_stackable_count", category = {"misc", "container_expansion"})
@ConfigInfo(baseName = "shulker_stackable_count", comments =
"""
range: 1~64""")
public static int shulkerCount = 1;
@TransformedConfig(name = "same_nbt_shulker_stackable", category = {"misc", "container_expansion"})
@ConfigInfo(baseName = "same_nbt_shulker_stackable")
public static boolean nbtShulkerStackable = false;
@Override
public EnumConfigCategory getCategory() {
return EnumConfigCategory.MISC;
}
@Override
public String getBaseName() {
return "container_expansion";
}
}
@@ -0,0 +1,16 @@
package fun.bm.lophine.config.modules.function;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "language")
public class LanguageConfig implements IConfigModule {
@TransformedConfig(name = "lang", category = {"optimizations", "language"})
@ConfigInfo(baseName = "lang", comments = """
Please use the key from https://minecraft.wiki/w/Language
Sample of format: en_us zh_cn zh_hk zh_tw""")
public static String lang = "en_us";
}
@@ -1,31 +1,27 @@
package fun.bm.lophine.config.modules.misc;
package fun.bm.lophine.config.modules.function;
import me.earthme.luminol.config.EnumConfigCategory;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "old-feature")
public class OldFeatureConfig implements IConfigModule {
@TransformedConfig(name = "spawn_invulnerable_time", category = {"misc", "old-feature"})
@ConfigInfo(baseName = "spawn_invulnerable_time")
public static boolean spawnInvulnerableTime = false;
@TransformedConfig(name = "old_zombie_reinforcement", category = {"misc", "old-feature"})
@ConfigInfo(baseName = "old_zombie_reinforcement")
public static boolean oldZombieReinforcement = false;
@TransformedConfig(name = "old_explosion_damage_calculator", category = {"misc", "old-feature"})
@ConfigInfo(baseName = "old_explosion_damage_calculator")
public static boolean oldExplosionDamageCalculator = false;
@TransformedConfig(name = "old_raid_behavior", category = {"misc", "old-feature"})
@TransformedConfig(name = "give_bad_omen_when_kill_raid_captain", category = {"misc", "revert_raid_changes"}, transformComments = false)
@ConfigInfo(baseName = "old_raid_behavior")
public static boolean oldRaidBehavior = false;
@Override
public EnumConfigCategory getCategory() {
return EnumConfigCategory.MISC;
}
@Override
public String getBaseName() {
return "old-feature";
}
}
@@ -1,24 +1,17 @@
package fun.bm.lophine.config.modules.misc;
package fun.bm.lophine.config.modules.function;
import me.earthme.luminol.config.EnumConfigCategory;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "redstone")
public class RedStoneConfig implements IConfigModule {
@TransformedConfig(name = "shears_rotate", category = {"misc", "redstone"})
@TransformedConfig(name = "allow_skip_cooldown", category = {"misc", "redstone"})
@ConfigInfo(baseName = "shears_rotate", comments =
"""
Allows you to use the Shears to right-click to rotate the block.""")
public static boolean shears = false;
@Override
public EnumConfigCategory getCategory() {
return EnumConfigCategory.MISC;
}
@Override
public String getBaseName() {
return "redstone";
}
}
@@ -0,0 +1,48 @@
package fun.bm.lophine.config.modules.function;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
import java.util.List;
@ConfigClassInfo(configAttribution = EnumConfigCategory.FUNCTION, mainName = "survux-protocol")
public class SurvuxProtocolConfig implements IConfigModule {
@TransformedConfig(name = "entity-protocol", category = {"misc", "survux-protocol"})
@ConfigInfo(baseName = "entity-protocol")
public static boolean entityProtocol = false;
@TransformedConfig(name = "hud-logger-protocol", category = {"misc", "survux-protocol"})
@ConfigInfo(baseName = "hud-logger-protocol")
public static boolean hudLoggerProtocol = false;
@TransformedConfig(name = "hud-metadata-protocol", category = {"misc", "survux-protocol"})
@ConfigInfo(baseName = "hud-metadata-protocol")
public static boolean hudMetadataProtocol = false;
@TransformedConfig(name = "hud-metadata-share-seed", category = {"misc", "survux-protocol"})
@ConfigInfo(baseName = "hud-metadata-share-seed")
public static boolean hudMetadataShareSeed = false;
@TransformedConfig(name ="structure-protocol", category = {"misc", "survux-protocol"})
@ConfigInfo(baseName = "structure-protocol")
public static boolean structureProtocol = false;
@TransformedConfig(name = "hud-enabled-loggers", category = {"misc", "survux-protocol"})
@ConfigInfo(baseName = "hud-enabled-loggers")
public static List<String> hudEnabledLoggers = List.of("tps", "mob_caps");
@TransformedConfig(name = "hud-update-interval", category = {"misc", "survux-protocol"})
@ConfigInfo(baseName = "hud-update-interval")
public static int hudUpdateInterval = 1;
@TransformedConfig(name = "litematics-enabled", category = {"misc", "survux-protocol"})
@ConfigInfo(baseName = "litematics-enabled")
public static boolean litematicsEnabled = false;
@TransformedConfig(name = "litematics-max-nbt-size", category = {"misc", "survux-protocol"})
@ConfigInfo(baseName = "litematics-max-nbt-size")
public static int litematicsMaxNbtSize = 2097152;
}
@@ -0,0 +1,18 @@
package fun.bm.lophine.config.modules.function;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(configAttribution = EnumConfigCategory.MISC, mainName = "villager")
public class VillagerConfig implements IConfigModule {
@TransformedConfig(name = "villager-infinite-trade", category = {"misc", "villager"})
@TransformedConfig(name = "villager-infinite-trade", category = {"misc", "villager-config"})
@ConfigInfo(baseName = "villager-infinite-trade", comments =
"""
Allow villager infinite trade (limit of 524288 times)
---- we won't edit saved data, only edit in send data to client.""")
public static boolean villagerInfiniteTrade = false;
}
@@ -1,9 +1,11 @@
package fun.bm.lophine.config.modules.misc;
import me.earthme.luminol.config.EnumConfigCategory;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(configAttribution = EnumConfigCategory.MISC, mainName = "disable-check")
public class DisableCheckConfig implements IConfigModule {
@ConfigInfo(baseName = "disable-op-move-check", comments = """
Disable the check for the operator's move check""")
@@ -12,14 +14,4 @@ public class DisableCheckConfig implements IConfigModule {
@ConfigInfo(baseName = "disable-op-fly-check", comments = """
Disable the check for the operator's fly check""")
public static boolean disableOpFlyCheck = false;
@Override
public EnumConfigCategory getCategory() {
return EnumConfigCategory.MISC;
}
@Override
public String getBaseName() {
return "disable-check";
}
}
@@ -1,46 +0,0 @@
package fun.bm.lophine.config.modules.misc;
import me.earthme.luminol.config.EnumConfigCategory;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigInfo;
import java.util.List;
public class SurvuxProtocolConfig implements IConfigModule {
@ConfigInfo(baseName = "entity-protocol")
public static boolean entityProtocol = false;
@ConfigInfo(baseName = "hud-logger-protocol")
public static boolean hudLoggerProtocol = false;
@ConfigInfo(baseName = "hud-metadata-protocol")
public static boolean hudMetadataProtocol = false;
@ConfigInfo(baseName = "hud-metadata-share-seed")
public static boolean hudMetadataShareSeed = false;
@ConfigInfo(baseName = "structure-protocol")
public static boolean structureProtocol = false;
@ConfigInfo(baseName = "hud-enabled-loggers")
public static List<String> hudEnabledLoggers = List.of("tps", "mob_caps");
@ConfigInfo(baseName = "hud-update-interval")
public static int hudUpdateInterval = 1;
@ConfigInfo(baseName = "litematics-enabled")
public static boolean litematicsEnabled = false;
@ConfigInfo(baseName = "litematics-max-nbt-size")
public static int litematicsMaxNbtSize = 2097152;
@Override
public EnumConfigCategory getCategory() {
return EnumConfigCategory.MISC;
}
@Override
public String getBaseName() {
return "servux-protocol";
}
}
@@ -1,23 +0,0 @@
package fun.bm.lophine.config.modules.misc;
import me.earthme.luminol.config.EnumConfigCategory;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigInfo;
public class VillagerConfig implements IConfigModule {
@ConfigInfo(baseName = "villager-infinite-trade", comments =
"""
Allow villager infinite trade (limit of 524288 times)
---- we won't edit saved data, only edit in send data to client.""")
public static boolean villagerInfiniteTrade = false;
@Override
public EnumConfigCategory getCategory() {
return EnumConfigCategory.MISC;
}
@Override
public String getBaseName() {
return "villager-config";
}
}
@@ -1,22 +0,0 @@
package fun.bm.lophine.config.modules.optimizations;
import me.earthme.luminol.config.EnumConfigCategory;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigInfo;
public class LanguageConfig implements IConfigModule {
@ConfigInfo(baseName = "lang", comments = """
Please use the key from https://minecraft.wiki/w/Language
Sample of format: en_us zh_cn zh_hk zh_tw""")
public static String lang = "en_us";
@Override
public EnumConfigCategory getCategory() {
return EnumConfigCategory.OPTIMIZATIONS;
}
@Override
public String getBaseName() {
return "language";
}
}
@@ -1,11 +1,15 @@
package fun.bm.lophine.config.modules.removed;
import me.earthme.luminol.config.EnumConfigCategory;
import me.earthme.luminol.config.IConfigModule;
import me.earthme.luminol.config.flags.ConfigClassInfo;
import me.earthme.luminol.config.flags.ConfigInfo;
import me.earthme.luminol.config.flags.TransformedConfig;
import me.earthme.luminol.enums.EnumConfigCategory;
@ConfigClassInfo(configAttribution = EnumConfigCategory.REMOVED, mainName = "removed_config")
public class RemovedConfig implements IConfigModule {
@TransformedConfig(name = "disable_end_crystal_check", category = {"fixes", "end_crystal"}, transform = false)
@TransformedConfig(name = "disable_end_crystal_check", category = {"misc", "end_crystal"}, transform = false)
@TransformedConfig(name = "allow_skip_cooldown", category = {"misc", "revert_raid_changes"}, transform = false)
@TransformedConfig(name = "bad_omen_infinite", category = {"misc", "revert_raid_changes"}, transform = false)
@TransformedConfig(name = "skip_height_check", category = {"misc", "revert_raid_changes"}, transform = false)
@@ -19,14 +23,4 @@ public class RemovedConfig implements IConfigModule {
"""
RemovedConfig redirect to here, no any function.""")
public static boolean enabled = true;
@Override
public EnumConfigCategory getCategory() {
return EnumConfigCategory.REMOVED;
}
@Override
public String getBaseName() {
return "removed_config";
}
}
@@ -5,7 +5,7 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import com.mojang.logging.LogUtils;
import fun.bm.lophine.config.modules.optimizations.LanguageConfig;
import fun.bm.lophine.config.modules.function.LanguageConfig;
import me.earthme.luminol.config.ConfigManager;
import me.earthme.luminol.config.ConfigsInstance;
import net.minecraft.DetectedVersion;
@@ -18,6 +18,7 @@
package org.leavesmc.leaves.protocol.servux;
import com.mojang.logging.LogUtils;
import fun.bm.lophine.config.modules.function.SurvuxProtocolConfig;
import io.netty.buffer.Unpooled;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
@@ -152,7 +153,7 @@ public class ServuxEntityDataProtocol implements LeavesProtocol {
@Override
public boolean isActive() {
return fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.entityProtocol;
return SurvuxProtocolConfig.entityProtocol;
}
public enum EntityDataPayloadType {
@@ -20,6 +20,7 @@ package org.leavesmc.leaves.protocol.servux;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import com.mojang.serialization.DataResult;
import fun.bm.lophine.config.modules.function.SurvuxProtocolConfig;
import io.netty.buffer.Unpooled;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
@@ -103,7 +104,7 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
metadata.putString("id", HudDataPayload.CHANNEL.toString());
metadata.putInt("version", PROTOCOL_VERSION);
metadata.putString("servux", ServuxProtocol.SERVUX_STRING);
if (fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.hudLoggerProtocol) {
if (SurvuxProtocolConfig.hudLoggerProtocol) {
CompoundTag nbt = new CompoundTag();
for (DataLogger.Type type : DataLogger.Type.VALUES) {
nbt.putBoolean(type.getSerializedName(), isLoggerTypeEnabled(type));
@@ -184,7 +185,7 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
metadata.putInt("spawnPosZ", spawnPos.getZ());
metadata.putInt("spawnChunkRadius", level.getGameRules().getInt(GameRules.RULE_SPAWN_CHUNK_RADIUS));
if (fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.hudMetadataShareSeed) {
if (SurvuxProtocolConfig.hudMetadataShareSeed) {
metadata.putLong("worldSeed", level.getSeed());
}
}
@@ -216,7 +217,7 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
}
private static boolean isLoggerTypeEnabled(DataLogger.Type type) {
return fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.hudEnabledLoggers.contains(type.getSerializedName());
return SurvuxProtocolConfig.hudEnabledLoggers.contains(type.getSerializedName());
}
@ProtocolHandler.Ticker
@@ -232,13 +233,13 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
@ProtocolHandler.Ticker(tickerId = "logger")
public void loggerTick() {
if (!fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.hudLoggerProtocol) {
if (!SurvuxProtocolConfig.hudLoggerProtocol) {
return;
}
MinecraftServer server = MinecraftServer.getServer();
if (server.getTickCount() % fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.hudUpdateInterval == 0) {
if (server.getTickCount() % SurvuxProtocolConfig.hudUpdateInterval == 0) {
LOGGERS.forEach((type, logger) -> {
if (!isLoggerTypeEnabled(type)) {
return;
@@ -276,7 +277,7 @@ public class ServuxHudDataProtocol implements LeavesProtocol {
@Override
public boolean isActive() {
return fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.hudMetadataProtocol;
return SurvuxProtocolConfig.hudMetadataProtocol;
}
@Override
@@ -18,6 +18,7 @@
package org.leavesmc.leaves.protocol.servux;
import com.mojang.logging.LogUtils;
import fun.bm.lophine.config.modules.function.SurvuxProtocolConfig;
import io.netty.buffer.Unpooled;
import it.unimi.dsi.fastutil.longs.LongIterator;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
@@ -335,7 +336,7 @@ public class ServuxStructuresProtocol implements LeavesProtocol {
@Override
public boolean isActive() {
return fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.structureProtocol;
return SurvuxProtocolConfig.structureProtocol;
}
public enum StructuresPayloadType {
@@ -17,6 +17,7 @@
package org.leavesmc.leaves.protocol.servux.litematics;
import fun.bm.lophine.config.modules.function.SurvuxProtocolConfig;
import io.netty.buffer.Unpooled;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
@@ -132,7 +133,7 @@ public class ServuxLitematicsProtocol implements LeavesProtocol {
}
playerSession.remove(uuid);
fullPacket.readVarInt();
Tag tag = FriendlyByteBuf.readNbt(fullPacket, new NbtAccounter(fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.litematicsMaxNbtSize == -1 ? Long.MAX_VALUE : fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.litematicsMaxNbtSize, 512));
Tag tag = FriendlyByteBuf.readNbt(fullPacket, new NbtAccounter(SurvuxProtocolConfig.litematicsMaxNbtSize == -1 ? Long.MAX_VALUE : SurvuxProtocolConfig.litematicsMaxNbtSize, 512));
if (!(tag instanceof CompoundTag)) {
ServuxProtocol.LOGGER.error("cannot read nbt tag from packet");
return;
@@ -290,7 +291,7 @@ public class ServuxLitematicsProtocol implements LeavesProtocol {
@Override
public boolean isActive() {
return fun.bm.lophine.config.modules.misc.SurvuxProtocolConfig.litematicsEnabled;
return SurvuxProtocolConfig.litematicsEnabled;
}
public enum ServuxLitematicaPayloadType {
@@ -17,7 +17,7 @@
package org.leavesmc.leaves.util;
import fun.bm.lophine.config.modules.misc.RedStoneConfig;
import fun.bm.lophine.config.modules.function.RedStoneConfig;
import net.minecraft.Util;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
+1 -1
View File
@@ -3,7 +3,7 @@ pluginManagement {
gradlePluginPortal()
mavenLocal()
maven("https://repo.papermc.io/repository/maven-public/")
maven("https://repo.menthamc.com/repository/maven-public/")
maven("https://repo.menthamc.org/repository/maven-public/")
}
}