Skip to content

Commit

Permalink
Add config with volume and LOD options, add server data for upcoming …
Browse files Browse the repository at this point in the history
…radar feature
  • Loading branch information
FoundationGames committed Jul 29, 2023
1 parent 2e7ace2 commit 37999d1
Show file tree
Hide file tree
Showing 24 changed files with 367 additions and 35 deletions.
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ group = project.maven_group

repositories {
maven { url "https://api.modrinth.com/maven" }
maven { url = 'https://maven.terraformersmc.com/' }
}

dependencies {
Expand All @@ -23,6 +24,8 @@ dependencies {

modImplementation "maven.modrinth:jsonem:${project.jsonem_version}"
include "maven.modrinth:jsonem:${project.jsonem_version}"

modApi("com.terraformersmc:modmenu:${project.modmenu_version}") { transitive false }
}

processResources {
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ loader_version=0.14.21
#Fabric api
fabric_version=0.84.0+1.20.1

mod_version = 1.0.0-beta.4
mod_version = 1.0.0-beta.5
maven_group = io.github.foundationgames
archives_base_name = phonos

jsonem_version=0.2.1+1.20

modmenu_version=7.1.0
4 changes: 0 additions & 4 deletions src/main/java/io/github/foundationgames/phonos/Phonos.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,4 @@ public void onInitialize() {
public static Identifier id(String path) {
return new Identifier("phonos", path);
}

public static float getPhonosVolume() {
return 1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.github.foundationgames.phonos.client.render.block.RadioLoudspeakerBlockEntityRenderer;
import io.github.foundationgames.phonos.client.render.block.RadioTransceiverBlockEntityRenderer;
import io.github.foundationgames.phonos.client.render.block.SatelliteStationBlockEntityRenderer;
import io.github.foundationgames.phonos.config.PhonosClientConfig;
import io.github.foundationgames.phonos.item.AudioCableItem;
import io.github.foundationgames.phonos.item.PhonosItems;
import io.github.foundationgames.phonos.network.ClientPayloadPackets;
Expand Down Expand Up @@ -37,6 +38,8 @@ public class PhonosClient implements ClientModInitializer {

@Override
public void onInitializeClient() {
PhonosClientConfig.get(); // Load if not already

ClientPayloadPackets.initClient();
ClientSoundStorage.initClient();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.github.foundationgames.phonos.block.entity.RadioTransceiverBlockEntity;
import io.github.foundationgames.phonos.util.PhonosUtil;
import io.github.foundationgames.phonos.world.RadarPoints;
import io.github.foundationgames.phonos.world.sound.block.BlockConnectionLayout;
import io.github.foundationgames.phonos.world.sound.block.InputBlock;
import net.minecraft.block.*;
Expand All @@ -11,6 +12,7 @@
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.StateManager;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
Expand Down Expand Up @@ -148,6 +150,23 @@ public void setInputPluggedIn(int inputIndex, boolean pluggedIn, BlockState stat
if (world.getBlockEntity(pos) instanceof RadioTransceiverBlockEntity be) {
inputIndex = MathHelper.clamp(inputIndex, 0, be.inputs.length - 1);
be.inputs[inputIndex] = pluggedIn;

if (world instanceof ServerWorld sWorld) {
if (pluggedIn) {
RadarPoints.get(sWorld).add(be.getChannel(), pos);
} else {
boolean remove = true;
for (boolean in : be.inputs) if (in) {
remove = false;
break;
}

if (remove) {
RadarPoints.get(sWorld).remove(be.getChannel(), pos);
}
}
}

be.sync();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public void tick(World world, BlockPos pos, BlockState state) {
if (!world.isClient()) {
if (this.outputs.purge(conn -> this.outputs.dropConnectionItem(world, conn, true))) {
sync();
markDirty();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ public void tick(World world, BlockPos pos, BlockState state) {

if (this.outputs.purge(conn -> this.outputs.dropConnectionItem(world, conn, true))) {
sync();
markDirty();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
import io.github.foundationgames.phonos.block.RadioTransceiverBlock;
import io.github.foundationgames.phonos.radio.RadioDevice;
import io.github.foundationgames.phonos.radio.RadioStorage;
import io.github.foundationgames.phonos.world.RadarPoints;
import io.github.foundationgames.phonos.world.sound.InputPlugPoint;
import io.github.foundationgames.phonos.world.sound.block.BlockConnectionLayout;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.state.property.Properties;
import net.minecraft.util.DyeColor;
import net.minecraft.util.math.BlockPos;
Expand Down Expand Up @@ -112,6 +114,12 @@ public Direction getRotation() {
public void setAndUpdateChannel(int channel) {
channel = Math.floorMod(channel, RadioStorage.CHANNEL_COUNT);

if (this.world instanceof ServerWorld sWorld) for (boolean in : this.inputs) if (in) {
RadarPoints.get(sWorld).remove(this.channel, this.pos);
RadarPoints.get(sWorld).add(channel, this.pos);
break;
}

var radio = RadioStorage.getInstance(this.world);

radio.removeReceivingEmitter(this.channel, this.emitterId());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package io.github.foundationgames.phonos.client.render;

import io.github.foundationgames.phonos.config.PhonosClientConfig;
import io.github.foundationgames.phonos.util.PhonosUtil;
import io.github.foundationgames.phonos.util.Pose3f;
import io.github.foundationgames.phonos.world.sound.WireConnection;
import io.github.foundationgames.phonos.world.sound.WirePlugPoint;
import io.github.foundationgames.phonos.world.sound.CableConnection;
import io.github.foundationgames.phonos.world.sound.CablePlugPoint;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.model.Model;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.WorldRenderer;
Expand All @@ -17,7 +19,7 @@

import java.util.function.Consumer;

public class ConnectionRenderer {
public class CableRenderer {
private static final Quaternionf rotationCache = new Quaternionf();
private static final BlockPos.Mutable lightPos = new BlockPos.Mutable();

Expand Down Expand Up @@ -62,7 +64,7 @@ private static void lerpCableEnd(Vector4f[] out, Vector4f[] begin, Vector4f[] en
}
}

public static void renderConnection(World world, WireConnection conn, MatrixStack matrices, VertexConsumer buffer, Model cableEndModel, int overlay, float tickDelta) {
public static void renderConnection(PhonosClientConfig config, World world, CableConnection conn, MatrixStack matrices, VertexConsumer buffer, Model cableEndModel, int overlay, float tickDelta) {
int startLight, endLight;

matrices.push();
Expand Down Expand Up @@ -91,7 +93,20 @@ public static void renderConnection(World world, WireConnection conn, MatrixStac
float g = conn.color != null ? conn.color.getColorComponents()[1] : 1;
float b = conn.color != null ? conn.color.getColorComponents()[2] : 1;
float length = cableStPt.distance(cableEnPt);
int segments = (int) Math.ceil(4 * length);
int segments = Math.max((int) Math.ceil(4 * length * config.cableLODNearDetail), 1);

if (config.cableLODs) {
float cx = (cableStPt.x + cableEnPt.x) * 0.5f;
float cy = (cableStPt.y + cableEnPt.y) * 0.5f;
float cz = (cableStPt.z + cableEnPt.z) * 0.5f;

double sqDist = MinecraftClient.getInstance().gameRenderer.getCamera().getPos()
.squaredDistanceTo(cx, cy, cz);
double delta = MathHelper.clamp(sqDist / (length * length * 4), 0, 1);
double detail = MathHelper.lerp(delta, config.cableLODNearDetail, config.cableLODFarDetail);

segments = Math.max((int) Math.ceil(4 * length * detail), Math.min(3, segments));
}

cableRotAxis.set(cableEnPt.z - cableStPt.z, 0, cableEnPt.x - cableStPt.x);

Expand Down Expand Up @@ -162,7 +177,7 @@ public static void renderConnection(World world, WireConnection conn, MatrixStac
private static final Pose3f tcp_endPose = new Pose3f(new Vector3f(), new Quaternionf());
private static final Quaternionf tcp_rot = new Quaternionf();
private static final Vector4f tcp_vec4a = new Vector4f();
private static void transformConnPoint(World world, WirePlugPoint point, MatrixStack matrices, Vector3f connPos, float tickDelta) {
private static void transformConnPoint(World world, CablePlugPoint point, MatrixStack matrices, Vector3f connPos, float tickDelta) {
connPos.set(0, 0, 0);

point.writeOriginPose(world, tickDelta, tcp_originPose);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import io.github.foundationgames.phonos.Phonos;
import io.github.foundationgames.phonos.PhonosClient;
import io.github.foundationgames.phonos.client.model.BasicModel;
import io.github.foundationgames.phonos.client.render.ConnectionRenderer;
import io.github.foundationgames.phonos.client.render.CableRenderer;
import io.github.foundationgames.phonos.config.PhonosClientConfig;
import io.github.foundationgames.phonos.world.sound.block.OutputBlockEntity;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.render.VertexConsumerProvider;
Expand All @@ -23,12 +24,13 @@ public CableOutputBlockEntityRenderer(BlockEntityRendererFactory.Context ctx) {
@Override
public void render(E entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) {
var buffer = vertexConsumers.getBuffer(cableEndModel.getLayer(TEXTURE));
var config = PhonosClientConfig.get();

matrices.push();
matrices.translate(-entity.getPos().getX(), -entity.getPos().getY(), -entity.getPos().getZ());

entity.getOutputs().forEach((i, conn) ->
ConnectionRenderer.renderConnection(entity.getWorld(), conn, matrices, buffer, cableEndModel, overlay, tickDelta));
CableRenderer.renderConnection(config, entity.getWorld(), conn, matrices, buffer, cableEndModel, overlay, tickDelta));

matrices.pop();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package io.github.foundationgames.phonos.config;

import com.google.gson.Gson;
import io.github.foundationgames.phonos.Phonos;
import net.fabricmc.loader.api.FabricLoader;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class PhonosClientConfig {
private static PhonosClientConfig config = null;

public double phonosMasterVolume = 1;
public double streamVolume = 1;

public boolean cableLODs = true;
public double cableLODNearDetail = 1;
public double cableLODFarDetail = 0.25;

public PhonosClientConfig() {
}

public PhonosClientConfig copyTo(PhonosClientConfig copy) {
for (var f : PhonosClientConfig.class.getDeclaredFields()) {
try {
f.set(copy, f.get(this));
} catch (IllegalAccessException ignored) {}
}

return copy;
}

public static PhonosClientConfig get() {
if (config == null) {
config = new PhonosClientConfig();

try {
config.load();
} catch (IOException ex) {
Phonos.LOG.error("Error loading Phonos client config!", ex);
}
}

return config;
}

private static Path configPath() {
return FabricLoader.getInstance().getConfigDir().resolve("phonos.json");
}

public void load() throws IOException {
var path = configPath();

try (var in = Files.newBufferedReader(path)) {
var fileCfg = new Gson().fromJson(in, PhonosClientConfig.class);
fileCfg.copyTo(this);
}
}

public void save() throws IOException {
var path = configPath();

var gson = new Gson();
try (var writer = gson.newJsonWriter(Files.newBufferedWriter(path))) {
writer.setIndent(" ");

gson.toJson(gson.toJsonTree(this, PhonosClientConfig.class), writer);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package io.github.foundationgames.phonos.config;

import io.github.foundationgames.phonos.Phonos;
import it.unimi.dsi.fastutil.booleans.BooleanConsumer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.OptionListWidget;
import net.minecraft.client.option.GameOptions;
import net.minecraft.client.option.SimpleOption;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;

public class PhonosClientConfigScreen extends Screen {
private static final Text TITLE = Text.translatable("text.config.phonos.title");

private final Screen parent;
private final List<SimpleOption<?>> options = new ArrayList<>();
private final Runnable save;

public PhonosClientConfigScreen(Screen parent, Runnable save) {
super(TITLE);

this.parent = parent;
this.save = save;
}

public static PhonosClientConfigScreen create(PhonosClientConfig config, Screen parent) {
var copy = config.copyTo(new PhonosClientConfig());

var screen = new PhonosClientConfigScreen(parent, () -> {
copy.copyTo(config);
try {
config.save();
} catch (IOException e) {
Phonos.LOG.error("Could not save config!", e);
}
});

screen.addPercentage("phonosMasterVolume", val -> copy.phonosMasterVolume = val, copy.phonosMasterVolume);
screen.addPercentage("streamVolume", val -> copy.streamVolume = val, copy.streamVolume);
screen.addBoolean("cableLODs", val -> copy.cableLODs = val, copy.cableLODs);
screen.addPercentage("cableLODNearDetail", val -> copy.cableLODNearDetail = val, copy.cableLODNearDetail);
screen.addPercentage("cableLODFarDetail", val -> copy.cableLODFarDetail = val, copy.cableLODFarDetail);

return screen;
}

public void addBoolean(String key, BooleanConsumer setter, boolean currentValue) {
this.options.add(SimpleOption.ofBoolean("text.config.phonos.option." + key, currentValue, setter));
}

public void addPercentage(String key, DoubleConsumer setter, double currentValue) {
addIntRange(key, val -> setter.accept(val * 0.01D), (int)(currentValue * 100), 0, 100);
}

public void addIntRange(String key, IntConsumer setter, int currentValue, int min, int max) {
this.options.add(new SimpleOption<>("text.config.phonos.option." + key,
SimpleOption.emptyTooltip(),
(optionText, value) -> GameOptions.getGenericValueText(optionText, Text.literal(value.toString())),
new SimpleOption.ValidatingIntSliderCallbacks(min, max),
currentValue, setter::accept)
);
}

public void close() {
this.client.setScreen(this.parent);
}

@Override
protected void init() {
var buttons = new OptionListWidget(this.client, this.width, this.height, 32, this.height - 32, 25);
for (SimpleOption<?> option : this.options) {
buttons.addSingleOptionEntry(option);
}
this.addDrawableChild(buttons);

this.addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, (button) -> {
this.save.run();
this.close();
}).dimensions(this.width / 2 + 2, this.height - 27, 150, 20).build());

this.addDrawableChild(ButtonWidget.builder(ScreenTexts.CANCEL, (button) -> this.close())
.dimensions(this.width / 2 - 152, this.height - 27, 150, 20).build());
}

@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);

context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 13, 0xFFFFFF);
}
}
Loading

0 comments on commit 37999d1

Please sign in to comment.