Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add redstone functionality to the Simulation Chamber #76

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.shadowsoffire.hostilenetworks;

import dev.shadowsoffire.hostilenetworks.net.SetRedstoneStatePayload;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

Expand Down Expand Up @@ -38,6 +39,7 @@ public HostileNetworks(IEventBus bus) {
Hostile.bootstrap(bus);
PayloadHelper.registerPayload(new ConfigPayload.Provider());
PayloadHelper.registerPayload(new OpenDeepLearnerPayload.Provider());
PayloadHelper.registerPayload(new SetRedstoneStatePayload.Provider());
}

@SubscribeEvent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import dev.shadowsoffire.hostilenetworks.tile.SimChamberTileEntity;
import dev.shadowsoffire.hostilenetworks.tile.SimChamberTileEntity.FailureState;
import dev.shadowsoffire.hostilenetworks.tile.SimChamberTileEntity.SimItemHandler;
import dev.shadowsoffire.hostilenetworks.tile.SimChamberTileEntity.RedstoneState;
import dev.shadowsoffire.placebo.menu.BlockEntityMenu;
import dev.shadowsoffire.placebo.menu.FilteredSlot;
import net.minecraft.core.BlockPos;
Expand Down Expand Up @@ -48,4 +49,10 @@ public FailureState getFailState() {
return this.tile.getFailState();
}

public void setRedstoneState(int ordinal) {
this.tile.setRedstoneState(ordinal);
}

public RedstoneState getRedstoneState() { return this.tile.getRedstoneState(); }

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,29 @@
import java.util.ArrayList;
import java.util.List;

import com.mojang.blaze3d.systems.RenderSystem;
import dev.shadowsoffire.hostilenetworks.HostileConfig;
import dev.shadowsoffire.hostilenetworks.HostileNetworks;
import dev.shadowsoffire.hostilenetworks.data.DataModelInstance;
import dev.shadowsoffire.hostilenetworks.data.ModelTier;
import dev.shadowsoffire.hostilenetworks.item.DataModelItem;
import dev.shadowsoffire.hostilenetworks.net.SetRedstoneStatePayload;
import dev.shadowsoffire.hostilenetworks.tile.SimChamberTileEntity;
import dev.shadowsoffire.hostilenetworks.tile.SimChamberTileEntity.FailureState;
import dev.shadowsoffire.hostilenetworks.tile.SimChamberTileEntity.RedstoneState;
import dev.shadowsoffire.hostilenetworks.util.Color;
import dev.shadowsoffire.placebo.screen.PlaceboContainerScreen;
import dev.shadowsoffire.placebo.screen.TickableText;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.player.Inventory;
import net.neoforged.neoforge.network.PacketDistributor;

