Initial Commit

pull/3/head
TheBrokenRail 3 years ago
commit b483684372

27
.gitignore vendored

@ -0,0 +1,27 @@
# gradle
.gradle/
build/
out/
classes/
# idea
.idea/
*.iml
*.ipr
*.iws
# vscode
.settings/
.vscode/
bin/
.classpath
.project
# fabric
run/
remappedSrc/

@ -0,0 +1,4 @@
# Changelog
**1.0.0**
* Initial Release

@ -0,0 +1,5 @@
# EnergonRelics
TBD
## Changelog
[View Changelog](CHANGELOG.md)

24
TODO

@ -0,0 +1,24 @@
Network Chips:
- Contain a Network ID In NBT
- When Held, Highlights Supported Blocks
- When Right-Cliking On A Supported-Block Add it To The Network
Energy Recievers:
- Conatin network ID(s)
- Requests a certain amount of power every tick
- Spreads out power ewuest over all networks
- Chunk loads unloaded networks
- No energy transfer speed restrictions
Energy Providers:
- Contaisn Network Chip
- Can only provide power to recievers within 60 blocks
- Can be an energy reciever
Battery:
- Surrounded on all but one sides by Battery casing, last side covered by battery controller
- Energy reiever for charging
- Energy prvodier for usage
- Highlight covers entire multi-block
Reactor:
- Temporary battery
- Refreshes battery every 10 ticks, no fuel set battery to 0, if fuel fill battery
On each tick an energy receiver can add an "action", an action has a success function, a fail function, and a cost, the action is propagated up to the energy provider, which will either execute the success function and deduct the energy amount, or execute the fail function.

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

@ -0,0 +1,54 @@
plugins {
id 'fabric-loom' version '0.4-SNAPSHOT'
}
compileJava {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
version = project.mod_version
group = project.maven_group
minecraft {
}
dependencies {
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.minecraft_version}+build.${project.yarn_build}:v2"
modCompile "net.fabricmc:fabric-loader:${project.fabric_loader_version}"
modCompile "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
}
processResources {
inputs.property "version", project.version
from(sourceSets.main.resources.srcDirs) {
include "fabric.mod.json"
expand "version": project.version
}
from(sourceSets.main.resources.srcDirs) {
exclude "fabric.mod.json"
}
}
// ensure that the encoding is set to UTF-8, no matter what the system default is
// this fixes some edge cases with special characters not displaying correctly
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
}
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
// if it is present.
// If you remove this task, sources will not be generated.
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = "sources"
from sourceSets.main.allSource
}
jar {
from "LICENSE"
}

@ -0,0 +1,16 @@
# Done to increase the memory available to gradle.
org.gradle.jvmargs = -Xmx1G
# Fabric Properties
# check these on https://fabricmc.net/use
minecraft_version = 1.16.1
yarn_build = 20
fabric_loader_version = 0.8.9+build.203
# Mod Properties
mod_version = 1.0.0
maven_group = com.thebrokenrail
# Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_api_version = 0.14.1+build.372-1.16

@ -0,0 +1 @@
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip

@ -0,0 +1,12 @@
pluginManagement {
repositories {
jcenter()
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
gradlePluginPortal()
}
}
rootProject.name = 'EnergonRelics'

@ -0,0 +1,14 @@
package com.thebrokenrail.energonrelics;
public class Config {
public static final int POWER_RANGE = 64;
public static final int ENERGON_LIGHT_ENERGY_REQUIRED = 5;
public static final long SOLAR_PANEL_MAX_ENERGY_OUTPUT = 50;
public static final long BATTERY_CHARGE_RATE = 40;
public static final int REACTOR_TIME = 2400;
public static final int REACTOR_ENERGY_OUTPUT = 250;
}

