Skip to content

Commit

Permalink
added new config system for registering visual workbenches
Browse files Browse the repository at this point in the history
  • Loading branch information
Fuzss committed Dec 6, 2021
1 parent 485c014 commit 05da0e6
Show file tree
Hide file tree
Showing 10 changed files with 211 additions and 96 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,18 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog].

## [v2.0.0-1.17.1] - 2021-12-06
### Added
- Added new system for manually registering crafting table blocks that should be supported by Visual Workbench
- Previous solution was too unreliable
### Fixed
- Fixed a client desync issue when FastWorkbench Minus Replacement mod is installed

## [v2.0.0b2-1.17.1] - 2021-11-28
### Fixed
- Fixed an issue where shift-clicking multiple crafting results wouldn't work properly

## [v2.0.0b1-1.17.1] - 2021-11-23
- Ported to Minecraft 1.17
### Issues
- Fletching and smithing tables cannot be moved by pistons

[Keep a Changelog]: https://keepachangelog.com/en/1.0.0/
8 changes: 4 additions & 4 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ org.gradle.daemon=false
minecraftVersion=1.17.1
projectLoader=Forge
forgeVersion=1.17.1-37.0.104
puzzlesVersion=v2.0.1-1.17.1-Forge
puzzlesVersion=v2.0.2-1.17.1-Forge
mappingsChannel=parchment
mappingsVersion=2021.10.31-1.17.1
enableHotswap=false
Expand All @@ -16,13 +16,13 @@ copyBuildJar=true
# dependencies
minForgeVersion=37
minMinecraftVersion=1.17.1
minPuzzlesVersion=2.0.1
minPuzzlesVersion=2.0.2
packFormat=7

# attributes
modId=visualworkbench
modName=Visual Workbench
modVersion=2.0.0b2
modVersion=2.0.0
modAuthor=Fuzs
modDescription=Items stay inside of crafting tables and are also rendered on top. It's really fancy!
modPageUrl=https://www.curseforge.com/minecraft/mc-mods/visual-workbench
Expand All @@ -33,5 +33,5 @@ modGroup=fuzs.visualworkbench

# publishing
curseProjectId=500273
curseReleaseType=beta
curseReleaseType=release
curseProjectVersion=1.17.1
7 changes: 5 additions & 2 deletions src/main/java/fuzs/visualworkbench/VisualWorkbench.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package fuzs.visualworkbench;

import fuzs.puzzleslib.config.AbstractConfig;
import fuzs.puzzleslib.config.ConfigHolder;
import fuzs.puzzleslib.config.ConfigHolderImpl;
import fuzs.visualworkbench.config.ClientConfig;
import fuzs.visualworkbench.config.ServerConfig;
import fuzs.visualworkbench.config.JsonConfigBuilder;
import fuzs.visualworkbench.registry.ModRegistry;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLConstructModEvent;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
Expand All @@ -19,11 +21,12 @@ public class VisualWorkbench {
public static final Logger LOGGER = LogManager.getLogger(MOD_NAME);

@SuppressWarnings("Convert2MethodRef")
public static final ConfigHolder<ClientConfig, ServerConfig> CONFIG = ConfigHolder.of(() -> new ClientConfig(), () -> new ServerConfig());
public static final ConfigHolder<ClientConfig, AbstractConfig> CONFIG = ConfigHolder.client(() -> new ClientConfig());

@SubscribeEvent
public static void onConstructMod(final FMLConstructModEvent evt) {
((ConfigHolderImpl<?, ?>) CONFIG).addConfigs(MOD_ID);
JsonConfigBuilder.INSTANCE.load();
ModRegistry.touch();
}
}
165 changes: 165 additions & 0 deletions src/main/java/fuzs/visualworkbench/config/JsonConfigBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package fuzs.visualworkbench.config;

import com.google.common.collect.ImmutableList;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import fuzs.puzzleslib.json.JsonConfigFileUtil;
import fuzs.puzzleslib.json.JsonSerializationUtil;
import fuzs.visualworkbench.VisualWorkbench;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.registries.ForgeRegistries;

