2 Commits

Author SHA1 Message Date
Martin Prokoph
caee4c801a port: The Copper Age (1.21.9)
Most changes were related to the MidnightLib 1.8.0 update
2025-10-01 19:00:00 +02:00
Martin Prokoph
97117ea46a port: Chase the Skies (1.21.6) 2025-06-17 19:44:15 +02:00
55 changed files with 142 additions and 1818 deletions

View File

@@ -3,7 +3,7 @@ import groovy.json.JsonOutput
plugins {
id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "1.10-SNAPSHOT" apply false
id "dev.architectury.loom" version "1.11-SNAPSHOT" apply false
id "me.shedaniel.unified-publishing" version "0.1.+" apply false
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
}

View File

@@ -1,32 +1,18 @@
package net.puzzlemc.core;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.SynchronousResourceReloader;
import net.puzzlemc.core.config.PuzzleConfig;
import net.puzzlemc.gui.PuzzleGui;
import net.puzzlemc.predicates.PuzzlePredicates;
import net.puzzlemc.splashscreen.PuzzleSplashScreen;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PuzzleCore {
public final static String MOD_ID = "puzzle";
private static final List<PuzzleModule> MODULES = new ArrayList<>();
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
public static void initModules() {
PuzzleConfig.init(MOD_ID, PuzzleConfig.class);
Collections.addAll(MODULES, PuzzleGui.INSTANCE, PuzzleSplashScreen.INSTANCE, PuzzlePredicates.INSTANCE);
MODULES.forEach(PuzzleModule::init);
}
public static class PuzzleResourceManager implements SynchronousResourceReloader {
public static PuzzleResourceManager INSTANCE = new PuzzleResourceManager();
@Override
public void reload(ResourceManager manager) {
MODULES.forEach(module -> module.reloadResources(manager));
}
PuzzleGui.init();
PuzzleSplashScreen.init();
}
}

View File

@@ -1,13 +0,0 @@
package net.puzzlemc.core;
import net.minecraft.resource.ResourceManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public interface PuzzleModule {
default void init() {}
default void reloadResources(ResourceManager manager) {}
String getModuleId();
default Logger getLogger() {return LoggerFactory.getLogger("puzzle/"+getModuleId());}
}

View File

@@ -1,50 +0,0 @@
package net.puzzlemc.core.mixin;
import eu.midnightdust.lib.util.PlatformFunctions;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.util.List;
import java.util.Set;
public class PuzzleMixinPlugin implements IMixinConfigPlugin {
private String mixinPackage;
@Override
public void onLoad(String mixinPackage) {
this.mixinPackage = mixinPackage + ".";
}
@Override
public String getRefMapperConfig() {
return null;
}
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
final String mixinName = mixinClassName.substring(this.mixinPackage.length());
final String packageName = mixinName.substring(0, mixinName.lastIndexOf('.'));
if (packageName.startsWith("sodium") && !PlatformFunctions.isModLoaded("sodium")) return false;
return true;
}
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
}
@Override
public List<String> getMixins() {
return null;
}
@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
}

View File