@ -0,0 +1,80 @@
package com.thebrokenrail.energonrelics;
import com.thebrokenrail.energonrelics.block.battery.ActiveBatteryControllerBlock;
import com.thebrokenrail.energonrelics.block.reactor.ReactorControllerBlock;
import com.thebrokenrail.energonrelics.block.reactor.ReactorCoreBlock;
import com.thebrokenrail.energonrelics.block.reactor.ReactorInputBlock;
import com.thebrokenrail.energonrelics.block.ThermalCasingBlock;
import com.thebrokenrail.energonrelics.block.battery.BatteryControllerBlock;
import com.thebrokenrail.energonrelics.block.battery.BatteryCoreBlock;
import com.thebrokenrail.energonrelics.block.EnergonLightBlock;
import com.thebrokenrail.energonrelics.block.SolarPanelBlock;
import com.thebrokenrail.energonrelics.block.SwitchBlock;
import com.thebrokenrail.energonrelics.block.util.SimpleBlock;
import com.thebrokenrail.energonrelics.item.MultimeterItem;
import com.thebrokenrail.energonrelics.item.NetworkChipItem;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Material;
import net.minecraft.block.MaterialColor;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class EnergonRelics implements ModInitializer {
public static final String NAMESPACE = "energonrelics";
public static NetworkChipItem NETWORK_CHIP_ITEM;
public static final ItemGroup ITEM_GROUP = FabricItemGroupBuilder.build(new Identifier(NAMESPACE, "item_group"), () -> new ItemStack(NETWORK_CHIP_ITEM));
public static final EnergonLightBlock ENERGON_LIGHT_BLOCK = new EnergonLightBlock();
public static final SolarPanelBlock SOLAR_PANEL_BLOCK = new SolarPanelBlock();
public static final SwitchBlock SWITCH_BLOCk = new SwitchBlock();
public static final MultimeterItem MULTIMETER_ITEM = new MultimeterItem();
public static final ThermalCasingBlock THERMAL_CASING_BLOCK = new ThermalCasingBlock();
public static final BatteryCoreBlock BATTERY_CORE_BLOCk = new BatteryCoreBlock();
public static final BatteryControllerBlock BATTERY_CONTROLLER_BLOCk = new BatteryControllerBlock();
public static final ActiveBatteryControllerBlock ACTIVE_BATTERY_CONTROLLER_BLOCK = new ActiveBatteryControllerBlock();
public static final ReactorCoreBlock REACTOR_CORE_BLOCK = new ReactorCoreBlock();
public static final ReactorInputBlock REACTOR_INPUT_BLOCK = new ReactorInputBlock();
public static final ReactorControllerBlock REACTOR_CONTROLLER_BLOCK = new ReactorControllerBlock();
public static final Item VERIDIUM_INGOT = new Item(new Item.Settings().group(ITEM_GROUP));
public static final SimpleBlock VERIDIUM_ORE = new SimpleBlock(FabricBlockSettings.of(Material.STONE).requiresTool().strength(3.0F, 3.0F));
public static final SimpleBlock VERIDIUM_BLOCK = new SimpleBlock(FabricBlockSettings.of(Material.METAL, MaterialColor.GOLD).requiresTool().strength(3.0F, 6.0F).sounds(BlockSoundGroup.METAL));
public static final Item CIRCUIT_BOARD_ITEM = new Item(new Item.Settings().group(ITEM_GROUP));
@Override
public void onInitialize() {
NETWORK_CHIP_ITEM = Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "network_chip"), new NetworkChipItem());
Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "multimeter"), MULTIMETER_ITEM);
Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "circuit_board"), CIRCUIT_BOARD_ITEM);
ENERGON_LIGHT_BLOCK.register("energon_light");
SOLAR_PANEL_BLOCK.register("solar_panel");
SWITCH_BLOCk.register("switch");
THERMAL_CASING_BLOCK.register("thermal_casing");
BATTERY_CORE_BLOCk.register("battery_core");
BATTERY_CONTROLLER_BLOCk.register("battery_controller");
ACTIVE_BATTERY_CONTROLLER_BLOCK.register("active_battery_controller");
REACTOR_CORE_BLOCK.register("reactor_core");
REACTOR_INPUT_BLOCK.register("reactor_input");
REACTOR_CONTROLLER_BLOCK.register("reactor_controller");
Registry.register(Registry.ITEM, new Identifier(NAMESPACE, "veridium_ingot"), VERIDIUM_INGOT);
VERIDIUM_ORE.register("veridium_ore");
VERIDIUM_BLOCK.register("veridium_block");
}
}

@ -0,0 +1,36 @@
package com.thebrokenrail.energonrelics.block;
import com.thebrokenrail.energonrelics.block.entity.EnergonLightBlockEntity;
import com.thebrokenrail.energonrelics.block.util.EnergyProviderBlock;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.Properties;
import java.util.function.Function;
public class EnergonLightBlock extends EnergyProviderBlock {
public static final BooleanProperty POWERED = Properties.POWERED;
public EnergonLightBlock() {
super(FabricBlockSettings.of(Material.GLASS).sounds(BlockSoundGroup.GLASS).nonOpaque().lightLevel(state -> state.get(POWERED) ? 15 : 0).strength(0.3f));
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 EnergonLightBlockEntity::new;
}
}

@ -0,0 +1,22 @@
package com.thebrokenrail.energonrelics.block;
import com.thebrokenrail.energonrelics.block.entity.SolarPanelBlockEntity;
import com.thebrokenrail.energonrelics.block.util.EnergyProviderBlock;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Material;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.sound.BlockSoundGroup;
import java.util.function.Function;
public class SolarPanelBlock extends EnergyProviderBlock {
public SolarPanelBlock() {
super(FabricBlockSettings.of(Material.GLASS).sounds(BlockSoundGroup.GLASS).requiresTool().strength(1.5f, 6.0f));
}
@Override
protected Function<BlockEntityType<BlockEntity>, BlockEntity> getFactory() {
return SolarPanelBlockEntity::new;
}
}

