Skip to content

Commit

Permalink
Add logic for energy support, closes #3.
Browse files Browse the repository at this point in the history
Computer and robot now consume energy; constant amount per tick while running.
Added charger block to allow charging robots.
Charger can charge anything with IEnergyStorage capability and items with it in an ItemHandler on top of it.
Also some renames, mostly nbt -> tag.
  • Loading branch information
fnuecke committed Feb 12, 2021
1 parent 924294d commit c196659
Show file tree
Hide file tree
Showing 53 changed files with 985 additions and 433 deletions.
4 changes: 4 additions & 0 deletions src/main/java/li/cil/oc2/client/ClientSetup.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import li.cil.oc2.client.model.BusCableModelLoader;
import li.cil.oc2.client.renderer.NetworkCableRenderer;
import li.cil.oc2.client.renderer.entity.RobotEntityRenderer;
import li.cil.oc2.client.renderer.tileentity.ChargerTileEntityRenderer;
import li.cil.oc2.client.renderer.tileentity.ComputerTileEntityRenderer;
import li.cil.oc2.client.renderer.tileentity.DiskDriveTileEntityRenderer;
import li.cil.oc2.client.renderer.tileentity.NetworkConnectorTileEntityRenderer;
Expand Down Expand Up @@ -43,6 +44,7 @@ public static void handleSetupEvent(final FMLClientSetupEvent event) {
ClientRegistry.bindTileEntityRenderer(TileEntities.COMPUTER_TILE_ENTITY.get(), ComputerTileEntityRenderer::new);
ClientRegistry.bindTileEntityRenderer(TileEntities.NETWORK_CONNECTOR_TILE_ENTITY.get(), NetworkConnectorTileEntityRenderer::new);
ClientRegistry.bindTileEntityRenderer(TileEntities.DISK_DRIVE_TILE_ENTITY.get(), DiskDriveTileEntityRenderer::new);
ClientRegistry.bindTileEntityRenderer(TileEntities.CHARGER_TILE_ENTITY.get(), ChargerTileEntityRenderer::new);

RenderingRegistry.registerEntityRenderingHandler(Entities.ROBOT.get(), RobotEntityRenderer::new);
}
Expand All @@ -65,5 +67,7 @@ public static void handleTextureStitchEvent(final TextureStitchEvent.Pre event)
event.addSprite(ComputerTileEntityRenderer.OVERLAY_POWER_LOCATION);
event.addSprite(ComputerTileEntityRenderer.OVERLAY_STATUS_LOCATION);
event.addSprite(ComputerTileEntityRenderer.OVERLAY_TERMINAL_LOCATION);