import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class JsonConfigBuilder {
public static final JsonConfigBuilder INSTANCE = new JsonConfigBuilder();
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping()
.registerTypeAdapter(ResourceLocation.class, new ResourceLocation.Serializer())
.create();
private static final String JSON_CONFIG_NAME = "visual_workbench.json";
private static final List<ResourceLocation> DEFAULT_VISUAL_WORKBENCHES = Stream.of(
"minecraft:crafting_table",
"blue_skies:bluebright_crafting_table",
"blue_skies:starlit_crafting_table",
"blue_skies:frostbright_crafting_table",
"blue_skies:lunar_crafting_table",
"blue_skies:dusk_crafting_table",
"blue_skies:maple_crafting_table",
"blue_skies:cherry_crafting_table",
"blocksplus:spruce_crafting_table",
"blocksplus:birch_crafting_table",
"blocksplus:jungle_crafting_table",
"blocksplus:acacia_crafting_table",
"blocksplus:dark_oak_crafting_table",
"blocksplus:crimson_crafting_table",
"blocksplus:warped_crafting_table",
"blocksplus:bamboo_crafting_table",
"blocksplus:mushroom_crafting_table",
"mctb:spruce_crafting_table",
"mctb:birch_crafting_table",
"mctb:acacia_crafting_table",
"mctb:jungle_crafting_table",
"mctb:dark_oak_crafting_table",
"mctb:warped_crafting_table",
"mctb:crimson_crafting_table",
"mctb:cherry_crafting_table",
"mctb:dead_crafting_table",
"mctb:fir_crafting_table",
"mctb:hellbark_crafting_table",
"mctb:jacaranda_crafting_table",
"mctb:magic_crafting_table",
"mctb:mahogany_crafting_table",
"mctb:palm_crafting_table",
"mctb:redwood_crafting_table",
"mctb:umbran_crafting_table",
"mctb:willow_crafting_table",
"betternether:crafting_table_anchor_tree",
"betternether:crafting_table_nether_sakura",
"betternether:crafting_table_crimson",
"betternether:crafting_table_warped",
"betternether:crafting_table_stalagnate",
"betternether:crafting_table_reed",
"betternether:crafting_table_willow",
"betternether:crafting_table_wart",
"betternether:crafting_table_rubeus",
"betternether:crafting_table_mushroom",
"betternether:crafting_table_mushroom_fir",
"betterendforge:mossy_glowshroom_crafting_table",
"betterendforge:lacugrove_crafting_table",
"betterendforge:end_lotus_crafting_table",
"betterendforge:pythadendron_crafting_table",
"betterendforge:dragon_tree_crafting_table",
"betterendforge:tenanea_crafting_table",
"betterendforge:helix_tree_crafting_table",
"betterendforge:umbrella_tree_crafting_table",
"betterendforge:jellyshroom_crafting_table",
"betterendforge:lucernia_crafting_table",
"crumbs:spruce_crafting_table",
"crumbs:birch_crafting_table",
"crumbs:jungle_crafting_table",
"crumbs:acacia_crafting_table",
"crumbs:dark_oak_crafting_table",
"crumbs:crimson_crafting_table",
"crumbs:warped_crafting_table",
"byg:aspen_crafting_table",
"byg:baobab_crafting_table",
"byg:blue_enchanted_crafting_table",
"byg:cherry_crafting_table",
"byg:cika_crafting_table",
"byg:cypress_crafting_table",
"byg:ebony_crafting_table",
"byg:fir_crafting_table",
"byg:green_enchanted_crafting_table",
"byg:holly_crafting_table",
"byg:jacaranda_crafting_table",
"byg:mahogany_crafting_table",
"byg:mangrove_crafting_table",
"byg:maple_crafting_table",
"byg:pine_crafting_table",
"byg:rainbow_eucalyptus_crafting_table",
"byg:redwood_crafting_table",
"byg:skyris_crafting_table",
"byg:willow_crafting_table",
"byg:witch_hazel_crafting_table",
"byg:zelkova_crafting_table",
"byg:sythian_crafting_table",
"byg:embur_crafting_table",
"byg:palm_crafting_table",
"byg:lament_crafting_table",
"byg:bulbis_crafting_table",
"byg:nightshade_crafting_table",
"byg:ether_crafting_table",
"byg:imparius_crafting_table"
)
.map(ResourceLocation::new)
.collect(Collectors.collectingAndThen(Collectors.toList(), ImmutableList::copyOf));

private ResourceLocation[] locationValues;
private Set<Block> blockValues;

public void load() {
JsonConfigFileUtil.getAndLoad(JSON_CONFIG_NAME, JsonConfigBuilder::serialize, (FileReader reader) -> this.locationValues = JsonConfigBuilder.deserialize(reader));
}

public boolean contains(Block block) {
if (this.blockValues == null) {
this.blockValues = this.getBlockStream().collect(Collectors.toSet());
}
return this.blockValues.contains(block);
}

private static void serialize(File jsonFile) {
final JsonObject jsonObject = JsonSerializationUtil.getConfigBase(String.format("Crafting table blocks to enable %s support for.", VisualWorkbench.MOD_NAME));
Type token = new TypeToken<List<ResourceLocation>>(){}.getType();
JsonElement jsonElement = GSON.toJsonTree(DEFAULT_VISUAL_WORKBENCHES, token);
jsonObject.add("values", jsonElement);
JsonConfigFileUtil.saveToFile(jsonFile, jsonObject);
}

private static ResourceLocation[] deserialize(FileReader reader) {
final JsonElement values = JsonSerializationUtil.readJsonObject(reader).get("values");
if (values != null) {
return GSON.fromJson(values, ResourceLocation[].class);
}
VisualWorkbench.LOGGER.error("Unable to read {} json config file", VisualWorkbench.MOD_NAME);
return new ResourceLocation[0];
}

public Stream<Block> getBlockStream() {
return Stream.of(this.locationValues)
.filter(Objects::nonNull)
.filter(ForgeRegistries.BLOCKS::containsKey)
.map(ForgeRegistries.BLOCKS::getValue);
}
}
28 changes: 0 additions & 28 deletions src/main/java/fuzs/visualworkbench/config/ServerConfig.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package fuzs.visualworkbench.mixin;

