From d4a4254a3a03a0581ae8e04f834c6444c08e4453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AD=90=E6=82=A6=E8=A7=A3=E8=AF=B4?= Date: Thu, 8 Feb 2024 12:23:22 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=94=20Railway=20Sign=20Wall=20Double?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/ziyue/tjmetro/BlockEntityTypes.java | 4 + .../main/java/ziyue/tjmetro/BlockList.java | 5 + .../main/java/ziyue/tjmetro/TianjinMetro.java | 10 + .../ziyue/tjmetro/TianjinMetroClient.java | 5 + .../blocks/BlockRailwaySignWallDouble.java | 171 +++++++++ .../java/ziyue/tjmetro/packet/IPacket.java | 2 + .../ziyue/tjmetro/packet/PacketGuiClient.java | 10 + .../ziyue/tjmetro/packet/PacketGuiServer.java | 64 +++- .../tjmetro/render/RenderRailwaySignWall.java | 2 +- .../render/RenderRailwaySignWallDouble.java | 243 ++++++++++++ .../screen/RailwaySignWallDoubleScreen.java | 358 ++++++++++++++++++ .../railway_sign_wall_double_10.json | 7 + .../railway_sign_wall_double_4.json | 7 + .../railway_sign_wall_double_6.json | 7 + .../railway_sign_wall_double_8.json | 7 + .../railway_sign_wall_double_middle.json | 7 + .../resources/assets/tjmetro/lang/en_us.json | 5 +- .../block/railway_sign_tianjin_middle.json | 38 +- .../item/railway_sign_wall_double_10.json | 6 + .../item/railway_sign_wall_double_4.json | 6 + .../item/railway_sign_wall_double_6.json | 6 + .../item/railway_sign_wall_double_8.json | 6 + .../item/railway_sign_wall_double_10.png | Bin 0 -> 1858 bytes .../item/railway_sign_wall_double_4.png | Bin 0 -> 1848 bytes .../item/railway_sign_wall_double_6.png | Bin 0 -> 1847 bytes .../item/railway_sign_wall_double_8.png | Bin 0 -> 1844 bytes 26 files changed, 948 insertions(+), 28 deletions(-) create mode 100644 common/src/main/java/ziyue/tjmetro/blocks/BlockRailwaySignWallDouble.java create mode 100644 common/src/main/java/ziyue/tjmetro/render/RenderRailwaySignWallDouble.java create mode 100644 common/src/main/java/ziyue/tjmetro/screen/RailwaySignWallDoubleScreen.java create mode 100644 common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_10.json create mode 100644 common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_4.json create mode 100644 common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_6.json create mode 100644 common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_8.json create mode 100644 common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_middle.json create mode 100644 common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_10.json create mode 100644 common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_4.json create mode 100644 common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_6.json create mode 100644 common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_8.json create mode 100644 common/src/main/resources/assets/tjmetro/textures/item/railway_sign_wall_double_10.png create mode 100644 common/src/main/resources/assets/tjmetro/textures/item/railway_sign_wall_double_4.png create mode 100644 common/src/main/resources/assets/tjmetro/textures/item/railway_sign_wall_double_6.png create mode 100644 common/src/main/resources/assets/tjmetro/textures/item/railway_sign_wall_double_8.png diff --git a/common/src/main/java/ziyue/tjmetro/BlockEntityTypes.java b/common/src/main/java/ziyue/tjmetro/BlockEntityTypes.java index af22238..a5e9ef5 100644 --- a/common/src/main/java/ziyue/tjmetro/BlockEntityTypes.java +++ b/common/src/main/java/ziyue/tjmetro/BlockEntityTypes.java @@ -25,6 +25,10 @@ public interface BlockEntityTypes RegistryObject> RAILWAY_SIGN_WALL_6_TILE_ENTITY = new RegistryObject<>(() -> RegistryUtilities.getBlockEntityType((pos, state) -> new BlockRailwaySignWall.TileEntityRailwaySignWall(6, pos, state), BlockList.RAILWAY_SIGN_WALL_6.get())); RegistryObject> RAILWAY_SIGN_WALL_8_TILE_ENTITY = new RegistryObject<>(() -> RegistryUtilities.getBlockEntityType((pos, state) -> new BlockRailwaySignWall.TileEntityRailwaySignWall(8, pos, state), BlockList.RAILWAY_SIGN_WALL_8.get())); RegistryObject> RAILWAY_SIGN_WALL_10_TILE_ENTITY = new RegistryObject<>(() -> RegistryUtilities.getBlockEntityType((pos, state) -> new BlockRailwaySignWall.TileEntityRailwaySignWall(10, pos, state), BlockList.RAILWAY_SIGN_WALL_10.get())); + RegistryObject> RAILWAY_SIGN_WALL_DOUBLE_4_TILE_ENTITY = new RegistryObject<>(() -> RegistryUtilities.getBlockEntityType((pos, state) -> new BlockRailwaySignWallDouble.TileEntityRailwaySignWallDouble(4, pos, state), BlockList.RAILWAY_SIGN_WALL_DOUBLE_4.get())); + RegistryObject> RAILWAY_SIGN_WALL_DOUBLE_6_TILE_ENTITY = new RegistryObject<>(() -> RegistryUtilities.getBlockEntityType((pos, state) -> new BlockRailwaySignWallDouble.TileEntityRailwaySignWallDouble(6, pos, state), BlockList.RAILWAY_SIGN_WALL_DOUBLE_6.get())); + RegistryObject> RAILWAY_SIGN_WALL_DOUBLE_8_TILE_ENTITY = new RegistryObject<>(() -> RegistryUtilities.getBlockEntityType((pos, state) -> new BlockRailwaySignWallDouble.TileEntityRailwaySignWallDouble(8, pos, state), BlockList.RAILWAY_SIGN_WALL_DOUBLE_8.get())); + RegistryObject> RAILWAY_SIGN_WALL_DOUBLE_10_TILE_ENTITY = new RegistryObject<>(() -> RegistryUtilities.getBlockEntityType((pos, state) -> new BlockRailwaySignWallDouble.TileEntityRailwaySignWallDouble(10, pos, state), BlockList.RAILWAY_SIGN_WALL_DOUBLE_10.get())); RegistryObject> RAILWAY_SIGN_WALL_BIG_2_TILE_ENTITY = new RegistryObject<>(() -> RegistryUtilities.getBlockEntityType((pos, state) -> new BlockRailwaySignWallBig.TileEntityRailwaySignWallBig(2, pos, state), BlockList.RAILWAY_SIGN_WALL_BIG_2.get())); RegistryObject> RAILWAY_SIGN_WALL_BIG_3_TILE_ENTITY = new RegistryObject<>(() -> RegistryUtilities.getBlockEntityType((pos, state) -> new BlockRailwaySignWallBig.TileEntityRailwaySignWallBig(3, pos, state), BlockList.RAILWAY_SIGN_WALL_BIG_3.get())); RegistryObject> RAILWAY_SIGN_WALL_BIG_4_TILE_ENTITY = new RegistryObject<>(() -> RegistryUtilities.getBlockEntityType((pos, state) -> new BlockRailwaySignWallBig.TileEntityRailwaySignWallBig(4, pos, state), BlockList.RAILWAY_SIGN_WALL_BIG_4.get())); diff --git a/common/src/main/java/ziyue/tjmetro/BlockList.java b/common/src/main/java/ziyue/tjmetro/BlockList.java index 0c57fe0..c6eb986 100644 --- a/common/src/main/java/ziyue/tjmetro/BlockList.java +++ b/common/src/main/java/ziyue/tjmetro/BlockList.java @@ -54,6 +54,11 @@ public interface BlockList RegistryObject RAILWAY_SIGN_WALL_8 = new RegistryObject<>(() -> new BlockRailwaySignWall(8)); RegistryObject RAILWAY_SIGN_WALL_10 = new RegistryObject<>(() -> new BlockRailwaySignWall(10)); RegistryObject RAILWAY_SIGN_WALL_MIDDLE = new RegistryObject<>(() -> new BlockRailwaySignWall(0)); + RegistryObject RAILWAY_SIGN_WALL_DOUBLE_4 = new RegistryObject<>(() -> new BlockRailwaySignWallDouble(4)); + RegistryObject RAILWAY_SIGN_WALL_DOUBLE_6 = new RegistryObject<>(() -> new BlockRailwaySignWallDouble(6)); + RegistryObject RAILWAY_SIGN_WALL_DOUBLE_8 = new RegistryObject<>(() -> new BlockRailwaySignWallDouble(8)); + RegistryObject RAILWAY_SIGN_WALL_DOUBLE_10 = new RegistryObject<>(() -> new BlockRailwaySignWallDouble(10)); + RegistryObject RAILWAY_SIGN_WALL_DOUBLE_MIDDLE = new RegistryObject<>(() -> new BlockRailwaySignWallDouble(0)); RegistryObject RAILWAY_SIGN_WALL_BIG_2 = new RegistryObject<>(() -> new BlockRailwaySignWallBig(2)); RegistryObject RAILWAY_SIGN_WALL_BIG_3 = new RegistryObject<>(() -> new BlockRailwaySignWallBig(3)); RegistryObject RAILWAY_SIGN_WALL_BIG_4 = new RegistryObject<>(() -> new BlockRailwaySignWallBig(4)); diff --git a/common/src/main/java/ziyue/tjmetro/TianjinMetro.java b/common/src/main/java/ziyue/tjmetro/TianjinMetro.java index 614954d..e692c21 100644 --- a/common/src/main/java/ziyue/tjmetro/TianjinMetro.java +++ b/common/src/main/java/ziyue/tjmetro/TianjinMetro.java @@ -80,6 +80,10 @@ public static void init( registerBlockItem.accept("railway_sign_wall_6", BlockList.RAILWAY_SIGN_WALL_6, RAILWAYS); registerBlockItem.accept("railway_sign_wall_8", BlockList.RAILWAY_SIGN_WALL_8, RAILWAYS); registerBlockItem.accept("railway_sign_wall_10", BlockList.RAILWAY_SIGN_WALL_10, RAILWAYS); + registerBlockItem.accept("railway_sign_wall_double_4", BlockList.RAILWAY_SIGN_WALL_DOUBLE_4, RAILWAYS); + registerBlockItem.accept("railway_sign_wall_double_6", BlockList.RAILWAY_SIGN_WALL_DOUBLE_6, RAILWAYS); + registerBlockItem.accept("railway_sign_wall_double_8", BlockList.RAILWAY_SIGN_WALL_DOUBLE_8, RAILWAYS); + registerBlockItem.accept("railway_sign_wall_double_10", BlockList.RAILWAY_SIGN_WALL_DOUBLE_10, RAILWAYS); registerBlockItem.accept("railway_sign_wall_big_2", BlockList.RAILWAY_SIGN_WALL_BIG_2, RAILWAYS); registerBlockItem.accept("railway_sign_wall_big_3", BlockList.RAILWAY_SIGN_WALL_BIG_3, RAILWAYS); registerBlockItem.accept("railway_sign_wall_big_4", BlockList.RAILWAY_SIGN_WALL_BIG_4, RAILWAYS); @@ -105,6 +109,7 @@ public static void init( registerBlock.accept("railway_sign_wall_middle", BlockList.RAILWAY_SIGN_WALL_MIDDLE); registerBlock.accept("railway_sign_wall_big_middle", BlockList.RAILWAY_SIGN_WALL_BIG_MIDDLE); + registerBlock.accept("railway_sign_wall_double_middle", BlockList.RAILWAY_SIGN_WALL_DOUBLE_MIDDLE); registerBlock.accept("railway_sign_tianjin_middle", BlockList.RAILWAY_SIGN_TIANJIN_MIDDLE); registerBlockEntityType.accept("station_name_sign_2", BlockEntityTypes.STATION_NAME_SIGN_ENTITY_2); @@ -121,6 +126,10 @@ public static void init( registerBlockEntityType.accept("railway_sign_wall_6", BlockEntityTypes.RAILWAY_SIGN_WALL_6_TILE_ENTITY); registerBlockEntityType.accept("railway_sign_wall_8", BlockEntityTypes.RAILWAY_SIGN_WALL_8_TILE_ENTITY); registerBlockEntityType.accept("railway_sign_wall_10", BlockEntityTypes.RAILWAY_SIGN_WALL_10_TILE_ENTITY); + registerBlockEntityType.accept("railway_sign_wall_double_4", BlockEntityTypes.RAILWAY_SIGN_WALL_DOUBLE_4_TILE_ENTITY); + registerBlockEntityType.accept("railway_sign_wall_double_6", BlockEntityTypes.RAILWAY_SIGN_WALL_DOUBLE_6_TILE_ENTITY); + registerBlockEntityType.accept("railway_sign_wall_double_8", BlockEntityTypes.RAILWAY_SIGN_WALL_DOUBLE_8_TILE_ENTITY); + registerBlockEntityType.accept("railway_sign_wall_double_10", BlockEntityTypes.RAILWAY_SIGN_WALL_DOUBLE_10_TILE_ENTITY); registerBlockEntityType.accept("railway_sign_wall_big_2", BlockEntityTypes.RAILWAY_SIGN_WALL_BIG_2_TILE_ENTITY); registerBlockEntityType.accept("railway_sign_wall_big_3", BlockEntityTypes.RAILWAY_SIGN_WALL_BIG_3_TILE_ENTITY); registerBlockEntityType.accept("railway_sign_wall_big_4", BlockEntityTypes.RAILWAY_SIGN_WALL_BIG_4_TILE_ENTITY); @@ -149,6 +158,7 @@ public static void init( mtr.Registry.registerNetworkReceiver(PACKET_UPDATE_CUSTOM_CONTENT, PacketGuiServer::receiveCustomContentC2S); mtr.Registry.registerNetworkReceiver(PACKET_UPDATE_CUSTOM_COLOR, PacketGuiServer::receiveCustomColorC2S); mtr.Registry.registerNetworkReceiver(PACKET_SIGN_TYPES, PacketGuiServer::receiveSignIdsC2S); + mtr.Registry.registerNetworkReceiver(PACKET_SIGN_TYPES_DOUBLE, PacketGuiServer::receiveSignIdsDoubleC2S); } @FunctionalInterface diff --git a/common/src/main/java/ziyue/tjmetro/TianjinMetroClient.java b/common/src/main/java/ziyue/tjmetro/TianjinMetroClient.java index bc2ce88..e87c831 100644 --- a/common/src/main/java/ziyue/tjmetro/TianjinMetroClient.java +++ b/common/src/main/java/ziyue/tjmetro/TianjinMetroClient.java @@ -49,6 +49,10 @@ public static void init() { RegistryClient.registerTileEntityRenderer(BlockEntityTypes.RAILWAY_SIGN_WALL_6_TILE_ENTITY.get(), RenderRailwaySignWall::new); RegistryClient.registerTileEntityRenderer(BlockEntityTypes.RAILWAY_SIGN_WALL_8_TILE_ENTITY.get(), RenderRailwaySignWall::new); RegistryClient.registerTileEntityRenderer(BlockEntityTypes.RAILWAY_SIGN_WALL_10_TILE_ENTITY.get(), RenderRailwaySignWall::new); + RegistryClient.registerTileEntityRenderer(BlockEntityTypes.RAILWAY_SIGN_WALL_DOUBLE_4_TILE_ENTITY.get(), RenderRailwaySignWallDouble::new); + RegistryClient.registerTileEntityRenderer(BlockEntityTypes.RAILWAY_SIGN_WALL_DOUBLE_6_TILE_ENTITY.get(), RenderRailwaySignWallDouble::new); + RegistryClient.registerTileEntityRenderer(BlockEntityTypes.RAILWAY_SIGN_WALL_DOUBLE_8_TILE_ENTITY.get(), RenderRailwaySignWallDouble::new); + RegistryClient.registerTileEntityRenderer(BlockEntityTypes.RAILWAY_SIGN_WALL_DOUBLE_10_TILE_ENTITY.get(), RenderRailwaySignWallDouble::new); RegistryClient.registerTileEntityRenderer(BlockEntityTypes.RAILWAY_SIGN_WALL_BIG_2_TILE_ENTITY.get(), RenderRailwaySignWall::new); RegistryClient.registerTileEntityRenderer(BlockEntityTypes.RAILWAY_SIGN_WALL_BIG_3_TILE_ENTITY.get(), RenderRailwaySignWall::new); RegistryClient.registerTileEntityRenderer(BlockEntityTypes.RAILWAY_SIGN_WALL_BIG_4_TILE_ENTITY.get(), RenderRailwaySignWall::new); @@ -75,5 +79,6 @@ public static void init() { RegistryClient.registerNetworkReceiver(IPacket.PACKET_OPEN_CUSTOM_CONTENT_SCREEN, packet -> PacketGuiClient.openCustomContentScreenS2C(Minecraft.getInstance(), packet)); RegistryClient.registerNetworkReceiver(IPacket.PACKET_OPEN_CUSTOM_COLOR_SCREEN, packet -> PacketGuiClient.openCustomColorScreenS2C(Minecraft.getInstance(), packet)); RegistryClient.registerNetworkReceiver(IPacket.PACKET_OPEN_RAILWAY_SIGN_SCREEN, packet -> PacketGuiClient.openRailwaySignScreenS2C(Minecraft.getInstance(), packet)); + RegistryClient.registerNetworkReceiver(IPacket.PACKET_OPEN_RAILWAY_SIGN_WALL_DOUBLE_SCREEN, packet -> PacketGuiClient.openRailwaySignWallDoubleScreenS2C(Minecraft.getInstance(), packet)); } } diff --git a/common/src/main/java/ziyue/tjmetro/blocks/BlockRailwaySignWallDouble.java b/common/src/main/java/ziyue/tjmetro/blocks/BlockRailwaySignWallDouble.java new file mode 100644 index 0000000..4f756e1 --- /dev/null +++ b/common/src/main/java/ziyue/tjmetro/blocks/BlockRailwaySignWallDouble.java @@ -0,0 +1,171 @@ +package ziyue.tjmetro.blocks; + +import mtr.block.IBlock; +import mtr.mappings.BlockEntityClientSerializableMapper; +import mtr.mappings.BlockEntityMapper; +import mtr.mappings.Text; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import ziyue.tjmetro.BlockEntityTypes; +import ziyue.tjmetro.BlockList; +import ziyue.tjmetro.blocks.base.BlockRailwaySignBase; +import ziyue.tjmetro.blocks.base.IRailwaySign; +import ziyue.tjmetro.packet.PacketGuiServer; + +import java.util.*; + +/** + * Railway Sign Wall, must be even. + * + * @author ZiYueCommentary + * @see BlockRailwaySignBase + * @see BlockRailwaySignWall + * @see BlockRailwaySignWallBig + * @since beta-1 + */ + +public class BlockRailwaySignWallDouble extends BlockRailwaySignWall +{ + public BlockRailwaySignWallDouble(int length) { + super(length); + } + + @Override + public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand interactionHand, BlockHitResult hit) { + final Direction facing = IBlock.getStatePropertySafe(state, FACING); + final BlockPos checkPos = findEndWithDirection(world, pos, facing, false); + return IBlock.checkHoldingBrush(world, player, () -> { + if (checkPos != null) { + PacketGuiServer.openRailwaySignWallDoubleScreenS2C((ServerPlayer) player, checkPos); + } + }); + } + + @Override + public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) { + if (world.isClientSide) return; + final Direction facing = IBlock.getStatePropertySafe(state, FACING); + for (int i = 1; i < getMiddleLength(); i++) { + world.setBlock(pos.relative(facing.getClockWise(), i), BlockList.RAILWAY_SIGN_WALL_DOUBLE_MIDDLE.get().defaultBlockState().setValue(FACING, facing).setValue(EOS, false), 3); + } + world.setBlock(pos.relative(facing.getClockWise(), getMiddleLength()), BlockList.RAILWAY_SIGN_WALL_DOUBLE_MIDDLE.get().defaultBlockState().setValue(FACING, facing).setValue(EOS, true), 3); + world.updateNeighborsAt(pos, Blocks.AIR); + state.updateNeighbourShapes(world, pos, 3); + } + + @Override + public BlockState updateShape(BlockState state, Direction direction, BlockState newState, LevelAccessor world, BlockPos pos, BlockPos posFrom) { + final Direction facing = IBlock.getStatePropertySafe(state, FACING); + final boolean isNext = ((!state.getValue(EOS) && (direction == facing.getClockWise())) || state.is(BlockList.RAILWAY_SIGN_WALL_DOUBLE_MIDDLE.get())) && (direction == facing.getCounterClockWise()); + if (isNext && !(newState.getBlock() instanceof BlockRailwaySignBase)) { + return Blocks.AIR.defaultBlockState(); + } else { + return state; + } + } + + @Override + protected BlockPos findEndWithDirection(Level world, BlockPos startPos, Direction direction, boolean allowOpposite) { + return IRailwaySign.findEndWithDirection(world, startPos, direction, allowOpposite, BlockList.RAILWAY_SIGN_WALL_DOUBLE_MIDDLE.get()); + } + + @Override + public String getDescriptionId() { + return "block.tjmetro.railway_sign_wall_double"; + } + + @Override + public BlockEntityMapper createBlockEntity(BlockPos pos, BlockState state) { + if (this == BlockList.RAILWAY_SIGN_WALL_DOUBLE_MIDDLE.get()) + return null; + else + return new TileEntityRailwaySignWallDouble(length, pos, state); + } + + public static class TileEntityRailwaySignWallDouble extends BlockEntityClientSerializableMapper + { + protected final List> selectedIds; + protected final String[][] signIds; + protected static final String KEY_SELECTED_IDS = "selected_ids"; + protected static final String KEY_SIGN_LENGTH = "sign_length"; + + public TileEntityRailwaySignWallDouble(int length, BlockPos pos, BlockState state) { + super(getType(length), pos, state); + signIds = new String[2][length]; + selectedIds = new ArrayList<>(); + selectedIds.add(new HashSet<>()); + selectedIds.add(new HashSet<>()); + } + + @Override + public void readCompoundTag(CompoundTag compoundTag) { + selectedIds.forEach(Set::clear); + for (int i = 0; i < 2; i++) { + Arrays.stream(compoundTag.getLongArray(KEY_SELECTED_IDS + i)).forEach(selectedIds.get(i)::add); + for (int j = 0; j < signIds[i].length; j++) { + final String signId = compoundTag.getString(KEY_SIGN_LENGTH + i + j); + signIds[i][j] = signId.isEmpty() ? null : signId; + } + } + } + + @Override + public void writeCompoundTag(CompoundTag compoundTag) { + for (int i = 0; i < 2; i++) { + compoundTag.putLongArray(KEY_SELECTED_IDS + i, new ArrayList<>(selectedIds.get(i))); + for (int j = 0; j < signIds[i].length; j++) { + compoundTag.putString(KEY_SIGN_LENGTH + i + j, signIds[i][j] == null ? "" : signIds[i][j]); + } + } + } + + public void setData(List> selectedIds, String[][] signTypes) { + this.selectedIds.forEach(Set::clear); + this.selectedIds.addAll(selectedIds); + if (signIds[0].length == signTypes[0].length) { // Both lines have the same length + System.arraycopy(signTypes, 0, signIds, 0, signTypes.length); + } + setChanged(); + syncData(); + } + + public List> getSelectedIds() { + return selectedIds; + } + + public String[][] getSignIds() { + return signIds; + } + + protected static BlockEntityType getType(int length) { + return switch (length) { + case 4 -> BlockEntityTypes.RAILWAY_SIGN_WALL_DOUBLE_4_TILE_ENTITY.get(); + case 6 -> BlockEntityTypes.RAILWAY_SIGN_WALL_DOUBLE_6_TILE_ENTITY.get(); + case 8 -> BlockEntityTypes.RAILWAY_SIGN_WALL_DOUBLE_8_TILE_ENTITY.get(); + case 10 -> BlockEntityTypes.RAILWAY_SIGN_WALL_DOUBLE_10_TILE_ENTITY.get(); + default -> null; + }; + } + } +} diff --git a/common/src/main/java/ziyue/tjmetro/packet/IPacket.java b/common/src/main/java/ziyue/tjmetro/packet/IPacket.java index 6da6c9c..5d8da58 100644 --- a/common/src/main/java/ziyue/tjmetro/packet/IPacket.java +++ b/common/src/main/java/ziyue/tjmetro/packet/IPacket.java @@ -15,5 +15,7 @@ public interface IPacket ResourceLocation PACKET_OPEN_CUSTOM_COLOR_SCREEN = new ResourceLocation(Reference.MOD_ID, "packet_open_custom_color_screen"); ResourceLocation PACKET_UPDATE_CUSTOM_COLOR = new ResourceLocation(Reference.MOD_ID, "packet_update_custom_color_screen"); ResourceLocation PACKET_OPEN_RAILWAY_SIGN_SCREEN = new ResourceLocation(Reference.MOD_ID, "packet_open_railway_sign_screen"); + ResourceLocation PACKET_OPEN_RAILWAY_SIGN_WALL_DOUBLE_SCREEN = new ResourceLocation(Reference.MOD_ID, "packet_open_railway_sign_wall_double_screen"); ResourceLocation PACKET_SIGN_TYPES = new ResourceLocation(MTR.MOD_ID, "packet_sign_types"); + ResourceLocation PACKET_SIGN_TYPES_DOUBLE = new ResourceLocation(MTR.MOD_ID, "packet_sign_types_double"); } diff --git a/common/src/main/java/ziyue/tjmetro/packet/PacketGuiClient.java b/common/src/main/java/ziyue/tjmetro/packet/PacketGuiClient.java index 7609da4..35fd7e6 100644 --- a/common/src/main/java/ziyue/tjmetro/packet/PacketGuiClient.java +++ b/common/src/main/java/ziyue/tjmetro/packet/PacketGuiClient.java @@ -12,6 +12,7 @@ import ziyue.tjmetro.screen.ColorPickerScreen; import ziyue.tjmetro.screen.CustomContentScreen; import ziyue.tjmetro.screen.RailwaySignScreen; +import ziyue.tjmetro.screen.RailwaySignWallDoubleScreen; import static ziyue.tjmetro.packet.IPacket.*; @@ -68,4 +69,13 @@ public static void openRailwaySignScreenS2C(Minecraft minecraftClient, FriendlyB } }); } + + public static void openRailwaySignWallDoubleScreenS2C(Minecraft minecraftClient, FriendlyByteBuf packet) { + final BlockPos pos = packet.readBlockPos(); + minecraftClient.execute(() -> { + if (!(minecraftClient.screen instanceof RailwaySignScreen)) { + UtilitiesClient.setScreen(minecraftClient, new RailwaySignWallDoubleScreen(pos)); + } + }); + } } diff --git a/common/src/main/java/ziyue/tjmetro/packet/PacketGuiServer.java b/common/src/main/java/ziyue/tjmetro/packet/PacketGuiServer.java index 09e0413..ae6c69f 100644 --- a/common/src/main/java/ziyue/tjmetro/packet/PacketGuiServer.java +++ b/common/src/main/java/ziyue/tjmetro/packet/PacketGuiServer.java @@ -14,11 +14,14 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.level.block.entity.BlockEntity; +import ziyue.tjmetro.blocks.BlockRailwaySignWallDouble; import ziyue.tjmetro.blocks.base.BlockCustomColorBase; import ziyue.tjmetro.blocks.base.BlockCustomContentBlockBase; import ziyue.tjmetro.blocks.base.BlockRailwaySignBase; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; import java.util.function.Consumer; @@ -98,20 +101,69 @@ public static void receiveSignIdsC2S(MinecraftServer minecraftServer, ServerPlay minecraftServer.execute(() -> { final BlockEntity entity = player.level.getBlockEntity(signPos); - if (entity instanceof BlockRailwaySignBase.TileEntityRailwaySign) { - setTileEntityDataAndWriteUpdate(player, entity2 -> entity2.setData(selectedIds, signIds), (BlockRailwaySignBase.TileEntityRailwaySign) entity); - } else if (entity instanceof BlockRouteSignBase.TileEntityRouteSignBase) { + if (entity instanceof BlockRailwaySignBase.TileEntityRailwaySign entity1) { + setTileEntityDataAndWriteUpdate(player, entity2 -> entity2.setData(selectedIds, signIds), entity1); + } else if (entity instanceof BlockRouteSignBase.TileEntityRouteSignBase entity1) { final long platformId = selectedIds.isEmpty() ? 0 : (long) selectedIds.toArray()[0]; final BlockEntity entityAbove = player.level.getBlockEntity(signPos.above()); - if (entityAbove instanceof BlockRouteSignBase.TileEntityRouteSignBase) { - setTileEntityDataAndWriteUpdate(player, entity2 -> entity2.setPlatformId(platformId), ((BlockRouteSignBase.TileEntityRouteSignBase) entityAbove), (BlockRouteSignBase.TileEntityRouteSignBase) entity); + if (entityAbove instanceof BlockRouteSignBase.TileEntityRouteSignBase entity2) { + setTileEntityDataAndWriteUpdate(player, entity3 -> entity3.setPlatformId(platformId), entity2, entity1); } else { - setTileEntityDataAndWriteUpdate(player, entity2 -> entity2.setPlatformId(platformId), (BlockRouteSignBase.TileEntityRouteSignBase) entity); + setTileEntityDataAndWriteUpdate(player, entity2 -> entity2.setPlatformId(platformId), entity1); } } }); } + public static void openRailwaySignWallDoubleScreenS2C(ServerPlayer player, BlockPos signPos) { + final FriendlyByteBuf packet = new FriendlyByteBuf(Unpooled.buffer()); + packet.writeBlockPos(signPos); + Registry.sendToPlayer(player, PACKET_OPEN_RAILWAY_SIGN_WALL_DOUBLE_SCREEN, packet); + } + + public static void sendSignIdsDoubleC2S(BlockPos signPos, List> selectedIds, String[][] signIds) { + final FriendlyByteBuf packet = new FriendlyByteBuf(Unpooled.buffer()); + packet.writeBlockPos(signPos); + packet.writeInt(selectedIds.get(0).size()); + selectedIds.forEach(line -> line.forEach(packet::writeLong)); + packet.writeInt(signIds[0].length); + for (int i = 0; i < 2; i++) { + for (final String signType : signIds[i]) { + packet.writeUtf(signType == null ? "" : signType); + } + } + RegistryClient.sendToServer(PACKET_SIGN_TYPES_DOUBLE, packet); + } + + public static void receiveSignIdsDoubleC2S(MinecraftServer minecraftServer, ServerPlayer player, FriendlyByteBuf packet) { + final BlockPos signPos = packet.readBlockPos(); + final int selectedIdsLength = packet.readInt(); + final List> selectedIds = new ArrayList<>(); + selectedIds.add(new HashSet<>()); + selectedIds.add(new HashSet<>()); + for (int i = 0; i < 2; i++) { + for (int j = 0; j < selectedIdsLength; j++) { + selectedIds.get(i).add(packet.readLong()); + } + } + final int signLength = packet.readInt(); + final String[][] signIds = new String[2][signLength]; + for (int i = 0; i < 2; i++) { + for (int j = 0; j < signLength; j++) { + final String signId = packet.readUtf(SerializedDataBase.PACKET_STRING_READ_LENGTH); + signIds[i][j] = signId.isEmpty() ? null : signId; + } + } + + minecraftServer.execute(() -> { + final BlockEntity entity = player.level.getBlockEntity(signPos); + if (entity instanceof BlockRailwaySignWallDouble.TileEntityRailwaySignWallDouble sign) { + setTileEntityDataAndWriteUpdate(player, entity2 -> entity2.setData(selectedIds, signIds), sign); + } + }); + } + + @SafeVarargs public static void setTileEntityDataAndWriteUpdate(ServerPlayer player, Consumer setData, T... entities) { final RailwayData railwayData = RailwayData.getInstance(player.level); diff --git a/common/src/main/java/ziyue/tjmetro/render/RenderRailwaySignWall.java b/common/src/main/java/ziyue/tjmetro/render/RenderRailwaySignWall.java index 6115d2c..5eec919 100644 --- a/common/src/main/java/ziyue/tjmetro/render/RenderRailwaySignWall.java +++ b/common/src/main/java/ziyue/tjmetro/render/RenderRailwaySignWall.java @@ -79,7 +79,7 @@ public void render(T entity, float tickDelta, PoseStack matrices, MultiBufferSou matrices.mulPose(Vector3f.ZP.rotationDegrees(180)); matrices.translate(block.getXStart() / 16F - 0.5, -0.25, 0.493); if (entity.isBig()) { - matrices.translate(0, -0.2, -0.03); + matrices.translate(0, -0.218, -0.007); matrices.scale(2, 2, 2); } diff --git a/common/src/main/java/ziyue/tjmetro/render/RenderRailwaySignWallDouble.java b/common/src/main/java/ziyue/tjmetro/render/RenderRailwaySignWallDouble.java new file mode 100644 index 0000000..593111e --- /dev/null +++ b/common/src/main/java/ziyue/tjmetro/render/RenderRailwaySignWallDouble.java @@ -0,0 +1,243 @@ +package ziyue.tjmetro.render; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.Tesselator; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Vector3f; +import mtr.block.BlockRailwaySign; +import mtr.block.BlockStationNameBase; +import mtr.block.IBlock; +import mtr.client.ClientCache; +import mtr.client.ClientData; +import mtr.client.CustomResources; +import mtr.client.IDrawing; +import mtr.data.IGui; +import mtr.data.Platform; +import mtr.data.RailwayData; +import mtr.data.Station; +import mtr.mappings.BlockEntityRendererMapper; +import mtr.render.MoreRenderLayers; +import mtr.render.RenderRailwaySign; +import mtr.render.RenderTrains; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.state.BlockState; +import ziyue.tjmetro.blocks.BlockRailwaySignWall; +import ziyue.tjmetro.blocks.BlockRailwaySignWallDouble; +import ziyue.tjmetro.blocks.base.BlockRailwaySignBase; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author ZiYueCommentary + * @see RenderRailwaySign + * @since beta-1 + */ + +public class RenderRailwaySignWallDouble extends BlockEntityRendererMapper implements IBlock, IGui, IDrawing +{ + public static final int HEIGHT_TO_SCALE = 27; + + public RenderRailwaySignWallDouble(BlockEntityRenderDispatcher dispatcher) { + super(dispatcher); + } + + @Override + public void render(T entity, float tickDelta, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay) { + final BlockGetter world = entity.getLevel(); + if (world == null) return; + + final BlockPos pos = entity.getBlockPos(); + final BlockState state = world.getBlockState(pos); + if (!(state.getBlock() instanceof BlockRailwaySignWallDouble block)) return; + if (entity.getSignIds()[0].length != block.length) return; + final Direction facing = IBlock.getStatePropertySafe(state, BlockStationNameBase.FACING); + final String[][] signIds = entity.getSignIds(); + int[] backgroundColor = new int[2]; + for (int i = 0; i < 2; i++) { + for (final String signId : signIds[i]) { + if (signId != null) { + final CustomResources.CustomSign sign = RenderRailwaySign.getSign(signId); + if (sign != null) { + if (sign.backgroundColor != 0) { + backgroundColor[i] = sign.backgroundColor; + break; + } + } + } + } + } + + matrices.pushPose(); + matrices.translate(0.5, 0.53125, 0.5); + matrices.mulPose(Vector3f.YP.rotationDegrees(-facing.toYRot())); + matrices.mulPose(Vector3f.ZP.rotationDegrees(180)); + matrices.translate(block.getXStart() / 16F - 0.5, -0.468, 0.493); + + final VertexConsumer vertexConsumer = vertexConsumers.getBuffer(MoreRenderLayers.getLight(new ResourceLocation("mtr:textures/block/white.png"), false)); + IDrawing.drawTexture(matrices, vertexConsumer, 0, 0F, SMALL_OFFSET * 2, 0.5F * (signIds[0].length), 0.5F, SMALL_OFFSET * 2, facing, backgroundColor[0] | ARGB_BLACK, MAX_LIGHT_GLOWING); + IDrawing.drawTexture(matrices, vertexConsumer, 0, 0.5F, SMALL_OFFSET * 2, 0.5F * (signIds[1].length), 1F, SMALL_OFFSET * 2, facing, backgroundColor[1] | ARGB_BLACK, MAX_LIGHT_GLOWING); + for (int i = 0; i < 2; i++) { + for (int j = 0; j < signIds[i].length; j++) { + if (signIds[i][j] != null) { + drawSign(matrices, vertexConsumers, Minecraft.getInstance().font, pos, signIds[i][j], 0.5F * j, 0, 0.5F, RenderRailwaySign.getMaxWidth(signIds[i], j, false), RenderRailwaySign.getMaxWidth(signIds[i], j, true), entity.getSelectedIds().get(i), facing, backgroundColor[i] | ARGB_BLACK, (textureId, x, y, size, flipTexture) -> { + final VertexConsumer vertexConsumer1 = vertexConsumers.getBuffer(MoreRenderLayers.getLight(new ResourceLocation(textureId.toString()), true)); + IDrawing.drawTexture(matrices, vertexConsumer1, x, y, size, size, flipTexture ? 1 : 0, 0, flipTexture ? 0 : 1, 1, facing, -1, MAX_LIGHT_GLOWING); + }); + } + } + matrices.translate(0, 0.5, 0); + } + + matrices.popPose(); + } + + @Override + public boolean shouldRenderOffScreen(T blockEntity) { + return true; + } + + public static void drawSign(PoseStack matrices, MultiBufferSource vertexConsumers, Font textRenderer, BlockPos pos, String signId, float x, float y, float size, float maxWidthLeft, float maxWidthRight, Set selectedIds, Direction facing, int backgroundColor, RenderRailwaySign.DrawTexture drawTexture) { + if (RenderTrains.shouldNotRender(pos, RenderTrains.maxTrainRenderDistance, facing)) return; + + final CustomResources.CustomSign sign = RenderRailwaySign.getSign(signId); + if (sign == null) return; + + final float signSize = (sign.small ? BlockRailwaySignBase.SMALL_SIGN_PERCENTAGE : 1) * size; + final float margin = (size - signSize) / 2; + + final boolean hasCustomText = sign.hasCustomText(); + final boolean flipCustomText = sign.flipCustomText; + final boolean flipTexture = sign.flipTexture; + final boolean isExit = signId.equals(BlockRailwaySign.SignType.EXIT_LETTER.toString()) || signId.equals(BlockRailwaySign.SignType.EXIT_LETTER_FLIPPED.toString()); + final boolean isLine = signId.equals(BlockRailwaySign.SignType.LINE.toString()) || signId.equals(BlockRailwaySign.SignType.LINE_FLIPPED.toString()); + final boolean isPlatform = signId.equals(BlockRailwaySign.SignType.PLATFORM.toString()) || signId.equals(BlockRailwaySign.SignType.PLATFORM_FLIPPED.toString()); + + final MultiBufferSource.BufferSource immediate = RenderTrains.shouldNotRender(pos, RenderTrains.maxTrainRenderDistance / 2, null) ? null : MultiBufferSource.immediate(Tesselator.getInstance().getBuilder()); + + if (vertexConsumers != null && isExit) { + final Station station = RailwayData.getStation(ClientData.STATIONS, ClientData.DATA_CACHE, pos); + if (station == null) return; + + final Map> exits = station.getGeneratedExits(); + final List selectedExitsSorted = selectedIds.stream().map(Station::deserializeExit).filter(exits::containsKey).sorted(String::compareTo).collect(Collectors.toList()); + + matrices.pushPose(); + matrices.translate(x + margin + (flipCustomText ? signSize : 0), y + margin, 0); + final float maxWidth = ((flipCustomText ? maxWidthLeft : maxWidthRight) + 1) * size - margin * 2; + final float exitWidth = signSize * selectedExitsSorted.size(); + matrices.scale(Math.min(1, maxWidth / exitWidth), 1, 1); + + final VertexConsumer vertexConsumer = vertexConsumers.getBuffer(MoreRenderLayers.getLight(new ResourceLocation("mtr:textures/block/sign/exit_letter_blank.png"), true)); + + for (int i = 0; i < selectedExitsSorted.size(); i++) { + final String selectedExit = selectedExitsSorted.get(flipCustomText ? selectedExitsSorted.size() - i - 1 : i); + final float offset = (flipCustomText ? -1 : 1) * signSize * i - (flipCustomText ? signSize : 0); + + IDrawing.drawTexture(matrices, vertexConsumer, offset, 0, SMALL_OFFSET, offset + signSize, signSize, SMALL_OFFSET, facing, -1, MAX_LIGHT_GLOWING); + + final String selectedExitLetter = selectedExit.substring(0, 1); + final String selectedExitNumber = selectedExit.substring(1); + final boolean hasNumber = !selectedExitNumber.isEmpty(); + final float space = hasNumber ? margin * 1.5F : 0; + IDrawing.drawStringWithFont(matrices, textRenderer, immediate, selectedExitLetter, hasNumber ? HorizontalAlignment.LEFT : HorizontalAlignment.CENTER, VerticalAlignment.CENTER, offset + (hasNumber ? margin : signSize / 2), signSize / 2 + margin, signSize - margin * 2 - space, signSize - margin, 1, ARGB_WHITE, false, MAX_LIGHT_GLOWING, null); + if (hasNumber) { + IDrawing.drawStringWithFont(matrices, textRenderer, immediate, selectedExitNumber, HorizontalAlignment.RIGHT, VerticalAlignment.TOP, offset + signSize - margin, signSize / 2, space, signSize / 2 - margin / 4, 1, ARGB_WHITE, false, MAX_LIGHT_GLOWING, null); + } + + if (maxWidth > exitWidth && selectedExitsSorted.size() == 1 && !exits.get(selectedExit).isEmpty()) { + IDrawing.drawStringWithFont(matrices, textRenderer, immediate, exits.get(selectedExit).get(0), flipCustomText ? HorizontalAlignment.RIGHT : HorizontalAlignment.LEFT, VerticalAlignment.CENTER, flipCustomText ? offset - margin : offset + signSize + margin, signSize / 2, maxWidth - exitWidth - margin * 2, signSize, HEIGHT_TO_SCALE / signSize, ARGB_WHITE, false, MAX_LIGHT_GLOWING, null); + } + } + + matrices.popPose(); + } else if (vertexConsumers != null && isLine) { + final Station station = RailwayData.getStation(ClientData.STATIONS, ClientData.DATA_CACHE, pos); + if (station == null) return; + + final Map routesInStation = ClientData.DATA_CACHE.stationIdToRoutes.get(station.id); + if (routesInStation != null) { + final List selectedIdsSorted = selectedIds.stream().filter(selectedId -> RailwayData.isBetween(selectedId, Integer.MIN_VALUE, Integer.MAX_VALUE)).map(Math::toIntExact).filter(routesInStation::containsKey).map(routesInStation::get).sorted(Comparator.comparingInt(route -> route.color)).collect(Collectors.toList()); + + final float maxWidth = Math.max(0, ((flipCustomText ? maxWidthLeft : maxWidthRight) + 1) * size - margin * 2); + final float height = size - margin * 2; + final List resourceLocationDataList = new ArrayList<>(); + float totalTextWidth = 0; + for (final ClientCache.ColorNameTuple route : selectedIdsSorted) { + final ClientCache.DynamicResource resourceLocationData = ClientData.DATA_CACHE.getRouteSquare(route.color, route.name, flipCustomText ? HorizontalAlignment.RIGHT : HorizontalAlignment.LEFT); + resourceLocationDataList.add(resourceLocationData); + totalTextWidth += height * resourceLocationData.width / resourceLocationData.height + margin / 2F; + } + + matrices.pushPose(); + matrices.translate(flipCustomText ? x + size - margin : x + margin, 0, 0); + + if (totalTextWidth > margin / 2F) { + totalTextWidth -= margin / 2F; + } + if (totalTextWidth > maxWidth) { + matrices.scale(maxWidth / totalTextWidth, 1, 1); + } + + float xOffset = 0; + for (final ClientCache.DynamicResource resourceLocationData : resourceLocationDataList) { + final float width = height * resourceLocationData.width / resourceLocationData.height; + IDrawing.drawTexture(matrices, vertexConsumers.getBuffer(MoreRenderLayers.getLight(resourceLocationData.resourceLocation, false)), flipCustomText ? -xOffset - width : xOffset, margin, width, height, Direction.UP, MAX_LIGHT_GLOWING); + xOffset += width + margin / 2F; + } + + matrices.popPose(); + } + } else if (vertexConsumers != null && isPlatform) { + final Station station = RailwayData.getStation(ClientData.STATIONS, ClientData.DATA_CACHE, pos); + if (station == null) { + return; + } + + final Map platformPositions = ClientData.DATA_CACHE.requestStationIdToPlatforms(station.id); + if (platformPositions != null) { + final List selectedIdsSorted = selectedIds.stream().filter(platformPositions::containsKey).sorted(Comparator.comparing(platformPositions::get)).collect(Collectors.toList()); + final int selectedCount = selectedIdsSorted.size(); + + final float extraMargin = margin - margin / selectedCount; + final float height = (size - extraMargin * 2) / selectedCount; + for (int i = 0; i < selectedIdsSorted.size(); i++) { + final float topOffset = i * height + extraMargin; + final float bottomOffset = (i + 1) * height + extraMargin; + final float left = flipCustomText ? x - maxWidthLeft * size : x + margin; + final float right = flipCustomText ? x + size - margin : x + (maxWidthRight + 1) * size; + final VertexConsumer vertexConsumer = vertexConsumers.getBuffer(MoreRenderLayers.getLight(ClientData.DATA_CACHE.getDirectionArrow(selectedIdsSorted.get(i), false, false, flipCustomText ? HorizontalAlignment.RIGHT : HorizontalAlignment.LEFT, false, margin / size, (right - left) / (bottomOffset - topOffset), backgroundColor, ARGB_WHITE, backgroundColor).resourceLocation, true)); + IDrawing.drawTexture(matrices, vertexConsumer, left, topOffset, 0, right, bottomOffset, 0, 0, 0, 1, 1, facing, -1, MAX_LIGHT_GLOWING); + } + } + } else { + drawTexture.drawTexture(sign.textureId, x + margin, y + margin, signSize, flipTexture); + + if (hasCustomText) { + final float fixedMargin = size * (1 - BlockRailwaySignBase.SMALL_SIGN_PERCENTAGE) / 2; + final boolean isSmall = sign.small; + final float maxWidth = Math.max(0, (flipCustomText ? maxWidthLeft : maxWidthRight) * size - fixedMargin * (isSmall ? 1 : 2)); + final float start = flipCustomText ? x - (isSmall ? 0 : fixedMargin) : x + size + (isSmall ? 0 : fixedMargin); + if (vertexConsumers == null) { + IDrawing.drawStringWithFont(matrices, textRenderer, immediate, isExit || isLine ? "..." : sign.customText, flipCustomText ? HorizontalAlignment.RIGHT : HorizontalAlignment.LEFT, VerticalAlignment.TOP, start, y + fixedMargin, maxWidth, size - fixedMargin * 2, 0.01F, ARGB_WHITE, false, MAX_LIGHT_GLOWING, null); + } else { + final ClientCache.DynamicResource dynamicResource = ClientData.DATA_CACHE.getSignText(sign.customText, flipCustomText ? HorizontalAlignment.RIGHT : HorizontalAlignment.LEFT, fixedMargin / size, backgroundColor, ARGB_WHITE); + final VertexConsumer vertexConsumer = vertexConsumers.getBuffer(MoreRenderLayers.getLight(dynamicResource.resourceLocation, true)); + final float width = Math.min(size * dynamicResource.width / dynamicResource.height, maxWidth); + IDrawing.drawTexture(matrices, vertexConsumer, start - (flipCustomText ? width : 0), 0, 0, start + (flipCustomText ? 0 : width), size, 0, 0, 0, 1, 1, facing, -1, MAX_LIGHT_GLOWING); + } + } + } + + if (immediate != null) { + immediate.endBatch(); + } + } +} diff --git a/common/src/main/java/ziyue/tjmetro/screen/RailwaySignWallDoubleScreen.java b/common/src/main/java/ziyue/tjmetro/screen/RailwaySignWallDoubleScreen.java new file mode 100644 index 0000000..d41e302 --- /dev/null +++ b/common/src/main/java/ziyue/tjmetro/screen/RailwaySignWallDoubleScreen.java @@ -0,0 +1,358 @@ +package ziyue.tjmetro.screen; + +import com.mojang.blaze3d.vertex.PoseStack; +import mtr.block.BlockRailwaySign; +import mtr.client.ClientCache; +import mtr.client.ClientData; +import mtr.client.CustomResources; +import mtr.client.IDrawing; +import mtr.data.*; +import mtr.mappings.ScreenMapper; +import mtr.mappings.Text; +import mtr.mappings.UtilitiesClient; +import mtr.render.RenderRailwaySign; +import mtr.screen.DashboardListSelectorScreen; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.components.Button; +import net.minecraft.client.gui.components.ImageButton; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import net.minecraft.world.level.block.entity.BlockEntity; +import ziyue.tjmetro.TianjinMetro; +import ziyue.tjmetro.blocks.BlockRailwaySignWallDouble; +import ziyue.tjmetro.blocks.base.BlockRailwaySignBase; +import ziyue.tjmetro.packet.PacketGuiServer; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author ZiYueCommentary + * @see mtr.screen.RailwaySignScreen + * @see BlockRailwaySignBase + * @since beta-1 + */ + +public class RailwaySignWallDoubleScreen extends ScreenMapper implements IGui +{ + protected int line; + protected int editingIndex; + protected int page; + protected int totalPages; + protected int columns; + protected int rows; + + protected final BlockPos signPos; + protected final boolean isRailwaySign; + protected final int length; + protected final String[][] signIds; + protected final List> selectedIds; + protected final List exitsForList = new ArrayList<>(); + protected final List platformsForList = new ArrayList<>(); + protected final List routesForList = new ArrayList<>(); + protected final List allSignIds = new ArrayList<>(); + + protected final Button[][] buttonsEdit; + protected final Button[] buttonsSelection; + protected final Button buttonClear; + protected final ImageButton buttonPrevPage; + protected final ImageButton buttonNextPage; + + protected static final int SIGN_SIZE = 32; + protected static final int SIGN_BUTTON_SIZE = 16; + protected static final int BUTTON_Y_START = (SQUARE_SIZE + SIGN_SIZE) * 2 + SIGN_BUTTON_SIZE / 2; + + public RailwaySignWallDoubleScreen(BlockPos signPos) { + super(Text.literal("")); + editingIndex = -1; + this.signPos = signPos; + final ClientLevel world = Minecraft.getInstance().level; + + for (final BlockRailwaySign.SignType signType : BlockRailwaySign.SignType.values()) { + allSignIds.add(signType.toString()); + } + final List sortedKeys = new ArrayList<>(CustomResources.CUSTOM_SIGNS.keySet()); + Collections.sort(sortedKeys); + allSignIds.addAll(sortedKeys); + + try { + final Station station = RailwayData.getStation(ClientData.STATIONS, ClientData.DATA_CACHE, signPos); + if (station != null) { + final Map> exits = station.getGeneratedExits(); + final List exitParents = new ArrayList<>(exits.keySet()); + exitParents.sort(String::compareTo); + exitParents.forEach(exitParent -> { + final List destinations = exits.get(exitParent); + exitsForList.add(new DataConverter(Station.serializeExit(exitParent), exitParent + " " + (!destinations.isEmpty() ? destinations.get(0) : ""), 0)); + }); + + final List platforms = new ArrayList<>(ClientData.DATA_CACHE.requestStationIdToPlatforms(station.id).values()); + Collections.sort(platforms); + platforms.stream().map(platform -> new DataConverter(platform.id, platform.name + " " + IGui.mergeStations(ClientData.DATA_CACHE.requestPlatformIdToRoutes(platform.id).stream().map(route -> route.stationDetails.get(route.stationDetails.size() - 1).stationName).collect(Collectors.toList())), 0)).forEach(platformsForList::add); + + final Map routeMap = ClientData.DATA_CACHE.stationIdToRoutes.get(station.id); + routeMap.forEach((color, route) -> routesForList.add(new DataConverter(route.color, route.name, route.color))); + } + } catch (Exception e) { + if (ClientData.DATA_CACHE.stationIdToRoutes.get(RailwayData.getStation(ClientData.STATIONS, ClientData.DATA_CACHE, signPos).id) == null) + TianjinMetro.LOGGER.warn("Position [" + signPos.toShortString() + "] has no station/routes!"); + else + TianjinMetro.LOGGER.error(e); + } + + if (world != null) { + final BlockEntity entity = world.getBlockEntity(signPos); + if (entity instanceof BlockRailwaySignWallDouble.TileEntityRailwaySignWallDouble entityRailwaySign) { + signIds = entityRailwaySign.getSignIds(); + selectedIds = entityRailwaySign.getSelectedIds(); + isRailwaySign = true; + } else { + signIds = new String[0][0]; + selectedIds = new ArrayList<>(); + selectedIds.add(new HashSet<>()); + selectedIds.add(new HashSet<>()); + isRailwaySign = false; + } + if (world.getBlockState(signPos).getBlock() instanceof BlockRailwaySignWallDouble block) { + length = block.length; + } else { + length = 0; + } + } else { + length = 0; + signIds = new String[0][0]; + selectedIds = new ArrayList<>(); + selectedIds.add(new HashSet<>()); + selectedIds.add(new HashSet<>()); + isRailwaySign = false; + } + + buttonsEdit = new Button[2][length]; + for (int i = 0; i < 2; i++) { + for (int j = 0; j < buttonsEdit[i].length; j++) { + final int index = j; + int finalI = i; + buttonsEdit[i][j] = new Button(0, 0, 0, SQUARE_SIZE, Text.translatable("selectWorld.edit"), button -> edit(finalI, index)); + } + } + + + buttonsSelection = new Button[allSignIds.size()]; + for (int i = 0; i < allSignIds.size(); i++) { + final int index = i; + buttonsSelection[i] = new Button(0, 0, 0, SIGN_BUTTON_SIZE, Text.literal(""), button -> setNewSignId(allSignIds.get(index))); + } + + buttonClear = new Button(0, 0, 0, SQUARE_SIZE, Text.translatable("gui.mtr.reset_sign"), button -> setNewSignId(null)); + buttonPrevPage = new ImageButton(0, 0, 0, SQUARE_SIZE, 0, 0, 20, new ResourceLocation("mtr:textures/gui/icon_left.png"), 20, 40, button -> setPage(page - 1)); + buttonNextPage = new ImageButton(0, 0, 0, SQUARE_SIZE, 0, 0, 20, new ResourceLocation("mtr:textures/gui/icon_right.png"), 20, 40, button -> setPage(page + 1)); + } + + @Override + protected void init() { + super.init(); + + for (int i = 0; i < 2; i++) { + for (int j = 0; j < buttonsEdit[i].length; j++) { + IDrawing.setPositionAndWidth(buttonsEdit[i][j], (width - SIGN_SIZE * length) / 2 + j * SIGN_SIZE, i * (SIGN_SIZE + SQUARE_SIZE) + SIGN_SIZE, SIGN_SIZE); + addDrawableChild(buttonsEdit[i][j]); + } + } + + columns = Math.max((width - SIGN_BUTTON_SIZE * 3) / (SIGN_BUTTON_SIZE * 8) * 2, 1); + rows = Math.max((height - SIGN_SIZE * 2 - SQUARE_SIZE * 4 - SQUARE_SIZE / 2) / SIGN_BUTTON_SIZE, 1); + + final int xOffsetSmall = (width - SIGN_BUTTON_SIZE * (columns * 4 + 3)) / 2 + SIGN_BUTTON_SIZE; + final int xOffsetBig = xOffsetSmall + SIGN_BUTTON_SIZE * (columns + 1); + + totalPages = loopSigns((index, x, y, isBig) -> { + IDrawing.setPositionAndWidth(buttonsSelection[index], (isBig ? xOffsetBig : xOffsetSmall) + x, BUTTON_Y_START + y, isBig ? SIGN_BUTTON_SIZE * 3 : SIGN_BUTTON_SIZE); + buttonsSelection[index].visible = false; + addDrawableChild(buttonsSelection[index]); + }, true); + + final int buttonClearX = (width - PANEL_WIDTH - SQUARE_SIZE * 4) / 2; + final int buttonY = height - SQUARE_SIZE * 2; + + IDrawing.setPositionAndWidth(buttonClear, buttonClearX, buttonY, PANEL_WIDTH); + buttonClear.visible = false; + addDrawableChild(buttonClear); + + IDrawing.setPositionAndWidth(buttonPrevPage, buttonClearX + PANEL_WIDTH, buttonY, SQUARE_SIZE); + buttonPrevPage.visible = false; + addDrawableChild(buttonPrevPage); + IDrawing.setPositionAndWidth(buttonNextPage, buttonClearX + PANEL_WIDTH + SQUARE_SIZE * 3, buttonY, SQUARE_SIZE); + buttonNextPage.visible = false; + addDrawableChild(buttonNextPage); + + if (!isRailwaySign && minecraft != null) { + UtilitiesClient.setScreen(minecraft, new DashboardListSelectorScreen(this::onClose, platformsForList, selectedIds.get(line), true, false)); + } + } + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + try { + renderBackground(matrices); + super.render(matrices, mouseX, mouseY, delta); + if (minecraft == null) { + return; + } + + for (int i = 0; i < 2; i++) { + for (int j = 0; j < signIds[i].length; j++) { + if (signIds[i][j] != null) { + RenderRailwaySign.drawSign(matrices, null, null, font, signPos, signIds[i][j], (width - SIGN_SIZE * length) / 2F + j * SIGN_SIZE, i * (SQUARE_SIZE + SIGN_SIZE), SIGN_SIZE, RenderRailwaySign.getMaxWidth(signIds[i], j, false), RenderRailwaySign.getMaxWidth(signIds[i], j, true), selectedIds.get(i), Direction.UP, 0, (textureId, x, y, size, flipTexture) -> { + UtilitiesClient.beginDrawingTexture(textureId); + blit(matrices, (int) x, (int) y, 0, 0, (int) size, (int) size, (int) (flipTexture ? -size : size), (int) size); + }); + } + } + } + + if (editingIndex >= 0) { + final int xOffsetSmall = (width - SIGN_BUTTON_SIZE * (columns * 4 + 3)) / 2 + SIGN_BUTTON_SIZE; + final int xOffsetBig = xOffsetSmall + SIGN_BUTTON_SIZE * (columns + 1); + + loopSigns((index, x, y, isBig) -> { + final String signId = allSignIds.get(index); + final CustomResources.CustomSign sign = RenderRailwaySign.getSign(signId); + if (sign != null) { + final boolean moveRight = sign.hasCustomText() && sign.flipCustomText; + UtilitiesClient.beginDrawingTexture(sign.textureId); + RenderRailwaySign.drawSign(matrices, null, null, font, signPos, signId, (isBig ? xOffsetBig : xOffsetSmall) + x + (moveRight ? SIGN_BUTTON_SIZE * 2 : 0), BUTTON_Y_START + y, SIGN_BUTTON_SIZE, 2, 2, selectedIds.get(line), Direction.UP, 0, (textureId, x1, y1, size, flipTexture) -> blit(matrices, (int) x1, (int) y1, 0, 0, (int) size, (int) size, (int) (flipTexture ? -size : size), (int) size)); + } + }, false); + + Gui.drawCenteredString(matrices, font, String.format("%s/%s", page + 1, totalPages), (width - PANEL_WIDTH - SQUARE_SIZE * 4) / 2 + PANEL_WIDTH + SQUARE_SIZE * 2, height - SQUARE_SIZE * 2 + TEXT_PADDING, ARGB_WHITE); + } + } catch (Exception e) { + TianjinMetro.LOGGER.error(e); + } + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double amount) { + setPage(page + (int) Math.signum(-amount)); + return super.mouseScrolled(mouseX, mouseY, amount); + } + + @Override + public void onClose() { + PacketGuiServer.sendSignIdsDoubleC2S(signPos, selectedIds, signIds); + super.onClose(); + } + + @Override + public boolean isPauseScreen() { + return false; + } + + @Override + public void resize(Minecraft client, int width, int height) { + super.resize(client, width, height); + for (int i = 0; i < 2; i++) { + for (Button button : buttonsEdit[i]) { + button.active = true; + } + } + for (Button button : buttonsSelection) { + button.visible = false; + } + editingIndex = -1; + } + + protected int loopSigns(LoopSignsCallback loopSignsCallback, boolean ignorePage) { + int pageCount = rows * columns; + int indexSmall = 0; + int indexBig = 0; + int columnSmall = 0; + int columnBig = 0; + int rowSmall = 0; + int rowBig = 0; + int totalPagesSmallCount = 1; + int totalPagesBigCount = 1; + for (int i = 0; i < allSignIds.size(); i++) { + final CustomResources.CustomSign sign = RenderRailwaySign.getSign(allSignIds.get(i)); + final boolean isBig = sign != null && sign.hasCustomText(); + + final boolean onPage = (isBig ? indexBig : indexSmall) / pageCount == page; + buttonsSelection[i].visible = onPage; + if (ignorePage || onPage) { + loopSignsCallback.loopSignsCallback(i, (isBig ? columnBig * 3 : columnSmall) * SIGN_BUTTON_SIZE, (isBig ? rowBig : rowSmall) * SIGN_BUTTON_SIZE, isBig); + } + + if (isBig) { + columnBig++; + if (totalPagesBigCount < 0) { + totalPagesBigCount = -totalPagesBigCount + 1; + } + if (columnBig >= columns) { + columnBig = 0; + rowBig++; + if (rowBig >= rows) { + rowBig = 0; + totalPagesBigCount = -totalPagesBigCount; + } + } + indexBig++; + } else { + columnSmall++; + if (totalPagesSmallCount < 0) { + totalPagesSmallCount = -totalPagesSmallCount + 1; + } + if (columnSmall >= columns) { + columnSmall = 0; + rowSmall++; + if (rowSmall >= rows) { + rowSmall = 0; + totalPagesSmallCount = -totalPagesSmallCount; + } + } + indexSmall++; + } + } + return Math.max(Math.abs(totalPagesBigCount), Math.abs(totalPagesSmallCount)); + } + + protected void edit(int line, int editingIndex) { + this.line = line; + this.editingIndex = editingIndex; + for (int i = 0; i < 2; i++) { + for (Button button : buttonsEdit[i]) { + button.active = true; + } + } + buttonClear.visible = true; + setPage(page); + buttonsEdit[line][editingIndex].active = false; + } + + protected void setNewSignId(String newSignId) { + if (editingIndex >= 0 && editingIndex < signIds[0].length) { + signIds[line][editingIndex] = newSignId; + final boolean isExitLetter = newSignId != null && (newSignId.equals(BlockRailwaySign.SignType.EXIT_LETTER.toString()) || newSignId.equals(BlockRailwaySign.SignType.EXIT_LETTER_FLIPPED.toString())); + final boolean isPlatform = newSignId != null && (newSignId.equals(BlockRailwaySign.SignType.PLATFORM.toString()) || newSignId.equals(BlockRailwaySign.SignType.PLATFORM_FLIPPED.toString())); + final boolean isLine = newSignId != null && (newSignId.equals(BlockRailwaySign.SignType.LINE.toString()) || newSignId.equals(BlockRailwaySign.SignType.LINE_FLIPPED.toString())); + if ((isExitLetter || isPlatform || isLine) && minecraft != null) { + UtilitiesClient.setScreen(minecraft, new DashboardListSelectorScreen(this, isExitLetter ? exitsForList : isPlatform ? platformsForList : routesForList, selectedIds.get(line), false, false)); + } + } + } + + protected void setPage(int newPage) { + page = Mth.clamp(newPage, 0, totalPages - 1); + buttonPrevPage.visible = editingIndex >= 0 && page > 0; + buttonNextPage.visible = editingIndex >= 0 && page < totalPages - 1; + } + + @FunctionalInterface + protected interface LoopSignsCallback + { + void loopSignsCallback(int index, int x, int y, boolean isBig); + } +} diff --git a/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_10.json b/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_10.json new file mode 100644 index 0000000..a924c5a --- /dev/null +++ b/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_10.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "tjmetro:block/railway_sign_wall" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_4.json b/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_4.json new file mode 100644 index 0000000..a924c5a --- /dev/null +++ b/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_4.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "tjmetro:block/railway_sign_wall" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_6.json b/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_6.json new file mode 100644 index 0000000..a924c5a --- /dev/null +++ b/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_6.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "tjmetro:block/railway_sign_wall" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_8.json b/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_8.json new file mode 100644 index 0000000..a924c5a --- /dev/null +++ b/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_8.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "tjmetro:block/railway_sign_wall" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_middle.json b/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_middle.json new file mode 100644 index 0000000..a924c5a --- /dev/null +++ b/common/src/main/resources/assets/tjmetro/blockstates/railway_sign_wall_double_middle.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "tjmetro:block/railway_sign_wall" + } + } +} \ No newline at end of file diff --git a/common/src/main/resources/assets/tjmetro/lang/en_us.json b/common/src/main/resources/assets/tjmetro/lang/en_us.json index cba886f..27b21ac 100644 --- a/common/src/main/resources/assets/tjmetro/lang/en_us.json +++ b/common/src/main/resources/assets/tjmetro/lang/en_us.json @@ -7,6 +7,7 @@ "block.tjmetro.station_name_sign_2": "Station Name Sign", "block.tjmetro.railway_sign_wall": "Railway Sign (Wall)", "block.tjmetro.railway_sign_wall_big": "Railway Sign (Wall, Big)", + "block.tjmetro.railway_sign_wall_double": "Railway Sign (Wall, Double)", "block.tjmetro.roadblock": "Roadblock", "block.tjmetro.roadblock_sign": "Roadblock", "block.tjmetro.platform_tj_1": "Platform (Tianjin)", @@ -33,6 +34,7 @@ "block.tjmetro.metal_detection_door": "Metal Detection Door", "block.tjmetro.railway_sign_tianjin": "Railway Sign (Tianjin)", "block.tjmetro.service_corridor_sign": "\"Serivce Corridor\" Sign", + "sign.tjmetro.service_corridor_sign": "Service Corridor", "sign.tjmetro.contact_station_for_help": "Please contact the station for help.", @@ -51,9 +53,8 @@ "config.tjmetro.enable_mtr_filters": "Enable MTR Filters", "config.tjmetro.use_tianjin_metro_font": "Enable Tianjin Metro Font", - "config.tjmetro.experimental_mtr_config_screen": "Experimental MTR Config Screen", - "tooltip.tjmetro.not_suggest": "This feature is not suggest.", + "tooltip.tjmetro.not_suggest": "This feature is not suggested.", "tooltip.tjmetro.mtr_config_screen": "Use the new config screen instead of the original.", "tooltip.tjmetro.experimental": "This feature is experimental.", "tooltip.tjmetro.station_name": "Text depends on the station", diff --git a/common/src/main/resources/assets/tjmetro/models/block/railway_sign_tianjin_middle.json b/common/src/main/resources/assets/tjmetro/models/block/railway_sign_tianjin_middle.json index 0eccb9a..7ea60d2 100644 --- a/common/src/main/resources/assets/tjmetro/models/block/railway_sign_tianjin_middle.json +++ b/common/src/main/resources/assets/tjmetro/models/block/railway_sign_tianjin_middle.json @@ -1,21 +1,21 @@ { - "credit": "Made by ZiYueCommentary, made with Blockbench.", - "parent": "block/block", - "textures": { - "particle": "tjmetro:block/gray" - }, - "elements": [ - { - "from": [0, 0.25, 7], - "to": [16, 10, 9], - "faces": { - "north": {"uv": [0, 4, 16, 15.75], "texture": "#particle"}, - "east": {"uv": [0, 4, 16, 15.75], "texture": "#particle"}, - "south": {"uv": [0, 4, 16, 15.75], "texture": "#particle"}, - "west": {"uv": [0, 4, 16, 15.75], "texture": "#particle"}, - "up": {"uv": [0, 4, 16, 15.75], "texture": "#particle"}, - "down": {"uv": [0, 4, 16, 15.75], "texture": "#particle"} - } - } - ] + "credit": "Made by ZiYueCommentary, made with Blockbench.", + "parent": "block/block", + "textures": { + "particle": "tjmetro:block/black" + }, + "elements": [ + { + "from": [0, 0.25, 6], + "to": [16, 10, 10], + "faces": { + "north": {"uv": [0, 4, 16, 15.75], "texture": "#particle"}, + "east": {"uv": [0, 4, 16, 15.75], "texture": "#particle"}, + "south": {"uv": [0, 4, 16, 15.75], "texture": "#particle"}, + "west": {"uv": [0, 4, 16, 15.75], "texture": "#particle"}, + "up": {"uv": [0, 4, 16, 15.75], "texture": "#particle"}, + "down": {"uv": [0, 4, 16, 15.75], "texture": "#particle"} + } + } + ] } \ No newline at end of file diff --git a/common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_10.json b/common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_10.json new file mode 100644 index 0000000..7eafd3f --- /dev/null +++ b/common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_10.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "tjmetro:item/railway_sign_wall_double_10" + } +} diff --git a/common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_4.json b/common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_4.json new file mode 100644 index 0000000..e57e785 --- /dev/null +++ b/common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_4.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "tjmetro:item/railway_sign_wall_double_4" + } +} diff --git a/common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_6.json b/common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_6.json new file mode 100644 index 0000000..6f606ef --- /dev/null +++ b/common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_6.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "tjmetro:item/railway_sign_wall_double_6" + } +} diff --git a/common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_8.json b/common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_8.json new file mode 100644 index 0000000..543b2d4 --- /dev/null +++ b/common/src/main/resources/assets/tjmetro/models/item/railway_sign_wall_double_8.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "tjmetro:item/railway_sign_wall_double_8" + } +} diff --git a/common/src/main/resources/assets/tjmetro/textures/item/railway_sign_wall_double_10.png b/common/src/main/resources/assets/tjmetro/textures/item/railway_sign_wall_double_10.png new file mode 100644 index 0000000000000000000000000000000000000000..ca2d91a9fe7a8fa78a35b402725d630fa052d960 GIT binary patch literal 1858 zcmbVNO>Em#9QQOjji}ubB!-0La@aH+KYt|t(7e$#4UJerX#*>VN_)0n605PFYr9R- z15{jq6CB`(G>#y|jY|PBi6VixOx%VhGzn=41meJPNaOF1xGBm$gcZjh@ArPc-~Z!1 zzq8VMVXpL4iD8(z#&T^HuFogu$rJGZiM#bPTpkaWUyB&#)Io9{`{3NE(+qRsMYp{k zuQx9nHucKbp%y6*y#UY*bN=Em!1gAIS&MXC-{k)K;%km|9h19KX`*JZNP6z_Zb;U4 zTWx!H)7BmC;sy5n&;SCD#F!m=eLpgWCYSOWaG$&uI5vgEn1ffsS3^g6*)MiaWMI`otrC9067=utAT;H0sg&P#42T1R%G~W}z|Fi{}** zQM|MRVdM#!ijLZ&fC#H3qT8WOmUh7Ad=gDyEQSQfG;CAaA6IH+Y?+nhGGfnMaeapl zqO%hdNDartPfkMwXIK~eJJGRlG zp@$)0*TY>R1b&xei!>UGv`<4226uAmqS-VWeiUQhCXJfOLCj^>b&LwC$f}O2yy{dn zUQ`sFwqU$qpAw?wVO z>$a*WgveMEoiW=>p$iKQ_a|8sR}L`BN=2?#bi@-~Re42L6kZ3PJa(#fN7QYM9X;vh zL*+IZ#+UJkgi*dsF5zx|*LNrKl44regS?2SHkq+>B%#Sh1eh%(t0N;4?jx19sIlxu z&^)7DaE)voN~c|EU^`iDCTAyYMj!{-Yj;XT9x3*G{-8&I^a1Uc$wagh4{%5px=_7` zws#VF5;)}TsQC!*JlOi9HB&}9&H9n$@PDl5hV35qy9D-bfh)?G6-D@Oz0wj-Y>4Bk z!!DcL7W+Fq6kiD919b@d|7`u0UHEo<*r+YEhd=#!Q!MSF*_j)+?)|v+Tl@X`lkVRa zoHGX>y<0!1cj~_;-zzw7|MJaR`0Nwkztz5b=XK_dZxmqbP`(HhF?2poW-#&f!?CkY>*>vXi$-TF~Yt7_O(=ONey&qoA2Ci*vRK3sV UZdLwyHF?okYSliwboI@D0mHXJX8-^I literal 0 HcmV?d00001 diff --git a/common/src/main/resources/assets/tjmetro/textures/item/railway_sign_wall_double_4.png b/common/src/main/resources/assets/tjmetro/textures/item/railway_sign_wall_double_4.png new file mode 100644 index 0000000000000000000000000000000000000000..5b92cf08ad5a4ad8f50309b4a6ee2cc2183d4880 GIT binary patch literal 1848 zcmbVNOKjXk7KhRGi z_djO*$@<#c^K)nB1VNZ@HtHMjT#T=ivv9xT-25FLr~Jl^P!LZ47+*8DFPuIr2(wM6 zwH0kyt0v)Y0aI?X!oc;xS`aQ?8u*y(ut>C7$MI^?qr>kd(V;czdf7sjzs$N$V?SV< z`)e(-ze5ZvU0M(?4om=WS%k%b+w($mP?Hi|6UOnhB8iDfv{RFoVnT7tS{Ijjz(l>E z$^;=K>P7)q^`dGUZ;2YxR0SFEmk~0Hx>>A>*-rwxfVRzz`jw0f-fB`eihNU1`u%>P zUo7yTqo{@f0Ggs{GFZsr(2MXu_QG>xggOgJ;P{clJuybaHs6hE5=c#BaQz(C3$r{y z#*_i}6}5okm=Z%uayx%F=q2QoD6Gd^=0zdcs=2M-n`mf7^e2z!Jz>oo~tE;tSajhIwO+m?}` zwxJ(OShleNBdtwK#R_Zdv@-UubFv#(Hug`uoN@vfN31p~YN}2Q*+2%Cbyia4YLz0n zY*ecRRmuog=osy4;J`-1y-Czq6$L~?BU*)&h^%YamPx6k%NT^nHl?as(W%W05_j_v zbBhh4RXk)tm~E5GxRZ@~&O}}kn>Fl0UP|@Jge40xO0uAUuM+Q#6h?UhQPQAh!wI2v zh8f)^yLm*M^rVSNyw_?HiJOc;2GVI~NAWdQn==1XZp-j4b>U`rjS-7}jz zjyw(=vUXg2i1(f@{rOrc1)V1S*k<@Y(lf!Ni@gqmlUtGUGNwgQ{#&o4#1qHixax4m z#>4z{hnM{Oz&wBs;Pij*-9Ns9FURd>eW^A0?av45+z6c%79T%$4qtw8KDu_*zxC0< zw~f#5{dE6}ndBoQ{PTYIrN2MD^TGWSU!Gt5#lO2Sn(4l~U@H zCRuSn6$dIf(gP9_7YRLL8u%@{XN&vnc%#mOsWb&pglj zH8Ypj*WNg?@WO&12uE7Y#s+*} zW~)2k#yB7|(P?KCQ+0!;Y&#)zbqCBm&b^84m4xDqB^}24lT58oOcr%RLE_67g2-co z^p&Xzw1G3~NRYLPjC2{*JCHT4ZfoWes@n(^&^Ge|e>4lK>yY3BP^cLXXZVp|kJvs- zLJSTEA?{K&j=GXqhS6SOeU^YQSZCx`wA*$oN;4c0+G;ow_^bqhXA`4Nbc#*ca50vV zRjJCZ?<3hYDyD(4NvniR<~JDG=9%U5iz@dR0gioD)712u@A@*WT13`RMUyc>rmP#D zWl>$Lk-9lyJC_8o&~Sg6m0RTjBO=(uq-x3an(51iQ88rKqMoeRT%=)F^D**xHSa5T z=rB8rM>I*t%j691j$8d;DlR!@4TlgHvoRg8e1Nm$11ii_`PwLG)CUOV1!^~g6iR0_ zmOD=`?hEHNX=B3Inj;ZjWYm+yqC1$8kH_+SJb%!mK>Cp4D`ZmUX9JwjpLz27ulIkrr5rn%UA}+#W9ibf zA1;4+ZOP(i6%-MM_8uy^9!tG7QZ+Oyx!J^g$7d@=O?2ZyeI`qfM7i#PA^j@Ig0yq_B?SE-e37weuZW>TE3hJ!tvYLGxN#m0 z6NHdxSQTsWt<>l z$^b`-T0xmlIgpYuF4~TJxi}>X>#=}^X#!YvjE%ZHP8>Q_)Fl7%^p?C44(3Y-tC~Je7G9*^4p5DUVy6_ePmo8<{L>)d~_{yySYHQ)0Jy z9AI$R4{(PmQP`2haTx7I-s3R{gLT#13fHxpVUpsIu%^?Hz~_qZQ=3v#^K`Q=TZ~c} z>AE3%*uXOJOoQl}rD@n3t#>%t&N7>=FRGk!0vrdbnx`Sv)HPYNXifH1oyeA1*JP`T ztCpeG4XTq7+pDn;8x8j+Su?9BFcN~=hGiPERpGS_51Dcu)oU10&GXD!R?P>> zEjCCm;vtKZa+{pTowC>SC*qQ0R&fAvF`dbP6nUvH0vy$;U%^Uas$V8Iazm_zIbXx6?k3*+K_$_rT)L zJkK15s2w&w!8`Xi{ozWfAf0CVq0R7rOfL;4T^x28oZN~uPGgZ2<-hsLQ#^4Tj+8>|I