@ -0,0 +1,66 @@
package com.thebrokenrail.energonrelics.block;
import com.thebrokenrail.energonrelics.block.entity.SwitchBlockEntity;
import com.thebrokenrail.energonrelics.block.util.EnergyProviderBlock;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.StateManager;
import net.minecraft.state.property.BooleanProperty;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.Random;
import java.util.function.Function;
@SuppressWarnings("deprecation")
public class SwitchBlock extends EnergyProviderBlock {
public static final BooleanProperty POWERED = Properties.POWERED;
public SwitchBlock() {
super(FabricBlockSettings.of(Material.STONE).requiresTool().strength(1.5f, 6.0f));
setDefaultState(getDefaultState().with(POWERED, false));
}
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return getDefaultState().with(POWERED, 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(POWERED);
if (bl != world.isReceivingRedstonePower(pos)) {
if (bl) {
world.getBlockTickScheduler().schedule(pos, this, 4);
} else {
world.setBlockState(pos, state.cycle(POWERED), 2);
}
}
}
}
@Override
public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
if (state.get(POWERED) && !world.isReceivingRedstonePower(pos)) {
world.setBlockState(pos, state.cycle(POWERED), 2);
}
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
builder.add(POWERED);
}
@Override
protected Function<BlockEntityType<BlockEntity>, BlockEntity> getFactory() {
return SwitchBlockEntity::new;
}
}

@ -0,0 +1,11 @@
package com.thebrokenrail.energonrelics.block;
import com.thebrokenrail.energonrelics.block.util.SimpleBlock;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Material;
public class ThermalCasingBlock extends SimpleBlock {
public ThermalCasingBlock() {
super(FabricBlockSettings.of(Material.STONE).requiresTool().strength(1.5f, 6.0f));
}
}

@ -0,0 +1,18 @@
package com.thebrokenrail.energonrelics.block.battery;
import com.thebrokenrail.energonrelics.block.entity.battery.ActiveBatteryControllerBlockEntity;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import java.util.function.Function;
public class ActiveBatteryControllerBlock extends BatteryControllerBlock {
public ActiveBatteryControllerBlock() {
super();
}
@Override
protected Function<BlockEntityType<BlockEntity>, BlockEntity> getFactory() {
return ActiveBatteryControllerBlockEntity::new;
}
}

@ -0,0 +1,54 @@
package com.thebrokenrail.energonrelics.block.battery;
import com.thebrokenrail.energonrelics.block.entity.battery.BatteryControllerBlockEntity;
import com.thebrokenrail.energonrelics.block.util.EnergyProviderBlock;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Material;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.item.ItemPlacementContext;
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.Direction;
import java.util.function.Function;
@SuppressWarnings("deprecation")
public class BatteryControllerBlock extends EnergyProviderBlock {
public static final DirectionProperty FACING = Properties.FACING;
public BatteryControllerBlock() {
super(FabricBlockSettings.of(Material.STONE).requiresTool().strength(1.5f, 6.0f));
setDefaultState(getDefaultState().with(FACING, Direction.NORTH));
}
@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
public BlockState getPlacementState(ItemPlacementContext ctx) {
return getDefaultState().with(FACING, ctx.getPlayerLookDirection().getOpposite());
}
@Override
protected Function<BlockEntityType<BlockEntity>, BlockEntity> getFactory() {
return BatteryControllerBlockEntity::new;
}
}

@ -0,0 +1,21 @@
package com.thebrokenrail.energonrelics.block.battery;
import com.thebrokenrail.energonrelics.block.entity.battery.BatteryCoreBlockEntity;
import com.thebrokenrail.energonrelics.block.util.SimpleBlockWithEntity;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Material;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import java.util.function.Function;
public class BatteryCoreBlock extends SimpleBlockWithEntity {
public BatteryCoreBlock() {
super(FabricBlockSettings.of(Material.STONE).requiresTool().strength(1.5f, 6.0f));
}
@Override
protected Function<BlockEntityType<BlockEntity>, BlockEntity> getFactory() {
return BatteryCoreBlockEntity::new;
}
}

@ -0,0 +1,18 @@
package com.thebrokenrail.energonrelics.block.entity;
import com.thebrokenrail.energonrelics.Config;
import com.thebrokenrail.energonrelics.block.EnergonLightBlock;
import com.thebrokenrail.energonrelics.energy.core.EnergyReceiverBlockEntity;
import com.thebrokenrail.energonrelics.energy.core.util.Action;
import net.minecraft.block.entity.BlockEntityType;
public class EnergonLightBlockEntity extends EnergyReceiverBlockEntity {
public EnergonLightBlockEntity(BlockEntityType<?> type) {
super(type);
}
@Override
protected void tickEnergy() {
addAction(Action.createBlockStatePropertyAction(Config.ENERGON_LIGHT_ENERGY_REQUIRED, EnergonLightBlock.POWERED, true, false));
}
}

