mirror of
https://github.com/PuzzleMC/Puzzle.git
synced 2025-12-15 19:35:10 +01:00
Compare commits
1 Commits
5117c886e0
...
feat/mbp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99a450e395 |
@@ -1,18 +1,32 @@
|
||||
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 org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class PuzzleCore {
|
||||
public final static String MOD_ID = "puzzle";
|
||||
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
|
||||
private static final List<PuzzleModule> MODULES = new ArrayList<>();
|
||||
|
||||
public static void initModules() {
|
||||
PuzzleConfig.init(MOD_ID, PuzzleConfig.class);
|
||||
PuzzleGui.init();
|
||||
PuzzleSplashScreen.init();
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
common/src/main/java/net/puzzlemc/core/PuzzleModule.java
Normal file
13
common/src/main/java/net/puzzlemc/core/PuzzleModule.java
Normal file
@@ -0,0 +1,13 @@
|
||||
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());}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
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) {
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,6 @@ 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<>();
|
||||
@@ -17,21 +15,21 @@ public class PuzzleApi {
|
||||
public static void addToGraphicsOptions(PuzzleWidget button) {
|
||||
GRAPHICS_OPTIONS.add(button);
|
||||
if (PuzzleConfig.debugMessages)
|
||||
LOGGER.info("{} -> Graphics Options", button.descriptionText.getContent().toString());
|
||||
PuzzleGui.logger().info("{} -> Graphics Options", button.descriptionText.getContent().toString());
|
||||
}
|
||||
public static void addToMiscOptions(PuzzleWidget button) {
|
||||
MISC_OPTIONS.add(button);
|
||||
if (PuzzleConfig.debugMessages)
|
||||
LOGGER.info("{} -> Misc Options", button.descriptionText.getContent().toString());
|
||||
PuzzleGui.logger().info("{} -> Misc Options", button.descriptionText.getContent().toString());
|
||||
}
|
||||
public static void addToPerformanceOptions(PuzzleWidget button) {
|
||||
PERFORMANCE_OPTIONS.add(button);
|
||||
if (PuzzleConfig.debugMessages)
|
||||
LOGGER.info("{}- > Performance Options", button.descriptionText.getContent().toString());
|
||||
PuzzleGui.logger().info("{}- > Performance Options", button.descriptionText.getContent().toString());
|
||||
}
|
||||
public static void addToResourceOptions(PuzzleWidget button) {
|
||||
RESOURCE_OPTIONS.add(button);
|
||||
if (PuzzleConfig.debugMessages)
|
||||
LOGGER.info("{} -> Resource Options", button.descriptionText.getContent().toString());
|
||||
PuzzleGui.logger().info("{} -> Resource Options", button.descriptionText.getContent().toString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ 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;
|
||||
@@ -10,16 +11,22 @@ import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.puzzlemc.splashscreen.PuzzleSplashScreen;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import static net.puzzlemc.core.PuzzleCore.LOGGER;
|
||||
|
||||
public class PuzzleGui {
|
||||
public class PuzzleGui implements PuzzleModule {
|
||||
public static final PuzzleGui INSTANCE = new 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");
|
||||
|
||||
public static void init() {
|
||||
@Override
|
||||
public String getModuleId() {
|
||||
return "gui";
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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) -> {
|
||||
@@ -56,7 +63,7 @@ public class PuzzleGui {
|
||||
if (isActive("entity_texture_features")) ETFCompat.init();
|
||||
if (isActive("entity_model_features")) EMFCompat.init();
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("ETF/EMF config structure changed. Again...", e);
|
||||
INSTANCE.getLogger().error("ETF/EMF config structure changed. Again...", e);
|
||||
}
|
||||
|
||||
lateInitDone = true;
|
||||
@@ -64,4 +71,7 @@ public class PuzzleGui {
|
||||
public static boolean isActive(String modid) {
|
||||
return PlatformFunctions.isModLoaded(modid) && !PuzzleConfig.disabledIntegrations.contains(modid);
|
||||
}
|
||||
public static Logger logger() {
|
||||
return INSTANCE.getLogger();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,13 @@ 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;
|
||||
|
||||
import static net.puzzlemc.core.PuzzleCore.LOGGER;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class PuzzleOptionListWidget extends MidnightConfig.MidnightConfigListWidget {
|
||||
TextRenderer textRenderer;
|
||||
@@ -42,10 +41,10 @@ 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
|
||||
LOGGER.warn("Button {} is missing the buttonType variable. This shouldn't happen!", button);
|
||||
PuzzleGui.logger().warn("Button {} is missing the buttonType variable. This shouldn't happen!", button);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOGGER.error("Failed to add button {}. Likely caused by an update of the specific mod.", button.descriptionText);
|
||||
PuzzleGui.logger().error("Failed to add button {}. Likely caused by an update of the specific mod.", button.descriptionText);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
29
common/src/main/java/net/puzzlemc/predicates/MBPData.java
Normal file
29
common/src/main/java/net/puzzlemc/predicates/MBPData.java
Normal file
@@ -0,0 +1,29 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
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) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
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");
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
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()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
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()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
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)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
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);
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
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);
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
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();
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
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);
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
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);
|
||||
//
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
50
common/src/main/java/net/puzzlemc/predicates/util/Utils.java
Normal file
50
common/src/main/java/net/puzzlemc/predicates/util/Utils.java
Normal file
@@ -0,0 +1,50 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ 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;
|
||||
@@ -34,10 +35,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 {
|
||||
public class PuzzleSplashScreen implements PuzzleModule {
|
||||
public static final PuzzleSplashScreen INSTANCE = new 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")));
|
||||
@@ -47,14 +48,17 @@ public class PuzzleSplashScreen {
|
||||
private static boolean keepBackground = false;
|
||||
private static RenderLayer CUSTOM_LOGO_LAYER;
|
||||
|
||||
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) {}
|
||||
}
|
||||
}
|
||||
@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)) {
|
||||
try { Files.setAttribute(CONFIG_PATH.toPath(), "dos:hidden", true);
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
buildRenderLayer();
|
||||
}
|
||||
@@ -63,7 +67,7 @@ public class PuzzleSplashScreen {
|
||||
return CUSTOM_LOGO_LAYER;
|
||||
}
|
||||
|
||||
public static void buildRenderLayer() {
|
||||
public void buildRenderLayer() {
|
||||
if (PuzzleConfig.resourcepackSplashScreen) {
|
||||
BlendFunction blendFunction = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE);
|
||||
if (PuzzleConfig.disableBlend) blendFunction = null;
|
||||
@@ -75,7 +79,7 @@ public class PuzzleSplashScreen {
|
||||
SourceFactor.valueOf(PuzzleConfig.customBlendFunction.get(2)),
|
||||
DestFactor.valueOf(PuzzleConfig.customBlendFunction.get(3)));
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Incorrect blend function defined in color.properties: {}{}", PuzzleConfig.customBlendFunction, e.getMessage());
|
||||
getLogger().error("Incorrect blend function defined in color.properties: {}{}", PuzzleConfig.customBlendFunction, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,82 +96,78 @@ public class PuzzleSplashScreen {
|
||||
}
|
||||
}
|
||||
|
||||
public static class ReloadListener implements SynchronousResourceReloader {
|
||||
public static final ReloadListener INSTANCE = new ReloadListener();
|
||||
|
||||
private ReloadListener() {}
|
||||
@Override
|
||||
public void reloadResources(ResourceManager manager) {
|
||||
client = MinecraftClient.getInstance();
|
||||
if (PuzzleConfig.resourcepackSplashScreen) {
|
||||
PuzzleSplashScreen.resetColors();
|
||||
client.getTextureManager().registerTexture(LOGO, new LogoTexture(LOGO));
|
||||
client.getTextureManager().registerTexture(BACKGROUND, new LogoTexture(BACKGROUND));
|
||||
|
||||
@Override
|
||||
public void reload(ResourceManager manager) {
|
||||
client = MinecraftClient.getInstance();
|
||||
if (PuzzleConfig.resourcepackSplashScreen) {
|
||||
PuzzleSplashScreen.resetColors();
|
||||
client.getTextureManager().registerTexture(LOGO, new LogoTexture(LOGO));
|
||||
client.getTextureManager().registerTexture(BACKGROUND, new LogoTexture(BACKGROUND));
|
||||
manager.findResources("optifine", path -> path.getPath().contains("color.properties")).forEach((id, resource) -> {
|
||||
try (InputStream stream = resource.getInputStream()) {
|
||||
Properties properties = new Properties();
|
||||
properties.load(stream);
|
||||
|
||||
manager.findResources("optifine", path -> path.getPath().contains("color.properties")).forEach((id, resource) -> {
|
||||
try (InputStream stream = resource.getInputStream()) {
|
||||
Properties properties = new Properties();
|
||||
properties.load(stream);
|
||||
|
||||
if (properties.get("screen.loading") != null) {
|
||||
PuzzleConfig.backgroundColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading").toString()).getRGB();
|
||||
PuzzleConfig.hasCustomSplashScreen = true;
|
||||
}
|
||||
if (properties.get("screen.loading.bar") != null) {
|
||||
PuzzleConfig.progressBarBackgroundColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.bar").toString()).getRGB();
|
||||
PuzzleConfig.hasCustomSplashScreen = true;
|
||||
}
|
||||
if (properties.get("screen.loading.progress") != null) {
|
||||
PuzzleConfig.progressBarColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.progress").toString()).getRGB();
|
||||
PuzzleConfig.hasCustomSplashScreen = true;
|
||||
}
|
||||
if (properties.get("screen.loading.outline") != null) {
|
||||
PuzzleConfig.progressFrameColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.outline").toString()).getRGB();
|
||||
PuzzleConfig.hasCustomSplashScreen = true;
|
||||
}
|
||||
if (properties.get("screen.loading.blend") != null) {
|
||||
// Recommended blend: SRC_ALPHA ONE_MINUS_SRC_ALPHA ONE ZERO
|
||||
PuzzleConfig.disableBlend = properties.get("screen.loading.blend").toString().equals("off");
|
||||
PuzzleConfig.customBlendFunction = new ArrayList<>(Arrays.stream(properties.get("screen.loading.blend").toString().split(" ")).toList());
|
||||
PuzzleConfig.hasCustomSplashScreen = true;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error occurred while loading color.properties {}", id.toString(), e);
|
||||
}
|
||||
});
|
||||
AtomicInteger logoCount = new AtomicInteger();
|
||||
manager.findResources("textures", path -> path.getPath().contains("mojangstudios.png")).forEach((id, resource) -> {
|
||||
try (InputStream stream = resource.getInputStream()) {
|
||||
Files.copy(stream, LOGO_TEXTURE, StandardCopyOption.REPLACE_EXISTING);
|
||||
client.getTextureManager().registerTexture(LOGO, new DynamicLogoTexture());
|
||||
if (logoCount.get() > 0) PuzzleConfig.hasCustomSplashScreen = true;
|
||||
logoCount.getAndIncrement();
|
||||
} catch (Exception 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) -> {
|
||||
try (InputStream stream = resource.getInputStream()) {
|
||||
Files.copy(stream, BACKGROUND_TEXTURE, StandardCopyOption.REPLACE_EXISTING);
|
||||
InputStream input = new FileInputStream(String.valueOf(PuzzleSplashScreen.BACKGROUND_TEXTURE));
|
||||
client.getTextureManager().registerTexture(BACKGROUND, new NativeImageBackedTexture(() -> "splash_screen_background", NativeImage.read(input)));
|
||||
keepBackground = true;
|
||||
if (properties.get("screen.loading") != null) {
|
||||
PuzzleConfig.backgroundColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading").toString()).getRGB();
|
||||
PuzzleConfig.hasCustomSplashScreen = true;
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error occurred while loading custom splash background {}", id.toString(), e);
|
||||
}
|
||||
});
|
||||
if (!keepBackground) {
|
||||
try {
|
||||
Files.delete(BACKGROUND_TEXTURE);
|
||||
} catch (Exception ignored) {}
|
||||
if (properties.get("screen.loading.bar") != null) {
|
||||
PuzzleConfig.progressBarBackgroundColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.bar").toString()).getRGB();
|
||||
PuzzleConfig.hasCustomSplashScreen = true;
|
||||
}
|
||||
if (properties.get("screen.loading.progress") != null) {
|
||||
PuzzleConfig.progressBarColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.progress").toString()).getRGB();
|
||||
PuzzleConfig.hasCustomSplashScreen = true;
|
||||
}
|
||||
if (properties.get("screen.loading.outline") != null) {
|
||||
PuzzleConfig.progressFrameColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.outline").toString()).getRGB();
|
||||
PuzzleConfig.hasCustomSplashScreen = true;
|
||||
}
|
||||
if (properties.get("screen.loading.blend") != null) {
|
||||
// Recommended blend: SRC_ALPHA ONE_MINUS_SRC_ALPHA ONE ZERO
|
||||
PuzzleConfig.disableBlend = properties.get("screen.loading.blend").toString().equals("off");
|
||||
PuzzleConfig.customBlendFunction = new ArrayList<>(Arrays.stream(properties.get("screen.loading.blend").toString().split(" ")).toList());
|
||||
PuzzleConfig.hasCustomSplashScreen = true;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
getLogger().error("Error occurred while loading color.properties {}", id.toString(), e);
|
||||
}
|
||||
});
|
||||
AtomicInteger logoCount = new AtomicInteger();
|
||||
manager.findResources("textures", path -> path.getPath().contains("mojangstudios.png")).forEach((id, resource) -> {
|
||||
try (InputStream stream = resource.getInputStream()) {
|
||||
Files.copy(stream, LOGO_TEXTURE, StandardCopyOption.REPLACE_EXISTING);
|
||||
client.getTextureManager().registerTexture(LOGO, new DynamicLogoTexture());
|
||||
if (logoCount.get() > 0) PuzzleConfig.hasCustomSplashScreen = true;
|
||||
logoCount.getAndIncrement();
|
||||
} catch (Exception e) {
|
||||
getLogger().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) -> {
|
||||
try (InputStream stream = resource.getInputStream()) {
|
||||
Files.copy(stream, BACKGROUND_TEXTURE, StandardCopyOption.REPLACE_EXISTING);
|
||||
InputStream input = new FileInputStream(String.valueOf(PuzzleSplashScreen.BACKGROUND_TEXTURE));
|
||||
client.getTextureManager().registerTexture(BACKGROUND, new NativeImageBackedTexture(() -> "splash_screen_background", NativeImage.read(input)));
|
||||
keepBackground = true;
|
||||
PuzzleConfig.hasCustomSplashScreen = true;
|
||||
} catch (Exception e) {
|
||||
getLogger().error("Error occurred while loading custom splash background {}", id.toString(), e);
|
||||
}
|
||||
});
|
||||
if (!keepBackground) {
|
||||
try {
|
||||
Files.delete(BACKGROUND_TEXTURE);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
keepBackground = false;
|
||||
PuzzleConfig.write(MOD_ID);
|
||||
buildRenderLayer();
|
||||
}
|
||||
keepBackground = false;
|
||||
PuzzleConfig.write(MOD_ID);
|
||||
buildRenderLayer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ public class PuzzleSplashScreen {
|
||||
InputStream input = new FileInputStream(String.valueOf(PuzzleSplashScreen.LOGO_TEXTURE));
|
||||
return new TextureContents(NativeImage.read(input), new TextureResourceMetadata(true, true));
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Encountered an error during logo loading: ", e);
|
||||
INSTANCE.getLogger().error("Encountered an error during logo loading: ", e);
|
||||
try {
|
||||
return TextureContents.load(resourceManager, LOGO);
|
||||
} catch (IOException ex) {
|
||||
|
||||
24
common/src/main/resources/puzzle-predicates.mixins.json
Normal file
24
common/src/main/resources/puzzle-predicates.mixins.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"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"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"required": true,
|
||||
"package": "net.puzzlemc.predicates.mixin.compat",
|
||||
"compatibilityLevel": "JAVA_17",
|
||||
"plugin": "net.puzzlemc.core.mixin.PuzzleMixinPlugin",
|
||||
"client": [
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
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);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,16 +3,17 @@ 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
|
||||
@@ -21,7 +22,7 @@ public class PuzzleFabric implements ClientModInitializer {
|
||||
}
|
||||
@Override
|
||||
public void reload(ResourceManager manager) {
|
||||
PuzzleSplashScreen.ReloadListener.INSTANCE.reload(manager);
|
||||
PuzzleCore.PuzzleResourceManager.INSTANCE.reload(manager);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -32,7 +32,9 @@
|
||||
"mixins": [
|
||||
"puzzle-gui.mixins.json",
|
||||
"puzzle-models.mixins.json",
|
||||
"puzzle-splashscreen.mixins.json"
|
||||
"puzzle-splashscreen.mixins.json",
|
||||
"puzzle-predicates.mixins.json",
|
||||
"puzzle-predicates_compat.mixins.json"
|
||||
],
|
||||
|
||||
"depends": {
|
||||
|
||||
Reference in New Issue
Block a user