Skip to content

Commit 43e9673

Browse files
authored
Allow vertical orientations for the Machine Chainer (#51)
1 parent 29693eb commit 43e9673

File tree

13 files changed

+579
-64
lines changed

13 files changed

+579
-64
lines changed

src/generated/resources/assets/extended_industrialization/lang/en_us.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@
141141
"text.extended_industrialization.key_mouse_scroll": "Mouse Scroll",
142142
"text.extended_industrialization.machine_batcher_coils": "Batch size and cost is determined by coil used.",
143143
"text.extended_industrialization.machine_chainer_connected_machines": "Connected Machines: %d / %d",
144-
"text.extended_industrialization.machine_chainer_help_1": "Connects up to %d consecutive machines in a horizontal line in the direction it is facing.",
144+
"text.extended_industrialization.machine_chainer_help_1": "Connects up to %d consecutive machines in a straight line in the direction it is facing.",
145145
"text.extended_industrialization.machine_chainer_help_2": "Accepts items, fluids, and energy and distributes them to connected machines.",
146146
"text.extended_industrialization.machine_chainer_help_3": "Can connect to other machine chainers, but it must not link back to itself.",
147147
"text.extended_industrialization.machine_chainer_problem_at": "Problem at: %s",
@@ -192,4 +192,4 @@
192192
"text.extended_industrialization.universal_transformer_from_tier_input": "Hull for cable tier to convert from (LV by default).",
193193
"text.extended_industrialization.universal_transformer_to_tier_input": "Hull for cable tier to convert to (LV by default).",
194194
"text.extended_industrialization.waste_collector_help": "When placed underneath animals, manure will be collected."
195-
}
195+
}

src/main/java/net/swedz/extended_industrialization/EIClient.java

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import aztech.modern_industrialization.machines.multiblocks.MultiblockTankBER;
1010
import net.minecraft.client.Minecraft;
1111
import net.minecraft.client.gui.screens.Screen;
12+
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
1213
import net.minecraft.client.renderer.blockentity.BlockEntityRenderers;
1314
import net.minecraft.world.InteractionHand;
1415
import net.minecraft.world.entity.player.Player;
@@ -24,14 +25,16 @@
2425
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
2526
import net.neoforged.neoforge.client.event.ClientTickEvent;
2627
import net.neoforged.neoforge.client.event.InputEvent;
28+
import net.neoforged.neoforge.client.event.ModelEvent;
2729
import net.neoforged.neoforge.client.event.RegisterClientTooltipComponentFactoriesEvent;
2830
import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent;
2931
import net.neoforged.neoforge.client.event.RegisterGuiLayersEvent;
3032
import net.neoforged.neoforge.client.gui.VanillaGuiLayers;
3133
import net.neoforged.neoforge.common.NeoForge;
3234
import net.neoforged.neoforge.registries.DeferredHolder;
33-
import net.swedz.extended_industrialization.client.MachineChainerHighlightRenderer;
3435
import net.swedz.extended_industrialization.client.NanoGravichestplateHudRenderer;
36+
import net.swedz.extended_industrialization.client.ber.chainer.MachineChainerHighlightRenderer;
37+
import net.swedz.extended_industrialization.client.model.chainer.MachineChainerUnbakedModel;
3538
import net.swedz.extended_industrialization.item.ElectricToolItem;
3639
import net.swedz.extended_industrialization.item.SteamChainsawItem;
3740
import net.swedz.extended_industrialization.item.machineconfig.MachineConfigCardItem;
@@ -94,9 +97,12 @@ private static void onRegisterColorItems(RegisterColorHandlersEvent.Item event)
9497
);
9598
}
9699