@ -0,0 +1,44 @@
package com.thebrokenrail.energonrelics.block.entity;
import com.thebrokenrail.energonrelics.Config;
import com.thebrokenrail.energonrelics.energy.helper.EnergyGeneratorBlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.util.math.Direction;
import net.minecraft.world.LightType;
import java.util.Objects;
public class SolarPanelBlockEntity extends EnergyGeneratorBlockEntity {
public SolarPanelBlockEntity(BlockEntityType<?> type) {
super(type);
}
private int getLight(Direction side) {
assert getWorld() != null;
return getWorld().getLightLevel(LightType.SKY, getPos().offset(side)) - getWorld().getAmbientDarkness();
}
private int getLight() {
int light = 0;
for (Direction side : Direction.values()) {
light = Math.max(light, getLight(side));
}
return light;
}
@Override
public long getDisplayEnergy() {
if (hasWorld() && Objects.requireNonNull(getWorld()).getDimension().hasSkyLight()) {
int light = getLight();
return (long) ((float) Config.SOLAR_PANEL_MAX_ENERGY_OUTPUT * ((float) light / 15f));
} else {
return 0;
}
}
@Override
protected void serverTick() {
setEnergy(getDisplayEnergy());
super.serverTick();
}
}

@ -0,0 +1,25 @@
package com.thebrokenrail.energonrelics.block.entity;
import com.thebrokenrail.energonrelics.block.SwitchBlock;
import com.thebrokenrail.energonrelics.energy.core.EnergyReceiverBlockEntity;
import net.minecraft.block.entity.BlockEntityType;
public class SwitchBlockEntity extends EnergyReceiverBlockEntity {
public SwitchBlockEntity(BlockEntityType<?> type) {
super(type);
}
@Override
protected void tickEnergy() {
}
@Override
public boolean isEnergyProvider() {
return true;
}
@Override
protected boolean isEnergyProviderActive() {
return getCachedState().get(SwitchBlock.POWERED);
}
}

@ -0,0 +1,14 @@
package com.thebrokenrail.energonrelics.block.entity.battery;
import net.minecraft.block.entity.BlockEntityType;
public class ActiveBatteryControllerBlockEntity extends BatteryControllerBlockEntity {
public ActiveBatteryControllerBlockEntity(BlockEntityType<?> type) {
super(type);
}
@Override
protected boolean isActiveController() {
return true;
}
}

@ -0,0 +1,132 @@
package com.thebrokenrail.energonrelics.block.entity.battery;
import com.thebrokenrail.energonrelics.Config;
import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.block.battery.BatteryControllerBlock;
import com.thebrokenrail.energonrelics.energy.core.EnergyReceiverBlockEntity;
import com.thebrokenrail.energonrelics.energy.core.util.Action;
import com.thebrokenrail.energonrelics.energy.helper.EnergyGenerator;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
public class BatteryControllerBlockEntity extends EnergyReceiverBlockEntity implements EnergyGenerator {
public BatteryControllerBlockEntity(BlockEntityType<?> type) {
super(type);
}
private static class UnlimitedAction implements Action.PropagatedAction {
private final World world;
private final BlockPos pos;
private UnlimitedAction(World world, BlockPos pos) {
this.world = world;
this.pos = pos;
}
@Override
public void expandPayments(int amount) {
}
@Override
public long amountOwed() {
return Long.MAX_VALUE;
}
@Override
public void pay(long amount) {
BlockEntity entity = world.getBlockEntity(pos);
if (entity instanceof BatteryControllerBlockEntity) {
BatteryControllerBlockEntity battery = (BatteryControllerBlockEntity) entity;
battery.setEnergy(battery.getEnergy() + amount);
}
}
}
@Override
protected void tickEnergy() {
long charge = Config.BATTERY_CHARGE_RATE;
if (!isActiveController()) {
addAction(new Action(charge, (world, pos, state) -> {
BlockEntity entity = world.getBlockEntity(pos);
if (entity instanceof BatteryControllerBlockEntity) {
BatteryControllerBlockEntity battery = (BatteryControllerBlockEntity) entity;
battery.setEnergy(battery.getEnergy() + charge);
}
}, (world, pos, state) -> {}));
} else {
propagateAction(new UnlimitedAction(getWorld(), getPos()));
}
}
protected boolean isActiveController() {
return false;
}
@Override
public void setEnergy(long value) {
BatteryCoreBlockEntity core = getBatteryCore();
if (core != null) {
core.setEnergy(value);
}
}
@Override
public long getEnergy() {
BatteryCoreBlockEntity core = getBatteryCore();
if (core != null) {
return core.getEnergy();
} else {
return 0;
}
}
@Override
public long getDisplayEnergy() {
return getEnergy();
}
@Override
protected void handlePropagatedAction(Action.PropagatedAction action) {
handlePropagatedActionWithGenerator(action);
}
@Override
public boolean isEnergyProvider() {
return true;
}
private BatteryCoreBlockEntity getBatteryCore() {
if (hasWorld()) {
Direction facing = getCachedState().get(BatteryControllerBlock.FACING);
BlockPos corePos = getPos().offset(facing.getOpposite());
assert getWorld() != null;
BlockEntity entity = getWorld().getBlockEntity(corePos);
if (entity instanceof BatteryCoreBlockEntity) {
boolean valid = true;
for (Direction side : Direction.values()) {
if (side != facing) {
BlockState state = getWorld().getBlockState(corePos.offset(side));
if (state == null || state.getBlock() != EnergonRelics.THERMAL_CASING_BLOCK) {
valid = false;
break;
}
}
}
if (valid) {
return (BatteryCoreBlockEntity) entity;
} else {
return null;
}
} else {
return null;
}
} else {
return null;
}
}
}

