Initial Commit

This commit is contained in:
TheBrokenRail 2020-07-13 16:37:21 -04:00
commit b483684372
141 changed files with 2955 additions and 0 deletions

27
.gitignore vendored Normal file
View File

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

4
CHANGELOG.md Normal file
View File

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

5
README.md Normal file
View File

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

24
TODO Normal file
View File

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

BIN
assets/battery_casing.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 B

BIN
assets/battery_core.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

BIN
assets/network_chip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

BIN
assets/switch_off.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

BIN
assets/switch_on.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

BIN
assets/switch_side.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

54
build.gradle Normal file
View File

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

16
gradle.properties Normal file
View File

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

View File

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

12
settings.gradle Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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.getCachedState();
return Block.shouldDrawSide(state, Objects.requireNonNull(entity.getWorld()), entity.getPos(), side);
}
private void renderSide(BlockEntity entity, Matrix4f matrix4f, VertexConsumer vertexConsumer, float f, float g, float h, float i, float j, float k, float l, float m, float n, float p, Direction side) {
if (shouldDrawSide(entity, side)) {
vertexConsumer.vertex(matrix4f, f, h, j).color(n, (float) 0.0, p, 0.2f).next();
vertexConsumer.vertex(matrix4f, g, h, k).color(n, (float) 0.0, p, 0.2f).next();
vertexConsumer.vertex(matrix4f, g, i, l).color(n, (float) 0.0, p, 0.2f).next();
vertexConsumer.vertex(matrix4f, f, i, m).color(n, (float) 0.0, p, 0.2f).next();
}
}
}

View File

@ -0,0 +1,184 @@
package com.thebrokenrail.energonrelics.component;
import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.energy.core.util.EnergyProvider;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.PersistentState;
import net.minecraft.world.World;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
public class NetworkComponent extends PersistentState {
private static class Entry {
private final List<BlockPos> sources = new ArrayList<>();
private int id = 0;
}
private final List<Entry> networks = new ArrayList<>();
private NetworkComponent() {
super(EnergonRelics.NAMESPACE);
}
@Override
public void fromTag(CompoundTag tag) {
networks.clear();
Tag list = tag.get("Networks");
if (list instanceof ListTag) {
ListTag networks = (ListTag) list;
for (int i = 0; i < networks.size(); i++) {
this.networks.add(getEntry(networks.getCompound(i)));
}
}
}
private Entry getEntry(CompoundTag tag) {
Entry entry = new Entry();
entry.id = tag.getInt("ID");
entry.sources.clear();
Tag list = tag.get("Sources");
if (list instanceof ListTag) {
ListTag sources = (ListTag) list;
for (int i = 0; i < sources.size(); i++) {
int x = sources.getCompound(i).getInt("X");
int y = sources.getCompound(i).getInt("Y");
int z = sources.getCompound(i).getInt("Z");
entry.sources.add(new BlockPos(x, y, z));
}
}
return entry;
}
private CompoundTag saveEntry(Entry entry) {
CompoundTag tag = new CompoundTag();
tag.putInt("ID", entry.id);
ListTag sources = new ListTag();
for (BlockPos pos : entry.sources) {
CompoundTag posTag = new CompoundTag();
posTag.putInt("X", pos.getX());
posTag.putInt("Y", pos.getY());
posTag.putInt("Z", pos.getZ());
sources.add(posTag);
}
tag.put("Sources", sources);
return tag;
}
@Override
public CompoundTag toTag(CompoundTag tag) {
ListTag networksTag = new ListTag();
for (Entry entry : networks) {
networksTag.add(saveEntry(entry));
}
tag.put("Networks", networksTag);
return tag;
}
private Entry getOrCreate(int id) {
for (Entry entry : networks) {
if (entry.id == id) {
return entry;
}
}
Entry entry = new Entry();
entry.id = id;
entry.sources.clear();
networks.add(entry);
markDirty();
return entry;
}
public static NetworkComponent getInstance(ServerWorld world) {
return Objects.requireNonNull(world.getServer().getWorld(World.OVERWORLD)).getPersistentStateManager().getOrCreate(NetworkComponent::new, EnergonRelics.NAMESPACE);
}
public List<BlockPos> getSourcePos(int id) {
Entry entry = getOrCreate(id);
return entry.sources;
}
public List<EnergyProvider> getSource(World world, int id) {
List<BlockPos> sources = getSourcePos(id);
List<BlockPos> valid = new ArrayList<>();
Iterator<BlockPos> iterator = sources.iterator();
List<EnergyProvider> providers = new ArrayList<>();
boolean dirty = false;
while (iterator.hasNext()) {
BlockPos pos = iterator.next();
if (!valid.contains(pos)) {
BlockEntity entity = world.getBlockEntity(pos);
if (entity instanceof EnergyProvider && ((EnergyProvider) entity).isNetwork(id)) {
providers.add((EnergyProvider) entity);
} else {
iterator.remove();
dirty = true;
}
valid.add(pos);
} else {
iterator.remove();
dirty = true;
}
}
if (dirty) {
markDirty();
}
Collections.shuffle(providers);
return providers;
}
public void addSource(int id, BlockPos pos) {
Entry entry = getOrCreate(id);
if (!entry.sources.contains(pos)) {
entry.sources.add(pos);
}
markDirty();
}
public void removeSource(int id, BlockPos pos) {
Entry entry = getOrCreate(id);
entry.sources.remove(pos);
markDirty();
}
public int create() {
int id = -1;
for (Entry entry : networks) {
id = Math.max(id, entry.id);
}
return getOrCreate(id + 1).id;
}
@Override
public void markDirty() {
List<Integer> ids = new ArrayList<>();
List<BlockPos> positions = new ArrayList<>();
Iterator<Entry> iterator = networks.iterator();
while (iterator.hasNext()) {
Entry entry = iterator.next();
boolean remove = false;
if (ids.contains(entry.id)) {
remove = true;
} else {
ids.add(entry.id);
}
if (!Collections.disjoint(positions, entry.sources)) {
remove = true;
} else {
positions.addAll(entry.sources);
}
if (remove) {
iterator.remove();
}
}
super.markDirty();
}
}

