Merge pull request #171 from BoogieMonster1O1/1.16-fabric
Fix blocks and the config
This commit is contained in:
commit
c062ae508b
32 changed files with 583 additions and 275 deletions
|
@ -34,6 +34,12 @@ dependencies {
|
|||
include("io.github.boogiemonster1o1:libcbe:${libcbe_version}") // Includes LibCBE as a Jar-in-Jar embedded dependency
|
||||
modImplementation("curse.maven:worldedit:3039223") // For saving schematics
|
||||
modImplementation("curse.maven:wecui:2995033") // Cos why not
|
||||
modCompileOnly("io.github.prospector:modmenu:1.14.6+build.31") {
|
||||
exclude module: "fabric-api"
|
||||
}
|
||||
modRuntime("io.github.prospector:modmenu:1.14.6+build.31") {
|
||||
exclude module: "fabric-api"
|
||||
}
|
||||
}
|
||||
|
||||
version "4.0.0+alpha.3"
|
||||
|
|
|
@ -2,7 +2,7 @@ minecraft_version=1.16.3
|
|||
yarn_mappings=1.16.3+build.1
|
||||
loader_version=0.9.3+build.207
|
||||
|
||||
fabric_version=0.20.2+build.402-1.16
|
||||
fabric_version=0.21.0+build.407-1.16
|
||||
|
||||
libcbe_version = 1.1.0
|
||||
|
||||
|
|
|
@ -66,6 +66,8 @@ public class DimensionalDoorsInitializer implements ModInitializer {
|
|||
ModSoundEvents.init();
|
||||
ModFeatures.init();
|
||||
|
||||
ModConfig.deserialize();
|
||||
|
||||
Targets.registerDefaultTargets();
|
||||
|
||||
SchematicHandler.INSTANCE.loadSchematics();
|
||||
|
|
|
@ -1,18 +1,89 @@
|
|||
package org.dimdev.dimdoors;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.util.Codecs;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
public final class ModConfig {
|
||||
public static final General GENERAL = new General();
|
||||
public static final Pockets POCKETS = new Pockets();
|
||||
public static final World WORLD = new World();
|
||||
public static final Dungeons DUNGEONS = new Dungeons();
|
||||
public static final Monoliths MONOLITHS = new Monoliths();
|
||||
public static final Limbo LIMBO = new Limbo();
|
||||
public static final Graphics GRAPHICS = new Graphics();
|
||||
public static ModConfig INSTANCE;
|
||||
private static final Path CONFIG_PATH;
|
||||
private static final Codec<ModConfig> CODEC;
|
||||
private static final String DEFAULT;
|
||||
private static final ModConfig FALLBACK;
|
||||
private static final Logger LOGGER;
|
||||
private final General general;
|
||||
private final Pockets pockets;
|
||||
private final World world;
|
||||
private final Dungeons dungeons;
|
||||
private final Monoliths monoliths;
|
||||
private final Limbo limbo;
|
||||
private final Graphics graphics;
|
||||
|
||||
protected ModConfig(General general, Pockets pockets, World world, Dungeons dungeons, Monoliths monoliths, Limbo limbo, Graphics graphics) {
|
||||
this.general = general;
|
||||
this.pockets = pockets;
|
||||
this.world = world;
|
||||
this.dungeons = dungeons;
|
||||
this.monoliths = monoliths;
|
||||
this.limbo = limbo;
|
||||
this.graphics = graphics;
|
||||
}
|
||||
|
||||
public General getGeneralConfig() {
|
||||
return this.general;
|
||||
}
|
||||
|
||||
public Pockets getPocketsConfig() {
|
||||
return this.pockets;
|
||||
}
|
||||
|
||||
public World getWorldConfig() {
|
||||
return this.world;
|
||||
}
|
||||
|
||||
public Dungeons getDungeonsConfig() {
|
||||
return this.dungeons;
|
||||
}
|
||||
|
||||
public Monoliths getMonolithsConfig() {
|
||||
return this.monoliths;
|
||||
}
|
||||
|
||||
public Limbo getLimboConfig() {
|
||||
return this.limbo;
|
||||
}
|
||||
|
||||
public Graphics getGraphicsConfig() {
|
||||
return this.graphics;
|
||||
}
|
||||
|
||||
public static class General {
|
||||
public static final Codec<General> CODEC = RecordCodecBuilder.create((instance) -> instance.group(
|
||||
Codec.BOOL.fieldOf("closeDoorBehind").forGetter((general) -> general.closeDoorBehind),
|
||||
Codec.DOUBLE.fieldOf("teleportOffset").forGetter((general) -> general.teleportOffset),
|
||||
Codec.BOOL.fieldOf("riftBoundingBoxInCreative").forGetter((general) -> general.riftBoundingBoxInCreative),
|
||||
Codec.DOUBLE.fieldOf("riftCloseSpeed").forGetter((general) -> general.riftCloseSpeed),
|
||||
Codec.DOUBLE.fieldOf("riftGrowthSpeed").forGetter((general) -> general.riftGrowthSpeed),
|
||||
Codec.INT.fieldOf("depthSpreadFactor").forGetter((general) -> general.depthSpreadFactor),
|
||||
Codec.BOOL.fieldOf("useEnderPearlsInCrafting").forGetter((general) -> general.useEnderPearlsInCrafting),
|
||||
Codec.DOUBLE.fieldOf("endermanSpawnChance").forGetter((general) -> general.endermanSpawnChance),
|
||||
Codec.DOUBLE.fieldOf("endermanAggressiveChance").forGetter((general) -> general.endermanAggressiveChance)
|
||||
).apply(instance, General::create));
|
||||
|
||||
public boolean closeDoorBehind = false;
|
||||
public double teleportOffset = 0.5;
|
||||
public boolean riftBoundingBoxInCreative;
|
||||
|
@ -22,43 +93,191 @@ public final class ModConfig {
|
|||
public boolean useEnderPearlsInCrafting = false;
|
||||
public double endermanSpawnChance = 0.001;
|
||||
public double endermanAggressiveChance = 0.5;
|
||||
|
||||
public static General create(boolean closeDoorBehind, double teleportOffset, boolean riftBoundingBoxInCreative, double riftCloseSpeed, double riftGrowthSpeed, int depthSpreadFactor, boolean useEnderPearlsInCrafting, double endermanSpawnChance, double endermanAggressiveChance) {
|
||||
General general = new General();
|
||||
general.closeDoorBehind = closeDoorBehind;
|
||||
general.teleportOffset = teleportOffset;
|
||||
general.riftBoundingBoxInCreative = riftBoundingBoxInCreative;
|
||||
general.riftCloseSpeed = riftCloseSpeed;
|
||||
general.riftGrowthSpeed = riftGrowthSpeed;
|
||||
general.depthSpreadFactor = depthSpreadFactor;
|
||||
general.useEnderPearlsInCrafting = useEnderPearlsInCrafting;
|
||||
general.endermanSpawnChance = endermanSpawnChance;
|
||||
general.endermanAggressiveChance = endermanAggressiveChance;
|
||||
return general;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Pockets {
|
||||
public static final Codec<Pockets> CODEC = RecordCodecBuilder.create((instance) -> instance.group(
|
||||
Codec.INT.fieldOf("pocketGridSize").forGetter((pockets) -> pockets.pocketGridSize),
|
||||
Codec.INT.fieldOf("maxPocketSize").forGetter((pockets) -> pockets.maxPocketSize),
|
||||
Codec.INT.fieldOf("privatePocketSize").forGetter((pockets) -> pockets.privatePocketSize),
|
||||
Codec.INT.fieldOf("publicPocketSize").forGetter((pockets) -> pockets.publicPocketSize),
|
||||
Codec.BOOL.fieldOf("loadAllSchematics").forGetter((pockets) -> pockets.loadAllSchematics),
|
||||
Codec.INT.fieldOf("cachedSchematics").forGetter((pockets) -> pockets.cachedSchematics)
|
||||
).apply(instance, Pockets::create));
|
||||
public int pocketGridSize = 32;
|
||||
public int maxPocketSize = 15;
|
||||
public int privatePocketSize = 2;
|
||||
public int publicPocketSize = 1;
|
||||
public boolean loadAllSchematics = false;
|
||||
public int cachedSchematics = 10;
|
||||
|
||||
public static Pockets create(int pocketGridSize, int maxPocketSize, int privatePocketSize, int publicPocketSize, boolean loadAllSchematics, int cachedSchematics) {
|
||||
Pockets pockets = new Pockets();
|
||||
pockets.pocketGridSize = pocketGridSize;
|
||||
pockets.maxPocketSize = maxPocketSize;
|
||||
pockets.privatePocketSize = privatePocketSize;
|
||||
pockets.publicPocketSize = publicPocketSize;
|
||||
pockets.loadAllSchematics = loadAllSchematics;
|
||||
pockets.cachedSchematics = cachedSchematics;
|
||||
return pockets;
|
||||
}
|
||||
}
|
||||
|
||||
public static class World {
|
||||
public static final Codec<World> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
Codec.DOUBLE.fieldOf("clusterGenChance").forGetter((world) -> world.clusterGenChance),
|
||||
Codec.INT.fieldOf("gatewayGenChance").forGetter((world) -> world.gatewayGenChance),
|
||||
Codecs.INT_SET.fieldOf("clusterDimBlacklist").forGetter((world) -> world.clusterDimBlacklist),
|
||||
Codecs.INT_SET.fieldOf("gatewayDimBlacklist").forGetter((world) -> world.gatewayDimBlacklist)
|
||||
).apply(instance, World::create));
|
||||
public double clusterGenChance = 0.0002;
|
||||
public int gatewayGenChance = 80;
|
||||
public Set<Integer> clusterDimBlacklist = new LinkedHashSet<>();
|
||||
public Set<Integer> gatewayDimBlacklist = new LinkedHashSet<>();
|
||||
|
||||
public static World create(double clusterGenChance, int gatewayGenChance, Set<Integer> clusterDimBlacklist, Set<Integer> gatewayDimBlacklist) {
|
||||
World world = new World();
|
||||
world.clusterGenChance = clusterGenChance;
|
||||
world.gatewayGenChance = gatewayGenChance;
|
||||
world.clusterDimBlacklist = clusterDimBlacklist;
|
||||
world.gatewayDimBlacklist = gatewayDimBlacklist;
|
||||
return world;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Dungeons {
|
||||
public static final Codec<Dungeons> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
Codec.INT.fieldOf("maxDungeonDepth").forGetter((dungeons) -> dungeons.maxDungeonDepth)
|
||||
).apply(instance, Dungeons::create));
|
||||
public int maxDungeonDepth = 50;
|
||||
|
||||
public static Dungeons create(int maxDungeonDepth) {
|
||||
Dungeons dungeons = new Dungeons();
|
||||
dungeons.maxDungeonDepth = maxDungeonDepth;
|
||||
return dungeons;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Monoliths {
|
||||
public static final Codec<Monoliths> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
Codec.BOOL.fieldOf("dangerousLimboMonoliths").forGetter((monoliths) -> monoliths.dangerousLimboMonoliths),
|
||||
Codec.BOOL.fieldOf("monolithTeleportation").forGetter((monoliths) -> monoliths.monolithTeleportation)
|
||||
).apply(instance, Monoliths::create));
|
||||
public boolean dangerousLimboMonoliths = false;
|
||||
public boolean monolithTeleportation = true;
|
||||
|
||||
public static Monoliths create(boolean dangerousLimboMonoliths, boolean monolithTeleportation) {
|
||||
Monoliths monoliths = new Monoliths();
|
||||
monoliths.dangerousLimboMonoliths = dangerousLimboMonoliths;
|
||||
monoliths.monolithTeleportation = monolithTeleportation;
|
||||
return monoliths;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Limbo {
|
||||
public static final Codec<Limbo> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
Codec.BOOL.fieldOf("universalLimbo").forGetter((limbo) -> limbo.universalLimbo),
|
||||
Codec.BOOL.fieldOf("hardcoreLimbo").forGetter((limbo) -> limbo.hardcoreLimbo),
|
||||
Codec.DOUBLE.fieldOf("decaySpreadChance").forGetter((limbo) -> limbo.decaySpreadChance)
|
||||
).apply(instance, Limbo::create));
|
||||
public boolean universalLimbo = false;
|
||||
public boolean hardcoreLimbo = false;
|
||||
public double decaySpreadChance = 0.5;
|
||||
|
||||
public static Limbo create(boolean universalLimbo, boolean hardcoreLimbo, double decaySpreadChance) {
|
||||
Limbo limbo = new Limbo();
|
||||
limbo.universalLimbo = universalLimbo;
|
||||
limbo.hardcoreLimbo = hardcoreLimbo;
|
||||
limbo.decaySpreadChance = decaySpreadChance;
|
||||
return limbo;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Graphics {
|
||||
public static final Codec<Graphics> CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
Codec.BOOL.fieldOf("showRiftCore").forGetter((graphics) -> graphics.showRiftCore),
|
||||
Codec.INT.fieldOf("highlightRiftCoreFor").forGetter((graphics) -> graphics.highlightRiftCoreFor),
|
||||
Codec.DOUBLE.fieldOf("riftSize").forGetter((graphics) -> graphics.riftSize),
|
||||
Codec.DOUBLE.fieldOf("riftJitter").forGetter((graphics) -> graphics.riftJitter)
|
||||
).apply(instance, Graphics::create));
|
||||
public boolean showRiftCore = false;
|
||||
public int highlightRiftCoreFor = 15000;
|
||||
public double riftSize = 1;
|
||||
public double riftJitter = 1;
|
||||
|
||||
public static Graphics create(boolean showRiftCore, int highlightRiftCoreFor, double riftSize, double riftJitter) {
|
||||
Graphics graphics = new Graphics();
|
||||
graphics.showRiftCore = showRiftCore;
|
||||
graphics.highlightRiftCoreFor = highlightRiftCoreFor;
|
||||
graphics.riftSize = riftSize;
|
||||
graphics.riftJitter = riftJitter;
|
||||
return graphics;
|
||||
}
|
||||
}
|
||||
|
||||
public static int deserialize() {
|
||||
try {
|
||||
if (Files.isDirectory(CONFIG_PATH)) {
|
||||
Files.delete(CONFIG_PATH);
|
||||
}
|
||||
if (!Files.exists(CONFIG_PATH)) {
|
||||
Files.createFile(CONFIG_PATH);
|
||||
Files.write(CONFIG_PATH, DEFAULT.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
INSTANCE = CODEC.decode(
|
||||
JsonOps.INSTANCE, new JsonParser().parse(
|
||||
new InputStreamReader(
|
||||
Files.newInputStream(CONFIG_PATH)
|
||||
)
|
||||
).getAsJsonObject()
|
||||
).getOrThrow(false, System.err::println).getFirst();
|
||||
return 1;
|
||||
} catch (IOException e) {
|
||||
System.err.println("An Unexpected error occured when deserializing the Config. Using default values for now.");
|
||||
e.printStackTrace();
|
||||
INSTANCE = FALLBACK;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
General.CODEC.fieldOf("general").forGetter(ModConfig::getGeneralConfig),
|
||||
Pockets.CODEC.fieldOf("pockets").forGetter(ModConfig::getPocketsConfig),
|
||||
World.CODEC.fieldOf("world").forGetter(ModConfig::getWorldConfig),
|
||||
Dungeons.CODEC.fieldOf("dungeons").forGetter(ModConfig::getDungeonsConfig),
|
||||
Monoliths.CODEC.fieldOf("monoliths").forGetter(ModConfig::getMonolithsConfig),
|
||||
Limbo.CODEC.fieldOf("limbo").forGetter(ModConfig::getLimboConfig),
|
||||
Graphics.CODEC.fieldOf("graphics").forGetter(ModConfig::getGraphicsConfig)
|
||||
).apply(instance, ModConfig::new));
|
||||
CONFIG_PATH = FabricLoader.getInstance().getConfigDir().resolve("dimensional_doors.json");
|
||||
FALLBACK = new ModConfig(
|
||||
new General(),
|
||||
new Pockets(),
|
||||
new World(),
|
||||
new Dungeons(),
|
||||
new Monoliths(),
|
||||
new Limbo(),
|
||||
new Graphics()
|
||||
);
|
||||
INSTANCE = FALLBACK;
|
||||
DEFAULT = CODEC.encodeStart(JsonOps.INSTANCE, INSTANCE)
|
||||
.getOrThrow(false, System.err::println)
|
||||
.toString();
|
||||
LOGGER = LogManager.getLogger();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,63 +42,63 @@ public class DetachedRiftBlockEntity extends RiftBlockEntity implements Tickable
|
|||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (world == null) {
|
||||
if (this.world == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (world.getBlockState(pos).getBlock() != ModBlocks.DETACHED_RIFT) {
|
||||
markInvalid();
|
||||
if (this.world.getBlockState(this.pos).getBlock() != ModBlocks.DETACHED_RIFT) {
|
||||
this.markInvalid();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!world.isClient() && random.nextDouble() < ModConfig.GENERAL.endermanSpawnChance) {
|
||||
EndermanEntity enderman = EntityType.ENDERMAN.spawn((ServerWorld) world, null, null, null, pos, SpawnReason.STRUCTURE, false, false);
|
||||
if (!this.world.isClient() && random.nextDouble() < ModConfig.INSTANCE.getGeneralConfig().endermanSpawnChance) {
|
||||
EndermanEntity enderman = EntityType.ENDERMAN.spawn((ServerWorld) this.world, null, null, null, this.pos, SpawnReason.STRUCTURE, false, false);
|
||||
|
||||
if (random.nextDouble() < ModConfig.GENERAL.endermanAggressiveChance) {
|
||||
if (random.nextDouble() < ModConfig.INSTANCE.getGeneralConfig().endermanAggressiveChance) {
|
||||
if (enderman != null) {
|
||||
enderman.setTarget(world.getClosestPlayer(enderman, 50));
|
||||
enderman.setTarget(this.world.getClosestPlayer(enderman, 50));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (closing) {
|
||||
if (size > 0) {
|
||||
size -= ModConfig.GENERAL.riftCloseSpeed;
|
||||
if (this.closing) {
|
||||
if (this.size > 0) {
|
||||
this.size -= ModConfig.INSTANCE.getGeneralConfig().riftCloseSpeed;
|
||||
} else {
|
||||
world.removeBlock(pos, false);
|
||||
this.world.removeBlock(this.pos, false);
|
||||
}
|
||||
} else if (!stabilized) {
|
||||
size += ModConfig.GENERAL.riftGrowthSpeed / (size + 1);
|
||||
} else if (!this.stabilized) {
|
||||
this.size += ModConfig.INSTANCE.getGeneralConfig().riftGrowthSpeed / (this.size + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void setClosing(boolean closing) {
|
||||
this.closing = closing;
|
||||
markDirty();
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
public void setStabilized(boolean stabilized) {
|
||||
this.stabilized = stabilized;
|
||||
markDirty();
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CompoundTag serialize(CompoundTag tag) {
|
||||
super.serialize(tag);
|
||||
tag.putBoolean("closing", closing);
|
||||
tag.putBoolean("stablized", stabilized);
|
||||
tag.putInt("spawnedEnderManId", spawnedEndermanId);
|
||||
tag.putFloat("size", size);
|
||||
tag.putBoolean("closing", this.closing);
|
||||
tag.putBoolean("stablized", this.stabilized);
|
||||
tag.putInt("spawnedEnderManId", this.spawnedEndermanId);
|
||||
tag.putFloat("size", this.size);
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deserialize(CompoundTag tag) {
|
||||
super.deserialize(tag);
|
||||
closing = tag.getBoolean("closing");
|
||||
stabilized = tag.getBoolean("stablized");
|
||||
spawnedEndermanId = tag.getInt("spawnedEnderManId");
|
||||
size = tag.getFloat("size");
|
||||
this.closing = tag.getBoolean("closing");
|
||||
this.stabilized = tag.getBoolean("stablized");
|
||||
this.spawnedEndermanId = tag.getInt("spawnedEnderManId");
|
||||
this.size = tag.getFloat("size");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -108,15 +108,15 @@ public class DetachedRiftBlockEntity extends RiftBlockEntity implements Tickable
|
|||
|
||||
@Override
|
||||
public void unregister() {
|
||||
if (!unregisterDisabled) {
|
||||
if (!this.unregisterDisabled) {
|
||||
super.unregister();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean receiveEntity(Entity entity, float yawOffset) {
|
||||
if (world instanceof ServerWorld)
|
||||
TeleportUtil.teleport(entity, world, pos, 0);
|
||||
if (this.world instanceof ServerWorld)
|
||||
TeleportUtil.teleport(entity, this.world, this.pos, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@ public class EntranceRiftBlockEntity extends RiftBlockEntity {
|
|||
public boolean teleport(Entity entity) {
|
||||
boolean status = super.teleport(entity);
|
||||
|
||||
if (riftStateChanged && !data.isAlwaysDelete()) {
|
||||
markDirty();
|
||||
if (this.riftStateChanged && !this.data.isAlwaysDelete()) {
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
return status;
|
||||
|
@ -45,8 +45,8 @@ public class EntranceRiftBlockEntity extends RiftBlockEntity {
|
|||
|
||||
@Override
|
||||
public boolean receiveEntity(Entity entity, float yawOffset) {
|
||||
Vec3d targetPos = Vec3d.ofCenter(pos).add(Vec3d.of(getOrientation().getVector()).multiply(ModConfig.GENERAL.teleportOffset + 0.5));
|
||||
TeleportUtil.teleport(entity, world, targetPos, yawOffset);
|
||||
Vec3d targetPos = Vec3d.ofCenter(this.pos).add(Vec3d.of(this.getOrientation().getVector()).multiply(ModConfig.INSTANCE.getGeneralConfig().teleportOffset + 0.5));
|
||||
TeleportUtil.teleport(entity, this.world, targetPos, yawOffset);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ public class EntranceRiftBlockEntity extends RiftBlockEntity {
|
|||
float[][] colors = new float[count][];
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
colors[i] = getEntranceRenderColor(rand);
|
||||
colors[i] = this.getEntranceRenderColor(rand);
|
||||
}
|
||||
|
||||
return RGBA.fromFloatArrays(colors);
|
||||
|
@ -70,7 +70,7 @@ public class EntranceRiftBlockEntity extends RiftBlockEntity {
|
|||
protected float[] getEntranceRenderColor(Random rand) {
|
||||
float red, green, blue;
|
||||
|
||||
if (world.getRegistryKey() == World.NETHER) {
|
||||
if (this.world.getRegistryKey() == World.NETHER) {
|
||||
red = rand.nextFloat() * 0.5F + 0.4F;
|
||||
green = rand.nextFloat() * 0.05F;
|
||||
blue = rand.nextFloat() * 0.05F;
|
||||
|
|
|
@ -20,7 +20,7 @@ import net.fabricmc.api.Environment;
|
|||
@Environment(EnvType.CLIENT)
|
||||
public class DetachedRiftBlockEntityRenderer extends BlockEntityRenderer<DetachedRiftBlockEntity> {
|
||||
public static final Identifier TESSERACT_PATH = new Identifier("dimdoors:textures/other/tesseract.png");
|
||||
private RGBA COLOR = new RGBA(1, 0.5f, 1, 1);
|
||||
private final RGBA COLOR = new RGBA(1, 0.5f, 1, 1);
|
||||
|
||||
private static final Tesseract TESSERACT = new Tesseract();
|
||||
private static final RiftCurves.PolygonInfo CURVE = RiftCurves.CURVES.get(0);
|
||||
|
@ -34,29 +34,29 @@ public class DetachedRiftBlockEntityRenderer extends BlockEntityRenderer<Detache
|
|||
public void render(DetachedRiftBlockEntity rift, float tickDelta, MatrixStack matrices, VertexConsumerProvider vcs, int breakProgress, int alpha) {
|
||||
Matrix4f model = matrices.peek().getModel();
|
||||
|
||||
if (ModConfig.GRAPHICS.showRiftCore) {
|
||||
renderTesseract(vcs.getBuffer(MyRenderLayer.TESSERACT), rift, matrices, tickDelta);
|
||||
if (ModConfig.INSTANCE.getGraphicsConfig().showRiftCore) {
|
||||
this.renderTesseract(vcs.getBuffer(MyRenderLayer.TESSERACT), rift, matrices, tickDelta);
|
||||
} else {
|
||||
long timeLeft = showRiftCoreUntil - System.currentTimeMillis();
|
||||
if (timeLeft >= 0) {
|
||||
renderTesseract(vcs.getBuffer(MyRenderLayer.TESSERACT), rift, matrices, tickDelta);
|
||||
this.renderTesseract(vcs.getBuffer(MyRenderLayer.TESSERACT), rift, matrices, tickDelta);
|
||||
}
|
||||
}
|
||||
|
||||
renderCrack(vcs.getBuffer(MyRenderLayer.CRACK), matrices, rift);
|
||||
this.renderCrack(vcs.getBuffer(MyRenderLayer.CRACK), matrices, rift);
|
||||
}
|
||||
|
||||
private void renderCrack(VertexConsumer vc, MatrixStack matrices, DetachedRiftBlockEntity rift) {
|
||||
matrices.push();
|
||||
matrices.translate(0.5, 0.5, 0.5);
|
||||
RiftCrackRenderer.drawCrack(matrices.peek().getModel(), vc, 0, CURVE, ModConfig.GRAPHICS.riftSize * rift.size, 0xF1234568L * rift.getPos().hashCode());
|
||||
RiftCrackRenderer.drawCrack(matrices.peek().getModel(), vc, 0, CURVE, ModConfig.INSTANCE.getGraphicsConfig().riftSize * rift.size, 0xF1234568L * rift.getPos().hashCode());
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
private void renderTesseract( VertexConsumer vc, DetachedRiftBlockEntity rift, MatrixStack matrices, float tickDelta) {
|
||||
double radian = nextAngle(rift, tickDelta) * TrigMath.DEG_TO_RAD;
|
||||
double radian = this.nextAngle(rift, tickDelta) * TrigMath.DEG_TO_RAD;
|
||||
RGBA color = rift.getColor();
|
||||
if (color == RGBA.NONE) color = COLOR;
|
||||
if (color == RGBA.NONE) color = this.COLOR;
|
||||
|
||||
matrices.push();
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ public final class RiftCrackRenderer {
|
|||
// Calculate jitter like for monoliths, depending x, y and z coordinates to avoid all rifts syncing
|
||||
float time = (System.currentTimeMillis() + riftRandom) % 2000000;
|
||||
|
||||
double jitterScale = ModConfig.GRAPHICS.riftJitter * size * size * size / 2000f;
|
||||
double jitterScale = ModConfig.INSTANCE.getGraphicsConfig().riftJitter * size * size * size / 2000f;
|
||||
// We use random constants here on purpose just to get different wave forms
|
||||
double xJitter = jitterScale * Math.sin(1.1f * time * size * jitterSpeed) * Math.sin(0.8f * time * jitterSpeed);
|
||||
double yJitter = jitterScale * Math.sin(1.2f * time * size * jitterSpeed) * Math.sin(0.9f * time * jitterSpeed);
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package org.dimdev.dimdoors.client.config;
|
||||
|
||||
import org.dimdev.dimdoors.ModConfig;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class LoadConfigScreen extends Screen {
|
||||
private final Screen parent;
|
||||
|
||||
protected LoadConfigScreen(Screen parent) {
|
||||
super(new TranslatableText("dimdoors.config.title"));
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() {
|
||||
MinecraftClient.getInstance().openScreen(this.parent);
|
||||
}
|
||||
|
||||
public Screen getParent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
this.addButton(new ButtonWidget(10, 10, 100, 20, new TranslatableText("dimdoors.config.screen.reload"), (button) -> {
|
||||
ModConfig.deserialize();
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
|
||||
super.render(matrices, mouseX, mouseY, delta);
|
||||
this.renderBackground(matrices);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package org.dimdev.dimdoors.client.config;
|
||||
|
||||
import io.github.prospector.modmenu.api.ConfigScreenFactory;
|
||||
import io.github.prospector.modmenu.api.ModMenuApi;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class ModMenuImpl implements ModMenuApi {
|
||||
@Override
|
||||
public ConfigScreenFactory<?> getModConfigScreenFactory() {
|
||||
return LoadConfigScreen::new;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package org.dimdev.dimdoors.command;
|
||||
|
||||
import org.dimdev.dimdoors.ModConfig;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
|
||||
import static net.minecraft.server.command.CommandManager.literal;
|
||||
|
||||
public class DimdoorsConfigCommand {
|
||||
public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
|
||||
dispatcher.register(
|
||||
literal("dimdoorsconfig")
|
||||
.requires(source -> source.hasPermissionLevel(2))
|
||||
.then(
|
||||
literal("load")
|
||||
.executes(ctx -> ModConfig.deserialize())
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ public final class ModCommands {
|
|||
PocketCommand.register(dispatcher);
|
||||
SchematicV2Command.register(dispatcher);
|
||||
SchematicCommand.register(dispatcher);
|
||||
DimdoorsConfigCommand.register(dispatcher);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package org.dimdev.dimdoors.entity;
|
|||
import java.util.Random;
|
||||
|
||||
import org.dimdev.dimdoors.ModConfig;
|
||||
import org.dimdev.dimdoors.entity.ai.MonolithTask;
|
||||
import org.dimdev.dimdoors.entity.ai.MonolithAggroGoal;
|
||||
import org.dimdev.dimdoors.item.ModItems;
|
||||
import org.dimdev.dimdoors.sound.ModSoundEvents;
|
||||
import org.dimdev.dimdoors.world.ModDimensions;
|
||||
|
@ -59,31 +59,31 @@ public class MonolithEntity extends MobEntity {
|
|||
public MonolithEntity(EntityType<? extends MonolithEntity> type, World world) {
|
||||
super(ModEntityTypes.MONOLITH, world);
|
||||
random = this.getRandom();
|
||||
noClip = true;
|
||||
aggroCap = MathHelper.nextInt(getRandom(), MIN_AGGRO_CAP, MAX_AGGRO_CAP);
|
||||
this.noClip = true;
|
||||
this.aggroCap = MathHelper.nextInt(this.getRandom(), MIN_AGGRO_CAP, MAX_AGGRO_CAP);
|
||||
this.setNoGravity(true);
|
||||
lookControl = new LookControl(this) {
|
||||
this.lookControl = new LookControl(this) {
|
||||
@Override
|
||||
protected boolean shouldStayHorizontal() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
setInvulnerable(true);
|
||||
this.setInvulnerable(true);
|
||||
}
|
||||
|
||||
public EntityDimensions getDimensions(EntityPose entityPose) {
|
||||
return DIMENSIONS;
|
||||
return this.DIMENSIONS;
|
||||
}
|
||||
|
||||
public boolean isDangerous() {
|
||||
return ModConfig.MONOLITHS.monolithTeleportation && (ModDimensions.isLimboDimension(world) || ModConfig.MONOLITHS.dangerousLimboMonoliths);
|
||||
return ModConfig.INSTANCE.getMonolithsConfig().monolithTeleportation && (ModDimensions.isLimboDimension(this.world) || ModConfig.INSTANCE.getMonolithsConfig().dangerousLimboMonoliths);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean damage(DamageSource source, float amount) {
|
||||
if (source != DamageSource.IN_WALL) {
|
||||
aggro = MAX_AGGRO;
|
||||
this.aggro = MAX_AGGRO;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ public class MonolithEntity extends MobEntity {
|
|||
protected void initDataTracker() {
|
||||
super.initDataTracker();
|
||||
// Add a short for the aggro level
|
||||
dataTracker.startTracking(AGGRO, 0);
|
||||
this.dataTracker.startTracking(AGGRO, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -137,7 +137,7 @@ public class MonolithEntity extends MobEntity {
|
|||
@Override
|
||||
protected void mobTick() {
|
||||
// Remove this Monolith if it's not in Limbo or in a pocket dungeon
|
||||
if (!(ModDimensions.isLimboDimension(world) || ModDimensions.isDimDoorsPocketDimension(world))) {
|
||||
if (!(ModDimensions.isLimboDimension(this.world) || ModDimensions.isDimDoorsPocketDimension(this.world))) {
|
||||
this.remove();
|
||||
super.mobTick();
|
||||
return;
|
||||
|
@ -159,17 +159,17 @@ public class MonolithEntity extends MobEntity {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!world.isClient) {
|
||||
if (!this.world.isClient) {
|
||||
if (player.distanceTo(this) > 70) {
|
||||
return;
|
||||
}
|
||||
|
||||
int aggro = dataTracker.get(AGGRO);
|
||||
int aggro = this.dataTracker.get(AGGRO);
|
||||
// Server side...
|
||||
// Rapidly increase the aggro level if this Monolith can see the player
|
||||
if (visibility) {
|
||||
if (ModDimensions.isLimboDimension(world)) {
|
||||
if (isDangerous()) {
|
||||
if (ModDimensions.isLimboDimension(this.world)) {
|
||||
if (this.isDangerous()) {
|
||||
aggro++;
|
||||
} else {
|
||||
aggro += 36;
|
||||
|
@ -179,11 +179,11 @@ public class MonolithEntity extends MobEntity {
|
|||
aggro += 3;
|
||||
}
|
||||
} else {
|
||||
if (isDangerous()) {
|
||||
if (aggro > aggroCap) {
|
||||
if (this.isDangerous()) {
|
||||
if (aggro > this.aggroCap) {
|
||||
// Decrease aggro over time
|
||||
aggro--;
|
||||
} else if (aggro < aggroCap) {
|
||||
} else if (aggro < this.aggroCap) {
|
||||
// Increase aggro if a player is within range and aggro < aggroCap
|
||||
aggro++;
|
||||
}
|
||||
|
@ -192,16 +192,16 @@ public class MonolithEntity extends MobEntity {
|
|||
}
|
||||
}
|
||||
// Clamp the aggro level
|
||||
int maxAggro = isDangerous() ? MAX_AGGRO : 180;
|
||||
int maxAggro = this.isDangerous() ? MAX_AGGRO : 180;
|
||||
aggro = (short) MathHelper.clamp(aggro, 0, maxAggro);
|
||||
dataTracker.set(AGGRO, aggro);
|
||||
this.dataTracker.set(AGGRO, aggro);
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public int getTextureState() {
|
||||
// Determine texture state from aggro progress
|
||||
return MathHelper.clamp(MAX_TEXTURE_STATE * dataTracker.get(AGGRO) / MAX_AGGRO, 0, MAX_TEXTURE_STATE);
|
||||
return MathHelper.clamp(MAX_TEXTURE_STATE * this.dataTracker.get(AGGRO) / MAX_AGGRO, 0, MAX_TEXTURE_STATE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -210,20 +210,20 @@ public class MonolithEntity extends MobEntity {
|
|||
* @param pos The position to play the sounds at
|
||||
*/
|
||||
public void playSounds(Vec3d pos) {
|
||||
float aggroPercent = getAggroProgress();
|
||||
if (soundTime <= 0) {
|
||||
playSound(ModSoundEvents.MONK, 1F, 1F);
|
||||
soundTime = 100;
|
||||
float aggroPercent = this.getAggroProgress();
|
||||
if (this.soundTime <= 0) {
|
||||
this.playSound(ModSoundEvents.MONK, 1F, 1F);
|
||||
this.soundTime = 100;
|
||||
}
|
||||
if (aggroPercent > 0.70 && soundTime < 100) {
|
||||
world.playSound(null, new BlockPos(pos), ModSoundEvents.TEARING, SoundCategory.HOSTILE, 1F, (float) (1 + getRandom().nextGaussian()));
|
||||
soundTime = 100 + getRandom().nextInt(75);
|
||||
if (aggroPercent > 0.70 && this.soundTime < 100) {
|
||||
this.world.playSound(null, new BlockPos(pos), ModSoundEvents.TEARING, SoundCategory.HOSTILE, 1F, (float) (1 + this.getRandom().nextGaussian()));
|
||||
this.soundTime = 100 + this.getRandom().nextInt(75);
|
||||
}
|
||||
if (aggroPercent > 0.80 && soundTime < MAX_SOUND_COOLDOWN) {
|
||||
world.playSound(null, new BlockPos(pos), ModSoundEvents.TEARING, SoundCategory.HOSTILE, 7, 1F);
|
||||
soundTime = 250;
|
||||
if (aggroPercent > 0.80 && this.soundTime < MAX_SOUND_COOLDOWN) {
|
||||
this.world.playSound(null, new BlockPos(pos), ModSoundEvents.TEARING, SoundCategory.HOSTILE, 7, 1F);
|
||||
this.soundTime = 250;
|
||||
}
|
||||
soundTime--;
|
||||
this.soundTime--;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -252,38 +252,38 @@ public class MonolithEntity extends MobEntity {
|
|||
}
|
||||
|
||||
public float getAggroProgress() {
|
||||
return (float) aggro / MAX_AGGRO;
|
||||
return (float) this.aggro / MAX_AGGRO;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initGoals() {
|
||||
super.initGoals();
|
||||
goalSelector.add(0, new MonolithTask(this, MAX_AGGRO_RANGE));
|
||||
this.goalSelector.add(0, new MonolithAggroGoal(this, MAX_AGGRO_RANGE));
|
||||
}
|
||||
|
||||
public void facePlayer(PlayerEntity player) {
|
||||
lookControl.lookAt(player, 1.0f, 1.0f);
|
||||
this.lookControl.lookAt(player, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
super.toTag(tag);
|
||||
tag.putInt("Aggro", aggro);
|
||||
tag.putInt("Aggro", this.aggro);
|
||||
return tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromTag(CompoundTag nbt) {
|
||||
super.fromTag(nbt);
|
||||
aggro = nbt.getInt("Aggro");
|
||||
this.aggro = nbt.getInt("Aggro");
|
||||
}
|
||||
|
||||
public int getAggro() {
|
||||
return dataTracker.get(AGGRO);
|
||||
return this.dataTracker.get(AGGRO);
|
||||
}
|
||||
|
||||
public void setAggro(int aggro) {
|
||||
dataTracker.set(AGGRO, aggro);
|
||||
this.dataTracker.set(AGGRO, aggro);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,30 +22,30 @@ import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
|
|||
import static net.minecraft.predicate.entity.EntityPredicates.EXCEPT_SPECTATOR;
|
||||
import static org.dimdev.dimdoors.entity.MonolithEntity.MAX_AGGRO;
|
||||
|
||||
public class MonolithTask extends Goal {
|
||||
public class MonolithAggroGoal extends Goal {
|
||||
protected final MonolithEntity mob;
|
||||
protected PlayerEntity target;
|
||||
protected final float range;
|
||||
protected final TargetPredicate targetPredicate;
|
||||
|
||||
public MonolithTask(MonolithEntity mobEntity, float f) {
|
||||
public MonolithAggroGoal(MonolithEntity mobEntity, float f) {
|
||||
this.mob = mobEntity;
|
||||
this.range = f;
|
||||
this.setControls(EnumSet.of(Goal.Control.LOOK));
|
||||
this.targetPredicate = (new TargetPredicate()).setBaseMaxDistance(range).includeTeammates().includeInvulnerable().ignoreEntityTargetRules().setPredicate(EXCEPT_SPECTATOR::test);
|
||||
this.targetPredicate = (new TargetPredicate()).setBaseMaxDistance(this.range).includeTeammates().includeInvulnerable().ignoreEntityTargetRules().setPredicate(EXCEPT_SPECTATOR::test);
|
||||
}
|
||||
|
||||
private PlayerEntity getTarget() {
|
||||
PlayerEntity playerEntity = this.mob.world.getClosestPlayer(this.targetPredicate, this.mob, this.mob.getX(), this.mob.getEyeY(), this.mob.getZ());
|
||||
return playerEntity != null && mob.canSee(playerEntity) && playerEntity.distanceTo(this.mob) < 50 ? playerEntity : null;
|
||||
return playerEntity != null && this.mob.canSee(playerEntity) && playerEntity.distanceTo(this.mob) < 50 ? playerEntity : null;
|
||||
}
|
||||
|
||||
public boolean canStart() {
|
||||
return (this.target = getTarget()) != null && target.distanceTo(this.mob) <= 50;
|
||||
return (this.target = this.getTarget()) != null && this.target.distanceTo(this.mob) <= 50;
|
||||
}
|
||||
|
||||
public boolean shouldContinue() {
|
||||
return (this.target = getTarget()) != null && target.distanceTo(this.mob) <= 50;
|
||||
return (this.target = this.getTarget()) != null && this.target.distanceTo(this.mob) <= 50;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
|
@ -57,50 +57,50 @@ public class MonolithTask extends Goal {
|
|||
}
|
||||
|
||||
public void tick() {
|
||||
if (target != null && this.target.distanceTo(this.mob) > 70) {
|
||||
if (this.target != null && this.target.distanceTo(this.mob) > 70) {
|
||||
this.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (target != null && (target.inventory.armor.get(0).getItem() == ModItems.WORLD_THREAD_HELMET && target.inventory.armor.get(1).getItem() == ModItems.WORLD_THREAD_CHESTPLATE && target.inventory.armor.get(2).getItem() == ModItems.WORLD_THREAD_LEGGINGS && target.inventory.armor.get(3).getItem() == ModItems.WORLD_THREAD_BOOTS)) {
|
||||
if (this.target != null && (this.target.inventory.armor.get(0).getItem() == ModItems.WORLD_THREAD_HELMET && this.target.inventory.armor.get(1).getItem() == ModItems.WORLD_THREAD_CHESTPLATE && this.target.inventory.armor.get(2).getItem() == ModItems.WORLD_THREAD_LEGGINGS && this.target.inventory.armor.get(3).getItem() == ModItems.WORLD_THREAD_BOOTS)) {
|
||||
Random random = new Random();
|
||||
int i = random.nextInt(64);
|
||||
if (this.target instanceof ServerPlayerEntity) {
|
||||
if (i < 6) {
|
||||
target.inventory.armor.get(0).damage(i, random, (ServerPlayerEntity) this.target);
|
||||
target.inventory.armor.get(1).damage(i, random, (ServerPlayerEntity) this.target);
|
||||
target.inventory.armor.get(2).damage(i, random, (ServerPlayerEntity) this.target);
|
||||
target.inventory.armor.get(3).damage(i, random, (ServerPlayerEntity) this.target);
|
||||
this.target.inventory.armor.get(0).damage(i, random, (ServerPlayerEntity) this.target);
|
||||
this.target.inventory.armor.get(1).damage(i, random, (ServerPlayerEntity) this.target);
|
||||
this.target.inventory.armor.get(2).damage(i, random, (ServerPlayerEntity) this.target);
|
||||
this.target.inventory.armor.get(3).damage(i, random, (ServerPlayerEntity) this.target);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
boolean visibility = target != null;
|
||||
mob.updateAggroLevel(target, visibility);
|
||||
boolean visibility = this.target != null;
|
||||
this.mob.updateAggroLevel(this.target, visibility);
|
||||
|
||||
// Change orientation and face a player if one is in range
|
||||
if (target != null) {
|
||||
mob.facePlayer(target);
|
||||
if (mob.isDangerous()) {
|
||||
if (this.target != null) {
|
||||
this.mob.facePlayer(this.target);
|
||||
if (this.mob.isDangerous()) {
|
||||
// Play sounds on the server side, if the player isn't in Limbo.
|
||||
// Limbo is excluded to avoid drowning out its background music.
|
||||
// Also, since it's a large open area with many Monoliths, some
|
||||
// of the sounds that would usually play for a moment would
|
||||
// keep playing constantly and would get very annoying.
|
||||
mob.playSounds(target.getPos());
|
||||
this.mob.playSounds(this.target.getPos());
|
||||
|
||||
PacketByteBuf data = new PacketByteBuf(Unpooled.buffer());
|
||||
data.writeInt(this.mob.getAggro());
|
||||
ServerSidePacketRegistry.INSTANCE.sendToPlayer(target, DimensionalDoorsInitializer.MONOLITH_PARTICLE_PACKET, data);
|
||||
ServerSidePacketRegistry.INSTANCE.sendToPlayer(this.target, DimensionalDoorsInitializer.MONOLITH_PARTICLE_PACKET, data);
|
||||
}
|
||||
|
||||
// Teleport the target player if various conditions are met
|
||||
if (mob.getAggro() >= MAX_AGGRO && ModConfig.MONOLITHS.monolithTeleportation && !target.isCreative() && mob.isDangerous()) {
|
||||
mob.setAggro(0);
|
||||
if (this.mob.getAggro() >= MAX_AGGRO && ModConfig.INSTANCE.getMonolithsConfig().monolithTeleportation && !this.target.isCreative() && this.mob.isDangerous()) {
|
||||
this.mob.setAggro(0);
|
||||
//Location destination = LimboDimension.getLimboSkySpawn(player);
|
||||
//TeleportUtil.teleport(player, destination, 0, 0);
|
||||
target.world.playSound(null, new BlockPos(target.getPos()), ModSoundEvents.CRACK, SoundCategory.HOSTILE, 13, 1);
|
||||
this.target.world.playSound(null, new BlockPos(this.target.getPos()), ModSoundEvents.CRACK, SoundCategory.HOSTILE, 13, 1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -43,9 +43,8 @@ public class DimensionalDoorItem extends TallBlockItem {
|
|||
// without sending custom packets.
|
||||
|
||||
if (context.getWorld().isClient) {
|
||||
Object[] translationArgs = new Object[0];
|
||||
context.getPlayer().sendMessage(new TranslatableText("rifts.entrances.rift_too_close", translationArgs), true);
|
||||
DetachedRiftBlockEntityRenderer.showRiftCoreUntil = System.currentTimeMillis() + ModConfig.GRAPHICS.highlightRiftCoreFor;
|
||||
context.getPlayer().sendMessage(new TranslatableText("rifts.entrances.rift_too_close"), true);
|
||||
DetachedRiftBlockEntityRenderer.showRiftCoreUntil = System.currentTimeMillis() + ModConfig.INSTANCE.getGraphicsConfig().highlightRiftCoreFor;
|
||||
}
|
||||
|
||||
return ActionResult.FAIL;
|
||||
|
|
|
@ -48,7 +48,7 @@ public class RiftBladeItem extends SwordItem {
|
|||
return new TypedActionResult<>(ActionResult.SUCCESS, stack);
|
||||
} else {
|
||||
player.sendMessage(new TranslatableText(this.getTranslationKey() + ".rift_miss"), true);
|
||||
DetachedRiftBlockEntityRenderer.showRiftCoreUntil = System.currentTimeMillis() + ModConfig.GRAPHICS.highlightRiftCoreFor;
|
||||
DetachedRiftBlockEntityRenderer.showRiftCoreUntil = System.currentTimeMillis() + ModConfig.INSTANCE.getGraphicsConfig().highlightRiftCoreFor;
|
||||
return new TypedActionResult<>(ActionResult.FAIL, stack);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ public class RiftConfigurationToolItem extends Item {
|
|||
if (world.isClient) {
|
||||
if (!RaycastHelper.hitsRift(hit, world)) {
|
||||
player.sendMessage(new TranslatableText("tools.rift_miss"), true);
|
||||
DetachedRiftBlockEntityRenderer.showRiftCoreUntil = System.currentTimeMillis() + ModConfig.GRAPHICS.highlightRiftCoreFor;
|
||||
DetachedRiftBlockEntityRenderer.showRiftCoreUntil = System.currentTimeMillis() + ModConfig.INSTANCE.getGraphicsConfig().highlightRiftCoreFor;
|
||||
}
|
||||
return new TypedActionResult<>(ActionResult.FAIL, stack);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ public class RiftRemoverItem extends Item {
|
|||
if (world.isClient) {
|
||||
if (!RaycastHelper.hitsDetachedRift(hit, world)) {
|
||||
player.sendMessage(new TranslatableText("tools.rift_miss"), true);
|
||||
DetachedRiftBlockEntityRenderer.showRiftCoreUntil = System.currentTimeMillis() + ModConfig.GRAPHICS.highlightRiftCoreFor;
|
||||
DetachedRiftBlockEntityRenderer.showRiftCoreUntil = System.currentTimeMillis() + ModConfig.INSTANCE.getGraphicsConfig().highlightRiftCoreFor;
|
||||
}
|
||||
return new TypedActionResult<>(ActionResult.FAIL, stack);
|
||||
}
|
||||
|
|
|
@ -25,8 +25,6 @@ import net.fabricmc.api.EnvType;
|
|||
import net.fabricmc.api.Environment;
|
||||
|
||||
public class RiftStabilizerItem extends Item {
|
||||
public static final String ID = "rift_stabilizer";
|
||||
|
||||
public RiftStabilizerItem(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
@ -42,7 +40,7 @@ public class RiftStabilizerItem extends Item {
|
|||
return new TypedActionResult<>(ActionResult.SUCCESS, stack);
|
||||
} else {
|
||||
player.sendMessage(new TranslatableText("tools.rift_miss"), true);
|
||||
DetachedRiftBlockEntityRenderer.showRiftCoreUntil = System.currentTimeMillis() + ModConfig.GRAPHICS.highlightRiftCoreFor;
|
||||
DetachedRiftBlockEntityRenderer.showRiftCoreUntil = System.currentTimeMillis() + ModConfig.INSTANCE.getGraphicsConfig().highlightRiftCoreFor;
|
||||
return new TypedActionResult<>(ActionResult.FAIL, stack);
|
||||
}
|
||||
}
|
||||
|
@ -54,10 +52,10 @@ public class RiftStabilizerItem extends Item {
|
|||
world.playSound(null, player.getBlockPos(), ModSoundEvents.RIFT_CLOSE, SoundCategory.BLOCKS, 0.6f, 1); // TODO: different sound
|
||||
stack.damage(1, player, a -> {
|
||||
});
|
||||
player.sendMessage(new TranslatableText(getTranslationKey() + ".stabilized"), true);
|
||||
player.sendMessage(new TranslatableText(this.getTranslationKey() + ".stabilized"), true);
|
||||
return new TypedActionResult<>(ActionResult.SUCCESS, stack);
|
||||
} else {
|
||||
player.sendMessage(new TranslatableText(getTranslationKey() + ".already_stabilized"), true);
|
||||
player.sendMessage(new TranslatableText(this.getTranslationKey() + ".already_stabilized"), true);
|
||||
}
|
||||
}
|
||||
return new TypedActionResult<>(ActionResult.FAIL, stack);
|
||||
|
@ -66,6 +64,6 @@ public class RiftStabilizerItem extends Item {
|
|||
@Environment(EnvType.CLIENT)
|
||||
@Override
|
||||
public void appendTooltip(ItemStack itemStack, World world, List<Text> list, TooltipContext tooltipContext) {
|
||||
list.add(new TranslatableText(getTranslationKey() + ".info"));
|
||||
list.add(new TranslatableText(this.getTranslationKey() + ".info"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ import net.minecraft.world.gen.feature.DefaultBiomeFeatures;
|
|||
|
||||
@Mixin(DefaultBiomeFeatures.class)
|
||||
public class DefaultBiomeFeaturesMixin {
|
||||
@Inject(method = "addDesertLakes", at = @At("RETURN"), remap = false)
|
||||
@Inject(method = "addDesertLakes", at = @At("RETURN"))
|
||||
private static void addGateway(GenerationSettings.Builder builder, CallbackInfo ci) {
|
||||
builder.feature(GenerationStep.Feature.TOP_LAYER_MODIFICATION, ModFeatures.SANDSTONE_PILLARS_FEATURE_V2);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ public abstract class PlayerEntityMixin extends LivingEntity {
|
|||
super(entityType, world);
|
||||
}
|
||||
|
||||
@Inject(method = "handleFallDamage", at = @At("HEAD"), cancellable = true, remap = false)
|
||||
@Inject(method = "handleFallDamage", at = @At("HEAD"), cancellable = true)
|
||||
public void handleLimboFallDamage(float fallDistance, float damageMultiplier, CallbackInfoReturnable<Boolean> cir) {
|
||||
if (this.world.getBiome(this.getBlockPos()) == ModBiomes.LIMBO_BIOME) {
|
||||
cir.setReturnValue(false);
|
||||
|
|
|
@ -16,7 +16,7 @@ import net.fabricmc.api.Environment;
|
|||
@Environment(EnvType.CLIENT)
|
||||
@Mixin(InGameHud.class)
|
||||
public class InGameHudMixin {
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;getTextureManager()Lnet/minecraft/client/texture/TextureManager;"), method = "renderVignetteOverlay(Lnet/minecraft/entity/Entity;)V", remap = false)
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;getTextureManager()Lnet/minecraft/client/texture/TextureManager;"), method = "renderVignetteOverlay(Lnet/minecraft/entity/Entity;)V")
|
||||
public void renderVignetteOverlay(Entity entity, CallbackInfo info) {
|
||||
if (entity.world.getBiome(entity.getBlockPos()) == ModBiomes.LIMBO_BIOME) {
|
||||
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
|
|
@ -61,7 +61,7 @@ public final class PocketGenerator {
|
|||
float netherProbability = WorldUtil.getWorld(virtualLocation.world).getDimension().isUltrawarm() ? 1 : (float) depth / 200; // TODO: improve nether probability
|
||||
Random random = new Random();
|
||||
String group = random.nextFloat() < netherProbability ? "nether" : "ruins";
|
||||
PocketTemplate pocketTemplate = SchematicHandler.INSTANCE.getRandomTemplate(group, depth, ModConfig.POCKETS.maxPocketSize, false);
|
||||
PocketTemplate pocketTemplate = SchematicHandler.INSTANCE.getRandomTemplate(group, depth, ModConfig.INSTANCE.getPocketsConfig().maxPocketSize, false);
|
||||
|
||||
return generatePocketFromTemplate(WorldUtil.getWorld(ModDimensions.DUNGEON), pocketTemplate, virtualLocation, linkTo, linkProperties);
|
||||
}
|
||||
|
|
|
@ -64,19 +64,19 @@ public class SchematicHandler { // TODO: parts of this should be moved to the or
|
|||
private List<PocketTemplate> templates;
|
||||
private Map<String, Map<String, Integer>> nameMap; // group -> name -> index in templates
|
||||
private List<Entry<PocketTemplate, Integer>> usageList = new ArrayList<>(); //template and nr of usages
|
||||
private Map<PocketTemplate, Integer> usageMap = new HashMap<>(); //template -> index in usageList
|
||||
private final Map<PocketTemplate, Integer> usageMap = new HashMap<>(); //template -> index in usageList
|
||||
|
||||
public void loadSchematics() {
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
templates = new ArrayList<>();
|
||||
this.templates = new ArrayList<>();
|
||||
|
||||
String[] names = {"default_dungeon_nether", "default_dungeon_normal", "default_private", "default_public", "default_blank"}; // TODO: don't hardcode
|
||||
for (String name : names) {
|
||||
try {
|
||||
URL resource = DimensionalDoorsInitializer.class.getResource("/data/dimdoors/pockets/json/" + name + ".json");
|
||||
String jsonString = IOUtils.toString(resource, StandardCharsets.UTF_8);
|
||||
templates.addAll(loadTemplatesFromJson(jsonString));
|
||||
this.templates.addAll(loadTemplatesFromJson(jsonString));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ public class SchematicHandler { // TODO: parts of this should be moved to the or
|
|||
if (file.isDirectory() || !file.getName().endsWith(".json")) continue;
|
||||
try {
|
||||
String jsonString = IOUtils.toString(file.toURI(), StandardCharsets.UTF_8);
|
||||
templates.addAll(loadTemplatesFromJson(jsonString));
|
||||
this.templates.addAll(loadTemplatesFromJson(jsonString));
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Error reading file " + file.toURI() + ". The following exception occured: ", e);
|
||||
}
|
||||
|
@ -113,16 +113,16 @@ public class SchematicHandler { // TODO: parts of this should be moved to the or
|
|||
byte[] schematicBytecode = IOUtils.toByteArray(new FileInputStream(file));
|
||||
Schematic.fromTag(NbtIo.readCompressed(new ByteArrayInputStream(schematicBytecode)));
|
||||
PocketTemplate template = new PocketTemplate(SAVED_POCKETS_GROUP_NAME, file.getName(), null, null, null, null, schematicBytecode, -1, 0);
|
||||
templates.add(template);
|
||||
this.templates.add(template);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Error reading schematic " + file.getName() + ": " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructNameMap();
|
||||
this.constructNameMap();
|
||||
|
||||
LOGGER.info("Loaded " + templates.size() + " templates in " + (System.currentTimeMillis() - startTime) + " ms.");
|
||||
LOGGER.info("Loaded " + this.templates.size() + " templates in " + (System.currentTimeMillis() - startTime) + " ms.");
|
||||
}
|
||||
|
||||
private static List<PocketTemplate> loadTemplatesFromJson(String jsonString) {
|
||||
|
@ -218,7 +218,7 @@ public class SchematicHandler { // TODO: parts of this should be moved to the or
|
|||
for (JsonElement pocketElement : pockets) {
|
||||
JsonObject pocket = pocketElement.getAsJsonObject();
|
||||
int size = pocket.get("size").getAsInt();
|
||||
if (!ModConfig.POCKETS.loadAllSchematics && size > ModConfig.POCKETS.maxPocketSize) continue;
|
||||
if (!ModConfig.INSTANCE.getPocketsConfig().loadAllSchematics && size > ModConfig.INSTANCE.getPocketsConfig().maxPocketSize) continue;
|
||||
String id = pocket.get("id").getAsString();
|
||||
String type = pocket.has("type") ? pocket.get("type").getAsString() : null;
|
||||
String name = pocket.has("name") ? pocket.get("name").getAsString() : null;
|
||||
|
@ -231,36 +231,36 @@ public class SchematicHandler { // TODO: parts of this should be moved to the or
|
|||
}
|
||||
|
||||
private void constructNameMap() {
|
||||
nameMap = new HashMap<>();
|
||||
this.nameMap = new HashMap<>();
|
||||
//to prevent having to use too many getters
|
||||
String bufferedDirectory = null;
|
||||
Map<String, Integer> bufferedMap = null;
|
||||
|
||||
for (PocketTemplate template : templates) {
|
||||
for (PocketTemplate template : this.templates) {
|
||||
String dirName = template.getGroup();
|
||||
if (dirName != null && dirName.equals(bufferedDirectory)) { //null check not needed
|
||||
bufferedMap.put(template.getId(), templates.indexOf(template));
|
||||
bufferedMap.put(template.getId(), this.templates.indexOf(template));
|
||||
} else {
|
||||
bufferedDirectory = dirName;
|
||||
if (nameMap.containsKey(dirName)) { //this will only happen if you have two json files referring to the same directory being loaded non-consecutively
|
||||
bufferedMap = nameMap.get(dirName);
|
||||
bufferedMap.put(template.getId(), templates.indexOf(template));
|
||||
if (this.nameMap.containsKey(dirName)) { //this will only happen if you have two json files referring to the same directory being loaded non-consecutively
|
||||
bufferedMap = this.nameMap.get(dirName);
|
||||
bufferedMap.put(template.getId(), this.templates.indexOf(template));
|
||||
} else {
|
||||
bufferedMap = new HashMap<>();
|
||||
bufferedMap.put(template.getId(), templates.indexOf(template));
|
||||
nameMap.put(dirName, bufferedMap);
|
||||
bufferedMap.put(template.getId(), this.templates.indexOf(template));
|
||||
this.nameMap.put(dirName, bufferedMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Set<String> getTemplateGroups() {
|
||||
return nameMap.keySet();
|
||||
return this.nameMap.keySet();
|
||||
}
|
||||
|
||||
public Set<String> getTemplateNames(String group) {
|
||||
if (nameMap.containsKey(group)) {
|
||||
return nameMap.get(group).keySet();
|
||||
if (this.nameMap.containsKey(group)) {
|
||||
return this.nameMap.get(group).keySet();
|
||||
} else {
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ public class SchematicHandler { // TODO: parts of this should be moved to the or
|
|||
* @return The dungeon template with that group and name, or null if it wasn't found
|
||||
*/
|
||||
public PocketTemplate getTemplate(String group, String name) {
|
||||
Map<String, Integer> groupMap = nameMap.get(group);
|
||||
Map<String, Integer> groupMap = this.nameMap.get(group);
|
||||
if (groupMap == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ public class SchematicHandler { // TODO: parts of this should be moved to the or
|
|||
if (index == null) {
|
||||
return null;
|
||||
}
|
||||
return templates.get(index);
|
||||
return this.templates.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -298,7 +298,7 @@ public class SchematicHandler { // TODO: parts of this should be moved to the or
|
|||
// TODO: cache this for faster calls:
|
||||
Map<PocketTemplate, Float> weightedTemplates = new HashMap<>();
|
||||
int largestSize = 0;
|
||||
for (PocketTemplate template : templates) {
|
||||
for (PocketTemplate template : this.templates) {
|
||||
if (template.getGroup().equals(group) && (maxSize == -1 || template.getSize() <= maxSize)) {
|
||||
if (getLargest && template.getSize() > largestSize) {
|
||||
weightedTemplates = new HashMap<>();
|
||||
|
@ -316,11 +316,11 @@ public class SchematicHandler { // TODO: parts of this should be moved to the or
|
|||
}
|
||||
|
||||
public PocketTemplate getPersonalPocketTemplate() {
|
||||
return getRandomTemplate("private", -1, ModConfig.POCKETS.privatePocketSize, true);
|
||||
return this.getRandomTemplate("private", -1, ModConfig.INSTANCE.getPocketsConfig().privatePocketSize, true);
|
||||
}
|
||||
|
||||
public PocketTemplate getPublicPocketTemplate() {
|
||||
return getRandomTemplate("public", -1, ModConfig.POCKETS.publicPocketSize, true);
|
||||
return this.getRandomTemplate("public", -1, ModConfig.INSTANCE.getPocketsConfig().publicPocketSize, true);
|
||||
}
|
||||
|
||||
public static void saveSchematic(Schematic schematic, String id) {
|
||||
|
@ -346,13 +346,13 @@ public class SchematicHandler { // TODO: parts of this should be moved to the or
|
|||
public void saveSchematicForEditing(Schematic schematic, String id) {
|
||||
saveSchematic(schematic, id);
|
||||
|
||||
if (!nameMap.containsKey(SAVED_POCKETS_GROUP_NAME)) {
|
||||
nameMap.put(SAVED_POCKETS_GROUP_NAME, new HashMap<>());
|
||||
if (!this.nameMap.containsKey(SAVED_POCKETS_GROUP_NAME)) {
|
||||
this.nameMap.put(SAVED_POCKETS_GROUP_NAME, new HashMap<>());
|
||||
}
|
||||
|
||||
Map<String, Integer> savedDungeons = nameMap.get(SAVED_POCKETS_GROUP_NAME);
|
||||
Map<String, Integer> savedDungeons = this.nameMap.get(SAVED_POCKETS_GROUP_NAME);
|
||||
if (savedDungeons.containsKey(id)) {
|
||||
templates.remove((int) savedDungeons.remove(id));
|
||||
this.templates.remove((int) savedDungeons.remove(id));
|
||||
}
|
||||
|
||||
//create byte array
|
||||
|
@ -367,59 +367,59 @@ public class SchematicHandler { // TODO: parts of this should be moved to the or
|
|||
}
|
||||
|
||||
if (schematicBytecode != null) {
|
||||
templates.add(new PocketTemplate(SAVED_POCKETS_GROUP_NAME, id, null, null, null, schematic, schematicBytecode, -1, 0));
|
||||
nameMap.get(SAVED_POCKETS_GROUP_NAME).put(id, templates.size() - 1);
|
||||
this.templates.add(new PocketTemplate(SAVED_POCKETS_GROUP_NAME, id, null, null, null, schematic, schematicBytecode, -1, 0));
|
||||
this.nameMap.get(SAVED_POCKETS_GROUP_NAME).put(id, this.templates.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
private int getUsage(PocketTemplate template) {
|
||||
if (!usageMap.containsKey(template)) return -1;
|
||||
int index = usageMap.get(template);
|
||||
if (usageList.size() <= index) return -1;
|
||||
PocketTemplate listTemplate = usageList.get(index).getKey();
|
||||
if (!this.usageMap.containsKey(template)) return -1;
|
||||
int index = this.usageMap.get(template);
|
||||
if (this.usageList.size() <= index) return -1;
|
||||
PocketTemplate listTemplate = this.usageList.get(index).getKey();
|
||||
if (listTemplate == template) {
|
||||
int usage = usageList.get(index).getValue();
|
||||
int usage = this.usageList.get(index).getValue();
|
||||
return usage;
|
||||
} else {//should never happen, but you never really know.
|
||||
LOGGER.warn("Pocket Template usage list is desynched from the usage map, re-sorting and synching now.");
|
||||
reSortUsages();
|
||||
return getUsage(template);
|
||||
this.reSortUsages();
|
||||
return this.getUsage(template);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUsedOftenEnough(PocketTemplate template) {
|
||||
int maxNrOfCachedSchematics = ModConfig.POCKETS.cachedSchematics;
|
||||
int usageRank = usageMap.get(template);
|
||||
int maxNrOfCachedSchematics = ModConfig.INSTANCE.getPocketsConfig().cachedSchematics;
|
||||
int usageRank = this.usageMap.get(template);
|
||||
return usageRank < maxNrOfCachedSchematics;
|
||||
}
|
||||
|
||||
public void incrementUsage(PocketTemplate template) {
|
||||
int startIndex;
|
||||
int newUsage;
|
||||
if (!usageMap.containsKey(template)) {
|
||||
usageList.add(new SimpleEntry<>(null, 0)); //add a dummy entry at the end
|
||||
startIndex = usageList.size() - 1;
|
||||
if (!this.usageMap.containsKey(template)) {
|
||||
this.usageList.add(new SimpleEntry<>(null, 0)); //add a dummy entry at the end
|
||||
startIndex = this.usageList.size() - 1;
|
||||
newUsage = 1;
|
||||
} else {
|
||||
startIndex = usageMap.get(template);
|
||||
newUsage = usageList.get(startIndex).getValue() + 1;
|
||||
startIndex = this.usageMap.get(template);
|
||||
newUsage = this.usageList.get(startIndex).getValue() + 1;
|
||||
}
|
||||
|
||||
int insertionIndex = findFirstEqualOrLessUsage(newUsage, 0, startIndex);
|
||||
int insertionIndex = this.findFirstEqualOrLessUsage(newUsage, 0, startIndex);
|
||||
//shift all entries inbetween the insertionIndex and the currentIndex to the right
|
||||
PocketTemplate currentTemplate;
|
||||
for (int i = startIndex; i > insertionIndex; i--) {
|
||||
usageList.set(i, usageList.get(i - 1));
|
||||
currentTemplate = usageList.get(i).getKey();
|
||||
usageMap.put(currentTemplate, i);
|
||||
this.usageList.set(i, this.usageList.get(i - 1));
|
||||
currentTemplate = this.usageList.get(i).getKey();
|
||||
this.usageMap.put(currentTemplate, i);
|
||||
}
|
||||
//insert the incremented entry at the correct place
|
||||
usageList.set(insertionIndex, new SimpleEntry(template, newUsage));
|
||||
usageMap.put(template, insertionIndex);
|
||||
this.usageList.set(insertionIndex, new SimpleEntry(template, newUsage));
|
||||
this.usageMap.put(template, insertionIndex);
|
||||
|
||||
if (insertionIndex < ModConfig.POCKETS.cachedSchematics) { //if the schematic of this template is supposed to get cached
|
||||
if (usageList.size() > ModConfig.POCKETS.cachedSchematics) { //if there are more used templates than there are schematics allowed to be cached
|
||||
usageList.get(ModConfig.POCKETS.cachedSchematics).getKey().setSchematic(null); //make sure that the number of cached schematics is limited
|
||||
if (insertionIndex < ModConfig.INSTANCE.getPocketsConfig().cachedSchematics) { //if the schematic of this template is supposed to get cached
|
||||
if (this.usageList.size() > ModConfig.INSTANCE.getPocketsConfig().cachedSchematics) { //if there are more used templates than there are schematics allowed to be cached
|
||||
this.usageList.get(ModConfig.INSTANCE.getPocketsConfig().cachedSchematics).getKey().setSchematic(null); //make sure that the number of cached schematics is limited
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -427,33 +427,33 @@ public class SchematicHandler { // TODO: parts of this should be moved to the or
|
|||
//uses binary search
|
||||
private int findFirstEqualOrLessUsage(int usage, int indexMin, int indexMax) {
|
||||
|
||||
if (usageList.get(indexMin).getValue() <= usage) {
|
||||
if (this.usageList.get(indexMin).getValue() <= usage) {
|
||||
return indexMin;
|
||||
}
|
||||
int halfwayIndex = (indexMin + indexMax) / 2;
|
||||
if (usageList.get(halfwayIndex).getValue() > usage) {
|
||||
return findFirstEqualOrLessUsage(usage, halfwayIndex + 1, indexMax);
|
||||
if (this.usageList.get(halfwayIndex).getValue() > usage) {
|
||||
return this.findFirstEqualOrLessUsage(usage, halfwayIndex + 1, indexMax);
|
||||
} else {
|
||||
return findFirstEqualOrLessUsage(usage, indexMin, halfwayIndex);
|
||||
return this.findFirstEqualOrLessUsage(usage, indexMin, halfwayIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private void reSortUsages() {
|
||||
//sort the usageList
|
||||
usageList = mergeSortPairArrayByPairValue(usageList);
|
||||
this.usageList = this.mergeSortPairArrayByPairValue(this.usageList);
|
||||
//make sure that everything in the usageList is actually in the usageMap
|
||||
for (Entry<PocketTemplate, Integer> pair : usageList) {
|
||||
usageMap.put(pair.getKey(), pair.getValue());
|
||||
for (Entry<PocketTemplate, Integer> pair : this.usageList) {
|
||||
this.usageMap.put(pair.getKey(), pair.getValue());
|
||||
}
|
||||
|
||||
//make sure that everything in the usageMap is actually in the usageList
|
||||
for (Entry<PocketTemplate, Integer> entry : usageMap.entrySet()) {
|
||||
for (Entry<PocketTemplate, Integer> entry : this.usageMap.entrySet()) {
|
||||
PocketTemplate template = entry.getKey();
|
||||
int index = entry.getValue();
|
||||
PocketTemplate template2 = usageList.get(index).getKey();
|
||||
if (index >= usageList.size() || template != template2) {
|
||||
entry.setValue(usageList.size());
|
||||
usageList.add(new SimpleEntry(template, 1));
|
||||
PocketTemplate template2 = this.usageList.get(index).getKey();
|
||||
if (index >= this.usageList.size() || template != template2) {
|
||||
entry.setValue(this.usageList.size());
|
||||
this.usageList.add(new SimpleEntry(template, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -463,9 +463,9 @@ public class SchematicHandler { // TODO: parts of this should be moved to the or
|
|||
if (input.size() < 2) {
|
||||
return input;
|
||||
} else {
|
||||
List<Entry<PocketTemplate, Integer>> a = mergeSortPairArrayByPairValue(input.subList(0, input.size() / 2));
|
||||
List<Entry<PocketTemplate, Integer>> b = mergeSortPairArrayByPairValue(input.subList(input.size() / 2, input.size()));
|
||||
return mergePairArraysByPairValue(a, b);
|
||||
List<Entry<PocketTemplate, Integer>> a = this.mergeSortPairArrayByPairValue(input.subList(0, input.size() / 2));
|
||||
List<Entry<PocketTemplate, Integer>> b = this.mergeSortPairArrayByPairValue(input.subList(input.size() / 2, input.size()));
|
||||
return this.mergePairArraysByPairValue(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,10 +34,10 @@ public final class ModBiomes {
|
|||
Registry.register(BuiltinRegistries.BIOME, PERSONAL_WHITE_VOID_KEY.getValue(), PERSONAL_WHITE_VOID_BIOME);
|
||||
Registry.register(BuiltinRegistries.BIOME, PUBLIC_BLACK_VOID_KEY.getValue(), PUBLIC_BLACK_VOID_BIOME);
|
||||
Registry.register(BuiltinRegistries.BIOME, DUNGEON_DANGEROUS_BLACK_VOID_KEY.getValue(), DUNGEON_DANGEROUS_BLACK_VOID_BIOME);
|
||||
BuiltinBiomesAccessor.getIdMap().put(BuiltinRegistries.BIOME.getRawId(LIMBO_BIOME), LIMBO_KEY);
|
||||
BuiltinBiomesAccessor.getIdMap().put(BuiltinRegistries.BIOME.getRawId(PERSONAL_WHITE_VOID_BIOME), PERSONAL_WHITE_VOID_KEY);
|
||||
BuiltinBiomesAccessor.getIdMap().put(BuiltinRegistries.BIOME.getRawId(PUBLIC_BLACK_VOID_BIOME), PUBLIC_BLACK_VOID_KEY);
|
||||
BuiltinBiomesAccessor.getIdMap().put(BuiltinRegistries.BIOME.getRawId(DUNGEON_DANGEROUS_BLACK_VOID_BIOME), DUNGEON_DANGEROUS_BLACK_VOID_KEY);
|
||||
// BuiltinBiomesAccessor.getIdMap().put(BuiltinRegistries.BIOME.getRawId(LIMBO_BIOME), LIMBO_KEY);
|
||||
// BuiltinBiomesAccessor.getIdMap().put(BuiltinRegistries.BIOME.getRawId(PERSONAL_WHITE_VOID_BIOME), PERSONAL_WHITE_VOID_KEY);
|
||||
// BuiltinBiomesAccessor.getIdMap().put(BuiltinRegistries.BIOME.getRawId(PUBLIC_BLACK_VOID_BIOME), PUBLIC_BLACK_VOID_KEY);
|
||||
// BuiltinBiomesAccessor.getIdMap().put(BuiltinRegistries.BIOME.getRawId(DUNGEON_DANGEROUS_BLACK_VOID_BIOME), DUNGEON_DANGEROUS_BLACK_VOID_KEY);
|
||||
}
|
||||
|
||||
private static BiomeEffects createEffect(boolean white) {
|
||||
|
|
|
@ -83,33 +83,34 @@ public final class ModDimensions {
|
|||
Optional.of(StructuresConfig.DEFAULT_STRONGHOLD),
|
||||
ImmutableMap.of()
|
||||
);
|
||||
GenerationShapeConfig limboShapeConfig = new GenerationShapeConfig(
|
||||
178,
|
||||
new NoiseSamplingConfig(
|
||||
1.000009876543,
|
||||
2.9999876545678,
|
||||
60,
|
||||
240
|
||||
),
|
||||
new SlideConfig(
|
||||
-10,
|
||||
3,
|
||||
0
|
||||
),
|
||||
new SlideConfig(
|
||||
-30,
|
||||
0,
|
||||
0
|
||||
),
|
||||
1,
|
||||
4,
|
||||
1,
|
||||
-0.26875,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
);
|
||||
// GenerationShapeConfig limboShapeConfig = new GenerationShapeConfig(
|
||||
// 178,
|
||||
// new NoiseSamplingConfig(
|
||||
// 1.000009876543,
|
||||
// 2.9999876545678,
|
||||
// 60,
|
||||
// 240
|
||||
// ),
|
||||
// new SlideConfig(
|
||||
// -10,
|
||||
// 3,
|
||||
// 0
|
||||
// ),
|
||||
// new SlideConfig(
|
||||
// -30,
|
||||
// 0,
|
||||
// 0
|
||||
// ),
|
||||
// 1,
|
||||
// 4,
|
||||
// 1,
|
||||
// -0.26875,
|
||||
// false,
|
||||
// true,
|
||||
// false,
|
||||
// false
|
||||
// );
|
||||
GenerationShapeConfig limboShapeConfig = new GenerationShapeConfig(256, new NoiseSamplingConfig(0.9999999814507745D, 0.9999999814507745D, 80.0D, 160.0D), new SlideConfig(-10, 3, 0), new SlideConfig(-30, 0, 0), 1, 2, 1.0D, -0.46875D, true, true, false, true);
|
||||
LIMBO_CHUNK_GENERATOR_SETTINGS = ChunkGeneratorSettingsAccessor.invokeInit(
|
||||
limboStructuresConfig,
|
||||
limboShapeConfig,
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
package org.dimdev.dimdoors.world.feature;
|
||||
|
||||
import org.dimdev.dimdoors.ModConfig;
|
||||
import org.dimdev.dimdoors.block.ModBlocks;
|
||||
import org.dimdev.dimdoors.world.feature.gateway.SandstonePillarsGateway;
|
||||
import org.dimdev.dimdoors.world.feature.gateway.SchematicGateway;
|
||||
import org.dimdev.dimdoors.world.feature.gateway.SchematicGatewayFeature;
|
||||
import org.dimdev.dimdoors.world.feature.gateway.SchematicGatewayFeatureConfig;
|
||||
import org.dimdev.dimdoors.world.feature.gateway.TwoPillarsGateway;
|
||||
import org.dimdev.dimdoors.world.feature.gateway.v2.SandstonePillarsV2Gateway;
|
||||
import org.dimdev.dimdoors.world.feature.gateway.v2.SchematicV2Gateway;
|
||||
import org.dimdev.dimdoors.world.feature.gateway.v2.SchematicV2GatewayFeature;
|
||||
|
@ -27,14 +21,14 @@ public final class ModFeatures {
|
|||
public static final ConfiguredFeature<?, ?> SANDSTONE_PILLARS_FEATURE_V2;
|
||||
|
||||
public static void init() {
|
||||
SANDSTONE_PILLARS_GATEWAY_V2.init();
|
||||
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, new Identifier("dimdoors", "sandstone_pillars_v2"), SANDSTONE_PILLARS_FEATURE_V2);
|
||||
}
|
||||
|
||||
static {
|
||||
ModBlocks.init();
|
||||
SANDSTONE_PILLARS_GATEWAY_V2 = new SandstonePillarsV2Gateway();
|
||||
|
||||
int gatewayChance = FabricLoader.getInstance().isDevelopmentEnvironment() ? 20 : ModConfig.WORLD.gatewayGenChance;
|
||||
int gatewayChance = FabricLoader.getInstance().isDevelopmentEnvironment() ? 20 : ModConfig.INSTANCE.getWorldConfig().gatewayGenChance;
|
||||
SANDSTONE_PILLARS_FEATURE_V2 = GATEWAY_FEATURE_V2.configure(new SchematicV2GatewayFeatureConfig(SchematicV2Gateway.SCHEMATIC_ID_MAP.get(SANDSTONE_PILLARS_GATEWAY_V2)))
|
||||
.decorate(ConfiguredFeatures.Decorators.SQUARE_TOP_SOLID_HEIGHTMAP
|
||||
.applyChance(gatewayChance));
|
||||
|
|
|
@ -21,15 +21,19 @@ import net.minecraft.world.StructureWorldAccess;
|
|||
public class SchematicV2Gateway extends BaseGateway {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private Schematic schematic;
|
||||
private final String id;
|
||||
public static final BiMap<SchematicV2Gateway, String> SCHEMATIC_ID_MAP = HashBiMap.create();
|
||||
public static final BiMap<String, SchematicV2Gateway> ID_SCHEMATIC_MAP = HashBiMap.create();
|
||||
|
||||
public SchematicV2Gateway(String id) {
|
||||
String schematicJarDirectory = "/data/dimdoors/gateways/v2/";
|
||||
SCHEMATIC_ID_MAP.putIfAbsent(this, id);
|
||||
ID_SCHEMATIC_MAP.putIfAbsent(id, this);
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
InputStream schematicStream = DimensionalDoorsInitializer.class.getResourceAsStream(schematicJarDirectory + id + ".schem");
|
||||
public void init() {
|
||||
String schematicJarDirectory = "/data/dimdoors/gateways/v2/";
|
||||
InputStream schematicStream = DimensionalDoorsInitializer.class.getResourceAsStream(schematicJarDirectory + this.id + ".schem");
|
||||
|
||||
DataInputStream schematicDataStream = null;
|
||||
boolean streamOpened = false;
|
||||
|
@ -37,7 +41,7 @@ public class SchematicV2Gateway extends BaseGateway {
|
|||
schematicDataStream = new DataInputStream(schematicStream);
|
||||
streamOpened = true;
|
||||
} else {
|
||||
LOGGER.warn("Schematic '" + id + "' was not found in the jar or config directory, neither with the .schem extension, nor with the .schematic extension.");
|
||||
LOGGER.warn("Schematic '" + this.id + "' was not found in the jar or config directory, neither with the .schem extension, nor with the .schematic extension.");
|
||||
}
|
||||
|
||||
CompoundTag tag;
|
||||
|
@ -48,7 +52,7 @@ public class SchematicV2Gateway extends BaseGateway {
|
|||
this.schematic = Schematic.fromTag(tag);
|
||||
schematicDataStream.close();
|
||||
} catch (IOException ex) {
|
||||
LOGGER.error("Schematic file for " + id + " could not be read as a valid schematic NBT file.", ex);
|
||||
LOGGER.error("Schematic file for " + this.id + " could not be read as a valid schematic NBT file.", ex);
|
||||
} finally {
|
||||
try {
|
||||
schematicDataStream.close();
|
||||
|
|
|
@ -116,7 +116,7 @@ public final class LimboDecay {
|
|||
public static void applySpreadDecay(World world, BlockPos pos) {
|
||||
//Check if we randomly apply decay spread or not. This can be used to moderate the frequency of
|
||||
//full spread decay checks, which can also shift its performance impact on the game.
|
||||
if (random.nextDouble() < ModConfig.LIMBO.decaySpreadChance) {
|
||||
if (random.nextDouble() < ModConfig.INSTANCE.getLimboConfig().decaySpreadChance) {
|
||||
//Apply decay to the blocks above, below, and on all four sides.
|
||||
//World.getBlockId() implements bounds checking, so we don't have to worry about reaching out of the world
|
||||
decayBlock(world, pos.up());
|
||||
|
|
|
@ -19,7 +19,7 @@ import net.minecraft.world.PersistentState;
|
|||
import net.minecraft.world.World;
|
||||
|
||||
public class PocketRegistry extends PersistentState {
|
||||
private Codec<Map<Integer, Pocket>> pocketsCodec = Codec.unboundedMap(Codec.INT, Pocket.CODEC);
|
||||
private final Codec<Map<Integer, Pocket>> pocketsCodec = Codec.unboundedMap(Codec.INT, Pocket.CODEC);
|
||||
|
||||
private static final String DATA_NAME = "pocketlib_pockets";
|
||||
|
||||
|
@ -33,10 +33,10 @@ public class PocketRegistry extends PersistentState {
|
|||
|
||||
public PocketRegistry() {
|
||||
super(DATA_NAME);
|
||||
gridSize = ModConfig.POCKETS.pocketGridSize;
|
||||
this.gridSize = ModConfig.INSTANCE.getPocketsConfig().pocketGridSize;
|
||||
|
||||
nextID = 0;
|
||||
pockets = new HashMap<>();
|
||||
this.nextID = 0;
|
||||
this.pockets = new HashMap<>();
|
||||
}
|
||||
|
||||
public PocketRegistry(String s) {
|
||||
|
@ -45,20 +45,20 @@ public class PocketRegistry extends PersistentState {
|
|||
|
||||
@Override
|
||||
public void fromTag(CompoundTag tag) {
|
||||
gridSize = tag.getInt("gridSize");
|
||||
privatePocketSize = tag.getInt("privatePocketSize");
|
||||
publicPocketSize = tag.getInt("publicPocketSize");
|
||||
pockets = NbtUtil.deserialize(tag.get("pockets"), pocketsCodec);
|
||||
nextID = tag.getInt("nextID");
|
||||
this.gridSize = tag.getInt("gridSize");
|
||||
this.privatePocketSize = tag.getInt("privatePocketSize");
|
||||
this.publicPocketSize = tag.getInt("publicPocketSize");
|
||||
this.pockets = NbtUtil.deserialize(tag.get("pockets"), this.pocketsCodec);
|
||||
this.nextID = tag.getInt("nextID");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag toTag(CompoundTag tag) {
|
||||
tag.putInt("gridSize", gridSize);
|
||||
tag.putInt("privatePocketSize", privatePocketSize);
|
||||
tag.putInt("publicPocketSize", publicPocketSize);
|
||||
tag.put("pockets", NbtUtil.serialize(pockets, pocketsCodec));
|
||||
tag.putInt("nextID", nextID);
|
||||
tag.putInt("gridSize", this.gridSize);
|
||||
tag.putInt("privatePocketSize", this.privatePocketSize);
|
||||
tag.putInt("publicPocketSize", this.publicPocketSize);
|
||||
tag.put("pockets", NbtUtil.serialize(this.pockets, this.pocketsCodec));
|
||||
tag.putInt("nextID", this.nextID);
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ public class PocketRegistry extends PersistentState {
|
|||
*/
|
||||
public Pocket newPocket() {
|
||||
Pocket pocket = null;
|
||||
while (pocket == null) pocket = newPocket(nextID++);
|
||||
while (pocket == null) pocket = this.newPocket(this.nextID++);
|
||||
return pocket;
|
||||
}
|
||||
|
||||
|
@ -96,18 +96,18 @@ public class PocketRegistry extends PersistentState {
|
|||
* @return The newly created Pocket, or null if that ID is already taken.
|
||||
*/
|
||||
public Pocket newPocket(int id) {
|
||||
if (pockets.get(id) != null) return null;
|
||||
GridUtil.GridPos pos = idToGridPos(id);
|
||||
Pocket pocket = new Pocket(id, world.getRegistryKey(), pos.x, pos.z);
|
||||
pockets.put(id, pocket);
|
||||
if (id >= nextID) nextID = id + 1;
|
||||
markDirty();
|
||||
if (this.pockets.get(id) != null) return null;
|
||||
GridUtil.GridPos pos = this.idToGridPos(id);
|
||||
Pocket pocket = new Pocket(id, this.world.getRegistryKey(), pos.x, pos.z);
|
||||
this.pockets.put(id, pocket);
|
||||
if (id >= this.nextID) this.nextID = id + 1;
|
||||
this.markDirty();
|
||||
return pocket;
|
||||
}
|
||||
|
||||
public void removePocket(int id) {
|
||||
pockets.remove(id);
|
||||
markDirty();
|
||||
this.pockets.remove(id);
|
||||
this.markDirty();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,7 +116,7 @@ public class PocketRegistry extends PersistentState {
|
|||
* @return The pocket with that ID, or null if there was no pocket with that ID.
|
||||
*/
|
||||
public Pocket getPocket(int id) {
|
||||
return pockets.get(id);
|
||||
return this.pockets.get(id);
|
||||
}
|
||||
|
||||
public GridUtil.GridPos idToGridPos(int id) {
|
||||
|
@ -135,8 +135,8 @@ public class PocketRegistry extends PersistentState {
|
|||
* @return The BlockPos of the pocket
|
||||
*/
|
||||
public BlockPos idToPos(int id) {
|
||||
GridUtil.GridPos pos = idToGridPos(id);
|
||||
return new BlockPos(pos.x * gridSize * 16, 0, pos.z * gridSize * 16);
|
||||
GridUtil.GridPos pos = this.idToGridPos(id);
|
||||
return new BlockPos(pos.x * this.gridSize * 16, 0, pos.z * this.gridSize * 16);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,35 +146,35 @@ public class PocketRegistry extends PersistentState {
|
|||
* @return The ID of the pocket, or -1 if there is no pocket at that location
|
||||
*/
|
||||
public int posToID(BlockPos pos) {
|
||||
return gridPosToID(new GridUtil.GridPos(pos.getX() / (gridSize * 16), pos.getZ() / (gridSize * 16)));
|
||||
return this.gridPosToID(new GridUtil.GridPos(pos.getX() / (this.gridSize * 16), pos.getZ() / (this.gridSize * 16)));
|
||||
}
|
||||
|
||||
public Pocket getPocketAt(BlockPos pos) { // TODO: use BlockPos
|
||||
return getPocket(posToID(pos));
|
||||
return this.getPocket(this.posToID(pos));
|
||||
}
|
||||
|
||||
public boolean isWithinPocketBounds(BlockPos pos) {
|
||||
Pocket pocket = getPocketAt(pos);
|
||||
Pocket pocket = this.getPocketAt(pos);
|
||||
return pocket != null && pocket.isInBounds(pos);
|
||||
}
|
||||
|
||||
public int getGridSize() {
|
||||
return gridSize;
|
||||
return this.gridSize;
|
||||
}
|
||||
|
||||
public int getPrivatePocketSize() {
|
||||
return privatePocketSize;
|
||||
return this.privatePocketSize;
|
||||
}
|
||||
|
||||
public int getPublicPocketSize() {
|
||||
return publicPocketSize;
|
||||
return this.publicPocketSize;
|
||||
}
|
||||
|
||||
public Map<Integer, Pocket> getPockets() {
|
||||
return pockets;
|
||||
return this.pockets;
|
||||
}
|
||||
|
||||
public int getNextID() {
|
||||
return nextID;
|
||||
return this.nextID;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ public class VirtualLocation {
|
|||
virtualLocation = null; // TODO: door was placed in a pockets dim but outside of a pockets...
|
||||
}
|
||||
} else if (ModDimensions.isLimboDimension(location.getWorld())) { // TODO: convert to interface on worldprovider
|
||||
virtualLocation = new VirtualLocation(location.world, location.getX(), location.getZ(), ModConfig.DUNGEONS.maxDungeonDepth);
|
||||
virtualLocation = new VirtualLocation(location.world, location.getX(), location.getZ(), ModConfig.INSTANCE.getDungeonsConfig().maxDungeonDepth);
|
||||
} // TODO: nether coordinate transform
|
||||
|
||||
if (virtualLocation == null) {
|
||||
|
@ -80,9 +80,9 @@ public class VirtualLocation {
|
|||
world = world.getServer().getWorld(OVERWORLD);
|
||||
}
|
||||
|
||||
float spread = ModConfig.GENERAL.depthSpreadFactor * depth;
|
||||
int newX = (int) (x + spread * 2 * (Math.random() - 0.5));
|
||||
int newZ = (int) (z + spread * 2 * (Math.random() - 0.5));
|
||||
float spread = ModConfig.INSTANCE.getGeneralConfig().depthSpreadFactor * this.depth;
|
||||
int newX = (int) (this.x + spread * 2 * (Math.random() - 0.5));
|
||||
int newZ = (int) (this.z + spread * 2 * (Math.random() - 0.5));
|
||||
BlockPos pos = world.getTopPosition(Heightmap.Type.WORLD_SURFACE, new BlockPos(newX, 0, newZ));
|
||||
return new Location(world, pos);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
],
|
||||
"client": [
|
||||
"org.dimdev.dimdoors.DimensionalDoorsClientInitializer"
|
||||
],
|
||||
"modmenu": [
|
||||
"org.dimdev.dimdoors.client.config.ModMenuImpl"
|
||||
]
|
||||
},
|
||||
"mixins": [
|
||||
|
|
Loading…
Reference in a new issue