@ -0,0 +1,35 @@
package com.thebrokenrail.energonrelics.block.entity.battery;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.nbt.CompoundTag;
public class BatteryCoreBlockEntity extends BlockEntity {
private long energy = 0;
public BatteryCoreBlockEntity(BlockEntityType<?> type) {
super(type);
}
@Override
public CompoundTag toTag(CompoundTag tag) {
super.toTag(tag);
tag.putLong("Energy", energy);
return tag;
}
@Override
public void fromTag(BlockState state, CompoundTag tag) {
super.fromTag(state, tag);
energy = tag.getLong("Energy");
}
long getEnergy() {
return energy;
}
void setEnergy(long value) {
energy = value;
}
}

@ -0,0 +1,103 @@
package com.thebrokenrail.energonrelics.block.entity.reactor;
import com.thebrokenrail.energonrelics.Config;
import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.block.battery.BatteryControllerBlock;
import com.thebrokenrail.energonrelics.block.reactor.ReactorControllerBlock;
import com.thebrokenrail.energonrelics.energy.helper.EnergyGeneratorBlockEntity;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import java.util.ArrayList;
import java.util.List;
public class ReactorControllerBlockEntity extends EnergyGeneratorBlockEntity {
private static class Reactor {
private final ReactorCoreBlockEntity core;
private final ReactorInputBlockEntity[] inputs;
private Reactor(ReactorCoreBlockEntity core, ReactorInputBlockEntity[] inputs) {
this.core = core;
this.inputs = inputs;
}
}
public ReactorControllerBlockEntity(BlockEntityType<?> type) {
super(type);
}
@Override
protected void serverTick() {
if (getCachedState().get(ReactorControllerBlock.POWERED)) {
Reactor reactor = getReactor();
if (reactor != null && !reactor.core.isReacting()) {
boolean foundFuel = false;
for (ReactorInputBlockEntity input : reactor.inputs) {
for (int i = 0; i < input.size(); i++) {
if (input.getStack(i).getItem() == EnergonRelics.VERIDIUM_INGOT) {
foundFuel = true;
input.removeStack(i, 1);
}
}
}
if (foundFuel) {
reactor.core.startReaction();
}
}
}
setEnergy(getDisplayEnergy());
super.serverTick();
}
@Override
public long getDisplayEnergy() {
Reactor reactor = getReactor();
if (reactor != null && reactor.core.isReacting()) {
return Config.REACTOR_ENERGY_OUTPUT;
} else {
return 0;
}
}
private Reactor getReactor() {
if (hasWorld()) {
Direction facing = getCachedState().get(BatteryControllerBlock.FACING);
BlockPos corePos = getPos().offset(facing.getOpposite());
assert getWorld() != null;
BlockEntity entity = getWorld().getBlockEntity(corePos);
if (entity instanceof ReactorCoreBlockEntity) {
boolean valid = true;
List<ReactorInputBlockEntity> inputs = new ArrayList<>();
for (Direction side : Direction.values()) {
if (side != facing) {
BlockPos checkPos = corePos.offset(side);
BlockEntity potentialInput = getWorld().getBlockEntity(checkPos);
if (potentialInput instanceof ReactorInputBlockEntity) {
inputs.add((ReactorInputBlockEntity) potentialInput);
} else {
BlockState state = getWorld().getBlockState(checkPos);
if (state == null || state.getBlock() != EnergonRelics.THERMAL_CASING_BLOCK) {
valid = false;
break;
}
}
}
}
if (valid) {
return new Reactor((ReactorCoreBlockEntity) entity, inputs.toArray(new ReactorInputBlockEntity[0]));
} else {
return null;
}
} else {
return null;
}
} else {
return null;
}
}
}