public class SimChamberScreen extends PlaceboContainerScreen<SimChamberContainer> {

Expand All @@ -38,6 +45,12 @@ public SimChamberScreen(SimChamberContainer pMenu, Inventory pPlayerInventory, C
this.imageHeight = HEIGHT;
}

@Override
public void init() {
super.init();
addRenderableWidget(new RedstoneButton(this.getGuiLeft() + 228, this.getGuiTop()));
}

@Override
protected void renderTooltip(GuiGraphics gfx, int pX, int pY) {
if (this.isHovering(211, 48, 7, 87, pX, pY)) {
Expand All @@ -62,6 +75,9 @@ else if (this.isHovering(14, 48, 7, 87, pX, pY)) {
gfx.renderComponentTooltip(this.font, txt, pX, pY);
}
}
else if (this.isHovering(229, 1, 16, 16, pX, pY)) {
gfx.renderTooltip(this.font, Component.translatable(this.menu.getRedstoneState().getKey()), pX, pY);
}
else super.renderTooltip(gfx, pX, pY);
}

Expand Down Expand Up @@ -119,6 +135,9 @@ protected void renderBg(GuiGraphics gfx, float pPartialTicks, int pX, int pY) {
gfx.blit(BASE, left + 8, top, 0, 0, 216, 141, 256, 256);
gfx.blit(BASE, left - 14, top, 0, 141, 18, 18, 256, 256);

// Redstone background
gfx.blit(BASE, left + 228, top, 0, 141, 18, 18, 256, 256);

int energyHeight = 87 - Mth.ceil(87F * this.menu.getEnergyStored() / HostileConfig.simPowerCap);

gfx.blit(BASE, left + 211, top + 48, 18, 141, 7, energyHeight, 256, 256);
Expand Down Expand Up @@ -192,4 +211,29 @@ else if (i == 5) {
if (this.menu.getRuntime() == 0) this.runtimeTextLoaded = false;
}

private class RedstoneButton extends AbstractWidget {

public RedstoneButton(int x, int y) {
super(x, y, 18, 18, Component.empty());
}

@Override
public void onClick(double mouseX, double mouseY) {
PacketDistributor.sendToServer(new SetRedstoneStatePayload((SimChamberScreen.this.menu.getRedstoneState().ordinal() + 1) % RedstoneState.values().length));
}

@Override
protected void updateWidgetNarration(NarrationElementOutput output) {
this.defaultButtonNarrationText(output);
}

@Override
protected void renderWidget(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) {
RenderSystem.enableBlend();
RenderSystem.enableDepthTest();
guiGraphics.setColor(1.0F, 1.0F, 1.0F, 1.0F);
guiGraphics.blit(SimChamberScreen.this.menu.getRedstoneState().getResourceLocation(), this.getX() + 1, this.getY() + 1, 0, 0, 16, 16, 16, 16);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package dev.shadowsoffire.hostilenetworks.net;

import dev.shadowsoffire.hostilenetworks.HostileNetworks;
import dev.shadowsoffire.hostilenetworks.gui.SimChamberContainer;
import dev.shadowsoffire.placebo.network.PayloadProvider;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.ConnectionProtocol;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.PacketFlow;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.neoforge.network.handling.IPayloadContext;

import java.util.List;
import java.util.Optional;

public record SetRedstoneStatePayload(int ordinal) implements CustomPacketPayload {

public static final CustomPacketPayload.Type<SetRedstoneStatePayload> TYPE = new CustomPacketPayload.Type<>(HostileNetworks.loc("redstone_state"));

public static final StreamCodec<ByteBuf, SetRedstoneStatePayload> CODEC = StreamCodec.composite(ByteBufCodecs.INT, SetRedstoneStatePayload::ordinal, SetRedstoneStatePayload::new);

@Override
public Type<? extends CustomPacketPayload> type() {
return TYPE;
}

public static class Provider implements PayloadProvider<SetRedstoneStatePayload> {

@Override
public Type<SetRedstoneStatePayload> getType() {
return TYPE;
}

@Override
public StreamCodec<? super RegistryFriendlyByteBuf, SetRedstoneStatePayload> getCodec() {
return CODEC;
}

@Override
public void handle(SetRedstoneStatePayload msg, IPayloadContext ctx) {
if(!(ctx.player() instanceof ServerPlayer sender)) {
return;
}
if (sender.containerMenu instanceof SimChamberContainer simChamber) {
simChamber.setRedstoneState(msg.ordinal());
}
}

@Override
public List<ConnectionProtocol> getSupportedProtocols() {
return List.of(ConnectionProtocol.PLAY);
}

@Override
public Optional<PacketFlow> getFlow() {
return Optional.of(PacketFlow.SERVERBOUND);
}

@Override
public String getVersion() {
return "1";
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@ public class SimChamberTileEntity extends BlockEntity implements TickingBlockEnt
protected int runtime = 0;
protected int predictionSuccess = 0;
protected FailureState failState = FailureState.NONE;
protected RedstoneState redstoneState = RedstoneState.IGNORED;

public SimChamberTileEntity(BlockPos pos, BlockState state) {
super(Hostile.TileEntities.SIM_CHAMBER, pos, state);
this.data.addData(() -> this.runtime, v -> this.runtime = v);
this.data.addData(() -> this.predictionSuccess, v -> this.predictionSuccess = v);
this.data.addData(() -> this.failState.ordinal(), v -> this.failState = FailureState.values()[v]);
this.data.addData(() -> this.redstoneState.ordinal(), v -> this.redstoneState = RedstoneState.values()[v]);
this.data.addEnergy(this.energy);
}

Expand All @@ -59,6 +61,7 @@ public void saveAdditional(CompoundTag tag, HolderLookup.Provider regs) {
tag.putInt("runtime", this.runtime);
tag.putInt("predSuccess", this.predictionSuccess);
tag.putInt("failState", this.failState.ordinal());
tag.putInt("redstoneState", this.redstoneState.ordinal());
}

@Override
Expand All @@ -75,6 +78,7 @@ public void loadAdditional(CompoundTag tag, HolderLookup.Provider regs) {
this.runtime = tag.getInt("runtime");
this.predictionSuccess = tag.getInt("predSuccess");
this.failState = FailureState.values()[tag.getInt("failState")];
this.redstoneState = RedstoneState.values()[tag.getInt("redstoneState")];
}

@Override
Expand Down Expand Up @@ -102,33 +106,37 @@ public void serverTick(Level level, BlockPos pos, BlockState state) {
}
}
else if (this.hasPowerFor(this.currentModel.getModel())) {
this.failState = FailureState.NONE;
if (--this.runtime == 0) {
ItemStack stk = this.inventory.getStackInSlot(2);
if (stk.isEmpty()) this.inventory.setStackInSlot(2, this.currentModel.getModel().baseDrop().copy());
else stk.grow(1);
if (this.predictionSuccess > 0) {
stk = this.inventory.getStackInSlot(3);
if (stk.isEmpty()) {
this.inventory.setStackInSlot(3, this.currentModel.getPredictionDrop().copyWithCount(this.predictionSuccess));
if (this.getRedstoneState().matches(level.hasNeighborSignal(worldPosition))) {
this.failState = FailureState.NONE;
if (--this.runtime == 0) {
ItemStack stk = this.inventory.getStackInSlot(2);
if (stk.isEmpty()) this.inventory.setStackInSlot(2, this.currentModel.getModel().baseDrop().copy());
else stk.grow(1);
if (this.predictionSuccess > 0) {
stk = this.inventory.getStackInSlot(3);
if (stk.isEmpty()) {
this.inventory.setStackInSlot(3, this.currentModel.getPredictionDrop().copyWithCount(this.predictionSuccess));
}
else {
stk.grow(this.predictionSuccess);
}
}
else {
stk.grow(this.predictionSuccess);
ModelTier tier = this.currentModel.getTier();
if (!tier.isMax() && HostileConfig.simModelUpgrade > 0) {
int newData = this.currentModel.getData() + 1;
if (!(HostileConfig.simModelUpgrade == 2 && newData > this.currentModel.getNextTierData())) {
this.currentModel.setData(newData);
}
}
DataModelItem.setIters(model, DataModelItem.getIters(model) + 1);
this.setChanged();
}
ModelTier tier = this.currentModel.getTier();
if (!tier.isMax() && HostileConfig.simModelUpgrade > 0) {
int newData = this.currentModel.getData() + 1;
if (!(HostileConfig.simModelUpgrade == 2 && newData > this.currentModel.getNextTierData())) {
this.currentModel.setData(newData);
}
else if (this.runtime != 0) {
this.energy.setEnergy(this.energy.getEnergyStored() - this.currentModel.getModel().simCost());
this.setChanged();
}
DataModelItem.setIters(model, DataModelItem.getIters(model) + 1);
this.setChanged();
}
else if (this.runtime != 0) {
this.energy.setEnergy(this.energy.getEnergyStored() - this.currentModel.getModel().simCost());
this.setChanged();
} else {
this.failState = FailureState.REDSTONE;
}
}
else {
Expand All @@ -150,6 +158,11 @@ public boolean canStartSimulation() {
return false;
}

if (!this.redstoneState.matches(this.level.hasNeighborSignal(this.worldPosition))) {
this.failState = FailureState.REDSTONE;
return false;
}

DataModel model = this.currentModel.getModel();
ItemStack nOut = this.inventory.getStackInSlot(2);
ItemStack pOut = this.inventory.getStackInSlot(3);
Expand Down Expand Up @@ -216,6 +229,16 @@ public FailureState getFailState() {
return this.failState;
}

public void setRedstoneState(int ordinal) {
RedstoneState[] states = RedstoneState.values();
this.redstoneState = states.length <= ordinal ? RedstoneState.IGNORED : states[ordinal];
}

public RedstoneState getRedstoneState() {
return this.redstoneState;
}


public class SimItemHandler extends InternalItemHandler {

public SimItemHandler() {
Expand Down Expand Up @@ -259,7 +282,8 @@ public enum FailureState {
INPUT("input"),
MODEL("model"),
FAULTY("faulty"),
ENERGY_MID_CYCLE("energy_mid_cycle");
ENERGY_MID_CYCLE("energy_mid_cycle"),
REDSTONE("redstone");

private final String name;

Expand All @@ -272,4 +296,36 @@ public String getKey() {
}
}

public enum RedstoneState {

IGNORED("ignored", ResourceLocation.withDefaultNamespace("textures/item/redstone.png")),
OFF_WHEN_POWERED("off_when_powered", ResourceLocation.withDefaultNamespace("textures/block/redstone_torch_off.png")),
ON_WHEN_POWERED("on_when_powered", ResourceLocation.withDefaultNamespace("textures/block/redstone_torch.png"));

private final String name;
private final ResourceLocation texture;

RedstoneState(String name, ResourceLocation texture) {
this.name = name;
this.texture = texture;
}

public String getKey() {
return "hostilenetworks.gui.redstone." + name;
}

public ResourceLocation getResourceLocation() {
return texture;
}

public boolean matches(boolean power) {
return switch(this) {
case IGNORED -> true;
case OFF_WHEN_POWERED -> !power;
case ON_WHEN_POWERED -> power;
};
}

}

}
4 changes: 4 additions & 0 deletions src/main/resources/assets/hostilenetworks/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@
"hostilenetworks.gui.max_data": "I am at maximum potential",
"hostilenetworks.gui.variant": "%s (Variant)",
"hostilenetworks.gui.upgrade_disabled": "Models cannot be upgraded via kills.",
"hostilenetworks.gui.redstone.ignored": "Redstone: Ignored",
"hostilenetworks.gui.redstone.off_when_powered": "Redstone: Off When Powered",
"hostilenetworks.gui.redstone.on_when_powered": "Redstone: On When Powered",

"hostilenetworks.hud.model": " Model",
"hostilenetworks.hud.kills": "%s Remaining",
Expand All @@ -59,6 +62,7 @@
"hostilenetworks.fail.model": "Please insert a Data Model\nto begin the simulation",
"hostilenetworks.fail.faulty": "Insufficient data in model\nplease insert a basic model\nor better",
"hostilenetworks.fail.energy_mid_cycle": "Simulation progress paused\nSystem energy levels critical",
"hostilenetworks.fail.redstone": "Simulation progress paused\nIncorrect redstone signal applied",

"hostilenetworks.run.0": "> Launching runtime ",
"hostilenetworks.run.1": "> Iteration #%s started",
Expand Down