97-
/**
98-
* Taken from {@link aztech.modern_industrialization.MIClient#registerBlockEntityRenderers(FMLClientSetupEvent)}. This is needed to make multiblocks render their layout when holding a wrench.
99-
*/
100+
@SubscribeEvent
101+
private static void registerModelLoaders(ModelEvent.RegisterGeometryLoaders event)
102+
{
103+
event.register(MachineChainerUnbakedModel.LOADER_ID, MachineChainerUnbakedModel.LOADER);
104+
}
105+
100106
@SubscribeEvent
101107
private static void registerBlockEntityRenderers(FMLClientSetupEvent event)
102108
{
@@ -107,22 +113,14 @@ private static void registerBlockEntityRenderers(FMLClientSetupEvent event)
107113
MachineBlockEntity blockEntity = machine.getBlockEntityInstance();
108114
BlockEntityType type = blockEntity.getType();
109115

110-
if(blockEntity instanceof LargeTankMultiblockBlockEntity)
111-
{
112-
BlockEntityRenderers.register(type, MultiblockTankBER::new);
113-
}
114-
else if(blockEntity instanceof MultiblockMachineBlockEntity)
116+
BlockEntityRendererProvider provider = switch (blockEntity)
115117
{
116-
BlockEntityRenderers.register(type, MultiblockMachineBER::new);
117-
}
118-
else if(blockEntity instanceof MachineChainerMachineBlockEntity)
119-
{
120-
BlockEntityRenderers.register(type, MachineChainerHighlightRenderer::new);
121-
}
122-
else
123-
{
124-
BlockEntityRenderers.register(type, (c) -> new MachineBlockEntityRenderer<>(c));
125-
}
118+
case MachineChainerMachineBlockEntity be -> MachineChainerHighlightRenderer::new;
119+
case LargeTankMultiblockBlockEntity be -> MultiblockTankBER::new;
120+
case MultiblockMachineBlockEntity be -> MultiblockMachineBER::new;
121+
default -> MachineBlockEntityRenderer::new;
122+
};
123+
BlockEntityRenderers.register(type, provider);
126124
}
127125
}
128126
}

src/main/java/net/swedz/extended_industrialization/EIText.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public enum EIText implements MICompatibleTranslatableTextEnum
4848
KEY_MOUSE_SCROLL("Mouse Scroll"),
4949
MACHINE_BATCHER_COILS("Batch size and cost is determined by coil used."),
5050
MACHINE_CHAINER_CONNECTED_MACHINES("Connected Machines: %d / %d"),
51-
MACHINE_CHAINER_HELP_1("Connects up to %d consecutive machines in a horizontal line in the direction it is facing."),
51+
MACHINE_CHAINER_HELP_1("Connects up to %d consecutive machines in a straight line in the direction it is facing."),
5252
MACHINE_CHAINER_HELP_2("Accepts items, fluids, and energy and distributes them to connected machines."),
5353
MACHINE_CHAINER_HELP_3("Can connect to other machine chainers, but it must not link back to itself."),
5454
MACHINE_CHAINER_PROBLEM_AT("Problem at: %s"),
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package net.swedz.extended_industrialization.client.ber.chainer;
2+
3+
import aztech.modern_industrialization.compat.sodium.SodiumCompat;
4+
import aztech.modern_industrialization.machines.models.MachineModelClientData;
5+
import aztech.modern_industrialization.util.ModelHelper;
6+
import com.mojang.blaze3d.vertex.PoseStack;
7+
import com.mojang.blaze3d.vertex.VertexConsumer;
8+
import net.minecraft.client.renderer.LevelRenderer;
9+
import net.minecraft.client.renderer.MultiBufferSource;
10+
import net.minecraft.client.renderer.Sheets;
11+
import net.minecraft.client.renderer.block.BlockModelShaper;
12+
import net.minecraft.client.renderer.block.model.BakedQuad;
13+
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
14+
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
15+
import net.minecraft.client.renderer.texture.OverlayTexture;
16+
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
17+
import net.minecraft.core.Direction;
18+
import net.minecraft.world.level.block.state.BlockState;
19+
import net.neoforged.neoforge.client.model.pipeline.QuadBakingVertexConsumer;
20+
import net.swedz.extended_industrialization.EI;
21+
import net.swedz.extended_industrialization.client.model.chainer.MachineChainerBakedModel;
22+
import net.swedz.extended_industrialization.machines.blockentity.MachineChainerMachineBlockEntity;
23+
24+
/**
25+
* Based on {@link aztech.modern_industrialization.machines.MachineBlockEntityRenderer}
26+
*/
27+
public sealed class MachineChainerBlockEntityRenderer implements BlockEntityRenderer<MachineChainerMachineBlockEntity> permits MachineChainerHighlightRenderer
28+
{
29+
private final BlockModelShaper blockModels;
30+
private BlockState lastBlockState = null;
31+
private MachineChainerBakedModel model = null;
32+
private final Object[] quadCache = new Object[36];
33+
private static final Object NO_QUAD = new Object();
34+
35+
public MachineChainerBlockEntityRenderer(BlockEntityRendererProvider.Context context)
36+
{
37+
blockModels = context.getBlockRenderDispatcher().getBlockModelShaper();
38+
}
39+
40+
private BakedQuad getCachedQuad(MachineModelClientData data, Direction direction)
41+
{
42+
var facing = data.frontDirection;
43+
int cachedQuadIndex = facing.ordinal() * 6 + direction.ordinal();
44+
45+
if(quadCache[cachedQuadIndex] == null)
46+
{
47+
TextureAtlasSprite sprite = model == null ? null : MachineChainerBakedModel.getSprite(model.getSprites(), direction, facing, true);
48+
if(sprite != null)
49+
{
50+
var vc = new QuadBakingVertexConsumer();
51+
quadCache[cachedQuadIndex] = ModelHelper.bakeSprite(vc, direction, sprite, -2 * MachineChainerBakedModel.Z_OFFSET);
52+
}
53+
else
54+
{
55+
quadCache[cachedQuadIndex] = NO_QUAD;
56+
}
57+
}
58+
59+
var quad = quadCache[cachedQuadIndex];
60+
return quad == NO_QUAD ? null : (BakedQuad) quad;
61+
}
62+
63+
private MachineChainerBakedModel getMachineModel(BlockState state)
64+
{
65+
if(blockModels.getBlockModel(state) instanceof MachineChainerBakedModel mbm)
66+
{
67+
return mbm;
68+
}
69+
else
70+
{
71+
EI.LOGGER.warn("Model {} should have been a MachineChainerBakedModel, but was {}", state, blockModels.getBlockModel(state).getClass());
72+
return null;
73+
}
74+
}
75+
76+
@Override
77+
public void render(MachineChainerMachineBlockEntity machine, float tickDelta, PoseStack matrices, MultiBufferSource buffer, int light, int overlay)
78+
{
79+
BlockState state = machine.getBlockState();
80+
if(lastBlockState == null)
81+
{
82+
lastBlockState = state;
83+
model = this.getMachineModel(state);
84+
}
85+
else if(lastBlockState != state)
86+
{
87+
throw new IllegalStateException("Tried to use the same machine BER with two block states: " + state + " and " + lastBlockState);
88+
}
89+
90+
MachineModelClientData data = machine.getMachineModelData();
91+
if(data.isActive)
92+
{
93+
VertexConsumer vc = buffer.getBuffer(Sheets.cutoutBlockSheet());
94+
95+
for(Direction direction : Direction.values())
96+
{
97+
BakedQuad quad = this.getCachedQuad(data, direction);
98+
if(quad != null)
99+
{
100+
int faceLight = LevelRenderer.getLightColor(machine.getLevel(), machine.getBlockState(), machine.getBlockPos().relative(direction));
101+
vc.putBulkData(matrices.last(), quad, 1.0f, 1.0f, 1.0f, 1.0f, faceLight, OverlayTexture.NO_OVERLAY);
102+
103+
SodiumCompat.markSpriteActive(quad.getSprite());
104+
}
105+
}
106+
}
107+
}
108+
109+
@Override
110+
public int getViewDistance()
111+
{
112+
return 256;
113+
}
114+
}