@ -0,0 +1,44 @@
package com.thebrokenrail.energonrelics.block.entity.reactor;
import com.thebrokenrail.energonrelics.Config;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.Tickable;
public class ReactorCoreBlockEntity extends BlockEntity implements Tickable {
private int reactionTime = 0;
public ReactorCoreBlockEntity(BlockEntityType<?> type) {
super(type);
}
@Override
public CompoundTag toTag(CompoundTag tag) {
super.toTag(tag);
tag.putInt("ReactionTime", reactionTime);
return tag;
}
@Override
public void fromTag(BlockState state, CompoundTag tag) {
super.fromTag(state, tag);
reactionTime = tag.getInt("ReactionTime");
}
boolean isReacting() {
return reactionTime > 0;
}
void startReaction() {
reactionTime = Config.REACTOR_TIME;
}
@Override
public void tick() {
if (reactionTime > 0) {
reactionTime--;
}
}
}

@ -0,0 +1,95 @@
package com.thebrokenrail.energonrelics.block.entity.reactor;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.Inventories;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.collection.DefaultedList;
import java.util.Objects;
public class ReactorInputBlockEntity extends BlockEntity implements Inventory {
public ReactorInputBlockEntity(BlockEntityType<?> type) {
super(type);
}
private final int INVENTORY_SIZE = 5;
private final DefaultedList<ItemStack> inv = DefaultedList.ofSize(INVENTORY_SIZE, ItemStack.EMPTY);
@Override
public int size() {
return inv.size();
}
@Override
public boolean isEmpty() {
boolean empty = false;
for (ItemStack stack : inv) {
if (stack.isEmpty()) {
empty = true;
break;
}
}
return empty;
}
@Override
public ItemStack getStack(int slot) {
return inv.get(slot);
}
@Override
public ItemStack removeStack(int slot, int amount) {
ItemStack stack = Inventories.splitStack(inv, slot, amount);
if (!stack.isEmpty()) {
markDirty();
}
return stack;
}
@Override
public ItemStack removeStack(int slot) {
return Inventories.removeStack(inv, slot);
}
@Override
public void setStack(int slot, ItemStack stack) {
inv.set(slot, stack);
if (stack.getCount() > getMaxCountPerStack()) {
stack.setCount(getMaxCountPerStack());
}
}
@Override
public boolean canPlayerUse(PlayerEntity player) {
if (Objects.requireNonNull(getWorld()).getBlockEntity(getPos()) != this) {
return false;
} else {
return player.squaredDistanceTo((double) getPos().getX() + 0.5D, (double) getPos().getY() + 0.5D, (double) getPos().getZ() + 0.5D) <= 64.0D;
}
}
@Override
public void clear() {
inv.clear();
}
@Override
public void fromTag(BlockState state, CompoundTag tag) {
super.fromTag(state, tag);
inv.clear();
Inventories.fromTag(tag, inv);
}
@Override
public CompoundTag toTag(CompoundTag tag) {
super.toTag(tag);
Inventories.toTag(tag, inv);
return tag;
}
}

@ -0,0 +1,66 @@
package com.thebrokenrail.energonrelics.block.reactor;
import com.thebrokenrail.energonrelics.block.battery.BatteryControllerBlock;
import com.thebrokenrail.energonrelics.block.entity.reactor.ReactorControllerBlockEntity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
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.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.Objects;
import java.util.Random;
import java.util.function.Function;
@SuppressWarnings("deprecation")
public class ReactorControllerBlock extends BatteryControllerBlock {
public static final BooleanProperty POWERED = Properties.POWERED;
public ReactorControllerBlock() {
super();
setDefaultState(getDefaultState().with(POWERED, false));
}
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return Objects.requireNonNull(super.getPlacementState(ctx)).with(POWERED, 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(POWERED);
if (bl != world.isReceivingRedstonePower(pos)) {
if (bl) {
world.getBlockTickScheduler().schedule(pos, this, 4);
} else {
world.setBlockState(pos, state.cycle(POWERED), 2);
}
}
}
}
@Override
public void scheduledTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
if (state.get(POWERED) && !world.isReceivingRedstonePower(pos)) {
world.setBlockState(pos, state.cycle(POWERED), 2);
}
}
@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(POWERED);
}
@Override
protected Function<BlockEntityType<BlockEntity>, BlockEntity> getFactory() {
return ReactorControllerBlockEntity::new;
}
}

