From 4983948e3b8255c02767ba58da793692251065eb Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Wed, 15 Jul 2020 18:44:49 -0400 Subject: [PATCH] Very Broken Lasers --- .../thebrokenrail/energonrelics/Config.java | 4 + .../energonrelics/EnergonRelics.java | 7 + .../block/DefensiveLaserBlock.java | 69 ++++ .../entity/DefensiveLaserBlockEntity.java | 354 ++++++++++++++++++ .../DefensiveLaserBlockEntityRenderer.java | 45 +++ .../blockstates/defensive_laser.json | 31 ++ .../assets/energonrelics/lang/en_us.json | 4 +- .../models/block/defensive_laser.json | 33 ++ .../models/item/defensive_laser.json | 3 + .../models/item/defensive_laser_core.json | 6 + .../textures/block/defensive_laser_base.png | Bin 0 -> 665 bytes .../textures/item/defensive_laser_core.png | Bin 0 -> 833 bytes 12 files changed, 555 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/thebrokenrail/energonrelics/block/DefensiveLaserBlock.java create mode 100644 src/main/java/com/thebrokenrail/energonrelics/block/entity/DefensiveLaserBlockEntity.java create mode 100644 src/main/java/com/thebrokenrail/energonrelics/client/render/DefensiveLaserBlockEntityRenderer.java create mode 100644 src/main/resources/assets/energonrelics/blockstates/defensive_laser.json create mode 100644 src/main/resources/assets/energonrelics/models/block/defensive_laser.json create mode 100644 src/main/resources/assets/energonrelics/models/item/defensive_laser.json create mode 100644 src/main/resources/assets/energonrelics/models/item/defensive_laser_core.json create mode 100644 src/main/resources/assets/energonrelics/textures/block/defensive_laser_base.png create mode 100644 src/main/resources/assets/energonrelics/textures/item/defensive_laser_core.png diff --git a/src/main/java/com/thebrokenrail/energonrelics/Config.java b/src/main/java/com/thebrokenrail/energonrelics/Config.java index 3b72671..8e95e51 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/Config.java +++ b/src/main/java/com/thebrokenrail/energonrelics/Config.java @@ -11,4 +11,8 @@ public class Config { public static final int REACTOR_TIME = 2400; public static final int REACTOR_ENERGY_OUTPUT = 250; + + public static final int DEFENSIVE_LASER_RANGE = 18; + public static final int DEFENSIVE_LASER_IDLE_ENERGY_REQUIRED = 25; + public static final int DEFENSIVE_LASER_FIRE_ENERGY_REQUIRED = 64; } diff --git a/src/main/java/com/thebrokenrail/energonrelics/EnergonRelics.java b/src/main/java/com/thebrokenrail/energonrelics/EnergonRelics.java index b221de8..179dd65 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/EnergonRelics.java +++ b/src/main/java/com/thebrokenrail/energonrelics/EnergonRelics.java @@ -1,5 +1,6 @@ package com.thebrokenrail.energonrelics; +import com.thebrokenrail.energonrelics.block.DefensiveLaserBlock; import com.thebrokenrail.energonrelics.block.battery.ActiveBatteryControllerBlock; import com.thebrokenrail.energonrelics.block.reactor.ReactorControllerBlock; import com.thebrokenrail.energonrelics.block.reactor.ReactorCoreBlock; @@ -58,6 +59,9 @@ public class EnergonRelics implements ModInitializer { public static final Item CIRCUIT_BOARD_ITEM = new Item(new Item.Settings().group(ITEM_GROUP)); + public static final Item DEFENSIVE_LASER_CORE_ITEM = new Item(new Item.Settings().group(ITEM_GROUP));; + public static final DefensiveLaserBlock DEFENSIVE_LASER_BLOCK = new DefensiveLaserBlock(); + @Override public void onInitialize() { NETWORK_CHIP_ITEM = Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "network_chip"), new NetworkChipItem()); @@ -82,5 +86,8 @@ public class EnergonRelics implements ModInitializer { VERIDIUM_ORE_BLOCK.register("veridium_ore"); VERIDIUM_BLOCK_BLOCK.register("veridium_block"); Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, new Identifier(NAMESPACE, "veridium_ore"), VERIDIUM_ORE_FEATURE); + + Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "defensive_laser_core"), DEFENSIVE_LASER_CORE_ITEM); + DEFENSIVE_LASER_BLOCK.register("defensive_laser"); } } diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/DefensiveLaserBlock.java b/src/main/java/com/thebrokenrail/energonrelics/block/DefensiveLaserBlock.java new file mode 100644 index 0000000..82c4d4c --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/block/DefensiveLaserBlock.java @@ -0,0 +1,69 @@ +package com.thebrokenrail.energonrelics.block; + +import com.thebrokenrail.energonrelics.block.entity.DefensiveLaserBlockEntity; +import com.thebrokenrail.energonrelics.block.util.EnergyProviderBlock; +import com.thebrokenrail.energonrelics.client.render.DefensiveLaserBlockEntityRenderer; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Material; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher; +import net.minecraft.client.render.block.entity.BlockEntityRenderer; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.sound.BlockSoundGroup; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.BooleanProperty; +import net.minecraft.state.property.DirectionProperty; +import net.minecraft.state.property.Properties; +import net.minecraft.util.BlockMirror; +import net.minecraft.util.BlockRotation; +import net.minecraft.util.math.Direction; + +import java.util.function.Function; + +@SuppressWarnings("deprecation") +public class DefensiveLaserBlock extends EnergyProviderBlock { + public static final BooleanProperty POWERED = Properties.POWERED; + public static final DirectionProperty FACING = Properties.FACING; + + public DefensiveLaserBlock() { + super(FabricBlockSettings.of(Material.GLASS).sounds(BlockSoundGroup.GLASS).nonOpaque().lightLevel(state -> state.get(POWERED) ? 15 : 0).strength(0.3f)); + setDefaultState(getDefaultState().with(POWERED, false).with(FACING, Direction.NORTH)); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + builder.add(POWERED); + builder.add(FACING); + } + + @Override + public BlockState rotate(BlockState state, BlockRotation rotation) { + return state.with(FACING, rotation.rotate(state.get(FACING))); + } + + @Override + public BlockState mirror(BlockState state, BlockMirror mirror) { + return state.rotate(mirror.getRotation(state.get(FACING))); + } + + @Override + public BlockState getPlacementState(ItemPlacementContext ctx) { + return getDefaultState().with(FACING, ctx.getSide().getOpposite()); + } + + @Override + protected Function, BlockEntity> getFactory() { + return DefensiveLaserBlockEntity::new; + } + + @Override + @Environment(EnvType.CLIENT) + protected Function> getRenderer() { + return DefensiveLaserBlockEntityRenderer::new; + } +} diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/entity/DefensiveLaserBlockEntity.java b/src/main/java/com/thebrokenrail/energonrelics/block/entity/DefensiveLaserBlockEntity.java new file mode 100644 index 0000000..f546835 --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/block/entity/DefensiveLaserBlockEntity.java @@ -0,0 +1,354 @@ +package com.thebrokenrail.energonrelics.block.entity; + +import com.thebrokenrail.energonrelics.Config; +import com.thebrokenrail.energonrelics.EnergonRelics; +import com.thebrokenrail.energonrelics.block.DefensiveLaserBlock; +import com.thebrokenrail.energonrelics.energy.core.EnergyReceiverBlockEntity; +import com.thebrokenrail.energonrelics.energy.core.util.Action; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.particle.ParticleTypes; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.RayTraceContext; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; + +public class DefensiveLaserBlockEntity extends EnergyReceiverBlockEntity { + private static final float MAX_PITCH = 60; + private static final float MIN_PITCH = -20; + + private static final float ROTATION_INCREMENT = 2; + + private static final int COUNTDOWN = 6; + + public final Rotation rotation = new Rotation(0, 0, "Rotation"); + private LivingEntity target; + private int countdown = 0; + + private final Predicate predicate = entity -> { + if (entity.getBlockPos().isWithinDistance(getPos(), Config.DEFENSIVE_LASER_RANGE)) { + Vec3d start = getPosVec().add(rotation.getRayVector()); + Vec3d end = entity.getPos(); + HitResult result = entity.getEntityWorld().rayTrace(new RayTraceContext(start, end, RayTraceContext.ShapeType.COLLIDER, RayTraceContext.FluidHandling.ANY, entity)); + return result.getType() == HitResult.Type.MISS; + } else { + return false; + } + }; + + private Vec3d getPosVec() { + return new Vec3d(getPos().getX() + 0.5d, getPos().getY() + 0.5d, getPos().getZ() + 0.5d); + } + + @Override + public BlockState getCachedState() { + if (hasWorld()) { + return super.getCachedState(); + } else { + return EnergonRelics.DEFENSIVE_LASER_BLOCK.getDefaultState(); + } + } + + private interface SwapFunction { + class SwapData { + private final float yaw; + private final float pitch; + + public SwapData(float yaw, float pitch) { + this.yaw = yaw; + this.pitch = pitch; + } + } + + Vec3d swap(SwapData data); + SwapData line(Vec3d data); + + static SwapFunction upDown(boolean up) { + return new SwapFunction() { + @Override + public Vec3d swap(SwapData data) { + return new Vec3d(-data.yaw, data.pitch, 0); + } + + private SwapData reverseSwap(Vec3d data) { + return new SwapData((float) -data.getX(), (float) data.getY()); + } + + @Override + public SwapData line(Vec3d data) { + SwapData reverse = reverseSwap(data); + return new SwapData(-reverse.yaw, reverse.pitch); + } + }; + } + static SwapFunction northSouth(boolean north) { + return new SwapFunction() { + @Override + public Vec3d swap(SwapData data) { + if (north) { + return new Vec3d(0, data.pitch, data.yaw); + } else { + return new Vec3d(0, -data.pitch, data.yaw); + } + } + + private SwapData reverseSwap(Vec3d data) { + if (north) { + return new SwapData((float) data.getZ(), (float) data.getY()); + } else { + return new SwapData((float) data.getZ(), (float) -data.getY()); + } + } + + @Override + public SwapData line(Vec3d data) { + SwapData reverse = reverseSwap(data); + if (north) { + return new SwapData(reverse.pitch + 90, reverse.yaw + 90); + } else { + return new SwapData(reverse.pitch - 180, reverse.yaw - 90); + } + } + }; + } + SwapFunction SWAP_PITCH_ROLL = new SwapFunction() { + @Override + public Vec3d swap(SwapData data) { + return new Vec3d(data.yaw, data.pitch, 0); + } + + private SwapData reverseSwap(Vec3d data) { + return new SwapData((float) data.getX(), (float) data.getY()); + } + + @Override + public SwapData line(Vec3d data) { + SwapData reverse = reverseSwap(data); + return new SwapData(-reverse.pitch, reverse.yaw); + } + }; + } + + public class Rotation { + private float yaw = 0; + private float pitch = 0; + private final String key; + + private Rotation(float yaw, float pitch, String key) { + setRaw(yaw, pitch); + this.key = key; + } + + private void fromTag(CompoundTag tag) { + CompoundTag rotation = tag.getCompound(key); + setRaw(rotation.getInt("Yaw"), rotation.getInt("Pitch")); + } + + private void toTag(CompoundTag tag) { + CompoundTag rotation = new CompoundTag(); + rotation.putFloat("Yaw", yaw); + rotation.putFloat("Pitch", pitch); + tag.put(key, rotation); + } + + private void change(float yaw, float pitch) { + setRaw(this.yaw + yaw, this.pitch + pitch); + markDirty(); + } + + private void setRaw(float yaw, float pitch) { + setYaw(yaw); + setPitch(pitch); + } + + private void setYaw(float yaw) { + this.yaw = yaw % 360; + } + + private void setPitch(float pitch) { + this.pitch = Math.max(MIN_PITCH, Math.min(MAX_PITCH, pitch % 360)); + } + + public float getYaw(boolean display) { + return (float) getBaseVector(display).getX(); + } + + public float getPitch(boolean display) { + return (float) getBaseVector(display).getY(); + } + + public float getRoll(boolean display) { + return (float) getBaseVector(display).getZ(); + } + + private Vec3d getBaseModifier() { + Direction facing = getCachedState().get(DefensiveLaserBlock.FACING); + switch (facing) { + case DOWN: { + return new Vec3d(0, 0, 0); + } + case UP: { + return new Vec3d(0, 180, 0); + } + case NORTH: { + return new Vec3d(0, 0, 90); + } + case SOUTH: { + return new Vec3d(180, 90, 90); + } + case EAST: { + return new Vec3d(180, 0, 90); + } + case WEST: { + return new Vec3d(0, 0, -90); + } + default: { + throw new UnsupportedOperationException(); + } + } + } + + public SwapFunction getSwapFunction() { + Direction facing = getCachedState().get(DefensiveLaserBlock.FACING); + switch (facing) { + case DOWN: { + return SwapFunction.upDown(false); + } + case UP: { + return SwapFunction.upDown(true); + } + case EAST: + case WEST: { + return SwapFunction.SWAP_PITCH_ROLL; + } + case NORTH: { + return SwapFunction.northSouth(true); + } + case SOUTH: { + return SwapFunction.northSouth(false); + } + default: { + throw new UnsupportedOperationException(); + } + } + } + + private Vec3d getBaseVector(boolean display) { + Vec3d modifier = getBaseModifier(); + return getSwapFunction().swap(new SwapFunction.SwapData(yaw, -(pitch - (display ? 45 : 0)))).add(modifier); + } + + private Vec3d getRayVector() { + SwapFunction.SwapData data = getSwapFunction().line(getBaseVector(false)); + float pitch = data.pitch * (float) DEG2RAD; + float yaw = data.yaw * (float) DEG2RAD; + float cosYaw = MathHelper.cos(yaw); + float sinYaw = MathHelper.sin(yaw); + float cosPitch = MathHelper.cos(pitch); + float sinPitch = MathHelper.sin(pitch); + return new Vec3d(sinYaw * cosPitch, -sinPitch, cosYaw * cosPitch); + } + + private float getAngleChange(float from, float to) { + float diff = MathHelper.subtractAngles(from, to); + return MathHelper.clamp(diff, -ROTATION_INCREMENT, ROTATION_INCREMENT); + } + + private void target(float targetYaw, float targetPitch) { + SwapFunction function = getSwapFunction(); + SwapFunction.SwapData data = function.line(getBaseVector(false)); + Vec3d vec = new Vec3d(targetYaw, targetPitch, 0); + float yawChange = getAngleChange(data.yaw, (float) vec.getX()); + float pitchChange = getAngleChange(data.pitch, (float) vec.getY()); + change(yawChange, pitchChange); + } + } + + public DefensiveLaserBlockEntity(BlockEntityType type) { + super(type); + } + + public static final double DEG2RAD = Math.PI / 180d; + private static final double RAD2DEG = 180d / Math.PI; + + private float getTargetPitch(double x, double y, double z) { + Vec3d pos = getPosVec(); + double diffX = x - pos.getX(); + double diffY = y - pos.getY(); + double diffZ = z - pos.getZ(); + double g = MathHelper.sqrt(diffX * diffX + diffZ * diffZ); + return (float) -(MathHelper.atan2(diffY, g) * RAD2DEG); + } + + private float getTargetYaw(double x, double z) { + Vec3d pos = getPosVec(); + double diffX = x - pos.getX(); + double diffZ = z - pos.getZ(); + return (float) (MathHelper.atan2(diffZ, diffX) * RAD2DEG) - 90.0F; + } + + @Override + protected void tickEnergy() { + assert getWorld() != null; + Vec3d vec = rotation.getRayVector().add(getPosVec()); + ((ServerWorld) getWorld()).spawnParticles(ParticleTypes.END_ROD, vec.getX(), vec.getY(), vec.getZ(), 1, 0, 0, 0, 0); + addAction(Action.createBlockStatePropertyAction(Config.DEFENSIVE_LASER_IDLE_ENERGY_REQUIRED, DefensiveLaserBlock.POWERED, true, false)); + rotation.target(45, 45); + if (getCachedState().get(DefensiveLaserBlock.POWERED)) { + if (countdown > 0) { + countdown--; + } + if (countdown == 1) { + // Fire! + target = null; + } else if (countdown < 1) { + if (target == null) { + List entities = getWorld().getEntities(LivingEntity.class, new Box(getPos()).expand(Config.DEFENSIVE_LASER_RANGE), predicate); + if (entities.size() > 0) { + Collections.shuffle(entities); + target = entities.get(0); + } + } else { + if (predicate.test(target)) { + Optional optional = target.getBoundingBox().rayTrace(getPosVec(), getPosVec().add(rotation.getRayVector().multiply(Config.DEFENSIVE_LASER_RANGE))); + if (optional.isPresent()) { + countdown = COUNTDOWN; + } else { + Vec3d targetPos = target.getPos(); + float targetYaw = getTargetYaw(targetPos.getX(), targetPos.getZ()); + float targetPitch = getTargetPitch(targetPos.getX(), targetPos.getY(), targetPos.getZ()); + rotation.target(targetYaw, targetPitch); + } + } else { + target = null; + } + } + } + } + } + + @Override + public CompoundTag toTag(CompoundTag tag) { + super.toTag(tag); + rotation.toTag(tag); + tag.putInt("Countdown", countdown); + return tag; + } + + @Override + public void fromTag(BlockState state, CompoundTag tag) { + super.fromTag(state, tag); + rotation.fromTag(tag); + countdown = tag.getInt("Countdown"); + } +} diff --git a/src/main/java/com/thebrokenrail/energonrelics/client/render/DefensiveLaserBlockEntityRenderer.java b/src/main/java/com/thebrokenrail/energonrelics/client/render/DefensiveLaserBlockEntityRenderer.java new file mode 100644 index 0000000..1953c8b --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/client/render/DefensiveLaserBlockEntityRenderer.java @@ -0,0 +1,45 @@ +package com.thebrokenrail.energonrelics.client.render; + +import com.thebrokenrail.energonrelics.EnergonRelics; +import com.thebrokenrail.energonrelics.block.entity.DefensiveLaserBlockEntity; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher; +import net.minecraft.client.render.model.json.ModelTransformation; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.client.util.math.Vector3f; +import net.minecraft.item.ItemStack; + +public class DefensiveLaserBlockEntityRenderer extends HighlightBlockEntityRenderer { + public DefensiveLaserBlockEntityRenderer(BlockEntityRenderDispatcher dispatcher) { + super(dispatcher); + } + + @Override + public void render(BlockEntity entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) { + matrices.push(); + matrices.translate(0.5d, 0.5d, 0.5d); + if (entity instanceof DefensiveLaserBlockEntity) { + DefensiveLaserBlockEntity laser = (DefensiveLaserBlockEntity) entity; + + float roll = (float) (laser.rotation.getRoll(true) * DefensiveLaserBlockEntity.DEG2RAD); + if (roll != 0) { + matrices.multiply(Vector3f.POSITIVE_Z.getRadialQuaternion(roll)); + } + float yaw = (float) (laser.rotation.getYaw(true) * DefensiveLaserBlockEntity.DEG2RAD); + if (yaw != 0) { + matrices.multiply(Vector3f.POSITIVE_Y.getRadialQuaternion(yaw)); + } + float pitch = (float) (laser.rotation.getPitch(true) * DefensiveLaserBlockEntity.DEG2RAD); + if (pitch != 0) { + matrices.multiply(Vector3f.POSITIVE_X.getRadialQuaternion(pitch)); + } + matrices.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(90)); + + MinecraftClient.getInstance().getItemRenderer().renderItem(new ItemStack(EnergonRelics.DEFENSIVE_LASER_CORE_ITEM), ModelTransformation.Mode.GROUND, light, overlay, matrices, vertexConsumers); + } + matrices.pop(); + super.render(entity, tickDelta, matrices, vertexConsumers, light, overlay); + } +} diff --git a/src/main/resources/assets/energonrelics/blockstates/defensive_laser.json b/src/main/resources/assets/energonrelics/blockstates/defensive_laser.json new file mode 100644 index 0000000..5f44eab --- /dev/null +++ b/src/main/resources/assets/energonrelics/blockstates/defensive_laser.json @@ -0,0 +1,31 @@ +{ + "variants": { + "facing=down": { + "model": "energonrelics:block/defensive_laser" + }, + "facing=east": { + "model": "energonrelics:block/defensive_laser", + "x": 90, + "y": 270 + }, + "facing=north": { + "model": "energonrelics:block/defensive_laser", + "x": 90, + "y": 180 + }, + "facing=south": { + "model": "energonrelics:block/defensive_laser", + "y": 180, + "x": 270 + }, + "facing=up": { + "model": "energonrelics:block/defensive_laser", + "x": 180 + }, + "facing=west": { + "model": "energonrelics:block/defensive_laser", + "y": 90, + "x": 90 + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/energonrelics/lang/en_us.json b/src/main/resources/assets/energonrelics/lang/en_us.json index 6cbbeb8..477a2f6 100644 --- a/src/main/resources/assets/energonrelics/lang/en_us.json +++ b/src/main/resources/assets/energonrelics/lang/en_us.json @@ -18,5 +18,7 @@ "block.energonrelics.reactor_core": "Reactor Core", "item.energonrelics.veridium_ingot": "Veridium Ingot", "block.energonrelics.veridium_ore": "Veridium Ore", - "block.energonrelics.veridium_block": "Veridium Block" + "block.energonrelics.veridium_block": "Veridium Block", + "item.energonrelics.defensive_laser_core": "Defensive laser Core", + "block.energonrelics.defensive_laser": "Defensive Laser" } \ No newline at end of file diff --git a/src/main/resources/assets/energonrelics/models/block/defensive_laser.json b/src/main/resources/assets/energonrelics/models/block/defensive_laser.json new file mode 100644 index 0000000..ea107aa --- /dev/null +++ b/src/main/resources/assets/energonrelics/models/block/defensive_laser.json @@ -0,0 +1,33 @@ +{ + "parent": "minecraft:block/block", + "textures": { + "0": "energonrelics:block/defensive_laser_base", + "particle": "energonrelics:block/defensive_laser_base" + }, + "elements": [ + { + "from": [0, 0, 0], + "to": [16, 4, 16], + "faces": { + "north": {"uv": [0, 0, 16, 4], "texture": "#0"}, + "east": {"uv": [0, 0, 16, 4], "texture": "#0"}, + "south": {"uv": [0, 0, 16, 4], "texture": "#0"}, + "west": {"uv": [0, 0, 16, 4], "texture": "#0"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#0"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#0"} + } + }, + { + "from": [7, 4, 7], + "to": [9, 8, 9], + "faces": { + "north": {"uv": [7, 6, 9, 10], "texture": "#0"}, + "east": {"uv": [7, 6, 9, 10], "texture": "#0"}, + "south": {"uv": [7, 6, 9, 10], "texture": "#0"}, + "west": {"uv": [7, 6, 9, 10], "texture": "#0"}, + "up": {"uv": [7, 7, 9, 9], "texture": "#0"}, + "down": {"uv": [7, 7, 9, 9], "texture": "#0"} + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/energonrelics/models/item/defensive_laser.json b/src/main/resources/assets/energonrelics/models/item/defensive_laser.json new file mode 100644 index 0000000..e96a27a --- /dev/null +++ b/src/main/resources/assets/energonrelics/models/item/defensive_laser.json @@ -0,0 +1,3 @@ +{ + "parent": "minecraft:builtin/entity" +} \ No newline at end of file diff --git a/src/main/resources/assets/energonrelics/models/item/defensive_laser_core.json b/src/main/resources/assets/energonrelics/models/item/defensive_laser_core.json new file mode 100644 index 0000000..7989230 --- /dev/null +++ b/src/main/resources/assets/energonrelics/models/item/defensive_laser_core.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "energonrelics:item/defensive_laser_core" + } +} diff --git a/src/main/resources/assets/energonrelics/textures/block/defensive_laser_base.png b/src/main/resources/assets/energonrelics/textures/block/defensive_laser_base.png new file mode 100644 index 0000000000000000000000000000000000000000..2f9b69d76c79624379dc927fc189f4ab938abc54 GIT binary patch literal 665 zcmV;K0%rY*P)q5gL~I2c3&BFP z@m2T_v=wX>1VIr*Ec^w&8VTziS4a>u%k2F)Gv_jM27J-1k#p*YA(t=O@km&kn_tiZ zF9c|$onE?i!?7k~u_!gi=N)yb-iB1K+WY<;Ez723KwXpYm|@vP;R)gBYSB`>CEQ_T z^kv~g;UQZND14>#q{q*S(;mMowiEFw@Ts0!x{8xkY-H@5@St#CE?Y8w&!cYAYUXEW zq;|>d!68nBFd9iptdONhNNQd(``%G<8{b>zC`WAH!1MZV%MNKWG)qHkBUz5@tuz}aO* zOYXw?CUibnx~>06ewn^h3SLj4Z64Zhpn1{D>UW)!dq}Ly6J5jJJ`BkI;LoT7xeY{a$QO)0v9eYiOdMps+!zE&{(!8+f^*POCpoL zsLq`nq@s3baG+MuA8?=NwH6duq8MQd7Dq*&G2l99F`ZQqje;WsCXiX&bwy1Ybx09c z1RU;l5R0iRBuVsSwfBFmL;+0hk8gpm>ZrW|p*~_WI=Cnh00000NkvXXu0mjflhG#4 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/energonrelics/textures/item/defensive_laser_core.png b/src/main/resources/assets/energonrelics/textures/item/defensive_laser_core.png new file mode 100644 index 0000000000000000000000000000000000000000..913107fe47f06a878f786048e60c67a2fc889e8e GIT binary patch literal 833 zcmV-H1HSx;P)q5gL~I2c3&BFP z@m2T_v=wX>1VIr*Ec^w&8VTziS4a>u%k2F)Gv_jM27J-1k#p*YA(t=O@km&kn_tiZ zF9c|$onE?i!?7k~u_!gi=N)yb-iB1K+WY<;Ez723KwXpYm|@vP;R)gBYSB`>CEQ_T z^kv~g;UQZND14>#q{q*S(;mMowiEFw@Ts0!x{8xkY-H@5@St#CE?Y8w&!cYAYUXEW zq;|>d!68nBFd9iptdONhNNQd(``%G<8{b>zC`WAH!1MZV%MNKWG)qHkBUz5@tuz}aO* zOYXw?CUibnx~>06ewn^h3SLj4Z64Zhpn1{D>UW)!dq}Ly6J5jJJ`BkI;L_w|E(5mL>a;Y zb8hp6Ka4E%KK;MPVb7rCa+KjArxODU%k%#%EQ}1r2YxW(@)q0xkb?R%zZqF(z5Nf; zEN^^>;c1C012YFZ(4gC3*W~Z{j?*9%3p#Ds|3BTJ{-5FU)Bi7a=>30v&=icPdT?QQ ziwT?4K+Xo){Nkx6gM`R#22qyn3`{_NM57VIOdoEd!iHg@3n$oChNEvFc<+b*A1*nA z@!S9&xFJ|wfb6QbECCD*KOjLR@MI%2Ob|hV(*RI_t!lpt*7!j*n1SIZBD}-;T^N=| z@PS=HFjPT)4sWvn+YAD{SJyIpH;H0k=45ABU$C74B^t2>X!@3~j4UiC!RY~HGe|S% zzI6=0ydz0Z@gQgadJ_T0f4|26Uz;HCpP(1etyvkv5B59AMIZnGdEA_j70Ord00000 LNkvXXu0mjf2TpyO literal 0 HcmV?d00001