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);
}, ExtendedPacketBuffer::readFloat),
BOOLEAN(Boolean.class, (value, buffer) -> {
buffer.writeBoolean(value);
}, ExtendedPacketBuffer::readBoolean),
BLOCK_POS(BlockPos.class, (pos, buffer) -> {
buffer.writeBlockPos(pos);
}, PacketByteBuf::readBlockPos),

View file

@ -24,6 +24,7 @@
package techreborn.blockentity.generator;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
@ -52,20 +53,12 @@ import techreborn.init.TRBlockEntities;
import techreborn.init.TRContent;
import techreborn.init.TRContent.SolarPanels;
import java.util.List;
public class SolarPanelBlockEntity extends PowerAcceptorBlockEntity implements IToolDrop, BuiltScreenHandlerProvider {
private boolean generating = false;
// State ZEROGEN: No exposure to sun
// State NIGHTGEN: Has direct exposure to sun
// 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;
// Range of panel between day/night production; we calculate this only when panel is updated
private int dayNightRange = 0;
private SolarPanels panel;
@ -82,20 +75,25 @@ public class SolarPanelBlockEntity extends PowerAcceptorBlockEntity implements I
if (world == null) {
return;
}
Block panelBlock = world.getBlockState(pos).getBlock();
if (panelBlock instanceof BlockSolarPanel solarPanelBlock) {
panel = solarPanelBlock.panelType;
}
dayNightRange = getPanel().generationRateD - getPanel().generationRateN;
}
// Setters and getters for the GUI to sync
private void setSunState(int state) {
this.state = state;
// Setters/getters that provide boolean interface to underlying generating int; something about
// screen auto-sync REQUIRES an integer value (booleans don't get transmitted?!), so resorted to
// this ugly approach
public boolean isGenerating() { return generating; }
private void setIsGenerating(boolean isGenerating) {
if (isGenerating != isGenerating()) {
// Update block state if necessary
world.setBlockState(pos, world.getBlockState(pos).with(BlockMachineBase.ACTIVE, isGenerating));
}
public int getSunState() {
return state;
this.generating = isGenerating;
}
SolarPanels getPanel() {
@ -109,35 +107,39 @@ public class SolarPanelBlockEntity extends PowerAcceptorBlockEntity implements I
if (world == null) {
return;
}
if (world.isSkyVisible(pos.up())) {
this.setSunState(NIGHTGEN);
if (!world.isRaining() && !world.isThundering() && world.isDay()) {
this.setSunState(DAYGEN);
}
} 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();
}
// Generation is only possible if sky is visible above us
setIsGenerating(world.isSkyVisible(pos.up()));
}
public int getGenerationRate() {
return switch (getSunState()) {
case DAYGEN -> getPanel().generationRateD;
case NIGHTGEN -> getPanel().generationRateN;
default -> 0;
};
if (!isGenerating()) {
return 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) {
return new ScreenHandlerBuilder("solar_panel").player(player.getInventory()).inventory().hotbar().addInventory()
.blockEntity(this).syncEnergyValue()
.sync(this::getSunState, this::setSunState)
.sync(this::isGenerating, this::setIsGenerating)
.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);
switch (blockEntity.getSunState()) {
case SolarPanelBlockEntity.DAYGEN -> builder.drawText(matrixStack, this, new TranslatableText("techreborn.message.daygen"), 10, 20, 15129632);
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);
if (!blockEntity.isGenerating()) {
builder.drawText(matrixStack, this, new TranslatableText("techreborn.message.panel_blocked"), 10, 20, 12066591);
}
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.onlyOtherPlayers": "Only Other Players",
"techreborn.message.onlyYou": "Only You",
"techreborn.message.daygen": "Panel in direct sunlight",
"techreborn.message.nightgen": "Panel in reduced sunlight",
"techreborn.message.zerogen": "Panel obstructed from sky",
"techreborn.message.panel_blocked": "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.transformer_upgrade": "Increase energy tier",