@ -0,0 +1,21 @@
package com.thebrokenrail.energonrelics.block.reactor;
import com.thebrokenrail.energonrelics.block.entity.reactor.ReactorCoreBlockEntity;
import com.thebrokenrail.energonrelics.block.util.SimpleBlockWithEntity;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.Material;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import java.util.function.Function;
public class ReactorCoreBlock extends SimpleBlockWithEntity {
public ReactorCoreBlock() {
super(FabricBlockSettings.of(Material.STONE).requiresTool().strength(1.5f, 6.0f));
}
@Override
protected Function<BlockEntityType<BlockEntity>, BlockEntity> getFactory() {
return ReactorCoreBlockEntity::new;
}
}

@ -0,0 +1,47 @@
package com.thebrokenrail.energonrelics.block.reactor;
import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.block.entity.reactor.ReactorInputBlockEntity;
import com.thebrokenrail.energonrelics.block.util.SimpleBlockWithEntity;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
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.player.PlayerEntity;
import net.minecraft.inventory.Inventory;
import net.minecraft.screen.HopperScreenHandler;
import net.minecraft.screen.SimpleNamedScreenHandlerFactory;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.function.Function;
public class ReactorInputBlock extends SimpleBlockWithEntity {
public ReactorInputBlock() {
super(FabricBlockSettings.of(Material.STONE).requiresTool().strength(1.5f, 6.0f));
}
@Override
protected Function<BlockEntityType<BlockEntity>, BlockEntity> getFactory() {
return ReactorInputBlockEntity::new;
}
@Override
@SuppressWarnings("deprecation")
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
BlockEntity entity = world.getBlockEntity(pos);
if (entity instanceof Inventory) {
if (!world.isClient()) {
player.openHandledScreen(new SimpleNamedScreenHandlerFactory((i, inv, player2) -> new HopperScreenHandler(i, inv, (Inventory) entity), new TranslatableText("block." + EnergonRelics.NAMESPACE + ".reactor_input")));
}
return ActionResult.SUCCESS;
} else {
return ActionResult.FAIL;
}
}
}

@ -0,0 +1,93 @@
package com.thebrokenrail.energonrelics.block.util;
import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.client.render.HighlightBlockEntityRenderer;
import com.thebrokenrail.energonrelics.component.NetworkComponent;
import com.thebrokenrail.energonrelics.energy.core.EnergyProviderBlockEntity;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.client.rendereregistry.v1.BlockEntityRendererRegistry;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public abstract class EnergyProviderBlock extends SimpleBlockWithEntity {
private static final List<EnergyProviderBlock> blocks = new ArrayList<>();
public EnergyProviderBlock(Settings settings) {
super(settings);
}
@Override
public void register(String name) {
super.register(name);
blocks.add(this);
}
@Environment(EnvType.CLIENT)
public static void initRenderer() {
for (EnergyProviderBlock block : blocks) {
BlockEntityRendererRegistry.INSTANCE.register(block.type, block.getRenderer());
}
}
@Environment(EnvType.CLIENT)
protected Function<BlockEntityRenderDispatcher, BlockEntityRenderer<BlockEntity>> getRenderer() {
return HighlightBlockEntityRenderer::new;
}
private void setEnergyProviderSource(World world, BlockPos pos, ItemStack stack, boolean remove) {
ServerWorld serverWorld = (ServerWorld) world;
NetworkComponent component = NetworkComponent.getInstance(serverWorld);
if (remove) {
component.removeSource(EnergonRelics.NETWORK_CHIP_ITEM.getID(stack), pos);
} else {
component.addSource(EnergonRelics.NETWORK_CHIP_ITEM.getID(stack), pos);
}
}
@Override
@SuppressWarnings("deprecation")
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
BlockEntity entity = world.getBlockEntity(pos);
if (entity instanceof EnergyProviderBlockEntity && ((EnergyProviderBlockEntity) entity).isEnergyProvider()) {
ItemStack stack = player.getStackInHand(hand);
if (stack.getItem() == EnergonRelics.NETWORK_CHIP_ITEM) {
if (!((EnergyProviderBlockEntity) entity).hasStack()) {
if (!world.isClient()) {
setEnergyProviderSource(world, pos, stack, false);
((EnergyProviderBlockEntity) entity).placeStack(stack);
stack.setCount(0);
}
return ActionResult.SUCCESS;
} else {
return ActionResult.FAIL;
}
} else if (stack.isEmpty() && hand == Hand.MAIN_HAND) {
if (!world.isClient()) {
ItemStack newStack = ((EnergyProviderBlockEntity) entity).takeStack();
player.setStackInHand(hand, newStack);
setEnergyProviderSource(world, pos, newStack, true);
}
return ActionResult.SUCCESS;
} else {
return ActionResult.PASS;
}
} else {
return ActionResult.PASS;
}
}
}