src/main/java/net/swedz/extended_industrialization/client/MachineChainerHighlightRenderer.java renamed to src/main/java/net/swedz/extended_industrialization/client/ber/chainer/MachineChainerHighlightRenderer.java

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
package net.swedz.extended_industrialization.client;
1+
package net.swedz.extended_industrialization.client.ber.chainer;
22

33
import aztech.modern_industrialization.MITags;
4-
import aztech.modern_industrialization.machines.MachineBlockEntityRenderer;
54
import aztech.modern_industrialization.util.RenderHelper;
65
import com.mojang.blaze3d.vertex.PoseStack;
76
import com.mojang.math.Axis;
@@ -17,7 +16,7 @@
1716
import net.swedz.extended_industrialization.machines.blockentity.MachineChainerMachineBlockEntity;
1817
import net.swedz.extended_industrialization.machines.component.chainer.ChainerLinks;
1918

20-
public final class MachineChainerHighlightRenderer extends MachineBlockEntityRenderer<MachineChainerMachineBlockEntity>
19+
public final class MachineChainerHighlightRenderer extends MachineChainerBlockEntityRenderer
2120
{
2221
private static final int COLOR_SUCCESS = 0x6FFF6F;
2322
private static final int COLOR_FAILURE = 0xFF6F6F;
@@ -130,20 +129,40 @@ private void renderPosition(MachineChainerMachineBlockEntity machine, float tick
130129

131130
private Direction pickNumberRenderFace(MachineChainerMachineBlockEntity machine)
132131
{
133-
int playerY = Minecraft.getInstance().player.blockPosition().getY();
134-
int machineY = machine.getBlockPos().getY();
132+
int playerY = (int) Math.round(Minecraft.getInstance().player.getY());
135133

136-
if(playerY == machineY || playerY == machineY - 1)
134+
Direction machineDirection = machine.orientation.facingDirection;
135+
if(machineDirection.getAxis().isHorizontal())
137136
{
138-
return Direction.fromYRot(Minecraft.getInstance().player.yHeadRot).getOpposite();
139-
}
140-
else if(playerY < machineY)
141-
{
142-
return Direction.DOWN;
137+
int machineY = machine.getBlockPos().getY();
138+
139+
if(playerY == machineY || playerY == machineY - 1)
140+
{
141+
return Direction.fromYRot(Minecraft.getInstance().player.yHeadRot).getOpposite();
142+
}
143+
else if(playerY < machineY)
144+
{
145+
return Direction.DOWN;
146+
}
147+
else
148+
{
149+
return Direction.UP;
150+
}
143151
}
144152
else
145153
{
146-
return Direction.UP;
154+
int machineEndY = machine.getChainerComponent().links().positionAfter().getY();
155+
156+
if(machineDirection == Direction.UP && playerY >= machineEndY)
157+
{
158+
return Direction.UP;
159+
}
160+
else if(machineDirection == Direction.DOWN && playerY < machineEndY)
161+
{
162+
return Direction.DOWN;
163+
}
164+
165+
return Direction.fromYRot(Minecraft.getInstance().player.yHeadRot).getOpposite();
147166
}
148167
}
149168

@@ -157,21 +176,32 @@ private String pickArrowSymbol(MachineChainerMachineBlockEntity machine,
157176
Direction playerDirectionRight = playerDirection.getClockWise();
158177

159178
String arrow = "";
160-
if(playerDirection == machineDirection)
179+
if(renderDirection != machineDirection && renderDirection != machineDirection.getOpposite())
161180
{
162-
arrow = renderDirection == Direction.DOWN ? ARROW_DOWN : ARROW_UP;
163-
}
164-
else if(playerDirection == machineDirection.getOpposite())
165-
{
166-
arrow = renderDirection == Direction.DOWN ? ARROW_UP : ARROW_DOWN;
167-
}
168-
else if(playerDirectionLeft == machineDirection)
169-
{
170-
arrow = ARROW_LEFT;
171-
}
172-
else if(playerDirectionRight == machineDirection)
173-
{
174-
arrow = ARROW_RIGHT;
181+
if(playerDirection == machineDirection)
182+
{
183+
arrow = renderDirection == Direction.DOWN ? ARROW_DOWN : ARROW_UP;
184+
}
185+
else if(playerDirection == machineDirection.getOpposite())
186+
{
187+
arrow = renderDirection == Direction.DOWN ? ARROW_UP : ARROW_DOWN;
188+
}
189+
else if(playerDirectionLeft == machineDirection)
190+
{
191+
arrow = ARROW_LEFT;
192+
}
193+
else if(playerDirectionRight == machineDirection)
194+
{
195+
arrow = ARROW_RIGHT;
196+
}
197+
else if(machineDirection == Direction.UP)
198+
{
199+
arrow = ARROW_UP;
200+
}
201+
else if(machineDirection == Direction.DOWN)
202+
{
203+
arrow = ARROW_DOWN;
204+
}
175205
}
176206
return arrow;
177207
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package net.swedz.extended_industrialization.client.model;
2+
3+
import com.google.gson.Gson;
4+
import com.google.gson.GsonBuilder;
5+
import com.google.gson.JsonObject;
6+
import net.minecraft.client.resources.model.Material;
7+
import net.minecraft.resources.ResourceLocation;
8+
import net.minecraft.world.inventory.InventoryMenu;
9+
10+
import java.lang.reflect.Field;
11+
12+
public interface MachineOverlaysJson
13+
{
14+
Material[] toSpriteIds();
15+
16+
int[] getOutputSpriteIndexes();
17+
18+
Gson GSON = new GsonBuilder().registerTypeAdapter(ResourceLocation.class, new ResourceLocation.Serializer()).create();
19+
20+
static <O extends MachineOverlaysJson> O parse(Class<O> clazz, JsonObject json, MachineOverlaysJson defaultOverlay)
21+
{
22+
O overlays = GSON.fromJson(json, clazz);
23+
24+
if(defaultOverlay != null)
25+
{
26+
try
27+
{
28+
for(Field field : clazz.getDeclaredFields())
29+
{
30+
if(field.get(overlays) == null)
31+
{
32+
field.set(overlays, field.get(defaultOverlay));
33+
}
34+
}
35+
}
36+
catch (IllegalAccessException ex)
37+
{
38+
throw new RuntimeException("Failed to copy fields from default overlay", ex);
39+
}
40+
}
41+
42+
return overlays;
43+
}
44+
45+
default Material select(ResourceLocation... candidates)
46+
{
47+
for(ResourceLocation id : candidates)
48+
{
49+
if(id != null)
50+
{
51+
return new Material(InventoryMenu.BLOCK_ATLAS, id);
52+
}
53+
}
54+
return null;
55+
}
56+
}

0 commit comments

Comments
 (0)