View File

@ -0,0 +1,147 @@
package com.thebrokenrail.energonrelics.energy.core;
import com.thebrokenrail.energonrelics.Config;
import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.component.NetworkComponent;
import com.thebrokenrail.energonrelics.energy.core.util.Action;
import com.thebrokenrail.energonrelics.energy.core.util.EnergyProvider;
import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable;
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.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Tickable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public class EnergyProviderBlockEntity extends BlockEntity implements EnergyProvider, BlockEntityClientSerializable, Tickable {
private final ArrayList<Action.PropagatedAction> pendingPropagatedActions = new ArrayList<>();
private static final List<EnergyProviderBlockEntity> scheduledTicks = new ArrayList<>();
public static void tickScheduled() {
Collections.shuffle(scheduledTicks);
for (EnergyProviderBlockEntity provider : scheduledTicks) {
provider.serverTick();
}
scheduledTicks.clear();
}
public EnergyProviderBlockEntity(BlockEntityType<?> type) {
super(type);
}
@Override
public final void addPropagatedAction(Action.PropagatedAction action) {
if (isEnergyProvider()) {
pendingPropagatedActions.add(action);
} else {
throw new UnsupportedOperationException();
}
}
@Override
public final boolean isNetwork(int network) {
return isEnergyProvider() && EnergonRelics.NETWORK_CHIP_ITEM.getID(stack) == network;
}
@Override
public final boolean isWithinDistance(Vec3d pos) {
return getPos().isWithinDistance(pos, Config.POWER_RANGE);
}
private ItemStack stack = ItemStack.EMPTY;
@Override
public CompoundTag toTag(CompoundTag tag) {
super.toTag(tag);
if (isEnergyProvider()) {
tag.put("NetworkChip", stack.toTag(new CompoundTag()));
}
return tag;
}
@Override
public void fromTag(BlockState state, CompoundTag tag) {
super.fromTag(state, tag);
if (isEnergyProvider()) {
stack = ItemStack.fromTag(tag.getCompound("NetworkChip"));
} else {
stack = ItemStack.EMPTY;
}
}
public boolean isEnergyProvider() {
return false;
}
protected void handlePropagatedAction(Action.PropagatedAction action) {
throw new UnsupportedOperationException();
}
private void tickPropagatedActions() {
if (isEnergyProvider()) {
for (Action.PropagatedAction action : pendingPropagatedActions) {
handlePropagatedAction(action);
}
NetworkComponent component = NetworkComponent.getInstance((ServerWorld) Objects.requireNonNull(getWorld()));
List<BlockPos> sources = component.getSourcePos(EnergonRelics.NETWORK_CHIP_ITEM.getID(stack));
if (!sources.contains(getPos())) {
takeStack();
}
}
pendingPropagatedActions.clear();
}
protected void serverTick() {
tickPropagatedActions();
}
@Override
public final void tick() {
if (hasWorld() && !Objects.requireNonNull(getWorld()).isClient()) {
scheduledTicks.add(this);
}
}
public ItemStack takeStack() {
ItemStack newStack = stack.copy();
stack = ItemStack.EMPTY;
markDirty();
return newStack;
}
public void placeStack(ItemStack newStack) {
stack = newStack.copy();
markDirty();
}
public boolean hasStack() {
return !stack.isEmpty();
}
@Override
public void fromClientTag(CompoundTag compoundTag) {
fromTag(Blocks.AIR.getDefaultState(), compoundTag);
}
@Override
public CompoundTag toClientTag(CompoundTag compoundTag) {
return toTag(compoundTag);
}
@Override
public void markDirty() {
super.markDirty();
sync();
}
}

