Add support for solar energy scaling during day (#2497)

This commit is contained in:
Dave Smith 2021-09-16 15:45:38 -06:00 committed by GitHub
parent dcca103f9a
commit 56dcc4dd16
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 52 deletions

View file

@ -59,6 +59,10 @@ public enum ObjectBufferUtils {
buffer.writeFloat(pos); buffer.writeFloat(pos);
}, ExtendedPacketBuffer::readFloat), }, ExtendedPacketBuffer::readFloat),
BOOLEAN(Boolean.class, (value, buffer) -> {
buffer.writeBoolean(value);
}, ExtendedPacketBuffer::readBoolean),
BLOCK_POS(BlockPos.class, (pos, buffer) -> { BLOCK_POS(BlockPos.class, (pos, buffer) -> {
buffer.writeBlockPos(pos); buffer.writeBlockPos(pos);
}, PacketByteBuf::readBlockPos), }, PacketByteBuf::readBlockPos),

View file

@ -24,6 +24,7 @@
package techreborn.blockentity.generator; package techreborn.blockentity.generator;
import java.util.List;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
@ -52,20 +53,12 @@ import techreborn.init.TRBlockEntities;
import techreborn.init.TRContent; import techreborn.init.TRContent;
import techreborn.init.TRContent.SolarPanels; import techreborn.init.TRContent.SolarPanels;
import java.util.List;
public class SolarPanelBlockEntity extends PowerAcceptorBlockEntity implements IToolDrop, BuiltScreenHandlerProvider { public class SolarPanelBlockEntity extends PowerAcceptorBlockEntity implements IToolDrop, BuiltScreenHandlerProvider {
private boolean generating = false;
// State ZEROGEN: No exposure to sun // Range of panel between day/night production; we calculate this only when panel is updated
// State NIGHTGEN: Has direct exposure to sun private int dayNightRange = 0;
// State DAYGEN: Has exposure to sun and weather is sunny and not raining/thundering
public static final int ZEROGEN = 0;
public static final int NIGHTGEN = 1;
public static final int DAYGEN = 2;
private int state = ZEROGEN;
private int prevState = ZEROGEN;
private SolarPanels panel; private SolarPanels panel;
@ -82,20 +75,25 @@ public class SolarPanelBlockEntity extends PowerAcceptorBlockEntity implements I
if (world == null) { if (world == null) {
return; return;
} }
Block panelBlock = world.getBlockState(pos).getBlock(); Block panelBlock = world.getBlockState(pos).getBlock();
if (panelBlock instanceof BlockSolarPanel solarPanelBlock) { if (panelBlock instanceof BlockSolarPanel solarPanelBlock) {
panel = solarPanelBlock.panelType; panel = solarPanelBlock.panelType;
} }
dayNightRange = getPanel().generationRateD - getPanel().generationRateN;
} }
// Setters/getters that provide boolean interface to underlying generating int; something about
// Setters and getters for the GUI to sync // screen auto-sync REQUIRES an integer value (booleans don't get transmitted?!), so resorted to
private void setSunState(int state) { // this ugly approach
this.state = state; public boolean isGenerating() { return generating; }
} private void setIsGenerating(boolean isGenerating) {
if (isGenerating != isGenerating()) {
public int getSunState() { // Update block state if necessary
return state; world.setBlockState(pos, world.getBlockState(pos).with(BlockMachineBase.ACTIVE, isGenerating));
}
this.generating = isGenerating;
} }
SolarPanels getPanel() { SolarPanels getPanel() {
@ -109,35 +107,39 @@ public class SolarPanelBlockEntity extends PowerAcceptorBlockEntity implements I
if (world == null) { if (world == null) {
return; return;
} }
if (world.isSkyVisible(pos.up())) {
this.setSunState(NIGHTGEN);
if (!world.isRaining() && !world.isThundering() && world.isDay()) { // Generation is only possible if sky is visible above us
this.setSunState(DAYGEN); setIsGenerating(world.isSkyVisible(pos.up()));
}
} else {
this.setSunState(ZEROGEN);
}
// Nether and The End
if (!world.getDimension().hasSkyLight()) {
this.setSunState(NIGHTGEN);
}
if (prevState != this.getSunState()) {
boolean isGenerating = getSunState() == DAYGEN;
world.setBlockState(pos, world.getBlockState(pos).with(BlockMachineBase.ACTIVE, isGenerating));
prevState = this.getSunState();
}
} }
public int getGenerationRate() { public int getGenerationRate() {
return switch (getSunState()) { if (!isGenerating()) {
case DAYGEN -> getPanel().generationRateD; return 0;
case NIGHTGEN -> getPanel().generationRateN; }
default -> 0;
}; float skyAngle = world.getSkyAngle(0);
// Ok, we are actively generating power, but check for a few conditions that would restrict
// the generation to minimal production...
if (!world.getDimension().hasSkyLight() || // No light source in dimension (e.g. nether or end)
(skyAngle > 0.25 && skyAngle < 0.75) || // Light source is below horizon
(world.isRaining() || world.isThundering())) { // Weather is present
return getPanel().generationRateN;
}
// At this point, we know a light source is present and it's clear weather. We need to determine
// the level of generation based on % of time through the day, with peak production at noon and
// a smooth transition to night production as sun rises/sets
float multiplier = 0.0f;
if (skyAngle > 0.75) {
// Morning to noon
multiplier = (0.25f - (1 - skyAngle)) / 0.25f;
} else {
// Noon to sunset
multiplier = (0.25f - skyAngle) / 0.25f;
}
return (int)Math.ceil(getPanel().generationRateN + (dayNightRange * multiplier));
} }
@ -287,7 +289,7 @@ public class SolarPanelBlockEntity extends PowerAcceptorBlockEntity implements I
public BuiltScreenHandler createScreenHandler(int syncID, final PlayerEntity player) { public BuiltScreenHandler createScreenHandler(int syncID, final PlayerEntity player) {
return new ScreenHandlerBuilder("solar_panel").player(player.getInventory()).inventory().hotbar().addInventory() return new ScreenHandlerBuilder("solar_panel").player(player.getInventory()).inventory().hotbar().addInventory()
.blockEntity(this).syncEnergyValue() .blockEntity(this).syncEnergyValue()
.sync(this::getSunState, this::setSunState) .sync(this::isGenerating, this::setIsGenerating)
.addInventory().create(this, syncID); .addInventory().create(this, syncID);
} }
} }

