From 661cc8c6dccfa63d6957696dc79c2b1eb99fe5ca Mon Sep 17 00:00:00 2001
From: apple502j <33279053+apple502j@users.noreply.github.com>
Date: Sun, 8 Oct 2023 21:13:56 +0900
Subject: [PATCH] Fix inconsistency of placed feature locations (#3369)

* Fix inconsistency of placed feature locations

`BiomeSource#getBiomes` mixin applies to all biome sources, including one for Overworld.
The return value is a set; however one caller in the worldgen code iterates over it: `PlacedFeatureIndexer`.
Using a hash set here randomizes the return value, affecting feature placement.
Use a linked hash set instead.

* Improve fix to only make changes when required.

---------

Co-authored-by: modmuss50 <modmuss50@gmail.com>
---
 .../fabricmc/fabric/mixin/biome/BiomeSourceMixin.java  |  9 +++------
 .../fabric/mixin/biome/TheEndBiomeSourceMixin.java     | 10 ++++++++--
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/mixin/biome/BiomeSourceMixin.java b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/mixin/biome/BiomeSourceMixin.java
index 546d5b2cf..117d2dca5 100644
--- a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/mixin/biome/BiomeSourceMixin.java
+++ b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/mixin/biome/BiomeSourceMixin.java
@@ -16,8 +16,6 @@
 
 package net.fabricmc.fabric.mixin.biome;
 
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.Set;
 import java.util.function.Supplier;
 
@@ -33,11 +31,10 @@ import net.minecraft.world.biome.source.BiomeSource;
 public class BiomeSourceMixin {
 	@Redirect(method = "getBiomes", at = @At(value = "INVOKE", target = "Ljava/util/function/Supplier;get()Ljava/lang/Object;"))
 	private Object getBiomes(Supplier<Set<RegistryEntry<Biome>>> instance) {
-		var biomes = new HashSet<>(instance.get());
-		fabric_modifyBiomeSet(biomes);
-		return Collections.unmodifiableSet(biomes);
+		return fabric_modifyBiomeSet(instance.get());
 	}
 
-	protected void fabric_modifyBiomeSet(Set<RegistryEntry<Biome>> biomes) {
+	protected Set<RegistryEntry<Biome>> fabric_modifyBiomeSet(Set<RegistryEntry<Biome>> biomes) {
+		return biomes;
 	}
 }
diff --git a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/mixin/biome/TheEndBiomeSourceMixin.java b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/mixin/biome/TheEndBiomeSourceMixin.java
index 3d156f4c6..09ee62424 100644
--- a/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/mixin/biome/TheEndBiomeSourceMixin.java
+++ b/fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/mixin/biome/TheEndBiomeSourceMixin.java
@@ -16,6 +16,8 @@
 
 package net.fabricmc.fabric.mixin.biome;
 
+import java.util.Collections;
+import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.function.Supplier;
 
@@ -108,14 +110,18 @@ public class TheEndBiomeSourceMixin extends BiomeSourceMixin {
 	}
 
 	@Override
-	protected void fabric_modifyBiomeSet(Set<RegistryEntry<Biome>> biomes) {
+	protected Set<RegistryEntry<Biome>> fabric_modifyBiomeSet(Set<RegistryEntry<Biome>> biomes) {
 		if (!hasCheckedForModifiedSet) {
 			hasCheckedForModifiedSet = true;
 			biomeSetModified = !overrides.get().customBiomes.isEmpty();
 		}
 
 		if (biomeSetModified) {
-			biomes.addAll(overrides.get().customBiomes);
+			var modifiedBiomes = new LinkedHashSet<>(biomes);
+			modifiedBiomes.addAll(overrides.get().customBiomes);
+			return Collections.unmodifiableSet(modifiedBiomes);
 		}
+
+		return biomes;
 	}
 }