Initial model and graphics for Internet GateWay block
This commit is contained in:
committed by
logan
parent
d37406244e
commit
1f55c8f174
@@ -38,6 +38,7 @@ public final class ClientSetup {
|
||||
BlockEntityRenderers.register(BlockEntities.DISK_DRIVE.get(), DiskDriveRenderer::new);
|
||||
BlockEntityRenderers.register(BlockEntities.CHARGER.get(), ChargerRenderer::new);
|
||||
BlockEntityRenderers.register(BlockEntities.PROJECTOR.get(), ProjectorRenderer::new);
|
||||
BlockEntityRenderers.register(BlockEntities.INTERNET_GATEWAY.get(), InternetGateWayRenderer::new);
|
||||
|
||||
event.enqueueWork(() -> {
|
||||
CustomItemModelProperties.initialize();
|
||||
|
||||
@@ -41,6 +41,20 @@ public abstract class ModRenderType extends RenderType {
|
||||
.setCullState(NO_CULL)
|
||||
.createCompositeState(false));
|
||||
|
||||
private static final RenderType GATEWAY_PARTICLE = create(
|
||||
API.MOD_ID + "/gateway_particle",
|
||||
DefaultVertexFormat.POSITION_COLOR,
|
||||
VertexFormat.Mode.QUADS,
|
||||
256,
|
||||
false,
|
||||
true,
|
||||
CompositeState.builder()
|
||||
.setShaderState(RENDERTYPE_LIGHTNING_SHADER)
|
||||
.setTransparencyState(LIGHTNING_TRANSPARENCY)
|
||||
.setWriteMaskState(COLOR_WRITE)
|
||||
.setCullState(CULL)
|
||||
.createCompositeState(false));
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static RenderType getNetworkCable() {
|
||||
@@ -87,6 +101,10 @@ public abstract class ModRenderType extends RenderType {
|
||||
state);
|
||||
}
|
||||
|
||||
public static RenderType getGateWayParticle() {
|
||||
return GATEWAY_PARTICLE;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private ModRenderType(final String name, final VertexFormat format, final VertexFormat.Mode drawMode, final int bufferSize, final boolean useDelegate, final boolean needsSorting, final Runnable setupTask, final Runnable clearTask) {
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
package li.cil.oc2.client.renderer.blockentity;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.math.Matrix4f;
|
||||
import com.mojang.math.Vector3f;
|
||||
|
||||
import li.cil.oc2.client.renderer.ModRenderType;
|
||||
import li.cil.oc2.common.blockentity.InternetGateWayBlockEntity;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
|
||||
public class InternetGateWayRenderer implements BlockEntityRenderer<InternetGateWayBlockEntity> {
|
||||
private static final float BLOCK_HEIGHT = 14f/16f;
|
||||
private static final float PORTAL_POSITION = 0.4f;
|
||||
private static final float EMITTER_POSITION = -3f/16f;
|
||||
private static final float EMITTER_SIZE = 6f/16f;
|
||||
private static final float EMITTER_PIXEL_SIZE = EMITTER_SIZE / 9f;
|
||||
private static final int[] SCRAMBLER = {1, 2, 0, 3, 13, 5, 15, 12, 6, 14, 10, 11, 7, 8, 9, 4};
|
||||
|
||||
public InternetGateWayRenderer(final BlockEntityRendererProvider.Context context) {
|
||||
//this.renderer = context.getBlockEntityRenderDispatcher();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(InternetGateWayBlockEntity gateWay, final float partialTicks, final PoseStack stack, final MultiBufferSource bufferSource, final int light, final int overlay) {
|
||||
stack.pushPose();
|
||||
stack.translate(0.5f, BLOCK_HEIGHT, 0.5f);
|
||||
stack.pushPose();
|
||||
long time = System.currentTimeMillis();
|
||||
long dt = time - gateWay.lastRender;
|
||||
gateWay.lastRender = time;
|
||||
if (dt > 1000) {
|
||||
//Catch up if rendering stopped
|
||||
gateWay.handledInboundCount = gateWay.inboundCount;
|
||||
gateWay.handledOutboundCount = gateWay.outboundCount;
|
||||
}
|
||||
double phase = ((double)time)/1000d;
|
||||
stack.translate(0f, PORTAL_POSITION+Math.sin(phase/2)*0.03f, 0f);
|
||||
//stack.mulPose(Vector3f.XN.rotationDegrees((float)Math.sin(phase)*5));
|
||||
//stack.mulPose(Vector3f.ZN.rotationDegrees((float)Math.sin(phase+2)*5));
|
||||
VertexConsumer portal = bufferSource.getBuffer(RenderType.endPortal());
|
||||
Matrix4f matrix = stack.last().pose();
|
||||
float halfSide = 0.2f;
|
||||
|
||||
renderCube(portal, matrix, halfSide, 0, 0, 0, false);
|
||||
stack.popPose();
|
||||
stack.translate(0, EMITTER_POSITION, 0);
|
||||
matrix = stack.last().pose();
|
||||
VertexConsumer packet = bufferSource.getBuffer(ModRenderType.getGateWayParticle());
|
||||
for (int x=0;x<InternetGateWayBlockEntity.EMITTER_SIDE_PIXELS;x++) {
|
||||
for (int z=0;z<InternetGateWayBlockEntity.EMITTER_SIDE_PIXELS;z++) {
|
||||
int flatPos = x * InternetGateWayBlockEntity.EMITTER_SIDE_PIXELS + z;
|
||||
if (gateWay.animProgress[flatPos] < 1f) {
|
||||
float animPos = gateWay.animProgress[flatPos];
|
||||
gateWay.animProgress[flatPos] += dt/1000f;
|
||||
if (gateWay.animReversed[flatPos]) {
|
||||
animPos = 1 - animPos;
|
||||
}
|
||||
renderCube(packet, matrix, EMITTER_PIXEL_SIZE/2, (x*2-3f)*EMITTER_PIXEL_SIZE, animPos*(PORTAL_POSITION-EMITTER_POSITION), (z*2-3f)*EMITTER_PIXEL_SIZE, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (gateWay.handledInboundCount<gateWay.inboundCount || gateWay.handledOutboundCount<gateWay.outboundCount) {
|
||||
int scrambledPointer = SCRAMBLER[gateWay.pointer];
|
||||
if (gateWay.animProgress[scrambledPointer]>=1f) {
|
||||
gateWay.pointer += 1;
|
||||
if (gateWay.pointer>=InternetGateWayBlockEntity.EMITTER_SIDE_PIXELS*InternetGateWayBlockEntity.EMITTER_SIDE_PIXELS) {
|
||||
gateWay.pointer = 0;
|
||||
}
|
||||
gateWay.animProgress[scrambledPointer] = 0f;
|
||||
if (gateWay.handledInboundCount<gateWay.inboundCount) {
|
||||
gateWay.animReversed[scrambledPointer] = false;
|
||||
gateWay.handledInboundCount += 1;
|
||||
} else {
|
||||
gateWay.animReversed[scrambledPointer] = true;
|
||||
gateWay.handledOutboundCount += 1;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stack.popPose();
|
||||
}
|
||||
|
||||
private void renderCube(VertexConsumer vertices, Matrix4f matrix, float halfSide, float x, float y, float z, boolean enColor) {
|
||||
//X axis
|
||||
renderCubeFace(vertices, matrix, +halfSide+x, 0+y, 0+z, halfSide, 5, 1, 0, enColor);
|
||||
renderCubeFace(vertices, matrix, -halfSide+x, 0+y, 0+z, halfSide, 5, 0, 1, enColor);
|
||||
//Y axis
|
||||
renderCubeFace(vertices, matrix, 0+x, +halfSide+y, 0+z, halfSide, 0, 5, 1, enColor);
|
||||
renderCubeFace(vertices, matrix, 0+x, -halfSide+y, 0+z, halfSide, 1, 5, 0, enColor);
|
||||
//Z axis
|
||||
renderCubeFace(vertices, matrix, 0+x, 0+y, -halfSide+z, halfSide, 0, 1, 5, enColor);
|
||||
renderCubeFace(vertices, matrix, 0+x, 0+y, +halfSide+z, halfSide, 1, 0, 5, enColor);
|
||||
}
|
||||
|
||||
private void renderCubeFace(VertexConsumer vertices, Matrix4f matrix, float x, float y, float z, float halfSideSize, int signShiftX, int signShiftY, int signShiftZ, boolean enColor) {
|
||||
float signs[] = {-1f, -1f, 1f, 1f, -1f, 0f, 0f, 0f, 0f};
|
||||
for (int i=0;i<4;i++) {
|
||||
vertices.vertex(matrix, x+halfSideSize*signs[i+signShiftX], y+halfSideSize*signs[i+signShiftY], z+halfSideSize*signs[i+signShiftZ]);
|
||||
if (enColor) {
|
||||
vertices.color(1f, 1f, 1f, 1f);
|
||||
}
|
||||
vertices.endVertex();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,14 +2,17 @@ package li.cil.oc2.common.block;
|
||||
|
||||
import li.cil.oc2.common.blockentity.BlockEntities;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.HalfTransparentBlock;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
public class InternetGatewayBlock extends Block implements EntityBlock {
|
||||
public class InternetGatewayBlock extends HalfTransparentBlock implements EntityBlock {
|
||||
|
||||
public InternetGatewayBlock() {
|
||||
super(Properties.of(Material.METAL).sound(SoundType.METAL).strength(1.5f, 6.0f));
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package li.cil.oc2.common.blockentity;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@@ -16,11 +13,19 @@ import li.cil.oc2.common.energy.FixedEnergyStorage;
|
||||
import li.cil.oc2.common.inet.InternetAdapter;
|
||||
import li.cil.oc2.common.inet.InternetConnection;
|
||||
import li.cil.oc2.common.inet.InternetManagerImpl;
|
||||
import li.cil.oc2.common.util.ChunkUtils;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.game.ClientGamePacketListener;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -32,16 +37,29 @@ public class InternetGateWayBlockEntity extends ModBlockEntity implements Networ
|
||||
private final Deque<byte[]> outboundQueue;
|
||||
|
||||
private InternetConnection internetConnection;
|
||||
|
||||
private static final String STATE_TAG = "internet_adapter";
|
||||
private Tag internetState;
|
||||
|
||||
private final FixedEnergyStorage energy = new FixedEnergyStorage(Config.gatewayEnergyStorage);
|
||||
|
||||
// Animation stuff
|
||||
public static final int EMITTER_SIDE_PIXELS = 4;
|
||||
public float animProgress[];
|
||||
public boolean animReversed[];
|
||||
public int inboundCount = 0;
|
||||
public int outboundCount = 0;
|
||||
public int handledInboundCount = 0;
|
||||
public int handledOutboundCount = 0;
|
||||
public long lastRender = 0;
|
||||
public int pointer = 0;
|
||||
|
||||
protected InternetGateWayBlockEntity(final BlockPos pos, final BlockState state) {
|
||||
super(BlockEntities.INTERNET_GATEWAY.get(), pos, state);
|
||||
inboundQueue = new ArrayDeque<>();
|
||||
outboundQueue = new ArrayDeque<>();
|
||||
internetState = null;
|
||||
animProgress = new float[EMITTER_SIDE_PIXELS*EMITTER_SIDE_PIXELS];
|
||||
animReversed = new boolean[EMITTER_SIDE_PIXELS*EMITTER_SIDE_PIXELS];
|
||||
internetState = EndTag.INSTANCE;
|
||||
setNeedsLevelUnloadEvent();
|
||||
}
|
||||
|
||||
@@ -60,7 +78,37 @@ public class InternetGateWayBlockEntity extends ModBlockEntity implements Networ
|
||||
.ifPresent(adapterState -> tag.put(Constants.INTERNET_ADAPTER_TAG_NAME, adapterState));
|
||||
}
|
||||
tag.put(Constants.ENERGY_TAG_NAME, energy.serializeNBT());
|
||||
LOGGER.info("State saved");
|
||||
LOGGER.trace("State saved");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getUpdateTag() {
|
||||
final CompoundTag tag = super.getUpdateTag();
|
||||
tag.putInt("inbound_count", inboundCount);
|
||||
tag.putInt("outbound_count", outboundCount);
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt)
|
||||
{
|
||||
CompoundTag compoundtag = pkt.getTag();
|
||||
if (compoundtag != null) {
|
||||
handleUpdateTag(compoundtag);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleUpdateTag(final CompoundTag tag) {
|
||||
inboundCount = tag.getInt("inbound_count");
|
||||
outboundCount = tag.getInt("outbound_count");
|
||||
handledInboundCount = Math.max(handledInboundCount, inboundCount-128);
|
||||
handledOutboundCount = Math.max(handledOutboundCount, outboundCount-128);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<ClientGamePacketListener> getUpdatePacket() {
|
||||
return ClientboundBlockEntityDataPacket.create(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,16 +116,16 @@ public class InternetGateWayBlockEntity extends ModBlockEntity implements Networ
|
||||
InternetManagerImpl.getInstance()
|
||||
.ifPresent(internetManager -> internetConnection = internetManager.connect(this, internetState));
|
||||
if (internetConnection != null) {
|
||||
LOGGER.info("Connected to the internet");
|
||||
LOGGER.trace("Connected to the internet");
|
||||
} else {
|
||||
LOGGER.info("Not connected to the internet");
|
||||
LOGGER.trace("Not connected to the internet");
|
||||
}
|
||||
}
|
||||
|
||||
protected void unloadServer(final boolean isRemove) {
|
||||
if (internetConnection != null) {
|
||||
internetConnection.stop();
|
||||
LOGGER.info("Connection stopped");
|
||||
LOGGER.trace("Connection stopped");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,15 +144,30 @@ public class InternetGateWayBlockEntity extends ModBlockEntity implements Networ
|
||||
boolean hasEnough = energy.getEnergyStored() >= Config.gatewayEnergyPerPacket;
|
||||
if (hasEnough) {
|
||||
energy.extractEnergy(Config.gatewayEnergyPerPacket, false);
|
||||
Level level = getLevel();
|
||||
if (level != null) {
|
||||
ChunkUtils.setLazyUnsaved(level, getBlockPos());
|
||||
}
|
||||
}
|
||||
return hasEnough;
|
||||
}
|
||||
|
||||
private void notifyPlayers() {
|
||||
Level level = getLevel();
|
||||
if (level != null) {
|
||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 2);
|
||||
//setChanged();
|
||||
LOGGER.info("Notified clients");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendEthernetFrame(byte[] frame) {
|
||||
LOGGER.info("Got inbound packet");
|
||||
LOGGER.trace("Got inbound packet");
|
||||
if (inboundQueue.size() < QUEUE_MAX) {
|
||||
if (tryUseEnergy()) {
|
||||
inboundCount += 1;
|
||||
notifyPlayers();
|
||||
inboundQueue.addLast(frame);
|
||||
}
|
||||
}
|
||||
@@ -117,12 +180,22 @@ public class InternetGateWayBlockEntity extends ModBlockEntity implements Networ
|
||||
|
||||
@Override
|
||||
public void writeEthernetFrame(NetworkInterface source, byte[] frame, int timeToLive) {
|
||||
LOGGER.info("Got outbound packet");
|
||||
LOGGER.trace("Got outbound packet");
|
||||
if (outboundQueue.size() < QUEUE_MAX) {
|
||||
if (tryUseEnergy()) {
|
||||
outboundCount += 1;
|
||||
notifyPlayers();
|
||||
outboundQueue.addLast(frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AABB getRenderBoundingBox() {
|
||||
return new AABB(
|
||||
getBlockPos(),
|
||||
getBlockPos().offset(1, 2, 1)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "oc2:block/internet_gateway"
|
||||
}
|
||||
}
|
||||
}
|
||||
114
src/main/resources/assets/oc2/models/block/internet_gateway.json
Normal file
114
src/main/resources/assets/oc2/models/block/internet_gateway.json
Normal file
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "block/block",
|
||||
"texture_size": [32, 32],
|
||||
"textures": {
|
||||
"0": "oc2:block/internet_gateway/internet_gateway_atlas0",
|
||||
"particle": "oc2:block/internet_gateway/internet_gateway_atlas0"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [3, 0, 3],
|
||||
"to": [13, 10, 13],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 5, 5], "texture": "#0"},
|
||||
"east": {"uv": [0, 0, 5, 5], "texture": "#0"},
|
||||
"south": {"uv": [0, 0, 5, 5], "texture": "#0"},
|
||||
"west": {"uv": [1.5, 1.5, 6.5, 6.5], "texture": "#0"},
|
||||
"up": {"uv": [1.5, 1.5, 6.5, 6.5], "texture": "#0"},
|
||||
"down": {"uv": [1.5, 1.5, 6.5, 6.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 0, 0],
|
||||
"to": [16, 13, 3],
|
||||
"faces": {
|
||||
"north": {"uv": [8, 0, 16, 6.5], "texture": "#0"},
|
||||
"east": {"uv": [14.5, 0, 16, 6.5], "texture": "#0"},
|
||||
"south": {"uv": [0, 0, 8, 6.5], "texture": "#0"},
|
||||
"west": {"uv": [8, 0, 9.5, 6.5], "texture": "#0"},
|
||||
"up": {"uv": [0, 8, 8, 9.5], "texture": "#0"},
|
||||
"down": {"uv": [0, 6.5, 8, 8], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 0, 13],
|
||||
"to": [16, 13, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 8, 6.5], "texture": "#0"},
|
||||
"east": {"uv": [8, 0, 9.5, 6.5], "texture": "#0"},
|
||||
"south": {"uv": [8, 0, 16, 6.5], "texture": "#0"},
|
||||
"west": {"uv": [14.5, 0, 16, 6.5], "texture": "#0"},
|
||||
"up": {"uv": [0, 14.5, 8, 16], "texture": "#0"},
|
||||
"down": {"uv": [0, 0, 8, 1.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 0, 3],
|
||||
"to": [3, 13, 13],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 1.5, 6.5], "texture": "#0"},
|
||||
"east": {"uv": [1.5, 0, 6.5, 6.5], "texture": "#0"},
|
||||
"south": {"uv": [0, 0, 1.5, 6.5], "texture": "#0"},
|
||||
"west": {"uv": [9.5, 0, 14.5, 6.5], "texture": "#0"},
|
||||
"up": {"uv": [0, 9.5, 1.5, 14.5], "texture": "#0"},
|
||||
"down": {"uv": [0, 1.5, 1.5, 6.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [13, 0, 3],
|
||||
"to": [16, 13, 13],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 1.5, 6.5], "texture": "#0"},
|
||||
"east": {"uv": [9.5, 0, 14.5, 6.5], "texture": "#0"},
|
||||
"south": {"uv": [0, 0, 1.5, 6.5], "texture": "#0"},
|
||||
"west": {"uv": [1.5, 0, 6.5, 6.5], "texture": "#0"},
|
||||
"up": {"uv": [6.5, 9.5, 8, 14.5], "texture": "#0"},
|
||||
"down": {"uv": [6.5, 1.5, 8, 6.5], "texture": "#0"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [5, 10, 5],
|
||||
"to": [11, 11, 11],
|
||||
"faces": {
|
||||
"north": {"uv": [3, 0, 6, 0.5], "texture": "#0"},
|
||||
"east": {"uv": [3, 0.5, 6, 1], "texture": "#0"},
|
||||
"south": {"uv": [3, 1, 6, 1.5], "texture": "#0"},
|
||||
"west": {"uv": [3, 1.5, 6, 2], "texture": "#0"},
|
||||
"up": {"uv": [16, 11, 11.5, 6.5], "texture": "#0"},
|
||||
"down": {"uv": [3, 3, 0, 6], "texture": "#0"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"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],
|
||||
"scale": [0.625, 0.625, 0.625]
|
||||
},
|
||||
"fixed": {
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"parent": "oc2:block/internet_gateway"
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 281 B |
Reference in New Issue
Block a user