View File

@ -0,0 +1,147 @@
package com.thebrokenrail.energonrelics.energy.core;
import com.thebrokenrail.energonrelics.component.NetworkComponent;
import com.thebrokenrail.energonrelics.energy.core.util.Action;
import com.thebrokenrail.energonrelics.energy.core.util.EnergyProvider;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.IntArrayTag;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Tickable;
import net.minecraft.util.math.Vec3d;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public abstract class EnergyReceiverBlockEntity extends EnergyProviderBlockEntity implements Tickable {
private class SelfProvider implements EnergyProvider {
@Override
public void addPropagatedAction(Action.PropagatedAction action) {
pendingActionsFromSelf.add(action);
}
@Override
public boolean isNetwork(int network) {
return true;
}
@Override
public boolean isWithinDistance(Vec3d pos) {
return true;
}
}
public EnergyReceiverBlockEntity(BlockEntityType<?> type) {
super(type);
}
private final List<Action.PropagatedAction> pendingActions = new ArrayList<>();
private final List<Action.PropagatedAction> pendingActionsFromSelf = new ArrayList<>();
private final EnergyProvider selfProvider = new SelfProvider();
private final List<EnergyProvider> providers = new ArrayList<>();
private final List<Integer> networks = new ArrayList<>();
private long totalCost = 0;
protected void propagateAction(Action.PropagatedAction action) {
totalCost = totalCost + action.amountOwed();
action.expandPayments(providers.size());
pendingActions.add(action);
}
protected void addAction(Action action) {
propagateAction(new Action.PropagatedActionImpl(action, getWorld(), getPos(), getCachedState().getBlock()));
}
@Override
public void serverTick() {
if (hasWorld() && !Objects.requireNonNull(getWorld()).isClient()) {
// Every Action Must Be Paid At Least Once For a Failure State To Occur
for (Action.PropagatedAction action : pendingActionsFromSelf) {
action.pay(0);
}
pendingActionsFromSelf.clear();
ServerWorld world = (ServerWorld) getWorld();
NetworkComponent component = NetworkComponent.getInstance(world);
providers.clear();
// At Least One Energy Provider Is Always Required
providers.add(selfProvider);
for (int network : networks) {
List<EnergyProvider> potentialProviders = component.getSource(world, network);
for (EnergyProvider provider : potentialProviders) {
Vec3d pos = new Vec3d(getPos().getX() + 0.5d, getPos().getY() + 0.5d, getPos().getZ() + 0.5d);
if (provider.isWithinDistance(pos)) {
providers.add(provider);
}
}
}
totalCost = 0;
pendingActions.clear();
tickEnergy();
super.serverTick();
for (Action.PropagatedAction action : pendingActions) {
for (EnergyProvider provider : providers) {
provider.addPropagatedAction(action);
}
}
}
}
public long getTotalCost() {
return totalCost;
}
@Override
protected void handlePropagatedAction(Action.PropagatedAction action) {
// Propagate Action To Energy Providers
if (isEnergyProviderActive()) {
propagateAction(action);
} else {
action.pay(0);
}
}
@Override
public CompoundTag toTag(CompoundTag tag) {
super.toTag(tag);
tag.put("Networks", new IntArrayTag(networks));
return tag;
}
@Override
public void fromTag(BlockState state, CompoundTag tag) {
super.fromTag(state, tag);
int[] networksArray = tag.getIntArray("Networks");
networks.clear();
for (int network : networksArray) {
networks.add(network);
}
}
protected boolean isEnergyProviderActive() {
throw new UnsupportedOperationException();
}
protected abstract void tickEnergy();
public void toggle(int network) {
if (contains(network)) {
networks.removeAll(Collections.singletonList(network));
} else {
networks.add(network);
}
markDirty();
}
public boolean contains(int network) {
return networks.contains(network);
}
}