event.addSprite(ChargerTileEntityRenderer.EFFECT_LOCATION);
}
}
2 changes: 1 addition & 1 deletion src/main/java/li/cil/oc2/client/item/CustomItemColors.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public static int getColorByDye(final DyeColor dye) {

public static int getColor(final ItemStack stack) {
final CompoundNBT tag = ItemStackUtils.getModDataTag(stack);
if (tag != null && tag.contains(COLOR_TAG_NAME, NBTTagIds.TAG_INT)) {
if (tag.contains(COLOR_TAG_NAME, NBTTagIds.TAG_INT)) {
return tag.getInt(COLOR_TAG_NAME);
} else {
return GREY;
Expand Down
14 changes: 8 additions & 6 deletions src/main/java/li/cil/oc2/client/renderer/CustomRenderType.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package li.cil.oc2.client.renderer;

import li.cil.oc2.api.API;
import net.minecraft.client.renderer.RenderState;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormat;
Expand All @@ -13,23 +12,26 @@ public static RenderType getUnlitBlock(final ResourceLocation location) {
final TextureState texture = new TextureState(location, false, true);
final RenderType.State state = RenderType.State.getBuilder()
.texture(texture)
.writeMask(COLOR_WRITE)
.alpha(DEFAULT_ALPHA)
.transparency(ADDITIVE_TRANSPARENCY)
.cull(CULL_DISABLED)
.build(false);
return RenderType.makeType(
API.MOD_ID + ":unlit_block",
DefaultVertexFormats.POSITION_TEX,
GL11.GL_QUADS,
256,
false,
true,
state);
}

public static RenderType getNetworkCable() {
final State state = State.getBuilder()
.texture(RenderState.NO_TEXTURE)
.transparency(RenderState.NO_TRANSPARENCY)
.cull(RenderState.CULL_DISABLED)
.lightmap(RenderState.LIGHTMAP_ENABLED)
.texture(NO_TEXTURE)
.transparency(NO_TRANSPARENCY)
.cull(CULL_DISABLED)
.lightmap(LIGHTMAP_ENABLED)
.build(false);
return RenderType.makeType(API.MOD_ID + ":network_cable",
DefaultVertexFormats.POSITION_COLOR_LIGHTMAP,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package li.cil.oc2.client.renderer.tileentity;

import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import li.cil.oc2.api.API;
import li.cil.oc2.client.renderer.CustomRenderType;
import li.cil.oc2.common.tileentity.ChargerTileEntity;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.model.RenderMaterial;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.inventory.container.PlayerContainer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Matrix4f;

public final class ChargerTileEntityRenderer extends TileEntityRenderer<ChargerTileEntity> {
public static final ResourceLocation EFFECT_LOCATION = new ResourceLocation(API.MOD_ID, "block/charger/effect");

private static final RenderMaterial TEXTURE_EFFECT = new RenderMaterial(PlayerContainer.LOCATION_BLOCKS_TEXTURE, EFFECT_LOCATION);

private static final int EFFECT_LAYERS = 3;
private static final float EFFECT_HEIGHT = 0.5f;
private static final float EFFECT_SPEED = 0.1f;
private static final float EFFECT_SCALE_START = 0.6f;
private static final float EFFECT_SCALE_END = 0.8f;

///////////////////////////////////////////////////////////////////

private float offset = 0;

///////////////////////////////////////////////////////////////////

public ChargerTileEntityRenderer(final TileEntityRendererDispatcher dispatcher) {
super(dispatcher);
}

///////////////////////////////////////////////////////////////////

@Override
public void render(final ChargerTileEntity tileEntity, final float partialTicks, final MatrixStack matrixStack, final IRenderTypeBuffer buffer, final int light, final int overlay) {
offset = (offset + EFFECT_SPEED * partialTicks / 20f) % (float) (Math.PI * 2);

matrixStack.push();
matrixStack.translate(0.5, 1.1, 0.5);

final IVertexBuilder builder = TEXTURE_EFFECT.getBuffer(buffer, CustomRenderType::getUnlitBlock);

for (int i = 0; i < EFFECT_LAYERS; i++) {
final float relativeY = (1 + MathHelper.sin(offset + ((float) Math.PI * 2f * i / EFFECT_LAYERS))) * 0.5f;
final float y = relativeY * EFFECT_HEIGHT;
final float scale = EFFECT_SCALE_START + relativeY * (EFFECT_SCALE_END - EFFECT_SCALE_START);

matrixStack.push();
matrixStack.translate(0, y, 0);
renderScaledQuad(matrixStack, builder, scale);
matrixStack.pop();
}

matrixStack.pop();
}

private static void renderScaledQuad(final MatrixStack matrixStack, final IVertexBuilder builder, final float scale) {
matrixStack.push();
matrixStack.scale(scale, scale, scale);
renderQuad(matrixStack.getLast().getMatrix(), builder);
matrixStack.pop();
}

private static void renderQuad(final Matrix4f matrix, final IVertexBuilder builder) {
// NB: We may get a SpriteAwareVertexBuilder here. Sadly, its chaining is broken,
// because methods may return the underlying vertex builder, so e.g. calling
// buffer.pos(...).tex(...) will not actually call SpriteAwareVertexBuilder.tex(...)
// but SpriteAwareVertexBuilder.vertexBuilder.tex(...), skipping the UV remapping.
builder.pos(matrix, -0.5f, 0, -0.5f);
builder.tex(0, 0);
builder.endVertex();

builder.pos(matrix, -0.5f, 0, 0.5f);
builder.tex(0, 1);
builder.endVertex();

builder.pos(matrix, 0.5f, 0, 0.5f);
builder.tex(1, 1);
builder.endVertex();

builder.pos(matrix, 0.5f, 0, -0.5f);
builder.tex(1, 0);
builder.endVertex();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -203,22 +203,25 @@ private void renderPower(final Matrix4f matrix, final IRenderTypeBuffer buffer)
renderQuad(matrix, TEXTURE_POWER.getBuffer(buffer, CustomRenderType::getUnlitBlock));
}

private static void renderQuad(final Matrix4f matrix, final IVertexBuilder buffer) {
private static void renderQuad(final Matrix4f matrix, final IVertexBuilder builder) {
// NB: We may get a SpriteAwareVertexBuilder here. Sadly, its chaining is broken,
// because methods may return the underlying vertex builder, so e.g. calling
// buffer.pos(...).tex(...) will not actually call SpriteAwareVertexBuilder.tex(...)
// but SpriteAwareVertexBuilder.vertexBuilder.tex(...), skipping the UV remapping.
buffer.pos(matrix, 0, 0, 0);
buffer.tex(0, 0);
buffer.endVertex();
buffer.pos(matrix, 0, 16, 0);
buffer.tex(0, 1);
buffer.endVertex();
buffer.pos(matrix, 16, 16, 0);
buffer.tex(1, 1);
buffer.endVertex();
buffer.pos(matrix, 16, 0, 0);
buffer.tex(1, 0);
buffer.endVertex();
builder.pos(matrix, 0, 0, 0);
builder.tex(0, 0);
builder.endVertex();

builder.pos(matrix, 0, 16, 0);
builder.tex(0, 1);
builder.endVertex();

builder.pos(matrix, 16, 16, 0);
builder.tex(1, 1);
builder.endVertex();

builder.pos(matrix, 16, 0, 0);
builder.tex(1, 0);
builder.endVertex();
}
}
81 changes: 75 additions & 6 deletions src/main/java/li/cil/oc2/common/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ public final class Config {
public static int maxFlashMemorySize = 4 * Constants.KILOBYTE;
public static int maxFloppySize = 512 * Constants.KILOBYTE;

public static int computerEnergyPerTick = 20;
public static int computerEnergyStorage = 4000;
public static int robotEnergyPerTick = 10;
public static int robotEnergyStorage = 600000;
public static int chargerEnergyPerTick = 2500;
public static int chargerEnergyStorage = 50000;

public static int blockOperationsModuleToolLevel = Items.DIAMOND_PICKAXE.getHarvestLevel(new ItemStack(Items.DIAMOND_PICKAXE), ToolType.PICKAXE, null, null);

public static UUID fakePlayerUUID = UUID.fromString("e39dd9a7-514f-4a2d-aa5e-b6030621416d");
Expand All @@ -44,6 +51,18 @@ public static void initialize() {
ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, COMMON_SPEC);
}

public static boolean computersUseEnergy() {
return computerEnergyPerTick > 0 && computerEnergyStorage > 0;
}

public static boolean robotsUseEnergy() {
return robotEnergyPerTick > 0 && robotEnergyStorage > 0;
}

public static boolean chargerUseEnergy() {
return chargerEnergyPerTick > 0 && chargerEnergyStorage > 0;
}

///////////////////////////////////////////////////////////////////

@SubscribeEvent
Expand All @@ -54,21 +73,37 @@ public static void handleModConfigEvent(final ModConfig.ModConfigEvent event) {
maxHardDriveSize = COMMON_INSTANCE.maxHardDriveSize.get();
maxFlashMemorySize = COMMON_INSTANCE.maxFlashMemorySize.get();

computerEnergyPerTick = COMMON_INSTANCE.computerEnergyPerTick.get();
computerEnergyStorage = COMMON_INSTANCE.computerEnergyStorage.get();
robotEnergyPerTick = COMMON_INSTANCE.robotEnergyPerTick.get();
robotEnergyStorage = COMMON_INSTANCE.robotEnergyStorage.get();
chargerEnergyPerTick = COMMON_INSTANCE.chargerEnergyPerTick.get();
chargerEnergyStorage = COMMON_INSTANCE.chargerEnergyStorage.get();

blockOperationsModuleToolLevel = COMMON_INSTANCE.blockOperationsModuleToolLevel.get();

fakePlayerUUID = UUID.fromString(COMMON_INSTANCE.fakePlayerUUID.get());
}
}

///////////////////////////////////////////////////////////////////

private static final class CommonSettings {
public ForgeConfigSpec.LongValue maxAllocatedMemory;
public ForgeConfigSpec.IntValue maxMemorySize;
public ForgeConfigSpec.IntValue maxHardDriveSize;
public ForgeConfigSpec.IntValue maxFlashMemorySize;
public final ForgeConfigSpec.LongValue maxAllocatedMemory;
public final ForgeConfigSpec.IntValue maxMemorySize;
public final ForgeConfigSpec.IntValue maxHardDriveSize;
public final ForgeConfigSpec.IntValue maxFlashMemorySize;

public final ForgeConfigSpec.IntValue computerEnergyPerTick;
public final ForgeConfigSpec.IntValue computerEnergyStorage;
public final ForgeConfigSpec.IntValue robotEnergyPerTick;
public final ForgeConfigSpec.IntValue robotEnergyStorage;
public final ForgeConfigSpec.IntValue chargerEnergyPerTick;
public final ForgeConfigSpec.IntValue chargerEnergyStorage;

public ForgeConfigSpec.IntValue blockOperationsModuleToolLevel;
public final ForgeConfigSpec.IntValue blockOperationsModuleToolLevel;

public ForgeConfigSpec.ConfigValue<String> fakePlayerUUID;
public final ForgeConfigSpec.ConfigValue<String> fakePlayerUUID;

public CommonSettings(final ForgeConfigSpec.Builder builder) {
builder.push("vm");
Expand All @@ -95,6 +130,40 @@ public CommonSettings(final ForgeConfigSpec.Builder builder) {

builder.pop();

builder.push("energy");

computerEnergyPerTick = builder
.translation(Constants.CONFIG_COMPUTER_ENERGY_PER_TICK)
.comment("The amount of energy (Forge Energy/RF) a computer draws per tick. Set to zero to disable.")
.defineInRange("computerEnergyPerTick", Config.computerEnergyPerTick, 0, Integer.MAX_VALUE);

computerEnergyStorage = builder
.translation(Constants.CONFIG_COMPUTER_ENERGY_STORAGE)
.comment("The amount of energy (Forge Energy/RF) a computer can store internally.")
.defineInRange("computerEnergyStorage", Config.computerEnergyStorage, 0, Integer.MAX_VALUE);

robotEnergyPerTick = builder
.translation(Constants.CONFIG_ROBOT_ENERGY_PER_TICK)
.comment("The amount of energy (Forge Energy/RF) a robot draws per tick. Set to zero to disable.")
.defineInRange("robotEnergyPerTick", Config.robotEnergyPerTick, 0, Integer.MAX_VALUE);

robotEnergyStorage = builder
.translation(Constants.CONFIG_ROBOT_ENERGY_STORAGE)
.comment("The amount of energy (Forge Energy/RF) a robot can store internally.")
.defineInRange("robotEnergyStorage", Config.robotEnergyStorage, 0, Integer.MAX_VALUE);

chargerEnergyPerTick = builder
.translation(Constants.CONFIG_CHARGER_ENERGY_PER_TICK)
.comment("The maximum amount of energy (Forge Energy/RF) a charger transfers per tick. Set to zero to disable.")
.defineInRange("chargerEnergyPerTick", Config.chargerEnergyPerTick, 0, Integer.MAX_VALUE);

chargerEnergyStorage = builder
.translation(Constants.CONFIG_CHARGER_ENERGY_STORAGE)
.comment("The amount of energy (Forge Energy/RF) a charger can store internally.")
.defineInRange("chargerEnergyStorage", Config.chargerEnergyStorage, 0, Integer.MAX_VALUE);

builder.pop();

builder.push("gameplay");

blockOperationsModuleToolLevel = builder
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/li/cil/oc2/common/Constants.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package li.cil.oc2.common;

import li.cil.oc2.api.API;
import net.minecraft.util.Direction;

public final class Constants {
Expand All @@ -18,7 +19,9 @@ public final class Constants {
///////////////////////////////////////////////////////////////////

public static final String BLOCK_ENTITY_TAG_NAME_IN_ITEM = "BlockEntityTag";
public static final String INVENTORY_TAG_NAME = "items";
public static final String MOD_TAG_NAME = API.MOD_ID;
public static final String ITEMS_TAG_NAME = "items";
public static final String ENERGY_TAG_NAME = "energy";

///////////////////////////////////////////////////////////////////

Expand All @@ -28,6 +31,7 @@ public final class Constants {
public static final String NETWORK_HUB_BLOCK_NAME = "network_hub";
public static final String DISK_DRIVE_BLOCK_NAME = "disk_drive";
public static final String REDSTONE_INTERFACE_BLOCK_NAME = "redstone_interface";
public static final String CHARGER_BLOCK_NAME = "charger";

///////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -57,6 +61,7 @@ public final class Constants {
public static final String TOOLTIP_FLASH_MEMORY_MISSING = "tooltip.oc2.flash_memory_missing";
public static final String TOOLTIP_MEMORY_MISSING = "tooltip.oc2.memory_missing";
public static final String TOOLTIP_HARD_DRIVE_MISSING = "tooltip.oc2.hard_drive_missing";
public static final String TOOLTIP_ENERGY = "tooltip.oc2.energy";

///////////////////////////////////////////////////////////////////

Expand All @@ -66,6 +71,12 @@ public final class Constants {
public static final String CONFIG_MAX_FLASH_MEMORY_SIZE = "config.oc2.vm.maxFlashMemorySize";
public static final String CONFIG_BLOCK_OPERATIONS_MODULE_TOOL_LEVEL = "config.oc2.modules.block_operations.toolLevel";
public static final String CONFIG_FAKE_PLAYER_UUID = "config.oc2.admin.fakePlayerUUID";
public static final String CONFIG_COMPUTER_ENERGY_PER_TICK = "config.oc2.computerEnergyPerTick";
public static final String CONFIG_COMPUTER_ENERGY_STORAGE = "config.oc2.computerEnergyStorage";
public static final String CONFIG_ROBOT_ENERGY_PER_TICK = "config.oc2.robotEnergyPerTick";
public static final String CONFIG_ROBOT_ENERGY_STORAGE = "config.oc2.robotEnergyStorage";
public static final String CONFIG_CHARGER_ENERGY_PER_TICK = "config.oc2.chargerEnergyPerTick";
public static final String CONFIG_CHARGER_ENERGY_STORAGE = "config.oc2.chargerEnergyStorage";

///////////////////////////////////////////////////////////////////

Expand All @@ -79,6 +90,7 @@ public final class Constants {
public static final String COMPUTER_BUS_STATE_INCOMPLETE = "gui.oc2.computer.bus_state.incomplete";
public static final String COMPUTER_BUS_STATE_TOO_COMPLEX = "gui.oc2.computer.bus_state.too_complex";
public static final String COMPUTER_BUS_STATE_MULTIPLE_CONTROLLERS = "gui.oc2.computer.bus_state.multiple_controllers";
public static final String COMPUTER_ERROR_NOT_ENOUGH_ENERGY = "gui.oc2.computer.error.not_enough_energy";

///////////////////////////////////////////////////////////////////

Expand Down
1 change: 1 addition & 0 deletions src/main/java/li/cil/oc2/common/block/Blocks.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public final class Blocks {
public static final RegistryObject<NetworkHubBlock> NETWORK_HUB = BLOCKS.register(Constants.NETWORK_HUB_BLOCK_NAME, NetworkHubBlock::new);
public static final RegistryObject<RedstoneInterfaceBlock> REDSTONE_INTERFACE = BLOCKS.register(Constants.REDSTONE_INTERFACE_BLOCK_NAME, RedstoneInterfaceBlock::new);
public static final RegistryObject<DiskDriveBlock> DISK_DRIVE = BLOCKS.register(Constants.DISK_DRIVE_BLOCK_NAME, DiskDriveBlock::new);
public static final RegistryObject<ChargerBlock> CHARGER = BLOCKS.register(Constants.CHARGER_BLOCK_NAME, ChargerBlock::new);

///////////////////////////////////////////////////////////////////

Expand Down

0 comments on commit c196659

Please sign in to comment.