Ex Deorum 1.9
This commit is contained in:
parent
e92626ac6a
commit
89b0c0d63f
|
|
@ -5,7 +5,7 @@ plugins {
|
|||
id 'org.spongepowered.mixin' version '0.7.+'
|
||||
}
|
||||
|
||||
version = '1.8'
|
||||
version = '1.9'
|
||||
group = 'thedarkcolour.exdeorum'
|
||||
base {
|
||||
archivesName = 'exdeorum'
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
## Ex Deorum 1.9
|
||||
- Fixed incompatibility with SkyblockBuilder where player would not receive torch/watering can and Ex Deorum advancements
|
||||
- Fixed error message printing while patching the End Portal method
|
||||
- Fixed several issues with hammers in LAN and server worlds
|
||||
- Fixed hammer recipes with tag ingredients not functioning
|
||||
|
||||
## Ex Deorum 1.8
|
||||
- Added a config option to limit the number of sieve drops from sieving moss. May be useful when playing with mods that add a lot of different saplings.
|
||||
- Added compatibility with Ars Nouveau's saplings and Sourceberries to the sieve.
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ import net.minecraftforge.client.event.RegisterClientReloadListenersEvent;
|
|||
import net.minecraftforge.client.event.RegisterShadersEvent;
|
||||
import net.minecraftforge.client.event.ScreenEvent;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.TagsUpdatedEvent;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
import net.minecraftforge.fml.event.config.ModConfigEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
|
|
@ -45,6 +47,7 @@ import thedarkcolour.exdeorum.client.ter.InfestedLeavesRenderer;
|
|||
import thedarkcolour.exdeorum.client.ter.SieveRenderer;
|
||||
import thedarkcolour.exdeorum.config.EConfig;
|
||||
import thedarkcolour.exdeorum.network.ClientMessageHandler;
|
||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||
import thedarkcolour.exdeorum.registry.EBlockEntities;
|
||||
import thedarkcolour.exdeorum.registry.EFluids;
|
||||
import thedarkcolour.exdeorum.registry.EWorldPresets;
|
||||
|
|
@ -52,6 +55,8 @@ import thedarkcolour.exdeorum.registry.EWorldPresets;
|
|||
import java.io.IOException;
|
||||
|
||||
public class ClientHandler {
|
||||
public static boolean needsRecipeCacheRefresh;
|
||||
|
||||
public static void register() {
|
||||
var modBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
var fmlBus = MinecraftForge.EVENT_BUS;
|
||||
|
|
@ -60,10 +65,18 @@ public class ClientHandler {
|
|||
modBus.addListener(ClientHandler::registerRenderers);
|
||||
modBus.addListener(ClientHandler::registerShaders);
|
||||
modBus.addListener(ClientHandler::addClientReloadListeners);
|
||||
modBus.addListener(ClientHandler::onConfigChanged);
|
||||
fmlBus.addListener(ClientHandler::onPlayerRespawn);
|
||||
fmlBus.addListener(ClientHandler::onPlayerLogout);
|
||||
modBus.addListener(ClientHandler::onConfigChanged);
|
||||
fmlBus.addListener(ClientHandler::onScreenOpen);
|
||||
fmlBus.addListener(ClientHandler::onTagsUpdated);
|
||||
}
|
||||
|
||||
private static void onTagsUpdated(TagsUpdatedEvent event) {
|
||||
if (needsRecipeCacheRefresh && Minecraft.getInstance().getConnection() != null) {
|
||||
RecipeUtil.reload(Minecraft.getInstance().getConnection().getRecipeManager());
|
||||
needsRecipeCacheRefresh = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void addClientReloadListeners(RegisterClientReloadListenersEvent event) {
|
||||
|
|
@ -84,6 +97,12 @@ public class ClientHandler {
|
|||
|
||||
private static void onPlayerLogout(ClientPlayerNetworkEvent.LoggingOut event) {
|
||||
ClientMessageHandler.isInVoidWorld = false;
|
||||
needsRecipeCacheRefresh = false;
|
||||
|
||||
// Only null when logging in
|
||||
if (Minecraft.getInstance().level != null) {
|
||||
RecipeUtil.unload();
|
||||
}
|
||||
}
|
||||
|
||||
private static void onConfigChanged(ModConfigEvent.Reloading event) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Ex Deorum
|
||||
* Copyright (c) 2023 thedarkcolour
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package thedarkcolour.exdeorum.event;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
// necessary to avoid EventBus loading LocalPlayer through its ASM transformations
|
||||
class ClientsideCode {
|
||||
static Player getLocalPlayer() {
|
||||
return Minecraft.getInstance().player;
|
||||
}
|
||||
}
|
||||
|
|
@ -29,6 +29,7 @@ import net.minecraft.resources.ResourceLocation;
|
|||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
|
|
@ -36,18 +37,23 @@ import net.minecraft.world.level.block.Blocks;
|
|||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.levelgen.XoroshiroRandomSource;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.ClientChatEvent;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.AddReloadListenerEvent;
|
||||
import net.minecraftforge.event.OnDatapackSyncEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.event.level.LevelEvent;
|
||||
import net.minecraftforge.fluids.FluidInteractionRegistry;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.InterModComms;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.ExDeorum;
|
||||
import thedarkcolour.exdeorum.blockentity.LavaCrucibleBlockEntity;
|
||||
import thedarkcolour.exdeorum.client.CompostColors;
|
||||
|
|
@ -56,6 +62,7 @@ import thedarkcolour.exdeorum.compat.top.ExDeorumTopCompat;
|
|||
import thedarkcolour.exdeorum.config.EConfig;
|
||||
import thedarkcolour.exdeorum.item.HammerItem;
|
||||
import thedarkcolour.exdeorum.item.WateringCanItem;
|
||||
import thedarkcolour.exdeorum.network.ClientMessageHandler;
|
||||
import thedarkcolour.exdeorum.network.NetworkHandler;
|
||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||
import thedarkcolour.exdeorum.registry.EFluids;
|
||||
|
|
@ -63,15 +70,21 @@ import thedarkcolour.exdeorum.registry.EItems;
|
|||
import thedarkcolour.exdeorum.tag.EBiomeTags;
|
||||
import thedarkcolour.exdeorum.voidworld.VoidChunkGenerator;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public final class EventHandler {
|
||||
public static void register() {
|
||||
var fmlBus = MinecraftForge.EVENT_BUS;
|
||||
var modBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
|
||||
fmlBus.addListener(EventHandler::onPlayerLogin);
|
||||
fmlBus.addListener(EventHandler::onDataSynced);
|
||||
fmlBus.addListener(EventHandler::addReloadListeners);
|
||||
modBus.addListener(EventHandler::interModEnqueue);
|
||||
fmlBus.addListener(EventHandler::createSpawnTree);
|
||||
modBus.addListener(EventHandler::interModEnqueue);
|
||||
modBus.addListener(EventHandler::onCommonSetup);
|
||||
|
||||
if (ExDeorum.DEBUG) {
|
||||
|
|
@ -154,9 +167,38 @@ public final class EventHandler {
|
|||
});
|
||||
}
|
||||
|
||||
private static void onDataSynced(OnDatapackSyncEvent event) {
|
||||
UUID excludedUUID = null;
|
||||
|
||||
if (FMLEnvironment.dist == Dist.CLIENT) {
|
||||
// since event code is turned into ASM, we need this to prevent ASM trying to load the LocalPlayer class
|
||||
Player player = DistExecutor.unsafeCallWhenOn(Dist.CLIENT, () -> ClientsideCode::getLocalPlayer);;
|
||||
if (player == null) {
|
||||
return;
|
||||
} else {
|
||||
excludedUUID = player.getUUID();
|
||||
}
|
||||
}
|
||||
|
||||
// A player who is first connecting isn't yet included in the server's player list, so include them.
|
||||
Set<ServerPlayer> players = new HashSet<>(event.getPlayerList().getPlayers());
|
||||
if (event.getPlayer() != null) {
|
||||
players.add(event.getPlayer());
|
||||
}
|
||||
|
||||
for (var player : players) {
|
||||
if (!player.getUUID().equals(excludedUUID)) {
|
||||
NetworkHandler.sendRecipeCacheReset(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent event) {
|
||||
if (event.getEntity() instanceof ServerPlayer player) {
|
||||
if (player.serverLevel().getChunkSource().getGenerator() instanceof VoidChunkGenerator) {
|
||||
var generator = player.serverLevel().getChunkSource().getGenerator();
|
||||
|
||||
// tries to account for other SkyBlock generator mods like SkyBlockBuilder
|
||||
if (generator instanceof VoidChunkGenerator || generator.getClass().getName().toLowerCase(Locale.ROOT).contains("skyblock")) {
|
||||
NetworkHandler.sendVoidWorld(player);
|
||||
var advancement = player.server.getAdvancements().getAdvancement(new ResourceLocation(ExDeorum.ID, "core/root"));
|
||||
|
||||
|
|
@ -188,7 +230,6 @@ public final class EventHandler {
|
|||
var recipes = event.getServerResources().getRecipeManager();
|
||||
event.addListener((prepBarrier, resourceManager, prepProfiler, reloadProfiler, backgroundExecutor, gameExecutor) -> {
|
||||
return prepBarrier.wait(Unit.INSTANCE).thenRunAsync(() -> {
|
||||
HammerItem.refreshValidBlocks(recipes);
|
||||
RecipeUtil.reload(recipes);
|
||||
LavaCrucibleBlockEntity.putDefaultHeatValues();
|
||||
}, gameExecutor);
|
||||
|
|
|
|||
|
|
@ -28,32 +28,41 @@ import net.minecraft.world.item.crafting.RecipeManager;
|
|||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.common.util.Lazy;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||
import thedarkcolour.exdeorum.registry.EItems;
|
||||
import thedarkcolour.exdeorum.registry.ERecipeTypes;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class HammerItem extends DiggerItem {
|
||||
public static final Set<Block> VALID_BLOCKS = new ObjectOpenHashSet<>();
|
||||
public static Lazy<Set<Block>> validBlocks = Lazy.of(HammerItem::computeValidBlocks);
|
||||
|
||||
public HammerItem(Tier tier, Properties properties) {
|
||||
super(1.0f, -2.8f, tier, null, properties);
|
||||
}
|
||||
|
||||
public static void refreshValidBlocks(RecipeManager recipes) {
|
||||
VALID_BLOCKS.clear();
|
||||
for (var recipe : recipes.byType(ERecipeTypes.HAMMER.get()).values()) {
|
||||
public static Set<Block> computeValidBlocks() {
|
||||
var hammerRecipes = RecipeUtil.getCachedHammerRecipes();
|
||||
var validBlocks = new ObjectOpenHashSet<Block>(hammerRecipes.size());
|
||||
|
||||
for (var recipe : hammerRecipes) {
|
||||
for (var item : recipe.getIngredient().getItems()) {
|
||||
if (item.getItem() instanceof BlockItem blockItem) {
|
||||
VALID_BLOCKS.add(blockItem.getBlock());
|
||||
validBlocks.add(blockItem.getBlock());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return validBlocks;
|
||||
}
|
||||
|
||||
public static void refreshValidBlocks(RecipeManager recipes) {
|
||||
validBlocks = Lazy.of(HammerItem::computeValidBlocks);
|
||||
}
|
||||
|
||||
protected Set<Block> getValidBlocks() {
|
||||
return VALID_BLOCKS;
|
||||
return validBlocks.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
package thedarkcolour.exdeorum.network;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import thedarkcolour.exdeorum.client.ClientHandler;
|
||||
import thedarkcolour.exdeorum.recipe.RecipeUtil;
|
||||
|
||||
public class ClientMessageHandler {
|
||||
public static boolean isInVoidWorld;
|
||||
|
|
@ -32,4 +34,9 @@ public class ClientMessageHandler {
|
|||
level.clientLevelData.isFlat = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void reloadClientRecipeCache() {
|
||||
//RecipeUtil.reload(Minecraft.getInstance().level.getRecipeManager());
|
||||
ClientHandler.needsRecipeCacheRefresh = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,12 +35,17 @@ public final class NetworkHandler {
|
|||
|
||||
public static void register() {
|
||||
CHANNEL.registerMessage(0, VoidWorldMessage.class, VoidWorldMessage::encode, VoidWorldMessage::decode, VoidWorldMessage::handle);
|
||||
CHANNEL.registerMessage(1, PlayerDataMessage.class, (msg, buffer) -> {}, buffer -> new PlayerDataMessage(), PlayerDataMessage::handle);
|
||||
}
|
||||
|
||||
public static void sendVoidWorld(ServerPlayer pPlayer) {
|
||||
CHANNEL.sendTo(new VoidWorldMessage(), pPlayer.connection.connection, NetworkDirection.PLAY_TO_CLIENT);
|
||||
}
|
||||
|
||||
public static void sendRecipeCacheReset(ServerPlayer player) {
|
||||
CHANNEL.sendTo(new PlayerDataMessage(), player.connection.connection, NetworkDirection.PLAY_TO_CLIENT);
|
||||
}
|
||||
|
||||
static void handle(Supplier<NetworkEvent.Context> ctxSupplier, Consumer<NetworkEvent.Context> handler) {
|
||||
var ctx = ctxSupplier.get();
|
||||
ctx.enqueueWork(() -> handler.accept(ctx));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Ex Deorum
|
||||
* Copyright (c) 2023 thedarkcolour
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package thedarkcolour.exdeorum.network;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
// Server -> Client
|
||||
// Fired whenever a player joins an LAN world or dedicated server to load the recipe caches
|
||||
// Also fired whenever those servers reload data
|
||||
public class PlayerDataMessage {
|
||||
public void handle(Supplier<NetworkEvent.Context> ctxSupplier) {
|
||||
NetworkHandler.handle(ctxSupplier, ctx -> {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> ClientMessageHandler::reloadClientRecipeCache);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -47,6 +47,7 @@ import net.minecraftforge.common.util.Lazy;
|
|||
import net.minecraftforge.fluids.FluidStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import thedarkcolour.exdeorum.compat.PreferredOres;
|
||||
import thedarkcolour.exdeorum.item.HammerItem;
|
||||
import thedarkcolour.exdeorum.recipe.barrel.BarrelCompostRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.barrel.BarrelMixingRecipe;
|
||||
import thedarkcolour.exdeorum.recipe.crucible.CrucibleRecipe;
|
||||
|
|
@ -77,6 +78,15 @@ public final class RecipeUtil {
|
|||
lavaCrucibleRecipeCache = loadSimpleRecipeCache(recipes, ERecipeTypes.LAVA_CRUCIBLE);
|
||||
waterCrucibleRecipeCache = loadSimpleRecipeCache(recipes, ERecipeTypes.WATER_CRUCIBLE);
|
||||
hammerRecipeCache = loadSimpleRecipeCache(recipes, ERecipeTypes.HAMMER);
|
||||
HammerItem.refreshValidBlocks(recipes);
|
||||
}
|
||||
|
||||
public static void unload() {
|
||||
SIEVE_RECIPE_CACHE.invalidateAll();
|
||||
barrelCompostRecipeCache = null;
|
||||
lavaCrucibleRecipeCache = null;
|
||||
waterCrucibleRecipeCache = null;
|
||||
hammerRecipeCache = null;
|
||||
}
|
||||
|
||||
private static <T extends SingleIngredientRecipe> Lazy<Map<Item, T>> loadSimpleRecipeCache(RecipeManager recipes, Supplier<RecipeType<T>> recipeType) {
|
||||
|
|
@ -138,6 +148,10 @@ public final class RecipeUtil {
|
|||
return hammerRecipeCache.get().get(playerItem);
|
||||
}
|
||||
|
||||
public static Collection<HammerRecipe> getCachedHammerRecipes() {
|
||||
return hammerRecipeCache.get().values();
|
||||
}
|
||||
|
||||
public static <C extends Container, T extends Recipe<C>> Collection<T> byType(RecipeManager manager, RecipeType<T> type) {
|
||||
return manager.byType(type).values();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ function initializeCoreMod() {
|
|||
new FieldInsnNode(Opcodes.PUTFIELD, insn.owner, insn.name, insn.desc)
|
||||
));
|
||||
|
||||
ASMAPI.log('INFO', 'The node we are patching at: { opcode: ' + insn.getOpcode() + ', name: ' + insn.getName());
|
||||
ASMAPI.log('INFO', 'The node we are patching at: { opcode: ' + insn.getOpcode() + ', name: ' + insn.name);
|
||||
|
||||
ASMAPI.log('INFO', 'Successfully patched end portal.');
|
||||
return method;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user