Improve Structure

This commit is contained in:
TheBrokenRail 2020-07-20 17:03:17 -04:00
parent 5a2b7c0d33
commit 58b97a8d80
13 changed files with 460 additions and 97 deletions

View File

@ -22,7 +22,7 @@ public class TestBlock extends SimpleBlock {
public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean notify) { public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean notify) {
super.onBlockAdded(state, world, pos, oldState, notify); super.onBlockAdded(state, world, pos, oldState, notify);
if (!world.isClient()) { if (!world.isClient()) {
new StructurePlacer(new ResearchComplexStartPart(new ResearchComplexState(world), Collections.emptyList())).place(world, pos); new StructurePlacer(new ResearchComplexStartPart(new ResearchComplexState(world, world.random), Collections.emptyList())).place(world, pos);
} }
} }
} }

View File

@ -16,6 +16,7 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Identifier;
import net.minecraft.util.hit.HitResult; import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box; import net.minecraft.util.math.Box;
@ -225,7 +226,7 @@ public class DefensiveLaserBlockEntity extends EnergyReceiverBlockEntity {
@Override @Override
protected void tickEnergy() { protected void tickEnergy() {
assert getWorld() != null; assert getWorld() != null;
addAction(Action.createBlockStatePropertyAction(HardcodedConfig.DEFENSIVE_LASER_IDLE_ENERGY_REQUIRED, DefensiveLaserBlock.POWERED, true, false)); addAction(Action.createBlockStatePropertyAction(HardcodedConfig.DEFENSIVE_LASER_IDLE_ENERGY_REQUIRED, DefensiveLaserBlock.POWERED, true, false, new Identifier(EnergonRelics.NAMESPACE, "defensive_laser_idle")));
if (getCachedState().get(DefensiveLaserBlock.POWERED)) { if (getCachedState().get(DefensiveLaserBlock.POWERED)) {
if (countdown > 0) { if (countdown > 0) {
countdown--; countdown--;
@ -234,7 +235,7 @@ public class DefensiveLaserBlockEntity extends EnergyReceiverBlockEntity {
addAction(new Action(HardcodedConfig.DEFENSIVE_LASER_FIRE_ENERGY_REQUIRED, (world, pos, state) -> { addAction(new Action(HardcodedConfig.DEFENSIVE_LASER_FIRE_ENERGY_REQUIRED, (world, pos, state) -> {
firing = false; firing = false;
fire(world, pos); fire(world, pos);
}, (world, pos, state) -> firing = false)); }, (world, pos, state) -> firing = false, new Identifier(EnergonRelics.NAMESPACE, "defensive_laser_fire")));
target = null; target = null;
firing = true; firing = true;
} else if (countdown < 1 && !firing) { } else if (countdown < 1 && !firing) {

View File

@ -1,10 +1,12 @@
package com.thebrokenrail.energonrelics.block.entity; package com.thebrokenrail.energonrelics.block.entity;
import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.config.HardcodedConfig; import com.thebrokenrail.energonrelics.config.HardcodedConfig;
import com.thebrokenrail.energonrelics.block.EnergonLightBlock; import com.thebrokenrail.energonrelics.block.EnergonLightBlock;
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;
import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.util.Identifier;
public class EnergonLightBlockEntity extends EnergyReceiverBlockEntity { public class EnergonLightBlockEntity extends EnergyReceiverBlockEntity {
public EnergonLightBlockEntity(BlockEntityType<?> type) { public EnergonLightBlockEntity(BlockEntityType<?> type) {
@ -13,6 +15,6 @@ public class EnergonLightBlockEntity extends EnergyReceiverBlockEntity {
@Override @Override
protected void tickEnergy() { protected void tickEnergy() {
addAction(Action.createBlockStatePropertyAction(HardcodedConfig.ENERGON_LIGHT_ENERGY_REQUIRED, EnergonLightBlock.POWERED, true, false)); addAction(Action.createBlockStatePropertyAction(HardcodedConfig.ENERGON_LIGHT_ENERGY_REQUIRED, EnergonLightBlock.POWERED, true, false, new Identifier(EnergonRelics.NAMESPACE, "energon_light")));
} }
} }

View File

@ -9,6 +9,7 @@ import com.thebrokenrail.energonrelics.energy.helper.EnergyGenerator;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
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.util.Identifier;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -18,11 +19,12 @@ public class PassiveBatteryControllerBlockEntity extends EnergyReceiverBlockEnti
super(type); super(type);
} }
private static class UnlimitedAction implements Action.PropagatedAction { private static class UnlimitedAction extends Action.UniqueAction implements Action.PropagatedAction {
private final World world; private final World world;
private final BlockPos pos; private final BlockPos pos;
private UnlimitedAction(World world, BlockPos pos) { private UnlimitedAction(World world, BlockPos pos) {
super(new Identifier(EnergonRelics.NAMESPACE, "active_battery_controller"), pos);
this.world = world; this.world = world;
this.pos = pos; this.pos = pos;
} }
@ -56,7 +58,7 @@ public class PassiveBatteryControllerBlockEntity extends EnergyReceiverBlockEnti
PassiveBatteryControllerBlockEntity battery = (PassiveBatteryControllerBlockEntity) entity; PassiveBatteryControllerBlockEntity battery = (PassiveBatteryControllerBlockEntity) entity;
battery.setEnergy(battery.getEnergy() + charge); battery.setEnergy(battery.getEnergy() + charge);
} }
}, (world, pos, state) -> {})); }, (world, pos, state) -> {}, new Identifier(EnergonRelics.NAMESPACE, "passive_battery_controller")));
} else { } else {
propagateAction(new UnlimitedAction(getWorld(), getPos())); propagateAction(new UnlimitedAction(getWorld(), getPos()));
} }

View File

@ -90,8 +90,12 @@ public class EnergyProviderBlockEntity extends BlockEntity implements EnergyProv
private void tickPropagatedActions() { private void tickPropagatedActions() {
if (isEnergyProvider()) { if (isEnergyProvider()) {
List<Action.PropagatedAction> done = new ArrayList<>();
for (Action.PropagatedAction action : pendingPropagatedActions) { for (Action.PropagatedAction action : pendingPropagatedActions) {
handlePropagatedAction(action); if (!done.contains(action)) {
handlePropagatedAction(action);
done.add(action);
}
} }
NetworkComponent component = NetworkComponent.getInstance((ServerWorld) Objects.requireNonNull(getWorld())); NetworkComponent component = NetworkComponent.getInstance((ServerWorld) Objects.requireNonNull(getWorld()));

View File

@ -3,9 +3,12 @@ package com.thebrokenrail.energonrelics.energy.core.util;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.state.property.Property; import net.minecraft.state.property.Property;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import java.util.Objects;
public class Action { public class Action {
public interface ActionFunction { public interface ActionFunction {
void run(World world, BlockPos pos, BlockState state); void run(World world, BlockPos pos, BlockState state);
@ -14,14 +17,16 @@ public class Action {
private final long cost; private final long cost;
private final ActionFunction success; private final ActionFunction success;
private final ActionFunction fail; private final ActionFunction fail;
private final Identifier id;
public Action(long cost, ActionFunction success, ActionFunction fail) { public Action(long cost, ActionFunction success, ActionFunction fail, Identifier id) {
this.cost = cost; this.cost = cost;
this.success = success; this.success = success;
this.fail = fail; this.fail = fail;
this.id = id;
} }
public static <T extends Comparable<T>> Action createBlockStatePropertyAction(long cost, Property<T> property, T successValue, T failureValue) { public static <T extends Comparable<T>> Action createBlockStatePropertyAction(long cost, Property<T> property, T successValue, T failureValue, Identifier id) {
return new Action(cost, (world, pos, state) -> { return new Action(cost, (world, pos, state) -> {
if (!state.get(property).equals(successValue)) { if (!state.get(property).equals(successValue)) {
world.setBlockState(pos, state.with(property, successValue)); world.setBlockState(pos, state.with(property, successValue));
@ -30,7 +35,7 @@ public class Action {
if (!state.get(property).equals(failureValue)) { if (!state.get(property).equals(failureValue)) {
world.setBlockState(pos, state.with(property, failureValue)); world.setBlockState(pos, state.with(property, failureValue));
} }
}); }, id);
} }
public interface PropagatedAction { public interface PropagatedAction {
@ -39,7 +44,28 @@ public class Action {
void pay(long amount); void pay(long amount);
} }
public static class PropagatedActionImpl implements PropagatedAction { public static class UniqueAction {
private final Identifier id;
private final BlockPos pos;
public UniqueAction(Identifier id, BlockPos pos) {
this.id = id;
this.pos = pos;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (obj instanceof UniqueAction) {
return Objects.equals(id, ((UniqueAction) obj).id) && Objects.equals(pos, ((UniqueAction) obj).pos);
} else {
return false;
}
}
}
public static class PropagatedActionImpl extends UniqueAction implements PropagatedAction {
private final Action action; private final Action action;
private final World world; private final World world;
private final BlockPos pos; private final BlockPos pos;
@ -49,7 +75,7 @@ public class Action {
private long amountPaid = 0; private long amountPaid = 0;
public PropagatedActionImpl(Action action, World world, BlockPos pos, Block block) { public PropagatedActionImpl(Action action, World world, BlockPos pos, Block block) {
super(); super(action.id, pos);
this.action = action; this.action = action;
this.world = world; this.world = world;
this.pos = pos; this.pos = pos;

View File

@ -3,9 +3,9 @@ package com.thebrokenrail.energonrelics.structure;
import com.thebrokenrail.energonrelics.util.MissingCaseException; import com.thebrokenrail.energonrelics.util.MissingCaseException;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.util.BlockMirror;
import net.minecraft.util.BlockRotation; import net.minecraft.util.BlockRotation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import java.util.ArrayList; import java.util.ArrayList;
@ -15,7 +15,7 @@ import java.util.Map;
public abstract class StructurePart<T> { public abstract class StructurePart<T> {
protected interface Transformation { protected interface Transformation {
Vec3d transform(Vec3d vec); BlockPos transform(BlockPos pos);
BlockState transform(BlockState state); BlockState transform(BlockState state);
} }
@ -36,8 +36,8 @@ public abstract class StructurePart<T> {
protected static final Transformation NONE = new Transformation() { protected static final Transformation NONE = new Transformation() {
@Override @Override
public Vec3d transform(Vec3d vec) { public BlockPos transform(BlockPos pos) {
return vec; return pos;
} }
@Override @Override
@ -47,8 +47,8 @@ public abstract class StructurePart<T> {
}; };
protected static final Transformation CLOCKWISE_90 = new Transformation() { protected static final Transformation CLOCKWISE_90 = new Transformation() {
@Override @Override
public Vec3d transform(Vec3d vec) { public BlockPos transform(BlockPos pos) {
return new Vec3d(-vec.getZ(), vec.getY(), vec.getX()); return new BlockPos(-pos.getZ(), pos.getY(), pos.getX());
} }
@Override @Override
@ -58,8 +58,8 @@ public abstract class StructurePart<T> {
}; };
protected static final Transformation CLOCKWISE_180 = new Transformation() { protected static final Transformation CLOCKWISE_180 = new Transformation() {
@Override @Override
public Vec3d transform(Vec3d vec) { public BlockPos transform(BlockPos pos) {
return new Vec3d(-vec.getX(), vec.getY(), -vec.getZ()); return new BlockPos(-pos.getX(), pos.getY(), -pos.getZ());
} }
@Override @Override
@ -69,8 +69,8 @@ public abstract class StructurePart<T> {
}; };
protected static final Transformation COUNTERCLOCKWISE_90 = new Transformation() { protected static final Transformation COUNTERCLOCKWISE_90 = new Transformation() {
@Override @Override
public Vec3d transform(Vec3d vec) { public BlockPos transform(BlockPos pos) {
return new Vec3d(vec.getZ(), vec.getY(), -vec.getX()); return new BlockPos(pos.getZ(), pos.getY(), -pos.getX());
} }
@Override @Override
@ -78,10 +78,21 @@ public abstract class StructurePart<T> {
return state.rotate(BlockRotation.COUNTERCLOCKWISE_90); return state.rotate(BlockRotation.COUNTERCLOCKWISE_90);
} }
}; };
protected static final Transformation MIRROR = new Transformation() {
@Override
public BlockPos transform(BlockPos pos) {
return new BlockPos(pos.getX(), pos.getY(), -pos.getZ());
}
@Override
public BlockState transform(BlockState state) {
return state.mirror(BlockMirror.LEFT_RIGHT);
}
};
protected abstract void build(StructureContext context); protected abstract void build(StructureContext context);
private Vec3d transform(Vec3d pos) { private BlockPos transform(BlockPos pos) {
for (Transformation transformation : transformations) { for (Transformation transformation : transformations) {
pos = transformation.transform(pos); pos = transformation.transform(pos);
} }
@ -95,22 +106,22 @@ public abstract class StructurePart<T> {
return state; return state;
} }
protected void set(int x, int y, int z, BlockState state) { protected void set(BlockPos originalPos, BlockState state) {
Vec3d vec = transform(new Vec3d(x, y, z)); BlockPos pos = transform(originalPos);
blocks.put(new BlockPos(vec.getX(), vec.getY(), vec.getZ()).asLong(), transform(state)); blocks.put(pos.asLong(), transform(state));
} }
protected void rect(int xPos, int yPos, int zPos, int width, int height, int depth, BlockState state) { protected void rect(BlockPos pos, int width, int height, int depth, BlockState state) {
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
for (int z = 0; z < depth; z++) { for (int z = 0; z < depth; z++) {
set(x + xPos, y + yPos, z + zPos, state); set(pos.add(x, y, z), state);
} }
} }
} }
} }
protected void repeat(Transformation[] functions, Runnable action) { protected void rotate(Transformation[] functions, Runnable action) {
for (Transformation function : functions) { for (Transformation function : functions) {
transformations.add(function); transformations.add(function);
action.run(); action.run();
@ -118,8 +129,8 @@ public abstract class StructurePart<T> {
} }
} }
protected void repeat(Runnable action) { protected void rotate(Runnable action) {
repeat(new Transformation[]{NONE, CLOCKWISE_90, CLOCKWISE_180, COUNTERCLOCKWISE_90}, action); rotate(new Transformation[]{NONE, CLOCKWISE_90, CLOCKWISE_180, COUNTERCLOCKWISE_90}, action);
} }
public void place(World world, BlockPos pos) { public void place(World world, BlockPos pos) {
@ -156,12 +167,26 @@ public abstract class StructurePart<T> {
} }
} }
protected void part(StructureContext context, int x, int y, int z, StructurePart<?> part) { protected void part(StructureContext context, BlockPos originalPos, StructurePart<?> part) {
Vec3d vec = transform(new Vec3d(x, y, z)); BlockPos pos = transform(originalPos);
context.addPart((int) vec.getX(), (int) vec.getY(), (int) vec.getZ(), part); context.addPart(pos.getX(), pos.getY(), pos.getZ(), part);
} }
protected List<Transformation> getTransformations() { protected List<Transformation> getTransformations() {
return transformations; return transformations;
} }
private BlockPos pos = null;
private BlockPos getPos() {
return pos;
}
protected BlockPos getPosFromOrigin(BlockPos pos) {
return transform(pos).add(getPos());
}
void setPos(BlockPos pos) {
this.pos = pos;
}
} }

View File

@ -1,6 +1,5 @@
package com.thebrokenrail.energonrelics.structure; package com.thebrokenrail.energonrelics.structure;
import net.minecraft.block.Blocks;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -34,12 +33,8 @@ public class StructurePlacer {
while (!pendingParts.isEmpty()) { while (!pendingParts.isEmpty()) {
List<StructurePos> newPendingParts = new ArrayList<>(); List<StructurePos> newPendingParts = new ArrayList<>();
for (StructurePos part : pendingParts) { for (StructurePos part : pendingParts) {
if (part.part != null) { part.part.setPos(new BlockPos(part.x, part.y, part.z));
part.part.build((x, y, z, newPart) -> { part.part.build((x, y, z, newPart) -> newPendingParts.add(new StructurePos(x + part.x, y + part.y, z + part.z, newPart)));
newPendingParts.add(new StructurePos(x + part.x, y + part.y, z + part.z, null));
//newPendingParts.add(new StructurePos(x + part.x, y + part.y, z + part.z, newPart));
});
}
parts.add(part); parts.add(part);
} }
pendingParts.clear(); pendingParts.clear();
@ -50,11 +45,7 @@ public class StructurePlacer {
public void place(World world, BlockPos pos) { public void place(World world, BlockPos pos) {
for (StructurePos part : parts) { for (StructurePos part : parts) {
BlockPos newPos = pos.add(part.x, part.y, part.z); BlockPos newPos = pos.add(part.x, part.y, part.z);
if (part.part != null) { part.part.place(world, newPos);
part.part.place(world, newPos);
} else {
world.setBlockState(newPos, Blocks.DIORITE.getDefaultState());
}
} }
} }
} }

View File

@ -0,0 +1,135 @@
package com.thebrokenrail.energonrelics.structure.researchcomplex;
import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.config.HardcodedConfig;
import com.thebrokenrail.energonrelics.structure.StructureContext;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.DoorBlock;
import net.minecraft.block.entity.BarrelBlockEntity;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.enums.DoubleBlockHalf;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
public abstract class AbstractResearchComplexRoomPart extends BaseResearchComplexPart {
public AbstractResearchComplexRoomPart(ResearchComplexState state, List<Transformation> list) {
super(state, list);
}
@Override
protected void build(StructureContext context) {
if (hasEnergy()) {
BlockState air = Blocks.AIR.getDefaultState();
BlockState bricks = Blocks.QUARTZ_BRICKS.getDefaultState();
rect(new BlockPos(-1, 0, 2), getWidth() * 3, 3, 3, air);
rect(new BlockPos(-1, -1, 2), getWidth() * 3, 1, 3, bricks);
rect(new BlockPos(-1, 3, 2), getWidth() * 3, 1, 3, bricks);
rect(new BlockPos(-1, 0, 5), getWidth() * 3, 3, 1, bricks);
rect(new BlockPos(-1, 0, 1), getWidth() * 3, 3, 1, bricks);
rect(new BlockPos(-2, 0, 2), 1, 3, 3, bricks);
rect(new BlockPos(-1 + getWidth() * 3, 0, 2), 1, 3, 3, bricks);
BlockState plate = Blocks.HEAVY_WEIGHTED_PRESSURE_PLATE.getDefaultState();
set(new BlockPos(0, -1, 0), bricks);
set(new BlockPos(0, 0, 0), plate);
BlockState door = Blocks.IRON_DOOR.getDefaultState().with(DoorBlock.FACING, Direction.SOUTH);
BlockState bottomDoor = door.with(DoorBlock.HALF, DoubleBlockHalf.LOWER);
BlockState topDoor = door.with(DoorBlock.HALF, DoubleBlockHalf.UPPER);
set(new BlockPos(0, 0, 1), bottomDoor);
set(new BlockPos(0, 1, 1), topDoor);
set(new BlockPos(0, -1, 1), bricks);
set(new BlockPos(0, 0, 2), plate);
BlockState light = EnergonRelics.ENERGON_LIGHT_BLOCK.getDefaultState();
List<BlockPos> list = getLights();
for (BlockPos pos : list) {
set(pos, light);
}
buildInterior();
}
}
protected abstract void buildInterior();
private List<BlockPos> getLights() {
List<BlockPos> lights = new ArrayList<>();
for (int i = 0; i < getWidth(); i++) {
lights.add(new BlockPos(i * 3, 3, 3));
}
return lights;
}
protected boolean hasEnergy() {
List<BlockPos> list = getLights();
return getState().hasEnergy(list.size() * HardcodedConfig.ENERGON_LIGHT_ENERGY_REQUIRED, getPosFromOrigin(list.get(list.size() - 1)));
}
abstract int getWidth();
static AbstractResearchComplexRoomPart get(ResearchComplexState state, List<Transformation> transformations) {
if (state.random.nextFloat() <= Barrel.CHANCE) {
return new Barrel(state, transformations);
} else {
return new Simple(state, transformations);
}
}
private static class Simple extends AbstractResearchComplexRoomPart {
private Simple(ResearchComplexState state, List<Transformation> list) {
super(state, list);
}
@Override
int getWidth() {
return 1;
}
@Override
protected void buildInterior() {
}
}
private static class Barrel extends AbstractResearchComplexRoomPart {
private static final float CHANCE = 0.05f;
private Barrel(ResearchComplexState state, List<Transformation> list) {
super(state, list);
}
@Override
int getWidth() {
return 2;
}
@Override
protected void buildInterior() {
BlockState barrel = Blocks.BARREL.getDefaultState();
rect(new BlockPos(3, 0, 2), 2, 2, 3, barrel);
rect(new BlockPos(2, 0, 3), 1, 1, 2, barrel);
rect(new BlockPos(4, 2, 3), 1, 1, 2, barrel);
set(new BlockPos(1, 0, 4), barrel);
}
@Override
protected void handleBlockPlace(World world, BlockPos pos, BlockState state) {
super.handleBlockPlace(world, pos, state);
BlockEntity entity = world.getBlockEntity(pos);
if (entity instanceof BarrelBlockEntity) {
((BarrelBlockEntity) entity).setLootTable(new Identifier(EnergonRelics.NAMESPACE, "chests/research_complex_barrel"), getState().random.nextLong());
}
}
}
}

View File

@ -1,14 +1,31 @@
package com.thebrokenrail.energonrelics.structure.researchcomplex; package com.thebrokenrail.energonrelics.structure.researchcomplex;
import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.config.HardcodedConfig;
import com.thebrokenrail.energonrelics.structure.StructureContext; import com.thebrokenrail.energonrelics.structure.StructureContext;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.StairsBlock;
import net.minecraft.block.enums.BlockHalf;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class ResearchComplexHallwayPart extends BaseResearchComplexPart { public class ResearchComplexHallwayPart extends BaseResearchComplexPart {
public ResearchComplexHallwayPart(ResearchComplexState state, List<Transformation> list) { private final boolean hasLight;
private int rightRoomPadding;
private int leftRoomPadding;
private static final float ROOM_CHANCE = 0.4f;
public ResearchComplexHallwayPart(ResearchComplexState state, List<Transformation> list, boolean hasLight, int rightRoomPadding, int leftRoomPadding) {
super(state, list); super(state, list);
this.hasLight = hasLight;
this.rightRoomPadding = rightRoomPadding;
this.leftRoomPadding = leftRoomPadding;
} }
private int getHeight() { private int getHeight() {
@ -22,14 +39,68 @@ public class ResearchComplexHallwayPart extends BaseResearchComplexPart {
@Override @Override
protected void build(StructureContext context) { protected void build(StructureContext context) {
BlockState bricks = Blocks.QUARTZ_BRICKS.getDefaultState(); BlockState bricks = Blocks.QUARTZ_BRICKS.getDefaultState();
BlockState air = Blocks.AIR.getDefaultState(); if (!hasLight || getState().hasEnergy(HardcodedConfig.ENERGON_LIGHT_ENERGY_REQUIRED, getPosFromOrigin(new BlockPos(3, 5, 1)))) {
for (int y = 0; y < getHeight(); y++) { BlockState air = Blocks.AIR.getDefaultState();
boolean isBricks = y == 0 || y == getHeight() - 1;
BlockState state = isBricks ? bricks : air; BlockState stairs = Blocks.QUARTZ_STAIRS.getDefaultState();
rect(2, y, 0, 3, 1, getDepth(), state); BlockState westStairs = stairs.with(StairsBlock.FACING, Direction.WEST);
if (y > 1 && y < getHeight() - 2) { BlockState eastStairs = stairs.with(StairsBlock.FACING, Direction.EAST);
rect(0, y, 0, 1, 2, getDepth(), bricks);
for (int y = 0; y < getHeight(); y++) {
BlockState state = y == 0 || y == getHeight() - 1 ? bricks : air;
if (y > 1 && y < getHeight() - 2) {
rect(new BlockPos(1, y, 0), 5, 1, getDepth(), air);
rect(new BlockPos(0, y, 0), 1, 1, getDepth(), bricks);
rect(new BlockPos(6, y, 0), 1, 1, getDepth(), bricks);
} else {
rect(new BlockPos(2, y, 0), 3, 1, getDepth(), state);
}
if (y == 1 || y == getHeight() - 2) {
if (y == getHeight() - 2) {
eastStairs = eastStairs.with(StairsBlock.HALF, BlockHalf.TOP);
westStairs = westStairs.with(StairsBlock.HALF, BlockHalf.TOP);
}
rect(new BlockPos(1, y, 0), 1, 1, getDepth(), westStairs);
rect(new BlockPos(5, y, 0), 1, 1, getDepth(), eastStairs);
}
} }
if (hasLight) {
set(new BlockPos(3, 5, 1), EnergonRelics.ENERGON_LIGHT_BLOCK.getDefaultState());
}
if (leftRoomPadding == 0) {
if (getState().random.nextFloat() <= ROOM_CHANCE) {
AbstractResearchComplexRoomPart room = AbstractResearchComplexRoomPart.get(getState(), getRoomTransformation(true));
part(context, new BlockPos(5, 1, 1), room);
leftRoomPadding = room.getWidth();
}
} else {
leftRoomPadding = leftRoomPadding - 1;
}
if (rightRoomPadding == 0) {
if (getState().random.nextFloat() <= ROOM_CHANCE) {
AbstractResearchComplexRoomPart room = AbstractResearchComplexRoomPart.get(getState(), getRoomTransformation(false));
part(context, new BlockPos(1, 1, 1), room);
rightRoomPadding = room.getWidth();
}
} else {
rightRoomPadding = rightRoomPadding - 1;
}
part(context, new BlockPos(0, 0, getDepth()), new ResearchComplexHallwayPart(getState(), getTransformations(), !hasLight, rightRoomPadding, leftRoomPadding));
} else {
rect(new BlockPos(1, 1, 0), 5, 4, 1, bricks);
} }
} }
private List<Transformation> getRoomTransformation(boolean mirror) {
List<Transformation> list = new ArrayList<>();
if (mirror) {
list.add(MIRROR);
}
list.addAll(getTransformations());
list.add(com.thebrokenrail.energonrelics.structure.StructurePart.CLOCKWISE_90);
return list;
}
} }

View File

@ -23,12 +23,12 @@ public class ResearchComplexStartPart extends BaseResearchComplexPart {
super(state, list); super(state, list);
} }
private void setBlockOrAir(int x, int y, int z, BlockState stairs) { private void setBlockOrAir(BlockPos pos, BlockState state) {
if (y == 1 || y == 4) { if (pos.getY() == 1 || pos.getY() == 4) {
set(x, y, z, stairs); set(pos, state);
} else { } else {
BlockState air = Blocks.AIR.getDefaultState(); BlockState air = Blocks.AIR.getDefaultState();
set(x, y, z, air); set(pos, air);
} }
} }
@ -38,12 +38,12 @@ public class ResearchComplexStartPart extends BaseResearchComplexPart {
BlockState state = yOffset == 0 || yOffset == 5 ? bricks : air; BlockState state = yOffset == 0 || yOffset == 5 ? bricks : air;
rect(0, yOffset, 0, 2, 1, 6, state); rect(new BlockPos(0, yOffset, 0), 2, 1, 6, state);
rect(0, yOffset, 0, 6, 1, 2, state); rect(new BlockPos(0, yOffset, 0), 6, 1, 2, state);
set(2, yOffset, 3, state); set(new BlockPos(2, yOffset, 3), state);
set(3, yOffset, 2, state); set(new BlockPos(3, yOffset, 2), state);
set(3, yOffset, 3, state); set(new BlockPos(2, yOffset, 2), state);
if (yOffset != 0 && yOffset != 5) { if (yOffset != 0 && yOffset != 5) {
BlockState stairs = Blocks.QUARTZ_STAIRS.getDefaultState(); BlockState stairs = Blocks.QUARTZ_STAIRS.getDefaultState();
@ -51,52 +51,52 @@ public class ResearchComplexStartPart extends BaseResearchComplexPart {
BlockHalf half = yOffset == 1 ? BlockHalf.BOTTOM : BlockHalf.TOP; BlockHalf half = yOffset == 1 ? BlockHalf.BOTTOM : BlockHalf.TOP;
stairs = stairs.with(StairsBlock.HALF, half); stairs = stairs.with(StairsBlock.HALF, half);
BlockState westStairs = stairs.with(StairsBlock.FACING, Direction.WEST); BlockState eastStairs = stairs.with(StairsBlock.FACING, Direction.EAST);
BlockState northStairs = stairs.with(StairsBlock.FACING, Direction.NORTH); BlockState southStairs = stairs.with(StairsBlock.FACING, Direction.SOUTH);
BlockState outerLeftStairs = northStairs.with(StairsBlock.SHAPE, StairShape.OUTER_LEFT); BlockState outerLeftStairs = southStairs.with(StairsBlock.SHAPE, StairShape.OUTER_LEFT);
BlockState innerLeftStairs = northStairs.with(StairsBlock.SHAPE, StairShape.INNER_LEFT); BlockState innerLeftStairs = southStairs.with(StairsBlock.SHAPE, StairShape.INNER_LEFT);
BlockState innerRightStairs = westStairs.with(StairsBlock.SHAPE, StairShape.INNER_RIGHT); BlockState innerRightStairs = eastStairs.with(StairsBlock.SHAPE, StairShape.INNER_RIGHT);
BlockState outerRightStairs = westStairs.with(StairsBlock.SHAPE, StairShape.OUTER_RIGHT); BlockState outerRightStairs = eastStairs.with(StairsBlock.SHAPE, StairShape.OUTER_RIGHT);
setBlockOrAir(3, yOffset, 0, westStairs); setBlockOrAir(new BlockPos(2, yOffset, 5), eastStairs);
setBlockOrAir(3, yOffset, 1, outerLeftStairs); setBlockOrAir(new BlockPos(2, yOffset, 4), outerLeftStairs);
setBlockOrAir(2, yOffset, 1, innerRightStairs); setBlockOrAir(new BlockPos(3, yOffset, 4), innerRightStairs);
setBlockOrAir(2, yOffset, 2, outerLeftStairs); setBlockOrAir(new BlockPos(3, yOffset, 3), outerLeftStairs);
setBlockOrAir(1, yOffset, 2, innerLeftStairs); setBlockOrAir(new BlockPos(4, yOffset, 3), innerLeftStairs);
setBlockOrAir(1, yOffset, 3, outerRightStairs); setBlockOrAir(new BlockPos(4, yOffset, 2), outerRightStairs);
setBlockOrAir(0, yOffset, 3, northStairs); setBlockOrAir(new BlockPos(5, yOffset, 2), southStairs);
if (yOffset != 1 && yOffset != 4) { if (yOffset != 1 && yOffset != 4) {
set(2, yOffset, 0, bricks); set(new BlockPos(3, yOffset, 5), bricks);
set(1, yOffset, 1, bricks); set(new BlockPos(4, yOffset, 4), bricks);
set(0, yOffset, 2, bricks); set(new BlockPos(5, yOffset, 3), bricks);
} }
} }
if (yOffset == 5) { if (yOffset == 5) {
set(3, yOffset, 3, EnergonRelics.ENERGON_LIGHT_BLOCK.getDefaultState()); set(new BlockPos(2, yOffset, 2), EnergonRelics.ENERGON_LIGHT_BLOCK.getDefaultState());
} }
} }
private void buildReactor() { private void buildReactor() {
set(0, 1, 0, EnergonRelics.THERMAL_CASING_BLOCK.getDefaultState()); set(new BlockPos(0, 1, 0), EnergonRelics.THERMAL_CASING_BLOCK.getDefaultState());
set(1, 2, 0, EnergonRelics.THERMAL_CASING_BLOCK.getDefaultState()); set(new BlockPos(1, 2, 0), EnergonRelics.THERMAL_CASING_BLOCK.getDefaultState());
set(0, 2, 0, EnergonRelics.REACTOR_CORE_BLOCK.getDefaultState()); set(new BlockPos(0, 2, 0), EnergonRelics.REACTOR_CORE_BLOCK.getDefaultState());
set(-1, 2, 0, EnergonRelics.THERMAL_CASING_BLOCK.getDefaultState()); set(new BlockPos(-1, 2, 0), EnergonRelics.THERMAL_CASING_BLOCK.getDefaultState());
set(0, 3, 0, EnergonRelics.REACTOR_INPUT_BLOCK.getDefaultState()); set(new BlockPos(0, 3, 0), EnergonRelics.REACTOR_INPUT_BLOCK.getDefaultState());
set(0, 2, 1, EnergonRelics.REACTOR_CONTROLLER_BLOCK.getDefaultState()); set(new BlockPos(0, 2, -1), EnergonRelics.REACTOR_CONTROLLER_BLOCK.getDefaultState());
set(0, 1, 1, Blocks.LEVER.getDefaultState().with(LeverBlock.FACE, WallMountLocation.FLOOR)); set(new BlockPos(0, 1, -1), Blocks.LEVER.getDefaultState().with(LeverBlock.FACE, WallMountLocation.FLOOR));
set(0, 2, -1, EnergonRelics.THERMAL_GLASS_BLOCK.getDefaultState()); set(new BlockPos(0, 2, 1), EnergonRelics.THERMAL_GLASS_BLOCK.getDefaultState());
} }
@Override @Override
protected void build(StructureContext context) { protected void build(StructureContext context) {
if (getState().hasEnergy(HardcodedConfig.ENERGON_LIGHT_ENERGY_REQUIRED * 4)) { if (getState().hasEnergy(HardcodedConfig.ENERGON_LIGHT_ENERGY_REQUIRED * 4, new BlockPos(0, 2, 0))) {
repeat(() -> { rotate(() -> {
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
buildBase(i); buildBase(i);
} }
//part(context, 1, 0, getWidth() / 2, new ResearchComplexHallwayPart(getState(), getTransformations())); part(context, new BlockPos(-3, 0, 6), new ResearchComplexHallwayPart(getState(), getTransformations(), true, 1, 1));
}); });
buildReactor(); buildReactor();
} }

View File

@ -3,17 +3,22 @@ package com.thebrokenrail.energonrelics.structure.researchcomplex;
import com.thebrokenrail.energonrelics.component.NetworkComponent; import com.thebrokenrail.energonrelics.component.NetworkComponent;
import com.thebrokenrail.energonrelics.config.HardcodedConfig; import com.thebrokenrail.energonrelics.config.HardcodedConfig;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.BlockRotation; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import java.util.Random;
public class ResearchComplexState { public class ResearchComplexState {
private final int baseID; private final int baseID;
private long energyBudget = HardcodedConfig.REACTOR_ENERGY_OUTPUT; private long energyBudget = HardcodedConfig.REACTOR_ENERGY_OUTPUT;
public ResearchComplexState(World world) { final Random random;
public ResearchComplexState(World world, Random random) {
ServerWorld serverWorld = (ServerWorld) world; ServerWorld serverWorld = (ServerWorld) world;
NetworkComponent component = NetworkComponent.getInstance(serverWorld); NetworkComponent component = NetworkComponent.getInstance(serverWorld);
baseID = component.create(); baseID = component.create();
this.random = random;
} }
private int getID(int id) { private int getID(int id) {
@ -24,10 +29,14 @@ public class ResearchComplexState {
return getID(0); return getID(0);
} }
boolean hasEnergy(long amount) { boolean hasEnergy(long amount, BlockPos pos) {
if (amount <= energyBudget) { if (pos.isWithinDistance(new BlockPos(0, 2, 0), HardcodedConfig.POWER_RANGE)) {
energyBudget = energyBudget - amount; if (amount <= energyBudget) {
return true; energyBudget = energyBudget - amount;
return true;
} else {
return false;
}
} else { } else {
return false; return false;
} }

View File

@ -0,0 +1,97 @@
{
"type": "minecraft:chest",
"pools": [
{
"rolls": 4,
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:string",
"weight": 31,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1,
"max": 5
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:bread",
"weight": 14,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1,
"max": 3
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:iron_ingot",
"weight": 5,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1,
"max": 2
}
}
]
},
{
"type": "minecraft:item",
"name": "minecraft:gold_ingot",
"weight": 2,
"functions": [
{
"function": "minecraft:set_count",
"count": 1
}
]
}
]
},
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "energonrelics:circuit_board",
"weight": 12,
"functions": [
{
"function": "minecraft:set_count",
"count": {
"type": "minecraft:uniform",
"min": 1,
"max": 6
}
}
]
},
{
"type": "minecraft:item",
"name": "energonrelics:veridium_ingot",
"weight": 2,
"functions": [
{
"function": "minecraft:set_count",
"count": 1
}
]
}
]
}
]
}