View File

@ -0,0 +1,86 @@
package com.thebrokenrail.energonrelics.energy.core.util;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.state.property.Property;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class Action {
public interface ActionFunction {
void run(World world, BlockPos pos, BlockState state);
}
private final long cost;
private final ActionFunction success;
private final ActionFunction fail;
public Action(long cost, ActionFunction success, ActionFunction fail) {
this.cost = cost;
this.success = success;
this.fail = fail;
}
public static <T extends Comparable<T>> Action createBlockStatePropertyAction(long cost, Property<T> property, T successValue, T failureValue) {
return new Action(cost, (world, pos, state) -> {
if (!state.get(property).equals(successValue)) {
world.setBlockState(pos, state.with(property, successValue));
}
}, (world, pos, state) -> {
if (!state.get(property).equals(failureValue)) {
world.setBlockState(pos, state.with(property, failureValue));
}
});
}
public interface PropagatedAction {
void expandPayments(int amount);
long amountOwed();
void pay(long amount);
}
public static class PropagatedActionImpl implements PropagatedAction {
private final Action action;
private final World world;
private final BlockPos pos;
private final Block block;
private int expectedPayments = 1;
private int payments = 0;
private long amountPaid = 0;
public PropagatedActionImpl(Action action, World world, BlockPos pos, Block block) {
super();
this.action = action;
this.world = world;
this.pos = pos;
this.block = block;
}
@Override
public void expandPayments(int amount) {
if (amount < 1) {
throw new UnsupportedOperationException();
}
expectedPayments = expectedPayments - 1 + amount;
}
@Override
public long amountOwed() {
return action.cost - amountPaid;
}
@Override
public void pay(long amount) {
amountPaid = amountPaid + amount;
payments++;
BlockState state = world.getBlockState(pos);
if (state != null && state.getBlock() == block) {
if (amountOwed() <= 0) {
action.success.run(world, pos, state);
} else if (payments >= expectedPayments) {
action.fail.run(world, pos, state);
}
}
}
}
}

View File

@ -0,0 +1,9 @@
package com.thebrokenrail.energonrelics.energy.core.util;
import net.minecraft.util.math.Vec3d;
public interface EnergyProvider {
void addPropagatedAction(Action.PropagatedAction action);
boolean isNetwork(int network);
boolean isWithinDistance(Vec3d pos);
}

View File

