Skip to content

Commit

Permalink
Add compass wobble to unnatural dimensions
Browse files Browse the repository at this point in the history
  • Loading branch information
OreCruncher committed Jan 6, 2025
1 parent 4e847c9 commit 5920155
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class DimensionInfo {
protected int spaceHeight;
protected boolean alwaysOutside = false;
protected boolean playBiomeSounds = true;
protected boolean compassWobble = false;

DimensionInfo() {
this.name = ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "no_dimension");
Expand All @@ -37,6 +38,8 @@ public DimensionInfo(final Level world) {
// Force sea level based on known world types that give heartburn
if (this.isFlatWorld)
this.seaLevel = 0;

this.compassWobble = !world.dimensionType().natural();
}

public void update(DimensionConfigRule config) {
Expand All @@ -49,6 +52,8 @@ public void update(DimensionConfigRule config) {
v -> this.cloudHeight = v,
() -> this.cloudHeight = this.skyHeight / 2);

config.compassWobble().ifPresent(v -> this.compassWobble = v);

this.spaceHeight = this.skyHeight + SPACE_HEIGHT_OFFSET;
}
}
Expand Down Expand Up @@ -85,4 +90,8 @@ public boolean isFlatWorld() {
return this.isFlatWorld;
}

public boolean getCompassWobble() {
return this.compassWobble;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ public record DimensionConfigRule(
Optional<Integer> skyHeight,
Optional<Integer> cloudHeight,
Optional<Boolean> alwaysOutside,
Optional<Boolean> playBiomeSounds) {
Optional<Boolean> playBiomeSounds,
Optional<Boolean> compassWobble) {

public static final Codec<DimensionConfigRule> CODEC = RecordCodecBuilder.create((instance) -> instance.group(
ResourceLocation.CODEC.fieldOf("dimId").forGetter(DimensionConfigRule::dimensionId),
Codec.INT.optionalFieldOf("seaLevel").forGetter(DimensionConfigRule::seaLevel),
Codec.INT.optionalFieldOf("skyHeight").forGetter(DimensionConfigRule::skyHeight),
Codec.INT.optionalFieldOf("cloudHeight").forGetter(DimensionConfigRule::cloudHeight),
Codec.BOOL.optionalFieldOf("alwaysOutside").forGetter(DimensionConfigRule::alwaysOutside),
Codec.BOOL.optionalFieldOf("playBiomeSounds").forGetter(DimensionConfigRule::playBiomeSounds))
Codec.BOOL.optionalFieldOf("playBiomeSounds").forGetter(DimensionConfigRule::playBiomeSounds),
Codec.BOOL.optionalFieldOf("compassWobble").forGetter(DimensionConfigRule::compassWobble))
.apply(instance, DimensionConfigRule::new));

@Override
Expand All @@ -32,6 +34,7 @@ public String toString() {
this.cloudHeight.ifPresent(v -> builder.append(" cloudHeight: ").append(v));
this.alwaysOutside.ifPresent(v -> builder.append(" alwaysOutside: ").append(v));
this.playBiomeSounds.ifPresent(v -> builder.append(" playBiomeSounds: ").append(v));
this.compassWobble.ifPresent(v -> builder.append(" compassWobble: ").append(v));
return builder.toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,9 @@ public interface IDimensionInformation {
* The veritical Y level where clouds are expected to be
*/
int getCloudHeight();

/**
* Indicates whether the compass should "wobble" making the bearing unreadable
*/
boolean getCompassWobble();
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ public int getCloudHeight() {
return this.getInfo().getCloudHeight();
}

public boolean getCompassWobble() {
return this.getInfo().getCompassWobble();
}

private DimensionInfo getInfo() {
if (this.info == null)
this.info = this.dimensionLibrary.getData(this.level());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
import org.joml.Matrix4f;
import org.orecruncher.dsurround.Constants;
import org.orecruncher.dsurround.Configuration;
import org.orecruncher.dsurround.config.libraries.IDimensionInformation;
import org.orecruncher.dsurround.config.libraries.ITagLibrary;
import org.orecruncher.dsurround.lib.GameUtils;
import org.orecruncher.dsurround.lib.random.Randomizer;
import org.orecruncher.dsurround.tags.ItemEffectTags;

public class CompassOverlay extends AbstractOverlay {
Expand All @@ -30,14 +32,19 @@ public class CompassOverlay extends AbstractOverlay {
private static final ResourceLocation COMPASS_TEXTURE = ResourceLocation.fromNamespaceAndPath(Constants.MOD_ID, "textures/compass.png");

private final ITagLibrary tagLibrary;
private final IDimensionInformation dimensionInformation;
private final Configuration config;
private final CompassWobble wobbler;
private boolean showCompass;
private boolean spinRandomly;
private float scale;
private float spriteOffset;

public CompassOverlay(Configuration config, ITagLibrary tagLibrary) {
public CompassOverlay(Configuration config, ITagLibrary tagLibrary, IDimensionInformation dimensionInformation) {
this.tagLibrary = tagLibrary;
this.dimensionInformation = dimensionInformation;
this.config = config;
this.wobbler = new CompassWobble();
this.showCompass = false;
this.spriteOffset = this.config.compassAndClockOptions.compassStyle.getSpriteNumber();
this.scale = (float)this.config.compassAndClockOptions.scale;
Expand All @@ -53,14 +60,31 @@ public void tick(Minecraft client) {
var player = GameUtils.getPlayer().orElseThrow();
var mainHandItem = player.getMainHandItem();
var offHandItem = player.getOffhandItem();
this.showCompass = this.doShowCompass(mainHandItem) || this.doShowCompass(offHandItem);

var mainHandShow = this.doShowCompass(mainHandItem);
var offHandShow = this.doShowCompass(offHandItem);
this.showCompass = mainHandShow || offHandShow;

if (mainHandShow) {
this.spinRandomly = this.doCompassSpin(mainHandItem);
}

if (offHandShow && !this.spinRandomly) {
this.spinRandomly = this.doCompassSpin(offHandItem);
}

this.wobbler.update(player.level().getGameTime());
}
}

private boolean doShowCompass(ItemStack stack) {
return this.tagLibrary.is(ItemEffectTags.COMPASSES, stack);
}

private boolean doCompassSpin(ItemStack stack) {
return this.dimensionInformation.getCompassWobble() && this.tagLibrary.is(ItemEffectTags.COMPASS_WOBBLE, stack);
}

@Override
public void render(GuiGraphics context, float partialTick) {
if (!this.showCompass)
Expand All @@ -72,9 +96,16 @@ public void render(GuiGraphics context, float partialTick) {

matrixStack.pushPose();

final var player = GameUtils.getPlayer().orElseThrow();
float rotation;

int direction = Mth.floor(((player.getViewYRot(partialTick) * TEXTURE_SIZE) / 360F) + 0.5D) & (TEXTURE_SIZE - 1);
if (this.spinRandomly) {
rotation = this.wobbler.getRandomlySpinningRotation(partialTick);
} else {
final var player = GameUtils.getPlayer().orElseThrow();
rotation = player.getViewYRot(partialTick);
}

int direction = Mth.floor(((rotation * TEXTURE_SIZE) / 360F) + 0.5D) & (TEXTURE_SIZE - 1);
float x = (context.guiWidth() - BAND_WIDTH * this.scale) / 2F;
float y = (context.guiHeight() - CROSSHAIR_OFFSET - BAND_HEIGHT * this.scale) / 2F;

Expand Down Expand Up @@ -117,4 +148,56 @@ void drawTexturedQuad(PoseStack stack, ResourceLocation texture, float x1, float
if (mesh != null)
BufferUploader.drawWithShader(mesh);
}

/**
* Cloned from the Minecraft compass code
*/
static class CompassWobble {
private static int TICK_DELAY = 5;
private static float MAX_DELTA_TICK = 1F / 20F;
private float targetRotation;
private float lastRotation;
private float rotation;
private float rotationStep;
private long lastUpdateTick;
private int tickWait;

public float getRandomlySpinningRotation(float partialTick) {
return Mth.lerp(partialTick, this.lastRotation, this.rotation) * 360F;
}

public void update(long tickCount) {
if (this.lastUpdateTick != tickCount) {
this.updateRotation(tickCount);
}
}

private void updateRotation(long tickCount) {
this.lastUpdateTick = tickCount;
this.lastRotation = this.rotation;

if (this.rotation < this.targetRotation) {
this.rotation += this.rotationStep;
if (this.rotation > this.targetRotation) {
this.rotation = this.targetRotation;
}
} else if (this.rotation > this.targetRotation) {
this.rotation -= this.rotationStep;
if (this.rotation < this.targetRotation) {
this.rotation = this.targetRotation;
}
}

// If we reached the target rotation, we need to set a new one
// and calculate the stepping to get there.
if (this.rotation == this.targetRotation) {
if (this.tickWait < 0 ) {
this.tickWait = Randomizer.current().nextInt(TICK_DELAY);
} else if (--this.tickWait == 0) {
this.targetRotation = Randomizer.current().nextFloat();
this.rotationStep = MAX_DELTA_TICK;
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class ItemEffectTags {
public static final TagKey<Item> SWORDS = of("swords");
public static final TagKey<Item> TOOLS = of("tools");
public static final TagKey<Item> COMPASSES = of("compasses");
public static final TagKey<Item> COMPASS_WOBBLE = of("compass_wobble");
public static final TagKey<Item> CLOCKS = of("clocks");

private static TagKey<Item> of(String id) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"values": [
"minecraft:compass"
]
}

0 comments on commit 5920155

Please sign in to comment.