Pocket computer light color cycle

Slowly cycles between the orange NFC modem color, and the color set by the back peripheral if both are active.
This commit is contained in:
hugeblank 2024-01-19 23:36:02 -08:00
parent 0da145c91a
commit 5c67b6c0a5
10 changed files with 106 additions and 33 deletions

View File

@ -47,22 +47,40 @@ public interface IPocketAccess {
void setColour(int colour);
/**
* Get the colour of this pocket computer's light as a RGB number.
* Get the primary colour of this pocket computer's light as a RGB number.
*
* @return The colour this light is. This will be a RGB colour between {@code 0x000000} and {@code 0xFFFFFF} or
* @return The primary colour this light is. This will be a RGB colour between {@code 0x000000} and {@code 0xFFFFFF} or
* -1 if it has no colour.
* @see #setLight(int)
* @see #setLightPrimary(int)
*/
int getLight();
int getLightPrimary();
/**
* Set the colour of the pocket computer's light to a RGB number.
* Set the primary colour of the pocket computer's light to a RGB number.
*
* @param colour The colour this modem's light will be changed to. This should be a RGB colour between
* @param colour The primary colour this modem's light will be changed to. This should be a RGB colour between
* {@code 0x000000} and {@code 0xFFFFFF} or -1 to reset to the default colour.
* @see #getLight()
* @see #getLightPrimary()
*/
void setLight(int colour);
void setLightPrimary(int colour);
/**
* Get the secondary colour of this pocket computer's light as a RGB number.
*
* @return The secondary colour this light is. This will be a RGB colour between {@code 0x000000} and {@code 0xFFFFFF} or
* -1 if it has no colour.
* @see #setLightSecondary(int)
*/
int getLightSecondary();
/**
* Set the secondary colour of the pocket computer's light to a RGB number.
*
* @param colour The secondary colour this modem's light will be changed to. This should be a RGB colour between
* {@code 0x000000} and {@code 0xFFFFFF} or -1 to reset to the default colour.
* @see #getLightSecondary()
*/
void setLightSecondary(int colour);
/**
* Get the upgrade-specific NBT.

View File

@ -24,6 +24,10 @@ public static long getRenderFrame() {
return renderFrame;
}
public static int getTick() {
return tick;
}
public static void onTick() {
tick++;
}

View File

@ -67,9 +67,9 @@ public void handlePlayRecord(BlockPos pos, @Nullable SoundEvent sound, @Nullable
}
@Override
public void handlePocketComputerData(int instanceId, ComputerState state, int lightState, TerminalState terminal) {
public void handlePocketComputerData(int instanceId, ComputerState state, int primaryLightState, int secondaryLightState, TerminalState terminal) {
var computer = ClientPocketComputers.get(instanceId, terminal.colour);
computer.setState(state, lightState);
computer.setState(state, primaryLightState, secondaryLightState);
if (terminal.hasTerminal()) computer.setTerminal(terminal);
}

View File

@ -4,6 +4,7 @@
package dan200.computercraft.client.pocket;
import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.shared.computer.core.ComputerState;
import dan200.computercraft.shared.computer.terminal.NetworkedTerminal;
@ -24,14 +25,42 @@
public class PocketComputerData {
private final NetworkedTerminal terminal;
private ComputerState state = ComputerState.OFF;
private int lightColour = -1;
private int primaryLightColour = -1;
private int secondaryLightColour = -1;
public PocketComputerData(boolean colour) {
terminal = new NetworkedTerminal(Config.pocketTermWidth, Config.pocketTermHeight, colour);
}
public int getLightState() {
return state != ComputerState.OFF ? lightColour : -1;
if (state != ComputerState.OFF) {
if (secondaryLightColour == -1) {
return primaryLightColour;
} else if (primaryLightColour == -1) {
return secondaryLightColour;
} else {
double weight = ((Math.sin(((double)(FrameInfo.getTick() % 41) / 40)*Math.PI*2)+1)/2);
return blend(primaryLightColour, secondaryLightColour, weight);
}
}
return -1;
}
private static int blend(int a, int b, double weight) {
int[][] rgb = {
{ a >> 16, b >> 16 },
{ (a & 0x00ff00) >> 8, (b & 0x00ff00) >> 8 },
{ a & 0x0000ff, b & 0x0000ff }
};
int[] channels = new int[3];
for (int i = 0; i < 3; i++) {
channels[i] = (int)Math.sqrt((Math.pow(rgb[i][0], 2)*weight + Math.pow(rgb[i][1], 2)*(1-weight))/2);
}
int color = 0;
for (int channel : channels) {
color = (color << 8) + channel;
}
return color;
}
public Terminal getTerminal() {
@ -42,9 +71,10 @@ public ComputerState getState() {
return state;
}
public void setState(ComputerState state, int lightColour) {
public void setState(ComputerState state, int primaryLightColour, int secondaryLightColor) {
this.state = state;
this.lightColour = lightColour;
this.primaryLightColour = primaryLightColour;
this.secondaryLightColour = secondaryLightColor;
}
public void setTerminal(TerminalState state) {

View File

@ -30,7 +30,7 @@ public interface ClientNetworkContext {
void handlePlayRecord(BlockPos pos, @Nullable SoundEvent sound, @Nullable String name);
void handlePocketComputerData(int instanceId, ComputerState state, int lightState, TerminalState terminal);
void handlePocketComputerData(int instanceId, ComputerState state, int primaryLightColor, int secondaryLightColor, TerminalState terminal);
void handlePocketComputerDeleted(int instanceId);

View File

@ -19,20 +19,23 @@
public class PocketComputerDataMessage implements NetworkMessage<ClientNetworkContext> {
private final int instanceId;
private final ComputerState state;
private final int lightState;
private final int primaryLightState;
private final int secondaryLightState;
private final TerminalState terminal;
public PocketComputerDataMessage(PocketServerComputer computer, boolean sendTerminal) {
instanceId = computer.getInstanceID();
state = computer.getState();
lightState = computer.getLight();
primaryLightState = computer.getLightPrimary();
secondaryLightState = computer.getLightSecondary();
terminal = sendTerminal ? computer.getTerminalState() : new TerminalState((NetworkedTerminal) null);
}
public PocketComputerDataMessage(FriendlyByteBuf buf) {
instanceId = buf.readVarInt();
state = buf.readEnum(ComputerState.class);
lightState = buf.readVarInt();
primaryLightState = buf.readVarInt();
secondaryLightState = buf.readVarInt();
terminal = new TerminalState(buf);
}
@ -40,13 +43,14 @@ public PocketComputerDataMessage(FriendlyByteBuf buf) {
public void write(FriendlyByteBuf buf) {
buf.writeVarInt(instanceId);
buf.writeEnum(state);
buf.writeVarInt(lightState);
buf.writeVarInt(primaryLightState);
buf.writeVarInt(secondaryLightState);
terminal.write(buf);
}
@Override
public void handle(ClientNetworkContext context) {
context.handlePocketComputerData(instanceId, state, lightState, terminal);
context.handlePocketComputerData(instanceId, state, primaryLightState, secondaryLightState, terminal);
}
@Override

View File

@ -38,8 +38,10 @@ public class PocketServerComputer extends ServerComputer implements IPocketAcces
private @Nullable Entity entity;
private ItemStack stack = ItemStack.EMPTY;
private int lightColour = -1;
private boolean lightChanged = false;
private int primaryLightColour = -1;
private boolean primaryLightChanged = false;
private int secondaryLightColour = -1;
private boolean secondaryLightChanged = false;
private final Set<ServerPlayer> tracking = new HashSet<>();
@ -77,17 +79,31 @@ public void setColour(int colour) {
}
@Override
public int getLight() {
return lightColour;
public int getLightPrimary() {
return primaryLightColour;
}
@Override
public void setLight(int colour) {
public void setLightPrimary(int colour) {
if (colour < 0 || colour > 0xFFFFFF) colour = -1;
if (lightColour == colour) return;
lightColour = colour;
lightChanged = true;
if (primaryLightColour == colour) return;
primaryLightColour = colour;
primaryLightChanged = true;
}
@Override
public int getLightSecondary() {
return secondaryLightColour;
}
@Override
public void setLightSecondary(int colour) {
if (colour < 0 || colour > 0xFFFFFF) colour = -1;
if (secondaryLightColour == colour) return;
secondaryLightColour = colour;
secondaryLightChanged = true;
}
@Override
@ -161,8 +177,9 @@ public void tickServer() {
tracking.removeIf(player -> !player.isAlive() || player.level() != getLevel());
// And now find any new players, add them to the tracking list, and broadcast state where appropriate.
var sendState = hasOutputChanged() || lightChanged;
lightChanged = false;
var sendState = hasOutputChanged() || primaryLightChanged || secondaryLightChanged;
primaryLightChanged = false;
secondaryLightChanged = false;
if (sendState) {
// Broadcast the state to all players
tracking.addAll(getLevel().players());

View File

@ -34,6 +34,6 @@ public void update(IPocketAccess access, @Nullable IPeripheral peripheral) {
modem.setLocation(access);
var state = modem.getModemState();
if (state.pollChanged()) access.setLight(state.isOpen() ? 0xBA0000 : -1);
if (state.pollChanged()) access.setLightPrimary(state.isOpen() ? 0xBA0000 : -1);
}
}

View File

@ -25,7 +25,7 @@ public void update(IPocketAccess access) {
setLocation(access);
var state = getModemState();
if (state.pollChanged()) access.setLight(state.isOpen() ? 0xf39d20 : -1);
if (state.pollChanged()) access.setLightSecondary(state.isOpen() ? 0xf39d20 : -1);
}
@Override

View File

@ -43,6 +43,6 @@ public void update() {
super.update();
access.setLight(madeSound() ? 0x3320fc : -1);
access.setLightPrimary(madeSound() ? 0x3320fc : -1);
}
}