@ -0,0 +1,19 @@
package com.thebrokenrail.energonrelics.block.util;
import com.thebrokenrail.energonrelics.EnergonRelics;
import net.minecraft.block.Block;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
public class SimpleBlock extends Block {
public SimpleBlock(Settings settings) {
super(settings);
}
public void register(String name) {
Registry.register(Registry.BLOCK, new Identifier(EnergonRelics.NAMESPACE, name), this);
Registry.register(Registry.ITEM, new Identifier(EnergonRelics.NAMESPACE, name), new BlockItem(this, new Item.Settings().group(EnergonRelics.ITEM_GROUP)));
}
}

@ -0,0 +1,32 @@
package com.thebrokenrail.energonrelics.block.util;
import com.thebrokenrail.energonrelics.EnergonRelics;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.minecraft.world.BlockView;
import java.util.function.Function;
public abstract class SimpleBlockWithEntity extends SimpleBlock implements BlockEntityProvider {
protected BlockEntityType<BlockEntity> type;
public SimpleBlockWithEntity(Settings settings) {
super(settings);
}
@Override
public void register(String name) {
super.register(name);
type = Registry.register(Registry.BLOCK_ENTITY_TYPE, new Identifier(EnergonRelics.NAMESPACE, name), BlockEntityType.Builder.create(() -> getFactory().apply(type), this).build(null));
}
protected abstract Function<BlockEntityType<BlockEntity>, BlockEntity> getFactory();
@Override
public BlockEntity createBlockEntity(BlockView world) {
return getFactory().apply(type);
}
}

@ -0,0 +1,14 @@
package com.thebrokenrail.energonrelics.client;
import com.thebrokenrail.energonrelics.block.util.EnergyProviderBlock;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@Environment(EnvType.CLIENT)
public class EnergonRelicsClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
EnergyProviderBlock.initRenderer();
}
}

@ -0,0 +1,77 @@
package com.thebrokenrail.energonrelics.client.render;
import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.energy.core.EnergyReceiverBlockEntity;
import com.thebrokenrail.energonrelics.mixin.RenderPhaseAccessor;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Hand;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Matrix4f;
import java.util.Objects;
public class HighlightBlockEntityRenderer extends BlockEntityRenderer<BlockEntity> {
public HighlightBlockEntityRenderer(BlockEntityRenderDispatcher dispatcher) {
super(dispatcher);
}
private static RenderLayer getLayer() {
return RenderLayer.of("fasterthanc_holographic_sky", VertexFormats.POSITION_COLOR, 7, 256, false, true, RenderLayer.MultiPhaseParameters.builder().transparency(RenderPhaseAccessor.getTRANSLUCENT_TRANSPARENCY()).layering(RenderPhaseAccessor.getVIEW_OFFSET_Z_LAYERING()).build(false));
}
private static final RenderLayer LAYER = getLayer();
@Override
public void render(BlockEntity entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) {
matrices.push();
if (entity instanceof EnergyReceiverBlockEntity) {
MinecraftClient client = MinecraftClient.getInstance();
assert client.player != null;
ItemStack stack = client.player.getStackInHand(Hand.MAIN_HAND);
if (stack.getItem() == EnergonRelics.NETWORK_CHIP_ITEM) {
boolean contains = ((EnergyReceiverBlockEntity) entity).contains(EnergonRelics.NETWORK_CHIP_ITEM.getID(stack));
Matrix4f matrix4f = matrices.peek().getModel();
if (!contains) {
renderLayer(entity, matrix4f, vertexConsumers.getBuffer(LAYER), 1.0f, 0.0f);
} else {
renderLayer(entity, matrix4f, vertexConsumers.getBuffer(LAYER), 0.0f, 1.0f);
}
}
}
matrices.pop();
}
private void renderLayer(BlockEntity entity, Matrix4f matrix4f, VertexConsumer vertexConsumer, float r, float b) {
renderSide(entity, matrix4f, vertexConsumer, 0.0F, 1.0F, 0.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, r, b, Direction.SOUTH);
renderSide(entity, matrix4f, vertexConsumer, 0.0F, 1.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, r, b, Direction.NORTH);
renderSide(entity, matrix4f, vertexConsumer, 1.0F, 1.0F, 1.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.0F, r, b, Direction.EAST);
renderSide(entity, matrix4f, vertexConsumer, 0.0F, 0.0F, 0.0F, 1.0F, 0.0F, 1.0F, 1.0F, 0.0F, r, b, Direction.WEST);
renderSide(entity, matrix4f, vertexConsumer, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F, 1.0F, r, b, Direction.DOWN);
renderSide(entity, matrix4f, vertexConsumer, 0.0F, 1.0F, 1.0f, 1.0f, 1.0F, 1.0F, 0.0F, 0.0F, r, b, Direction.UP);
}
private boolean shouldDrawSide(BlockEntity entity, Direction side) {
BlockState state = entity.getCachedS