View file

@ -48,10 +48,8 @@ public class GuiSolar extends GuiBase<BuiltScreenHandler> {
builder.drawMultiEnergyBar(matrixStack, this, 156, 19, (int) blockEntity.getEnergy(), (int) blockEntity.getMaxStoredPower(), mouseX, mouseY, 0, layer); builder.drawMultiEnergyBar(matrixStack, this, 156, 19, (int) blockEntity.getEnergy(), (int) blockEntity.getMaxStoredPower(), mouseX, mouseY, 0, layer);
switch (blockEntity.getSunState()) { if (!blockEntity.isGenerating()) {
case SolarPanelBlockEntity.DAYGEN -> builder.drawText(matrixStack, this, new TranslatableText("techreborn.message.daygen"), 10, 20, 15129632); builder.drawText(matrixStack, this, new TranslatableText("techreborn.message.panel_blocked"), 10, 20, 12066591);
case SolarPanelBlockEntity.NIGHTGEN -> builder.drawText(matrixStack, this, new TranslatableText("techreborn.message.nightgen"), 10, 20, 7566195);
case SolarPanelBlockEntity.ZEROGEN -> builder.drawText(matrixStack, this, new TranslatableText("techreborn.message.zerogen"), 10, 20, 12066591);
} }
builder.drawText(matrixStack, this, new LiteralText("Generating: " + blockEntity.getGenerationRate() + " E/t"), 10, 30, 0); builder.drawText(matrixStack, this, new LiteralText("Generating: " + blockEntity.getGenerationRate() + " E/t"), 10, 30, 0);

View file

@ -720,9 +720,7 @@
"techreborn.message.allPlayers": "All Players", "techreborn.message.allPlayers": "All Players",
"techreborn.message.onlyOtherPlayers": "Only Other Players", "techreborn.message.onlyOtherPlayers": "Only Other Players",
"techreborn.message.onlyYou": "Only You", "techreborn.message.onlyYou": "Only You",
"techreborn.message.daygen": "Panel in direct sunlight", "techreborn.message.panel_blocked": "Panel obstructed from sky",
"techreborn.message.nightgen": "Panel in reduced sunlight",
"techreborn.message.zerogen": "Panel obstructed from sky",
"techreborn.message.info.item.techreborn.overclocker_upgrade": "Increases speed at the cost of more energy used per tick", "techreborn.message.info.item.techreborn.overclocker_upgrade": "Increases speed at the cost of more energy used per tick",
"techreborn.message.info.item.techreborn.transformer_upgrade": "Increase energy tier", "techreborn.message.info.item.techreborn.transformer_upgrade": "Increase energy tier",