Add Tractor Beams
All checks were successful
EnergonRelics/pipeline/head This commit looks good

This commit is contained in:
TheBrokenRail 2020-07-27 23:10:16 -04:00
parent f02d352811
commit 1d4c0b7316
35 changed files with 560 additions and 156 deletions

View File

@ -5,9 +5,14 @@ import com.thebrokenrail.energonrelics.block.CreativeEnergySourceBlock;
import com.thebrokenrail.energonrelics.block.DefensiveLaserBlock; import com.thebrokenrail.energonrelics.block.DefensiveLaserBlock;
import com.thebrokenrail.energonrelics.block.HolographicSkyBlock; import com.thebrokenrail.energonrelics.block.HolographicSkyBlock;
import com.thebrokenrail.energonrelics.block.LightningRodBlock; 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.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.structure.StructureGeneratorBlock;
import com.thebrokenrail.energonrelics.block.misc.ThermalGlassBlock; import com.thebrokenrail.energonrelics.block.misc.ThermalGlassBlock;
import com.thebrokenrail.energonrelics.block.battery.ActiveBatteryControllerBlock; 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 ForcefieldBlock FORCEFIELD_BLOCK = new ForcefieldBlock();
public static final ForcefieldProjectorBlock FORCEFIELD_PROJECTOR_BLOCK = new ForcefieldProjectorBlock(); 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 Identifier BEEP_SOUND_ID = new Identifier(NAMESPACE, "beep");
private static final SoundEvent BEEP_SOUND_EVENT = new SoundEvent(BEEP_SOUND_ID); 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_BLOCK.register("forcefield");
FORCEFIELD_PROJECTOR_BLOCK.register("forcefield_projector"); 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); Registry.register(Registry.SOUND_EVENT, BEEP_SOUND_ID, BEEP_SOUND_EVENT);
CREATIVE_ENERGY_SOURCE_BLOCK.register("creative_energy_source"); CREATIVE_ENERGY_SOURCE_BLOCK.register("creative_energy_source");

View File

@ -8,6 +8,9 @@ import net.minecraft.block.BlockState;
import net.minecraft.block.Material; import net.minecraft.block.Material;
import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType; 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.item.ItemPlacementContext;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.StateManager; import net.minecraft.state.StateManager;

View File