@ -0,0 +1,16 @@
package com.thebrokenrail.energonrelics.energy.helper;
import com.thebrokenrail.energonrelics.energy.core.util.Action;
public interface EnergyGenerator {
default void handlePropagatedActionWithGenerator(Action.PropagatedAction action) {
long amount = Math.min(getEnergy(), action.amountOwed());
setEnergy(getEnergy() - amount);
action.pay(amount);
}
long getEnergy();
void setEnergy(long value);
long getDisplayEnergy();
}

View File

@ -0,0 +1,36 @@
package com.thebrokenrail.energonrelics.energy.helper;
import com.thebrokenrail.energonrelics.energy.core.EnergyProviderBlockEntity;
import com.thebrokenrail.energonrelics.energy.core.util.Action;
import net.minecraft.block.entity.BlockEntityType;
public abstract class EnergyGeneratorBlockEntity extends EnergyProviderBlockEntity implements EnergyGenerator {
public EnergyGeneratorBlockEntity(BlockEntityType<?> type) {
super(type);
}
private long energy = 0;
@Override
public boolean isEnergyProvider() {
return true;
}
@Override
public long getEnergy() {
return energy;
}
@Override
public void setEnergy(long value) {
energy = value;
}
@Override
protected void handlePropagatedAction(Action.PropagatedAction action) {
handlePropagatedActionWithGenerator(action);
}
@Override
public abstract long getDisplayEnergy();
}

View File

@ -0,0 +1,67 @@
package com.thebrokenrail.energonrelics.item;
import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.energy.core.EnergyReceiverBlockEntity;
import com.thebrokenrail.energonrelics.energy.helper.EnergyGenerator;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.Entity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.text.LiteralText;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Formatting;
import net.minecraft.world.RayTraceContext;
import net.minecraft.world.World;
import java.util.Objects;
public class MultimeterItem extends Item {
public MultimeterItem() {
super(new Settings().maxCount(1).group(EnergonRelics.ITEM_GROUP));
}
private Text numberToText(long value) {
String str;
if (value >= Long.MAX_VALUE) {
str = "\u221e";
} else {
str = String.valueOf(value);
}
return new LiteralText(str).formatted(Formatting.WHITE);
}
@Override
public ActionResult useOnBlock(ItemUsageContext context) {
World world = context.getWorld();
BlockEntity entity = world.getBlockEntity(context.getBlockPos());
boolean success = false;
MutableText text = new LiteralText("");
if (entity instanceof EnergyGenerator) {
if (!world.isClient() && context.getPlayer() != null) {
text.append(new TranslatableText("text." + EnergonRelics.NAMESPACE + ".energy_available", numberToText(((EnergyGenerator) entity).getDisplayEnergy())).formatted(Formatting.YELLOW));
}
success = true;
}
if (entity instanceof EnergyReceiverBlockEntity) {
if (!world.isClient() && context.getPlayer() != null) {
if (success) {
text.append(" ");
}
text.append(new TranslatableText("text." + EnergonRelics.NAMESPACE + ".energy_required", numberToText(((EnergyReceiverBlockEntity) entity).getTotalCost())).formatted(Formatting.YELLOW));
}
success = true;
}
if (success) {
if (!world.isClient()) {
Objects.requireNonNull(context.getPlayer()).sendMessage(text, true);
}
return ActionResult.SUCCESS;
} else {
return ActionResult.PASS;
}
}
}

View File

