Merge pull request #511 from PolyhedralDev/dev/wolves

Fixed wolf variant support for Paper platform
This commit is contained in:
Zoë Gidiere 2025-06-23 13:17:18 -06:00 committed by GitHub
commit 118aeb872f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 82 additions and 7 deletions

View File

@ -23,7 +23,10 @@ import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.terra.bukkit.nms.Initializer; import com.dfsek.terra.bukkit.nms.Initializer;
import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryKey;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -31,7 +34,6 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
import java.util.Locale;
import com.dfsek.terra.AbstractPlatform; import com.dfsek.terra.AbstractPlatform;
import com.dfsek.terra.api.addon.BaseAddon; import com.dfsek.terra.api.addon.BaseAddon;
@ -132,7 +134,8 @@ public class PlatformImpl extends AbstractPlatform {
} }
private BukkitPlatformBiome parseBiome(String id, DepthTracker depthTracker) throws LoadException { private BukkitPlatformBiome parseBiome(String id, DepthTracker depthTracker) throws LoadException {
if(!id.startsWith("minecraft:")) throw new LoadException("Invalid biome identifier " + id, depthTracker); NamespacedKey key = NamespacedKey.fromString(id);
return new BukkitPlatformBiome(org.bukkit.block.Biome.valueOf(id.toUpperCase(Locale.ROOT).substring(10))); if(key == null || !key.namespace().equals("minecraft")) throw new LoadException("Invalid biome identifier " + id, depthTracker);
return new BukkitPlatformBiome(RegistryAccess.registryAccess().getRegistry(RegistryKey.BIOME).getOrThrow(key));
} }
} }

View File

@ -18,20 +18,36 @@
package com.dfsek.terra.bukkit.listeners; package com.dfsek.terra.bukkit.listeners;
import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper;
import com.dfsek.terra.bukkit.hooks.MultiverseGeneratorPluginHook; import com.dfsek.terra.bukkit.hooks.MultiverseGeneratorPluginHook;
import com.dfsek.terra.bukkit.world.BukkitBiomeInfo;
import com.dfsek.terra.bukkit.world.BukkitPlatformBiome;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.entity.Wolf;
import org.bukkit.entity.Wolf.Variant;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.server.PluginEnableEvent; import org.bukkit.event.server.PluginEnableEvent;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.List;
/** /**
* Listener for events on all implementations. * Listener for events on all implementations.
*/ */
public class CommonListener implements Listener { public class CommonListener implements Listener {
private static final Logger logger = LoggerFactory.getLogger(CommonListener.class); private static final Logger logger = LoggerFactory.getLogger(CommonListener.class);
private static final List<SpawnReason> WOLF_VARIANT_SPAWN_REASONS = List.of(
SpawnReason.SPAWNER, SpawnReason.TRIAL_SPAWNER, SpawnReason.SPAWNER_EGG, SpawnReason.DEFAULT
);
private final Platform platform; private final Platform platform;
public CommonListener(Platform platform) { public CommonListener(Platform platform) {
@ -51,4 +67,50 @@ public class CommonListener implements Listener {
} }
} }
} }
@EventHandler
public void onWolfSpawn(CreatureSpawnEvent event) {
if (!(event.getEntity() instanceof Wolf wolf)) {
return;
}
// Doesn't apply if variant has already been applied
if (wolf.getVariant() != Variant.PALE) {
return;
}
if (!WOLF_VARIANT_SPAWN_REASONS.contains(event.getSpawnReason())) {
return;
}
World world = wolf.getWorld();
if (!(world.getGenerator() instanceof BukkitChunkGeneratorWrapper wrapper)) {
return;
}
ConfigPack pack = platform.getConfigRegistry().get(wrapper.getPack().getRegistryKey()).orElse(null);
if (pack == null) {
return;
}
NamespacedKey biomeKey = wolf.getWorld().getBiome(wolf.getLocation()).getKey();
pack.getBiomeProvider().stream()
.filter(biome -> {
NamespacedKey key = ((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
.get(BukkitBiomeInfo.class)
.biomeKey();
return key.equals(biomeKey);
})
.findFirst()
.ifPresent(biome -> {
NamespacedKey vanillaBiomeKey = ((BukkitPlatformBiome) biome.getPlatformBiome()).getHandle().getKey();
switch(vanillaBiomeKey.toString()) {
case "minecraft:snowy_taiga" -> wolf.setVariant(Variant.ASHEN);
case "minecraft:old_growth_pine_taiga" -> wolf.setVariant(Variant.BLACK);
case "minecraft:old_growth_spruce_taiga" -> wolf.setVariant(Variant.CHESTNUT);
case "minecraft:grove" -> wolf.setVariant(Variant.SNOWY);
case "minecraft:forest" -> wolf.setVariant(Variant.WOODS);
}
});
}
} }

View File

@ -0,0 +1,8 @@
package com.dfsek.terra.bukkit.world;
import com.dfsek.terra.api.properties.Properties;
import org.bukkit.NamespacedKey;
public record BukkitBiomeInfo(NamespacedKey biomeKey) implements Properties {}

View File

@ -2,6 +2,8 @@ package com.dfsek.terra.bukkit.nms.v1_21_6;
import com.dfsek.terra.bukkit.nms.v1_21_6.config.VanillaBiomeProperties; import com.dfsek.terra.bukkit.nms.v1_21_6.config.VanillaBiomeProperties;
import com.dfsek.terra.bukkit.world.BukkitBiomeInfo;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.core.Holder.Reference; import net.minecraft.core.Holder.Reference;
import net.minecraft.core.HolderSet; import net.minecraft.core.HolderSet;
@ -54,14 +56,14 @@ public class AwfulBukkitHacks {
Biome platform = NMSBiomeInjector.createBiome(biomeRegistry.get(vanillaMinecraftKey).orElseThrow().value(), vanillaBiomeProperties); Biome platform = NMSBiomeInjector.createBiome(biomeRegistry.get(vanillaMinecraftKey).orElseThrow().value(), vanillaBiomeProperties);
ResourceKey<Biome> delegateKey = ResourceKey.create( ResourceLocation delegateMinecraftKey = ResourceLocation.fromNamespaceAndPath("terra", NMSBiomeInjector.createBiomeID(pack, key));
Registries.BIOME, NamespacedKey delegateBukkitKey = NamespacedKey.fromString(delegateMinecraftKey.toString());
ResourceLocation.fromNamespaceAndPath("terra", NMSBiomeInjector.createBiomeID(pack, key)) ResourceKey<Biome> delegateKey = ResourceKey.create(Registries.BIOME, delegateMinecraftKey);
);
Reference<Biome> holder = biomeRegistry.register(delegateKey, platform, RegistrationInfo.BUILT_IN); Reference<Biome> holder = biomeRegistry.register(delegateKey, platform, RegistrationInfo.BUILT_IN);
Reflection.REFERENCE.invokeBindValue(holder, platform); // IMPORTANT: bind holder. Reflection.REFERENCE.invokeBindValue(holder, platform); // IMPORTANT: bind holder.
platformBiome.getContext().put(new BukkitBiomeInfo(delegateBukkitKey));
platformBiome.getContext().put(new NMSBiomeInfo(delegateKey)); platformBiome.getContext().put(new NMSBiomeInfo(delegateKey));
terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location()); terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location());