@ -1,8 +1,7 @@
package com.thebrokenrail.energonrelics.block.entity.forcefield; package com.thebrokenrail.energonrelics.block.entity.forcefield;
import com.thebrokenrail.energonrelics.EnergonRelics; import com.thebrokenrail.energonrelics.block.forcefield.util.AbstractFieldBlock;
import com.thebrokenrail.energonrelics.block.forcefield.ForcefieldBlock; import com.thebrokenrail.energonrelics.block.forcefield.util.FieldProjectorBlock;
import com.thebrokenrail.energonrelics.block.forcefield.ForcefieldProjectorBlock;
import com.thebrokenrail.energonrelics.config.HardcodedConfig; import com.thebrokenrail.energonrelics.config.HardcodedConfig;
import com.thebrokenrail.energonrelics.energy.core.EnergyReceiverBlockEntity; import com.thebrokenrail.energonrelics.energy.core.EnergyReceiverBlockEntity;
import com.thebrokenrail.energonrelics.energy.core.util.Action; 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.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
public class ForcefieldProjectorBlockEntity extends EnergyReceiverBlockEntity { import java.util.function.Function;
public ForcefieldProjectorBlockEntity(BlockEntityType<?> type) {
public class FieldProjectorBlockEntity extends EnergyReceiverBlockEntity {
private final Function<BlockState, AbstractFieldBlock> block;
public FieldProjectorBlockEntity(BlockEntityType<?> type, Function<BlockState, AbstractFieldBlock> block) {
super(type); super(type);
this.block = block;
} }
@Override @Override
protected void energyTick() { protected void energyTick() {
assert getWorld() != null; assert getWorld() != null;
addAction(Action.createBlockStatePropertyAction(HardcodedConfig.FORCEFIELD_PROJECTOR_ENERGY_REQUIRED, ForcefieldProjectorBlock.POWERED, true, false)); addAction(Action.createBlockStatePropertyAction(HardcodedConfig.FORCEFIELD_PROJECTOR_ENERGY_REQUIRED, FieldProjectorBlock.POWERED, true, false));
if (getCachedState().get(ForcefieldProjectorBlock.POWERED)) { if (getCachedState().get(FieldProjectorBlock.POWERED)) {
Direction facing = getCachedState().get(ForcefieldProjectorBlock.FACING); Direction facing = getCachedState().get(FieldProjectorBlock.FACING);
BlockState state = EnergonRelics.FORCEFIELD_BLOCK.getDefaultState().with(ForcefieldBlock.FACING, facing); BlockState state = block.apply(getCachedState()).getDefaultState().with(AbstractFieldBlock.FACING, facing);
for (int i = 1; i < HardcodedConfig.FORCEFIELD_MAX_SIZE + 1; i++) { for (int i = 1; i < HardcodedConfig.FORCEFIELD_MAX_SIZE + 1; i++) {
BlockPos targetPos = getPos().offset(facing, i); BlockPos targetPos = getPos().offset(facing, i);
BlockState targetState = getWorld().getBlockState(targetPos); 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); getWorld().setBlockState(targetPos, state);
} else if (targetState != state) { } else if (targetState != state) {
break; break;

View File

@ -1,120 +1,16 @@
package com.thebrokenrail.energonrelics.block.forcefield; package com.thebrokenrail.energonrelics.block.forcefield;
import com.thebrokenrail.energonrelics.EnergonRelics; import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.block.entity.forcefield.ForcefieldProjectorBlockEntity; import com.thebrokenrail.energonrelics.block.forcefield.util.AbstractFieldBlock;
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.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() { 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)); super(true);
setDefaultState(getDefaultState().with(FACING, Direction.NORTH));
} }
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected BlockState getProjectorBlockState() {
builder.add(FACING); return EnergonRelics.FORCEFIELD_PROJECTOR_BLOCK.getDefaultState();
}
@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;
} }
} }

View File

@ -1,35 +1,10 @@
package com.thebrokenrail.energonrelics.block.forcefield; package com.thebrokenrail.energonrelics.block.forcefield;
import com.thebrokenrail.energonrelics.block.entity.forcefield.ForcefieldProjectorBlockEntity; import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.block.util.energy.FacingEnergyBlock; import com.thebrokenrail.energonrelics.block.forcefield.util.FieldProjectorBlock;
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;
public class ForcefieldProjectorBlock extends FieldProjectorBlock {
public ForcefieldProjectorBlock() { public ForcefieldProjectorBlock() {
super(FabricBlockSettings.copy(Blocks.IRON_BLOCK)); super(state -> EnergonRelics.FORCEFIELD_BLOCK);
setDefaultState(getDefaultState().with(POWERED, false));
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(POWERED);
}
@Override
protected Function<BlockEntityType<BlockEntity>, BlockEntity> getFactory() {
return ForcefieldProjectorBlockEntity::new;
} }
} }

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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<Block, BlockState> 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);
}
}
}

View File

@ -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<Block, BlockState> 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;
}
}

View File

@ -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();
}
}

View File

@ -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<BlockState, AbstractFieldBlock> block;
public FieldProjectorBlock(Function<BlockState, AbstractFieldBlock> block) {
super(FabricBlockSettings.copy(Blocks.IRON_BLOCK));
setDefaultState(getDefaultState().with(POWERED, false));
this.block = block;
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(POWERED);
}
@Override
protected Function<BlockEntityType<BlockEntity>, BlockEntity> getFactory() {
return type -> new FieldProjectorBlockEntity(type, block);
}
}

View File