@@ -6,6 +6,8 @@ import net.puzzlemc.gui.screen.widget.PuzzleWidget;
import java.util.ArrayList;
import java.util.List;
import static net.puzzlemc.core.PuzzleCore.LOGGER;
public class PuzzleApi {
public static List<PuzzleWidget> GRAPHICS_OPTIONS = new ArrayList<>();
public static List<PuzzleWidget> MISC_OPTIONS = new ArrayList<>();
@@ -15,21 +17,21 @@ public class PuzzleApi {
public static void addToGraphicsOptions(PuzzleWidget button) {
GRAPHICS_OPTIONS.add(button);
if (PuzzleConfig.debugMessages)
PuzzleGui.logger().info("{} -> Graphics Options", button.descriptionText.getContent().toString());
LOGGER.info("{} -> Graphics Options", button.descriptionText.getContent().toString());
}
public static void addToMiscOptions(PuzzleWidget button) {
MISC_OPTIONS.add(button);
if (PuzzleConfig.debugMessages)
PuzzleGui.logger().info("{} -> Misc Options", button.descriptionText.getContent().toString());
LOGGER.info("{} -> Misc Options", button.descriptionText.getContent().toString());
}
public static void addToPerformanceOptions(PuzzleWidget button) {
PERFORMANCE_OPTIONS.add(button);
if (PuzzleConfig.debugMessages)
PuzzleGui.logger().info("{}- > Performance Options", button.descriptionText.getContent().toString());
LOGGER.info("{}- > Performance Options", button.descriptionText.getContent().toString());
}
public static void addToResourceOptions(PuzzleWidget button) {
RESOURCE_OPTIONS.add(button);
if (PuzzleConfig.debugMessages)
PuzzleGui.logger().info("{} -> Resource Options", button.descriptionText.getContent().toString());
LOGGER.info("{} -> Resource Options", button.descriptionText.getContent().toString());
}
}

View File

@@ -3,7 +3,6 @@ package net.puzzlemc.gui;
import eu.midnightdust.core.MidnightLib;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.minecraft.util.Identifier;
import net.puzzlemc.core.PuzzleModule;
import net.puzzlemc.core.config.PuzzleConfig;
import net.puzzlemc.gui.compat.*;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
@@ -11,22 +10,16 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.puzzlemc.splashscreen.PuzzleSplashScreen;
import org.slf4j.Logger;
public class PuzzleGui implements PuzzleModule {
public static final PuzzleGui INSTANCE = new PuzzleGui();
import static net.puzzlemc.core.PuzzleCore.LOGGER;
public class PuzzleGui {
public final static String id = "puzzle";
public static final Text YES = Text.translatable("gui.yes").formatted(Formatting.GREEN);
public static final Text NO = Text.translatable("gui.no").formatted(Formatting.RED);
public static final Identifier PUZZLE_BUTTON = Identifier.of(id, "icon/button");
@Override
public String getModuleId() {
return "gui";
}
@Override
public void init() {
public static void init() {
MidnightLib.hiddenMods.add("puzzle");
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.of("\uD83E\uDDE9 Puzzle")));
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.translatable("puzzle.midnightconfig.title"), (button) -> button.setMessage(Text.of("OPEN")), (button) -> {
@@ -63,7 +56,7 @@ public class PuzzleGui implements PuzzleModule {
if (isActive("entity_texture_features")) ETFCompat.init();
if (isActive("entity_model_features")) EMFCompat.init();
} catch (Exception e) {
INSTANCE.getLogger().error("ETF/EMF config structure changed. Again...", e);
LOGGER.error("ETF/EMF config structure changed. Again...", e);
}
lateInitDone = true;
@@ -71,7 +64,4 @@ public class PuzzleGui implements PuzzleModule {
public static boolean isActive(String modid) {
return PlatformFunctions.isModLoaded(modid) && !PuzzleConfig.disabledIntegrations.contains(modid);
}
public static Logger logger() {
return INSTANCE.getLogger();
}
}

View File

@@ -1,5 +1,6 @@
package net.puzzlemc.gui.compat;
import com.mojang.text2speech.OperatingSystem;
import link.infra.borderlessmining.config.ConfigHandler;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
@@ -17,7 +18,7 @@ public class BorderlessMiningCompat {
bmConfig.setEnabledPending(!bmConfig.isEnabledOrPending());
bmConfig.save();
}));
if (MinecraftClient.IS_SYSTEM_MAC) {
if (OperatingSystem.get() == OperatingSystem.MAC_OS) {
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.translatable("config.borderlessmining.general.enabledmac"), (button) -> button.setMessage(bmConfig.enableMacOS ? YES : NO), (button) -> {
bmConfig.enableMacOS = !bmConfig.enableMacOS;
bmConfig.setEnabledPending(bmConfig.isEnabled());

View File

@@ -5,6 +5,7 @@ import net.minecraft.client.gui.tab.GridScreenTab;
import net.minecraft.client.gui.tab.Tab;
import net.minecraft.client.gui.tab.TabManager;
import net.minecraft.client.gui.widget.TabNavigationWidget;
import net.minecraft.client.input.KeyInput;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
@@ -75,9 +76,8 @@ public class PuzzleOptionsScreen extends Screen {
list.addAll(options);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (this.tabNavigation.trySwitchTabsWithKey(keyCode)) return true;
return super.keyPressed(keyCode, scanCode, modifiers);
public boolean keyPressed(KeyInput input) {
return this.tabNavigation.keyPressed(input) || super.keyPressed(input);
}
@Override
public void tick() {

View File

@@ -1,6 +1,9 @@
package net.puzzlemc.gui.screen.widget;
import eu.midnightdust.lib.config.ButtonEntry;
import eu.midnightdust.lib.config.EntryInfo;
import eu.midnightdust.lib.config.MidnightConfig;
import eu.midnightdust.lib.config.MidnightConfigListWidget;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
@@ -11,15 +14,15 @@ import net.minecraft.client.resource.language.I18n;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableTextContent;
import net.minecraft.util.Formatting;
import net.puzzlemc.gui.PuzzleGui;
import net.puzzlemc.gui.screen.PuzzleOptionsScreen;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;
@Environment(EnvType.CLIENT)
public class PuzzleOptionListWidget extends MidnightConfig.MidnightConfigListWidget {
import static net.puzzlemc.core.PuzzleCore.LOGGER;
public class PuzzleOptionListWidget extends MidnightConfigListWidget {
TextRenderer textRenderer;
public PuzzleOptionListWidget(MinecraftClient minecraftClient, int i, int j, int k, int l) {
@@ -41,29 +44,30 @@ public class PuzzleOptionListWidget extends MidnightConfig.MidnightConfigListWid
else if (button.buttonType == ButtonType.TEXT_FIELD)
this.addButton(List.of(new PuzzleTextFieldWidget(textRenderer, buttonX, 0, 150, 20, button.setTextValue, button.changeTextValue)), button.descriptionText);
else
PuzzleGui.logger().warn("Button {} is missing the buttonType variable. This shouldn't happen!", button);
LOGGER.warn("Button {} is missing the buttonType variable. This shouldn't happen!", button);
}
catch (Exception e) {
PuzzleGui.logger().error("Failed to add button {}. Likely caused by an update of the specific mod.", button.descriptionText);
LOGGER.error("Failed to add button {}. Likely caused by an update of the specific mod.", button.descriptionText);
}
}
}
public void addButton(List<ClickableWidget> buttons, Text text) {
MidnightConfig.EntryInfo info = new MidnightConfig.EntryInfo(null, "puzzle");
EntryInfo info = new EntryInfo(null, "puzzle");
if (buttons.isEmpty()) info.comment = new MidnightConfig.Comment(){
public Class<? extends Annotation> annotationType() {return null;}
public boolean centered() {return true;}
public String category() {return "";}
public String name() {return "";}
public String url() {return "";}
public String requiredMod() {return "";}
};
var entry = new MidnightConfig.ButtonEntry(buttons, text, info);
var entry = new ButtonEntry(buttons, text, info);
this.addEntry(entry);
}
public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
super.renderWidget(context, mouseX, mouseY, delta);
MidnightConfig.ButtonEntry e = this.getHoveredEntry();
ButtonEntry e = this.getHoveredEntry();
if (client.currentScreen instanceof PuzzleOptionsScreen page && e != null && !e.buttons.isEmpty() &&
e.text.getContent() instanceof TranslatableTextContent content) {
ClickableWidget button = e.buttons.getFirst();
@@ -90,7 +94,7 @@ public class PuzzleOptionListWidget extends MidnightConfig.MidnightConfigListWid
}
@Override
public MidnightConfig.ButtonEntry getHoveredEntry() {
public ButtonEntry getHoveredEntry() {
return super.getHoveredEntry();
}
}

View File

@@ -1,14 +0,0 @@
package net.puzzlemc.predicates;
import com.mojang.serialization.MapCodec;
import net.minecraft.block.BlockState;
import net.minecraft.util.Identifier;
import net.puzzlemc.predicates.mixin.StateAccessor;
public class BlockStateOverride extends BlockState {
public final Identifier overrideId;
public BlockStateOverride(BlockState baseState, Identifier overrideId) {
super(baseState.getBlock(), ((StateAccessor<?, ?>)baseState).getPropertyMap(), (MapCodec<BlockState>) ((StateAccessor<?, ?>)baseState).getCodec());
this.overrideId = overrideId;
}
}

View File

@@ -1,29 +0,0 @@
package net.puzzlemc.predicates;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.puzzlemc.predicates.data.logic.When;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
public class MBPData {
public static final HashMap<Block, List<When>> PREDICATES = new HashMap<>();
public static Optional<BlockStateOverride> meetsPredicate(BlockView world, BlockPos pos, BlockState state, Identifier renderContext) {
if (PREDICATES.containsKey(state.getBlock())) {
for (When when : PREDICATES.get(state.getBlock())) {
if (when.meetsCondition(world, pos, state, renderContext)) {
long seed = pos.hashCode();
return Optional.of(new BlockStateOverride(state, when.getModel(seed)));
}
}
}
return Optional.empty();
}
}

View File

@@ -1,68 +0,0 @@
package net.puzzlemc.predicates;
import net.fabricmc.loader.api.FabricLoader;
import org.objectweb.asm.tree.ClassNode;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
import java.util.List;
import java.util.Set;
public class MBPMixinPlugin implements IMixinConfigPlugin {
public static boolean HAS_SODIUM = false;
public static boolean HAS_WORLDMESHER = false;
@Override
public void onLoad(String mixinPackage) {
HAS_SODIUM = FabricLoader.getInstance().isModLoaded("sodium");
HAS_WORLDMESHER = FabricLoader.getInstance().isModLoaded("worldmesher");
StringBuilder builder = new StringBuilder();
if (HAS_SODIUM) {
builder.append("sodium, ");
}
if (HAS_WORLDMESHER) {
builder.append("worldmesher, ");
}
String str = "Starting MBP";
if (builder.length() > 0) {
str = str + " with " + builder.substring(0, builder.length()-2);
}
PuzzlePredicates.logger().debug(str);
}
@Override
public String getRefMapperConfig() {
return null;
}
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
if (mixinClassName.equals("compat.sodium.ChunkBuilderMeshingTaskMixin"))
return HAS_SODIUM;
//if (mixinClassName.equals("BlockRenderManagerMixin"))
// return !HAS_SODIUM;
//if (mixinClassName.equals("WorldMeshMixin"))
//return HAS_WORLDMESHER;
return true;
}
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
}
@Override
public List<String> getMixins() {
return List.of("compat.sodium.ChunkBuilderMeshingTaskMixin");
}
@Override
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
}
}

View File

@@ -1,73 +0,0 @@
package net.puzzlemc.predicates;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.minecraft.block.Block;
import net.minecraft.client.render.entity.state.EntityRenderState;
import net.minecraft.resource.Resource;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import net.puzzlemc.core.PuzzleModule;
import net.puzzlemc.predicates.data.logic.When;
import net.puzzlemc.predicates.util.Utils;
import org.slf4j.Logger;
import java.util.*;
public class PuzzlePredicates implements PuzzleModule {
public static final PuzzlePredicates INSTANCE = new PuzzlePredicates();
public static EntityRenderState currentEntityRenderState;
@Override
public String getModuleId() {
return "predicates";
}
public static Logger logger() {
return INSTANCE.getLogger();
}
public static Identifier id(String path) {
return Identifier.of("mbp", path);
}
@Override
public void init() {
// TODO
//ModelLoadingPluginManager.registerPlugin(new MBPModelLoadingPlugin.ModelIdLoader(), new MBPModelLoadingPlugin());
}
@Override
public void reloadResources(ResourceManager manager) {
MBPData.PREDICATES.clear();
Map<Identifier, Resource> map = manager.findResources("mbp", id -> id.getPath().endsWith(".json"));
for (Identifier id : map.keySet()) {
getLogger().info("Loading MBP: " + id);
try {
Identifier blockTarget = Identifier.of(id.toString().substring(0,id.toString().length()-5).replace("mbp/", ""));
JsonObject asset = JsonParser.parseReader(map.get(id).getReader()).getAsJsonObject();
Optional<Block> block = Utils.getBlock(blockTarget);
if (block.isPresent()) {
JsonArray overrides = asset.getAsJsonArray("overrides");
List<When> whenList = new ArrayList<>();
for(JsonElement overrideEntry : overrides) {
When when = When.parse(overrideEntry);
whenList.add(when);
}
MBPData.PREDICATES.put(block.get(), Collections.unmodifiableList(whenList));
getLogger().info(MBPData.PREDICATES.toString());
} else {
getLogger().error("Block entry not found in file %s: %s ".formatted(id, blockTarget));
}
} catch (Exception e) {
getLogger().error("Error in file: %s".formatted(id));
e.printStackTrace();
}
}
}
}

View File

@@ -1,12 +0,0 @@
package net.puzzlemc.predicates.accessor;
import net.minecraft.client.render.block.BlockRenderManager;
import net.minecraft.client.render.entity.state.BlockDisplayEntityRenderState;
public interface BlockRenderManagerAccess {
void moreBlockPredicates$setContextEntity(BlockDisplayEntityRenderState renderState);
static BlockRenderManagerAccess of(BlockRenderManager manager) {
return (BlockRenderManagerAccess) manager;
}
}

View File

@@ -1,13 +0,0 @@
package net.puzzlemc.predicates.accessor;
import net.minecraft.client.render.model.BakedModelManager;
import net.minecraft.client.render.model.BlockStateModel;
import net.puzzlemc.predicates.BlockStateOverride;
public interface BlockStateModelManagerAccess {
BlockStateModel reallyGetModel(BlockStateOverride override);
static BlockStateModelManagerAccess of(BakedModelManager manager) {
return (BlockStateModelManagerAccess) manager;
}
}

View File

@@ -1,36 +0,0 @@
package net.puzzlemc.predicates.common;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.client.render.block.BlockModels;
import net.minecraft.client.render.model.BlockStateModel;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockRenderView;
import net.puzzlemc.predicates.BlockStateOverride;
import net.puzzlemc.predicates.MBPData;
import net.puzzlemc.predicates.accessor.BlockStateModelManagerAccess;
import java.util.Optional;
public class BlockRendering {
public static BlockStateModel tryModelOverride(BlockModels models, BlockRenderView world, BlockState state, BlockPos pos, Identifier renderContext) {
BlockRenderType blockRenderType = state.getRenderType();
if (blockRenderType == BlockRenderType.MODEL) {
Optional<BlockStateOverride> override = MBPData.meetsPredicate(world, pos, state, renderContext);
if (override.isPresent()) {
BlockStateModel model;
BlockStateModelManagerAccess manager = ((BlockStateModelManagerAccess) models.getModelManager());
model = manager.reallyGetModel(override.get());
if (model == models.getModelManager().getMissingModel()) {
var overId = override.get();
model = models.getModelManager().getBlockModels().getModel((BlockState) model);
}
return model;
}
}
return null;
}
}

View File

@@ -1,16 +0,0 @@
package net.puzzlemc.predicates.common;
import net.minecraft.util.Identifier;
import static net.puzzlemc.predicates.PuzzlePredicates.id;
public final class ContextIdentifiers {
public static final Identifier PISTON_PUSHING = id("pushed_by_piston");
public static final Identifier FALLING_BLOCK = id("falling_block");
public static final Identifier MARKER_PARTICLE = id("marker_particle");
public static final Identifier ITEM = id("item");
public static final Identifier ITEM_HELD = id("item_held");
public static final Identifier MISC = id("misc");
public static final Identifier CHUNK_MESH = id("chunk_mesh");
public static final Identifier ENTITY = id("entity");
}

View File

@@ -1,63 +0,0 @@
package net.puzzlemc.predicates.data;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import net.puzzlemc.predicates.PuzzlePredicates;
import net.puzzlemc.predicates.data.conditions.*;
import net.puzzlemc.predicates.data.logic.Not;
import net.puzzlemc.predicates.data.logic.Or;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
public abstract class BlockModelPredicate implements WorldViewCondition {
private static final HashMap<String, Function<JsonElement, BlockModelPredicate>> HANDLERS = new HashMap<>() {{
// Logical operators
put("or", Or::parse);
put("not", Not::parse);
// Actual conditions
put("adjacent_block", AdjacentBlock::parse);
put("coordinate_range", CoordinateRange::parse);
put("biome", InBiome::parse);
put("state", IsBlockState::parse);
put("light_range", LightRange::parse);
put("is_context", IsContext::parse);
}};
public static ArrayList<BlockModelPredicate> parseFromJson(JsonElement element) {
ArrayList<JsonObject> objects = new ArrayList<>();
if (element.isJsonArray()) {
JsonArray arr = element.getAsJsonArray();
for (JsonElement obj : arr) {
objects.add(obj.getAsJsonObject());
}
} else {
objects.add(element.getAsJsonObject());
}
ArrayList<BlockModelPredicate> predicates = new ArrayList<>();
for(JsonObject curObject : objects) {
for (Map.Entry<String, JsonElement> entries : curObject.entrySet()) {
if (HANDLERS.containsKey(entries.getKey())) {
try {
predicates.add(HANDLERS.get(entries.getKey()).apply(entries.getValue()));
} catch (JsonParseException e) {
PuzzlePredicates.logger().warn(String.format("Failed to load predicate \"%s\"! Reason: %s", entries.getKey(), e.getMessage()));
}
} else {
PuzzlePredicates.logger().warn(String.format("Unhandled predicate \"%s\"!", entries.getKey()));
}
}
}
return predicates;
}
}

View File

@@ -1,33 +0,0 @@
package net.puzzlemc.predicates.data;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import net.minecraft.predicate.NumberRange;
import net.minecraft.util.math.BlockPos;
public final class DataHelper {
public static NumberRange.IntRange parseIntRange(JsonElement arg) {
JsonObject object = arg.getAsJsonObject();
boolean hasMin = object.has("min"), hasMax = object.has("max");
if (hasMin && hasMax) {
return NumberRange.IntRange.between(object.get("min").getAsInt(), object.get("max").getAsInt());
} else if (hasMin) {
return NumberRange.IntRange.atLeast(object.get("min").getAsInt());
} else if (hasMax) {
return NumberRange.IntRange.atMost(object.get("max").getAsInt());
} else {
// none?!?!??!?!?!?!?!?!
throw new JsonParseException("No min or max defined for range!");
}
}
public static BlockPos parseBlockPos(JsonObject offset) {
int x = offset.get("x").getAsInt();
int y = offset.get("y").getAsInt();
int z = offset.get("z").getAsInt();
return new BlockPos(x, y, z);
}
}

View File

@@ -1,10 +0,0 @@
package net.puzzlemc.predicates.data;
import net.minecraft.block.BlockState;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
public interface WorldViewCondition {
boolean meetsCondition(BlockView world, BlockPos pos, BlockState state, Identifier renderContext);
}

View File

@@ -1,50 +0,0 @@
package net.puzzlemc.predicates.data.conditions;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minecraft.block.BlockState;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.puzzlemc.predicates.data.BlockModelPredicate;
import net.puzzlemc.predicates.data.DataHelper;
import org.jetbrains.annotations.Nullable;
public class AdjacentBlock extends BlockModelPredicate {
private final @Nullable IsBlockState stateCondition;
private final BlockPos offset;
private final boolean checkFullCube;
private final boolean checkTransparent;
public AdjacentBlock(@Nullable IsBlockState stateCondition, BlockPos offset, boolean checkFullCube, boolean checkTransparent) {
this.stateCondition = stateCondition;
this.offset = offset;
this.checkFullCube = checkFullCube;
this.checkTransparent = checkTransparent;
}
@Override
public boolean meetsCondition(BlockView world, BlockPos pos, BlockState state, Identifier renderContext) {
BlockState block = world.getBlockState(pos);
boolean b = true;
if (checkFullCube) b = block.isFullCube(world, pos);
if (checkTransparent) b &= block.isTransparent();
if (stateCondition != null) b &= stateCondition.meetsCondition(world, pos.add(offset), state, renderContext);
return b;
}
public static AdjacentBlock parse(JsonElement arg) {
JsonObject obj = arg.getAsJsonObject();
IsBlockState stateCondition = null;
if (obj.has("state")) {
stateCondition = IsBlockState.parse(obj.get("state"));
}
boolean checkFullCube = false;
boolean checkTransparent = false;
if (obj.has("is_full_cube")) checkFullCube = obj.get("is_full_cube").getAsBoolean();
if (obj.has("is_transparent")) checkTransparent = obj.get("is_transparent").getAsBoolean();
return new AdjacentBlock(stateCondition, DataHelper.parseBlockPos(obj.getAsJsonObject("offset")), checkFullCube, checkTransparent);
}
}

View File

@@ -1,35 +0,0 @@
package net.puzzlemc.predicates.data.conditions;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minecraft.block.BlockState;
import net.minecraft.predicate.NumberRange;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.BlockView;
import net.puzzlemc.predicates.data.BlockModelPredicate;
import net.puzzlemc.predicates.data.DataHelper;
public class CoordinateRange extends BlockModelPredicate {
public final NumberRange.IntRange range;
public final Direction.Axis axis;
public CoordinateRange(NumberRange.IntRange range, Direction.Axis axis) {
this.range = range;
this.axis = axis;
}
@Override
public boolean meetsCondition(BlockView world, BlockPos pos, BlockState state, Identifier renderContext) {
return range.test(pos.getComponentAlongAxis(this.axis));
}
public static CoordinateRange parse(JsonElement arg) {
JsonObject object = arg.getAsJsonObject();
Direction.Axis axis = Direction.Axis.fromId(object.get("axis").getAsString());
return new CoordinateRange(DataHelper.parseIntRange(arg), axis);
}
}

View File

@@ -1,30 +0,0 @@
package net.puzzlemc.predicates.data.conditions;
import com.google.gson.JsonElement;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.puzzlemc.predicates.data.BlockModelPredicate;
public class InBiome extends BlockModelPredicate {
final Identifier biomeID;
public InBiome(Identifier biomeID) {
this.biomeID = biomeID;
}
@Override
public boolean meetsCondition(BlockView world, BlockPos pos, BlockState state, Identifier renderContext) {
World w = MinecraftClient.getInstance().world;;
assert w != null;
return w.getBiome(pos).matchesId(biomeID);
}
public static InBiome parse(JsonElement arg) {
return new InBiome(Identifier.of(arg.getAsString()));
}
}

View File

@@ -1,68 +0,0 @@
package net.puzzlemc.predicates.data.conditions;
import com.google.gson.JsonElement;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.block.BlockState;
import net.minecraft.block.pattern.CachedBlockPosition;
import net.minecraft.client.MinecraftClient;
import net.minecraft.command.argument.BlockArgumentParser;
import net.minecraft.command.argument.BlockPredicateArgumentType;
import net.minecraft.registry.Registries;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.puzzlemc.predicates.data.BlockModelPredicate;
import org.jetbrains.annotations.Nullable;
public class IsBlockState extends BlockModelPredicate {
final @Nullable BlockPredicateImpl blockStatePredicate;
public IsBlockState(@Nullable BlockPredicateImpl blockStatePredicate) {
this.blockStatePredicate = blockStatePredicate;
}
@Override
public boolean meetsCondition(BlockView world, BlockPos pos, BlockState state, Identifier renderContext) {
if (blockStatePredicate == null) return true;
return blockStatePredicate.test(new CachedBlockPosition(MinecraftClient.getInstance().world, pos, false));
}
public static IsBlockState parse(JsonElement arg) {
try {
String str = arg.getAsString();
if (str != null) {
return new IsBlockState(new BlockPredicateImpl(str));
}
return null; // explode
} catch (CommandSyntaxException e) {
throw new RuntimeException(e);
}
}
private static class BlockPredicateImpl implements BlockPredicateArgumentType.BlockPredicate {
final BlockArgumentParser.BlockResult res;
public final String stateString;
public final boolean fuzzy;
public BlockPredicateImpl(String stateString) throws CommandSyntaxException {
this.stateString = stateString;
fuzzy = !stateString.contains("[");
res = BlockArgumentParser.block(Registries.BLOCK, stateString, false);
}
@Override
public boolean hasNbt() {
return false;
}
@Override
public boolean test(CachedBlockPosition cachedBlockPosition) {
if (fuzzy) return cachedBlockPosition.getBlockState().getBlock() == res.blockState().getBlock();
return cachedBlockPosition.getBlockState().equals(res.blockState());
}
}
}

View File

@@ -1,27 +0,0 @@
package net.puzzlemc.predicates.data.conditions;
import com.google.gson.JsonElement;
import net.minecraft.block.BlockState;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.puzzlemc.predicates.data.BlockModelPredicate;
public class IsContext extends BlockModelPredicate {
final Identifier expectedContext;
public IsContext(Identifier expectedContext) {
this.expectedContext = expectedContext;
}
@Override
public boolean meetsCondition(BlockView world, BlockPos pos, BlockState state, Identifier renderContext) {
return expectedContext.equals(renderContext);
}
public static IsContext parse(JsonElement arg) {
return new IsContext(Identifier.of(arg.getAsString()));
}
}

View File

@@ -1,39 +0,0 @@
package net.puzzlemc.predicates.data.conditions;
import com.google.gson.JsonElement;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.predicate.NumberRange;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import net.puzzlemc.predicates.data.BlockModelPredicate;
import net.puzzlemc.predicates.data.DataHelper;
public class LightRange extends BlockModelPredicate {
public final NumberRange.IntRange range;
public LightRange(NumberRange.IntRange range) {
this.range = range;
}
@Override
public boolean meetsCondition(BlockView _unused, BlockPos pos, BlockState state, Identifier renderContext) {
World world = MinecraftClient.getInstance().world;
// ;-;
return range.test(world.getLightLevel(pos))
|| range.test(world.getLightLevel(pos.up()))
|| range.test(world.getLightLevel(pos.down()))
|| range.test(world.getLightLevel(pos.north()))
|| range.test(world.getLightLevel(pos.south()))
|| range.test(world.getLightLevel(pos.east()))
|| range.test(world.getLightLevel(pos.west()));
}
public static LightRange parse(JsonElement arg) {
return new LightRange(DataHelper.parseIntRange(arg));
}
}

View File

@@ -1,32 +0,0 @@
package net.puzzlemc.predicates.data.logic;
import com.google.common.collect.ImmutableList;
import com.google.gson.JsonElement;
import net.minecraft.block.BlockState;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.puzzlemc.predicates.data.BlockModelPredicate;
import java.util.List;
public class And extends BlockModelPredicate {
final List<BlockModelPredicate> predicates;
public And(List<BlockModelPredicate> predicates) {
this.predicates = predicates;
}
@Override
public boolean meetsCondition(BlockView world, BlockPos pos, BlockState state, Identifier renderContext) {
for (BlockModelPredicate action : predicates) {
if (!action.meetsCondition(world, pos, state, renderContext)) return false;
}
return true;
}
public static And parse(JsonElement arg) {
return new And(ImmutableList.copyOf(BlockModelPredicate.parseFromJson(arg)));
}
}

View File

@@ -1,26 +0,0 @@
package net.puzzlemc.predicates.data.logic;
import com.google.gson.JsonElement;
import net.minecraft.block.BlockState;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.puzzlemc.predicates.data.BlockModelPredicate;
public class Not extends BlockModelPredicate {
final And condition;
public Not(And condition) {
this.condition = condition;
}
@Override
public boolean meetsCondition(BlockView world, BlockPos pos, BlockState state, Identifier renderContext) {
return !condition.meetsCondition(world, pos, state, renderContext);
}
public static Not parse(JsonElement arg) {
return new Not(And.parse(arg));
}
}

View File

@@ -1,39 +0,0 @@
package net.puzzlemc.predicates.data.logic;
import com.google.common.collect.ImmutableList;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import net.minecraft.block.BlockState;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.puzzlemc.predicates.data.BlockModelPredicate;
import java.util.ArrayList;
import java.util.List;
public class Or extends BlockModelPredicate {
final List<And> conditions;
public Or(List<And> conditions) {
this.conditions = conditions;
}
@Override
public boolean meetsCondition(BlockView world, BlockPos pos, BlockState state, Identifier renderContext) {
for (And action : conditions) {
if (action.meetsCondition(world, pos, state, renderContext)) return true;
}
return false;
}
public static Or parse(JsonElement arg) {
ArrayList<And> conditionsList = new ArrayList<>();
JsonArray entryArray = arg.getAsJsonArray();
for (JsonElement entry : entryArray) {
conditionsList.add(And.parse(entry));
}
return new Or(ImmutableList.copyOf(conditionsList));
}
}

View File

@@ -1,71 +0,0 @@
package net.puzzlemc.predicates.data.logic;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import net.minecraft.block.BlockState;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockView;
import net.puzzlemc.predicates.data.BlockModelPredicate;
import net.puzzlemc.predicates.data.WorldViewCondition;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class When implements WorldViewCondition {
final And conditions;
private final List<Identifier> applyModelList;
public When(And conditions, List<Identifier> applyModelList) {
this.conditions = conditions;
this.applyModelList = Collections.unmodifiableList(applyModelList);
}
public Identifier getModel(long seed) {
return applyModelList.get((int) (Math.abs(seed) % applyModelList.size()));
}
public List<Identifier> getModels() {
return applyModelList;
}
public static When parse(JsonElement arg) {
JsonObject object = arg.getAsJsonObject();
List<BlockModelPredicate> conditions = BlockModelPredicate.parseFromJson(object.get("when"));
List<Identifier> applyModelList;
JsonElement apply = object.get("apply");
if (apply.isJsonArray()) {
applyModelList = new ArrayList<>();
for (JsonElement entry : apply.getAsJsonArray()) {
String applyId;
int weight = 1;
if (entry.isJsonObject()) {
JsonObject obj = entry.getAsJsonObject();
applyId = obj.get("model").getAsString();
if (obj.has("weight")) weight = obj.get("weight").getAsInt();
} else {
applyId = entry.getAsString();
}
String[] id = applyId.split(":");
Identifier currentModelID = Identifier.of(id[0], "block/" + id[1]);
for (int i = 0; i < weight; i++) {
applyModelList.add(currentModelID);
}
}
} else {
String[] id = apply.getAsString().split(":");
applyModelList = List.of(Identifier.of(id[0], "block/" + id[1]));
}
return new When(new And(conditions), applyModelList);
}
@Override
public boolean meetsCondition(BlockView world, BlockPos pos, BlockState state, Identifier renderContext) {
return conditions.meetsCondition(world, pos, state, renderContext);
}
}

View File

@@ -1,60 +0,0 @@
package net.puzzlemc.predicates.mixin;
import net.minecraft.client.render.block.BlockModels;
import net.minecraft.client.render.model.BakedModelManager;
import net.minecraft.client.render.model.BlockStateModel;
import net.puzzlemc.predicates.BlockStateOverride;
import net.puzzlemc.predicates.accessor.BlockStateModelManagerAccess;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@Mixin(BakedModelManager.class)
public abstract class BakedModelManagerMixin implements BlockStateModelManagerAccess {
//@Shadow private Map<Identifier, BlockStateModel> models;
@Shadow public abstract BlockStateModel getMissingModel();
@Shadow public abstract BlockModels getBlockModels();
@Override @Unique
public BlockStateModel reallyGetModel(BlockStateOverride override) {
return getBlockModels().getModel(override);
//return models.getOrDefault(model, this.getMissingModel());
}
// ITEMS (originally from ItemRendererMixin)
// @Inject(method = "getModel", at = @At(value = "HEAD"))
// private void getHeldItemModelVariableStealerLol(ItemStack stack, World world, LivingEntity entity, int seed, CallbackInfoReturnable<BakedModel> cir) {
// this.world = world;
// this.entity = entity;
// }
//
// @Redirect(method = "getModel", at = @At(value = "INVOKE",target = "Lnet/minecraft/client/render/item/ItemModels;getModel(Lnet/minecraft/item/ItemStack;)Lnet/minecraft/client/render/model/BakedModel;"))
// private BakedModel getHeldItemModelMixin(ItemModels itemModels, ItemStack stack) {
// if (world == null || entity == null) return itemModels.getModel(stack);
//
// BlockPos targetPos = entity.getBlockPos();
// if (entity instanceof PlayerEntity player) {
// HitResult hit = player.raycast(8, MinecraftClient.getInstance().getTickDelta(), false);
// if (hit instanceof BlockHitResult blockHitResult) {
// targetPos = blockHitResult.getBlockPos().add(blockHitResult.getSide().getVector());
// }
// }
//
// Optional<Identifier> identifier = MBPData.meetsPredicate(world, targetPos, Block.getBlockFromItem(stack.getItem()).getDefaultState(), ContextIdentifiers.ITEM_HELD);
//
// if (identifier.isPresent()) {
// BlockStateModelManagerAccess access = BlockStateModelManagerAccess.of(itemModels.getModelManager());
// return access.reallyGetModel(identifier.get());
// }
//
// world = null;
// entity = null;
// return itemModels.getModel(stack);
// }
}

View File

@@ -1,24 +0,0 @@
package net.puzzlemc.predicates.mixin;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.block.BlockRenderManager;
import net.minecraft.client.render.entity.DisplayEntityRenderer;
import net.minecraft.client.render.entity.state.BlockDisplayEntityRenderState;
import net.minecraft.client.util.math.MatrixStack;
import net.puzzlemc.predicates.accessor.BlockRenderManagerAccess;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(DisplayEntityRenderer.BlockDisplayEntityRenderer.class)
public class BlockDisplayEntityRendererMixin {
@Shadow @Final private BlockRenderManager blockRenderManager;
@Inject(method = "render(Lnet/minecraft/client/render/entity/state/BlockDisplayEntityRenderState;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IF)V", at = @At("HEAD"))
public void getContext(BlockDisplayEntityRenderState blockDisplayEntityRenderState, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, float f, CallbackInfo ci) {
BlockRenderManagerAccess.of(blockRenderManager).moreBlockPredicates$setContextEntity(blockDisplayEntityRenderState);
}
}

View File

@@ -1,40 +0,0 @@
package net.puzzlemc.predicates.mixin;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.particle.BlockDustParticle;
import net.minecraft.client.particle.SpriteBillboardParticle;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.puzzlemc.predicates.BlockStateOverride;
import net.puzzlemc.predicates.MBPData;
import net.puzzlemc.predicates.accessor.BlockStateModelManagerAccess;
import net.puzzlemc.predicates.common.ContextIdentifiers;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Optional;
@Mixin(BlockDustParticle.class)
public abstract class BlockDustParticleMixin extends SpriteBillboardParticle {
protected BlockDustParticleMixin(ClientWorld clientWorld, double d, double e, double f) {
super(clientWorld, d, e, f);
}
@Inject(at = @At(value = "TAIL"), method = "<init>(Lnet/minecraft/client/world/ClientWorld;DDDDDDLnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;)V")
public void init(ClientWorld world, double x, double y, double z, double velocityX, double velocityY, double velocityZ, BlockState state, BlockPos blockPos, CallbackInfo ci) {
Optional<BlockStateOverride> identifier = MBPData.meetsPredicate(world, blockPos, state, ContextIdentifiers.FALLING_BLOCK);
MinecraftClient client = MinecraftClient.getInstance();
if (identifier.isPresent()) {
BlockStateModelManagerAccess access = BlockStateModelManagerAccess.of(client.getBakedModelManager());
setSprite(access.reallyGetModel(identifier.get()).particleSprite());
} else {
this.setSprite(client.getBlockRenderManager().getModels().getModelParticleSprite(state));
}
}
}

View File

@@ -1,41 +0,0 @@
package net.puzzlemc.predicates.mixin;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.particle.BlockMarkerParticle;
import net.minecraft.client.particle.SpriteBillboardParticle;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.puzzlemc.predicates.BlockStateOverride;
import net.puzzlemc.predicates.MBPData;
import net.puzzlemc.predicates.accessor.BlockStateModelManagerAccess;
import net.puzzlemc.predicates.common.ContextIdentifiers;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Optional;
@Mixin(BlockMarkerParticle.class)
public abstract class BlockMarkerParticleMixin extends SpriteBillboardParticle {
protected BlockMarkerParticleMixin(ClientWorld clientWorld, double d, double e, double f) {
super(clientWorld, d, e, f);
}
@Inject(at = @At(value = "TAIL"), method = "<init>")
public void init(ClientWorld world, double x, double y, double z, BlockState state, CallbackInfo ci) {
Optional<BlockStateOverride> identifier = MBPData.meetsPredicate(world, BlockPos.ofFloored(x, y, z), state, ContextIdentifiers.MARKER_PARTICLE);
MinecraftClient client = MinecraftClient.getInstance();
if (identifier.isPresent()) {
BlockStateModelManagerAccess access = BlockStateModelManagerAccess.of(client.getBakedModelManager());
setSprite(access.reallyGetModel(identifier.get()).particleSprite());
} else {
this.setSprite(client.getBlockRenderManager().getModels().getModelParticleSprite(state));
}
}
}

View File

@@ -1,47 +0,0 @@
package net.puzzlemc.predicates.mixin;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.block.BlockModelRenderer;
import net.minecraft.client.render.model.BlockModelPart;
import net.minecraft.client.render.model.BlockStateModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockRenderView;
import net.puzzlemc.predicates.PuzzlePredicates;
import org.spongepowered.asm.mixin.Mixin;
import java.util.List;
@Mixin(BlockModelRenderer.class)
public class BlockModelRendererMixin {
@WrapMethod(method = "render(Lnet/minecraft/world/BlockRenderView;Ljava/util/List;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;ZI)V")
public void renderBlock(BlockRenderView world, List<BlockModelPart> parts, BlockState state, BlockPos pos, MatrixStack matrices, VertexConsumer vertexConsumer, boolean cull, int overlay, Operation<Void> original) {
BlockRenderType blockRenderType = state.getRenderType();
System.out.println("B");
if (blockRenderType == BlockRenderType.MODEL) {
if (state.getBlock() == Blocks.SPRUCE_LEAVES) PuzzlePredicates.logger().info(":( Should be activated now");
// BlockStateModel newModel = BlockRendering.tryModelOverride(BlockModels, world, state, pos, ContextIdentifiers.MISC);
// if (newModel != null) {
// PuzzlePredicates.logger().info(":) Replacing "+state.getBlock().toString());
// // TODO: Don't create an instance of Random here
// original.call(world, newModel.getParts(Random.create()), state, pos, matrices, vertexConsumer, cull, OverlayTexture.DEFAULT_UV);
// //this.blockModelRenderer.render(world, newModel.getParts(random), state, pos, matrices, vertexConsumer, cull, OverlayTexture.DEFAULT_UV);
// //ci.cancel();
// return;
// }
}
original.call(world, parts, state, pos, matrices, vertexConsumer, cull, overlay);
}
@WrapMethod(method = "render(Lnet/minecraft/client/util/math/MatrixStack$Entry;Lnet/minecraft/client/render/VertexConsumer;Lnet/minecraft/client/render/model/BlockStateModel;FFFII)V")
private static void c(MatrixStack.Entry entry, VertexConsumer vertexConsumer, BlockStateModel model, float red, float green, float blue, int light, int overlay, Operation<Void> original) {
System.out.println("c");
original.call(entry, vertexConsumer, model, red, green, blue, light, overlay);
}
}

View File

@@ -1,99 +0,0 @@
package net.puzzlemc.predicates.mixin;
import net.minecraft.block.BlockRenderType;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.color.block.BlockColors;
import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.RenderLayers;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.block.BlockModelRenderer;
import net.minecraft.client.render.block.BlockModels;
import net.minecraft.client.render.block.BlockRenderManager;
import net.minecraft.client.render.entity.state.BlockDisplayEntityRenderState;
import net.minecraft.client.render.model.BlockModelPart;
import net.minecraft.client.render.model.BlockStateModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.random.Random;
import net.minecraft.world.BlockRenderView;
import net.puzzlemc.predicates.BlockStateOverride;
import net.puzzlemc.predicates.MBPData;
import net.puzzlemc.predicates.PuzzlePredicates;
import net.puzzlemc.predicates.accessor.BlockStateModelManagerAccess;
import net.puzzlemc.predicates.accessor.BlockRenderManagerAccess;
import net.puzzlemc.predicates.common.BlockRendering;
import net.puzzlemc.predicates.common.ContextIdentifiers;
import net.puzzlemc.predicates.util.Utils;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
import java.util.Optional;
@Mixin(value = BlockRenderManager.class, priority = 2000)
public class BlockRenderManagerMixin implements BlockRenderManagerAccess {
@Shadow @Final private BlockModelRenderer blockModelRenderer;
@Shadow @Final private BlockModels models;
@Shadow @Final private BlockColors blockColors;
@Shadow @Final private Random random;
@Unique private BlockDisplayEntityRenderState mbp$contextRenderState;
@Inject(at = @At("HEAD"), method = "renderBlock", cancellable = true)
public void renderBlock(BlockState state, BlockPos pos, BlockRenderView world, MatrixStack matrices, VertexConsumer vertexConsumer, boolean cull, List<BlockModelPart> parts, CallbackInfo ci) {
BlockRenderType blockRenderType = state.getRenderType();
System.out.println("a");
if (blockRenderType == BlockRenderType.MODEL) {
if (state.getBlock() == Blocks.SPRUCE_LEAVES) PuzzlePredicates.logger().info(":( Should be activated now");
BlockStateModel newModel = BlockRendering.tryModelOverride(this.models, world, state, pos, ContextIdentifiers.MISC);
if (newModel != null) {
PuzzlePredicates.logger().info(":) Replacing "+state.getBlock().toString());
this.blockModelRenderer.render(world, newModel.getParts(random), state, pos, matrices, vertexConsumer, cull, OverlayTexture.DEFAULT_UV);
ci.cancel();
}
}
}
@Inject(at = @At("HEAD"), method = "renderBlockAsEntity", cancellable = true)
public void renderBlockAsEntity(BlockState state, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, CallbackInfo ci) {
if (state.getRenderType() == BlockRenderType.MODEL) {
BlockPos pos = mbp$contextRenderState == null ? BlockPos.ORIGIN : Utils.posFromRenderState(mbp$contextRenderState);
mbp$contextRenderState = null;
Optional<BlockStateOverride> id = MBPData.meetsPredicate(MinecraftClient.getInstance().world, pos, state, ContextIdentifiers.ENTITY);
if (id.isEmpty()) return;
BlockStateModel bakedModel = ((BlockStateModelManagerAccess) this.models.getModelManager()).reallyGetModel(id.get());
int i = this.blockColors.getColor(state, null, null, 0);
float f = (float) (i >> 16 & 0xFF) / 255.0F;
float g = (float) (i >> 8 & 0xFF) / 255.0F;
float h = (float) (i & 0xFF) / 255.0F;
BlockModelRenderer
.render(
matrices.peek(),
vertexConsumers.getBuffer(RenderLayers.getEntityBlockLayer(state)),
bakedModel,
f,
g,
h,
light,
overlay
);
ci.cancel();
}
}
@Override
public void moreBlockPredicates$setContextEntity(BlockDisplayEntityRenderState renderState) {
mbp$contextRenderState = renderState;
}
}

View File

@@ -1,48 +0,0 @@
package net.puzzlemc.predicates.mixin;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.block.BlockRenderManager;
import net.minecraft.client.render.entity.FallingBlockEntityRenderer;
import net.minecraft.client.render.entity.state.FallingBlockEntityRenderState;
import net.minecraft.client.render.model.BlockStateModel;
import net.minecraft.client.util.math.MatrixStack;
import net.puzzlemc.predicates.BlockStateOverride;
import net.puzzlemc.predicates.MBPData;
import net.puzzlemc.predicates.accessor.BlockStateModelManagerAccess;
import net.puzzlemc.predicates.common.ContextIdentifiers;
import net.puzzlemc.predicates.util.Utils;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Optional;
@Mixin(value = FallingBlockEntityRenderer.class, priority = 1100)
public class FallingBlockEntityRendererMixin {
@Unique private FallingBlockEntityRenderState mbp$fallingBlockEntityRenderState;
@Inject(at = @At("HEAD"), method = "render(Lnet/minecraft/client/render/entity/state/FallingBlockEntityRenderState;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V")
public void render(FallingBlockEntityRenderState fallingBlockEntityRenderState, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo ci) {
this.mbp$fallingBlockEntityRenderState = fallingBlockEntityRenderState;
}
@WrapOperation(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockRenderManager;getModel(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/model/BlockStateModel;"),method = "render(Lnet/minecraft/client/render/entity/state/FallingBlockEntityRenderState;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V")
public BlockStateModel render(BlockRenderManager instance, BlockState state, Operation<BlockStateModel> original) {
Optional<BlockStateOverride> identifier = MBPData.meetsPredicate(mbp$fallingBlockEntityRenderState.world, Utils.posFromRenderState(mbp$fallingBlockEntityRenderState), state, ContextIdentifiers.FALLING_BLOCK);
MinecraftClient client = MinecraftClient.getInstance();
if (identifier.isPresent()) {
BlockStateModelManagerAccess access = BlockStateModelManagerAccess.of(client.getBakedModelManager());
return access.reallyGetModel(identifier.get());
} else {
return original.call(instance, state);
}
}
}

View File

@@ -1,21 +0,0 @@
package net.puzzlemc.predicates.mixin;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.ItemEntityRenderer;
import net.minecraft.client.render.entity.state.ItemEntityRenderState;
import net.minecraft.client.util.math.MatrixStack;
import net.puzzlemc.predicates.PuzzlePredicates;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ItemEntityRenderer.class)
public class ItemEntityRendererMixin {
@Inject(at = @At("HEAD"), method = "render(Lnet/minecraft/client/render/entity/state/ItemEntityRenderState;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V")
private void beforeRender(ItemEntityRenderState itemEntityRenderState, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo ci) {
PuzzlePredicates.currentEntityRenderState = itemEntityRenderState;
}
}

View File

@@ -1,22 +0,0 @@
package net.puzzlemc.predicates.mixin;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.ItemFrameEntityRenderer;
import net.minecraft.client.render.entity.state.ItemFrameEntityRenderState;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.decoration.ItemFrameEntity;
import net.puzzlemc.predicates.PuzzlePredicates;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ItemFrameEntityRenderer.class)
public class ItemFrameEntityRendererMixin<T extends ItemFrameEntity> {
@Inject(method = "render(Lnet/minecraft/client/render/entity/state/ItemFrameEntityRenderState;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At("HEAD"))
public void renderMixin(ItemFrameEntityRenderState itemFrameEntityRenderState, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo ci) {
PuzzlePredicates.currentEntityRenderState = itemFrameEntityRenderState;
}
}

View File

@@ -1,73 +0,0 @@
package net.puzzlemc.predicates.mixin;
import net.minecraft.block.Block;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.render.model.BlockStateModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.puzzlemc.predicates.MBPData;
import net.puzzlemc.predicates.PuzzlePredicates;
import net.puzzlemc.predicates.accessor.BlockStateModelManagerAccess;
import net.puzzlemc.predicates.common.ContextIdentifiers;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
@Mixin(ItemRenderer.class)
public abstract class ItemRendererMixin {
//@Shadow @Final private ItemModels models;
@Unique private World world;
@Unique private Entity entity;
//@Redirect(method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/render/model/json/ModelTransformation$Mode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/item/ItemRenderer;renderBakedItemModel(Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/item/ItemStack;IILnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;)V"))
// @Redirect(
// method = "renderItem(Lnet/minecraft/item/ItemStack;Lnet/minecraft/client/render/model/json/ModelTransformationMode;ZLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/client/render/model/BakedModel;)V",
// at = @At(
// value = "INVOKE",
// target = "Lnet/minecraft/client/render/item/ItemRenderer;renderBakedItemModel(Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/item/ItemStack;IILnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;)V"
// )
// )
// private void renderBakedModelMixin(ItemRenderer instance, BakedModel model, ItemStack stack, int light, int overlay, MatrixStack matrices, VertexConsumer vertices) {
// if (world == null) world = MinecraftClient.getInstance().world;
// if (entity == null) entity = MBPClient.currentEntity;
// if (entity == null) entity = MinecraftClient.getInstance().player;
//
// if (entity != null) {
// BlockPos targetPos = entity.getBlockPos();
// if (entity instanceof PlayerEntity player) {
// HitResult hit = player.raycast(8, MinecraftClient.getInstance().getTickDelta(), false);
// if (hit instanceof BlockHitResult blockHitResult) {
// targetPos = blockHitResult.getBlockPos().add(blockHitResult.getSide().getVector());
// }
// }
//
// Optional<Identifier> identifier = MBPData.meetsPredicate(world, targetPos, Block.getBlockFromItem(stack.getItem()).getDefaultState(), ContextIdentifiers.ITEM);
// if (identifier.isPresent()) {
// BlockStateModelManagerAccess access = BlockStateModelManagerAccess.of(models.getModelManager());
// model = access.reallyGetModel(identifier.get());
// }
// PuzzlePredicates.currentEntityRenderState = null;
// }
//
// this.renderBakedItemModel(model, stack, light, overlay, matrices, vertices);
// }
}

View File

@@ -1,50 +0,0 @@
package net.puzzlemc.predicates.mixin;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.block.BlockRenderManager;
import net.minecraft.client.render.block.entity.PistonBlockEntityRenderer;
import net.minecraft.client.render.model.BlockStateModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.puzzlemc.predicates.BlockStateOverride;
import net.puzzlemc.predicates.MBPData;
import net.puzzlemc.predicates.accessor.BlockStateModelManagerAccess;
import net.puzzlemc.predicates.common.ContextIdentifiers;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Optional;
@Mixin(value = PistonBlockEntityRenderer.class, priority = 1100)
public class PistonBlockEntityRendererMixin {
@Unique private BlockPos mbp$tempBlockPos;
@Unique private World mbp$tempWorld;
@Inject(at = @At("HEAD"), method = "renderModel")
public void renderModel(BlockPos pos, BlockState state, MatrixStack matrices, VertexConsumerProvider vertexConsumers, World world, boolean cull, int overlay, CallbackInfo ci) {
this.mbp$tempBlockPos = pos;
this.mbp$tempWorld = world;
}
@WrapOperation(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockRenderManager;getModel(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/model/BlockStateModel;"), method = "renderModel")
public BlockStateModel renderModel(BlockRenderManager instance, BlockState state, Operation<BlockStateModel> original) {
Optional<BlockStateOverride> identifier = MBPData.meetsPredicate(mbp$tempWorld, mbp$tempBlockPos, state, ContextIdentifiers.PISTON_PUSHING);
MinecraftClient client = MinecraftClient.getInstance();
if (identifier.isPresent()) {
BlockStateModelManagerAccess access = BlockStateModelManagerAccess.of(client.getBakedModelManager());
return access.reallyGetModel(identifier.get());
} else {
return original.call(instance, state);
}
}
}

View File

@@ -1,17 +0,0 @@
package net.puzzlemc.predicates.mixin;
import com.mojang.serialization.MapCodec;
import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap;
import net.minecraft.state.State;
import net.minecraft.state.property.Property;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(State.class)
public interface StateAccessor<O, S> {
@Accessor
Reference2ObjectArrayMap<Property<?>, Comparable<?>> getPropertyMap();
@Accessor
MapCodec<S> getCodec();
}

View File

@@ -1,40 +0,0 @@
package net.puzzlemc.predicates.mixin.compat.sodium;
import net.minecraft.block.BlockState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.block.BlockModels;
import net.minecraft.client.render.model.BlockStateModel;
import net.minecraft.util.math.BlockPos;
import net.puzzlemc.predicates.common.BlockRendering;
import net.puzzlemc.predicates.common.ContextIdentifiers;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
//@Mixin(value = ChunkBuilderMeshingTask.class)
public class ChunkBuilderMeshingTaskMixin {
@Unique private int x = 0;
@Unique private int y = 0;
@Unique private int z = 0;
// @Redirect(method = "execute(Lme/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildContext;Lme/jellysquid/mods/sodium/client/util/task/CancellationToken;)Lme/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildOutput;", at = @At(value = "INVOKE", target = "Lme/jellysquid/mods/sodium/client/world/WorldSlice;getBlockState(III)Lnet/minecraft/block/BlockState;"))
// public BlockState getBlockStateRedirect(WorldSlice worldSlice, int x, int y, int z) {
// this.x = x;
// this.y = y;
// this.z = z;
// return worldSlice.getBlockState(x,y,z);
// }
//
// @Redirect(method = "execute(Lme/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildContext;Lme/jellysquid/mods/sodium/client/util/task/CancellationToken;)Lme/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildOutput;", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockModels;getModel(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/model/BakedModel;"))
// public BlockStateModel getModelRedirect(BlockModels models, BlockState state) {
// BakedModel newModel = BlockRendering.tryModelOverride(models, MinecraftClient.getInstance().world, state, new BlockPos(x, y, z), ContextIdentifiers.CHUNK_MESH);
// if (newModel != null)
// return newModel;
//
// // If failed return original method call
// return models.getModel(state);
// }
}

View File

@@ -1,65 +0,0 @@
package net.puzzlemc.predicates.resources;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.minecraft.block.Block;
import net.minecraft.resource.Resource;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import net.puzzlemc.predicates.PuzzlePredicates;
import net.puzzlemc.predicates.data.logic.When;
import net.puzzlemc.predicates.util.Utils;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
//public class MBPModelLoadingPlugin implements PreparableModelLoadingPlugin<HashSet<Identifier>> {
//
//
// @Override
// public void onInitializeModelLoader(HashSet<Identifier> data, ModelLoadingPlugin.Context pluginContext) {
// pluginContext.addModels(data);
// }
//
// public static class ModelIdLoader implements PreparableModelLoadingPlugin.DataLoader<HashSet<Identifier>> {
// @Override
// public CompletableFuture<HashSet<Identifier>> load(ResourceManager manager, Executor executor) {
//
// return CompletableFuture.supplyAsync(() -> {
// HashSet<Identifier> wantedModels = new HashSet<>();
//
// Map<Identifier, Resource> map = manager.findResources("mbp", id -> id.getPath().endsWith(".json"));
// for (Identifier id : map.keySet()) {
//
// try {
// Identifier blockTarget = Identifier.of(id.toString().substring(0,id.toString().length()-5).replace("mbp/", ""));
// JsonObject asset = JsonParser.parseReader(map.get(id).getReader()).getAsJsonObject();
//
// Optional<Block> block = Utils.getBlock(blockTarget);
//
// if (block.isPresent()) {
// JsonArray overrides = asset.getAsJsonArray("overrides");
// for(JsonElement overrideEntry : overrides) {
// When when = When.parse(overrideEntry);
//
// wantedModels.addAll(when.getModels());
// }
// }
//
// } catch (Exception e) {
// PuzzlePredicates.logger().error("Error found in file: " + id, e);
// }
// }
// return wantedModels;
// }, executor);
//
//
// }
// }
//}

View File

@@ -1,50 +0,0 @@
package net.puzzlemc.predicates.util;
import net.minecraft.block.Block;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.entity.state.EntityRenderState;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.biome.Biome;
import java.util.Optional;
import java.util.function.Supplier;
public class Utils {
private static DynamicRegistryManager getRegistryManager() {
MinecraftClient instance = MinecraftClient.getInstance();
return instance != null && instance.world != null ? instance.world.getRegistryManager() : null;
}
public static final Supplier<Optional<Registry<Biome>>> BIOME_REGISTRY = () -> {
DynamicRegistryManager drm = getRegistryManager();
if (drm != null) return drm.getOptional(RegistryKeys.BIOME);
return Optional.empty();
};
public static Optional<Biome> getBiome(Identifier biomeId) {
Optional<Registry<Biome>> registry = BIOME_REGISTRY.get();
if (registry.isPresent()) {
return registry.get().getOptionalValue(biomeId);
}
return Optional.empty();
}
public static Optional<Identifier> getBiome(Biome biome) {
Optional<Registry<Biome>> registry = BIOME_REGISTRY.get();
return registry.map(biomes -> biomes.getId(biome));
}
public static Optional<Block> getBlock(Identifier blockId) {
return Registries.BLOCK.getOptionalValue(blockId);
}
public static BlockPos posFromRenderState(EntityRenderState state) {
return BlockPos.ofFloored(state.x, state.y, state.z);
}
}

View File

@@ -7,15 +7,10 @@ import com.mojang.blaze3d.platform.DestFactor;
import com.mojang.blaze3d.platform.SourceFactor;
import eu.midnightdust.lib.util.MidnightColorUtil;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.minecraft.client.gui.screen.SplashOverlay;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.RenderPhase;
import net.minecraft.client.texture.NativeImageBackedTexture;
import net.minecraft.client.texture.TextureContents;
import net.minecraft.resource.*;
import net.minecraft.util.TriState;
import net.minecraft.util.Util;
import net.puzzlemc.core.PuzzleModule;
import net.puzzlemc.core.config.PuzzleConfig;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.resource.metadata.TextureResourceMetadata;
@@ -35,10 +30,10 @@ import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import static net.puzzlemc.core.PuzzleCore.LOGGER;
import static net.puzzlemc.core.PuzzleCore.MOD_ID;
public class PuzzleSplashScreen implements PuzzleModule {
public static final PuzzleSplashScreen INSTANCE = new PuzzleSplashScreen();
public class PuzzleSplashScreen {
public static final Identifier LOGO = Identifier.of("textures/gui/title/mojangstudios.png");
public static final Identifier BACKGROUND = Identifier.of("puzzle/splash_background.png");
public static File CONFIG_PATH = new File(String.valueOf(PlatformFunctions.getConfigDirectory().resolve(".puzzle_cache")));
@@ -46,28 +41,25 @@ public class PuzzleSplashScreen implements PuzzleModule {
public static Path BACKGROUND_TEXTURE = Paths.get(CONFIG_PATH + "/splash_background.png");
private static MinecraftClient client = MinecraftClient.getInstance();
private static boolean keepBackground = false;
private static RenderLayer CUSTOM_LOGO_LAYER;
private static RenderPipeline CUSTOM_LOGO_PIPELINE;
@Override
public String getModuleId() {
return "splashscreen";
}
@Override
public void init() {
// When config directory is nonexistent, create it and set the folder as hidden on Windows systems //
if (!CONFIG_PATH.exists() && CONFIG_PATH.mkdir() && Util.getOperatingSystem().equals(Util.OperatingSystem.WINDOWS)) {
public static void init() {
if (!CONFIG_PATH.exists()) { // Run when config directory is nonexistent //
if (CONFIG_PATH.mkdir()) { // Create our custom config directory //
if (Util.getOperatingSystem().equals(Util.OperatingSystem.WINDOWS)) {
try { Files.setAttribute(CONFIG_PATH.toPath(), "dos:hidden", true);
} catch (IOException ignored) {}
}
}
}
buildRenderLayer();
}
public static RenderLayer getCustomLogoRenderLayer() {
return CUSTOM_LOGO_LAYER;
public static RenderPipeline getCustomLogoRenderPipeline() {
return CUSTOM_LOGO_PIPELINE;
}
public void buildRenderLayer() {
public static void buildRenderLayer() {
if (PuzzleConfig.resourcepackSplashScreen) {
BlendFunction blendFunction = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE);
if (PuzzleConfig.disableBlend) blendFunction = null;
@@ -79,7 +71,7 @@ public class PuzzleSplashScreen implements PuzzleModule {
SourceFactor.valueOf(PuzzleConfig.customBlendFunction.get(2)),
DestFactor.valueOf(PuzzleConfig.customBlendFunction.get(3)));
} catch (Exception e) {
getLogger().error("Incorrect blend function defined in color.properties: {}{}", PuzzleConfig.customBlendFunction, e.getMessage());
LOGGER.error("Incorrect blend function defined in color.properties: {}{}", PuzzleConfig.customBlendFunction, e.getMessage());
}
}
@@ -89,16 +81,17 @@ public class PuzzleSplashScreen implements PuzzleModule {
.withDepthWrite(false);
CUSTOM_LOGO_PIPELINE_BUILDER = blendFunction != null ? CUSTOM_LOGO_PIPELINE_BUILDER.withBlend(blendFunction) : CUSTOM_LOGO_PIPELINE_BUILDER.withoutBlend();
CUSTOM_LOGO_LAYER = RenderLayer.of("mojang_logo_puzzle", 786432, CUSTOM_LOGO_PIPELINE_BUILDER.build(),
RenderLayer.MultiPhaseParameters.builder()
.texture(new RenderPhase.Texture(SplashOverlay.LOGO, TriState.DEFAULT, false))
.build(false));
CUSTOM_LOGO_PIPELINE = CUSTOM_LOGO_PIPELINE_BUILDER.build();
}
}
public static class ReloadListener implements SynchronousResourceReloader {
public static final ReloadListener INSTANCE = new ReloadListener();
private ReloadListener() {}
@Override
public void reloadResources(ResourceManager manager) {
public void reload(ResourceManager manager) {
client = MinecraftClient.getInstance();
if (PuzzleConfig.resourcepackSplashScreen) {
PuzzleSplashScreen.resetColors();
@@ -134,7 +127,7 @@ public class PuzzleSplashScreen implements PuzzleModule {
}
} catch (Exception e) {
getLogger().error("Error occurred while loading color.properties {}", id.toString(), e);
LOGGER.error("Error occurred while loading color.properties {}", id.toString(), e);
}
});
AtomicInteger logoCount = new AtomicInteger();
@@ -145,7 +138,7 @@ public class PuzzleSplashScreen implements PuzzleModule {
if (logoCount.get() > 0) PuzzleConfig.hasCustomSplashScreen = true;
logoCount.getAndIncrement();
} catch (Exception e) {
getLogger().error("Error occurred while loading custom minecraft logo {}", id.toString(), e);
LOGGER.error("Error occurred while loading custom minecraft logo {}", id.toString(), e);
}
});
manager.findResources(MOD_ID, path -> path.getPath().contains("splash_background.png")).forEach((id, resource) -> {
@@ -156,20 +149,20 @@ public class PuzzleSplashScreen implements PuzzleModule {
keepBackground = true;
PuzzleConfig.hasCustomSplashScreen = true;
} catch (Exception e) {
getLogger().error("Error occurred while loading custom splash background {}", id.toString(), e);
LOGGER.error("Error occurred while loading custom splash background {}", id.toString(), e);
}
});
if (!keepBackground) {
try {
Files.delete(BACKGROUND_TEXTURE);
} catch (Exception ignored) {
}
} catch (Exception ignored) {}
}
keepBackground = false;
PuzzleConfig.write(MOD_ID);
buildRenderLayer();
}
}
}
public static void resetColors() {
PuzzleConfig.backgroundColor = 15675965;
@@ -215,7 +208,7 @@ public class PuzzleSplashScreen implements PuzzleModule {
InputStream input = new FileInputStream(String.valueOf(PuzzleSplashScreen.LOGO_TEXTURE));
return new TextureContents(NativeImage.read(input), new TextureResourceMetadata(true, true));
} catch (IOException e) {
INSTANCE.getLogger().error("Encountered an error during logo loading: ", e);
LOGGER.error("Encountered an error during logo loading: ", e);
try {
return TextureContents.load(resourceManager, LOGO);
} catch (IOException ex) {

View File

@@ -2,11 +2,12 @@ package net.puzzlemc.splashscreen.mixin;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.mojang.blaze3d.pipeline.RenderPipeline;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gl.RenderPipelines;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Overlay;
import net.minecraft.client.gui.screen.SplashOverlay;
import net.minecraft.client.render.*;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.NativeImageBackedTexture;
import net.minecraft.client.texture.TextureManager;
@@ -26,7 +27,6 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.function.Function;
import java.util.function.IntSupplier;
import static net.puzzlemc.splashscreen.PuzzleSplashScreen.BACKGROUND;
@@ -63,11 +63,11 @@ public abstract class MixinSplashScreen extends Overlay {
return (!PuzzleConfig.resourcepackSplashScreen || PuzzleConfig.progressBarBackgroundColor == 15675965) ? instance.getAsInt() : PuzzleConfig.backgroundColor | 255 << 24;
}
@WrapOperation(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawTexture(Ljava/util/function/Function;Lnet/minecraft/util/Identifier;IIFFIIIIIII)V"))
private void puzzle$modifyRenderLayer(DrawContext instance, Function<Identifier, RenderLayer> renderLayers, Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color, Operation<Void> original) {
@WrapOperation(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawTexture(Lcom/mojang/blaze3d/pipeline/RenderPipeline;Lnet/minecraft/util/Identifier;IIFFIIIIIII)V"))
private void puzzle$modifyRenderLayer(DrawContext instance, RenderPipeline pipeline, Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color, Operation<Void> original) {
if (PuzzleConfig.resourcepackSplashScreen)
instance.drawTexture(id -> PuzzleSplashScreen.getCustomLogoRenderLayer(), sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, color);
else instance.drawTexture(renderLayers, sprite, x, y, u, v, width, height, textureWidth, textureHeight, color);
instance.drawTexture(PuzzleSplashScreen.getCustomLogoRenderPipeline(), sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, color);
else instance.drawTexture(pipeline, sprite, x, y, u, v, width, height, textureWidth, textureHeight, color);
}
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;getScaledWindowWidth()I", ordinal = 2))
@@ -82,14 +82,12 @@ public abstract class MixinSplashScreen extends Overlay {
if (f >= 1.0F) s = 1.0F - MathHelper.clamp(f - 1.0F, 0.0F, 1.0F);
else if (reloading) s = MathHelper.clamp(g, 0.0F, 1.0F);
else s = 1.0F;
context.getMatrices().translate(0, 0, 1f);
context.drawTexture(RenderLayer::getGuiTextured, BACKGROUND, 0, 0, 0, 0, width, height, width, height, ColorHelper.getWhite(s));
context.drawTexture(RenderPipelines.GUI_TEXTURED, BACKGROUND, 0, 0, 0, 0, width, height, width, height, ColorHelper.getWhite(s));
}
}
@Inject(method = "renderProgressBar", at = @At("HEAD"))
private void puzzle$addProgressBarBackground(DrawContext context, int minX, int minY, int maxX, int maxY, float opacity, CallbackInfo ci) {
context.getMatrices().translate(0, 0, 1f);
if (!PuzzleConfig.resourcepackSplashScreen || PuzzleConfig.progressBarBackgroundColor == 15675965) return;
long l = Util.getMeasuringTimeMs();
float f = this.reloadCompleteTime > -1L ? (float)(l - this.reloadCompleteTime) / 1000.0F : -1.0F;

View File

@@ -1,24 +0,0 @@
{
"required": true,
"package": "net.puzzlemc.predicates.mixin",
"compatibilityLevel": "JAVA_17",
"client": [
"BakedModelManagerMixin",
"BlockDisplayEntityRendererMixin",
"BlockDustParticleMixin",
"BlockMarkerParticleMixin",
"BlockModelRendererMixin",
"BlockRenderManagerMixin",
"FallingBlockEntityRendererMixin",
"ItemEntityRendererMixin",
"ItemFrameEntityRendererMixin",
"ItemRendererMixin",
"PistonBlockEntityRendererMixin"
],
"injectors": {
"defaultRequire": 1
},
"mixins": [
"StateAccessor"
]
}

View File

@@ -1,11 +0,0 @@
{
"required": true,
"package": "net.puzzlemc.predicates.mixin.compat",
"compatibilityLevel": "JAVA_17",
"plugin": "net.puzzlemc.core.mixin.PuzzleMixinPlugin",
"client": [
],
"injectors": {
"defaultRequire": 1
}
}

View File

@@ -26,7 +26,7 @@ dependencies {
modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
modImplementation include ("maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric")
modImplementation ("com.terraformersmc:modmenu:${project.modmenu_version}") {
modCompileOnlyApi ("com.terraformersmc:modmenu:${project.modmenu_version}") {
exclude(group: "net.fabricmc.fabric-api")
}

View File

@@ -1,68 +0,0 @@
package net.puzzlemc.fabric;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin;
import net.fabricmc.fabric.api.client.model.loading.v1.PreparableModelLoadingPlugin;
import net.minecraft.block.Block;
import net.minecraft.resource.Resource;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import net.puzzlemc.predicates.PuzzlePredicates;
import net.puzzlemc.predicates.data.logic.When;
import net.puzzlemc.predicates.util.Utils;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
public class MBPModelLoadingPlugin implements PreparableModelLoadingPlugin<HashSet<Identifier>> {
@Override
public void initialize(HashSet<Identifier> data, ModelLoadingPlugin.Context pluginContext) {
//pluginContext.addModels(data);
}
public static class ModelIdLoader implements DataLoader<HashSet<Identifier>> {
@Override
public CompletableFuture<HashSet<Identifier>> load(ResourceManager manager, Executor executor) {
return CompletableFuture.supplyAsync(() -> {
HashSet<Identifier> wantedModels = new HashSet<>();
Map<Identifier, Resource> map = manager.findResources("mbp", id -> id.getPath().endsWith(".json"));
for (Identifier id : map.keySet()) {
try {
Identifier blockTarget = Identifier.of(id.toString().substring(0,id.toString().length()-5).replace("mbp/", ""));
JsonObject asset = JsonParser.parseReader(map.get(id).getReader()).getAsJsonObject();
Optional<Block> block = Utils.getBlock(blockTarget);
if (block.isPresent()) {
JsonArray overrides = asset.getAsJsonArray("overrides");
PuzzlePredicates.logger().info("* Model Loader: "+blockTarget+ " " + overrides);
for(JsonElement overrideEntry : overrides) {
When when = When.parse(overrideEntry);
wantedModels.addAll(when.getModels());
}
}
} catch (Exception e) {
PuzzlePredicates.logger().error("Error found in file: " + id, e);
}
}
return wantedModels;
}, executor);
}
}
}

View File

@@ -3,17 +3,16 @@ package net.puzzlemc.fabric;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
import net.fabricmc.fabric.impl.client.model.loading.ModelLoadingPluginManager;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier;
import net.puzzlemc.core.PuzzleCore;
import net.puzzlemc.splashscreen.PuzzleSplashScreen;
public class PuzzleFabric implements ClientModInitializer {
@Override
public void onInitializeClient() {
PuzzleCore.initModules();
ModelLoadingPluginManager.registerPlugin(new MBPModelLoadingPlugin.ModelIdLoader(), new MBPModelLoadingPlugin());
ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() {
@Override
@@ -22,7 +21,7 @@ public class PuzzleFabric implements ClientModInitializer {
}
@Override
public void reload(ResourceManager manager) {
PuzzleCore.PuzzleResourceManager.INSTANCE.reload(manager);
PuzzleSplashScreen.ReloadListener.INSTANCE.reload(manager);
}
});
}

View File

@@ -32,9 +32,7 @@
"mixins": [
"puzzle-gui.mixins.json",
"puzzle-models.mixins.json",
"puzzle-splashscreen.mixins.json",
"puzzle-predicates.mixins.json",
"puzzle-predicates_compat.mixins.json"
"puzzle-splashscreen.mixins.json"
],
"depends": {

View File

@@ -1,13 +1,13 @@
# Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx2G
minecraft_version=1.21.5
minecraft_version=1.21.9
supported_versions=
yarn_mappings=1.21.5+build.1
yarn_mappings=1.21.9+build.1
enabled_platforms=fabric,neoforge
# Mod Properties
mod_version = 2.1.0
mod_version = 2.1.2
maven_group = net.puzzlemc
archives_base_name = puzzle
release_type=release
@@ -15,15 +15,15 @@ curseforge_id=563977
modrinth_id=3IuO68q1
# Modloaders
fabric_loader_version=0.16.10
fabric_api_version=0.119.5+1.21.5
fabric_loader_version=0.17.2
fabric_api_version=0.133.14+1.21.9
neoforge_version=21.5.3-beta
neoforge_version=21.9.3-beta
yarn_mappings_patch_neoforge_version = 1.21+build.4
# Libraries
midnightlib_version = 1.7.0+1.21.4
modmenu_version = 13.0.0-beta.1
midnightlib_version = 1.8.1+1.21.9
modmenu_version = 15.0.0-beta.1
# Mod Integrations
cull_leaves_version = 3.0.2-fabric

View File

@@ -21,7 +21,7 @@ public class PuzzleNeoForge {
ModList.get().getModContainerById(MOD_ID).orElseThrow().registerExtensionPoint(IConfigScreenFactory.class, (client, parent) -> new PuzzleOptionsScreen(parent));
}
@EventBusSubscriber(modid = MOD_ID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
@EventBusSubscriber(modid = MOD_ID, value = Dist.CLIENT)
public static class MidnightLibBusEvents {
@SubscribeEvent
public static void onResourceReload(AddClientReloadListenersEvent event) {