import fuzs.visualworkbench.VisualWorkbench;
import fuzs.visualworkbench.config.JsonConfigBuilder;
import fuzs.visualworkbench.registry.ModRegistry;
import fuzs.visualworkbench.world.level.block.CraftingBlockEntityProvider;
import fuzs.visualworkbench.world.level.block.entity.CraftingTableBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.stats.Stats;
Expand Down Expand Up @@ -31,20 +30,15 @@

@SuppressWarnings("deprecation")
@Mixin(CraftingTableBlock.class)
public abstract class CraftingTableBlockMixin extends Block implements EntityBlock, CraftingBlockEntityProvider {
public abstract class CraftingTableBlockMixin extends Block implements EntityBlock {
public CraftingTableBlockMixin(Properties p_i48440_1_) {
super(p_i48440_1_);
}

@Override
public boolean withCraftingBlockEntity() {
return !VisualWorkbench.CONFIG.server().workbenchBlacklist.contains(this) && !ModRegistry.NON_VISUAL_WORKBENCHES_TAG.contains(this);
}

@Nullable
@Override
public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) {
if (this.withCraftingBlockEntity()) {
if (JsonConfigBuilder.INSTANCE.contains(this)) {
return new CraftingTableBlockEntity(pPos, pState);
}
return null;
Expand All @@ -63,61 +57,51 @@ private static <E extends BlockEntity, A extends BlockEntity> BlockEntityTicker<

@Override
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
if (!this.withCraftingBlockEntity()) {
super.setPlacedBy(world, pos, state, placer, stack);
return;
}
if (stack.hasCustomHoverName()) {
if (world.getBlockEntity(pos) instanceof CraftingTableBlockEntity tileentity) {
tileentity.setCustomName(stack.getHoverName());
if (world.getBlockEntity(pos) instanceof CraftingTableBlockEntity blockEntity) {
if (stack.hasCustomHoverName()) {
blockEntity.setCustomName(stack.getHoverName());
}
} else {
super.setPlacedBy(world, pos, state, placer, stack);
}
}

@Override
public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) {
if (!this.withCraftingBlockEntity()) {
super.onRemove(state, world, pos, newState, isMoving);
return;
}
if (!state.is(newState.getBlock())) {
if (world.getBlockEntity(pos) instanceof CraftingTableBlockEntity tileentity) {
Containers.dropContents(world, pos, tileentity);
if (world.getBlockEntity(pos) instanceof CraftingTableBlockEntity blockEntity) {
Containers.dropContents(world, pos, blockEntity);
}
super.onRemove(state, world, pos, newState, isMoving);
}
super.onRemove(state, world, pos, newState, isMoving);
}

@Override
public boolean triggerEvent(BlockState state, Level world, BlockPos pos, int id, int param) {
if (!this.withCraftingBlockEntity()) {
return super.triggerEvent(state, world, pos, id, param);
final boolean result = super.triggerEvent(state, world, pos, id, param);
if (world.getBlockEntity(pos) instanceof CraftingTableBlockEntity blockEntity) {
return blockEntity.triggerEvent(id, param);
}
super.triggerEvent(state, world, pos, id, param);
return world.getBlockEntity(pos) instanceof CraftingTableBlockEntity tileentity && tileentity.triggerEvent(id, param);
return result;
}

@Inject(method = "use", at = @At("HEAD"), cancellable = true)
public void use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit, CallbackInfoReturnable<InteractionResult> callbackInfo) {
if (this.withCraftingBlockEntity()) {
if (world.getBlockEntity(pos) instanceof CraftingTableBlockEntity blockEntity) {
if (world.isClientSide) {
callbackInfo.setReturnValue(InteractionResult.SUCCESS);
} else {
if (world.getBlockEntity(pos) instanceof CraftingTableBlockEntity tileentity) {
player.openMenu(tileentity);
player.awardStat(Stats.INTERACT_WITH_CRAFTING_TABLE);
}
player.openMenu(blockEntity);
player.awardStat(Stats.INTERACT_WITH_CRAFTING_TABLE);
callbackInfo.setReturnValue(InteractionResult.CONSUME);
}
}
}

@Inject(method = "getMenuProvider", at = @At("HEAD"), cancellable = true)
public void getMenuProvider(BlockState state, Level world, BlockPos pos, CallbackInfoReturnable<MenuProvider> callbackInfo) {
if (this.withCraftingBlockEntity()) {
if (world.getBlockEntity(pos) instanceof CraftingTableBlockEntity tileentity) {
callbackInfo.setReturnValue(tileentity);
}
if (world.getBlockEntity(pos) instanceof CraftingTableBlockEntity blockEntity) {
callbackInfo.setReturnValue(blockEntity);
}
}
}
Loading

0 comments on commit 05da0e6

Please sign in to comment.