@ -0,0 +1,87 @@
package com.thebrokenrail.energonrelics.item;
import com.thebrokenrail.energonrelics.EnergonRelics;
import com.thebrokenrail.energonrelics.component.NetworkComponent;
import com.thebrokenrail.energonrelics.energy.core.EnergyReceiverBlockEntity;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.entity.Entity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Formatting;
import net.minecraft.world.World;
import java.util.List;
public class NetworkChipItem extends Item {
public NetworkChipItem() {
super(new Settings().maxCount(1).group(EnergonRelics.ITEM_GROUP));
}
private void setID(ItemStack stack, int id) {
CompoundTag tag = stack.getOrCreateTag();
tag.putInt("NetworkID", id);
}
public int getID(ItemStack stack) {
CompoundTag tag = stack.getOrCreateTag();
if (tag.contains("NetworkID")) {
return tag.getInt("NetworkID");
} else {
return -1;
}
}
private int getOrCreateID(ItemStack stack, NetworkComponent component) {
int id = getID(stack);
if (id == -1) {
id = component.create();
setID(stack, id);
}
return id;
}
@Override
public void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) {
super.inventoryTick(stack, world, entity, slot, selected);
if (!world.isClient()) {
ServerWorld serverWorld = (ServerWorld) world;
NetworkComponent component = NetworkComponent.getInstance(serverWorld);
getOrCreateID(stack, component);
}
}
@Override
@Environment(EnvType.CLIENT)
public void appendTooltip(ItemStack stack, World world, List<Text> tooltip, TooltipContext context) {
super.appendTooltip(stack, world, tooltip, context);
int id = getID(stack);
if (id != -1) {
tooltip.add(new TranslatableText("item." + EnergonRelics.NAMESPACE + ".network_chip.tooltip", String.valueOf(id)).formatted(Formatting.GRAY));
}
}
@Override
public ActionResult useOnBlock(ItemUsageContext context) {
World world = context.getWorld();
BlockEntity entity = world.getBlockEntity(context.getBlockPos());
if (entity instanceof EnergyReceiverBlockEntity) {
if (!world.isClient()) {
ServerWorld serverWorld = (ServerWorld) world;
NetworkComponent component = NetworkComponent.getInstance(serverWorld);
((EnergyReceiverBlockEntity) entity).toggle(getOrCreateID(context.getStack(), component));
}
return ActionResult.SUCCESS;
} else {
return ActionResult.PASS;
}
}
}

View File

@ -0,0 +1,22 @@
package com.thebrokenrail.energonrelics.mixin;
import com.thebrokenrail.energonrelics.energy.core.EnergyProviderBlockEntity;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(World.class)
public abstract class MixinWorld {
@Shadow
public abstract boolean isClient();
@Inject(at = @At("TAIL"), method = "tickBlockEntities")
public void tickBlockEntities(CallbackInfo info) {
if (!isClient()) {
EnergyProviderBlockEntity.tickScheduled();
}
}
}

View File

@ -0,0 +1,23 @@
package com.thebrokenrail.energonrelics.mixin;
import net.minecraft.client.render.RenderPhase;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(RenderPhase.class)
public interface RenderPhaseAccessor {
@Accessor
static RenderPhase.Transparency getTRANSLUCENT_TRANSPARENCY() {
throw new UnsupportedOperationException();
}
@Accessor
static RenderPhase.Target getTRANSLUCENT_TARGET() {
throw new UnsupportedOperationException();
}
@Accessor
static RenderPhase.Layering getVIEW_OFFSET_Z_LAYERING() {
throw new UnsupportedOperationException();
}
}

View File

@ -0,0 +1,27 @@
{
"variants": {
"facing=down": {
"model": "energonrelics:block/active_battery_controller",
"x": 90
},
"facing=east": {
"model": "energonrelics:block/active_battery_controller",
"y": 90
},
"facing=north": {
"model": "energonrelics:block/active_battery_controller"
},
"facing=south": {
"model": "energonrelics:block/active_battery_controller",
"y": 180
},
"facing=up": {
"model": "energonrelics:block/active_battery_controller",
"x": 270
},
"facing=west": {
"model": "energonrelics:block/active_battery_controller",
"y": 270
}
}
}

View File

@ -0,0 +1,27 @@
{
"variants": {
"facing=down": {
"model": "energonrelics:block/battery_controller",
"x": 90
},
"facing=east": {
"model": "energonrelics:block/battery_controller",
"y": 90
},
"facing=north": {
"model": "energonrelics:block/battery_controller"
},
"facing=south": {
"model": "energonrelics:block/battery_controller",
"y": 180
},
"facing=up": {
"model": "energonrelics:block/battery_controller",
"x": 270
},
"facing=west": {
"model": "energonrelics:block/battery_controller",
"y": 270
}
}
}

View File

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

View File