@ -1,6 +1,7 @@
package com.thebrokenrail.energonrelics.client; package com.thebrokenrail.energonrelics.client;
import com.thebrokenrail.energonrelics.EnergonRelics; 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.block.util.energy.EnergyBlock;
import com.thebrokenrail.energonrelics.client.config.UserConfig; import com.thebrokenrail.energonrelics.client.config.UserConfig;
import me.sargunvohra.mcmods.autoconfig1u.AutoConfig; 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.THERMAL_GLASS_BLOCK, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(EnergonRelics.DEFENSIVE_LASER_BLOCK, RenderLayer.getCutout()); BlockRenderLayerMap.INSTANCE.putBlock(EnergonRelics.DEFENSIVE_LASER_BLOCK, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(EnergonRelics.FORCEFIELD_BLOCK, RenderLayer.getTranslucent()); 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); AutoConfig.register(UserConfig.class, ReloadSerializer::new);
AttackBlockCallback.EVENT.register((playerEntity, world, hand, blockPos, direction) -> { 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; return ActionResult.FAIL;
} else { } else {
return ActionResult.PASS; return ActionResult.PASS;

View File

@ -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<Block> 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<Boolean> info) {
if (isTouching(block -> block instanceof BeamBlock) && !saving) {
info.setReturnValue(true);
}
}
@Inject(at = @At("HEAD"), method = "toTag")
public void tagTagHead(CompoundTag tag, CallbackInfoReturnable<CompoundTag> info) {
saving = true;
}
@Inject(at = @At("RETURN"), method = "toTag")
public void tagTagReturn(CompoundTag tag, CallbackInfoReturnable<CompoundTag> info) {
saving = false;
}
}

View File

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "energonrelics:block/repulsor_beam"
}
}
}

View File

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "energonrelics:block/tractor_beam"
}
}
}

View File

@ -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
}
}
}

View File

@ -38,5 +38,6 @@
"block.energonrelics.forcefield": "Forcefield", "block.energonrelics.forcefield": "Forcefield",
"block.energonrelics.forcefield_projector": "Forcefield Projector", "block.energonrelics.forcefield_projector": "Forcefield Projector",
"block.energonrelics.creative_energy_source": "Creative Energy Source", "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"
} }

View File

@ -1,8 +1,8 @@
{ {
"parent": "minecraft:block/orientable", "parent": "minecraft:block/orientable",
"textures": { "textures": {
"top": "energonrelics:block/forcefield_projector_side", "top": "energonrelics:block/field_projector_side",
"front": "energonrelics:block/forcefield_projector_off", "front": "energonrelics:block/forcefield_projector_off",
"side": "energonrelics:block/forcefield_projector_side" "side": "energonrelics:block/field_projector_side"
} }
} }

View File

@ -1,8 +1,8 @@
{ {
"parent": "minecraft:block/orientable", "parent": "minecraft:block/orientable",
"textures": { "textures": {
"top": "energonrelics:block/forcefield_projector_side", "top": "energonrelics:block/field_projector_side",
"front": "energonrelics:block/forcefield_projector_on", "front": "energonrelics:block/forcefield_projector_on",
"side": "energonrelics:block/forcefield_projector_side" "side": "energonrelics:block/field_projector_side"
} }
} }

View File

@ -0,0 +1,6 @@
{
"parent": "minecraft:block/cube_all",
"textures": {
"all": "energonrelics:block/repulsor_beam"
}
}

View File

@ -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"
}
}

View File

@ -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"
}
}

View File

@ -0,0 +1,6 @@
{
"parent": "minecraft:block/cube_all",
"textures": {
"all": "energonrelics:block/tractor_beam"
}
}

View File

@ -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"
}
}

View File

@ -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"
}
}

View File

@ -0,0 +1,3 @@
{
"parent": "energonrelics:block/tractor_beam_projector_off"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 734 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 735 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 735 B

View File

@ -11,6 +11,7 @@
"BrewingRecipeRegistryAccessor", "BrewingRecipeRegistryAccessor",
"DamageSourceAccessor", "DamageSourceAccessor",
"MixinDefaultBiomeFeatures", "MixinDefaultBiomeFeatures",
"MixinEntity",
"MixinLivingEntity", "MixinLivingEntity",
"MixinWorld" "MixinWorld"
], ],