Add support for solar energy scaling during day (#2497)
This commit is contained in:
parent
dcca103f9a
commit
56dcc4dd16
4 changed files with 54 additions and 52 deletions
|
@ -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),
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Add table
Reference in a new issue