@ -0,0 +1,10 @@
{
"variants": {
"powered=false": {
"model": "energonrelics:block/energon_light_off"
},
"powered=true": {
"model": "energonrelics:block/energon_light_on"
}
}
}

View File

@ -0,0 +1,50 @@
{
"variants": {
"facing=down,powered=false": {
"model": "energonrelics:block/reactor_controller_off",
"x": 90
},
"facing=down,powered=true": {
"model": "energonrelics:block/reactor_controller_on",
"x": 90
},
"facing=east,powered=false": {
"model": "energonrelics:block/reactor_controller_off",
"y": 90
},
"facing=east,powered=true": {
"model": "energonrelics:block/reactor_controller_on",
"y": 90
},
"facing=north,powered=false": {
"model": "energonrelics:block/reactor_controller_off"
},
"facing=north,powered=true": {
"model": "energonrelics:block/reactor_controller_on"
},
"facing=south,powered=false": {
"model": "energonrelics:block/reactor_controller_off",
"y": 180
},
"facing=south,powered=true": {
"model": "energonrelics:block/reactor_controller_on",
"y": 180
},
"facing=up,powered=false": {
"model": "energonrelics:block/reactor_controller_off",
"x": 270
},
"facing=up,powered=true": {
"model": "energonrelics:block/reactor_controller_on",
"x": 270
},
"facing=west,powered=false": {
"model": "energonrelics:block/reactor_controller_off",
"y": 270
},
"facing=west,powered=true": {
"model": "energonrelics:block/reactor_controller_on",
"y": 270
}
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,10 @@
{
"variants": {
"powered=false": {
"model": "energonrelics:block/switch_off"
},
"powered=true": {
"model": "energonrelics:block/switch_on"
}
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,22 @@
{
"item.energonrelics.network_chip": "Network Chip",
"item.energonrelics.network_chip.tooltip": "ID: %s",
"itemGroup.energonrelics.item_group": "EnergonRelics",
"block.energonrelics.energon_light": "Energon Light",
"block.energonrelics.solar_panel": "Solar Panel",
"block.energonrelics.switch": "Switch",
"item.energonrelics.multimeter": "Multimeter",
"text.energonrelics.energy_required": "Energy Required: %s Energon",
"text.energonrelics.energy_available": "Energy Available: %s Energon",
"block.energonrelics.thermal_casing": "Thermal Casing",
"block.energonrelics.battery_core": "Battery Core",
"block.energonrelics.battery_controller": "Passive Battery Controller",
"block.energonrelics.active_battery_controller": "Active Battery Controller",
"item.energonrelics.circuit_board": "Circuit Board",
"block.energonrelics.reactor_controller": "Reactor Controller",
"block.energonrelics.reactor_input": "Reactor Input",
"block.energonrelics.reactor_core": "Reactor Core",
"item.energonrelics.veridium_ingot": "Veridium Ingot",
"block.energonrelics.veridium_ore": "Veridium Ore",
"block.energonrelics.veridium_block": "Veridium Block"
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"top": "energonrelics:block/active_battery_controller_side",
"front": "energonrelics:block/active_battery_controller",
"side": "energonrelics:block/active_battery_controller_side"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"top": "energonrelics:block/battery_controller_side",
"front": "energonrelics:block/battery_controller",
"side": "energonrelics:block/battery_controller_side"
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"top": "energonrelics:block/reactor_controller_side",
"front": "energonrelics:block/reactor_controller_off",
"side": "energonrelics:block/reactor_controller_side"
}
}

View File

@ -0,0 +1,8 @@
{
"parent": "minecraft:block/orientable",
"textures": {
"top": "energonrelics:block/reactor_controller_side",
"front": "energonrelics:block/reactor_controller_on",
"side": "energonrelics:block/reactor_controller_side"
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "energonrelics:item/circuit_board"
}
}

View File

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

View File

@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "energonrelics:item/multimeter"
}
}

View File

@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "energonrelics:item/network_chip"
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "energonrelics:item/veridium_ingot"
}
}

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 687 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 769 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 B

Some files were not shown because too many files have changed in this diff Show More