diff --git a/src/client/kotlin/me/znepb/roadworks/RoadworksClient.kt b/src/client/kotlin/me/znepb/roadworks/RoadworksClient.kt index 57d7670..fef16af 100644 --- a/src/client/kotlin/me/znepb/roadworks/RoadworksClient.kt +++ b/src/client/kotlin/me/znepb/roadworks/RoadworksClient.kt @@ -25,6 +25,7 @@ object RoadworksClient : ClientModInitializer { BlockEntityRendererFactories.register(Registry.ModBlockEntities.FIVE_HEAD_TRAFFIC_SIGNAL_LEFT_BLOCK_ENTITY, ::FiveHeadTrafficSignalLeftBlockRenderer) BlockEntityRendererFactories.register(Registry.ModBlockEntities.FIVE_HEAD_TRAFFIC_SIGNAL_RIGHT_BLOCK_ENTITY, ::FiveHeadTrafficSignalRightBlockRenderer) BlockEntityRendererFactories.register(Registry.ModBlockEntities.PEDESTRIAN_SIGNAL_BLOCK_ENTITY, ::PedestrianSignalRenderer) + BlockEntityRendererFactories.register(Registry.ModBlockEntities.PEDESTRIAN_BUTTON_BLOCK_ENTITY, ::PedestrianButtonRenderer) BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), Registry.ModBlocks.WHITE_CENTER_MARKING, diff --git a/src/client/kotlin/me/znepb/roadworks/init/ModelLoader.kt b/src/client/kotlin/me/znepb/roadworks/init/ModelLoader.kt index fdf8a64..eefb5c5 100644 --- a/src/client/kotlin/me/znepb/roadworks/init/ModelLoader.kt +++ b/src/client/kotlin/me/znepb/roadworks/init/ModelLoader.kt @@ -21,7 +21,9 @@ class ModelLoader { AbstractThreeHeadSignalBlockRenderer.SIGNAL_FRAME_3, AbstractThreeHeadSignalBlockRenderer.SIGNAL, PedestrianSignalRenderer.DONT_WALK, - PedestrianSignalRenderer.WALK + PedestrianSignalRenderer.WALK, + PedestrianButtonRenderer.PEDESTRIAN_BUTTON_ON, + PedestrianButtonRenderer.PEDESTRIAN_BUTTON_OFF ) } @@ -30,7 +32,7 @@ class ModelLoader { run { logger.info("Registering block models") plugin.addModels(models) - plugin.addModels(SignalRenderer.SIGNAL_MODEL_IDS) + plugin.addModels(PostMountRenderer.SIGNAL_MODEL_IDS) } } } diff --git a/src/client/kotlin/me/znepb/roadworks/render/AbstractBeaconRenderer.kt b/src/client/kotlin/me/znepb/roadworks/render/AbstractBeaconRenderer.kt index eb06770..d69fa10 100644 --- a/src/client/kotlin/me/znepb/roadworks/render/AbstractBeaconRenderer.kt +++ b/src/client/kotlin/me/znepb/roadworks/render/AbstractBeaconRenderer.kt @@ -44,10 +44,10 @@ abstract class AbstractBeaconRenderer( }).toDouble() / 16 }.toDouble() - val renderer = SignalRenderer(entity, matrices, vertexConsumers, light, overlay, direction, translateBy) + val renderer = PostMountRenderer(entity, matrices, vertexConsumers, light, overlay, direction, translateBy) matrices.push() - renderer.rotateForSignalRender() + renderer.rotateForRender() matrices.translate(0.0, 0.0, translateBy) RenderUtils.renderModel(matrices, renderer.buffer, light, overlay, SIGNAL_FRAME_1, null) matrices.pop() diff --git a/src/client/kotlin/me/znepb/roadworks/render/AbstractFiveHeadSignalBlockRenderer.kt b/src/client/kotlin/me/znepb/roadworks/render/AbstractFiveHeadSignalBlockRenderer.kt index ea1cb16..3fd1ba8 100644 --- a/src/client/kotlin/me/znepb/roadworks/render/AbstractFiveHeadSignalBlockRenderer.kt +++ b/src/client/kotlin/me/znepb/roadworks/render/AbstractFiveHeadSignalBlockRenderer.kt @@ -46,10 +46,10 @@ abstract class AbstractFiveHeadSignalBlockRenderer( }).toDouble() / 16 }.toDouble() - val renderer = SignalRenderer(entity, matrices, vertexConsumers, light, overlay, direction, translateBy) + val renderer = PostMountRenderer(entity, matrices, vertexConsumers, light, overlay, direction, translateBy) matrices.push() - renderer.rotateForSignalRender() + renderer.rotateForRender() matrices.translate(0.0, 0.0, translateBy) RenderUtils.renderModel(matrices, renderer.buffer, light, overlay, SIGNAL_FRAME_5, null) matrices.pop() diff --git a/src/client/kotlin/me/znepb/roadworks/render/AbstractThreeHeadSignalBlockRenderer.kt b/src/client/kotlin/me/znepb/roadworks/render/AbstractThreeHeadSignalBlockRenderer.kt index 69e3e13..a14a879 100644 --- a/src/client/kotlin/me/znepb/roadworks/render/AbstractThreeHeadSignalBlockRenderer.kt +++ b/src/client/kotlin/me/znepb/roadworks/render/AbstractThreeHeadSignalBlockRenderer.kt @@ -46,10 +46,10 @@ abstract class AbstractThreeHeadSignalBlockRenderer( }).toDouble() / 16 }.toDouble() - val renderer = SignalRenderer(entity, matrices, vertexConsumers, light, overlay, direction, translateBy) + val renderer = PostMountRenderer(entity, matrices, vertexConsumers, light, overlay, direction, translateBy) matrices.push() - renderer.rotateForSignalRender() + renderer.rotateForRender() matrices.translate(0.0, 0.0, translateBy) RenderUtils.renderModel(matrices, renderer.buffer, light, overlay, SIGNAL_FRAME_3, null) matrices.pop() diff --git a/src/client/kotlin/me/znepb/roadworks/render/PedestrianButtonRenderer.kt b/src/client/kotlin/me/znepb/roadworks/render/PedestrianButtonRenderer.kt new file mode 100644 index 0000000..82d9e16 --- /dev/null +++ b/src/client/kotlin/me/znepb/roadworks/render/PedestrianButtonRenderer.kt @@ -0,0 +1,57 @@ +package me.znepb.roadworks.render + +import me.znepb.roadworks.RoadworksMain.ModId +import me.znepb.roadworks.block.PedestrianButton +import me.znepb.roadworks.block.PedestrianButtonBlockEntity +import me.znepb.roadworks.block.post.AbstractPostMountableBlockEntity.Companion.getThickest +import me.znepb.roadworks.util.PostThickness +import me.znepb.roadworks.util.RenderUtils +import net.minecraft.client.render.VertexConsumerProvider +import net.minecraft.client.render.block.entity.BlockEntityRendererFactory +import net.minecraft.client.util.math.MatrixStack +import net.minecraft.state.property.Properties +import net.minecraft.util.math.Direction + +class PedestrianButtonRenderer( + private val ctx: BlockEntityRendererFactory.Context, +) : + AbstractPostMountableRenderer() { + + companion object { + val PEDESTRIAN_BUTTON_OFF = ModId("block/pedestrian_button_off") + val PEDESTRIAN_BUTTON_ON = ModId("block/pedestrian_button_on") + } + + override fun renderAttachment( + entity: PedestrianButtonBlockEntity, + tickDelta: Float, + matrices: MatrixStack, + vertexConsumers: VertexConsumerProvider, + light: Int, + overlay: Int + ) { + + val direction = Direction.byId(entity.facing) + val thickest = getThickest(entity) + val translateBy = if(entity.wall) { + 7.0/16 + } else { + -(when (thickest) { + PostThickness.NONE -> 0 + PostThickness.THIN -> 2 + PostThickness.MEDIUM -> 3 + PostThickness.THICK -> 3 + }).toDouble() / 16 + }.toDouble() + + val isButtonPressed = entity.world?.getBlockState(entity.pos)?.block is PedestrianButton && entity.world?.getBlockState(entity.pos)?.get(Properties.POWERED) == true + + val renderer = PostMountRenderer(entity, matrices, vertexConsumers, light, overlay, direction, translateBy) + matrices.push() + renderer.rotateForRender() + matrices.translate(0.0, 0.0, translateBy) + RenderUtils.renderModel(matrices, renderer.buffer, light, overlay, if(isButtonPressed) PEDESTRIAN_BUTTON_ON else PEDESTRIAN_BUTTON_OFF, null) + matrices.pop() + + } +} \ No newline at end of file diff --git a/src/client/kotlin/me/znepb/roadworks/render/PedestrianSignalRenderer.kt b/src/client/kotlin/me/znepb/roadworks/render/PedestrianSignalRenderer.kt index 019d759..cb9460e 100644 --- a/src/client/kotlin/me/znepb/roadworks/render/PedestrianSignalRenderer.kt +++ b/src/client/kotlin/me/znepb/roadworks/render/PedestrianSignalRenderer.kt @@ -43,10 +43,10 @@ class PedestrianSignalRenderer( }).toDouble() / 16 }.toDouble() - val renderer = SignalRenderer(entity, matrices, vertexConsumers, light, overlay, direction, translateBy) + val renderer = PostMountRenderer(entity, matrices, vertexConsumers, light, overlay, direction, translateBy) matrices.push() - renderer.rotateForSignalRender() + renderer.rotateForRender() matrices.translate(0.0, 0.0, translateBy) RenderUtils.renderModel(matrices, renderer.buffer, light, overlay, if (entity.getSignal(SignalLight.WALK)) WALK else DONT_WALK, null) matrices.pop() diff --git a/src/client/kotlin/me/znepb/roadworks/render/SignalRenderer.kt b/src/client/kotlin/me/znepb/roadworks/render/PostMountRenderer.kt similarity index 87% rename from src/client/kotlin/me/znepb/roadworks/render/SignalRenderer.kt rename to src/client/kotlin/me/znepb/roadworks/render/PostMountRenderer.kt index 8ebd071..45d4cc3 100644 --- a/src/client/kotlin/me/znepb/roadworks/render/SignalRenderer.kt +++ b/src/client/kotlin/me/znepb/roadworks/render/PostMountRenderer.kt @@ -1,6 +1,7 @@ package me.znepb.roadworks.render import me.znepb.roadworks.RoadworksMain.ModId +import me.znepb.roadworks.block.post.AbstractPostMountableBlockEntity import me.znepb.roadworks.block.signals.AbstractTrafficSignalBlockEntity import me.znepb.roadworks.block.signals.SignalLight import me.znepb.roadworks.datagen.ModelProvider @@ -13,8 +14,8 @@ import net.minecraft.client.util.math.MatrixStack import net.minecraft.util.math.Direction import org.joml.Quaternionf -class SignalRenderer( - private val entity: AbstractTrafficSignalBlockEntity, +class PostMountRenderer( + private val entity: AbstractPostMountableBlockEntity, private val matrices: MatrixStack, private val vertexConsumer: VertexConsumerProvider, private val light: Int, @@ -28,7 +29,7 @@ class SignalRenderer( val buffer: VertexConsumer = vertexConsumer.getBuffer(TexturedRenderLayers.getEntityTranslucentCull()) - fun rotateForSignalRender() { + fun rotateForRender() { matrices.multiply( Quaternionf().rotateXYZ( Math.toRadians(180.0).toFloat(), @@ -44,8 +45,10 @@ class SignalRenderer( x: Double, y: Double ) { + if(entity !is AbstractTrafficSignalBlockEntity) return + matrices.push() - rotateForSignalRender() + rotateForRender() matrices.translate(x, y, postOffset) renderModel( matrices, buffer, light, overlay, diff --git a/src/main/generated/.cache/6fe4d677fbb7b44f14903d96301f1a75bf6b5ac7 b/src/main/generated/.cache/6fe4d677fbb7b44f14903d96301f1a75bf6b5ac7 index 4d80e95..f47b11e 100644 --- a/src/main/generated/.cache/6fe4d677fbb7b44f14903d96301f1a75bf6b5ac7 +++ b/src/main/generated/.cache/6fe4d677fbb7b44f14903d96301f1a75bf6b5ac7 @@ -1,2 +1,2 @@ -// 1.20.1 2024-06-06T22:35:14.8128604 Roadworks/Language (en_us) -83a497a018a044969947c4127779a0db8ba81f4b assets\roadworks\lang\en_us.json +// 1.20.1 2024-06-07T19:30:39.5048389 Roadworks/Language (en_us) +00e965a320863a2118473dc37172f148de20b8c5 assets\roadworks\lang\en_us.json diff --git a/src/main/generated/.cache/b04aec471b8c80daca32233710909329a8febd71 b/src/main/generated/.cache/b04aec471b8c80daca32233710909329a8febd71 index 8a811bc..4499ba7 100644 --- a/src/main/generated/.cache/b04aec471b8c80daca32233710909329a8febd71 +++ b/src/main/generated/.cache/b04aec471b8c80daca32233710909329a8febd71 @@ -1,5 +1,5 @@ -// 1.20.1 2024-06-06T22:35:14.8123596 Roadworks/Tags for minecraft:block +// 1.20.1 2024-06-07T19:30:39.5038327 Roadworks/Tags for minecraft:block 6458da5395adad7476561352b614d45e9d8169a1 data\roadworks\tags\blocks\standalone_markings.json b007ad12c3c45db36f651fa35b4b78b2ae28ad59 data\roadworks\tags\blocks\marking.json -fdceaba6990989dbc2afd6e18fb38f0eedbf0231 data\roadworks\tags\blocks\post_mountables.json +6430e3cc2899d59c8e5521eb5dc96beedebfac0b data\roadworks\tags\blocks\post_mountables.json d02e791778da7a79b0b515823cffbb2fc5c4f6d3 data\roadworks\tags\blocks\posts.json diff --git a/src/main/generated/.cache/d9c50af9b8cfa8a81402aa75c3c441ce883c3523 b/src/main/generated/.cache/d9c50af9b8cfa8a81402aa75c3c441ce883c3523 index 4b5aad5..853adfe 100644 --- a/src/main/generated/.cache/d9c50af9b8cfa8a81402aa75c3c441ce883c3523 +++ b/src/main/generated/.cache/d9c50af9b8cfa8a81402aa75c3c441ce883c3523 @@ -1,4 +1,4 @@ -// 1.20.1 2024-06-06T22:35:14.8068465 Roadworks/Model Definitions +// 1.20.1 2024-06-07T19:30:39.4993331 Roadworks/Model Definitions 8342f8ba46d3f722dfb56f742e5daf49f4fab226 assets\roadworks\models\block\marking_white_infill.json 0476eefd0ae91fa40d125aaff968660c569d8436 assets\roadworks\blockstates\marking_yellow_turn_offset_center_in.json 1fd37bb3b7f834e2354f5e374e050becce306f55 assets\roadworks\models\item\marking_yellow_t_center_short.json @@ -34,8 +34,8 @@ da64ef53859d5165dbe4567a3688f385fc5d923a assets\roadworks\blockstates\marking_ye ac1d89f685ef457242bfb18877da9eba10283ef8 assets\roadworks\blockstates\yield_sign.json 006e2824087ad17bf079dcf6d9e2aa102dbc7282 assets\roadworks\models\item\five_head_traffic_signal_right.json d58f141e84c77deb2982cf34c6adae849b5dea78 assets\roadworks\blockstates\marking_white_zebra_crossing.json -9c012156291ffb6223ead669418ee2eb9908dee6 assets\roadworks\models\block\marking_yellow_l_right.json 5a9a2a5fa42d707ccad44ed5512b3a48a74a2264 assets\roadworks\blockstates\marking_yellow_stub_short_edge_right.json +9c012156291ffb6223ead669418ee2eb9908dee6 assets\roadworks\models\block\marking_yellow_l_right.json 427a25d99db3f53ce0f9901e7b4b55a513ee07d9 assets\roadworks\blockstates\marking_yellow_l_right.json 4a4f36b76ff8168b9d5cac1b1f601ccecdc943e3 assets\roadworks\models\block\signal_dont_walk_on.json ef9c4d50d4a421fda95fac5df6d86a41be482858 assets\roadworks\blockstates\marking_white_left_straight_turn_arrows.json @@ -64,8 +64,8 @@ e76eecdb678340b7951532fcf82a5a31d8978147 assets\roadworks\blockstates\marking_wh f0e39f868d72dfddf7fd64f610258b6299f25e05 assets\roadworks\blockstates\marking_yellow_stub_short_center.json 1345d5c3192f7dead930a671279faf171ef23380 assets\roadworks\models\block\marking_yellow_l_thin_short_left.json 5cecd31d5e9102b045248daa349dd9c6bee6cb91 assets\roadworks\blockstates\marking_yellow_stub_medium_edge_right.json -4b5ce26a9d03fcbd9a71f5c791d1a3d853afbd78 assets\roadworks\blockstates\marking_yellow_l_thin_right.json cc527d048482e5a5a0200e02de47b9867a02109a assets\roadworks\blockstates\marking_yellow_turn_offset_in_center_r.json +4b5ce26a9d03fcbd9a71f5c791d1a3d853afbd78 assets\roadworks\blockstates\marking_yellow_l_thin_right.json 0f9e1b2bebcaad93a3d0e8679ff6ad31f56b8536 assets\roadworks\blockstates\marking_white_t_center_long.json ef83e3c2d7ed8fb617c762142f47c949d41a197c assets\roadworks\models\block\marking_white_t_right.json 7b8fc3c6bd08d8a9ff76187da7e8833f48525991 assets\roadworks\models\item\marking_white_zebra_crossing.json @@ -80,6 +80,7 @@ ab18f595fc067f7e493feec80f6984a649d4fd2b assets\roadworks\models\item\marking_wh 81cf408c01949a8ce8fd5355aa67297f47efe376 assets\roadworks\models\item\marking_white_stub_long_edge_right.json 906976bca33a6a394d3b4a32112d9abce5cda006 assets\roadworks\models\block\marking_yellow_stub_medium_edge_right.json f8320861200fcfc606844c64d2f03077ffc1f8b6 assets\roadworks\blockstates\marking_white_turn_outside.json +201083b91ed663d52a84ecdb89645cbf0e585c93 assets\roadworks\models\item\pedestrian_button.json 27e7a4086c4c15f5208c0ce348e2d65eb7e824b0 assets\roadworks\blockstates\marking_white_edge_dash.json b40294e48ebf0cf928f44bb171f5f434cd9fba0c assets\roadworks\models\block\marking_yellow_stub_long_edge_right.json 5be05e2aa118b006399125f36ba7ddbd61d532d8 assets\roadworks\models\block\marking_white_right_straight_turn_arrows.json @@ -130,7 +131,7 @@ ed5363f8b60be04501113bd6e82d1ae4c86e3dd9 assets\roadworks\blockstates\marking_wh e6bc743a09d9a3837d022d5dc705d572b678926d assets\roadworks\models\block\marking_white_left_turn_arrow.json 7259b027bb55d4abf65e8f35397c080df56b9a97 assets\roadworks\blockstates\marking_white_stub_short_edge_left.json 289998e65735b20860453d5385e1b3bdbdfd8648 assets\roadworks\blockstates\marking_white_right_left_turn_arrows.json -c62576ad328d676ac675e233721663fbfaea9f84 assets\roadworks\blockstates\pedestrian_signal.json +ef21e1ce24e503be09d2d6a4a10c06f99691e9d7 assets\roadworks\blockstates\pedestrian_signal.json b4a615626cb8dc99bed5ec820115d28235068aaa assets\roadworks\models\item\marking_white_right_left_turn_arrows.json 3077557112dec6dabea5ffa7f55a070522a0fee3 assets\roadworks\models\item\channeler.json 54fae1bb46ea3bdbb070ee13d7f2bf6744cc33d8 assets\roadworks\blockstates\thick_post.json @@ -147,8 +148,8 @@ bb400976102761f68568485da8623749fd34f22d assets\roadworks\blockstates\marking_wh 9fa5d5c2815478812cf43d54c6f261d0706e9f11 assets\roadworks\models\item\traffic_cabinet.json 07e57dc321bb836cc2b8ef998f7525d17dad53d3 assets\roadworks\blockstates\marking_white_edge_thick.json eecb80e4212ee5645a9fdddfb679a3fb46dcb74a assets\roadworks\models\item\marking_yellow_t_left_long.json -48415f2b54e97a25db027c0677c0ef3815ea82e2 assets\roadworks\blockstates\marking_yellow_double_center_split_right.json 90525eca0425dfd6c3bd6a9966a21a13a1572ca6 assets\roadworks\blockstates\marking_yellow_center.json +48415f2b54e97a25db027c0677c0ef3815ea82e2 assets\roadworks\blockstates\marking_yellow_double_center_split_right.json 52909fecc1f747a64fe5d89ae9550bea3c121de8 assets\roadworks\models\block\marking_yellow_edge_dash.json 248753f319f3a0f696fda252f3f015321786e8c7 assets\roadworks\models\item\stop_ahead_sign.json 452096532e520a4dabd30277c255ad401ac22358 assets\roadworks\models\block\signal_yellow_right_on.json @@ -158,8 +159,8 @@ bbd6b7a3675a36a636ebb172abbc28f23a725026 assets\roadworks\models\block\signal_gr d10d4a0645533fc19a937b0ab205737650e314f7 assets\roadworks\models\item\marking_white_u_turn_arrow.json e053a00bfae3415adac9b61243f9a973fa3f81d0 assets\roadworks\models\block\marking_white_only.json 668cab2945f3d15d9226f94c5e40191bbf0844f6 assets\roadworks\models\item\marking_yellow_turn_offset_center_out.json -93d2c54cf57602989a2a3a8085669a0cc6726fb4 assets\roadworks\blockstates\marking_white_stub_long_edge_left.json 91afbc4e6141429665825d4688614a70a0a60ae3 assets\roadworks\blockstates\marking_white_l_thin_short_left.json +93d2c54cf57602989a2a3a8085669a0cc6726fb4 assets\roadworks\blockstates\marking_white_stub_long_edge_left.json bbd394a1a4ca289c4d5ca9ba0f19922dfe41c44a assets\roadworks\models\block\marking_yellow_double_center_turn.json 73e7fa6756f5eb17fc1fb7a8af46173e4520b823 assets\roadworks\models\item\marking_white_stub_long_center.json b121ec1e90c342aef2e089e0ee465b486bc64ca2 assets\roadworks\models\item\yield_sign.json @@ -186,6 +187,7 @@ bd33108aa505a4c90faa6154ffc96fdfbb74e794 assets\roadworks\models\item\signal_ahe 526c564ba14a9dfa768cb4acd1fcf835391b1a3c assets\roadworks\models\item\marking_white_stub_short_center.json 40972c537ede4992c96c1ef8b1454e845cb49c92 assets\roadworks\models\block\marking_yellow_t_left_short.json 9d5e5fb7f21653bd1abff6c88c6da3d50cd5e73a assets\roadworks\models\block\marking_yellow_t_right_short.json +a3d3fc505fc709dfa04098ac0dfd0c985cf0d935 assets\roadworks\blockstates\pedestrian_button.json 53ae4b046374421060bf99191b1330e6fd74a302 assets\roadworks\models\item\stop_sign.json 4788e5b1e5c31208e553e82877f89d21e43b54ad assets\roadworks\blockstates\marking_yellow_l_thin_short_left.json c241582292402c90159380f8831b2cbe3103decf assets\roadworks\models\block\marking_white_stub_short_center.json @@ -232,15 +234,15 @@ e520bc30033a9448a19d3d96d0fcfc9ac25cab6b assets\roadworks\models\block\signal_ye 4bad3abc26315972f3e6147be1d62475a8ab0a2c assets\roadworks\models\block\marking_yellow_turn_center.json 6682fb97d65207ce3fb21aef635a76173d9b1c71 assets\roadworks\models\item\marking_yellow_infill.json 4f325dc50eab3d9474224ecae23de07b308003a7 assets\roadworks\blockstates\road_work_ahead_sign.json -6baeda0100f1aab661b9db0ed593657d115676e5 assets\roadworks\models\block\marking_white_center_thick.json ab0b2023f2fd23eb2b7ae397c955e183be691f40 assets\roadworks\blockstates\marking_white_l_right.json +6baeda0100f1aab661b9db0ed593657d115676e5 assets\roadworks\models\block\marking_white_center_thick.json 9b5aaeb25cdaa174ea629d3c27c7c498070e4680 assets\roadworks\models\block\marking_white_t_right_short.json e58b286b17574599311ed085a731898b7a5fe57b assets\roadworks\blockstates\marking_yellow_stub_long_edge_right.json 20105466067cca5a7b6c20dce314ea5821b32384 assets\roadworks\blockstates\marking_yellow_turn_offset_in_center_l.json 0bb8cd297e830ac6af3e9a20bc261ca66d7e7488 assets\roadworks\models\block\signal_green_right_off.json d346af8777e5ecf79c25643b5e6756acab9f7cd3 assets\roadworks\models\block\marking_white_t_left_short.json -496a2873a4fbaa6948bce5059aefb82fc7f0db6e assets\roadworks\models\item\red_beacon.json e9701723872dde089734267a5a7be9ff0c49a94e assets\roadworks\models\item\marking_white_t_left.json +496a2873a4fbaa6948bce5059aefb82fc7f0db6e assets\roadworks\models\item\red_beacon.json adaef6a87fdf35e94fe78dc4fa6b224618a35029 assets\roadworks\models\block\marking_white_center_dash.json 7e35c524ad99453e1a1ef9c7eb9cd37920558ce8 assets\roadworks\blockstates\channeler.json bc32eb539102a06f4322bd5d2e85388174df3297 assets\roadworks\models\item\marking_yellow_t_center.json @@ -294,13 +296,13 @@ ba0e1ffef8152147b266440cb0a19442d5257f6b assets\roadworks\models\block\marking_w d1541496274896d3936a49767efef3b45b50f551 assets\roadworks\models\block\marking_white_l_right.json 4935f207e455f0a8523666003270719c270bc6b4 assets\roadworks\models\item\marking_yellow_t_right.json 66168d9086cfc790576a39f15146dab552d674d6 assets\roadworks\models\item\marking_white_stub_medium_edge_left.json -d1abb49c9e5d9ae999df3eb8ccf40fb406f9a807 assets\roadworks\blockstates\traffic_cone.json 280122404db90168104f65251643776af895e48b assets\roadworks\blockstates\marking_yellow_offset_center.json +d1abb49c9e5d9ae999df3eb8ccf40fb406f9a807 assets\roadworks\blockstates\traffic_cone.json d676b300782143245fbf039694a5e4f557a55d68 assets\roadworks\models\item\yield_ahead_sign.json 6125fb8f0845ce0d525d44dade689070e7cdbeb6 assets\roadworks\models\block\stop_ahead_sign.json 36ba54880e472cb37f05f1af1687d6971515cf24 assets\roadworks\blockstates\marking_yellow_infill.json -fa45a5f67663c865cb11817e6990d3edb6d67fff assets\roadworks\blockstates\marking_white_t_right_long.json 345bca9fefc105823b7cf1978e21cbd124e434ae assets\roadworks\blockstates\thin_post.json +fa45a5f67663c865cb11817e6990d3edb6d67fff assets\roadworks\blockstates\marking_white_t_right_long.json 0d1f864dd99b4efafc543892ccde5d1ce245a11d assets\roadworks\models\item\marking_yellow_turn_offset_out_center_l.json 3a8c8aaae0172da4463c803f49ec913c3f32a81b assets\roadworks\blockstates\marking_yellow_t_center_short.json 41ee1efdafce6c0b5872d00c79475c6c23f37a4f assets\roadworks\models\block\marking_white_rr.json @@ -350,7 +352,7 @@ a3e53c0fad9ba31445e76ba0ce6daf71a3a8ce3b assets\roadworks\models\item\road_work_ cb0a263d702cb5114132acba965350628ec8686d assets\roadworks\blockstates\marking_white_t_center_short.json 880c3e3a18612ed9b78f1d56c51e322b03ff274d assets\roadworks\models\block\signal_green_left_on.json 4a0e0b9f379f8f6ad9cc4b002dbf0ce1941db79c assets\roadworks\models\item\marking_yellow_stub_long_center.json -857be7ba09c433f6b41d26653c62c58c335cfc6f assets\roadworks\models\item\marking_yellow_stub_medium_edge_left.json 7c2ce9e08ee7be19da80b60e4db04d837303db6b assets\roadworks\models\block\signal_green_off.json +857be7ba09c433f6b41d26653c62c58c335cfc6f assets\roadworks\models\item\marking_yellow_stub_medium_edge_left.json 1a4cd09c73f014d28c05a7a610c99b4b05726f25 assets\roadworks\blockstates\marking_white_t_left.json ed3957963c3a49026ae62e9a3ece707c987b9db6 assets\roadworks\blockstates\marking_white_right_turn_arrow.json diff --git a/src/main/generated/assets/roadworks/blockstates/pedestrian_button.json b/src/main/generated/assets/roadworks/blockstates/pedestrian_button.json new file mode 100644 index 0000000..2e3ed0a --- /dev/null +++ b/src/main/generated/assets/roadworks/blockstates/pedestrian_button.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "roadworks:block/pedestrian_button" + } + } +} \ No newline at end of file diff --git a/src/main/generated/assets/roadworks/blockstates/pedestrian_signal.json b/src/main/generated/assets/roadworks/blockstates/pedestrian_signal.json index a52a88a..87f7bca 100644 --- a/src/main/generated/assets/roadworks/blockstates/pedestrian_signal.json +++ b/src/main/generated/assets/roadworks/blockstates/pedestrian_signal.json @@ -1,7 +1,7 @@ { "variants": { "": { - "model": "roadworks:block/pedestrian_walk" + "model": "roadworks:block/pedestrian_signal" } } } \ No newline at end of file diff --git a/src/main/generated/assets/roadworks/lang/en_us.json b/src/main/generated/assets/roadworks/lang/en_us.json index 2dc4c43..c1f2ddf 100644 --- a/src/main/generated/assets/roadworks/lang/en_us.json +++ b/src/main/generated/assets/roadworks/lang/en_us.json @@ -95,6 +95,7 @@ "block.roadworks.marking_yellow_turn_offset_out_center_l": "Center-Offset Outside to Center Turn (Left)", "block.roadworks.marking_yellow_turn_offset_out_center_r": "Center-Offset Outside to Center Turn (Right)", "block.roadworks.marking_yellow_turn_outside": "Outside Yellow Edge Turn Line", + "block.roadworks.pedestrian_button": "Pedestrian Button", "block.roadworks.pedestrian_signal": "Pedestrian Signal", "block.roadworks.post": "Post", "block.roadworks.red_beacon": "Red Beacon", diff --git a/src/main/generated/assets/roadworks/models/item/pedestrian_button.json b/src/main/generated/assets/roadworks/models/item/pedestrian_button.json new file mode 100644 index 0000000..f768d35 --- /dev/null +++ b/src/main/generated/assets/roadworks/models/item/pedestrian_button.json @@ -0,0 +1,3 @@ +{ + "parent": "roadworks:block/pedestrian_button" +} \ No newline at end of file diff --git a/src/main/generated/data/roadworks/tags/blocks/post_mountables.json b/src/main/generated/data/roadworks/tags/blocks/post_mountables.json index 75275cb..742b26b 100644 --- a/src/main/generated/data/roadworks/tags/blocks/post_mountables.json +++ b/src/main/generated/data/roadworks/tags/blocks/post_mountables.json @@ -17,6 +17,7 @@ "roadworks:three_head_traffic_signal_left", "roadworks:five_head_traffic_signal_left", "roadworks:five_head_traffic_signal_right", - "roadworks:pedestrian_signal" + "roadworks:pedestrian_signal", + "roadworks:pedestrian_button" ] } \ No newline at end of file diff --git a/src/main/kotlin/me/znepb/roadworks/Registry.kt b/src/main/kotlin/me/znepb/roadworks/Registry.kt index 6c837e5..efa9544 100644 --- a/src/main/kotlin/me/znepb/roadworks/Registry.kt +++ b/src/main/kotlin/me/znepb/roadworks/Registry.kt @@ -2,6 +2,8 @@ package me.znepb.roadworks import dan200.computercraft.api.peripheral.PeripheralLookup import me.znepb.roadworks.RoadworksMain.ModId +import me.znepb.roadworks.block.PedestrianButton +import me.znepb.roadworks.block.PedestrianButtonBlockEntity import me.znepb.roadworks.block.SignBlock import me.znepb.roadworks.block.SignBlockEntity import me.znepb.roadworks.block.cabinet.TrafficCabinet @@ -137,6 +139,11 @@ object Registry { listOf(ModBlocks.PEDESTRIAN_SIGNAL), ModId("pedestrian_signal_block_entity") ) + val PEDESTRIAN_BUTTON_BLOCK_ENTITY = registerBlockEntities( + ::PedestrianButtonBlockEntity, + listOf(ModBlocks.PEDESTRIAN_BUTTON), + ModId("pedestrian_button_block_entity") + ) } object ModBlocks { @@ -228,6 +235,7 @@ object Registry { FiveHeadTrafficSignalRight(AbstractBlock.Settings.copy(Blocks.STONE_BRICK_WALL)) ) val PEDESTRIAN_SIGNAL = rBlock("pedestrian_signal", PedestrianSignal(AbstractBlock.Settings.copy(Blocks.STONE_BRICK_WALL))) + val PEDESTRIAN_BUTTON = rBlock("pedestrian_button", PedestrianButton(AbstractBlock.Settings.copy(Blocks.STONE_BRICK_WALL))) val YELLOW_INFILL_MARKING = rBlock("marking_yellow_infill", BasicMarking()) val YELLOW_CENTER_DASH_MARKING = rBlock("marking_yellow_center_dash", BasicMarking()) @@ -381,6 +389,7 @@ object Registry { itemSettings()) val FIVE_HEAD_TRAFFIC_SIGNAL_LEFT = rItem(ModBlocks.FIVE_HEAD_TRAFFIC_SIGNAL_LEFT, ::BlockItem, itemSettings()) val PEDESTRIAN_SIGNAL = rItem(ModBlocks.PEDESTRIAN_SIGNAL, ::BlockItem, itemSettings()) + val PEDESTRIAN_BUTTON = rItem(ModBlocks.PEDESTRIAN_BUTTON, ::BlockItem, itemSettings()) val WHITE_INFILL_MARKING = rItem(ModBlocks.WHITE_INFILL_MARKING, ::BlockItem, itemSettings()) val WHITE_ARROW_LEFT_MARKING = rItem(ModBlocks.WHITE_ARROW_LEFT_MARKING, ::BlockItem, itemSettings()) diff --git a/src/main/kotlin/me/znepb/roadworks/RoadworksMain.kt b/src/main/kotlin/me/znepb/roadworks/RoadworksMain.kt index af0abd4..df05258 100644 --- a/src/main/kotlin/me/znepb/roadworks/RoadworksMain.kt +++ b/src/main/kotlin/me/znepb/roadworks/RoadworksMain.kt @@ -1,7 +1,7 @@ package me.znepb.roadworks +import me.znepb.roadworks.block.Linkable import me.znepb.roadworks.block.cabinet.TrafficCabinetBlockEntity -import me.znepb.roadworks.block.signals.AbstractTrafficSignalBlockEntity import net.fabricmc.api.ModInitializer import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents import net.minecraft.block.BlockState @@ -27,7 +27,7 @@ object RoadworksMain : ModInitializer { Registry.init() PlayerBlockBreakEvents.BEFORE.register { world: World, player: PlayerEntity, pos: BlockPos, state: BlockState, blockEntity: BlockEntity? -> - if(blockEntity is AbstractTrafficSignalBlockEntity) { blockEntity.remove() } + if(blockEntity is Linkable) { blockEntity.remove() } if(blockEntity is TrafficCabinetBlockEntity) { blockEntity.remove() } true diff --git a/src/main/kotlin/me/znepb/roadworks/block/Linkable.kt b/src/main/kotlin/me/znepb/roadworks/block/Linkable.kt new file mode 100644 index 0000000..b7a7e16 --- /dev/null +++ b/src/main/kotlin/me/znepb/roadworks/block/Linkable.kt @@ -0,0 +1,108 @@ +package me.znepb.roadworks.block + +import me.znepb.roadworks.block.cabinet.TrafficCabinetBlockEntity +import me.znepb.roadworks.block.post.AbstractPostMountableBlockEntity +import net.minecraft.block.BlockState +import net.minecraft.block.entity.BlockEntityType +import net.minecraft.nbt.NbtCompound +import net.minecraft.util.math.BlockPos +import net.minecraft.world.World + +abstract class Linkable + ( + pos: BlockPos, + state: BlockState, + blockEntityType: BlockEntityType<*>, +) + : AbstractPostMountableBlockEntity(blockEntityType, pos, state) { + protected var linked = false + protected var linkX = 0 + protected var linkY = 0 + protected var linkZ = 0 + + init { + this.markDirty() + } + + companion object { + fun onTick(world: World, pos: BlockPos, state: BlockState, blockEntity: Linkable) { + blockEntity.onTick(world, pos, state, blockEntity) + } + } + + fun getLinkPos() = BlockPos(linkX, linkY, linkZ) + fun isLinked() = linked + + fun link(cabinetBlockEntity: TrafficCabinetBlockEntity): Int? { + val id = cabinetBlockEntity.addDevice(this.pos) + + if (id != null) { + linkX = cabinetBlockEntity.pos.x + linkY = cabinetBlockEntity.pos.y + linkZ = cabinetBlockEntity.pos.z + linked = true + + this.markDirty() + return id + } + + return null + } + + fun unlink() { + linked = false + reset() + this.markDirty() + } + + fun remove() { + // Remove from cabinet when this block is removed + if (linked) { + val blockEntity = this.world?.getBlockEntity(getLinkPos()) + if (blockEntity is TrafficCabinetBlockEntity) { + blockEntity.removeConnection(this.pos) + } + } + } + + private fun reset() { + this.linked = false + this.markDirty() + } + + override fun readExtraNBT(nbt: NbtCompound) { + linked = nbt.getBoolean("linked") + linkX = nbt.getInt("linkX") + linkY = nbt.getInt("linkY") + linkZ = nbt.getInt("linkZ") + } + + override fun writeExtraNBT(nbt: NbtCompound) { + nbt.putBoolean("linked", linked) + nbt.putInt("linkX", linkX) + nbt.putInt("linkY", linkY) + nbt.putInt("linkZ", linkZ) + } + + abstract fun getLinkType(): String + + fun onTick(world: World, pos: BlockPos, state: BlockState, blockEntity: Linkable) { + if (!world.isClient && blockEntity.isLinked() && world.getBlockEntity( + BlockPos( + this.linkX, + this.linkY, + this.linkZ + ) + ) !is TrafficCabinetBlockEntity + ) { + this.unlink() + } + + super.onTick(world) + } + + fun getLinkedCabinet(): TrafficCabinetBlockEntity? { + val blockEntity = this.world?.getBlockEntity(BlockPos(this.linkX, this.linkY, this.linkZ)) + return if (blockEntity != null && blockEntity is TrafficCabinetBlockEntity) blockEntity else null + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/znepb/roadworks/block/PedestrianButton.kt b/src/main/kotlin/me/znepb/roadworks/block/PedestrianButton.kt new file mode 100644 index 0000000..c42a08f --- /dev/null +++ b/src/main/kotlin/me/znepb/roadworks/block/PedestrianButton.kt @@ -0,0 +1,133 @@ +package me.znepb.roadworks.block + +import me.znepb.roadworks.Registry +import me.znepb.roadworks.block.post.AbstractPostMountableBlock +import me.znepb.roadworks.block.post.AbstractPostMountableBlockEntity +import me.znepb.roadworks.util.PostThickness +import me.znepb.roadworks.util.RotateVoxelShape +import net.minecraft.block.Block +import net.minecraft.block.BlockState +import net.minecraft.block.entity.BlockEntity +import net.minecraft.block.entity.BlockEntityTicker +import net.minecraft.block.entity.BlockEntityType +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.server.world.ServerWorld +import net.minecraft.state.StateManager +import net.minecraft.state.property.Properties +import net.minecraft.util.ActionResult +import net.minecraft.util.Hand +import net.minecraft.util.hit.BlockHitResult +import net.minecraft.util.math.BlockPos +import net.minecraft.util.math.Direction +import net.minecraft.util.math.random.Random +import net.minecraft.util.shape.VoxelShape +import net.minecraft.util.shape.VoxelShapes +import net.minecraft.world.BlockView +import net.minecraft.world.World +import net.minecraft.world.event.GameEvent + +class PedestrianButton(settings: Settings) : AbstractPostMountableBlock(settings, ::PedestrianButtonBlockEntity) +{ + init { + defaultState = defaultState.with(Properties.POWERED, false) + } + + companion object { + val SHAPE_POST_NONE = createCuboidShape(6.0, 6.0, 6.5, 10.0, 10.0, 9.0) + val SHAPE_WALL = SHAPE_POST_NONE.offset(0.0, 0.0, (7.0 / 16)) + val SHAPE_POST_THIN = SHAPE_POST_NONE.offset(0.0, 0.0, (-2.0 / 16)) + val SHAPE_POST_MEDIUM = SHAPE_POST_NONE.offset(0.0, 0.0, (-3.0 / 16)) + val SHAPE_POST_THICK = SHAPE_POST_NONE.offset(0.0, 0.0, (-3.0 / 16)) + } + + override fun onUse( + state: BlockState, + world: World, + pos: BlockPos?, + player: PlayerEntity?, + hand: Hand?, + hit: BlockHitResult? + ): ActionResult? { + return if (state.get(Properties.POWERED) as Boolean) { + ActionResult.CONSUME + } else { + world.setBlockState(pos, state.with(Properties.POWERED, true) as BlockState, Block.NOTIFY_LISTENERS + Block.NOTIFY_NEIGHBORS) + world.scheduleBlockTick(pos, this, 10) + world.emitGameEvent(player, GameEvent.BLOCK_ACTIVATE, pos) + this.blockEntity?.press() + ActionResult.success(world.isClient) + } + } + + override fun scheduledTick(state: BlockState, world: ServerWorld, pos: BlockPos?, random: Random?) { + if (state.get(Properties.POWERED) as Boolean) { + world.setBlockState(pos, state.with(Properties.POWERED, false) as BlockState, Block.NOTIFY_LISTENERS + Block.NOTIFY_NEIGHBORS) + } + } + + override fun getWeakRedstonePower( + state: BlockState, + world: BlockView?, + pos: BlockPos?, + direction: Direction? + ): Int { + return if (state.get(Properties.POWERED) as Boolean) 15 else 0 + } + + override fun getStrongRedstonePower( + state: BlockState, + world: BlockView?, + pos: BlockPos?, + direction: Direction + ): Int { + return if (state.get(Properties.POWERED) as Boolean && this.blockEntity?.facing?.let { + Direction.fromHorizontal( + it + ) + } == direction) 15 else 0 + } + + override fun emitsRedstonePower(state: BlockState?): Boolean { + return true + } + + override fun appendProperties(builder: StateManager.Builder) { + builder.add(*arrayOf(Properties.POWERED)) + } + + override fun getTicker( + world: World, + state: BlockState, + type: BlockEntityType + ): BlockEntityTicker? { + if (world.isClient) return null + return checkType(type, Registry.ModBlockEntities.PEDESTRIAN_BUTTON_BLOCK_ENTITY, AbstractPostMountableBlockEntity.Companion::onTick) + } + + override fun getAttachmentShape(world: BlockView, pos: BlockPos): VoxelShape { + if(world.getBlockEntity(pos) !is PedestrianButtonBlockEntity) return VoxelShapes.empty() + + val blockEntity = world.getBlockEntity(pos) as PedestrianButtonBlockEntity + + return if(blockEntity.wall) { + RotateVoxelShape.rotateVoxelShape( + SHAPE_WALL, + Direction.NORTH, + Direction.byId(blockEntity.facing) + ) + } else { + val maxThickness = AbstractPostMountableBlockEntity.getThickest(blockEntity) + + RotateVoxelShape.rotateVoxelShape( + when(maxThickness) { + PostThickness.THIN -> SHAPE_POST_THIN + PostThickness.MEDIUM -> SHAPE_POST_MEDIUM + PostThickness.THICK -> SHAPE_POST_THICK + else -> SHAPE_POST_NONE + }, + Direction.NORTH, + Direction.byId(blockEntity.facing) + ) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/znepb/roadworks/block/PedestrianButtonBlockEntity.kt b/src/main/kotlin/me/znepb/roadworks/block/PedestrianButtonBlockEntity.kt new file mode 100644 index 0000000..55201fa --- /dev/null +++ b/src/main/kotlin/me/znepb/roadworks/block/PedestrianButtonBlockEntity.kt @@ -0,0 +1,28 @@ +package me.znepb.roadworks.block + +import me.znepb.roadworks.Registry.ModBlockEntities.PEDESTRIAN_BUTTON_BLOCK_ENTITY +import net.minecraft.block.BlockState +import net.minecraft.util.math.BlockPos +import net.minecraft.world.World + +class PedestrianButtonBlockEntity( + pos: BlockPos, + state: BlockState, +) : Linkable(pos, state, PEDESTRIAN_BUTTON_BLOCK_ENTITY) { + init { + this.markDirty() + } + + fun press() { + val id = this.getLinkedCabinet()?.getConnectionIdentifierFromBlockPos(this.pos) + id?.let { this.getLinkedCabinet()?.peripheral?.notifyButtonPush(it) } + } + + override fun getLinkType(): String = "button" + + companion object { + fun onTick(world: World, pos: BlockPos, state: BlockState, blockEntity: PedestrianButtonBlockEntity) { + blockEntity.onTick(world, pos, state, blockEntity) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/znepb/roadworks/block/cabinet/TrafficCabinetBlockEntity.kt b/src/main/kotlin/me/znepb/roadworks/block/cabinet/TrafficCabinetBlockEntity.kt index cf959e2..072e94e 100644 --- a/src/main/kotlin/me/znepb/roadworks/block/cabinet/TrafficCabinetBlockEntity.kt +++ b/src/main/kotlin/me/znepb/roadworks/block/cabinet/TrafficCabinetBlockEntity.kt @@ -1,10 +1,12 @@ package me.znepb.roadworks.block.cabinet -import me.znepb.roadworks.RoadworksMain.logger import me.znepb.roadworks.Registry +import me.znepb.roadworks.RoadworksMain.logger +import me.znepb.roadworks.block.Linkable +import me.znepb.roadworks.block.PedestrianButtonBlockEntity +import me.znepb.roadworks.block.signals.AbstractTrafficSignalBlockEntity import me.znepb.roadworks.block.signals.SignalLight import me.znepb.roadworks.block.signals.SignalType -import me.znepb.roadworks.block.signals.AbstractTrafficSignalBlockEntity import me.znepb.roadworks.util.MiscUtils.Companion.blockPosFromNbtIntArray import me.znepb.roadworks.util.MiscUtils.Companion.blockPosToNbtIntArray import net.minecraft.block.BlockState @@ -13,27 +15,24 @@ import net.minecraft.nbt.NbtCompound import net.minecraft.nbt.NbtList import net.minecraft.util.math.BlockPos import net.minecraft.world.World -import java.lang.Exception -import kotlin.collections.HashMap class TrafficCabinetBlockEntity( pos: BlockPos, state: BlockState ) : BlockEntity(Registry.ModBlockEntities.CABINET_BLOCK_ENTITY, pos, state) { val peripheral = TrafficCabinetPeripheral(this) - private var signals = SignalConnections() - private val idTypeCache = HashMap() - private var queue = HashMap>() - - fun getTotalDevices() = signals.getAmount() - fun getSignals() = signals - fun getTotalSignals(): Int = signals.getAmount() - fun getTypeOfId(id: Int): SignalType? { + private var connections = Connections() + private val idTypeCache = HashMap() + private var signalSetQueue = HashMap>() + + fun getTotalDevices() = connections.getAmount() + fun getConnections() = connections + fun getTypeOfId(id: Int): String? { return idTypeCache[id] } - fun getSignalBlockEntityFromId(id: Int): BlockEntity? { - val result = signals.getSignal(id) ?: return null + fun getConnectionBlockEntityFromID(id: Int): BlockEntity? { + val result = connections.get(id) ?: return null if(world != null) { val blockPos = result.getPos() @@ -44,8 +43,8 @@ class TrafficCabinetBlockEntity( entity } else { // Entity disappeared! - removeSignal(id) - logger.warn("Signal with ID $id was removed incorrectly, removing now") + removeConnection(id) + logger.warn("Connection with ID $id was removed incorrectly, removing now") null } } @@ -54,19 +53,27 @@ class TrafficCabinetBlockEntity( return null } - fun getSignalIdentifierFromBlockPos(pos: BlockPos): Int? { - return signals.getSignal(pos)?.getId() + fun getConnectionIdentifierFromBlockPos(pos: BlockPos): Int? { + return connections.get(pos)?.getId() + } + + fun addDevice(pos: BlockPos): Int? { + val blockEntity = this.world?.getBlockEntity(pos) + + if(blockEntity is AbstractTrafficSignalBlockEntity) return addSignal(pos) + else if(blockEntity is PedestrianButtonBlockEntity) return addButton(pos) + else return null } fun addSignal(pos: BlockPos): Int? { val blockEntity = this.world?.getBlockEntity(pos) if(blockEntity is AbstractTrafficSignalBlockEntity) { - val newSignal = signals.addSignal(pos) + val newSignal = connections.add(pos) blockEntity.getSignalType().lights.forEach { blockEntity.setSignal(it, it.genericType == SignalLight.RED || it.isGeneric && it == SignalLight.RED) } - idTypeCache[newSignal.getId()] = blockEntity.getSignalType() + idTypeCache[newSignal.getId()] = blockEntity.getLinkType() this.markDirty() return newSignal.getId() } @@ -74,25 +81,38 @@ class TrafficCabinetBlockEntity( return null } - fun removeSignal(pos: BlockPos) { - getSignalIdentifierFromBlockPos(pos)?.let { removeSignal(it) } + fun addButton(pos: BlockPos): Int? { + val blockEntity = this.world?.getBlockEntity(pos) + + if(blockEntity is PedestrianButtonBlockEntity) { + val newButton = connections.add(pos) + idTypeCache[newButton.getId()] = blockEntity.getLinkType() + this.markDirty() + return newButton.getId() + } + + return null + } + + fun removeConnection(pos: BlockPos) { + getConnectionIdentifierFromBlockPos(pos)?.let { removeConnection(it) } } - fun removeSignal(identifier: Int) { - val signal = signals.getSignal(identifier) ?: return + fun removeConnection(identifier: Int) { + val connection = connections.get(identifier) ?: return - val blockEntity = world?.getBlockEntity(signal.getPos()) - if(blockEntity is AbstractTrafficSignalBlockEntity) { + val blockEntity = world?.getBlockEntity(connection.getPos()) + if(blockEntity is Linkable) { blockEntity.unlink() } - signals.removeSignal(signal.getId()) + connections.remove(connection.getId()) this.markDirty() } fun remove() { - signals.getSignals().forEach { - val signal = signals.getSignal(it.getId()) ?: return + connections.getAll().forEach { + val signal = connections.get(it.getId()) ?: return val blockEntity = world?.getBlockEntity(signal.getPos()) if(blockEntity is AbstractTrafficSignalBlockEntity) { @@ -103,32 +123,32 @@ class TrafficCabinetBlockEntity( override fun readNbt(nbt: NbtCompound) { super.readNbt(nbt) - signals.fromNbtList(nbt.get("signals") as NbtList) + connections.fromNbtList(nbt.get("connections") as NbtList) this.markDirty() } override fun writeNbt(nbt: NbtCompound) { - nbt.put("signals", signals.toNbtList()) + nbt.put("connections", connections.toNbtList()) super.writeNbt(nbt) } fun queueSignalSet(id: Int, signalLight: SignalLight, value: Boolean) { - val idQueue = queue.getOrPut(id) { hashMapOf() } + val idQueue = signalSetQueue.getOrPut(id) { hashMapOf() } idQueue[signalLight] = value } fun onTick(world: World, pos: BlockPos, state: BlockState) { - if(queue.isNotEmpty()) { - signals.getSignals().forEach { - val item = queue[it.getId()] + if(signalSetQueue.isNotEmpty()) { + connections.getAll().forEach { + val item = signalSetQueue[it.getId()] if(item != null) { val type = getTypeOfId(it.getId()) - val signalBlockEntity = getSignalBlockEntityFromId(it.getId()) + val signalBlockEntity = getConnectionBlockEntityFromID(it.getId()) if(signalBlockEntity is AbstractTrafficSignalBlockEntity) { - type?.lights?.forEach { light -> + type?.let { it1 -> SignalType.fromType(it1) }!!.lights.forEach { light -> if (item[light] != null) { signalBlockEntity.queueSignalSet(light, item[light]!!) } @@ -138,21 +158,21 @@ class TrafficCabinetBlockEntity( } } - this.signals.getSignals().forEach { + this.connections.getAll().forEach { if(this.idTypeCache[it.getId()] == null) { try { val blockEntity = this.world?.getBlockEntity(it.getPos()) - if(blockEntity is AbstractTrafficSignalBlockEntity) { - this.idTypeCache[it.getId()] = blockEntity.getSignalType() + if(blockEntity is Linkable) { + this.idTypeCache[it.getId()] = blockEntity.getLinkType() } } catch(_: Exception) {} } } } - class SignalConnections { - class SignalConnection(private val id: Int, private val pos: BlockPos) { + class Connections { + class Connection(private val id: Int, private val pos: BlockPos) { fun getId() = id fun getPos() = pos @@ -164,46 +184,46 @@ class TrafficCabinetBlockEntity( } companion object { - fun fromNbt(nbt: NbtCompound): SignalConnection { - return SignalConnection(nbt.getInt("id"), blockPosFromNbtIntArray(nbt.getIntArray("pos"))) + fun fromNbt(nbt: NbtCompound): Connection { + return Connection(nbt.getInt("id"), blockPosFromNbtIntArray(nbt.getIntArray("pos"))) } } } - private val list = mutableListOf() + private val list = mutableListOf() fun getNextId(): Int { var id = 1 - while(getSignal(id) != null) { + while(get(id) != null) { id++ } return id } - fun addSignal(id: Int, pos: BlockPos): SignalConnection { - if(getSignal(id) != null) throw IllegalArgumentException("ID $id already exists") - if(getSignal(pos) != null) throw IllegalArgumentException("Signal at $pos is already connected") - val newConnection = SignalConnection(id, pos) + fun add(id: Int, pos: BlockPos): Connection { + if(get(id) != null) throw IllegalArgumentException("ID $id already exists") + if(get(pos) != null) throw IllegalArgumentException("Signal at $pos is already connected") + val newConnection = Connection(id, pos) list.add(newConnection) return newConnection } - fun addSignal(pos: BlockPos): SignalConnection { - return this.addSignal(getNextId(), pos) + fun add(pos: BlockPos): Connection { + return this.add(getNextId(), pos) } - fun getSignal(id: Int): SignalConnection? { + fun get(id: Int): Connection? { val filtered = list.filter { it.getId() == id } return if(filtered.isNotEmpty()) filtered[0] else null } - fun getSignal(blockPos: BlockPos): SignalConnection? { + fun get(blockPos: BlockPos): Connection? { val filtered = list.filter { it.getPos() == blockPos } return if(filtered.isNotEmpty()) filtered[0] else null } - fun removeSignal(id: Int) { + fun remove(id: Int) { list.remove(list.filter { it.getId() == id }[0]) } @@ -214,7 +234,7 @@ class TrafficCabinetBlockEntity( && it.getType("pos") == NbtCompound.INT_ARRAY_TYPE && it.getType("id") == NbtCompound.INT_TYPE ) { - this.list.add(SignalConnection.fromNbt(it)) + this.list.add(Connection.fromNbt(it)) } } } @@ -227,7 +247,7 @@ class TrafficCabinetBlockEntity( return list } - fun getSignals() = list + fun getAll() = list fun getAmount() = list.size } diff --git a/src/main/kotlin/me/znepb/roadworks/block/cabinet/TrafficCabinetPeripheral.kt b/src/main/kotlin/me/znepb/roadworks/block/cabinet/TrafficCabinetPeripheral.kt index 5e5a9f9..0abe4f1 100644 --- a/src/main/kotlin/me/znepb/roadworks/block/cabinet/TrafficCabinetPeripheral.kt +++ b/src/main/kotlin/me/znepb/roadworks/block/cabinet/TrafficCabinetPeripheral.kt @@ -3,24 +3,41 @@ package me.znepb.roadworks.block.cabinet import dan200.computercraft.api.lua.LuaException import dan200.computercraft.api.lua.LuaFunction import dan200.computercraft.api.lua.ObjectLuaTable +import dan200.computercraft.api.peripheral.IComputerAccess import dan200.computercraft.api.peripheral.IPeripheral -import me.znepb.roadworks.block.signals.AbstractTrafficSignalBlockEntity +import me.znepb.roadworks.RoadworksMain.logger import me.znepb.roadworks.block.signals.SignalLight import me.znepb.roadworks.block.signals.SignalType class TrafficCabinetPeripheral(val blockEntity: TrafficCabinetBlockEntity) : IPeripheral { override fun getType() = "traffic_cabinet" override fun getTarget() = blockEntity + private val attachedComputers: MutableList = mutableListOf() - fun getSignalBlockEntity(id: Int): AbstractTrafficSignalBlockEntity? { - val signal = blockEntity.getSignalBlockEntityFromId(id) - return if(signal is AbstractTrafficSignalBlockEntity) signal else null + override fun attach(computer: IComputerAccess) { + this.attachedComputers.add(computer) + logger.info("Attach " + computer.id) + super.attach(computer) + } + + override fun detach(computer: IComputerAccess) { + this.attachedComputers.remove(computer) + logger.info("Detach " + computer.id) + super.detach(computer) + } + + fun notifyButtonPush(id: Int) { + this.attachedComputers.forEach { + it.queueEvent("cabinet_trigger", it.attachmentName, "pedestrian_button", id) + } + + logger.info("Push Button " + id) } /// Returns whether this traffic cabinet has the specified ID available. @LuaFunction fun hasId(id: Int): Boolean { - blockEntity.getSignals().getSignals().forEach { + blockEntity.getConnections().getAll().forEach { if(it.getId() == id) { return true } @@ -38,11 +55,11 @@ class TrafficCabinetPeripheral(val blockEntity: TrafficCabinetBlockEntity) : IPe /// Gets the signal's type from its ID. @LuaFunction - fun getSignalType(id: Int): String? { + fun getType(id: Int): String? { if(!hasId(id)) return null - blockEntity.getSignals().getSignals().forEach { - return blockEntity.getTypeOfId(it.getId())?.type + blockEntity.getConnections().getAll().forEach { + return blockEntity.getTypeOfId(it.getId()) } return null @@ -50,11 +67,11 @@ class TrafficCabinetPeripheral(val blockEntity: TrafficCabinetBlockEntity) : IPe /// Gets signals of a type. @LuaFunction - fun getSignalsOfType(type: String): List { + fun getConnectionsOfType(type: String): List { val list = mutableListOf() - blockEntity.getSignals().getSignals().forEach { - if(blockEntity.getTypeOfId(it.getId())?.type == type) { + blockEntity.getConnections().getAll().forEach { + if(blockEntity.getTypeOfId(it.getId()) == type) { list.add(it.getId()) } } @@ -64,13 +81,13 @@ class TrafficCabinetPeripheral(val blockEntity: TrafficCabinetBlockEntity) : IPe /// Gets all signals on this traffic cabinet. @LuaFunction - fun getSignals(): List { + fun getConnections(): List { val signals = mutableListOf(); - blockEntity.getSignals().getSignals().forEach { + blockEntity.getConnections().getAll().forEach { val map = hashMapOf() map["id"] = it.getId() - map["type"] = blockEntity.getTypeOfId(it.getId())?.type + map["type"] = blockEntity.getTypeOfId(it.getId()) signals.add(ObjectLuaTable(map)) } @@ -81,7 +98,7 @@ class TrafficCabinetPeripheral(val blockEntity: TrafficCabinetBlockEntity) : IPe /// Sets the balue of a beacon. @LuaFunction fun setBeacon(id: Int, on: Boolean): Boolean { - return when (val type = blockEntity.getTypeOfId(id)) { + return when (val type = blockEntity.getTypeOfId(id)?.let { SignalType.fromType(it) }) { SignalType.ONE_HEAD_RED -> { blockEntity.queueSignalSet(id, SignalLight.RED, on) true @@ -103,7 +120,7 @@ class TrafficCabinetPeripheral(val blockEntity: TrafficCabinetBlockEntity) : IPe /// Sets the colors of a three-head signal. @LuaFunction fun setThreeHead(id: Int, red: Boolean, yellow: Boolean, green: Boolean): Boolean { - when (val type = blockEntity.getTypeOfId(id)) { + when (val type = blockEntity.getTypeOfId(id)?.let { SignalType.fromType(it) }) { SignalType.THREE_HEAD -> { blockEntity.queueSignalSet(id, SignalLight.RED, red) blockEntity.queueSignalSet(id, SignalLight.YELLOW, yellow) @@ -135,7 +152,7 @@ class TrafficCabinetPeripheral(val blockEntity: TrafficCabinetBlockEntity) : IPe @LuaFunction fun setFiveHead(id: Int, red: Boolean, yellowLeft: Boolean, greenLeft: Boolean, yellowRight: Boolean, greenRight: Boolean): Boolean { - return when (val type = blockEntity.getTypeOfId(id)) { + return when (val type = blockEntity.getTypeOfId(id)?.let { SignalType.fromType(it) }) { SignalType.FIVE_HEAD_LEFT -> { blockEntity.queueSignalSet(id, SignalLight.RED, red) blockEntity.queueSignalSet(id, SignalLight.YELLOW, yellowRight) @@ -159,7 +176,7 @@ class TrafficCabinetPeripheral(val blockEntity: TrafficCabinetBlockEntity) : IPe /// Sets the state of a pedestrian signal. @LuaFunction fun setPedestrianSignal(id: Int, walk: Boolean): Boolean { - return when (val type = blockEntity.getTypeOfId(id)) { + return when (val type = blockEntity.getTypeOfId(id)?.let { SignalType.fromType(it) }) { SignalType.PEDESTRIAN -> { blockEntity.queueSignalSet(id, SignalLight.WALK, walk) blockEntity.queueSignalSet(id, SignalLight.DONT_WALK, !walk) diff --git a/src/main/kotlin/me/znepb/roadworks/block/post/AbstractPostMountableBlock.kt b/src/main/kotlin/me/znepb/roadworks/block/post/AbstractPostMountableBlock.kt index a10c349..1d7539d 100644 --- a/src/main/kotlin/me/znepb/roadworks/block/post/AbstractPostMountableBlock.kt +++ b/src/main/kotlin/me/znepb/roadworks/block/post/AbstractPostMountableBlock.kt @@ -20,6 +20,7 @@ abstract class AbstractPostMountableBlock : BlockWithEntity(settings), BlockEntityProvider { private var placementContext: ItemPlacementContext? = null + protected var blockEntity: T? = null override fun isTransparent(state: BlockState?, world: BlockView?, pos: BlockPos?): Boolean { return true @@ -47,6 +48,7 @@ abstract class AbstractPostMountableBlock override fun createBlockEntity(pos: BlockPos, state: BlockState): BlockEntity { val be = blockEntityFactory.create(pos, state) this.placementContext?.let { be.setContext(it) } + this.blockEntity = be return be } diff --git a/src/main/kotlin/me/znepb/roadworks/block/signals/AbstractTrafficSignalBlockEntity.kt b/src/main/kotlin/me/znepb/roadworks/block/signals/AbstractTrafficSignalBlockEntity.kt index b2a9595..78f7867 100644 --- a/src/main/kotlin/me/znepb/roadworks/block/signals/AbstractTrafficSignalBlockEntity.kt +++ b/src/main/kotlin/me/znepb/roadworks/block/signals/AbstractTrafficSignalBlockEntity.kt @@ -1,13 +1,9 @@ package me.znepb.roadworks.block.signals -import me.znepb.roadworks.block.cabinet.TrafficCabinetBlockEntity -import me.znepb.roadworks.block.post.AbstractPostMountableBlockEntity +import me.znepb.roadworks.block.Linkable import net.minecraft.block.BlockState import net.minecraft.block.entity.BlockEntityType import net.minecraft.nbt.NbtCompound -import net.minecraft.network.listener.ClientPlayPacketListener -import net.minecraft.network.packet.Packet -import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket import net.minecraft.util.math.BlockPos import net.minecraft.world.World @@ -18,12 +14,8 @@ abstract class AbstractTrafficSignalBlockEntity blockEntityType: BlockEntityType<*>, private val signalType: SignalType ) - : AbstractPostMountableBlockEntity(blockEntityType, pos, state) + : Linkable(pos, state, blockEntityType) { - protected var linked = false - protected var linkX = 0 - protected var linkY = 0 - protected var linkZ = 0 protected val signalState = signalStateMapFromList() protected val queue = HashMap() @@ -45,52 +37,8 @@ abstract class AbstractTrafficSignalBlockEntity } fun getSignalType() = signalType - fun getLinkPos() = BlockPos(linkX, linkY, linkZ) - fun isLinked() = linked fun getLights() = signalType.lights - fun link(cabinetBlockEntity: TrafficCabinetBlockEntity): Int? { - val id = cabinetBlockEntity.addSignal(this.pos) - - if(id != null) { - linkX = cabinetBlockEntity.pos.x - linkY = cabinetBlockEntity.pos.y - linkZ = cabinetBlockEntity.pos.z - linked = true - - this.markDirty() - - SignalLight.getReds(cachedState.block).forEach { queueSignalSet(it, true) } - SignalLight.getGreens(cachedState.block).forEach { queueSignalSet(it, false) } - SignalLight.getYellows(cachedState.block).forEach { queueSignalSet(it, false) } - - return id - } - - return null - } - - fun unlink() { - linked = false - reset() - this.markDirty() - } - - fun remove() { - // Remove from cabinet when this block is removed - if(linked) { - val blockEntity = this.world?.getBlockEntity(getLinkPos()) - if(blockEntity is TrafficCabinetBlockEntity) { - blockEntity.removeSignal(this.pos) - } - } - } - - private fun reset() { - this.linked = false - this.markDirty() - } - fun queueSignalSet(signalType: SignalLight, value: Boolean) { queue[signalType] = value } @@ -110,10 +58,7 @@ abstract class AbstractTrafficSignalBlockEntity signalState[it] = nbt.getBoolean(it.light) } - linked = nbt.getBoolean("linked") - linkX = nbt.getInt("linkX") - linkY = nbt.getInt("linkY") - linkZ = nbt.getInt("linkZ") + super.readExtraNBT(nbt) } override fun writeExtraNBT(nbt: NbtCompound) { @@ -121,31 +66,18 @@ abstract class AbstractTrafficSignalBlockEntity signalState[it]?.let { it1 -> nbt.putBoolean(it.light, it1) } } - nbt.putBoolean("linked", linked) - nbt.putInt("linkX", linkX) - nbt.putInt("linkY", linkY) - nbt.putInt("linkZ", linkZ) + super.writeExtraNBT(nbt) } - override fun toUpdatePacket(): Packet { - return BlockEntityUpdateS2CPacket.create(this) - } - - override fun toInitialChunkDataNbt(): NbtCompound? { - return createNbt() - } + override fun getLinkType() = this.getSignalType().type fun onTick(world: World, pos: BlockPos, state: BlockState, blockEntity: AbstractTrafficSignalBlockEntity) { - if(!world.isClient) { - if (!blockEntity.isLinked()) { - val ticks = world.server?.ticks - if (ticks != null) { - SignalLight.getReds(state.block).forEach { queueSignalSet(it, (ticks % 40) > 20) } - SignalLight.getGreens(state.block).forEach { queueSignalSet(it, false) } - SignalLight.getYellows(state.block).forEach { queueSignalSet(it, false) } - } - } else if (world.getBlockEntity(BlockPos(this.linkX, this.linkY, this.linkZ)) !is TrafficCabinetBlockEntity) { - this.unlink() + if(!world.isClient && !blockEntity.isLinked()) { + val ticks = world.server?.ticks + if (ticks != null) { + SignalLight.getReds(state.block).forEach { queueSignalSet(it, (ticks % 40) > 20) } + SignalLight.getGreens(state.block).forEach { queueSignalSet(it, false) } + SignalLight.getYellows(state.block).forEach { queueSignalSet(it, false) } } } diff --git a/src/main/kotlin/me/znepb/roadworks/block/signals/PedestrianSignal.kt b/src/main/kotlin/me/znepb/roadworks/block/signals/PedestrianSignal.kt index 120c651..58c2670 100644 --- a/src/main/kotlin/me/znepb/roadworks/block/signals/PedestrianSignal.kt +++ b/src/main/kotlin/me/znepb/roadworks/block/signals/PedestrianSignal.kt @@ -28,8 +28,9 @@ class PedestrianSignal } override fun getAttachmentShape(world: BlockView, pos: BlockPos): VoxelShape { - val blockEntity = world.getBlockEntity(pos) as AbstractTrafficSignalBlockEntity? - ?: return VoxelShapes.empty() + if(world.getBlockEntity(pos) !is PedestrianSignalBlockEntity) return VoxelShapes.empty(); + + val blockEntity = world.getBlockEntity(pos) as PedestrianSignalBlockEntity return if(blockEntity.wall) { RotateVoxelShape.rotateVoxelShape( diff --git a/src/main/kotlin/me/znepb/roadworks/datagen/LanguageProvider.kt b/src/main/kotlin/me/znepb/roadworks/datagen/LanguageProvider.kt index 7b3b8aa..d59ae9b 100644 --- a/src/main/kotlin/me/znepb/roadworks/datagen/LanguageProvider.kt +++ b/src/main/kotlin/me/znepb/roadworks/datagen/LanguageProvider.kt @@ -38,6 +38,7 @@ class LanguageProvider(output: FabricDataOutput) : FabricLanguageProvider(output translationBuilder.add(Registry.ModBlocks.FIVE_HEAD_TRAFFIC_SIGNAL_LEFT, "Five-head Traffic Signal Left") translationBuilder.add(Registry.ModBlocks.FIVE_HEAD_TRAFFIC_SIGNAL_RIGHT, "Five-head Traffic Signal Right") translationBuilder.add(Registry.ModBlocks.PEDESTRIAN_SIGNAL, "Pedestrian Signal") + translationBuilder.add(Registry.ModBlocks.PEDESTRIAN_BUTTON, "Pedestrian Button") translationBuilder.add(Registry.ModBlocks.WHITE_INFILL_MARKING, "White Infill Marking") translationBuilder.add(Registry.ModBlocks.WHITE_ARROW_LEFT_MARKING, "White Left Arrow Marking") diff --git a/src/main/kotlin/me/znepb/roadworks/datagen/ModelProvider.kt b/src/main/kotlin/me/znepb/roadworks/datagen/ModelProvider.kt index d069052..640b1ef 100644 --- a/src/main/kotlin/me/znepb/roadworks/datagen/ModelProvider.kt +++ b/src/main/kotlin/me/znepb/roadworks/datagen/ModelProvider.kt @@ -71,6 +71,7 @@ class ModelProvider(output: FabricDataOutput) : FabricModelProvider(output) { generator.blockStateCollector.accept(createSingletonBlockState(Registry.ModBlocks.FIVE_HEAD_TRAFFIC_SIGNAL_LEFT, ModId("block/five_head_traffic_signal_left"))) generator.blockStateCollector.accept(createSingletonBlockState(Registry.ModBlocks.FIVE_HEAD_TRAFFIC_SIGNAL_RIGHT, ModId("block/five_head_traffic_signal_right"))) generator.blockStateCollector.accept(createSingletonBlockState(Registry.ModBlocks.PEDESTRIAN_SIGNAL, ModId("block/pedestrian_signal"))) + generator.blockStateCollector.accept(createSingletonBlockState(Registry.ModBlocks.PEDESTRIAN_BUTTON, ModId("block/pedestrian_button"))) generator.blockStateCollector.accept(createSingletonBlockState(Registry.ModBlocks.TRAFFIC_CONE, ModId( "block/traffic_cone"))) generator.blockStateCollector.accept(createSingletonBlockState(Registry.ModBlocks.BOLLARD_THIN, ModId("block/bollard_thin"))) diff --git a/src/main/kotlin/me/znepb/roadworks/datagen/TagProvider.kt b/src/main/kotlin/me/znepb/roadworks/datagen/TagProvider.kt index d347179..e3a29e2 100644 --- a/src/main/kotlin/me/znepb/roadworks/datagen/TagProvider.kt +++ b/src/main/kotlin/me/znepb/roadworks/datagen/TagProvider.kt @@ -151,7 +151,8 @@ class TagProvider(output: FabricDataOutput, completableFuture: CompletableFuture THREE_HEAD_TRAFFIC_SIGNAL_LEFT, FIVE_HEAD_TRAFFIC_SIGNAL_LEFT, FIVE_HEAD_TRAFFIC_SIGNAL_RIGHT, - PEDESTRIAN_SIGNAL + PEDESTRIAN_SIGNAL, + PEDESTRIAN_BUTTON ) } } diff --git a/src/main/kotlin/me/znepb/roadworks/item/Linker.kt b/src/main/kotlin/me/znepb/roadworks/item/Linker.kt index 5dbb7ee..3db1393 100644 --- a/src/main/kotlin/me/znepb/roadworks/item/Linker.kt +++ b/src/main/kotlin/me/znepb/roadworks/item/Linker.kt @@ -1,8 +1,8 @@ package me.znepb.roadworks.item import me.znepb.roadworks.Registry +import me.znepb.roadworks.block.Linkable import me.znepb.roadworks.block.cabinet.TrafficCabinetBlockEntity -import me.znepb.roadworks.block.signals.AbstractTrafficSignalBlockEntity import net.minecraft.block.entity.BlockEntity import net.minecraft.block.entity.BlockEntityType import net.minecraft.entity.player.PlayerEntity @@ -21,38 +21,38 @@ class Linker(settings: Settings) : Item(settings) { var linkingWith: BlockEntityType<*>? = null companion object { - val MAX_DEVICES = 16 - val MAX_SIGNAL_DISTANCE = 32.0 + val MAX_DEVICES = 24 + val MAX_DEVICE_DISTANCE = 48.0 } - private fun getCabinet(blockEntity: AbstractTrafficSignalBlockEntity, context: ItemUsageContext): TrafficCabinetBlockEntity? { + private fun getCabinet(blockEntity: Linkable, context: ItemUsageContext): TrafficCabinetBlockEntity? { val be = context.world?.getBlockEntity(blockEntity.getLinkPos()) return if(be is TrafficCabinetBlockEntity) { be } else null } private fun unlink( - signal: AbstractTrafficSignalBlockEntity, + device: Linkable, cabinet: TrafficCabinetBlockEntity, context: ItemUsageContext) { - signal.unlink() - cabinet.removeSignal(context.blockPos) - context.player?.sendMessage(Text.literal("Signal unlinked"), true) + device.unlink() + cabinet.removeConnection(context.blockPos) + context.player?.sendMessage(Text.literal("Device unlinked"), true) } private fun alreadyLinked( - signal: AbstractTrafficSignalBlockEntity, + device: Linkable, cabinet: TrafficCabinetBlockEntity, context: ItemUsageContext ) { if(context.player?.isSneaking == true) { - unlink(signal, cabinet, context) + unlink(device, cabinet, context) } else { context.player?.sendMessage( // Notify player this is already linked Text.literal( - "Block is already linked as ID " + - "${cabinet.getSignalIdentifierFromBlockPos(context.blockPos)}. " + + "Device is already linked as ID " + + "${cabinet.getConnectionIdentifierFromBlockPos(context.blockPos)}. " + "Crouch-Right click to unlink." ), true @@ -62,14 +62,14 @@ class Linker(settings: Settings) : Item(settings) { private fun linkCabinet(cabinet: TrafficCabinetBlockEntity, context: ItemUsageContext): ActionResult { if(cabinet.getTotalDevices() > MAX_DEVICES) { - // Too many signals connected to this box! + // Too many devices connected to this box! context.player?.sendMessage(Text.literal("There are too many devices connected to this box! Max is $MAX_DEVICES"), true) return ActionResult.SUCCESS } linking = context.blockPos linkingWith = Registry.ModBlockEntities.CABINET_BLOCK_ENTITY - context.player?.sendMessage(Text.literal("Right-click a traffic signal to link to this cabinet"), true) + context.player?.sendMessage(Text.literal("Right-click a traffic device to link to this cabinet"), true) return ActionResult.SUCCESS } @@ -83,39 +83,39 @@ class Linker(settings: Settings) : Item(settings) { return } - if(!linkedFrom.pos.isWithinDistance(block.pos, MAX_SIGNAL_DISTANCE)) { + if(!linkedFrom.pos.isWithinDistance(block.pos, MAX_DEVICE_DISTANCE)) { // Device is too far! - context.player?.sendMessage(Text.literal("This device is too far! Max distance is $MAX_SIGNAL_DISTANCE blocks"), true) + context.player?.sendMessage(Text.literal("This device is too far! Max distance is $MAX_DEVICE_DISTANCE blocks"), true) return } - if(block is AbstractTrafficSignalBlockEntity) { + if(block is Linkable) { val id = block.link(linkedFrom) if(id != null) { - // Signal connected! - context.player?.sendMessage(Text.literal("Signal successfully connected with ID $id"), true) + // Device connected! + context.player?.sendMessage(Text.literal("Device successfully connected with ID $id"), true) } else { - // Something funky happened to the signal - context.player?.sendMessage(Text.literal("Could not link signal"), true) + // Something funky happened to the device + context.player?.sendMessage(Text.literal("Could not link device"), true) } } else { - context.player?.sendMessage(Text.literal("Cabinet must be connected to a signal"), true) + context.player?.sendMessage(Text.literal("Cabinet must be connected to a device"), true) return } } - private fun linkSignal(signal: AbstractTrafficSignalBlockEntity, context: ItemUsageContext): ActionResult { + private fun linkDevice(device: Linkable, context: ItemUsageContext): ActionResult { fun startLink() { linking = context.blockPos linkingWith = Registry.ModBlockEntities.THREE_HEAD_TRAFFIC_SIGNAL_BLOCK_ENTITY - context.player?.sendMessage(Text.literal("Right-click a traffic cabinet to link this signal"), true) + context.player?.sendMessage(Text.literal("Right-click a traffic cabinet to link this device"), true) } - if (signal.isLinked()) { - val cabinet = getCabinet(signal, context) + if (device.isLinked()) { + val cabinet = getCabinet(device, context) if(cabinet != null) { - alreadyLinked(signal, cabinet, context) + alreadyLinked(device, cabinet, context) } else { startLink() } @@ -126,40 +126,40 @@ class Linker(settings: Settings) : Item(settings) { return ActionResult.SUCCESS } - private fun completeSignalToCabinetLink(cabinet: BlockEntity, context: ItemUsageContext) { + private fun completeDeviceToCabinetLink(cabinet: BlockEntity, context: ItemUsageContext) { if(cabinet !is TrafficCabinetBlockEntity) { // Player right-clicked on something other than a cabinet - context.player?.sendMessage(Text.literal("Signal must be connected to a traffic cabinet"), true) + context.player?.sendMessage(Text.literal("Device must be connected to a traffic cabinet"), true) return } - if(cabinet.getTotalSignals() >= MAX_DEVICES) { - // Too many signals connected to this box! - context.player?.sendMessage(Text.literal("There are too many signals connected to this box! Max is $MAX_DEVICES"), true) + if(cabinet.getTotalDevices() >= MAX_DEVICES) { + // Too many devices connected to this box! + context.player?.sendMessage(Text.literal("There are too many devices connected to this box! Max is $MAX_DEVICES"), true) return } val linkedFrom = context.world.getBlockEntity(linking) - if(linkedFrom !is AbstractTrafficSignalBlockEntity) { - // Traffic signal disappeared somehow - context.player?.sendMessage(Text.literal("The signal is no longer there"), true) + if(linkedFrom !is Linkable) { + // Traffic device disappeared somehow + context.player?.sendMessage(Text.literal("The device is no longer there"), true) return } - if(!linkedFrom.pos.isWithinDistance(cabinet.pos, MAX_SIGNAL_DISTANCE)) { - // Signal is too far! - context.player?.sendMessage(Text.literal("This signal is too far! Max distance is $MAX_SIGNAL_DISTANCE blocks"), true) + if(!linkedFrom.pos.isWithinDistance(cabinet.pos, MAX_DEVICE_DISTANCE)) { + // Device is too far! + context.player?.sendMessage(Text.literal("This device is too far! Max distance is $MAX_DEVICE_DISTANCE blocks"), true) return } val id = linkedFrom.link(cabinet) if(id != null) { - // Signal connected! - context.player?.sendMessage(Text.literal("Signal successfully connected with ID $id"), true) + // Device connected! + context.player?.sendMessage(Text.literal("Device successfully connected with ID $id"), true) } else { - // Something funky happened to the signal - context.player?.sendMessage(Text.literal("Could not link signal"), true) + // Something funky happened to the device + context.player?.sendMessage(Text.literal("Could not link device"), true) } } @@ -184,16 +184,16 @@ class Linker(settings: Settings) : Item(settings) { val blockEntity = context.world?.getBlockEntity(context.blockPos) if(linking == null) { - if (blockEntity is AbstractTrafficSignalBlockEntity) { - return linkSignal(blockEntity, context) + if (blockEntity is Linkable) { + return linkDevice(blockEntity, context) } else if(blockEntity is TrafficCabinetBlockEntity) { return linkCabinet(blockEntity, context) } else { - context.player?.sendMessage(Text.literal("Right-click a signal or traffic cabinet"), true) + context.player?.sendMessage(Text.literal("Right-click a device or traffic cabinet"), true) } } else if(blockEntity != null) { if(linkingWith == Registry.ModBlockEntities.THREE_HEAD_TRAFFIC_SIGNAL_BLOCK_ENTITY) { - completeSignalToCabinetLink(blockEntity, context) + completeDeviceToCabinetLink(blockEntity, context) reset() } else if(linkingWith == Registry.ModBlockEntities.CABINET_BLOCK_ENTITY) { completeLinkToCabinet(blockEntity, context) diff --git a/src/main/resources/assets/roadworks/models/block/pedestrian_button.json b/src/main/resources/assets/roadworks/models/block/pedestrian_button.json new file mode 100644 index 0000000..93f0921 --- /dev/null +++ b/src/main/resources/assets/roadworks/models/block/pedestrian_button.json @@ -0,0 +1,115 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "0": "roadworks:block/light_gray", + "1": "roadworks:block/markings/yellow", + "particle": "roadworks:block/light_gray" + }, + "elements": [ + { + "from": [7, 7, 6.5], + "to": [9, 9, 8], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 7, 7]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "east": {"uv": [0, 0, 1.5, 2], "texture": "#0"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "west": {"uv": [0, 0, 1.5, 2], "texture": "#0"}, + "up": {"uv": [0, 0, 2, 1.5], "texture": "#0"}, + "down": {"uv": [0, 0, 2, 1.5], "texture": "#0"} + } + }, + { + "from": [6, 7, 8], + "to": [10, 9, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 7, 8]}, + "faces": { + "north": {"uv": [0, 0, 4, 2], "texture": "#1"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "south": {"uv": [0, 0, 4, 2], "texture": "#1"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "up": {"uv": [0, 0, 4, 1], "texture": "#1"}, + "down": {"uv": [0, 0, 4, 1], "texture": "#1"} + } + }, + { + "from": [9, 7, 7], + "to": [10, 9, 8], + "rotation": {"angle": 0, "axis": "y", "origin": [10, 7, 7]}, + "faces": { + "north": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "south": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "up": {"uv": [0, 0, 1, 1], "texture": "#1"}, + "down": {"uv": [0, 0, 1, 1], "texture": "#1"} + } + }, + { + "from": [6, 7, 7], + "to": [7, 9, 8], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 7, 7]}, + "faces": { + "north": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "south": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "up": {"uv": [0, 0, 1, 1], "texture": "#1"}, + "down": {"uv": [0, 0, 1, 1], "texture": "#1"} + } + }, + { + "from": [7, 9, 7], + "to": [9, 10, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 9, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 2], "texture": "#1"} + } + }, + { + "from": [7, 6, 7], + "to": [9, 7, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 6, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 2], "texture": "#1"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 45, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 225, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 3, 0], + "scale": [0.25, 0.25, 0.25] + }, + "gui": { + "rotation": [30, 225, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/roadworks/models/block/pedestrian_button_off.json b/src/main/resources/assets/roadworks/models/block/pedestrian_button_off.json new file mode 100644 index 0000000..04955b7 --- /dev/null +++ b/src/main/resources/assets/roadworks/models/block/pedestrian_button_off.json @@ -0,0 +1,88 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "0": "roadworks:block/light_gray", + "1": "roadworks:block/markings/yellow", + "particle": "roadworks:block/light_gray" + }, + "elements": [ + { + "from": [7, 7, 6.5], + "to": [9, 9, 8], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 7, 7]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "east": {"uv": [0, 0, 1.5, 2], "texture": "#0"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "west": {"uv": [0, 0, 1.5, 2], "texture": "#0"}, + "up": {"uv": [0, 0, 2, 1.5], "texture": "#0"}, + "down": {"uv": [0, 0, 2, 1.5], "texture": "#0"} + } + }, + { + "from": [6, 7, 8], + "to": [10, 9, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 7, 8]}, + "faces": { + "north": {"uv": [0, 0, 4, 2], "texture": "#1"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "south": {"uv": [0, 0, 4, 2], "texture": "#1"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "up": {"uv": [0, 0, 4, 1], "texture": "#1"}, + "down": {"uv": [0, 0, 4, 1], "texture": "#1"} + } + }, + { + "from": [9, 7, 7], + "to": [10, 9, 8], + "rotation": {"angle": 0, "axis": "y", "origin": [10, 7, 7]}, + "faces": { + "north": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "south": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "up": {"uv": [0, 0, 1, 1], "texture": "#1"}, + "down": {"uv": [0, 0, 1, 1], "texture": "#1"} + } + }, + { + "from": [6, 7, 7], + "to": [7, 9, 8], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 7, 7]}, + "faces": { + "north": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "south": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "up": {"uv": [0, 0, 1, 1], "texture": "#1"}, + "down": {"uv": [0, 0, 1, 1], "texture": "#1"} + } + }, + { + "from": [7, 9, 7], + "to": [9, 10, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 9, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 2], "texture": "#1"} + } + }, + { + "from": [7, 6, 7], + "to": [9, 7, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 6, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 2], "texture": "#1"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/roadworks/models/block/pedestrian_button_on.json b/src/main/resources/assets/roadworks/models/block/pedestrian_button_on.json new file mode 100644 index 0000000..5d399cf --- /dev/null +++ b/src/main/resources/assets/roadworks/models/block/pedestrian_button_on.json @@ -0,0 +1,88 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "0": "roadworks:block/light_gray", + "1": "roadworks:block/markings/yellow", + "particle": "roadworks:block/light_gray" + }, + "elements": [ + { + "from": [7, 7, 7.5], + "to": [9, 9, 8], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 7, 7]}, + "faces": { + "north": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "east": {"uv": [0, 0, 0.5, 2], "texture": "#0"}, + "south": {"uv": [0, 0, 2, 2], "texture": "#0"}, + "west": {"uv": [0, 0, 0.5, 2], "texture": "#0"}, + "up": {"uv": [0, 0, 2, 0.5], "texture": "#0"}, + "down": {"uv": [0, 0, 2, 0.5], "texture": "#0"} + } + }, + { + "from": [6, 7, 8], + "to": [10, 9, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 7, 8]}, + "faces": { + "north": {"uv": [0, 0, 4, 2], "texture": "#1"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "south": {"uv": [0, 0, 4, 2], "texture": "#1"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "up": {"uv": [0, 0, 4, 1], "texture": "#1"}, + "down": {"uv": [0, 0, 4, 1], "texture": "#1"} + } + }, + { + "from": [9, 7, 7], + "to": [10, 9, 8], + "rotation": {"angle": 0, "axis": "y", "origin": [10, 7, 7]}, + "faces": { + "north": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "south": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "up": {"uv": [0, 0, 1, 1], "texture": "#1"}, + "down": {"uv": [0, 0, 1, 1], "texture": "#1"} + } + }, + { + "from": [6, 7, 7], + "to": [7, 9, 8], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 7, 7]}, + "faces": { + "north": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "east": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "south": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "west": {"uv": [0, 0, 1, 2], "texture": "#1"}, + "up": {"uv": [0, 0, 1, 1], "texture": "#1"}, + "down": {"uv": [0, 0, 1, 1], "texture": "#1"} + } + }, + { + "from": [7, 9, 7], + "to": [9, 10, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 9, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 2], "texture": "#1"} + } + }, + { + "from": [7, 6, 7], + "to": [9, 7, 9], + "rotation": {"angle": 0, "axis": "y", "origin": [7, 6, 8]}, + "faces": { + "north": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "east": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "south": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "west": {"uv": [0, 0, 2, 1], "texture": "#1"}, + "up": {"uv": [0, 0, 2, 2], "texture": "#1"}, + "down": {"uv": [0, 0, 2, 2], "texture": "#1"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/roadworks/textures/block/light_gray.png b/src/main/resources/assets/roadworks/textures/block/light_gray.png new file mode 100644 index 0000000..4bb877d Binary files /dev/null and b/src/main/resources/assets/roadworks/textures/block/light_gray.png differ