diff --git a/build.gradle b/build.gradle index ccee394e..a731a4b4 100644 --- a/build.gradle +++ b/build.gradle @@ -4,6 +4,7 @@ buildscript { maven { url = 'https://maven.minecraftforge.net' } maven { url = 'https://maven.parchmentmc.org' } mavenCentral() + } dependencies { classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true @@ -18,10 +19,11 @@ plugins { apply plugin: 'net.minecraftforge.gradle' apply plugin: 'org.parchmentmc.librarian.forgegradle' +jarJar.enable() -version = '0.5.0-beta-1.18.2' -group = 'de.mrjulsen.trafficcraft' // http://maven.apache.org/guides/mini/guide-naming-conventions.html -archivesBaseName = 'trafficcraft' +version = "${mod_version}-${mod_minecraft_version}" +group = "${mod_root_path}" // http://maven.apache.org/guides/mini/guide-naming-conventions.html +archivesBaseName = "${mod_filename}" // Mojang ships Java 17 to end users in 1.18+, so your mod should target Java 17. java.toolchain.languageVersion = JavaLanguageVersion.of(17) @@ -41,9 +43,9 @@ minecraft { // // Use non-default mappings at your own risk. They may not always work. // Simply re-run your setup task after changing the mappings to update your workspace. - mappings channel: 'parchment', version: '1.18.1-2022.02.13-1.18.2' + mappings channel: 'parchment', version: "${parchment_version}" - // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default. + accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') // Currently, this location cannot be changed from the default. // Default run configurations. // These can be tweaked, removed, or duplicated as needed. @@ -64,13 +66,17 @@ minecraft { property 'forge.logging.console.level', 'debug' // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. - property 'forge.enabledGameTestNamespaces', 'trafficcraft' + property 'forge.enabledGameTestNamespaces', 'trafficcraft' + + property 'mixin.env.remapRefMap', 'true' + property 'mixin.env.refMapRemappingFile', "${buildDir}/createSrgToMcp/output.srg" mods { trafficcraft { source sourceSets.main } } + } server { @@ -144,25 +150,25 @@ repositories { // Put repositories for dependencies here // ForgeGradle automatically adds the Forge maven and Maven Central for you - // If you have mod jar dependencies in ./libs, you can declare them as a repository like so: - // flatDir { - // dir 'libs' - // } + maven { + url "https://cursemaven.com" + } } dependencies { // Specify the version of Minecraft to use. If this is any group other than 'net.minecraft', it is assumed // that the dep is a ForgeGradle 'patcher' dependency, and its patches will be applied. // The userdev artifact is a special name and will get all sorts of transformations applied to it. - minecraft 'net.minecraftforge:forge:1.18.2-40.2.1' - + minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" + jarJar("curse.maven:dragonlib-${dragonlib_curseforge_projectid}:${dragonlib_curseforge_fileid}") { + jarJar.ranged(it, "[${dragonlib_version}-${minecraft_version},)") + } + implementation fg.deobf("curse.maven:dragonlib-${dragonlib_curseforge_projectid}:${dragonlib_curseforge_fileid}") // Real mod deobf dependency examples - these get remapped to your current mappings // compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency // runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}") // Adds the full JEI mod as a runtime dependency // implementation fg.deobf("com.tterrag.registrate:Registrate:MC${mc_version}-${registrate_version}") // Adds registrate as a dependency - // Examples using mod jars from ./libs - // implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}") // For more info... // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html @@ -173,20 +179,31 @@ dependencies { jar { manifest { attributes([ - "Specification-Title" : "trafficcraft", - "Specification-Vendor" : "trafficcraftsareus", - "Specification-Version" : "1", // We are version 1 of ourselves + "Specification-Title" : "TrafficCraft", + "Specification-Vendor" : "MrJulsen", + "Specification-Version" : "${mod_version}-${mod_minecraft_version}", // We are version 1 of ourselves "Implementation-Title" : project.name, "Implementation-Version" : project.jar.archiveVersion, - "Implementation-Vendor" : "trafficcraftsareus", + "Implementation-Vendor" : "MrJulsen", "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") ]) } } +task jarJarRelease { + group = 'jarjar' + doLast { + tasks.jarJar { + classifier = '' + } + } + finalizedBy tasks.jarJar +} + // Example configuration to allow publishing using the maven-publish plugin // This is the preferred method to reobfuscate your jar file jar.finalizedBy('reobfJar') +tasks.jarJar.finalizedBy('reobfJarJar') // However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing // publish.dependsOn('reobfJar') diff --git a/gradle.properties b/gradle.properties index 5f949f5f..8d87d534 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,20 @@ # Sets default memory used for gradle commands. Can be overridden by user or command line properties. # This is required to provide enough memory for the Minecraft decompilation process. org.gradle.jvmargs=-Xmx6G -org.gradle.daemon=false \ No newline at end of file +org.gradle.daemon=false + +mod_version = 0.6.0-beta +mod_minecraft_version = 1.18.2 +mod_filename = trafficcraft +mod_root_path = de.mrjulsen.trafficcraft + +minecraft_version = 1.18.2 +forge_version = 40.2.1 + +parchment_version = 1.18.1-2022.02.13-1.18.2 + + +# dependency versions +dragonlib_curseforge_projectid = 946163 +dragonlib_curseforge_fileid = 4990073 +dragonlib_version = 0.1.12 \ No newline at end of file diff --git a/src/main/java/de/mrjulsen/trafficcraft/Constants.java b/src/main/java/de/mrjulsen/trafficcraft/Constants.java index dd740068..cb11d1d8 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/Constants.java +++ b/src/main/java/de/mrjulsen/trafficcraft/Constants.java @@ -2,21 +2,29 @@ import java.util.Random; +import de.mrjulsen.mcdragonlib.utils.Utils; import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.server.MinecraftServer; public class Constants { - public static final byte TPS = 1000 / MinecraftServer.MS_PER_TICK; public static final int MAX_ASPHALT_PATTERNS = 323; public static final int MAX_PAINT = 128; - public static final int TICKS_PER_DAY = 24000; public static final int METAL_COLOR = 0xFF828282; public static final int TRAFFIC_CONE_BASE_COLOR = 0xFFD12725; - public static final MutableComponent CREATIVE_MODE_ONLY_TOOLTIP = new TranslatableComponent("core.trafficcraft.creative_only.tooltip").withStyle(ChatFormatting.GOLD); + public static final MutableComponent CREATIVE_MODE_ONLY_TOOLTIP = Utils.translate("core.trafficcraft.creative_only.tooltip").withStyle(ChatFormatting.GOLD); + + public static final Component textCopy = Utils.translate("core.trafficcraft.common.copy"); + public static final Component textPaste = Utils.translate("core.trafficcraft.common.paste"); + + public static final String GERMAN_LOCAL_CODE = "de"; + + public static final String WIKIPEDIA_TRAFFIC_LIGHT_ID = "Q8004"; + public static final String WIKIPEDIA_GERMAN_TRAM_SIGNAL_ID = "Q2354774"; public static final Random RANDOM = new Random(); } + + diff --git a/src/main/java/de/mrjulsen/trafficcraft/ModMain.java b/src/main/java/de/mrjulsen/trafficcraft/ModMain.java index 2e80a8a3..e0bee89e 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/ModMain.java +++ b/src/main/java/de/mrjulsen/trafficcraft/ModMain.java @@ -4,20 +4,17 @@ import de.mrjulsen.trafficcraft.client.screen.menu.ModMenuTypes; import de.mrjulsen.trafficcraft.config.ModCommonConfig; +import de.mrjulsen.trafficcraft.init.ClientInitWrapper; +import de.mrjulsen.trafficcraft.init.ServerInit; import de.mrjulsen.trafficcraft.network.NetworkManager; -import de.mrjulsen.trafficcraft.proxy.ClientProxy; -import de.mrjulsen.trafficcraft.proxy.IProxy; -import de.mrjulsen.trafficcraft.proxy.ServerProxy; import de.mrjulsen.trafficcraft.registry.ModBlockEntities; import de.mrjulsen.trafficcraft.registry.ModBlocks; import de.mrjulsen.trafficcraft.registry.ModItems; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.config.ModConfig; -import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import org.slf4j.Logger; @@ -26,7 +23,6 @@ @Mod(ModMain.MOD_ID) public class ModMain { public static final String MOD_ID = "trafficcraft"; - public final IProxy PROXY = DistExecutor.safeRunForDist(() -> ClientProxy::new, () -> ServerProxy::new); // Directly reference a slf4j logger public static final Logger LOGGER = LogUtils.getLogger(); @@ -34,22 +30,15 @@ public class ModMain { public ModMain() { IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus(); - eventBus.addListener(this::setup); + eventBus.addListener(ServerInit::setup); + eventBus.addListener(ClientInitWrapper::setup); ModBlocks.register(eventBus); ModItems.register(eventBus); ModBlockEntities.register(eventBus); ModMenuTypes.register(eventBus); - //ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, ModClientConfig.SPEC, MOD_ID + "-client.toml"); ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, ModCommonConfig.SPEC, MOD_ID + "-common.toml"); - NetworkManager.registerNetworkPackets(); + NetworkManager.create(); MinecraftForge.EVENT_BUS.register(this); } - - private void setup(final FMLCommonSetupEvent event) { - // some preinit code - LOGGER.info("Welcome to the TrafficCraft mod."); - - PROXY.setup(event); - } } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/ConcreteBarrierBlock.java b/src/main/java/de/mrjulsen/trafficcraft/block/ConcreteBarrierBlock.java index 446faac5..13582a42 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/ConcreteBarrierBlock.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/ConcreteBarrierBlock.java @@ -98,7 +98,6 @@ public ConcreteBarrierBlock() { @Override public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) { - //return pState.getValue(FACING) == Direction.NORTH || pState.getValue(FACING) == Direction.SOUTH ? SHAPE_SN : SHAPE_EW; if ((pState.getValue(FACING) == Direction.NORTH || pState.getValue(FACING) == Direction.SOUTH) && !pState.getValue(NORTH) && !pState.getValue(SOUTH)) { return Shapes.or(SHAPE_SIDE_EAST, SHAPE_SIDE_WEST); } else if ((pState.getValue(FACING) == Direction.EAST || pState.getValue(FACING) == Direction.WEST) && !pState.getValue(EAST) && !pState.getValue(WEST)) { diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/DelineatorBlock.java b/src/main/java/de/mrjulsen/trafficcraft/block/DelineatorBlock.java index a3a2a385..c8c9c81f 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/DelineatorBlock.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/DelineatorBlock.java @@ -28,12 +28,19 @@ public class DelineatorBlock extends WaterloggableBlock { public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING; public static final VoxelShape SHAPE_COMMON = Block.box(6, 0, 6, 10, 16, 10); + public static final VoxelShape SHAPE_SMALL = Block.box(6, 0, 6, 10, 11, 10); - public DelineatorBlock() { + public static final VoxelShape OCCLUSION_COMMON = Block.box(5, 0, 5, 9, 16, 9); + public static final VoxelShape OCCLUSION_SMALL = Block.box(5, 0, 5, 9, 11, 9); + + private final boolean small; + + public DelineatorBlock(boolean small) { super(BlockBehaviour.Properties.of(Material.BAMBOO) .sound(SoundType.BAMBOO) .instabreak() ); + this.small = small; this.registerDefaultState(this.stateDefinition.any() .setValue(FACING, Direction.NORTH) ); @@ -42,12 +49,12 @@ public DelineatorBlock() { @Override public VoxelShape getOcclusionShape(BlockState pState, BlockGetter pLevel, BlockPos pPos) { - return SHAPE_COMMON; + return isSmall() ? OCCLUSION_SMALL : OCCLUSION_COMMON; } @Override - public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) { - return SHAPE_COMMON; + public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) { + return isSmall() ? SHAPE_SMALL : SHAPE_COMMON; } @Override @@ -86,5 +93,9 @@ public BlockState updateShape(BlockState pState, Direction pFacing, BlockState p public boolean canSurvive(BlockState pState, LevelReader pLevel, BlockPos pPos) { return canSupportCenter(pLevel, pPos.below(), Direction.UP); } + + public boolean isSmall() { + return small; + } } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/DragonBlock.java b/src/main/java/de/mrjulsen/trafficcraft/block/DragonBlock.java deleted file mode 100644 index 28cbca2c..00000000 --- a/src/main/java/de/mrjulsen/trafficcraft/block/DragonBlock.java +++ /dev/null @@ -1,38 +0,0 @@ -package de.mrjulsen.trafficcraft.block; - -import java.util.List; - -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.TextComponent; -import net.minecraft.network.chat.TranslatableComponent; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Rarity; -import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; - -public class DragonBlock extends Block { - - public DragonBlock(Properties properties) { - super(properties); - } - - public static class DragonItem extends BlockItem { - - public DragonItem(Block pBlock, Properties pProperties) { - super(pBlock, pProperties.rarity(Rarity.EPIC)); - } - - @Override - public void appendHoverText(ItemStack stack, Level player, List list, TooltipFlag flag) { - super.appendHoverText(stack, player, list, flag); - list.add(new TranslatableComponent("core.trafficcraft.credits.line0")); - list.add(new TextComponent("")); - list.add(new TranslatableComponent("core.trafficcraft.credits.line1")); - list.add(new TranslatableComponent("core.trafficcraft.credits.line2")); - } - - } - -} diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/PaintBucketBlock.java b/src/main/java/de/mrjulsen/trafficcraft/block/PaintBucketBlock.java index 07ef6ac3..b413f955 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/PaintBucketBlock.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/PaintBucketBlock.java @@ -1,13 +1,14 @@ package de.mrjulsen.trafficcraft.block; +import de.mrjulsen.mcdragonlib.utils.Utils; import de.mrjulsen.trafficcraft.block.data.ColorableBlock; import de.mrjulsen.trafficcraft.block.data.IColorBlockEntity; import de.mrjulsen.trafficcraft.block.entity.ColoredBlockEntity; import de.mrjulsen.trafficcraft.data.PaintColor; import de.mrjulsen.trafficcraft.item.BrushItem; +import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; @@ -108,7 +109,7 @@ public BlockState getStateForPlacement(BlockPlaceContext pContext) { public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult result) { if (state.getValue(WATERLOGGED)) { - player.displayClientMessage(new TranslatableComponent("block.trafficcraft.paint_bucket.message.underwater"), true); + player.displayClientMessage(Utils.translate("block.trafficcraft.paint_bucket.message.underwater").withStyle(ChatFormatting.RED), true); return InteractionResult.FAIL; } @@ -126,7 +127,7 @@ public InteractionResult use(BlockState state, Level level, BlockPos pos, Player // Check if bucket is empty if (paint <= 0) { if(!level.isClientSide) - player.displayClientMessage(new TranslatableComponent("block.trafficcraft.paint_bucket.message.empty"), true); + player.displayClientMessage(Utils.translate("block.trafficcraft.paint_bucket.message.empty").withStyle(ChatFormatting.RED), true); return InteractionResult.FAIL; } @@ -152,13 +153,13 @@ public InteractionResult use(BlockState state, Level level, BlockPos pos, Player if (state.getValue(PAINT) > 0) { if (!blockEntity.getColor().equals(dye.getDyeColor())) { - player.displayClientMessage(new TranslatableComponent("block.trafficcraft.paint_bucket.message.wrong_color"), true); + player.displayClientMessage(Utils.translate("block.trafficcraft.paint_bucket.message.wrong_color").withStyle(ChatFormatting.RED), true); return InteractionResult.FAIL; } } if (state.getValue(PAINT) >= MAX_PAINT) { - player.displayClientMessage(new TranslatableComponent("block.trafficcraft.paint_bucket.message.full"), true); + player.displayClientMessage(Utils.translate("block.trafficcraft.paint_bucket.message.full").withStyle(ChatFormatting.YELLOW), true); return InteractionResult.FAIL; } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/StreetLampBaseBlock.java b/src/main/java/de/mrjulsen/trafficcraft/block/StreetLampBaseBlock.java index 02d5439c..c02fdacd 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/StreetLampBaseBlock.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/StreetLampBaseBlock.java @@ -2,12 +2,12 @@ import javax.annotation.Nullable; +import de.mrjulsen.mcdragonlib.utils.Utils; import de.mrjulsen.trafficcraft.block.data.ITrafficPostLike; import de.mrjulsen.trafficcraft.block.entity.StreetLampBlockEntity; import de.mrjulsen.trafficcraft.item.WrenchItem; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.network.chat.TranslatableComponent; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; @@ -136,7 +136,7 @@ public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Pla if (!pLevel.isClientSide) { if (pLevel.getBlockEntity(pPos) instanceof StreetLampBlockEntity blockEntity && blockEntity.getOnTime() != blockEntity.getOffTime()) { if (!pLevel.isClientSide) { - pPlayer.displayClientMessage(new TranslatableComponent("block.trafficcraft.street_lamp.use.error_scheduled"), true); + pPlayer.displayClientMessage(Utils.translate("block.trafficcraft.street_lamp.use.error_scheduled"), true); return InteractionResult.FAIL; } } else { diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/TrafficLightBlock.java b/src/main/java/de/mrjulsen/trafficcraft/block/TrafficLightBlock.java index c42a80a4..ac244224 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/TrafficLightBlock.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/TrafficLightBlock.java @@ -1,13 +1,15 @@ package de.mrjulsen.trafficcraft.block; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + import javax.annotation.Nullable; import de.mrjulsen.trafficcraft.block.data.ColorableBlock; import de.mrjulsen.trafficcraft.block.data.ITrafficPostLike; -import de.mrjulsen.trafficcraft.block.data.TrafficLightDirection; -import de.mrjulsen.trafficcraft.block.data.TrafficLightMode; +import de.mrjulsen.trafficcraft.block.data.TrafficLightModel; import de.mrjulsen.trafficcraft.block.data.TrafficLightTrigger; -import de.mrjulsen.trafficcraft.block.data.TrafficLightVariant; import de.mrjulsen.trafficcraft.block.entity.TrafficLightBlockEntity; import de.mrjulsen.trafficcraft.client.ClientWrapper; import de.mrjulsen.trafficcraft.item.BrushItem; @@ -55,43 +57,37 @@ public class TrafficLightBlock extends ColorableBlock implements SimpleWaterlogg public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING; - public static final EnumProperty VARIANT = EnumProperty.create("variant", TrafficLightVariant.class); - public static final EnumProperty DIRECTION = EnumProperty.create("direction", TrafficLightDirection.class); - public static final EnumProperty MODE = EnumProperty.create("mode", TrafficLightMode.class); + public static final EnumProperty MODEL = EnumProperty.create("model", TrafficLightModel.class); - public static final VoxelShape SHAPE_COMMON = Block.box(7, 0, 7, 9, 16, 9); + @Deprecated public static final EnumProperty VARIANT = EnumProperty.create("variant", de.mrjulsen.trafficcraft.block.data.compat.TrafficLightVariant.class); + @Deprecated public static final EnumProperty DIRECTION = EnumProperty.create("direction", de.mrjulsen.trafficcraft.block.data.compat.TrafficLightDirection.class); + @Deprecated public static final EnumProperty MODE = EnumProperty.create("mode", de.mrjulsen.trafficcraft.block.data.compat.TrafficLightMode.class); - public static final VoxelShape SHAPE_PART_NORTH = Block.box(4, 4.5d, 1, 12, 16, 6); - public static final VoxelShape SHAPE_PART_SOUTH = Block.box(4, 4.5d, 10, 12, 16, 15); - public static final VoxelShape SHAPE_PART_EAST = Block.box(10, 4.5d, 4, 15, 16, 12); - public static final VoxelShape SHAPE_PART_WEST = Block.box(1, 4.5d, 4, 6, 16, 12); - - public static final VoxelShape SHAPE_EXTRA_PART_NORTH = Block.box(4, -0.5d, 1, 12, 5, 6); - public static final VoxelShape SHAPE_EXTRA_PART_SOUTH = Block.box(4, -0.5d, 10, 12, 5, 15); - public static final VoxelShape SHAPE_EXTRA_PART_EAST = Block.box(10, -0.5d, 4, 15, 5, 12); - public static final VoxelShape SHAPE_EXTRA_PART_WEST = Block.box(1, -0.5d, 4, 6, 5, 12); + public static final VoxelShape SHAPE_COMMON = Block.box(7, 0, 7, 9, 16, 9); - public static final VoxelShape SHAPE_NORTH = Shapes.or(SHAPE_COMMON, SHAPE_PART_NORTH); - public static final VoxelShape SHAPE_SOUTH = Shapes.or(SHAPE_COMMON, SHAPE_PART_SOUTH); - public static final VoxelShape SHAPE_EAST = Shapes.or(SHAPE_COMMON, SHAPE_PART_EAST); - public static final VoxelShape SHAPE_WEST = Shapes.or(SHAPE_COMMON, SHAPE_PART_WEST); + private static final Map> shapes = new HashMap<>(); + static { + Arrays.stream(TrafficLightModel.values()).forEach(x -> { + Map voxelShapes = new HashMap<>(); + voxelShapes.put(Direction.NORTH, Block.box(4, x.getHitboxBottom(), 1, 12, x.getHitboxTop(), 6)); + voxelShapes.put(Direction.SOUTH, Block.box(4, x.getHitboxBottom(), 10, 12, x.getHitboxTop(), 15)); + voxelShapes.put(Direction.EAST, Block.box(10, x.getHitboxBottom(), 4, 15, x.getHitboxTop(), 12)); + voxelShapes.put(Direction.WEST, Block.box(1, x.getHitboxBottom(), 4, 6, x.getHitboxTop(), 12)); + shapes.put(x, voxelShapes); + }); + } public TrafficLightBlock() { super(BlockBehaviour.Properties.of(Material.METAL) .strength(5f) .requiresCorrectToolForDrops() .sound(SoundType.ANVIL) - .lightLevel((state) -> { - return state.getValue(MODE) == TrafficLightMode.OFF ? 0 : 1; - }) ); this.registerDefaultState(this.stateDefinition.any() - .setValue(FACING, Direction.NORTH) - .setValue(VARIANT, TrafficLightVariant.NORMAL) - .setValue(DIRECTION, TrafficLightDirection.NORMAL) - .setValue(MODE, TrafficLightMode.OFF) + .setValue(FACING, Direction.NORTH) + .setValue(MODEL, TrafficLightModel.THREE_LIGHTS) ); - this.registerDefaultState(this.stateDefinition.any().setValue(WATERLOGGED, Boolean.valueOf(false)).setValue(FACING, Direction.NORTH).setValue(VARIANT, TrafficLightVariant.NORMAL).setValue(DIRECTION, TrafficLightDirection.NORMAL).setValue(MODE, TrafficLightMode.OFF)); + this.registerDefaultState(this.stateDefinition.any().setValue(WATERLOGGED, Boolean.valueOf(false)).setValue(FACING, Direction.NORTH).setValue(MODEL, TrafficLightModel.THREE_LIGHTS)); } @Override @@ -101,19 +97,7 @@ public VoxelShape getOcclusionShape(BlockState pState, BlockGetter pLevel, Block @Override public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) { - TrafficLightVariant variant = pState.getValue(VARIANT); - switch((Direction)pState.getValue(FACING)) { - case NORTH: - return variant == TrafficLightVariant.NORMAL ? Shapes.or(SHAPE_NORTH, SHAPE_EXTRA_PART_NORTH) : SHAPE_NORTH; - case SOUTH: - return variant == TrafficLightVariant.NORMAL ? Shapes.or(SHAPE_SOUTH, SHAPE_EXTRA_PART_SOUTH) : SHAPE_SOUTH; - case EAST: - return variant == TrafficLightVariant.NORMAL ? Shapes.or(SHAPE_EAST, SHAPE_EXTRA_PART_EAST) : SHAPE_EAST; - case WEST: - return variant == TrafficLightVariant.NORMAL ? Shapes.or(SHAPE_WEST, SHAPE_EXTRA_PART_WEST) : SHAPE_WEST; - default: - return SHAPE_COMMON; - } + return Shapes.or(SHAPE_COMMON, shapes.get(pState.getValue(MODEL)).get((Direction)pState.getValue(FACING))); } @Override @@ -154,7 +138,7 @@ public BlockState getStateForPlacement(BlockPlaceContext pContext) { @Override protected void createBlockStateDefinition(Builder pBuilder) { super.createBlockStateDefinition(pBuilder); - pBuilder.add(WATERLOGGED, FACING, VARIANT, DIRECTION, MODE); + pBuilder.add(WATERLOGGED, FACING, MODEL); } public boolean isPathfindable(BlockState pState, BlockGetter pLevel, BlockPos pPos, PathComputationType pType) { @@ -174,7 +158,7 @@ public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Pla if (pLevel.isClientSide && item instanceof WrenchItem) { if (!pPlayer.isShiftKeyDown()) - ClientWrapper.showTrafficLightConfigScreen(pPos, pLevel); + ClientWrapper.showTrafficLightConfigScreen(pLevel, pPos); return InteractionResult.SUCCESS; } @@ -191,7 +175,9 @@ public void neighborChanged(BlockState pState, Level pLevel, BlockPos pPos, Bloc } } else { blockEntity.setPowered(false); - blockEntity.stopSchedule(); + if (blockEntity.getSchedule().getTrigger() == TrafficLightTrigger.REDSTONE) { + blockEntity.stopSchedule(); + } } } } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/TrafficLightControllerBlock.java b/src/main/java/de/mrjulsen/trafficcraft/block/TrafficLightControllerBlock.java index 06a1dc27..b138e774 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/TrafficLightControllerBlock.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/TrafficLightControllerBlock.java @@ -123,7 +123,9 @@ public void neighborChanged(BlockState pState, Level pLevel, BlockPos pPos, Bloc } } else { blockEntity.setPowered(false); - blockEntity.stopSchedule(); + if (blockEntity.getFirstOrMainSchedule().getTrigger() == TrafficLightTrigger.REDSTONE) { + blockEntity.stopSchedule(); + } } } } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/TrafficLightRequestButtonBlock.java b/src/main/java/de/mrjulsen/trafficcraft/block/TrafficLightRequestButtonBlock.java index 628876f7..9334b3f8 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/TrafficLightRequestButtonBlock.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/TrafficLightRequestButtonBlock.java @@ -125,8 +125,11 @@ public void press(BlockState pState, Level pLevel, BlockPos pPos) { public void tick(BlockState pState, ServerLevel pLevel, BlockPos pPos, Random pRand) { if (pState.getValue(POWERED)) { if (pLevel.getBlockEntity(pPos) instanceof TrafficLightRequestButtonBlockEntity blockEntity && blockEntity.isValidLinked()) { - pLevel.setBlockAndUpdate(pPos, pState.setValue(POWERED, false).setValue(ACTIVATED, true)); - blockEntity.activate(); + if (blockEntity.activate()) { + pLevel.setBlockAndUpdate(pPos, pState.setValue(POWERED, false).setValue(ACTIVATED, true)); + } else { + pLevel.setBlockAndUpdate(pPos, pState.setValue(POWERED, false).setValue(ACTIVATED, false)); + } } else { pLevel.setBlockAndUpdate(pPos, pState.setValue(POWERED, false).setValue(ACTIVATED, false)); } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/TrafficSignBlock.java b/src/main/java/de/mrjulsen/trafficcraft/block/TrafficSignBlock.java index 6d944c5c..37775cb7 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/TrafficSignBlock.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/TrafficSignBlock.java @@ -1,8 +1,8 @@ package de.mrjulsen.trafficcraft.block; +import de.mrjulsen.mcdragonlib.common.IIdentifiable; import de.mrjulsen.trafficcraft.block.data.ITrafficPostLike; import de.mrjulsen.trafficcraft.block.data.TrafficSignShape; -import de.mrjulsen.trafficcraft.block.entity.IIdentifiable; import de.mrjulsen.trafficcraft.block.entity.TrafficSignBlockEntity; import de.mrjulsen.trafficcraft.client.ClientWrapper; import de.mrjulsen.trafficcraft.item.CreativePatternCatalogueItem; diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/TrafficSignWorkbenchBlock.java b/src/main/java/de/mrjulsen/trafficcraft/block/TrafficSignWorkbenchBlock.java index 7a7de32a..f5975903 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/TrafficSignWorkbenchBlock.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/TrafficSignWorkbenchBlock.java @@ -1,9 +1,9 @@ package de.mrjulsen.trafficcraft.block; +import de.mrjulsen.mcdragonlib.utils.Utils; import de.mrjulsen.trafficcraft.client.screen.menu.TrafficSignWorkbenchMenu; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.network.chat.TextComponent; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.MenuProvider; @@ -90,6 +90,6 @@ public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Pla public MenuProvider getMenuProvider(BlockState pState, Level pLevel, BlockPos pPos) { return new SimpleMenuProvider((containerId, inv, player) -> { return new TrafficSignWorkbenchMenu(containerId, inv, ContainerLevelAccess.create(pLevel, pPos)); - }, new TextComponent("")); + }, Utils.text("")); } } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/data/IIconEnum.java b/src/main/java/de/mrjulsen/trafficcraft/block/data/IIconEnum.java new file mode 100644 index 00000000..2fc17a75 --- /dev/null +++ b/src/main/java/de/mrjulsen/trafficcraft/block/data/IIconEnum.java @@ -0,0 +1,19 @@ +package de.mrjulsen.trafficcraft.block.data; + +import de.mrjulsen.mcdragonlib.client.gui.Sprite; +import de.mrjulsen.trafficcraft.ModMain; +import net.minecraft.resources.ResourceLocation; + +public interface IIconEnum { + + public static final ResourceLocation ICON_TEXTURE_LOCATION = new ResourceLocation(ModMain.MOD_ID, "textures/gui/icons.png"); + public static final int TEXTURE_SIZE = 128; + public static final int DEFAULT_SPRITE_SIZE = 16; + + int getUMultiplier(); + int getVMultiplier(); + + default Sprite getSprite() { + return new Sprite(ICON_TEXTURE_LOCATION, TEXTURE_SIZE, TEXTURE_SIZE, DEFAULT_SPRITE_SIZE * getUMultiplier(), DEFAULT_SPRITE_SIZE * getVMultiplier(), DEFAULT_SPRITE_SIZE, DEFAULT_SPRITE_SIZE); + } +} diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/data/IItemIcon.java b/src/main/java/de/mrjulsen/trafficcraft/block/data/IItemIcon.java new file mode 100644 index 00000000..623fb45a --- /dev/null +++ b/src/main/java/de/mrjulsen/trafficcraft/block/data/IItemIcon.java @@ -0,0 +1,11 @@ +package de.mrjulsen.trafficcraft.block.data; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ItemLike; + +public interface IItemIcon { + ItemLike getItemIcon(); + default ItemStack getIconStack() { + return new ItemStack(getItemIcon()); + } +} diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/data/TownSignVariant.java b/src/main/java/de/mrjulsen/trafficcraft/block/data/TownSignVariant.java index b28ef230..7b431462 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/data/TownSignVariant.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/data/TownSignVariant.java @@ -1,8 +1,9 @@ package de.mrjulsen.trafficcraft.block.data; +import de.mrjulsen.mcdragonlib.common.ITranslatableEnum; import net.minecraft.util.StringRepresentable; -public enum TownSignVariant implements StringRepresentable { +public enum TownSignVariant implements StringRepresentable, ITranslatableEnum { FRONT("front", 0), BACK("back", 1), BOTH("both", 2); @@ -23,10 +24,6 @@ public int getIndex() { return this.index; } - public String getTranslationKey() { - return String.format("gui.trafficcraft.town_sign.variant.%s", variant); - } - public static TownSignVariant getVariantByIndex(int index) { for (TownSignVariant shape : TownSignVariant.values()) { if (shape.getIndex() == index) { @@ -40,4 +37,14 @@ public static TownSignVariant getVariantByIndex(int index) { public String getSerializedName() { return variant; } + + @Override + public String getEnumName() { + return "townsignvariant"; + } + + @Override + public String getEnumValueName() { + return getVariant(); + } } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightColor.java b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightColor.java new file mode 100644 index 00000000..c93fe36c --- /dev/null +++ b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightColor.java @@ -0,0 +1,86 @@ +package de.mrjulsen.trafficcraft.block.data; + +import java.util.Arrays; + +import de.mrjulsen.mcdragonlib.common.ITranslatableEnum; +import net.minecraft.util.StringRepresentable; + +public enum TrafficLightColor implements StringRepresentable, ITranslatableEnum { + NONE("none", 0, TrafficLightType.values(), 0), + RED("red", 1, new TrafficLightType[] { TrafficLightType.CAR }, 1), + YELLOW("yellow", 2, new TrafficLightType[] { TrafficLightType.CAR }, 2), + GREEN("green", 3, new TrafficLightType[] { TrafficLightType.CAR }, 3), + F0("f0", 4, new TrafficLightType[] { TrafficLightType.TRAM }, 1), + F4("f4", 5, new TrafficLightType[] { TrafficLightType.TRAM }, 2), + F1_F2_F3_F5("f1_f2_f3_f5", 6, new TrafficLightType[] { TrafficLightType.TRAM }, 3); + + private String name; + private byte index; + private TrafficLightType[] allowedInTypes; + private byte groupIndex; + + private TrafficLightColor(String name, int index, TrafficLightType[] allowedInTypes, int groupIndex) { + this.name = name; + this.index = (byte)index; + this.allowedInTypes = allowedInTypes; + this.groupIndex = (byte)groupIndex; + } + + public String getName() { + return this.name; + } + + public byte getIndex() { + return this.index; + } + + public static TrafficLightColor[] getAllowedForType(TrafficLightType type, boolean offStatusAllowed) { + return Arrays.stream(TrafficLightColor.values()).filter(x -> Arrays.stream(x.allowedInTypes).anyMatch(y -> y == type) && (offStatusAllowed || x != NONE)).toArray(TrafficLightColor[]::new); + } + + public boolean isAllowedFor(TrafficLightType type) { + return Arrays.stream(allowedInTypes).anyMatch(x -> x == type); + } + + public byte getGroupIndex() { + return groupIndex; + } + + /** + * Returns an array of {@code TrafficLightColor}s which have a similar meaning. For example: Red and H0 (both mean "stop") + */ + public TrafficLightColor[] getSimilar() { + return Arrays.stream(TrafficLightColor.values()).filter(x -> x.getGroupIndex() == this.getGroupIndex()).toArray(TrafficLightColor[]::new); + } + + public boolean isSimilar(TrafficLightColor other) { + return getGroupIndex() == other.getGroupIndex(); + } + + public String getTranslationKey() { + return String.format("gui.trafficcraft.trafficlightcolor.%s", name); + } + + public static TrafficLightColor getColorByIndex(byte index) { + return Arrays.stream(TrafficLightColor.values()).filter(x -> x.getIndex() == index).findFirst().orElse(TrafficLightColor.NONE); + } + + public static TrafficLightColor getColorByGroupIndex(byte index, TrafficLightType type) { + return Arrays.stream(TrafficLightColor.values()).filter(x -> x.getGroupIndex() == index && x.isAllowedFor(type)).findFirst().orElse(TrafficLightColor.NONE); + } + + @Override + public String getSerializedName() { + return name; + } + + @Override + public String getEnumName() { + return "trafficlightcolor"; + } + + @Override + public String getEnumValueName() { + return getName(); + } +} diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightControlType.java b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightControlType.java index 22d2105d..b2271f91 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightControlType.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightControlType.java @@ -1,43 +1,67 @@ package de.mrjulsen.trafficcraft.block.data; +import java.util.Arrays; + +import de.mrjulsen.mcdragonlib.common.IIterableEnum; +import de.mrjulsen.mcdragonlib.common.ITranslatableEnum; +import de.mrjulsen.trafficcraft.registry.ModBlocks; +import de.mrjulsen.trafficcraft.registry.ModItems; import net.minecraft.util.StringRepresentable; +import net.minecraft.world.level.ItemLike; -public enum TrafficLightControlType implements StringRepresentable { - STATIC("static", 0), - OWN_SCHEDULE("own_schedule", 1), - REMOTE("remote", 2); +public enum TrafficLightControlType implements StringRepresentable, ITranslatableEnum, IItemIcon, IIterableEnum { + STATIC("static", 0, ModBlocks.TRAFFIC_LIGHT.get()), + OWN_SCHEDULE("own_schedule", 1, ModItems.PATTERN_CATALOGUE.get()), + REMOTE("remote", 2, ModBlocks.TRAFFIC_LIGHT_CONTROLLER.get()); private String controlType; - private int index; + private byte index; + private ItemLike icon; - private TrafficLightControlType(String controlType, int index) { + private TrafficLightControlType(String controlType, int index, ItemLike icon) { this.controlType = controlType; - this.index = index; + this.index = (byte)index; + this.icon = icon; } public String getControlType() { return this.controlType; } - public int getIndex() { + public byte getIndex() { return this.index; } - public String getTranslationKey() { - return String.format("gui.trafficcraft.trafficlight.controltype.%s", controlType); + @Override + public ItemLike getItemIcon() { + return icon; + } + + public String getValueShortTranslationKey() { + return String.format("enum.trafficcraft.trafficlightcontroltype.short.%s", controlType); } - public static TrafficLightControlType getControlTypeByIndex(int index) { - for (TrafficLightControlType controlType : TrafficLightControlType.values()) { - if (controlType.getIndex() == index) { - return controlType; - } - } - return TrafficLightControlType.STATIC; + public static TrafficLightControlType getControlTypeByIndex(byte index) { + return Arrays.stream(TrafficLightControlType.values()).filter(x -> x.getIndex() == index).findFirst().orElse(TrafficLightControlType.STATIC); } @Override public String getSerializedName() { return controlType; } + + @Override + public String getEnumName() { + return "trafficlightcontroltype"; + } + + @Override + public String getEnumValueName() { + return getControlType(); + } + + @Override + public TrafficLightControlType[] getValues() { + return values(); + } } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightIcon.java b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightIcon.java new file mode 100644 index 00000000..b71ea174 --- /dev/null +++ b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightIcon.java @@ -0,0 +1,95 @@ +package de.mrjulsen.trafficcraft.block.data; + +import java.util.Arrays; + +import de.mrjulsen.mcdragonlib.client.gui.Sprite; +import de.mrjulsen.mcdragonlib.common.ITranslatableEnum; +import net.minecraft.util.StringRepresentable; + +public enum TrafficLightIcon implements StringRepresentable, ITranslatableEnum, IIconEnum { + NONE("none", 0, 0, 1, TrafficLightType.values(), TrafficLightColor.values()), + RIGHT("right", 1, 1, 1, new TrafficLightType[] { TrafficLightType.CAR, TrafficLightType.TRAM }, new TrafficLightColor[] { TrafficLightColor.RED, TrafficLightColor.YELLOW, TrafficLightColor.GREEN, TrafficLightColor.F1_F2_F3_F5 }), + LEFT("left", 2, 2, 1, new TrafficLightType[] { TrafficLightType.CAR, TrafficLightType.TRAM }, new TrafficLightColor[] { TrafficLightColor.RED, TrafficLightColor.YELLOW, TrafficLightColor.GREEN, TrafficLightColor.F1_F2_F3_F5 }), + STRAIGHT("straight", 3, 3, 1, new TrafficLightType[] { TrafficLightType.CAR, TrafficLightType.TRAM }, new TrafficLightColor[] { TrafficLightColor.RED, TrafficLightColor.YELLOW, TrafficLightColor.GREEN, TrafficLightColor.F1_F2_F3_F5 }), + STRAIGHT_RIGHT("straight_right", 4, 4, 1, new TrafficLightType[] { TrafficLightType.CAR }, new TrafficLightColor[] { TrafficLightColor.RED, TrafficLightColor.YELLOW, TrafficLightColor.GREEN }), + STRAIGHT_LEFT("straight_left", 5, 5, 1, new TrafficLightType[] { TrafficLightType.CAR }, new TrafficLightColor[] { TrafficLightColor.RED, TrafficLightColor.YELLOW, TrafficLightColor.GREEN }), + PEDESTRIAN("pedestrian", 6, 6, 1, new TrafficLightType[] { TrafficLightType.CAR }, new TrafficLightColor[] { TrafficLightColor.RED, TrafficLightColor.YELLOW, TrafficLightColor.GREEN }), + BIKE("bike", 7, 7, 1, new TrafficLightType[] { TrafficLightType.CAR }, new TrafficLightColor[] { TrafficLightColor.RED, TrafficLightColor.YELLOW, TrafficLightColor.GREEN }); + + private String name; + private byte index; + private int uMul; + private int vMul; + private TrafficLightType[] allowedInTypes; + private TrafficLightColor[] applicableToColors; + + private TrafficLightIcon(String name, int index, int u, int v, TrafficLightType[] allowedInTypes, TrafficLightColor[] applicableToColors) { + this.name = name; + this.index = (byte)index; + this.uMul = u; + this.vMul = v; + this.allowedInTypes = allowedInTypes; + this.applicableToColors = applicableToColors; + } + + public String getName() { + return this.name; + } + + public byte getIndex() { + return this.index; + } + + @Override + public int getUMultiplier() { + return uMul; + } + + @Override + public int getVMultiplier() { + return vMul; + } + + public static TrafficLightIcon[] getAllowedForType(TrafficLightType type) { + return Arrays.stream(TrafficLightIcon.values()).filter(x -> Arrays.stream(x.allowedInTypes).anyMatch(y -> y == type)).toArray(TrafficLightIcon[]::new); + } + + public boolean isAllowedFor(TrafficLightType type) { + return Arrays.stream(allowedInTypes).anyMatch(x -> x == type); + } + + public static TrafficLightIcon[] applicableToColor(TrafficLightColor color) { + return Arrays.stream(TrafficLightIcon.values()).filter(x -> Arrays.stream(x.applicableToColors).anyMatch(y -> y == color)).toArray(TrafficLightIcon[]::new); + } + + public boolean isApplicableToColor(TrafficLightColor color) { + return Arrays.stream(applicableToColors).anyMatch(x -> x == color); + } + + public String getTranslationKey() { + return String.format("gui.trafficcraft.trafficlighticon.%s", name); + } + + public static TrafficLightIcon getIconByIndex(byte index) { + return Arrays.stream(TrafficLightIcon.values()).filter(x -> x.getIndex() == index).findFirst().orElse(TrafficLightIcon.NONE); + } + + public Sprite getSprite(TrafficLightType type) { + return new Sprite(ICON_TEXTURE_LOCATION, TEXTURE_SIZE, TEXTURE_SIZE, DEFAULT_SPRITE_SIZE * getUMultiplier(), DEFAULT_SPRITE_SIZE * (getVMultiplier() + type.getIndex()), DEFAULT_SPRITE_SIZE, DEFAULT_SPRITE_SIZE); + } + + @Override + public String getSerializedName() { + return name; + } + + @Override + public String getEnumName() { + return "trafficlighticon"; + } + + @Override + public String getEnumValueName() { + return getName(); + } +} diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightMode.java b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightMode.java deleted file mode 100644 index 7d6ffb8f..00000000 --- a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightMode.java +++ /dev/null @@ -1,46 +0,0 @@ -package de.mrjulsen.trafficcraft.block.data; - -import net.minecraft.util.StringRepresentable; - -public enum TrafficLightMode implements StringRepresentable { - ALL_ON("all", 0), - OFF("off", 1), - RED("red", 2), - RED_YELLOW("red_yellow", 3), - YELLOW("yellow", 4), - GREEN("green", 5); - - private String mode; - private int index; - - private TrafficLightMode(String shape, int index) { - this.mode = shape; - this.index = index; - } - - public String getMode() { - return this.mode; - } - - public int getIndex() { - return this.index; - } - - public String getTranslationKey() { - return String.format("gui.trafficcraft.trafficlight.mode.%s", mode); - } - - public static TrafficLightMode getModeByIndex(int index) { - for (TrafficLightMode shape : TrafficLightMode.values()) { - if (shape.getIndex() == index) { - return shape; - } - } - return TrafficLightMode.OFF; - } - - @Override - public String getSerializedName() { - return mode; - } -} diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightModel.java b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightModel.java new file mode 100644 index 00000000..3a056a00 --- /dev/null +++ b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightModel.java @@ -0,0 +1,81 @@ +package de.mrjulsen.trafficcraft.block.data; + +import java.util.Arrays; + +import de.mrjulsen.mcdragonlib.common.ITranslatableEnum; +import net.minecraft.util.StringRepresentable; + +public enum TrafficLightModel implements StringRepresentable, ITranslatableEnum, IIconEnum { + ONE_LIGHT("single", 1, 9, 16, 2, 0), + TWO_LIGHTS("double", 2, 4.5f, 16, 3, 0), + THREE_LIGHTS("tripple", 3, -0.5f, 16, 4, 0); + + private String name; + private byte lightsCount; + private float hitboxBottom; + private float hitboxTop; + private int uMul; + private int vMul; + + private TrafficLightModel(String name, int lightsCount, float hitboxBottom, float hitboxTop, int u, int v) { + this.name = name; + this.lightsCount = (byte)lightsCount; + this.hitboxBottom = hitboxBottom; + this.hitboxTop = hitboxTop; + this.uMul = u; + this.vMul = v; + } + + public String getName() { + return this.name; + } + + public byte getLightsCount() { + return this.lightsCount; + } + + public float getHitboxBottom() { + return hitboxBottom; + } + + public float getHitboxTop() { + return hitboxTop; + } + + public float getTotalHitboxHeight() { + return Math.abs(getHitboxTop() - getHitboxBottom()); + } + + @Override + public int getUMultiplier() { + return uMul; + } + + @Override + public int getVMultiplier() { + return vMul; + } + + public static TrafficLightModel getModelByLightsCount(byte lightsCount) { + return Arrays.stream(TrafficLightModel.values()).filter(x -> x.getLightsCount() == lightsCount).findFirst().orElse(TrafficLightModel.THREE_LIGHTS); + } + + @Override + public String getSerializedName() { + return name; + } + + @Override + public String getEnumName() { + return "trafficlightmodel"; + } + + @Override + public String getEnumValueName() { + return getName(); + } + + public static byte maxRequiredSlots() { + return (byte)Arrays.stream(TrafficLightModel.values()).mapToInt(x -> x.getLightsCount()).max().getAsInt(); + } +} diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightTrigger.java b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightTrigger.java index 87525aa2..4da3c2c4 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightTrigger.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightTrigger.java @@ -1,25 +1,40 @@ package de.mrjulsen.trafficcraft.block.data; +import java.util.Arrays; + +import de.mrjulsen.mcdragonlib.common.IIterableEnum; +import de.mrjulsen.mcdragonlib.common.ITranslatableEnum; +import de.mrjulsen.trafficcraft.registry.ModBlocks; import net.minecraft.util.StringRepresentable; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.block.Blocks; -public enum TrafficLightTrigger implements StringRepresentable { - NONE("none", 0), - ON_REQUEST("on_request", 1), - REDSTONE("redstone", 2); +public enum TrafficLightTrigger implements StringRepresentable, ITranslatableEnum, IItemIcon, IIterableEnum { + NONE("none", 0, Blocks.BARRIER), + ON_REQUEST("on_request", 1, ModBlocks.TRAFFIC_LIGHT_REQUEST_BUTTON.get()), + REDSTONE("redstone", 2, Items.REDSTONE); private String trigger; - private int index; + private byte index; + private ItemLike icon; - private TrafficLightTrigger(String shape, int index) { + private TrafficLightTrigger(String shape, int index, ItemLike icon) { this.trigger = shape; - this.index = index; + this.index = (byte)index; + this.icon = icon; + } + + @Override + public ItemLike getItemIcon() { + return icon; } public String getTrigger() { return this.trigger; } - public int getIndex() { + public byte getIndex() { return this.index; } @@ -27,17 +42,27 @@ public String getTranslationKey() { return String.format("gui.trafficcraft.trafficlight.trigger.%s", trigger); } - public static TrafficLightTrigger getTriggerByIndex(int index) { - for (TrafficLightTrigger shape : TrafficLightTrigger.values()) { - if (shape.getIndex() == index) { - return shape; - } - } - return TrafficLightTrigger.NONE; + public static TrafficLightTrigger getTriggerByIndex(byte index) { + return Arrays.stream(TrafficLightTrigger.values()).filter(x -> x.getIndex() == index).findFirst().orElse(TrafficLightTrigger.NONE); } @Override public String getSerializedName() { return trigger; } + + @Override + public String getEnumName() { + return "trafficlighttrigger"; + } + + @Override + public String getEnumValueName() { + return getTrigger(); + } + + @Override + public TrafficLightTrigger[] getValues() { + return values(); + } } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightType.java b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightType.java new file mode 100644 index 00000000..7d75d662 --- /dev/null +++ b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightType.java @@ -0,0 +1,64 @@ +package de.mrjulsen.trafficcraft.block.data; + +import java.util.Arrays; + +import de.mrjulsen.mcdragonlib.common.ITranslatableEnum; +import net.minecraft.util.StringRepresentable; + +public enum TrafficLightType implements StringRepresentable, ITranslatableEnum, IIconEnum { + CAR("car", 0, 0, 0), + TRAM("tram", 1, 1, 0); + + private String name; + private byte index; + private int uMul; + private int vMul; + + private TrafficLightType(String name, int index, int u, int v) { + this.name = name; + this.index = (byte)index; + this.uMul = u; + this.vMul = v; + } + + public String getName() { + return this.name; + } + + public byte getIndex() { + return this.index; + } + + public String getTranslationKey() { + return String.format("enum.trafficcraft.trafficlighttype.%s", name); + } + + @Override + public int getUMultiplier() { + return uMul; + } + + @Override + public int getVMultiplier() { + return vMul; + } + + public static TrafficLightType getTypeByIndex(byte index) { + return Arrays.stream(TrafficLightType.values()).filter(x -> x.getIndex() == index).findFirst().orElse(TrafficLightType.CAR); + } + + @Override + public String getSerializedName() { + return name; + } + + @Override + public String getEnumName() { + return "trafficlighttype"; + } + + @Override + public String getEnumValueName() { + return getName(); + } +} diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficSignShape.java b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficSignShape.java index f4432f9d..2105e503 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficSignShape.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficSignShape.java @@ -2,9 +2,9 @@ import java.util.stream.IntStream; +import de.mrjulsen.mcdragonlib.utils.Utils; import de.mrjulsen.trafficcraft.ModMain; -import de.mrjulsen.trafficcraft.proxy.ClientProxy; -import de.mrjulsen.trafficcraft.util.Utils; +import de.mrjulsen.trafficcraft.init.ClientInit; import net.minecraft.client.renderer.texture.DynamicTexture; import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; @@ -70,7 +70,7 @@ public static TrafficSignShape getShapeByIndex(int index) { @OnlyIn(Dist.CLIENT) public DynamicTexture getShapeTexture() { - return ClientProxy.SHAPE_TEXTURES[this.getIndex()]; + return ClientInit.SHAPE_TEXTURES[this.getIndex()]; } public int getShapeTextureId() { diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightDirection.java b/src/main/java/de/mrjulsen/trafficcraft/block/data/compat/TrafficLightDirection.java similarity index 56% rename from src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightDirection.java rename to src/main/java/de/mrjulsen/trafficcraft/block/data/compat/TrafficLightDirection.java index cd637ff7..5283d956 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightDirection.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/data/compat/TrafficLightDirection.java @@ -1,7 +1,12 @@ -package de.mrjulsen.trafficcraft.block.data; +package de.mrjulsen.trafficcraft.block.data.compat; +import de.mrjulsen.trafficcraft.block.data.TrafficLightIcon; import net.minecraft.util.StringRepresentable; +/** + * @deprecated Only for compatibility purposes! + */ +@Deprecated public enum TrafficLightDirection implements StringRepresentable { NORMAL("normal", 0), RIGHT("right", 1), @@ -26,10 +31,6 @@ public int getIndex() { return this.index; } - public String getTranslationKey() { - return String.format("gui.trafficcraft.trafficlight.direction.%s", directionName); - } - public static TrafficLightDirection getDirectionByIndex(int index) { for (TrafficLightDirection shape : TrafficLightDirection.values()) { if (shape.getIndex() == index) { @@ -43,4 +44,26 @@ public static TrafficLightDirection getDirectionByIndex(int index) { public String getSerializedName() { return directionName; } + + public TrafficLightIcon convertToIcon(boolean isPedestrianKnown) { + if (isPedestrianKnown) { + return TrafficLightIcon.PEDESTRIAN; + } + + switch (this) { + case LEFT: + return TrafficLightIcon.LEFT; + case RIGHT: + return TrafficLightIcon.RIGHT; + case STRAIGHT: + return TrafficLightIcon.STRAIGHT; + case STRAIGHT_LEFT: + return TrafficLightIcon.STRAIGHT_LEFT; + case STRAIGHT_RIGHT: + return TrafficLightIcon.STRAIGHT_RIGHT; + case NORMAL: + default: + return TrafficLightIcon.NONE; + } + } } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/data/compat/TrafficLightMode.java b/src/main/java/de/mrjulsen/trafficcraft/block/data/compat/TrafficLightMode.java new file mode 100644 index 00000000..ec8bfab7 --- /dev/null +++ b/src/main/java/de/mrjulsen/trafficcraft/block/data/compat/TrafficLightMode.java @@ -0,0 +1,72 @@ +package de.mrjulsen.trafficcraft.block.data.compat; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import de.mrjulsen.trafficcraft.block.data.TrafficLightColor; +import net.minecraft.util.StringRepresentable; + +/** + * @deprecated Only for compatibility purposes! + */ +@Deprecated +public enum TrafficLightMode implements StringRepresentable { + ALL_ON("all", 0), + OFF("off", 1), + RED("red", 2), + RED_YELLOW("red_yellow", 3), + YELLOW("yellow", 4), + GREEN("green", 5); + + private String mode; + private int index; + + private TrafficLightMode(String shape, int index) { + this.mode = shape; + this.index = index; + } + + public String getMode() { + return this.mode; + } + + public int getIndex() { + return this.index; + } + + public static TrafficLightMode getModeByIndex(int index) { + for (TrafficLightMode shape : TrafficLightMode.values()) { + if (shape.getIndex() == index) { + return shape; + } + } + return TrafficLightMode.OFF; + } + + @Override + public String getSerializedName() { + return mode; + } + + public static Collection convertToColorList(TrafficLightMode mode) { + switch (mode) { + case ALL_ON: + return List.of(TrafficLightColor.GREEN, TrafficLightColor.YELLOW, TrafficLightColor.RED); + case GREEN: + return List.of(TrafficLightColor.GREEN); + case RED: + return List.of(TrafficLightColor.RED); + case RED_YELLOW: + return List.of(TrafficLightColor.YELLOW, TrafficLightColor.RED); + case YELLOW: + return List.of(TrafficLightColor.YELLOW); + default: + return Collections.emptyList(); + } + } + + public Collection convertToColorList() { + return convertToColorList(this); + } +} diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightVariant.java b/src/main/java/de/mrjulsen/trafficcraft/block/data/compat/TrafficLightVariant.java similarity index 65% rename from src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightVariant.java rename to src/main/java/de/mrjulsen/trafficcraft/block/data/compat/TrafficLightVariant.java index de8e9368..3a1cd84f 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/data/TrafficLightVariant.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/data/compat/TrafficLightVariant.java @@ -1,7 +1,12 @@ -package de.mrjulsen.trafficcraft.block.data; +package de.mrjulsen.trafficcraft.block.data.compat; +import de.mrjulsen.trafficcraft.block.data.TrafficLightModel; import net.minecraft.util.StringRepresentable; +/** + * @deprecated Only for compatibility purposes! + */ +@Deprecated public enum TrafficLightVariant implements StringRepresentable { NORMAL("normal", 0), SMALL("small", 1), @@ -24,10 +29,6 @@ public int getIndex() { return this.index; } - public String getTranslationKey() { - return String.format("gui.trafficcraft.trafficlight.variant.%s", variant); - } - public static TrafficLightVariant getVariantByIndex(int index) { for (TrafficLightVariant shape : TrafficLightVariant.values()) { if (shape.getIndex() == index) { @@ -41,4 +42,16 @@ public static TrafficLightVariant getVariantByIndex(int index) { public String getSerializedName() { return variant; } + + public TrafficLightModel convertToModel() { + switch (this) { + case SMALL: + case SPECIAL: + case PEDESTRIAN: + return TrafficLightModel.TWO_LIGHTS; + case NORMAL: + default: + return TrafficLightModel.THREE_LIGHTS; + } + } } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/entity/ColoredBlockEntity.java b/src/main/java/de/mrjulsen/trafficcraft/block/entity/ColoredBlockEntity.java index 776a24e5..cb23eae7 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/entity/ColoredBlockEntity.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/entity/ColoredBlockEntity.java @@ -5,7 +5,7 @@ import de.mrjulsen.trafficcraft.block.data.IColorBlockEntity; import de.mrjulsen.trafficcraft.data.PaintColor; import de.mrjulsen.trafficcraft.registry.ModBlockEntities; -import de.mrjulsen.trafficcraft.util.BlockEntityUtil; +import de.mrjulsen.mcdragonlib.common.BlockEntityUtil; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.Connection; diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/entity/HouseNumberSignBlockEntity.java b/src/main/java/de/mrjulsen/trafficcraft/block/entity/HouseNumberSignBlockEntity.java index 94f4ac0f..e6953f27 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/entity/HouseNumberSignBlockEntity.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/entity/HouseNumberSignBlockEntity.java @@ -4,7 +4,7 @@ import de.mrjulsen.trafficcraft.client.ber.SignRenderingConfig; import de.mrjulsen.trafficcraft.data.PaintColor; import de.mrjulsen.trafficcraft.registry.ModBlockEntities; -import de.mrjulsen.trafficcraft.util.BlockEntityUtil; +import de.mrjulsen.mcdragonlib.common.BlockEntityUtil; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.block.entity.BlockEntityType; @@ -25,7 +25,6 @@ public HouseNumberSignBlockEntity(BlockPos pos, BlockState state) { @Override public SignRenderingConfig getRenderingConfig() { SignRenderingConfig config = new SignRenderingConfig(1); - //config.textureYOffset = config.height() / 2; config.maxLineWidth = config.width() / 2; config.textureYOffset = 40; config.setFontScale(0, new SignRenderingConfig.AutomaticFontScaleConfig(1.0D, 3.0D)); diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/entity/IIdentifiable.java b/src/main/java/de/mrjulsen/trafficcraft/block/entity/IIdentifiable.java deleted file mode 100644 index fa467eaa..00000000 --- a/src/main/java/de/mrjulsen/trafficcraft/block/entity/IIdentifiable.java +++ /dev/null @@ -1,5 +0,0 @@ -package de.mrjulsen.trafficcraft.block.entity; - -public interface IIdentifiable { - String getId(); -} diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/entity/StreetLampBlockEntity.java b/src/main/java/de/mrjulsen/trafficcraft/block/entity/StreetLampBlockEntity.java index 4a1c9dde..0244f902 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/entity/StreetLampBlockEntity.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/entity/StreetLampBlockEntity.java @@ -2,10 +2,10 @@ import javax.annotation.Nullable; -import de.mrjulsen.trafficcraft.Constants; +import de.mrjulsen.mcdragonlib.DragonLibConstants; +import de.mrjulsen.mcdragonlib.utils.TimeUtils; import de.mrjulsen.trafficcraft.block.StreetLampBaseBlock; import de.mrjulsen.trafficcraft.registry.ModBlockEntities; -import de.mrjulsen.trafficcraft.util.TimeUtils; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.Connection; @@ -71,7 +71,7 @@ public void tick(Level level, BlockPos pos, BlockState state) { return; } - if (TimeUtils.isInRange((int)(level.getDayTime() % Constants.TICKS_PER_DAY), onTimeTicks, offTimeTicks)) { + if (TimeUtils.isInRange((int)(level.getDayTime() % DragonLibConstants.TICKS_PER_DAY), onTimeTicks, offTimeTicks)) { if (!state.getValue(StreetLampBaseBlock.LIT)) { level.setBlockAndUpdate(pos, state.setValue(StreetLampBaseBlock.LIT, true)); } @@ -95,10 +95,10 @@ public int getOffTime() { } public void setOnTime(int time) { - this.onTimeTicks = Mth.clamp(time, 0, Constants.TICKS_PER_DAY - 1); + this.onTimeTicks = Mth.clamp(time, 0, DragonLibConstants.TICKS_PER_DAY - 1); } public void setOffTime(int time) { - this.offTimeTicks = Mth.clamp(time, 0, Constants.TICKS_PER_DAY - 1); + this.offTimeTicks = Mth.clamp(time, 0, DragonLibConstants.TICKS_PER_DAY - 1); } } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/entity/StreetSignBlockEntity.java b/src/main/java/de/mrjulsen/trafficcraft/block/entity/StreetSignBlockEntity.java index 448df263..d3cdb797 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/entity/StreetSignBlockEntity.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/entity/StreetSignBlockEntity.java @@ -4,7 +4,7 @@ import de.mrjulsen.trafficcraft.client.ber.SignRenderingConfig; import de.mrjulsen.trafficcraft.data.PaintColor; import de.mrjulsen.trafficcraft.registry.ModBlockEntities; -import de.mrjulsen.trafficcraft.util.BlockEntityUtil; +import de.mrjulsen.mcdragonlib.common.BlockEntityUtil; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.block.entity.BlockEntityType; diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/entity/TownSignBlockEntity.java b/src/main/java/de/mrjulsen/trafficcraft/block/entity/TownSignBlockEntity.java index 7cb6ec41..d6acecf3 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/entity/TownSignBlockEntity.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/entity/TownSignBlockEntity.java @@ -6,7 +6,7 @@ import de.mrjulsen.trafficcraft.block.TownSignBlock.ETownSignSide; import de.mrjulsen.trafficcraft.client.ber.SignRenderingConfig; import de.mrjulsen.trafficcraft.registry.ModBlockEntities; -import de.mrjulsen.trafficcraft.util.BlockEntityUtil; +import de.mrjulsen.mcdragonlib.common.BlockEntityUtil; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.block.entity.BlockEntityType; diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficLightBlockEntity.java b/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficLightBlockEntity.java index b544fea8..66ad5fa7 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficLightBlockEntity.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficLightBlockEntity.java @@ -1,21 +1,27 @@ package de.mrjulsen.trafficcraft.block.entity; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; import java.util.List; - import javax.annotation.Nullable; +import de.mrjulsen.mcdragonlib.common.Location; import de.mrjulsen.trafficcraft.ModMain; -import de.mrjulsen.trafficcraft.block.TrafficLightBlock; import de.mrjulsen.trafficcraft.block.TrafficLightControllerBlock; +import de.mrjulsen.trafficcraft.block.data.TrafficLightColor; import de.mrjulsen.trafficcraft.block.data.TrafficLightControlType; -import de.mrjulsen.trafficcraft.block.data.TrafficLightMode; -import de.mrjulsen.trafficcraft.data.Location; -import de.mrjulsen.trafficcraft.data.TrafficLightAnimationData; +import de.mrjulsen.trafficcraft.block.data.TrafficLightIcon; +import de.mrjulsen.trafficcraft.block.data.TrafficLightType; +import de.mrjulsen.trafficcraft.data.TrafficLightScheduleEntryData; import de.mrjulsen.trafficcraft.data.TrafficLightSchedule; import de.mrjulsen.trafficcraft.registry.ModBlockEntities; -import de.mrjulsen.trafficcraft.util.BlockEntityUtil; +import de.mrjulsen.mcdragonlib.common.BlockEntityUtil; import net.minecraft.core.BlockPos; +import net.minecraft.nbt.ByteTag; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.Tag; import net.minecraft.network.Connection; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.world.level.Level; @@ -25,9 +31,30 @@ public class TrafficLightBlockEntity extends ColoredBlockEntity { + private static final String NBT_PHASE_ID = "phaseId"; + private static final String NBT_CONTROL_TYPE = "controlType"; + private static final String NBT_POWERED = "powered"; + private static final String NBT_TICKS = "ticks"; + private static final String NBT_TOTAL_TICKS = "totalTicks"; + private static final String NBT_RUNNING = "running"; + private static final String NBT_SCHEDULE = "schedule"; + private static final String NBT_ICON = "icon"; + private static final String NBT_TYPE = "type"; + private static final String NBT_COLOR_SLOTS = "colorSlots"; + private static final String NBT_ENABLED_COLORS = "enabledColors"; + @Deprecated private static final String NBT_LINKED_TO = "linkedTo"; + // Properties private int phaseId = 0; - private int controlType = 0; + private TrafficLightControlType controlType = TrafficLightControlType.STATIC; + private TrafficLightIcon icon = TrafficLightIcon.NONE; + private TrafficLightType type = TrafficLightType.CAR; + private final TrafficLightColor[] colorSlots = new TrafficLightColor[] { + TrafficLightColor.RED, + TrafficLightColor.YELLOW, + TrafficLightColor.GREEN + }; + private final Collection enabledColors = new ArrayList<>(); private boolean powered = false; private TrafficLightSchedule schedule = new TrafficLightSchedule(); @@ -35,8 +62,7 @@ public class TrafficLightBlockEntity extends ColoredBlockEntity { private long totalTicks = 0; private boolean running = true; - // backwards compatibility - @Deprecated private Location linkLocation = null; + /** @deprecated Backwards compatibility only! */ @Deprecated private Location linkLocation = null; private boolean linkMigrated = false; protected TrafficLightBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { @@ -51,23 +77,32 @@ public TrafficLightBlockEntity(BlockPos pos, BlockState state) { public void load(CompoundTag compound) { super.load(compound); - this.phaseId = compound.getInt("phaseId"); - this.controlType = compound.getInt("controlType"); - this.powered = compound.getBoolean("powered"); - this.ticker = compound.getInt("ticker"); - this.totalTicks = compound.getLong("totalTicks"); - this.running = compound.getBoolean("running"); + this.phaseId = compound.getInt(NBT_PHASE_ID); + this.controlType = TrafficLightControlType.getControlTypeByIndex(compound.getTagType(NBT_COLOR_SLOTS) == Tag.TAG_INT ? (byte)compound.getInt(NBT_CONTROL_TYPE) : compound.getByte(NBT_CONTROL_TYPE)); + this.powered = compound.getBoolean(NBT_POWERED); + this.ticker = compound.getInt(NBT_TICKS); + this.totalTicks = compound.getLong(NBT_TOTAL_TICKS); + this.running = compound.getBoolean(NBT_RUNNING); this.schedule = new TrafficLightSchedule(); - this.schedule.fromNbt(compound.getCompound("schedule")); + this.schedule.fromNbt(compound.getCompound(NBT_SCHEDULE)); + this.icon = TrafficLightIcon.getIconByIndex(compound.getByte(NBT_ICON)); + this.type = TrafficLightType.getTypeByIndex(compound.getByte(NBT_TYPE)); + int[] colorSlots = compound.getIntArray(NBT_COLOR_SLOTS); + for (int i = 0; i < colorSlots.length && i < this.colorSlots.length; i++) { + this.colorSlots[i] = TrafficLightColor.getColorByIndex((byte)colorSlots[i]); + } + this.enabledColors.clear(); + this.enabledColors.addAll(compound.getList(NBT_ENABLED_COLORS, Tag.TAG_BYTE).stream().map(x -> TrafficLightColor.getColorByIndex(((ByteTag)x).getAsByte())).toList()); // backwards compatibility linkMigration(compound); } + @SuppressWarnings("deprecation") private void linkMigration(CompoundTag nbt) { - if (nbt.contains("linkedTo")) { + if (nbt.contains(NBT_LINKED_TO)) { ModMain.LOGGER.warn("Traffic Light at position " + worldPosition.toShortString() + " contains deprecated link data. Trying to convert it."); - linkLocation = Location.fromNbt(nbt.getCompound("linkedTo"), true); + linkLocation = Location.fromNbtAsInt(nbt.getCompound(NBT_LINKED_TO)); linkMigrated = false; return; } @@ -76,37 +111,40 @@ private void linkMigration(CompoundTag nbt) { @Override protected void saveAdditional(CompoundTag tag) { - tag.putInt("phaseId", phaseId); - tag.putBoolean("powered", powered); - tag.putInt("controlType", controlType); - tag.putInt("ticker", ticker); - tag.putLong("totalTicks", ticker); - tag.putBoolean("running", running); - tag.put("schedule", schedule.toNbt()); + tag.putInt(NBT_PHASE_ID, phaseId); + tag.putBoolean(NBT_POWERED, powered); + tag.putByte(NBT_CONTROL_TYPE, controlType.getIndex()); + tag.putInt(NBT_TICKS, ticker); + tag.putLong(NBT_TOTAL_TICKS, ticker); + tag.putBoolean(NBT_RUNNING, running); + tag.put(NBT_SCHEDULE, schedule.toNbt()); + tag.putIntArray(NBT_COLOR_SLOTS, Arrays.stream(colorSlots).mapToInt(x -> x.getIndex()).toArray()); + tag.putByte(NBT_ICON, icon.getIndex()); + tag.putByte(NBT_TYPE, type.getIndex()); + ListTag enabledColorsTag = new ListTag(); + enabledColorsTag.addAll(enabledColors.stream().map(x -> ByteTag.valueOf(x.getIndex())).toList()); + tag.put(NBT_ENABLED_COLORS, enabledColorsTag); // backwards compatibility if (!linkMigrated && this.linkLocation != null) { - tag.put("linkedTo", linkLocation.toNbt()); + tag.put(NBT_LINKED_TO, linkLocation.toNbt()); } super.saveAdditional(tag); } @Nullable @Override - public ClientboundBlockEntityDataPacket getUpdatePacket() - { + public ClientboundBlockEntityDataPacket getUpdatePacket() { return ClientboundBlockEntityDataPacket.create(this, BlockEntity::getUpdateTag); } @Override - public CompoundTag getUpdateTag() - { + public CompoundTag getUpdateTag() { return this.saveWithFullMetadata(); } @Override - public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) - { + public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) { this.load(pkt.getTag()); this.level.markAndNotifyBlock(this.worldPosition, this.level.getChunkAt(this.worldPosition), this.getBlockState(), this.getBlockState(), 3, 512); } @@ -120,19 +158,19 @@ private void tick(Level level, BlockPos pos, BlockState state) { linkMigrationCheck(level, pos, state); if (running && this.getControlType() == TrafficLightControlType.OWN_SCHEDULE) { - List stateData = schedule.shouldChange(ticker); + List stateData = schedule.shouldChange(ticker); - if (stateData == null) { + if (stateData == null) { // OOB: End of schedule reached. ticker = 0; if (!schedule.isLoop()) { setRunning(false); } return; } else if (stateData.size() >= 0) { - for (TrafficLightAnimationData entry : stateData) { - TrafficLightMode mode = entry.getMode(); - if (mode != null) { - level.setBlockAndUpdate(pos, state.setValue(TrafficLightBlock.MODE, mode)); + for (TrafficLightScheduleEntryData entry : stateData) { + Collection colors = entry.getEnabledColors(); + if (colors != null) { + enableOnlyColors(colors); } } } @@ -155,11 +193,11 @@ private void linkMigrationCheck(Level level, BlockPos pos, BlockState state) { return; } - if (level.isLoaded(linkLocation.getLocationAsBlockPos())) { - if (level.getBlockState(linkLocation.getLocationAsBlockPos()).getBlock() instanceof TrafficLightControllerBlock && - level.getBlockEntity(linkLocation.getLocationAsBlockPos()) instanceof TrafficLightControllerBlockEntity blockEntity + if (level.isLoaded(linkLocation.getLocationBlockPos())) { + if (level.getBlockState(linkLocation.getLocationBlockPos()).getBlock() instanceof TrafficLightControllerBlock && + level.getBlockEntity(linkLocation.getLocationBlockPos()) instanceof TrafficLightControllerBlockEntity blockEntity ) { - blockEntity.addTrafficLightLocation(new Location(pos, level)); + blockEntity.addTrafficLightLocation(new Location(pos.getX(), pos.getY(), pos.getZ(), level.dimension().location().toString())); } linkMigrated = true; return; @@ -173,41 +211,107 @@ public static void tick(Level level, BlockPos pos, BlockState state, TrafficLigh /* GETTERS AND SETTERS */ - public void setPhaseId(int id) - { + public void setPhaseId(int id) { this.phaseId = id; BlockEntityUtil.sendUpdatePacket(this); } - public boolean setControlType(int controlTypeIndex) { - if (controlTypeIndex >= TrafficLightControlType.values().length) - return false; + public void setControlType(TrafficLightControlType controlType) { + this.controlType = controlType; + BlockEntityUtil.sendUpdatePacket(this); + } + + public void setSchedule(TrafficLightSchedule schedule) { + this.schedule = schedule; + BlockEntityUtil.sendUpdatePacket(this); + } + + public void setIcon(TrafficLightIcon icon) { + this.icon = icon; + BlockEntityUtil.sendUpdatePacket(this); + } - this.controlType = controlTypeIndex; + public boolean setColorToSlot(int index, TrafficLightColor color) { + if (index < 0 || index >= colorSlots.length) { + return false; + } + this.colorSlots[index] = color; BlockEntityUtil.sendUpdatePacket(this); return true; } - public void setControlType(TrafficLightControlType controlType) { - this.controlType = controlType.getIndex(); + public void setColorSlots(TrafficLightColor[] colorSlots) { + for (int i = 0; i < colorSlots.length && i < getColorSlotCount(); i++) { + this.colorSlots[i] = colorSlots[i]; + } BlockEntityUtil.sendUpdatePacket(this); } - public void setSchedule(TrafficLightSchedule schedule) { - this.schedule = schedule; + public void enableColors(Collection colors) { + this.enabledColors.addAll(colors); + this.enabledColors.stream().distinct().toList(); + BlockEntityUtil.sendUpdatePacket(this); + } + + public void enableOnlyColors(Collection colors) { + this.enabledColors.clear(); + this.enabledColors.addAll(colors); + this.enabledColors.stream().distinct().toList(); BlockEntityUtil.sendUpdatePacket(this); } + + public void disableColors(Collection colors) { + colors.forEach(x -> enabledColors.removeIf(y -> x == y)); + BlockEntityUtil.sendUpdatePacket(this); + } + + public void disableAll(Collection colors) { + enabledColors.clear(); + BlockEntityUtil.sendUpdatePacket(this); + } + + public void setType(TrafficLightType type) { + this.type = type; + BlockEntityUtil.sendUpdatePacket(this); + } + + + + + public Collection getEnabledColors() { + return this.enabledColors; + } + + public boolean isColorEnabled(TrafficLightColor color, boolean allowSimilar) { + return this.enabledColors.stream().anyMatch(x -> (allowSimilar && x.isSimilar(color)) || x == color); + } public int getPhaseId() { return this.phaseId; } - public int getControlTypeAsInt() { + public TrafficLightControlType getControlType() { return this.controlType; } - public TrafficLightControlType getControlType() { - return TrafficLightControlType.getControlTypeByIndex(this.controlType); + public TrafficLightColor[] getColorSlots() { + return this.colorSlots; + } + + public TrafficLightIcon getIcon() { + return this.icon; + } + + public TrafficLightType getTLType() { + return this.type; + } + + public TrafficLightColor getColorOfSlot(int index) { + return index >= 0 && index < colorSlots.length ? colorSlots[index] : TrafficLightColor.NONE; + } + + public int getColorSlotCount() { + return colorSlots.length; } public TrafficLightSchedule getSchedule() { @@ -230,11 +334,12 @@ public void setRunning(boolean b) { } public void startSchedule(boolean forceRestart) { - if (this.controlType == TrafficLightControlType.OWN_SCHEDULE.getIndex() && (forceRestart || !this.isFirstIteration())) { + if (this.controlType == TrafficLightControlType.OWN_SCHEDULE && (forceRestart || !this.isFirstIteration())) { this.ticker = 0; this.totalTicks = 0; this.running = true; } + setChanged(); BlockEntityUtil.sendUpdatePacket(this); } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficLightControllerBlockEntity.java b/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficLightControllerBlockEntity.java index 8777e6ec..3a41bccc 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficLightControllerBlockEntity.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficLightControllerBlockEntity.java @@ -1,20 +1,18 @@ package de.mrjulsen.trafficcraft.block.entity; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Collection; import java.util.List; -import java.util.Map; - import javax.annotation.Nullable; +import de.mrjulsen.mcdragonlib.common.Location; import de.mrjulsen.trafficcraft.block.TrafficLightBlock; +import de.mrjulsen.trafficcraft.block.data.TrafficLightColor; import de.mrjulsen.trafficcraft.block.data.TrafficLightControlType; -import de.mrjulsen.trafficcraft.block.data.TrafficLightMode; -import de.mrjulsen.trafficcraft.data.Location; -import de.mrjulsen.trafficcraft.data.TrafficLightAnimationData; +import de.mrjulsen.trafficcraft.data.TrafficLightScheduleEntryData; import de.mrjulsen.trafficcraft.data.TrafficLightSchedule; import de.mrjulsen.trafficcraft.registry.ModBlockEntities; -import de.mrjulsen.trafficcraft.util.BlockEntityUtil; +import de.mrjulsen.mcdragonlib.common.BlockEntityUtil; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; @@ -29,6 +27,11 @@ public class TrafficLightControllerBlockEntity extends BlockEntity { private static final String NBT_TRAFFIC_LIGHT_LOCATIONS = "LinkedTrafficLights"; + private static final String NBT_TICKS = "ticks"; + private static final String NBT_TOTAL_TICKS = "totalTicks"; + private static final String NBT_POWERED = "powered"; + private static final String NBT_SCHEDULES = "schedules"; + private static final String NBT_RUNNING = "running"; // Properties private List schedules = new ArrayList<>(); @@ -38,9 +41,6 @@ public class TrafficLightControllerBlockEntity extends BlockEntity { private boolean powered = false; private List trafficLightLocations = new ArrayList<>(); - // ticking - private Map modes = new HashMap<>(); - protected TrafficLightControllerBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); } @@ -53,12 +53,12 @@ public TrafficLightControllerBlockEntity(BlockPos pos, BlockState state) { public void load(CompoundTag compound) { super.load(compound); - this.ticks = compound.getInt("ticks"); - this.running = compound.getBoolean("running"); - this.totalTicks = compound.getLong("totalTicks"); - this.powered = compound.getBoolean("powered"); + this.ticks = compound.getInt(NBT_TICKS); + this.running = compound.getBoolean(NBT_RUNNING); + this.totalTicks = compound.getLong(NBT_TOTAL_TICKS); + this.powered = compound.getBoolean(NBT_POWERED); - ListTag listTag = compound.getList("schedules", Tag.TAG_COMPOUND); + ListTag listTag = compound.getList(NBT_SCHEDULES, Tag.TAG_COMPOUND); schedules.clear(); for (int i = 0; i < listTag.size(); i++) { TrafficLightSchedule data = new TrafficLightSchedule(); @@ -66,15 +66,6 @@ public void load(CompoundTag compound) { schedules.add(data); } - ListTag modesList = compound.getList("modes", Tag.TAG_COMPOUND); - modes.clear(); - for (int i = 0; i < modesList.size(); i++) { - CompoundTag c = modesList.getCompound(i); - int key = c.getInt("key"); - int value = compound.getInt("value"); - modes.put(key, TrafficLightMode.getModeByIndex(value)); - } - ListTag trafficLightsList = compound.getList(NBT_TRAFFIC_LIGHT_LOCATIONS, Tag.TAG_COMPOUND); trafficLightLocations.clear(); for (int i = 0; i < trafficLightsList.size(); i++) { @@ -92,25 +83,17 @@ protected void saveAdditional(CompoundTag tag) listTag.add(data.toNbt()); } - ListTag modesTag = new ListTag(); - for (Map.Entry entry : modes.entrySet()) { - CompoundTag c = new CompoundTag(); - c.putInt("key", entry.getKey()); - c.putInt("value", entry.getValue().getIndex()); - modesTag.add(c); - } - ListTag trafficLightsList = new ListTag(); for (Location loc : trafficLightLocations) { trafficLightsList.add(loc.toNbt()); } - tag.putInt("ticks", ticks); - tag.putLong("totalTicks", totalTicks); - tag.putBoolean("powered", powered); - tag.putBoolean("running", running); - tag.put("schedules", listTag); - tag.put("modes", modesTag); + tag.putInt(NBT_TICKS, ticks); + tag.putLong(NBT_TOTAL_TICKS, totalTicks); + tag.putBoolean(NBT_POWERED, powered); + tag.putBoolean(NBT_RUNNING, running); + tag.put(NBT_SCHEDULES, listTag); + //tag.put("modes", modesTag); tag.put(NBT_TRAFFIC_LIGHT_LOCATIONS, trafficLightsList); super.saveAdditional(tag); } @@ -141,7 +124,7 @@ private void instanceTick(Level level, BlockPos pos, BlockState state) { if (running) { TrafficLightSchedule schedule = this.getFirstOrMainSchedule(); - List stateData = schedule.shouldChange(ticks); + List stateData = schedule.shouldChange(ticks); if (stateData == null) { ticks = 0; @@ -150,25 +133,21 @@ private void instanceTick(Level level, BlockPos pos, BlockState state) { } return; } else if (stateData.size() > 0) { - for (TrafficLightAnimationData entry : stateData) { - TrafficLightMode mode = entry.getMode(); + for (TrafficLightScheduleEntryData entry : stateData) { + Collection colors = entry.getEnabledColors(); int phaseId = entry.getPhaseId(); trafficLightLocations.removeIf(a -> - level.isLoaded(a.getLocationAsBlockPos()) && - level.getBlockState(a.getLocationAsBlockPos()).getBlock() instanceof TrafficLightBlock && - level.getBlockEntity(a.getLocationAsBlockPos()) instanceof TrafficLightBlockEntity blockEntity && - blockEntity.getControlType() != TrafficLightControlType.REMOTE + !level.isLoaded(a.getLocationBlockPos()) && + !(level.getBlockState(a.getLocationBlockPos()).getBlock() instanceof TrafficLightBlock) || + !(level.getBlockEntity(a.getLocationBlockPos()) instanceof TrafficLightBlockEntity blockEntity) ); - trafficLightLocations.stream().filter(a -> - level.isLoaded(a.getLocationAsBlockPos()) && - level.getBlockState(a.getLocationAsBlockPos()).getBlock() instanceof TrafficLightBlock && - level.getBlockEntity(a.getLocationAsBlockPos()) instanceof TrafficLightBlockEntity blockEntity && - blockEntity.getPhaseId() == phaseId - ).forEach(a -> { - BlockState blockState = level.getBlockState(a.getLocationAsBlockPos()); - level.setBlockAndUpdate(a.getLocationAsBlockPos(), blockState.setValue(TrafficLightBlock.MODE, mode)); + trafficLightLocations.stream().filter(x -> + level.getBlockEntity(x.getLocationBlockPos()) instanceof TrafficLightBlockEntity blockEntity && + blockEntity.getControlType() == TrafficLightControlType.REMOTE && + blockEntity.getPhaseId() == phaseId).forEach(a -> { + ((TrafficLightBlockEntity)level.getBlockEntity(a.getLocationBlockPos())).enableOnlyColors(colors); }); } } @@ -236,13 +215,6 @@ public void setRunning(boolean b) { BlockEntityUtil.sendUpdatePacket(this); } - public TrafficLightMode getModeForPhaseId(int phaseId) { - if (!modes.containsKey(phaseId)) - return null; - - return modes.get(phaseId); - } - public void startSchedule(boolean forceRestart) { if (forceRestart || !this.isFirstIteration()) { this.totalTicks = 0; @@ -261,10 +233,6 @@ public void stopSchedule() { BlockEntityUtil.sendUpdatePacket(this); } - public boolean hasSomethingToDo(int phaseId, TrafficLightMode currentMode) { - return modes.containsKey(phaseId) && modes.get(phaseId) != currentMode; - } - public boolean isFirstIteration() { return this.totalTicks == this.ticks; } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficLightRequestButtonBlockEntity.java b/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficLightRequestButtonBlockEntity.java index b4d36c76..f5747a69 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficLightRequestButtonBlockEntity.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficLightRequestButtonBlockEntity.java @@ -2,11 +2,11 @@ import javax.annotation.Nullable; +import de.mrjulsen.mcdragonlib.common.Location; import de.mrjulsen.trafficcraft.block.TrafficLightRequestButtonBlock; import de.mrjulsen.trafficcraft.block.data.TrafficLightTrigger; -import de.mrjulsen.trafficcraft.data.Location; import de.mrjulsen.trafficcraft.registry.ModBlockEntities; -import de.mrjulsen.trafficcraft.util.BlockEntityUtil; +import de.mrjulsen.mcdragonlib.common.BlockEntityUtil; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.Connection; @@ -69,10 +69,13 @@ private void tick(Level level, BlockPos pos, BlockState state) { if (this.listening) { if (!level.isClientSide) { boolean isRunning = false; - if (level.getBlockEntity(this.linkLocation.getLocationAsBlockPos()) instanceof TrafficLightBlockEntity blockEntity) { - isRunning = blockEntity.isFirstIteration(); - } else if (level.getBlockEntity(this.linkLocation.getLocationAsBlockPos()) instanceof TrafficLightControllerBlockEntity blockEntity) { - isRunning = blockEntity.isFirstIteration(); + + if (this.linkLocation != null) { + if (level.getBlockEntity(this.linkLocation.getLocationBlockPos()) instanceof TrafficLightBlockEntity blockEntity) { + isRunning = blockEntity.isFirstIteration(); + } else if (level.getBlockEntity(this.linkLocation.getLocationBlockPos()) instanceof TrafficLightControllerBlockEntity blockEntity) { + isRunning = blockEntity.isFirstIteration(); + } } if (!isRunning) { @@ -105,7 +108,10 @@ public Location getLinkLocation() { } public boolean isValidLinked() { - return this.getLinkLocation() != null && level.getBlockEntity(this.linkLocation.getLocationAsBlockPos()) instanceof TrafficLightControllerBlockEntity; + return this.getLinkLocation() != null && ( + level.getBlockEntity(this.linkLocation.getLocationBlockPos()) instanceof TrafficLightControllerBlockEntity || + level.getBlockEntity(this.linkLocation.getLocationBlockPos()) instanceof TrafficLightBlockEntity + ); } public boolean isListening() { @@ -113,21 +119,24 @@ public boolean isListening() { } public boolean activate() { - this.listening = true; if (!this.isValidLinked()) return false; + + this.listening = true; - if (level.getBlockEntity(this.linkLocation.getLocationAsBlockPos()) instanceof TrafficLightBlockEntity blockEntity) { + if (level.getBlockEntity(this.linkLocation.getLocationBlockPos()) instanceof TrafficLightBlockEntity blockEntity) { if (blockEntity.getSchedule().getTrigger() == TrafficLightTrigger.ON_REQUEST) { - blockEntity.startSchedule(false); + blockEntity.startSchedule(true); return true; } - } else if (level.getBlockEntity(this.linkLocation.getLocationAsBlockPos()) instanceof TrafficLightControllerBlockEntity blockEntity) { + } else if (level.getBlockEntity(this.linkLocation.getLocationBlockPos()) instanceof TrafficLightControllerBlockEntity blockEntity) { if (blockEntity.getFirstOrMainSchedule().getTrigger() == TrafficLightTrigger.ON_REQUEST) { blockEntity.startSchedule(true); return true; } } + + this.listening = false; return false; } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficSignBlockEntity.java b/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficSignBlockEntity.java index 8e6469c6..2dfd3033 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficSignBlockEntity.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/entity/TrafficSignBlockEntity.java @@ -4,9 +4,10 @@ import de.mrjulsen.trafficcraft.client.ClientWrapper; import de.mrjulsen.trafficcraft.network.NetworkManager; -import de.mrjulsen.trafficcraft.network.packets.TrafficSignTextureResetPacket; +import de.mrjulsen.trafficcraft.network.packets.stc.TrafficSignTextureResetPacket; import de.mrjulsen.trafficcraft.registry.ModBlockEntities; -import de.mrjulsen.trafficcraft.util.BlockEntityUtil; +import de.mrjulsen.mcdragonlib.common.BlockEntityUtil; +import de.mrjulsen.mcdragonlib.common.IIdentifiable; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.Connection; @@ -17,7 +18,6 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.fml.DistExecutor; -import net.minecraftforge.network.NetworkDirection; public class TrafficSignBlockEntity extends BlockEntity implements IIdentifiable, AutoCloseable { @@ -83,7 +83,7 @@ public void setAndResetTexture(String base64) { setBase64Texture(base64); if (!this.level.isClientSide) { for (ServerPlayer player : level.players().stream().filter(p -> p instanceof ServerPlayer).toArray(ServerPlayer[]::new)) { - NetworkManager.MOD_CHANNEL.sendTo(new TrafficSignTextureResetPacket(ID), player.connection.getConnection(), NetworkDirection.PLAY_TO_CLIENT); + NetworkManager.getInstance().sendToClient(new TrafficSignTextureResetPacket(ID), player); } } } @@ -103,7 +103,7 @@ public void onChunkUnloaded() { private void clear() { if (!this.level.isClientSide) { for (ServerPlayer player : level.players().stream().filter(p -> p instanceof ServerPlayer).toArray(ServerPlayer[]::new)) { - NetworkManager.MOD_CHANNEL.sendTo(new TrafficSignTextureResetPacket(ID), player.connection.getConnection(), NetworkDirection.PLAY_TO_CLIENT); + NetworkManager.getInstance().sendToClient(new TrafficSignTextureResetPacket(ID), player); } } } @@ -112,9 +112,4 @@ private void clear() { public void close() { DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ClientWrapper.clearTexture(this)); } - - @Override - protected void finalize() { - this.close(); - } } diff --git a/src/main/java/de/mrjulsen/trafficcraft/block/entity/WritableTrafficSignBlockEntity.java b/src/main/java/de/mrjulsen/trafficcraft/block/entity/WritableTrafficSignBlockEntity.java index 3abf23da..1d78b557 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/block/entity/WritableTrafficSignBlockEntity.java +++ b/src/main/java/de/mrjulsen/trafficcraft/block/entity/WritableTrafficSignBlockEntity.java @@ -6,7 +6,7 @@ import de.mrjulsen.trafficcraft.client.ber.SignRenderingConfig; import de.mrjulsen.trafficcraft.registry.ModBlockEntities; -import de.mrjulsen.trafficcraft.util.BlockEntityUtil; +import de.mrjulsen.mcdragonlib.common.BlockEntityUtil; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.Connection; diff --git a/src/main/java/de/mrjulsen/trafficcraft/client/AmbientOcclusion.java b/src/main/java/de/mrjulsen/trafficcraft/client/AmbientOcclusion.java deleted file mode 100644 index d6b4e5f1..00000000 --- a/src/main/java/de/mrjulsen/trafficcraft/client/AmbientOcclusion.java +++ /dev/null @@ -1,453 +0,0 @@ -package de.mrjulsen.trafficcraft.client; - -import java.util.BitSet; - -import it.unimi.dsi.fastutil.longs.Long2FloatLinkedOpenHashMap; -import it.unimi.dsi.fastutil.longs.Long2IntLinkedOpenHashMap; -import net.minecraft.Util; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -/** - * @see {@code ModelBlockRenderer.class} - */ -@OnlyIn(Dist.CLIENT) -public class AmbientOcclusion { - private static final ThreadLocal CACHE = ThreadLocal.withInitial(Cache::new); - - public final float[] brightness = new float[4]; - public final int[] lightmap = new int[4]; - - public AmbientOcclusion() { - } - - public void calculate(BlockAndTintGetter pLevel, BlockState pState, BlockPos pPos, Direction pDirection, - float[] pShape, BitSet pShapeFlags, boolean pShade) { - BlockPos blockpos = pShapeFlags.get(0) ? pPos.relative(pDirection) : pPos; - AdjacencyInfo modelblockrenderer$adjacencyinfo = AdjacencyInfo.fromFacing(pDirection); - BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos(); - Cache modelblockrenderer$cache = CACHE.get(); - blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[0]); - BlockState blockstate = pLevel.getBlockState(blockpos$mutableblockpos); - int i = modelblockrenderer$cache.getLightColor(blockstate, pLevel, blockpos$mutableblockpos); - float f = modelblockrenderer$cache.getShadeBrightness(blockstate, pLevel, blockpos$mutableblockpos); - blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[1]); - BlockState blockstate1 = pLevel.getBlockState(blockpos$mutableblockpos); - int j = modelblockrenderer$cache.getLightColor(blockstate1, pLevel, blockpos$mutableblockpos); - float f1 = modelblockrenderer$cache.getShadeBrightness(blockstate1, pLevel, blockpos$mutableblockpos); - blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[2]); - BlockState blockstate2 = pLevel.getBlockState(blockpos$mutableblockpos); - int k = modelblockrenderer$cache.getLightColor(blockstate2, pLevel, blockpos$mutableblockpos); - float f2 = modelblockrenderer$cache.getShadeBrightness(blockstate2, pLevel, blockpos$mutableblockpos); - blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[3]); - BlockState blockstate3 = pLevel.getBlockState(blockpos$mutableblockpos); - int l = modelblockrenderer$cache.getLightColor(blockstate3, pLevel, blockpos$mutableblockpos); - float f3 = modelblockrenderer$cache.getShadeBrightness(blockstate3, pLevel, blockpos$mutableblockpos); - BlockState blockstate4 = pLevel.getBlockState(blockpos$mutableblockpos - .setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[0]).move(pDirection)); - boolean flag = !blockstate4.isViewBlocking(pLevel, blockpos$mutableblockpos) - || blockstate4.getLightBlock(pLevel, blockpos$mutableblockpos) == 0; - BlockState blockstate5 = pLevel.getBlockState(blockpos$mutableblockpos - .setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[1]).move(pDirection)); - boolean flag1 = !blockstate5.isViewBlocking(pLevel, blockpos$mutableblockpos) - || blockstate5.getLightBlock(pLevel, blockpos$mutableblockpos) == 0; - BlockState blockstate6 = pLevel.getBlockState(blockpos$mutableblockpos - .setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[2]).move(pDirection)); - boolean flag2 = !blockstate6.isViewBlocking(pLevel, blockpos$mutableblockpos) - || blockstate6.getLightBlock(pLevel, blockpos$mutableblockpos) == 0; - BlockState blockstate7 = pLevel.getBlockState(blockpos$mutableblockpos - .setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[3]).move(pDirection)); - boolean flag3 = !blockstate7.isViewBlocking(pLevel, blockpos$mutableblockpos) - || blockstate7.getLightBlock(pLevel, blockpos$mutableblockpos) == 0; - float f4; - int i1; - if (!flag2 && !flag) { - f4 = f; - i1 = i; - } else { - blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[0]) - .move(modelblockrenderer$adjacencyinfo.corners[2]); - BlockState blockstate8 = pLevel.getBlockState(blockpos$mutableblockpos); - f4 = modelblockrenderer$cache.getShadeBrightness(blockstate8, pLevel, blockpos$mutableblockpos); - i1 = modelblockrenderer$cache.getLightColor(blockstate8, pLevel, blockpos$mutableblockpos); - } - - float f5; - int j1; - if (!flag3 && !flag) { - f5 = f; - j1 = i; - } else { - blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[0]) - .move(modelblockrenderer$adjacencyinfo.corners[3]); - BlockState blockstate10 = pLevel.getBlockState(blockpos$mutableblockpos); - f5 = modelblockrenderer$cache.getShadeBrightness(blockstate10, pLevel, blockpos$mutableblockpos); - j1 = modelblockrenderer$cache.getLightColor(blockstate10, pLevel, blockpos$mutableblockpos); - } - - float f6; - int k1; - if (!flag2 && !flag1) { - f6 = f; - k1 = i; - } else { - blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[1]) - .move(modelblockrenderer$adjacencyinfo.corners[2]); - BlockState blockstate11 = pLevel.getBlockState(blockpos$mutableblockpos); - f6 = modelblockrenderer$cache.getShadeBrightness(blockstate11, pLevel, blockpos$mutableblockpos); - k1 = modelblockrenderer$cache.getLightColor(blockstate11, pLevel, blockpos$mutableblockpos); - } - - float f7; - int l1; - if (!flag3 && !flag1) { - f7 = f; - l1 = i; - } else { - blockpos$mutableblockpos.setWithOffset(blockpos, modelblockrenderer$adjacencyinfo.corners[1]) - .move(modelblockrenderer$adjacencyinfo.corners[3]); - BlockState blockstate12 = pLevel.getBlockState(blockpos$mutableblockpos); - f7 = modelblockrenderer$cache.getShadeBrightness(blockstate12, pLevel, blockpos$mutableblockpos); - l1 = modelblockrenderer$cache.getLightColor(blockstate12, pLevel, blockpos$mutableblockpos); - } - - int i3 = modelblockrenderer$cache.getLightColor(pState, pLevel, pPos); - blockpos$mutableblockpos.setWithOffset(pPos, pDirection); - BlockState blockstate9 = pLevel.getBlockState(blockpos$mutableblockpos); - if (pShapeFlags.get(0) || !blockstate9.isSolidRender(pLevel, blockpos$mutableblockpos)) { - i3 = modelblockrenderer$cache.getLightColor(blockstate9, pLevel, blockpos$mutableblockpos); - } - - float f8 = pShapeFlags.get(0) - ? modelblockrenderer$cache.getShadeBrightness(pLevel.getBlockState(blockpos), pLevel, blockpos) - : modelblockrenderer$cache.getShadeBrightness(pLevel.getBlockState(pPos), pLevel, pPos); - AmbientVertexRemap modelblockrenderer$ambientvertexremap = AmbientVertexRemap.fromFacing(pDirection); - if (pShapeFlags.get(1) && modelblockrenderer$adjacencyinfo.doNonCubicWeight) { - float f29 = (f3 + f + f5 + f8) * 0.25F; - float f31 = (f2 + f + f4 + f8) * 0.25F; - float f32 = (f2 + f1 + f6 + f8) * 0.25F; - float f33 = (f3 + f1 + f7 + f8) * 0.25F; - float f13 = pShape[modelblockrenderer$adjacencyinfo.vert0Weights[0].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert0Weights[1].shape]; - float f14 = pShape[modelblockrenderer$adjacencyinfo.vert0Weights[2].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert0Weights[3].shape]; - float f15 = pShape[modelblockrenderer$adjacencyinfo.vert0Weights[4].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert0Weights[5].shape]; - float f16 = pShape[modelblockrenderer$adjacencyinfo.vert0Weights[6].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert0Weights[7].shape]; - float f17 = pShape[modelblockrenderer$adjacencyinfo.vert1Weights[0].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert1Weights[1].shape]; - float f18 = pShape[modelblockrenderer$adjacencyinfo.vert1Weights[2].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert1Weights[3].shape]; - float f19 = pShape[modelblockrenderer$adjacencyinfo.vert1Weights[4].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert1Weights[5].shape]; - float f20 = pShape[modelblockrenderer$adjacencyinfo.vert1Weights[6].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert1Weights[7].shape]; - float f21 = pShape[modelblockrenderer$adjacencyinfo.vert2Weights[0].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert2Weights[1].shape]; - float f22 = pShape[modelblockrenderer$adjacencyinfo.vert2Weights[2].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert2Weights[3].shape]; - float f23 = pShape[modelblockrenderer$adjacencyinfo.vert2Weights[4].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert2Weights[5].shape]; - float f24 = pShape[modelblockrenderer$adjacencyinfo.vert2Weights[6].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert2Weights[7].shape]; - float f25 = pShape[modelblockrenderer$adjacencyinfo.vert3Weights[0].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert3Weights[1].shape]; - float f26 = pShape[modelblockrenderer$adjacencyinfo.vert3Weights[2].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert3Weights[3].shape]; - float f27 = pShape[modelblockrenderer$adjacencyinfo.vert3Weights[4].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert3Weights[5].shape]; - float f28 = pShape[modelblockrenderer$adjacencyinfo.vert3Weights[6].shape] - * pShape[modelblockrenderer$adjacencyinfo.vert3Weights[7].shape]; - this.brightness[modelblockrenderer$ambientvertexremap.vert0] = f29 * f13 + f31 * f14 + f32 * f15 - + f33 * f16; - this.brightness[modelblockrenderer$ambientvertexremap.vert1] = f29 * f17 + f31 * f18 + f32 * f19 - + f33 * f20; - this.brightness[modelblockrenderer$ambientvertexremap.vert2] = f29 * f21 + f31 * f22 + f32 * f23 - + f33 * f24; - this.brightness[modelblockrenderer$ambientvertexremap.vert3] = f29 * f25 + f31 * f26 + f32 * f27 - + f33 * f28; - int i2 = this.blend(l, i, j1, i3); - int j2 = this.blend(k, i, i1, i3); - int k2 = this.blend(k, j, k1, i3); - int l2 = this.blend(l, j, l1, i3); - this.lightmap[modelblockrenderer$ambientvertexremap.vert0] = this.blend(i2, j2, k2, l2, f13, f14, f15, f16); - this.lightmap[modelblockrenderer$ambientvertexremap.vert1] = this.blend(i2, j2, k2, l2, f17, f18, f19, f20); - this.lightmap[modelblockrenderer$ambientvertexremap.vert2] = this.blend(i2, j2, k2, l2, f21, f22, f23, f24); - this.lightmap[modelblockrenderer$ambientvertexremap.vert3] = this.blend(i2, j2, k2, l2, f25, f26, f27, f28); - } else { - float f9 = (f3 + f + f5 + f8) * 0.25F; - float f10 = (f2 + f + f4 + f8) * 0.25F; - float f11 = (f2 + f1 + f6 + f8) * 0.25F; - float f12 = (f3 + f1 + f7 + f8) * 0.25F; - this.lightmap[modelblockrenderer$ambientvertexremap.vert0] = this.blend(l, i, j1, i3); - this.lightmap[modelblockrenderer$ambientvertexremap.vert1] = this.blend(k, i, i1, i3); - this.lightmap[modelblockrenderer$ambientvertexremap.vert2] = this.blend(k, j, k1, i3); - this.lightmap[modelblockrenderer$ambientvertexremap.vert3] = this.blend(l, j, l1, i3); - this.brightness[modelblockrenderer$ambientvertexremap.vert0] = f9; - this.brightness[modelblockrenderer$ambientvertexremap.vert1] = f10; - this.brightness[modelblockrenderer$ambientvertexremap.vert2] = f11; - this.brightness[modelblockrenderer$ambientvertexremap.vert3] = f12; - } - - float f30 = pLevel.getShade(pDirection, pShade); - - for (int j3 = 0; j3 < this.brightness.length; ++j3) { - this.brightness[j3] *= f30; - } - - } - - /** - * @return the ambient occlusion light color - */ - private int blend(int pLightColor0, int pLightColor1, int pLightColor2, int pLightColor3) { - if (pLightColor0 == 0) { - pLightColor0 = pLightColor3; - } - - if (pLightColor1 == 0) { - pLightColor1 = pLightColor3; - } - - if (pLightColor2 == 0) { - pLightColor2 = pLightColor3; - } - - return pLightColor0 + pLightColor1 + pLightColor2 + pLightColor3 >> 2 & 16711935; - } - - private int blend(int pBrightness0, int pBrightness1, int pBrightness2, int pBrightness3, float pWeight0, - float pWeight1, float pWeight2, float pWeight3) { - int i = (int) ((float) (pBrightness0 >> 16 & 255) * pWeight0 + (float) (pBrightness1 >> 16 & 255) * pWeight1 - + (float) (pBrightness2 >> 16 & 255) * pWeight2 + (float) (pBrightness3 >> 16 & 255) * pWeight3) & 255; - int j = (int) ((float) (pBrightness0 & 255) * pWeight0 + (float) (pBrightness1 & 255) * pWeight1 - + (float) (pBrightness2 & 255) * pWeight2 + (float) (pBrightness3 & 255) * pWeight3) & 255; - return i << 16 | j; - } - - @OnlyIn(Dist.CLIENT) - protected static enum AdjacencyInfo { - DOWN(new Direction[] { Direction.WEST, Direction.EAST, Direction.NORTH, Direction.SOUTH }, 0.5F, true, - new SizeInfo[] { SizeInfo.FLIP_WEST, SizeInfo.SOUTH, SizeInfo.FLIP_WEST, SizeInfo.FLIP_SOUTH, - SizeInfo.WEST, SizeInfo.FLIP_SOUTH, SizeInfo.WEST, SizeInfo.SOUTH }, - new SizeInfo[] { SizeInfo.FLIP_WEST, SizeInfo.NORTH, SizeInfo.FLIP_WEST, SizeInfo.FLIP_NORTH, - SizeInfo.WEST, SizeInfo.FLIP_NORTH, SizeInfo.WEST, SizeInfo.NORTH }, - new SizeInfo[] { SizeInfo.FLIP_EAST, SizeInfo.NORTH, SizeInfo.FLIP_EAST, SizeInfo.FLIP_NORTH, - SizeInfo.EAST, SizeInfo.FLIP_NORTH, SizeInfo.EAST, SizeInfo.NORTH }, - new SizeInfo[] { SizeInfo.FLIP_EAST, SizeInfo.SOUTH, SizeInfo.FLIP_EAST, SizeInfo.FLIP_SOUTH, - SizeInfo.EAST, SizeInfo.FLIP_SOUTH, SizeInfo.EAST, SizeInfo.SOUTH }), - UP(new Direction[] { Direction.EAST, Direction.WEST, Direction.NORTH, Direction.SOUTH }, 1.0F, true, - new SizeInfo[] { SizeInfo.EAST, SizeInfo.SOUTH, SizeInfo.EAST, SizeInfo.FLIP_SOUTH, SizeInfo.FLIP_EAST, - SizeInfo.FLIP_SOUTH, SizeInfo.FLIP_EAST, SizeInfo.SOUTH }, - new SizeInfo[] { SizeInfo.EAST, SizeInfo.NORTH, SizeInfo.EAST, SizeInfo.FLIP_NORTH, SizeInfo.FLIP_EAST, - SizeInfo.FLIP_NORTH, SizeInfo.FLIP_EAST, SizeInfo.NORTH }, - new SizeInfo[] { SizeInfo.WEST, SizeInfo.NORTH, SizeInfo.WEST, SizeInfo.FLIP_NORTH, SizeInfo.FLIP_WEST, - SizeInfo.FLIP_NORTH, SizeInfo.FLIP_WEST, SizeInfo.NORTH }, - new SizeInfo[] { SizeInfo.WEST, SizeInfo.SOUTH, SizeInfo.WEST, SizeInfo.FLIP_SOUTH, SizeInfo.FLIP_WEST, - SizeInfo.FLIP_SOUTH, SizeInfo.FLIP_WEST, SizeInfo.SOUTH }), - NORTH(new Direction[] { Direction.UP, Direction.DOWN, Direction.EAST, Direction.WEST }, 0.8F, true, - new SizeInfo[] { SizeInfo.UP, SizeInfo.FLIP_WEST, SizeInfo.UP, SizeInfo.WEST, SizeInfo.FLIP_UP, - SizeInfo.WEST, SizeInfo.FLIP_UP, SizeInfo.FLIP_WEST }, - new SizeInfo[] { SizeInfo.UP, SizeInfo.FLIP_EAST, SizeInfo.UP, SizeInfo.EAST, SizeInfo.FLIP_UP, - SizeInfo.EAST, SizeInfo.FLIP_UP, SizeInfo.FLIP_EAST }, - new SizeInfo[] { SizeInfo.DOWN, SizeInfo.FLIP_EAST, SizeInfo.DOWN, SizeInfo.EAST, SizeInfo.FLIP_DOWN, - SizeInfo.EAST, SizeInfo.FLIP_DOWN, SizeInfo.FLIP_EAST }, - new SizeInfo[] { SizeInfo.DOWN, SizeInfo.FLIP_WEST, SizeInfo.DOWN, SizeInfo.WEST, SizeInfo.FLIP_DOWN, - SizeInfo.WEST, SizeInfo.FLIP_DOWN, SizeInfo.FLIP_WEST }), - SOUTH(new Direction[] { Direction.WEST, Direction.EAST, Direction.DOWN, Direction.UP }, 0.8F, true, - new SizeInfo[] { SizeInfo.UP, SizeInfo.FLIP_WEST, SizeInfo.FLIP_UP, SizeInfo.FLIP_WEST, - SizeInfo.FLIP_UP, SizeInfo.WEST, SizeInfo.UP, SizeInfo.WEST }, - new SizeInfo[] { SizeInfo.DOWN, SizeInfo.FLIP_WEST, SizeInfo.FLIP_DOWN, SizeInfo.FLIP_WEST, - SizeInfo.FLIP_DOWN, SizeInfo.WEST, SizeInfo.DOWN, SizeInfo.WEST }, - new SizeInfo[] { SizeInfo.DOWN, SizeInfo.FLIP_EAST, SizeInfo.FLIP_DOWN, SizeInfo.FLIP_EAST, - SizeInfo.FLIP_DOWN, SizeInfo.EAST, SizeInfo.DOWN, SizeInfo.EAST }, - new SizeInfo[] { SizeInfo.UP, SizeInfo.FLIP_EAST, SizeInfo.FLIP_UP, SizeInfo.FLIP_EAST, - SizeInfo.FLIP_UP, SizeInfo.EAST, SizeInfo.UP, SizeInfo.EAST }), - WEST(new Direction[] { Direction.UP, Direction.DOWN, Direction.NORTH, Direction.SOUTH }, 0.6F, true, - new SizeInfo[] { SizeInfo.UP, SizeInfo.SOUTH, SizeInfo.UP, SizeInfo.FLIP_SOUTH, SizeInfo.FLIP_UP, - SizeInfo.FLIP_SOUTH, SizeInfo.FLIP_UP, SizeInfo.SOUTH }, - new SizeInfo[] { SizeInfo.UP, SizeInfo.NORTH, SizeInfo.UP, SizeInfo.FLIP_NORTH, SizeInfo.FLIP_UP, - SizeInfo.FLIP_NORTH, SizeInfo.FLIP_UP, SizeInfo.NORTH }, - new SizeInfo[] { SizeInfo.DOWN, SizeInfo.NORTH, SizeInfo.DOWN, SizeInfo.FLIP_NORTH, SizeInfo.FLIP_DOWN, - SizeInfo.FLIP_NORTH, SizeInfo.FLIP_DOWN, SizeInfo.NORTH }, - new SizeInfo[] { SizeInfo.DOWN, SizeInfo.SOUTH, SizeInfo.DOWN, SizeInfo.FLIP_SOUTH, SizeInfo.FLIP_DOWN, - SizeInfo.FLIP_SOUTH, SizeInfo.FLIP_DOWN, SizeInfo.SOUTH }), - EAST(new Direction[] { Direction.DOWN, Direction.UP, Direction.NORTH, Direction.SOUTH }, 0.6F, true, - new SizeInfo[] { SizeInfo.FLIP_DOWN, SizeInfo.SOUTH, SizeInfo.FLIP_DOWN, SizeInfo.FLIP_SOUTH, - SizeInfo.DOWN, SizeInfo.FLIP_SOUTH, SizeInfo.DOWN, SizeInfo.SOUTH }, - new SizeInfo[] { SizeInfo.FLIP_DOWN, SizeInfo.NORTH, SizeInfo.FLIP_DOWN, SizeInfo.FLIP_NORTH, - SizeInfo.DOWN, SizeInfo.FLIP_NORTH, SizeInfo.DOWN, SizeInfo.NORTH }, - new SizeInfo[] { SizeInfo.FLIP_UP, SizeInfo.NORTH, SizeInfo.FLIP_UP, SizeInfo.FLIP_NORTH, SizeInfo.UP, - SizeInfo.FLIP_NORTH, SizeInfo.UP, SizeInfo.NORTH }, - new SizeInfo[] { SizeInfo.FLIP_UP, SizeInfo.SOUTH, SizeInfo.FLIP_UP, SizeInfo.FLIP_SOUTH, SizeInfo.UP, - SizeInfo.FLIP_SOUTH, SizeInfo.UP, SizeInfo.SOUTH }); - - final Direction[] corners; - final boolean doNonCubicWeight; - final SizeInfo[] vert0Weights; - final SizeInfo[] vert1Weights; - final SizeInfo[] vert2Weights; - final SizeInfo[] vert3Weights; - private static final AdjacencyInfo[] BY_FACING = Util.make(new AdjacencyInfo[6], (p_111134_) -> { - p_111134_[Direction.DOWN.get3DDataValue()] = DOWN; - p_111134_[Direction.UP.get3DDataValue()] = UP; - p_111134_[Direction.NORTH.get3DDataValue()] = NORTH; - p_111134_[Direction.SOUTH.get3DDataValue()] = SOUTH; - p_111134_[Direction.WEST.get3DDataValue()] = WEST; - p_111134_[Direction.EAST.get3DDataValue()] = EAST; - }); - - private AdjacencyInfo(Direction[] pCorners, float pShadeBrightness, boolean pDoNonCubicWeight, - SizeInfo[] pVert0Weights, SizeInfo[] pVert1Weights, SizeInfo[] pVert2Weights, - SizeInfo[] pVert3Weights) { - this.corners = pCorners; - this.doNonCubicWeight = pDoNonCubicWeight; - this.vert0Weights = pVert0Weights; - this.vert1Weights = pVert1Weights; - this.vert2Weights = pVert2Weights; - this.vert3Weights = pVert3Weights; - } - - public static AdjacencyInfo fromFacing(Direction pFacing) { - return BY_FACING[pFacing.get3DDataValue()]; - } - } - - @OnlyIn(Dist.CLIENT) - static enum AmbientVertexRemap { - DOWN(0, 1, 2, 3), - UP(2, 3, 0, 1), - NORTH(3, 0, 1, 2), - SOUTH(0, 1, 2, 3), - WEST(3, 0, 1, 2), - EAST(1, 2, 3, 0); - - final int vert0; - final int vert1; - final int vert2; - final int vert3; - private static final AmbientVertexRemap[] BY_FACING = Util.make(new AmbientVertexRemap[6], (p_111204_) -> { - p_111204_[Direction.DOWN.get3DDataValue()] = DOWN; - p_111204_[Direction.UP.get3DDataValue()] = UP; - p_111204_[Direction.NORTH.get3DDataValue()] = NORTH; - p_111204_[Direction.SOUTH.get3DDataValue()] = SOUTH; - p_111204_[Direction.WEST.get3DDataValue()] = WEST; - p_111204_[Direction.EAST.get3DDataValue()] = EAST; - }); - - private AmbientVertexRemap(int pVert0, int pVert1, int pVert2, int pVert3) { - this.vert0 = pVert0; - this.vert1 = pVert1; - this.vert2 = pVert2; - this.vert3 = pVert3; - } - - public static AmbientVertexRemap fromFacing(Direction pFacing) { - return BY_FACING[pFacing.get3DDataValue()]; - } - } - - @OnlyIn(Dist.CLIENT) - protected static enum SizeInfo { - DOWN(Direction.DOWN, false), - UP(Direction.UP, false), - NORTH(Direction.NORTH, false), - SOUTH(Direction.SOUTH, false), - WEST(Direction.WEST, false), - EAST(Direction.EAST, false), - FLIP_DOWN(Direction.DOWN, true), - FLIP_UP(Direction.UP, true), - FLIP_NORTH(Direction.NORTH, true), - FLIP_SOUTH(Direction.SOUTH, true), - FLIP_WEST(Direction.WEST, true), - FLIP_EAST(Direction.EAST, true); - - final int shape; - - private SizeInfo(Direction pDirection, boolean pFlip) { - this.shape = pDirection.get3DDataValue() + (pFlip ? Direction.values().length : 0); - } - } - - @OnlyIn(Dist.CLIENT) - static class Cache { - private boolean enabled; - private final Long2IntLinkedOpenHashMap colorCache = Util.make(() -> { - Long2IntLinkedOpenHashMap long2intlinkedopenhashmap = new Long2IntLinkedOpenHashMap(100, 0.25F) { - protected void rehash(int p_111238_) { - } - }; - long2intlinkedopenhashmap.defaultReturnValue(Integer.MAX_VALUE); - return long2intlinkedopenhashmap; - }); - private final Long2FloatLinkedOpenHashMap brightnessCache = Util.make(() -> { - Long2FloatLinkedOpenHashMap long2floatlinkedopenhashmap = new Long2FloatLinkedOpenHashMap(100, 0.25F) { - protected void rehash(int p_111245_) { - } - }; - long2floatlinkedopenhashmap.defaultReturnValue(Float.NaN); - return long2floatlinkedopenhashmap; - }); - - private Cache() { - } - - public void enable() { - this.enabled = true; - } - - public void disable() { - this.enabled = false; - this.colorCache.clear(); - this.brightnessCache.clear(); - } - - public int getLightColor(BlockState pState, BlockAndTintGetter pLevel, BlockPos pPos) { - long i = pPos.asLong(); - if (this.enabled) { - int j = this.colorCache.get(i); - if (j != Integer.MAX_VALUE) { - return j; - } - } - - int k = LevelRenderer.getLightColor(pLevel, pState, pPos); - if (this.enabled) { - if (this.colorCache.size() == 100) { - this.colorCache.removeFirstInt(); - } - - this.colorCache.put(i, k); - } - - return k; - } - - public float getShadeBrightness(BlockState pState, BlockAndTintGetter pLevel, BlockPos pPos) { - long i = pPos.asLong(); - if (this.enabled) { - float f = this.brightnessCache.get(i); - if (!Float.isNaN(f)) { - return f; - } - } - - float f1 = pState.getShadeBrightness(pLevel, pPos); - if (this.enabled) { - if (this.brightnessCache.size() == 100) { - this.brightnessCache.removeFirstFloat(); - } - - this.brightnessCache.put(i, f1); - } - - return f1; - } - } -} diff --git a/src/main/java/de/mrjulsen/trafficcraft/client/ClientEvents.java b/src/main/java/de/mrjulsen/trafficcraft/client/ClientEvents.java index 217e1077..b1871762 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/client/ClientEvents.java +++ b/src/main/java/de/mrjulsen/trafficcraft/client/ClientEvents.java @@ -1,15 +1,38 @@ package de.mrjulsen.trafficcraft.client; +import de.mrjulsen.trafficcraft.item.IScrollEventItem; import de.mrjulsen.trafficcraft.item.RoadConstructionTool; +import net.minecraft.client.Minecraft; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.world.item.ItemStack; import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.InputEvent; import net.minecraftforge.event.TickEvent.ClientTickEvent; +import net.minecraftforge.eventbus.api.EventPriority; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; @EventBusSubscriber(Dist.CLIENT) public class ClientEvents { + @SubscribeEvent public static void onTick(ClientTickEvent event) { RoadConstructionTool.clientTick(); } + + @SubscribeEvent(priority = EventPriority.HIGHEST) + @SuppressWarnings("resource") + public static void mouseScrollEvent(InputEvent.MouseScrollEvent event) { + LocalPlayer player = Minecraft.getInstance().player; + double scroll = event.getScrollDelta(); + + if (player == null || scroll == 0) { + return; + } + + ItemStack stack = player.getMainHandItem() == null ? player.getOffhandItem() : player.getMainHandItem(); + if (stack != null && stack.getItem() instanceof IScrollEventItem item) { + event.setCanceled(item.mouseScroll(player, stack, scroll, event.getMouseX(), event.getMouseY(), event.isRightDown(), event.isLeftDown(), event.isMiddleDown())); + } + } } diff --git a/src/main/java/de/mrjulsen/trafficcraft/client/ClientSetup.java b/src/main/java/de/mrjulsen/trafficcraft/client/ClientSetup.java new file mode 100644 index 00000000..ae9260b9 --- /dev/null +++ b/src/main/java/de/mrjulsen/trafficcraft/client/ClientSetup.java @@ -0,0 +1,40 @@ +package de.mrjulsen.trafficcraft.client; + +import java.util.Arrays; + +import de.mrjulsen.trafficcraft.ModMain; +import de.mrjulsen.trafficcraft.block.data.TrafficLightColor; +import de.mrjulsen.trafficcraft.block.data.TrafficLightIcon; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.inventory.InventoryMenu; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.TextureStitchEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod.EventBusSubscriber(modid = ModMain.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD) +public class ClientSetup { + + private static final String TEXTURE_PATH = "block/traffic_light"; + + @SubscribeEvent + public static void onTextureStitch(TextureStitchEvent.Pre event) { + if (!event.getAtlas().location().equals(InventoryMenu.BLOCK_ATLAS)) { + return; + } + + Arrays.stream(TrafficLightIcon.values()) + .forEach( + x -> Arrays.stream(TrafficLightColor.values()) + .filter(y -> x.isApplicableToColor(y)) + .forEach(y -> { + ResourceLocation loc = null; + if (x == TrafficLightIcon.NONE && y == TrafficLightColor.NONE) { + loc = new ResourceLocation(ModMain.MOD_ID, String.format("%s/off", TEXTURE_PATH)); + } else { + loc = new ResourceLocation(ModMain.MOD_ID, String.format("%s/%s_%s", TEXTURE_PATH, x.getName(), y.getName())); + } + event.addSprite(loc); + })); + } +} diff --git a/src/main/java/de/mrjulsen/trafficcraft/client/ClientWrapper.java b/src/main/java/de/mrjulsen/trafficcraft/client/ClientWrapper.java index a6d800a8..6520fc6c 100644 --- a/src/main/java/de/mrjulsen/trafficcraft/client/ClientWrapper.java +++ b/src/main/java/de/mrjulsen/trafficcraft/client/ClientWrapper.java @@ -2,22 +2,24 @@ import java.util.function.Supplier; +import de.mrjulsen.mcdragonlib.common.IIdentifiable; +import de.mrjulsen.mcdragonlib.utils.TimeUtils.TimeFormat; +import de.mrjulsen.trafficcraft.ModMain; import de.mrjulsen.trafficcraft.block.TownSignBlock; -import de.mrjulsen.trafficcraft.block.entity.IIdentifiable; import de.mrjulsen.trafficcraft.block.entity.TownSignBlockEntity; import de.mrjulsen.trafficcraft.block.entity.WritableTrafficSignBlockEntity; +import de.mrjulsen.trafficcraft.client.screen.TrafficLightConfigScreen; import de.mrjulsen.trafficcraft.client.screen.PaintBrushScreen; import de.mrjulsen.trafficcraft.client.screen.RoadConstructionToolScreen; import de.mrjulsen.trafficcraft.client.screen.StreetLampScheduleScreen; import de.mrjulsen.trafficcraft.client.screen.TownSignScreen; -import de.mrjulsen.trafficcraft.client.screen.TrafficLightConfigScreen; import de.mrjulsen.trafficcraft.client.screen.TrafficLightControllerScreen; import de.mrjulsen.trafficcraft.client.screen.TrafficSignPatternSelectionScreen; import de.mrjulsen.trafficcraft.client.screen.TrafficSignWorkbenchGui; import de.mrjulsen.trafficcraft.client.screen.WritableSignScreen; -import de.mrjulsen.trafficcraft.data.TimeFormat; -import de.mrjulsen.trafficcraft.network.packets.TrafficSignTextureResetPacket; -import de.mrjulsen.trafficcraft.network.packets.TrafficSignWorkbenchUpdateClientPacket; +import de.mrjulsen.trafficcraft.data.PaintColor; +import de.mrjulsen.trafficcraft.network.packets.stc.TrafficSignTextureResetPacket; +import de.mrjulsen.trafficcraft.network.packets.stc.TrafficSignWorkbenchUpdateClientPacket; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.world.item.ItemStack; @@ -26,8 +28,8 @@ public class ClientWrapper { - public static void showPaintBrushScreen(int pattern, int paint, int color, float scroll) { - Minecraft.getInstance().setScreen(new PaintBrushScreen(pattern, paint, color, scroll)); + public static void showPaintBrushScreen(int pattern, int paint, PaintColor color) { + Minecraft.getInstance().setScreen(new PaintBrushScreen(pattern, paint, color)); } public static void showSignPatternSelectionScreen(ItemStack stack) { @@ -38,8 +40,8 @@ public static void showStreetLampScheduleScreen(int turnOnTime, int turnOfftime, Minecraft.getInstance().setScreen(new StreetLampScheduleScreen(turnOnTime, turnOfftime, format)); } - public static void showTrafficLightConfigScreen(BlockPos pos, Level level) { - Minecraft.getInstance().setScreen(new TrafficLightConfigScreen(pos, level)); + public static void showTrafficLightConfigScreen(Level level, BlockPos pos) { + Minecraft.getInstance().setScreen(new TrafficLightConfigScreen(level, pos)); } public static void showTrafficLightControllerScreen(BlockPos pos, Level level) { @@ -63,14 +65,18 @@ public static void handleTrafficSignWorkbenchUpdateClientPacket(TrafficSignWorkb } public synchronized static void clearTexture(B id) { - TrafficSignTextureCacheClient.clear(id); + try { + TrafficSignTextureCacheClient.clear(id); + } catch (Exception e) { + ModMain.LOGGER.warn("Unable to clear texture.", e); + } } public static void handleTrafficSignTextureResetPacket(TrafficSignTextureResetPacket packet, Supplier ctx) { TrafficSignTextureCacheClient.clear(packet.id); } - public static void showRoadBuilderGadgetScreen(ItemStack itemstack, int blocksCount, int slopesCount) { + public static void showRoadConstructionToolScreen(ItemStack itemstack, int blocksCount, int slopesCount) { Minecraft.getInstance().setScreen(new RoadConstructionToolScreen(itemstack, blocksCount, slopesCount)); } } diff --git a/src/main/java/de/mrjulsen/trafficcraft/client/ModGuiUtils.java b/src/main/java/de/mrjulsen/trafficcraft/client/ModGuiUtils.java new file mode 100644 index 00000000..ecb0431c --- /dev/null +++ b/src/main/java/de/mrjulsen/trafficcraft/client/ModGuiUtils.java @@ -0,0 +1,131 @@ +package de.mrjulsen.trafficcraft.client; + +import de.mrjulsen.mcdragonlib.client.gui.DynamicGuiRenderer.AreaStyle; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.function.Consumer; + +import de.mrjulsen.mcdragonlib.client.gui.Sprite; +import de.mrjulsen.mcdragonlib.client.gui.Tooltip; +import de.mrjulsen.mcdragonlib.client.gui.WidgetsCollection; +import de.mrjulsen.mcdragonlib.client.gui.widgets.AbstractImageButton.ButtonType; +import de.mrjulsen.mcdragonlib.client.gui.widgets.IconButton; +import de.mrjulsen.trafficcraft.block.data.IIconEnum; +import net.minecraft.Util; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.screens.ConfirmLinkScreen; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.FormattedText; + +public class ModGuiUtils { + + public static IconButton createCopyButton(int x, int y, WidgetsCollection collection, AreaStyle style, Consumer