diff --git a/src/main/java/com/thebrokenrail/energonrelics/EnergonRelics.java b/src/main/java/com/thebrokenrail/energonrelics/EnergonRelics.java index 9570e4a..d1d6477 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/EnergonRelics.java +++ b/src/main/java/com/thebrokenrail/energonrelics/EnergonRelics.java @@ -5,9 +5,14 @@ import com.thebrokenrail.energonrelics.block.CreativeEnergySourceBlock; import com.thebrokenrail.energonrelics.block.DefensiveLaserBlock; import com.thebrokenrail.energonrelics.block.HolographicSkyBlock; import com.thebrokenrail.energonrelics.block.LightningRodBlock; -import com.thebrokenrail.energonrelics.block.misc.VeridiumBlockBlock; -import com.thebrokenrail.energonrelics.block.forcefield.ForcefieldBlock; import com.thebrokenrail.energonrelics.block.forcefield.ForcefieldProjectorBlock; +import com.thebrokenrail.energonrelics.block.forcefield.RepulsorBeamBlock; +import com.thebrokenrail.energonrelics.block.forcefield.TractorBeamBlock; +import com.thebrokenrail.energonrelics.block.forcefield.util.BeamBlock; +import com.thebrokenrail.energonrelics.block.forcefield.TractorBeamProjectorBlock; +import com.thebrokenrail.energonrelics.block.forcefield.ForcefieldBlock; +import com.thebrokenrail.energonrelics.block.misc.VeridiumBlockBlock; +import com.thebrokenrail.energonrelics.block.forcefield.util.FieldProjectorBlock; import com.thebrokenrail.energonrelics.block.structure.StructureGeneratorBlock; import com.thebrokenrail.energonrelics.block.misc.ThermalGlassBlock; import com.thebrokenrail.energonrelics.block.battery.ActiveBatteryControllerBlock; @@ -88,6 +93,10 @@ public class EnergonRelics implements ModInitializer { public static final ForcefieldBlock FORCEFIELD_BLOCK = new ForcefieldBlock(); public static final ForcefieldProjectorBlock FORCEFIELD_PROJECTOR_BLOCK = new ForcefieldProjectorBlock(); + public static final TractorBeamBlock TRACTOR_BEAM_BLOCK = new TractorBeamBlock(); + public static final RepulsorBeamBlock REPULSOR_BEAM_BLOCK = new RepulsorBeamBlock(); + public static final TractorBeamProjectorBlock TRACTOR_BEAM_PROJECTOR_BLOCK = new TractorBeamProjectorBlock(); + private static final Identifier BEEP_SOUND_ID = new Identifier(NAMESPACE, "beep"); private static final SoundEvent BEEP_SOUND_EVENT = new SoundEvent(BEEP_SOUND_ID); @@ -139,6 +148,10 @@ public class EnergonRelics implements ModInitializer { FORCEFIELD_BLOCK.register("forcefield"); FORCEFIELD_PROJECTOR_BLOCK.register("forcefield_projector"); + TRACTOR_BEAM_BLOCK.register("tractor_beam"); + REPULSOR_BEAM_BLOCK.register("repulsor_beam"); + TRACTOR_BEAM_PROJECTOR_BLOCK.register("tractor_beam_projector"); + Registry.register(Registry.SOUND_EVENT, BEEP_SOUND_ID, BEEP_SOUND_EVENT); CREATIVE_ENERGY_SOURCE_BLOCK.register("creative_energy_source"); diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/SwitchBlock.java b/src/main/java/com/thebrokenrail/energonrelics/block/SwitchBlock.java index 621edf2..ee23d76 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/block/SwitchBlock.java +++ b/src/main/java/com/thebrokenrail/energonrelics/block/SwitchBlock.java @@ -8,6 +8,9 @@ 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.entity.Entity; +import net.minecraft.entity.ItemEntity; +import net.minecraft.fluid.WaterFluid; import net.minecraft.item.ItemPlacementContext; import net.minecraft.server.world.ServerWorld; import net.minecraft.state.StateManager; diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/entity/forcefield/ForcefieldProjectorBlockEntity.java b/src/main/java/com/thebrokenrail/energonrelics/block/entity/forcefield/FieldProjectorBlockEntity.java similarity index 51% rename from src/main/java/com/thebrokenrail/energonrelics/block/entity/forcefield/ForcefieldProjectorBlockEntity.java rename to src/main/java/com/thebrokenrail/energonrelics/block/entity/forcefield/FieldProjectorBlockEntity.java index 109f89d..3098dba 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/block/entity/forcefield/ForcefieldProjectorBlockEntity.java +++ b/src/main/java/com/thebrokenrail/energonrelics/block/entity/forcefield/FieldProjectorBlockEntity.java @@ -1,8 +1,7 @@ package com.thebrokenrail.energonrelics.block.entity.forcefield; -import com.thebrokenrail.energonrelics.EnergonRelics; -import com.thebrokenrail.energonrelics.block.forcefield.ForcefieldBlock; -import com.thebrokenrail.energonrelics.block.forcefield.ForcefieldProjectorBlock; +import com.thebrokenrail.energonrelics.block.forcefield.util.AbstractFieldBlock; +import com.thebrokenrail.energonrelics.block.forcefield.util.FieldProjectorBlock; import com.thebrokenrail.energonrelics.config.HardcodedConfig; import com.thebrokenrail.energonrelics.energy.core.EnergyReceiverBlockEntity; import com.thebrokenrail.energonrelics.energy.core.util.Action; @@ -11,23 +10,28 @@ import net.minecraft.block.entity.BlockEntityType; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; -public class ForcefieldProjectorBlockEntity extends EnergyReceiverBlockEntity { - public ForcefieldProjectorBlockEntity(BlockEntityType type) { +import java.util.function.Function; + +public class FieldProjectorBlockEntity extends EnergyReceiverBlockEntity { + private final Function block; + + public FieldProjectorBlockEntity(BlockEntityType type, Function block) { super(type); + this.block = block; } @Override protected void energyTick() { assert getWorld() != null; - addAction(Action.createBlockStatePropertyAction(HardcodedConfig.FORCEFIELD_PROJECTOR_ENERGY_REQUIRED, ForcefieldProjectorBlock.POWERED, true, false)); - if (getCachedState().get(ForcefieldProjectorBlock.POWERED)) { - Direction facing = getCachedState().get(ForcefieldProjectorBlock.FACING); - BlockState state = EnergonRelics.FORCEFIELD_BLOCK.getDefaultState().with(ForcefieldBlock.FACING, facing); + addAction(Action.createBlockStatePropertyAction(HardcodedConfig.FORCEFIELD_PROJECTOR_ENERGY_REQUIRED, FieldProjectorBlock.POWERED, true, false)); + if (getCachedState().get(FieldProjectorBlock.POWERED)) { + Direction facing = getCachedState().get(FieldProjectorBlock.FACING); + BlockState state = block.apply(getCachedState()).getDefaultState().with(AbstractFieldBlock.FACING, facing); for (int i = 1; i < HardcodedConfig.FORCEFIELD_MAX_SIZE + 1; i++) { BlockPos targetPos = getPos().offset(facing, i); BlockState targetState = getWorld().getBlockState(targetPos); - if (targetState.isAir()) { + if (targetState.isAir() || (targetState != state && targetState.getBlock() instanceof AbstractFieldBlock && targetState.get(AbstractFieldBlock.FACING) == facing)) { getWorld().setBlockState(targetPos, state); } else if (targetState != state) { break; diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/ForcefieldBlock.java b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/ForcefieldBlock.java index a892f4d..e3ee326 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/ForcefieldBlock.java +++ b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/ForcefieldBlock.java @@ -1,120 +1,16 @@ package com.thebrokenrail.energonrelics.block.forcefield; import com.thebrokenrail.energonrelics.EnergonRelics; -import com.thebrokenrail.energonrelics.block.entity.forcefield.ForcefieldProjectorBlockEntity; -import com.thebrokenrail.energonrelics.block.util.SimpleBlock; -import com.thebrokenrail.energonrelics.config.HardcodedConfig; -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 com.thebrokenrail.energonrelics.block.forcefield.util.AbstractFieldBlock; import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.block.ShapeContext; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.piston.PistonBehavior; -import net.minecraft.sound.BlockSoundGroup; -import net.minecraft.state.StateManager; -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.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.shape.VoxelShape; -import net.minecraft.util.shape.VoxelShapes; -import net.minecraft.world.BlockView; -import net.minecraft.world.WorldAccess; - -@SuppressWarnings("deprecation") -public class ForcefieldBlock extends SimpleBlock { - public static final DirectionProperty FACING = Properties.FACING; +public class ForcefieldBlock extends AbstractFieldBlock { public ForcefieldBlock() { - super(FabricBlockSettings.copy(Blocks.BARRIER).dropsNothing().lightLevel(state -> 4).emissiveLighting((state, world, pos) -> true).nonOpaque().sounds(BlockSoundGroup.GLASS).allowsSpawning((state, world, pos, type) -> false).solidBlock((state, world, pos) -> false).suffocates((state, world, pos) -> false).blockVision((state, world, pos) -> false)); - setDefaultState(getDefaultState().with(FACING, Direction.NORTH)); + super(true); } @Override - protected void appendProperties(StateManager.Builder builder) { - 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 - @Environment(EnvType.CLIENT) - public float getAmbientOcclusionLightLevel(BlockState state, BlockView world, BlockPos pos) { - return 1f; - } - - @Override - public boolean isTranslucent(BlockState state, BlockView world, BlockPos pos) { - return true; - } - - @Override - public VoxelShape getVisualShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { - return VoxelShapes.empty(); - } - - @Override - protected boolean registerItem() { - return false; - } - - public ForcefieldProjectorBlockEntity findProjector(BlockView world, BlockPos pos, BlockState state) { - Direction facing = state.get(FACING).getOpposite(); - ForcefieldProjectorBlockEntity found = null; - for (int i = 0; i < HardcodedConfig.FORCEFIELD_MAX_SIZE + 1; i++) { - BlockPos targetPos = pos.offset(facing, i); - BlockState targetState = world.getBlockState(targetPos); - if (targetState.getBlock() == this) { - if (!facing.equals(targetState.get(FACING).getOpposite())) { - break; - } - } else if (targetState.getBlock() == EnergonRelics.FORCEFIELD_PROJECTOR_BLOCK) { - if (facing.equals(targetState.get(FACING).getOpposite()) && targetState.get(ForcefieldProjectorBlock.POWERED)) { - BlockEntity entity = world.getBlockEntity(targetPos); - if (entity instanceof ForcefieldProjectorBlockEntity) { - found = (ForcefieldProjectorBlockEntity) entity; - } - } - break; - } else { - break; - } - } - return found; - } - - @Override - public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState newState, WorldAccess world, BlockPos pos, BlockPos posFrom) { - BlockState defaultState = super.getStateForNeighborUpdate(state, direction, newState, world, pos, posFrom); - Direction facing = state.get(FACING).getOpposite(); - if (direction.equals(facing)) { - return findProjector(world, pos, state) != null ? defaultState : Blocks.AIR.getDefaultState(); - } else { - return defaultState; - } - } - - @Override - @Environment(EnvType.CLIENT) - public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) { - return stateFrom == state || super.isSideInvisible(state, stateFrom, direction); - } - - @Override - public PistonBehavior getPistonBehavior(BlockState state) { - return PistonBehavior.DESTROY; + protected BlockState getProjectorBlockState() { + return EnergonRelics.FORCEFIELD_PROJECTOR_BLOCK.getDefaultState(); } } diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/ForcefieldProjectorBlock.java b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/ForcefieldProjectorBlock.java index 5bd296e..f50e226 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/ForcefieldProjectorBlock.java +++ b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/ForcefieldProjectorBlock.java @@ -1,35 +1,10 @@ package com.thebrokenrail.energonrelics.block.forcefield; -import com.thebrokenrail.energonrelics.block.entity.forcefield.ForcefieldProjectorBlockEntity; -import com.thebrokenrail.energonrelics.block.util.energy.FacingEnergyBlock; -import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.BlockEntityType; -import net.minecraft.state.StateManager; -import net.minecraft.state.property.BooleanProperty; -import net.minecraft.state.property.Properties; - -import java.util.function.Function; - -public class ForcefieldProjectorBlock extends FacingEnergyBlock { - public static final BooleanProperty POWERED = Properties.POWERED; +import com.thebrokenrail.energonrelics.EnergonRelics; +import com.thebrokenrail.energonrelics.block.forcefield.util.FieldProjectorBlock; +public class ForcefieldProjectorBlock extends FieldProjectorBlock { public ForcefieldProjectorBlock() { - super(FabricBlockSettings.copy(Blocks.IRON_BLOCK)); - setDefaultState(getDefaultState().with(POWERED, false)); - } - - @Override - protected void appendProperties(StateManager.Builder builder) { - super.appendProperties(builder); - builder.add(POWERED); - } - - @Override - protected Function, BlockEntity> getFactory() { - return ForcefieldProjectorBlockEntity::new; + super(state -> EnergonRelics.FORCEFIELD_BLOCK); } } diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/RepulsorBeamBlock.java b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/RepulsorBeamBlock.java new file mode 100644 index 0000000..a494a3b --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/RepulsorBeamBlock.java @@ -0,0 +1,9 @@ +package com.thebrokenrail.energonrelics.block.forcefield; + +import com.thebrokenrail.energonrelics.block.forcefield.util.BeamBlock; + +public class RepulsorBeamBlock extends BeamBlock { + public RepulsorBeamBlock() { + super(true); + } +} diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/TractorBeamBlock.java b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/TractorBeamBlock.java new file mode 100644 index 0000000..9892b65 --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/TractorBeamBlock.java @@ -0,0 +1,9 @@ +package com.thebrokenrail.energonrelics.block.forcefield; + +import com.thebrokenrail.energonrelics.block.forcefield.util.BeamBlock; + +public class TractorBeamBlock extends BeamBlock { + public TractorBeamBlock() { + super(false); + } +} diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/TractorBeamProjectorBlock.java b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/TractorBeamProjectorBlock.java new file mode 100644 index 0000000..8ee15f2 --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/TractorBeamProjectorBlock.java @@ -0,0 +1,56 @@ +package com.thebrokenrail.energonrelics.block.forcefield; + +import com.thebrokenrail.energonrelics.EnergonRelics; +import com.thebrokenrail.energonrelics.block.forcefield.util.FieldProjectorBlock; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.BooleanProperty; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import java.util.Random; + +@SuppressWarnings("deprecation") +public class TractorBeamProjectorBlock extends FieldProjectorBlock { + public static final BooleanProperty IS_REPULSOR = BooleanProperty.of("is_repulsor"); + + public TractorBeamProjectorBlock() { + super(state -> state.get(IS_REPULSOR) ? EnergonRelics.REPULSOR_BEAM_BLOCK : EnergonRelics.TRACTOR_BEAM_BLOCK); + setDefaultState(getDefaultState().with(IS_REPULSOR, false)); + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder); + builder.add(IS_REPULSOR); + } + + @Override + public BlockState getPlacementState(ItemPlacementContext ctx) { + return getDefaultState().with(IS_REPULSOR, ctx.getWorld().isReceivingRedstonePower(ctx.getBlockPos())); + } + + @Override + public void neighborUpdate(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean notify) { + if (!world.isClient()) { + boolean bl = state.get(IS_REPULSOR); + if (bl != world.isReceivingRedstonePower(pos)) { + if (bl) { + world.getBlockTickScheduler().schedule(pos, this, 4); + } else { + world.setBlockState(pos, state.cycle(IS_REPULSOR), 2); + } + } + } + } + + @Override + public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) { + if (state.get(IS_REPULSOR) && !world.isReceivingRedstonePower(pos)) { + world.setBlockState(pos, state.cycle(IS_REPULSOR), 2); + } + } +} diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/util/AbstractFieldBlock.java b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/util/AbstractFieldBlock.java new file mode 100644 index 0000000..a0ad876 --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/util/AbstractFieldBlock.java @@ -0,0 +1,119 @@ +package com.thebrokenrail.energonrelics.block.forcefield.util; + +import com.thebrokenrail.energonrelics.block.entity.forcefield.FieldProjectorBlockEntity; +import com.thebrokenrail.energonrelics.block.util.SimpleBlock; +import com.thebrokenrail.energonrelics.config.HardcodedConfig; +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.Blocks; +import net.minecraft.block.ShapeContext; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.piston.PistonBehavior; +import net.minecraft.sound.BlockSoundGroup; +import net.minecraft.state.StateManager; +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.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; +import net.minecraft.world.WorldAccess; + +@SuppressWarnings("deprecation") +public abstract class AbstractFieldBlock extends SimpleBlock { + public static final DirectionProperty FACING = Properties.FACING; + + public AbstractFieldBlock(boolean hasCollision) { + super((hasCollision ? FabricBlockSettings.copy(Blocks.BARRIER) : FabricBlockSettings.copy(Blocks.BARRIER).noCollision()).dropsNothing().lightLevel(state -> 4).emissiveLighting((state, world, pos) -> true).nonOpaque().sounds(BlockSoundGroup.GLASS).allowsSpawning((state, world, pos, type) -> false).solidBlock((state, world, pos) -> false).suffocates((state, world, pos) -> false).blockVision((state, world, pos) -> false)); + setDefaultState(getDefaultState().with(FACING, Direction.NORTH)); + } + + protected abstract BlockState getProjectorBlockState(); + + @Override + protected void appendProperties(StateManager.Builder builder) { + 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 + @Environment(EnvType.CLIENT) + public float getAmbientOcclusionLightLevel(BlockState state, BlockView world, BlockPos pos) { + return 1f; + } + + @Override + public boolean isTranslucent(BlockState state, BlockView world, BlockPos pos) { + return true; + } + + @Override + public VoxelShape getVisualShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return VoxelShapes.empty(); + } + + @Override + protected boolean registerItem() { + return false; + } + + public FieldProjectorBlockEntity findProjector(BlockView world, BlockPos pos, BlockState state) { + Direction facing = state.get(FACING).getOpposite(); + FieldProjectorBlockEntity found = null; + for (int i = 0; i < HardcodedConfig.FORCEFIELD_MAX_SIZE + 1; i++) { + BlockPos targetPos = pos.offset(facing, i); + BlockState targetState = world.getBlockState(targetPos); + if (targetState.getBlock() == this) { + if (!facing.equals(targetState.get(FACING).getOpposite())) { + break; + } + } else if (targetState == getProjectorBlockState().with(FACING, facing.getOpposite()).with(FieldProjectorBlock.POWERED, true)) { + BlockEntity entity = world.getBlockEntity(targetPos); + if (entity instanceof FieldProjectorBlockEntity) { + found = (FieldProjectorBlockEntity) entity; + } + break; + } else { + break; + } + } + return found; + } + + @Override + public BlockState getStateForNeighborUpdate(BlockState state, Direction direction, BlockState newState, WorldAccess world, BlockPos pos, BlockPos posFrom) { + BlockState defaultState = super.getStateForNeighborUpdate(state, direction, newState, world, pos, posFrom); + Direction facing = state.get(FACING).getOpposite(); + if (direction.equals(facing)) { + return findProjector(world, pos, state) != null ? defaultState : Blocks.AIR.getDefaultState(); + } else { + return defaultState; + } + } + + @Override + @Environment(EnvType.CLIENT) + public boolean isSideInvisible(BlockState state, BlockState stateFrom, Direction direction) { + return state.get(FACING).getOpposite() == direction || stateFrom == state || super.isSideInvisible(state, stateFrom, direction); + } + + @Override + public PistonBehavior getPistonBehavior(BlockState state) { + return PistonBehavior.DESTROY; + } +} diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/util/BeamBlock.java b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/util/BeamBlock.java new file mode 100644 index 0000000..9203d14 --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/util/BeamBlock.java @@ -0,0 +1,52 @@ +package com.thebrokenrail.energonrelics.block.forcefield.util; + +import com.thebrokenrail.energonrelics.EnergonRelics; +import com.thebrokenrail.energonrelics.block.forcefield.TractorBeamProjectorBlock; +import net.minecraft.block.BlockState; +import net.minecraft.block.ShapeContext; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockView; +import net.minecraft.world.World; + +public class BeamBlock extends AbstractFieldBlock { + private final boolean isRepulsor; + + public BeamBlock(boolean isRepulsor) { + super(false); + this.isRepulsor = isRepulsor; + } + + @Override + protected BlockState getProjectorBlockState() { + return EnergonRelics.TRACTOR_BEAM_PROJECTOR_BLOCK.getDefaultState().with(TractorBeamProjectorBlock.IS_REPULSOR, isRepulsor); + } + + @SuppressWarnings("deprecation") + @Override + public void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) { + super.onEntityCollision(state, world, pos, entity); + if (!(entity instanceof PlayerEntity) || !((PlayerEntity) entity).abilities.flying) { + entity.slowMovement(state, new Vec3d(0.9d, 0.9d, 0.9d)); + + Direction facing = state.get(FACING); + if (!isRepulsor) { + facing = facing.getOpposite(); + } + + Vec3d pullForce = Vec3d.of(facing.getVector()).multiply(0.065f); + entity.addVelocity(pullForce.getX(), pullForce.getY(), pullForce.getZ()); + } + } + + @SuppressWarnings("deprecation") + @Override + public VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) { + return VoxelShapes.empty(); + } +} diff --git a/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/util/FieldProjectorBlock.java b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/util/FieldProjectorBlock.java new file mode 100644 index 0000000..83a6e94 --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/block/forcefield/util/FieldProjectorBlock.java @@ -0,0 +1,38 @@ +package com.thebrokenrail.energonrelics.block.forcefield.util; + +import com.thebrokenrail.energonrelics.block.entity.forcefield.FieldProjectorBlockEntity; +import com.thebrokenrail.energonrelics.block.util.energy.FacingEnergyBlock; +import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.state.StateManager; +import net.minecraft.state.property.BooleanProperty; +import net.minecraft.state.property.Properties; + +import java.util.function.Function; + +public class FieldProjectorBlock extends FacingEnergyBlock { + public static final BooleanProperty POWERED = Properties.POWERED; + + private final Function block; + + public FieldProjectorBlock(Function block) { + super(FabricBlockSettings.copy(Blocks.IRON_BLOCK)); + setDefaultState(getDefaultState().with(POWERED, false)); + this.block = block; + } + + @Override + protected void appendProperties(StateManager.Builder builder) { + super.appendProperties(builder); + builder.add(POWERED); + } + + @Override + protected Function, BlockEntity> getFactory() { + return type -> new FieldProjectorBlockEntity(type, block); + } +} diff --git a/src/main/java/com/thebrokenrail/energonrelics/client/EnergonRelicsClient.java b/src/main/java/com/thebrokenrail/energonrelics/client/EnergonRelicsClient.java index 4c0a13a..63e19bb 100644 --- a/src/main/java/com/thebrokenrail/energonrelics/client/EnergonRelicsClient.java +++ b/src/main/java/com/thebrokenrail/energonrelics/client/EnergonRelicsClient.java @@ -1,6 +1,7 @@ package com.thebrokenrail.energonrelics.client; import com.thebrokenrail.energonrelics.EnergonRelics; +import com.thebrokenrail.energonrelics.block.forcefield.util.AbstractFieldBlock; import com.thebrokenrail.energonrelics.block.util.energy.EnergyBlock; import com.thebrokenrail.energonrelics.client.config.UserConfig; import me.sargunvohra.mcmods.autoconfig1u.AutoConfig; @@ -40,12 +41,15 @@ public class EnergonRelicsClient implements ClientModInitializer { BlockRenderLayerMap.INSTANCE.putBlock(EnergonRelics.THERMAL_GLASS_BLOCK, RenderLayer.getCutout()); BlockRenderLayerMap.INSTANCE.putBlock(EnergonRelics.DEFENSIVE_LASER_BLOCK, RenderLayer.getCutout()); + BlockRenderLayerMap.INSTANCE.putBlock(EnergonRelics.FORCEFIELD_BLOCK, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(EnergonRelics.TRACTOR_BEAM_BLOCK, RenderLayer.getTranslucent()); + BlockRenderLayerMap.INSTANCE.putBlock(EnergonRelics.REPULSOR_BEAM_BLOCK, RenderLayer.getTranslucent()); AutoConfig.register(UserConfig.class, ReloadSerializer::new); AttackBlockCallback.EVENT.register((playerEntity, world, hand, blockPos, direction) -> { - if (world.getBlockState(blockPos).getBlock() == EnergonRelics.FORCEFIELD_BLOCK) { + if (world.getBlockState(blockPos).getBlock() instanceof AbstractFieldBlock) { return ActionResult.FAIL; } else { return ActionResult.PASS; diff --git a/src/main/java/com/thebrokenrail/energonrelics/mixin/MixinEntity.java b/src/main/java/com/thebrokenrail/energonrelics/mixin/MixinEntity.java new file mode 100644 index 0000000..fcce1d6 --- /dev/null +++ b/src/main/java/com/thebrokenrail/energonrelics/mixin/MixinEntity.java @@ -0,0 +1,67 @@ +package com.thebrokenrail.energonrelics.mixin; + +import com.thebrokenrail.energonrelics.block.forcefield.util.BeamBlock; +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.function.Predicate; + +@Mixin(Entity.class) +public abstract class MixinEntity { + @Shadow public abstract Box getBoundingBox(); + + @Shadow public abstract World getEntityWorld(); + + @Unique + private boolean isTouching(Predicate test) { + Box box = getBoundingBox(); + int i = MathHelper.floor(box.minX); + int j = MathHelper.ceil(box.maxX); + int k = MathHelper.floor(box.minY); + int l = MathHelper.ceil(box.maxY); + int m = MathHelper.floor(box.minZ); + int n = MathHelper.ceil(box.maxZ); + for (int p = i; p < j; ++p) { + for (int q = k; q < l; ++q) { + for (int r = m; r < n; ++r) { + BlockPos pos = new BlockPos(p, q, r); + if (test.test(getEntityWorld().getBlockState(pos).getBlock())) { + return true; + } + } + } + } + return false; + } + + @Unique + private boolean saving = false; + + @Inject(at = @At("HEAD"), method = "hasNoGravity", cancellable = true) + public void hasNoGravity(CallbackInfoReturnable info) { + if (isTouching(block -> block instanceof BeamBlock) && !saving) { + info.setReturnValue(true); + } + } + + @Inject(at = @At("HEAD"), method = "toTag") + public void tagTagHead(CompoundTag tag, CallbackInfoReturnable info) { + saving = true; + } + + @Inject(at = @At("RETURN"), method = "toTag") + public void tagTagReturn(CompoundTag tag, CallbackInfoReturnable info) { + saving = false; + } +} diff --git a/src/main/resources/assets/energonrelics-azazelthedemonlord/textures/block/forcefield_projector_side.png b/src/main/resources/assets/energonrelics-azazelthedemonlord/textures/block/field_projector_side.png similarity index 100% rename from src/main/resources/assets/energonrelics-azazelthedemonlord/textures/block/forcefield_projector_side.png rename to src/main/resources/assets/energonrelics-azazelthedemonlord/textures/block/field_projector_side.png diff --git a/src/main/resources/assets/energonrelics/blockstates/repulsor_beam.json b/src/main/resources/assets/energonrelics/blockstates/repulsor_beam.json new file mode 100644 index 0000000..9832561 --- /dev/null +++ b/src/main/resources/assets/energonrelics/blockstates/repulsor_beam.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "energonrelics:block/repulsor_beam" + } + } +} diff --git a/src/main/resources/assets/energonrelics/blockstates/tractor_beam.json b/src/main/resources/assets/energonrelics/blockstates/tractor_beam.json new file mode 100644 index 0000000..a95978c --- /dev/null +++ b/src/main/resources/assets/energonrelics/blockstates/tractor_beam.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "energonrelics:block/tractor_beam" + } + } +} diff --git a/src/main/resources/assets/energonrelics/blockstates/tractor_beam_projector.json b/src/main/resources/assets/energonrelics/blockstates/tractor_beam_projector.json new file mode 100644 index 0000000..780f1b1 --- /dev/null +++ b/src/main/resources/assets/energonrelics/blockstates/tractor_beam_projector.json @@ -0,0 +1,96 @@ +{ + "variants": { + "facing=down,powered=false,is_repulsor=false": { + "model": "energonrelics:block/tractor_beam_projector_off", + "x": 90 + }, + "facing=down,powered=true,is_repulsor=false": { + "model": "energonrelics:block/tractor_beam_projector_on", + "x": 90 + }, + "facing=east,powered=false,is_repulsor=false": { + "model": "energonrelics:block/tractor_beam_projector_off", + "y": 90 + }, + "facing=east,powered=true,is_repulsor=false": { + "model": "energonrelics:block/tractor_beam_projector_on", + "y": 90 + }, + "facing=north,powered=false,is_repulsor=false": { + "model": "energonrelics:block/tractor_beam_projector_off" + }, + "facing=north,powered=true,is_repulsor=false": { + "model": "energonrelics:block/tractor_beam_projector_on" + }, + "facing=south,powered=false,is_repulsor=false": { + "model": "energonrelics:block/tractor_beam_projector_off", + "y": 180 + }, + "facing=south,powered=true,is_repulsor=false": { + "model": "energonrelics:block/tractor_beam_projector_on", + "y": 180 + }, + "facing=up,powered=false,is_repulsor=false": { + "model": "energonrelics:block/tractor_beam_projector_off", + "x": 270 + }, + "facing=up,powered=true,is_repulsor=false": { + "model": "energonrelics:block/tractor_beam_projector_on", + "x": 270 + }, + "facing=west,powered=false,is_repulsor=false": { + "model": "energonrelics:block/tractor_beam_projector_off", + "y": 270 + }, + "facing=west,powered=true,is_repulsor=false": { + "model": "energonrelics:block/tractor_beam_projector_on", + "y": 270 + }, + "facing=down,powered=false,is_repulsor=true": { + "model": "energonrelics:block/repulsor_beam_projector_off", + "x": 90 + }, + "facing=down,powered=true,is_repulsor=true": { + "model": "energonrelics:block/repulsor_beam_projector_on", + "x": 90 + }, + "facing=east,powered=false,is_repulsor=true": { + "model": "energonrelics:block/repulsor_beam_projector_off", + "y": 90 + }, + "facing=east,powered=true,is_repulsor=true": { + "model": "energonrelics:block/repulsor_beam_projector_on", + "y": 90 + }, + "facing=north,powered=false,is_repulsor=true": { + "model": "energonrelics:block/repulsor_beam_projector_off" + }, + "facing=north,powered=true,is_repulsor=true": { + "model": "energonrelics:block/repulsor_beam_projector_on" + }, + "facing=south,powered=false,is_repulsor=true": { + "model": "energonrelics:block/repulsor_beam_projector_off", + "y": 180 + }, + "facing=south,powered=true,is_repulsor=true": { + "model": "energonrelics:block/repulsor_beam_projector_on", + "y": 180 + }, + "facing=up,powered=false,is_repulsor=true": { + "model": "energonrelics:block/repulsor_beam_projector_off", + "x": 270 + }, + "facing=up,powered=true,is_repulsor=true": { + "model": "energonrelics:block/repulsor_beam_projector_on", + "x": 270 + }, + "facing=west,powered=false,is_repulsor=true": { + "model": "energonrelics:block/repulsor_beam_projector_off", + "y": 270 + }, + "facing=west,powered=true,is_repulsor=true": { + "model": "energonrelics:block/repulsor_beam_projector_on", + "y": 270 + } + } +} \ 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 70e969c..8932f16 100644 --- a/src/main/resources/assets/energonrelics/lang/en_us.json +++ b/src/main/resources/assets/energonrelics/lang/en_us.json @@ -38,5 +38,6 @@ "block.energonrelics.forcefield": "Forcefield", "block.energonrelics.forcefield_projector": "Forcefield Projector", "block.energonrelics.creative_energy_source": "Creative Energy Source", - "block.energonrelics.holographic_sky": "Holographic Sky" + "block.energonrelics.holographic_sky": "Holographic Sky", + "block.energonrelics.tractor_beam_projector": "Tractor Beam Projector" } \ No newline at end of file diff --git a/src/main/resources/assets/energonrelics/models/block/forcefield_projector_off.json b/src/main/resources/assets/energonrelics/models/block/forcefield_projector_off.json index 89c0479..e2c9165 100644 --- a/src/main/resources/assets/energonrelics/models/block/forcefield_projector_off.json +++ b/src/main/resources/assets/energonrelics/models/block/forcefield_projector_off.json @@ -1,8 +1,8 @@ { "parent": "minecraft:block/orientable", "textures": { - "top": "energonrelics:block/forcefield_projector_side", + "top": "energonrelics:block/field_projector_side", "front": "energonrelics:block/forcefield_projector_off", - "side": "energonrelics:block/forcefield_projector_side" + "side": "energonrelics:block/field_projector_side" } } \ No newline at end of file diff --git a/src/main/resources/assets/energonrelics/models/block/forcefield_projector_on.json b/src/main/resources/assets/energonrelics/models/block/forcefield_projector_on.json index 3cf8217..df43978 100644 --- a/src/main/resources/assets/energonrelics/models/block/forcefield_projector_on.json +++ b/src/main/resources/assets/energonrelics/models/block/forcefield_projector_on.json @@ -1,8 +1,8 @@ { "parent": "minecraft:block/orientable", "textures": { - "top": "energonrelics:block/forcefield_projector_side", + "top": "energonrelics:block/field_projector_side", "front": "energonrelics:block/forcefield_projector_on", - "side": "energonrelics:block/forcefield_projector_side" + "side": "energonrelics:block/field_projector_side" } } \ No newline at end of file diff --git a/src/main/resources/assets/energonrelics/models/block/repulsor_beam.json b/src/main/resources/assets/energonrelics/models/block/repulsor_beam.json new file mode 100644 index 0000000..2b5680b --- /dev/null +++ b/src/main/resources/assets/energonrelics/models/block/repulsor_beam.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "energonrelics:block/repulsor_beam" + } +} diff --git a/src/main/resources/assets/energonrelics/models/block/repulsor_beam_projector_off.json b/src/main/resources/assets/energonrelics/models/block/repulsor_beam_projector_off.json new file mode 100644 index 0000000..d179410 --- /dev/null +++ b/src/main/resources/assets/energonrelics/models/block/repulsor_beam_projector_off.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/orientable", + "textures": { + "top": "energonrelics:block/field_projector_side", + "front": "energonrelics:block/repulsor_beam_projector_off", + "side": "energonrelics:block/field_projector_side" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/energonrelics/models/block/repulsor_beam_projector_on.json b/src/main/resources/assets/energonrelics/models/block/repulsor_beam_projector_on.json new file mode 100644 index 0000000..226d5df --- /dev/null +++ b/src/main/resources/assets/energonrelics/models/block/repulsor_beam_projector_on.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/orientable", + "textures": { + "top": "energonrelics:block/field_projector_side", + "front": "energonrelics:block/repulsor_beam_projector_on", + "side": "energonrelics:block/field_projector_side" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/energonrelics/models/block/tractor_beam.json b/src/main/resources/assets/energonrelics/models/block/tractor_beam.json new file mode 100644 index 0000000..0511f31 --- /dev/null +++ b/src/main/resources/assets/energonrelics/models/block/tractor_beam.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:block/cube_all", + "textures": { + "all": "energonrelics:block/tractor_beam" + } +} diff --git a/src/main/resources/assets/energonrelics/models/block/tractor_beam_projector_off.json b/src/main/resources/assets/energonrelics/models/block/tractor_beam_projector_off.json new file mode 100644 index 0000000..4aad796 --- /dev/null +++ b/src/main/resources/assets/energonrelics/models/block/tractor_beam_projector_off.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/orientable", + "textures": { + "top": "energonrelics:block/field_projector_side", + "front": "energonrelics:block/tractor_beam_projector_off", + "side": "energonrelics:block/field_projector_side" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/energonrelics/models/block/tractor_beam_projector_on.json b/src/main/resources/assets/energonrelics/models/block/tractor_beam_projector_on.json new file mode 100644 index 0000000..1011c84 --- /dev/null +++ b/src/main/resources/assets/energonrelics/models/block/tractor_beam_projector_on.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/orientable", + "textures": { + "top": "energonrelics:block/field_projector_side", + "front": "energonrelics:block/tractor_beam_projector_on", + "side": "energonrelics:block/field_projector_side" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/energonrelics/models/item/tractor_beam_projector.json b/src/main/resources/assets/energonrelics/models/item/tractor_beam_projector.json new file mode 100644 index 0000000..b517e63 --- /dev/null +++ b/src/main/resources/assets/energonrelics/models/item/tractor_beam_projector.json @@ -0,0 +1,3 @@ +{ + "parent": "energonrelics:block/tractor_beam_projector_off" +} \ No newline at end of file diff --git a/src/main/resources/assets/energonrelics/textures/block/forcefield_projector_side.png b/src/main/resources/assets/energonrelics/textures/block/field_projector_side.png similarity index 100% rename from src/main/resources/assets/energonrelics/textures/block/forcefield_projector_side.png rename to src/main/resources/assets/energonrelics/textures/block/field_projector_side.png diff --git a/src/main/resources/assets/energonrelics/textures/block/repulsor_beam.png b/src/main/resources/assets/energonrelics/textures/block/repulsor_beam.png new file mode 100644 index 0000000..97ed41f Binary files /dev/null and b/src/main/resources/assets/energonrelics/textures/block/repulsor_beam.png differ diff --git a/src/main/resources/assets/energonrelics/textures/block/repulsor_beam_projector_off.png b/src/main/resources/assets/energonrelics/textures/block/repulsor_beam_projector_off.png new file mode 100644 index 0000000..f284846 Binary files /dev/null and b/src/main/resources/assets/energonrelics/textures/block/repulsor_beam_projector_off.png differ diff --git a/src/main/resources/assets/energonrelics/textures/block/repulsor_beam_projector_on.png b/src/main/resources/assets/energonrelics/textures/block/repulsor_beam_projector_on.png new file mode 100644 index 0000000..c8710d0 Binary files /dev/null and b/src/main/resources/assets/energonrelics/textures/block/repulsor_beam_projector_on.png differ diff --git a/src/main/resources/assets/energonrelics/textures/block/tractor_beam.png b/src/main/resources/assets/energonrelics/textures/block/tractor_beam.png new file mode 100644 index 0000000..65a3c78 Binary files /dev/null and b/src/main/resources/assets/energonrelics/textures/block/tractor_beam.png differ diff --git a/src/main/resources/assets/energonrelics/textures/block/tractor_beam_projector_off.png b/src/main/resources/assets/energonrelics/textures/block/tractor_beam_projector_off.png new file mode 100644 index 0000000..a47af92 Binary files /dev/null and b/src/main/resources/assets/energonrelics/textures/block/tractor_beam_projector_off.png differ diff --git a/src/main/resources/assets/energonrelics/textures/block/tractor_beam_projector_on.png b/src/main/resources/assets/energonrelics/textures/block/tractor_beam_projector_on.png new file mode 100644 index 0000000..844a891 Binary files /dev/null and b/src/main/resources/assets/energonrelics/textures/block/tractor_beam_projector_on.png differ diff --git a/src/main/resources/energonrelics.mixins.json b/src/main/resources/energonrelics.mixins.json index 86bf0bc..17c9cc7 100644 --- a/src/main/resources/energonrelics.mixins.json +++ b/src/main/resources/energonrelics.mixins.json @@ -11,6 +11,7 @@ "BrewingRecipeRegistryAccessor", "DamageSourceAccessor", "MixinDefaultBiomeFeatures", + "MixinEntity", "MixinLivingEntity", "MixinWorld" ],