From 31c0f9c676f3c59776b7ebe77e3c4f2280831d48 Mon Sep 17 00:00:00 2001 From: Runemoro Date: Tue, 27 Mar 2018 16:17:15 -0400 Subject: [PATCH] Config localization and tile entity simplification --- .../java/org/dimdev/ddutils/Location.java | 2 +- .../org/dimdev/ddutils/schem/Schematic.java | 7 +- .../java/org/dimdev/dimdoors/DimDoors.java | 9 +- .../TileEntityEntranceRiftRenderer.java | 42 ++++----- .../org/dimdev/dimdoors/shared/ModConfig.java | 84 ++++++++---------- .../shared/blocks/BlockDimensionalDoor.java | 6 +- .../shared/blocks/BlockDimensionalPortal.java | 6 +- .../shared/blocks/BlockFloatingRift.java | 14 ++- .../shared/pockets/PocketTemplate.java | 14 +-- .../dimdoors/shared/rifts/TileEntityRift.java | 3 +- .../tileentities/TileEntityEntranceRift.java | 53 +++++------ .../shared/tools/SchematicGenerator.java | 2 +- .../java/org/dimdev/pocketlib/Pocket.java | 4 +- .../resources/assets/dimdoors/lang/en_US.lang | 46 +++++++++- .../dimdoors/textures/other/key_outline.png | Bin 0 -> 2340 bytes .../textures/other/key_outline_light.png | Bin 0 -> 3256 bytes .../dimdoors/textures/other/keyhole.png | Bin 0 -> 16819 bytes .../dimdoors/textures/other/keyhole_light.png | Bin 0 -> 16286 bytes 18 files changed, 163 insertions(+), 129 deletions(-) create mode 100644 src/main/resources/assets/dimdoors/textures/other/key_outline.png create mode 100644 src/main/resources/assets/dimdoors/textures/other/key_outline_light.png create mode 100644 src/main/resources/assets/dimdoors/textures/other/keyhole.png create mode 100644 src/main/resources/assets/dimdoors/textures/other/keyhole_light.png diff --git a/src/main/java/org/dimdev/ddutils/Location.java b/src/main/java/org/dimdev/ddutils/Location.java index e3c00bb7..87d34249 100644 --- a/src/main/java/org/dimdev/ddutils/Location.java +++ b/src/main/java/org/dimdev/ddutils/Location.java @@ -76,6 +76,6 @@ public class Location implements Serializable { @Override public int hashCode() { - return pos.hashCode() * 31 + dim; // TODO + return pos.hashCode() * 31 + dim; } } diff --git a/src/main/java/org/dimdev/ddutils/schem/Schematic.java b/src/main/java/org/dimdev/ddutils/schem/Schematic.java index 82f06a5b..575f347c 100644 --- a/src/main/java/org/dimdev/ddutils/schem/Schematic.java +++ b/src/main/java/org/dimdev/ddutils/schem/Schematic.java @@ -243,6 +243,10 @@ public class Schematic { } } if (value != null) { + // property is IProperty, value is Comparable, and the ?s refer to the same type because + // IProperty.getAllowedValues() returns Collection, but the compiler doesn't keep track of + // this, so casting to raw types: + //noinspection unchecked,RedundantCast,rawtypes chosenState = chosenState.withProperty((IProperty) property, (Comparable) value); } } @@ -368,7 +372,6 @@ public class Schematic { adjustedEntityNBT.setUniqueId("UUID", UUID.randomUUID()); Entity entity = EntityList.createEntityFromNBT(adjustedEntityNBT, world); - // TODO: check if it is in pocket bounds world.spawnEntity(entity); } } @@ -425,8 +428,6 @@ public class Schematic { } setTime += System.nanoTime() - setStart; long relightStart = System.nanoTime(); - // TODO: It's possible to relight a whole region at once, and immediately using this, according - // TODO: to Foghrye4: https://hastebin.com/hociqufabe.java cube.setInitialLightingDone(false); relightTime += System.nanoTime() - relightStart; cube.markDirty(); diff --git a/src/main/java/org/dimdev/dimdoors/DimDoors.java b/src/main/java/org/dimdev/dimdoors/DimDoors.java index d6519a8d..38a22c73 100644 --- a/src/main/java/org/dimdev/dimdoors/DimDoors.java +++ b/src/main/java/org/dimdev/dimdoors/DimDoors.java @@ -33,13 +33,12 @@ public class DimDoors { public static final String MODNAME = "Dimensional Doors"; public static final String MCVERSIONS = "[1.12,1.13)"; public static final String VERSION = "${version}"; - // TODO: make the forge version here change depending on a field in build.gradle public static final String DEPENDENCIES = "required-after:forge@[14.21.0.2320,);after:csb_ench_table"; // after:csb_ench_table as a workaround for https://github.com/crazysnailboy/EnchantingTable/issues/7 @Mod.Instance(DimDoors.MODID) public static DimDoors instance; - public static Logger log; // TODO: make non-static? + public static Logger log; @SidedProxy(clientSide = "org.dimdev.dimdoors.client.ClientProxy", serverSide = "org.dimdev.dimdoors.server.ServerProxy") @@ -86,11 +85,9 @@ public class DimDoors { } public static void sendTranslatedMessage(Entity entity, String text, Object... translationArgs) { - if (ModConfig.general.useStatusBar && entity instanceof EntityPlayerMP) { + if (entity instanceof EntityPlayerMP) { EntityPlayerMP player = (EntityPlayerMP) entity; - player.sendStatusMessage(new TextComponentTranslation(text, translationArgs), true); - } else { - chat(entity, text, translationArgs); + player.sendStatusMessage(new TextComponentTranslation(text, translationArgs), ModConfig.general.useStatusBar); } } diff --git a/src/main/java/org/dimdev/dimdoors/client/TileEntityEntranceRiftRenderer.java b/src/main/java/org/dimdev/dimdoors/client/TileEntityEntranceRiftRenderer.java index ba511359..4f464aac 100644 --- a/src/main/java/org/dimdev/dimdoors/client/TileEntityEntranceRiftRenderer.java +++ b/src/main/java/org/dimdev/dimdoors/client/TileEntityEntranceRiftRenderer.java @@ -41,12 +41,7 @@ public class TileEntityEntranceRiftRenderer extends TileEntitySpecialRenderer= 1) { - for (int i = 0; i < 1 + entrance.lockStatus; i++) { - renderKeyHole(entrance, x, y, z, i); - } + Vec3d offset = new Vec3d(entrance.orientation.getOpposite().getDirectionVec()).scale( + entrance.orientation == EnumFacing.NORTH || + entrance.orientation == EnumFacing.WEST || + entrance.orientation == EnumFacing.UP ? entrance.pushIn : entrance.pushIn - 1); + DimensionalWallRenderer.renderDimensionalWall( + x + offset.x, + y + offset.y, + z + offset.z, + //entrance.orientation.getHorizontalAngle(), + //entrance.orientation.getDirectionVec().getY() * 90, + entrance.orientation, + entrance.extendLeft + entrance.extendRight, + entrance.extendDown + entrance.extendUp, + getColors(entrance)); + + if (entrance.lockStatus >= 1) { + for (int i = 0; i < 1 + entrance.lockStatus; i++) { + renderKeyHole(entrance, x, y, z, i); } } } diff --git a/src/main/java/org/dimdev/dimdoors/shared/ModConfig.java b/src/main/java/org/dimdev/dimdoors/shared/ModConfig.java index e1bd3d20..fe13d3bc 100644 --- a/src/main/java/org/dimdev/dimdoors/shared/ModConfig.java +++ b/src/main/java/org/dimdev/dimdoors/shared/ModConfig.java @@ -11,10 +11,10 @@ import static net.minecraftforge.common.config.Config.*; @Config(modid = DimDoors.MODID, name = DimDoors.MODID, category = "") @Mod.EventBusSubscriber(modid = DimDoors.MODID) -public final class ModConfig { // TODO: localize the rest +public final class ModConfig { public static General general = new General(); - public static Pocket pockets = new Pocket(); + public static Pockets pockets = new Pockets(); public static World world = new World(); public static Dungeons dungeons = new Dungeons(); public static Monoliths monoliths = new Monoliths(); @@ -22,104 +22,98 @@ public final class ModConfig { // TODO: localize the rest public static class General { @Name("baseDimensionID") - @Comment({"Dimension ID of the first Dimensional Doors dimension. Other dimensions will use consecutive IDs.", - "It is strongly recommendended not to change this value. Only change it if it conflicts with other mods."}) + @LangKey("dimdoors.general.baseDimensionID") @RequiresWorldRestart public int baseDimensionID = 684; @Name("useStatusBar") - @Comment("When true, the status bar is used to relay status messages to the player, instead of the chat.") + @LangKey("dimdoors.general.useStatusBar") public boolean useStatusBar = true; @Name("closeDoorBehind") - @Comment("When true, Dimensional Doors will automatically close when the player enters their portal.") + @LangKey("dimdoors.general.closeDoorBehind") public boolean closeDoorBehind = true; - @Name("closeDoorBehind") - @Comment("Distance in blocks to teleport the player in front of the dimensional door.") - @RangeDouble(min = 0.5, max = 3) - public double teleportOffset = 1; + @Name("teleportOffset") + @LangKey("dimdoors.general.teleportOffset") + @RangeDouble(min = 0, max = 3) + public double teleportOffset = 0.5; + + @Name("riftBoundingBoxInCreative") + @LangKey("dimdoors.general.riftBoundingBoxInCreative") + public boolean riftBoundingBoxInCreative; } - public static class Pocket { - @Name("A_pocketGridSize") - @Comment("Sets how many chunks apart all pockets in any pocket dimensions should be placed.") + public static class Pockets { + @Name("pocketGridSize") + @LangKey("dimdoors.pockets.pocketGridSize") @RangeInt(min = 4) public int pocketGridSize = 32; - @Name("B_maxPocketSize") - @Comment({"Sets the maximum size of any pocket. A 'maxPocketSize' of 'x' will allow for pockets up to (x + 1) * (x + 1) chunks.", - "If this is set to any value bigger than 'pocketGridSize / 2', the value of 'pocketGridSize / 2' will be used instead."}) + @Name("maxPocketSize") + @LangKey("dimdoors.pockets.maxPocketSize") @RangeInt(min = 0) public int maxPocketSize = 15; - @Name("C_privatePocketSize") - @Comment({"Sets the minimum size of a newly created Private Pocket.", - "If this is set to any value bigger than 'maxPocketSize', the value of 'maxPocketSize' will be used instead."}) + @Name("privatePocketSize") + @LangKey("dimdoors.pockets.privatePocketSize") @RangeInt(min = 0, max = 7) public int privatePocketSize = 2; - @Name("D_publicPocketSize") - @Comment({"Sets the minimum size of a newly created Public Pocket.", - "If this is set to any value bigger than 'privatePocketSize', the value of 'privatePocketSize' will be used instead."}) + @Name("publicPocketSize") + @LangKey("dimdoors.pockets.publicPocketSize") @RangeInt(min = 0) public int publicPocketSize = 1; - @Name("Z_loadAllSchematics") - @Comment({"When true, all available Pocket Schematics will be loaded on game-start, even if the gridSize and pocketSize ", - "configuration fields would exclude these schematics from being used in 'naturally generated' pockets.", - "The /pocket command can be used to force-generate these pockets for dungeon building- or testing-purposes."}) + @Name("loadAllSchematics") + @LangKey("dimdoors.pockets.loadAllSchematics") public boolean loadAllSchematics = false; } public static class World { - @Name("A_clusterGenChance") - @Comment("Sets the chance (out of 1.0) that a cluster of Rift Scars will generate in a given chunk.") + @Name("clusterGenChance") + @LangKey("dimdoors.world.clusterGenChance") @RangeDouble(min = 0.0, max = 1.0) public double clusterGenChance = 0.0002; - @Name("A_gatewayGenChance") - @Comment("Sets the chance (out of 1.0) that a Transient Portal gateway will generate in a given chunk.") + @Name("gatewayGenChance") + @LangKey("dimdoors.world.gatewayGenChance") @RangeDouble(min = 0.0, max = 1.0) public double gatewayGenChance = 0.0015; - @Name("B_clusterDimBlacklist") - @Comment({"Dimension Blacklist for the generation of Rift Scar clusters. Add a dimension ID here to prevent generation in certain dimensions.", - "Default: []"}) + @Name("clusterDimBlacklist") + @LangKey("dimdoors.world.clusterDimBlacklist") public int[] clusterDimBlacklist = {}; - @Name("B_gatewayDimBlacklist") - @Comment({"Dimension Blacklist for the generation of Transient Portal gateways. Add a dimension ID here to prevent generation in certain dimensions.", - "Default: []"}) + @Name("gatewayDimBlacklist") + @LangKey("dimdoors.world.gatewayDimBlacklist") public int[] gatewayDimBlacklist = {}; } public static class Dungeons { @Name("maxDungeonDepth") - @Comment({"The depth at which limbo is located. If a Rift reaches any deeper than this while searching for a new ", - "destination, the player trying to enter the Rift will be sent straight to Limbo."}) - @RangeInt(min = 100) - public int maxDungeonDepth = 2000; + @LangKey("dimdoors.dungeons.maxDungeonDepth") + @RangeInt(min = 5) + public int maxDungeonDepth = 50; } public static class Monoliths { @Name("dangerousLimboMonoliths") - @Comment("When true, Monoliths in Limbo attack the player and deal damage.") + @LangKey("dimdoors.monoliths.dangerousLimboMonoliths") public boolean dangerousLimboMonoliths = false; @Name("monolithTeleportation") - @Comment("When true, being exposed to the gaze of Monoliths for too long, will cause the player to be teleported to the void above Limbo.") + @LangKey("dimdoors.monoliths.monolithTeleportation") public boolean monolithTeleportation = true; } public static class Limbo { @Name("universalLimbo") - @Comment({"When true, players are also teleported to Limbo when they die in any non-Pocket Dimension (except Limbo itself).", - "Otherwise, players only go to Limbo if they die in a Pocket Dimension."}) + @LangKey("dimdoors.limbo.universalLimbo") public boolean universalLimbo = false; @Name("hardcoreLimbo") - @Comment("When true, a player dying in Limbo will respawn in Limbo, making Eternal Fluid or Golden Dimensional Doors the only way to escape Limbo.") + @LangKey("dimdoors.limbo.hardcoreLimbo") public boolean hardcoreLimbo = false; } diff --git a/src/main/java/org/dimdev/dimdoors/shared/blocks/BlockDimensionalDoor.java b/src/main/java/org/dimdev/dimdoors/shared/blocks/BlockDimensionalDoor.java index 242612db..062a8b65 100644 --- a/src/main/java/org/dimdev/dimdoors/shared/blocks/BlockDimensionalDoor.java +++ b/src/main/java/org/dimdev/dimdoors/shared/blocks/BlockDimensionalDoor.java @@ -119,7 +119,9 @@ public abstract class BlockDimensionalDoor extends BlockDoor implements IRiftPro public TileEntityEntranceRift createNewTileEntity(World world, int meta) { TileEntityEntranceRift rift = new TileEntityEntranceRift(); rift.orientation = getStateFromMeta(meta).getValue(BlockDoor.FACING).getOpposite(); - rift.extendUp += 1; + if (DimDoors.proxy.isClient()) { + rift.extendUp += 1; + } return rift; } @@ -132,7 +134,7 @@ public abstract class BlockDimensionalDoor extends BlockDoor implements IRiftPro if (rift == null) { DimDoors.log.error("Rift tile entity was null when breaking block at " + new Location(world, pos) + ", please report this error."); } - if (rift.isPlaceRiftOnBreak() || rift.isRegistered() && RiftRegistry.instance().getSources(new Location(rift.getWorld(), rift.getPos())).size() > 0 && !rift.isAlwaysDelete()) { + if (rift.isLeaveScarWhenClosed() || rift.isRegistered() && RiftRegistry.instance().getSources(new Location(rift.getWorld(), rift.getPos())).size() > 0 && !rift.isAlwaysDelete()) { world.setBlockState(pos, ModBlocks.RIFT.getDefaultState()); // This isn't run when we change the block from within block break TileEntityFloatingRift newRift = (TileEntityFloatingRift) world.getTileEntity(pos); diff --git a/src/main/java/org/dimdev/dimdoors/shared/blocks/BlockDimensionalPortal.java b/src/main/java/org/dimdev/dimdoors/shared/blocks/BlockDimensionalPortal.java index cf60f2ee..59182c1d 100644 --- a/src/main/java/org/dimdev/dimdoors/shared/blocks/BlockDimensionalPortal.java +++ b/src/main/java/org/dimdev/dimdoors/shared/blocks/BlockDimensionalPortal.java @@ -62,8 +62,10 @@ public class BlockDimensionalPortal extends BlockDimensionalDoor { // TODO: conv public TileEntityEntranceRift createNewTileEntity(World world, int meta) { TileEntityEntranceRift rift = new TileEntityEntranceRift(); rift.orientation = getStateFromMeta(meta).getValue(BlockDoor.FACING).getOpposite(); - rift.extendUp += 1; - rift.pushIn = 0.5; + if (DimDoors.proxy.isClient()) { + rift.extendUp += 1; + rift.pushIn = 0.5; + } return rift; } } diff --git a/src/main/java/org/dimdev/dimdoors/shared/blocks/BlockFloatingRift.java b/src/main/java/org/dimdev/dimdoors/shared/blocks/BlockFloatingRift.java index 26114723..df8f541a 100644 --- a/src/main/java/org/dimdev/dimdoors/shared/blocks/BlockFloatingRift.java +++ b/src/main/java/org/dimdev/dimdoors/shared/blocks/BlockFloatingRift.java @@ -2,9 +2,12 @@ package org.dimdev.dimdoors.shared.blocks; import java.util.*; +import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.AxisAlignedBB; import org.dimdev.dimdoors.DimDoors; import org.dimdev.dimdoors.client.ParticleRiftEffect; +import org.dimdev.dimdoors.shared.ModConfig; import org.dimdev.dimdoors.shared.items.ModItems; import org.dimdev.dimdoors.shared.tileentities.TileEntityFloatingRift; import org.dimdev.ddutils.blocks.BlockSpecialAir; @@ -57,8 +60,15 @@ public class BlockFloatingRift extends BlockSpecialAir implements ITileEntityPro } @Override - public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { - return false; // TODO + @SuppressWarnings("deprecation") + public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, IBlockAccess world, BlockPos pos) { + if (ModConfig.general.riftBoundingBoxInCreative) { + EntityPlayer player = DimDoors.proxy.getLocalPlayer(); + if (player != null && player.isCreative()) { + return blockState.getBoundingBox(world, pos); + } + } + return null; } @Override diff --git a/src/main/java/org/dimdev/dimdoors/shared/pockets/PocketTemplate.java b/src/main/java/org/dimdev/dimdoors/shared/pockets/PocketTemplate.java index 98a97b29..0a00bec1 100644 --- a/src/main/java/org/dimdev/dimdoors/shared/pockets/PocketTemplate.java +++ b/src/main/java/org/dimdev/dimdoors/shared/pockets/PocketTemplate.java @@ -57,16 +57,16 @@ public class PocketTemplate { } } - public static void replacePlaceholders(Schematic parSchematic) { // TODO: it should be possible to place a schematic without replacing placeholders + public static void replacePlaceholders(Schematic schematic) { // TODO: rift inheritance rather than placeholders // Replace placeholders (some schematics will contain them) List tileEntities = new ArrayList<>(); - for (NBTTagCompound tileEntityNBT : parSchematic.tileEntities) { + for (NBTTagCompound tileEntityNBT : schematic.tileEntities) { if (tileEntityNBT.hasKey("placeholder")) { int x = tileEntityNBT.getInteger("x"); int y = tileEntityNBT.getInteger("y"); int z = tileEntityNBT.getInteger("z"); - IBlockState state = parSchematic.palette.get(parSchematic.blockData[x][y][z]); + IBlockState state = schematic.palette.get(schematic.blockData[x][y][z]); NBTTagCompound newNBT; switch (tileEntityNBT.getString("placeholder")) { @@ -115,11 +115,11 @@ public class PocketTemplate { tileEntities.add(tileEntityNBT); } } - parSchematic.tileEntities = tileEntities; + schematic.tileEntities = tileEntities; List entities = new ArrayList<>(); - for (NBTTagCompound entitiesNBT : parSchematic.entities) { + for (NBTTagCompound entitiesNBT : schematic.entities) { if (entitiesNBT.hasKey("placeholder")) { double x = entitiesNBT.getDouble("x"); double y = entitiesNBT.getDouble("y"); @@ -143,7 +143,7 @@ public class PocketTemplate { entities.add(entitiesNBT); } } - parSchematic.entities = entities; + schematic.entities = entities; } public void place(Pocket pocket) { @@ -241,7 +241,7 @@ public class PocketTemplate { if (linkProperties != null) rift.setProperties(linkProperties); rift.setDestination(rift.getProperties() == null || !rift.getProperties().oneWay ? linkTo : null); if (rift instanceof TileEntityEntranceRift && !rift.isAlwaysDelete()) { - ((TileEntityEntranceRift) rift).setPlaceRiftOnBreak(true); // We modified the door's state + ((TileEntityEntranceRift) rift).setLeaveScarWhenClosed(true); // We modified the door's state } } } diff --git a/src/main/java/org/dimdev/dimdoors/shared/rifts/TileEntityRift.java b/src/main/java/org/dimdev/dimdoors/shared/rifts/TileEntityRift.java index 2107e736..3ea5080d 100644 --- a/src/main/java/org/dimdev/dimdoors/shared/rifts/TileEntityRift.java +++ b/src/main/java/org/dimdev/dimdoors/shared/rifts/TileEntityRift.java @@ -7,7 +7,6 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.play.server.SPacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ITickable; import net.minecraftforge.common.DimensionManager; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -23,7 +22,7 @@ import org.dimdev.dimdoors.shared.rifts.registry.RiftRegistry; import javax.annotation.Nonnull; -@NBTSerializable public abstract class TileEntityRift extends TileEntity implements ITickable { // TODO: implement ITeleportSource and ITeleportDestination +@NBTSerializable public abstract class TileEntityRift extends TileEntity { // TODO: implement ITeleportSource and ITeleportDestination /*@Saved*/ @Nonnull @Getter protected RiftDestination destination; // How the rift acts as a source @Saved @Getter protected LinkProperties properties; // How the rift acts as a target, and properties that affect how it can link to other rifts diff --git a/src/main/java/org/dimdev/dimdoors/shared/tileentities/TileEntityEntranceRift.java b/src/main/java/org/dimdev/dimdoors/shared/tileentities/TileEntityEntranceRift.java index 479b0b47..1a713347 100644 --- a/src/main/java/org/dimdev/dimdoors/shared/tileentities/TileEntityEntranceRift.java +++ b/src/main/java/org/dimdev/dimdoors/shared/tileentities/TileEntityEntranceRift.java @@ -5,6 +5,8 @@ import net.minecraft.entity.EntityLiving; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.dimdev.ddutils.WorldUtils; import org.dimdev.ddutils.nbt.NBTUtils; import org.dimdev.annotatednbt.Saved; @@ -20,20 +22,20 @@ import net.minecraft.util.EnumFacing; import java.util.Random; -// TODO: merge horizontal and vertical entrances' render code into one, and support custom sizes @NBTSerializable public class TileEntityEntranceRift extends TileEntityRift { - @Saved @Getter /*package-private*/ boolean placeRiftOnBreak = false; - @Saved @Getter /*package-private*/ boolean closeAfterPassThrough = false; - @Saved @Getter public boolean shouldRender = true; - @Saved @Getter public byte lockStatus = 0; + @Saved @Getter protected boolean leaveScarWhenClosed = false; + @Saved @Getter protected boolean closeAfterPassThrough = false; // TODO: doesn't make sense lore-wise for doors, split into separate tile entity - // Set by the block TODO: get rid of these, calculate client-side! - @Saved public EnumFacing orientation; - @Saved public double extendUp = 0.5; // Use += to set these. - @Saved public double extendDown = 0.5; - @Saved public double extendLeft = 0.5; - @Saved public double extendRight = 0.5; - @Saved public double pushIn = 0.01; + // Set by the block on tile entity creation, can't get from the block, it's not necessarily a door + public EnumFacing orientation; + + // Render info, use += to change these on block tile entity creation + @SideOnly(Side.CLIENT) public double extendUp = 0.5; + @SideOnly(Side.CLIENT) public double extendDown = 0.5; + @SideOnly(Side.CLIENT) public double extendLeft = 0.5; + @SideOnly(Side.CLIENT) public double extendRight = 0.5; + @SideOnly(Side.CLIENT) public double pushIn = 0.01; + @SideOnly(Side.CLIENT) public byte lockStatus = 0; // TODO @Override public void copyFrom(TileEntityRift oldRift) { @@ -42,22 +44,13 @@ import java.util.Random; TileEntityEntranceRift oldEntranceRift = (TileEntityEntranceRift) oldRift; closeAfterPassThrough = oldEntranceRift.closeAfterPassThrough; } - placeRiftOnBreak = true; + leaveScarWhenClosed = true; } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); NBTUtils.readFromNBT(this, nbt); } - @Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { - nbt = super.writeToNBT(nbt); - return NBTUtils.writeToNBT(this, nbt); - } + @Override public NBTTagCompound writeToNBT(NBTTagCompound nbt) { nbt = super.writeToNBT(nbt); return NBTUtils.writeToNBT(this, nbt); } - @Override - public void update() { - - } - - public void setPlaceRiftOnBreak(boolean placeRiftOnBreak) { this.placeRiftOnBreak = placeRiftOnBreak; markDirty(); } - public void setShouldRender(boolean shouldRender) { this.shouldRender = shouldRender; markDirty(); } + public void setLeaveScarWhenClosed(boolean leaveScarWhenClosed) { this.leaveScarWhenClosed = leaveScarWhenClosed; markDirty(); } public void setLockStatus(byte lockStatus) { this.lockStatus = lockStatus; markDirty(); } public void setCloseAfterPassThrough(boolean closeAfterPassThrough) { this.closeAfterPassThrough = closeAfterPassThrough; markDirty(); } @@ -65,7 +58,7 @@ import java.util.Random; public boolean teleport(Entity entity) { boolean status = super.teleport(entity); if (riftStateChanged && !alwaysDelete) { - placeRiftOnBreak = true; + leaveScarWhenClosed = true; markDirty(); } return status; @@ -73,7 +66,7 @@ import java.util.Random; @Override public void teleportTo(Entity entity, float fromYaw, float fromPitch) { // TODO: teleportOffset for all rifts instead? - Vec3d targetPos = new Vec3d(pos).addVector(0.5, 0, 0.5).add(new Vec3d(orientation.getDirectionVec()).scale(ModConfig.general.teleportOffset)); + Vec3d targetPos = new Vec3d(pos).addVector(0.5, 0, 0.5).add(new Vec3d(orientation.getDirectionVec()).scale(ModConfig.general.teleportOffset + 0.5)); if (relativeRotation) { float yaw = getDestinationYaw(entity.rotationYaw) + entity.rotationYaw - fromYaw; float pitch = entity instanceof EntityLiving ? entity.rotationPitch : getDestinationPitch(entity.rotationPitch) + entity.rotationPitch - fromPitch; @@ -86,7 +79,7 @@ import java.util.Random; @Override public void teleportTo(Entity entity) { - Vec3d targetPos = new Vec3d(pos).add(new Vec3d(orientation.getDirectionVec()).scale(ModConfig.general.teleportOffset)); + Vec3d targetPos = new Vec3d(pos).add(new Vec3d(orientation.getDirectionVec()).scale(ModConfig.general.teleportOffset + 0.5)); TeleportUtils.teleport(entity, WorldUtils.getDim(world), targetPos.x, targetPos.y, targetPos.z, orientation.getHorizontalAngle(), 0); } @@ -130,11 +123,13 @@ import java.util.Random; return orientation.getOpposite().getFrontOffsetY() * 90; } - @Override public float getDestinationYaw(float entityYaw) { + @Override + public float getDestinationYaw(float entityYaw) { return orientation.getHorizontalAngle(); } - @Override public float getDestinationPitch(float entityPitch) { + @Override + public float getDestinationPitch(float entityPitch) { return 0; } } diff --git a/src/main/java/org/dimdev/dimdoors/shared/tools/SchematicGenerator.java b/src/main/java/org/dimdev/dimdoors/shared/tools/SchematicGenerator.java index 97cd3091..e2ec44b5 100644 --- a/src/main/java/org/dimdev/dimdoors/shared/tools/SchematicGenerator.java +++ b/src/main/java/org/dimdev/dimdoors/shared/tools/SchematicGenerator.java @@ -156,7 +156,7 @@ public final class SchematicGenerator { .build()); rift.setProperties(link); - rift.setPlaceRiftOnBreak(true); + rift.setLeaveScarWhenClosed(true); NBTTagCompound tileNBT = rift.serializeNBT(); tileNBT.setInteger("x", (size - 1) / 2); tileNBT.setInteger("y", 5); diff --git a/src/main/java/org/dimdev/pocketlib/Pocket.java b/src/main/java/org/dimdev/pocketlib/Pocket.java index 68359b94..1047275d 100644 --- a/src/main/java/org/dimdev/pocketlib/Pocket.java +++ b/src/main/java/org/dimdev/pocketlib/Pocket.java @@ -12,9 +12,9 @@ import org.dimdev.ddutils.nbt.NBTUtils; @NBTSerializable public class Pocket implements INBTStorable { @Saved @Getter protected int id; - @Saved @Getter protected int x; // Grid x TODO: rename to gridX and gridY, or just convert to non-grid dependant coordinates + @Saved @Getter protected int x; // Grid x TODO: convert to non-grid dependant coordinates @Saved @Getter protected int z; // Grid y - @Saved @Getter @Setter protected int size; // TODO: size = sizeInChunks - 1 ???!!! TODO: non chunk-based size, better bounds such as minX, minZ, maxX, maxZ, etc. + @Saved @Getter @Setter protected int size; // TODO: non chunk-based size, better bounds such as minX, minZ, maxX, maxZ, etc. @Saved @Getter @Setter protected VirtualLocation virtualLocation; @Getter int dim; // Not saved diff --git a/src/main/resources/assets/dimdoors/lang/en_US.lang b/src/main/resources/assets/dimdoors/lang/en_US.lang index 29fadc94..ab71c346 100644 --- a/src/main/resources/assets/dimdoors/lang/en_US.lang +++ b/src/main/resources/assets/dimdoors/lang/en_US.lang @@ -141,15 +141,55 @@ dimdoors.general=General Options dimdoors.general.tooltip=General configuration options for the mod dimdoors.general.baseDimensionID=Base Dimension ID dimdoors.general.baseDimensionID.tooltip=Dimension ID of the first Dimensional Doors dimension. Other dimensions will use consecutive IDs. It is strongly recommended to leave this to the default value. -dimdoors.general.useStatusBar.name=Status Bar Messages -dimdoors.general.useStatusBar.comment=Whether to use the status bar to send messages rather than the chat. +dimdoors.general.useStatusBar=Status Bar Messages +dimdoors.general.useStatusBar.tooltip=Whether to use the status bar to send messages rather than the chat. +dimdoors.general.closeDoorBehind=Close Door Behind +dimdoors.general.closeDoorBehind.tooltip=When true, Dimensional Doors will automatically close when the player enters their portal. +dimdoors.general.teleportOffset=Teleport Offset +dimdoors.general.teleportOffset.tooltip=Distance in blocks to teleport the player in front of the dimensional door. +dimdoors.general.riftBoundingBoxInCreative=Rift Bounding Box in Creative +dimdoors.general.riftBoundingBoxInCreative.tooltip=When true, shows the bounding boxes of floating rifts when the player is in creative. + dimdoors.pockets=Pocket Dimension Options dimdoors.pockets.tooltip=Options that determine the spacing and maximum size of pockets in the pocket world -dimdoors.world=Worldgen Options +dimdoors.pockets.pocketGridSize=Pocket Grid Size +dimdoors.pockets.pocketGridSize.tooltip=Sets how many chunks apart all pockets in any pocket dimensions should be placed. +dimdoors.pockets.maxPocketSize=Maximum Pocket Size +dimdoors.pockets.maxPocketSize.tooltip=Sets the maximum size of any pocket. A size of x will allow for pockets up to (x + 1) * (x + 1) chunks. If this is set to any value bigger than pocketGridSize / 2, the value of pocketGridSize / 2 will be used instead. +dimdoors.pockets.privatePocketSize=Private Pocket Size +dimdoors.pockets.privatePocketSize.tooltip=Sets the minimum size of a newly created Private Pocket. If this is set to any value bigger than maxPocketSize, the value of maxPocketSize will be used instead. +dimdoors.pockets.publicPocketSize=Public Pocket Size +dimdoors.pockets.publicPocketSize.tooltip=Sets the minimum size of a newly created Public Pocket. If this is set to any value bigger than privatePocketSize, the value of privatePocketSize will be used instead. +dimdoors.pockets.loadAllSchematics=Load All Schematics +dimdoors.pockets.loadAllSchematics.tooltip= When true, all available Pocket Schematics will be loaded on game-start, even if the gridSize and pocketSize configuration fields would exclude these schematics from being used in 'naturally generated' pockets. The /pocket command can be used to force-generate these pockets for dungeon building or testing purposes. + +dimdoors.world=World Generation Options dimdoors.world.tooltip=Options that determine where dimensional gateways and rift clusters can be generated and at what frequency +dimdoors.world.clusterGenChance=Cluster Generation Chance +dimdoors.world.clusterGenChance.tooltip=Sets the chance (out of 1.0) that a cluster of Rift Scars will generate in a given chunk. +dimdoors.world.gatewayGenChance=Gateway generation chance +dimdoors.world.gatewayGenChance.tooltip=Sets the chance (out of 1.0) that a Transient Portal gateway will generate in a given chunk. +dimdoors.world.clusterDimBlacklist=Cluster Dimension Blacklist +dimdoors.world.clusterDimBlacklist.tooltip=Dimension Blacklist for the generation of Rift Scar clusters. Add a dimension ID here to prevent generation in certain dimensions. +dimdoors.world.gatewayDimBlacklist=Gateway Dimension Blacklist +dimdoors.world.gatewayDimBlacklist.tooltip=Dimension Blacklist for the generation of Transient Portal gateways. Add a dimension ID here to prevent generation in certain dimensions. + dimdoors.dungeons=Dungeon Options dimdoors.dungeons.tooltip=Options that affect the generation of pocket dungeons +dimdoors.dungeons.maxDungeonDepth.tooltip=Maximum Dungeon Depth +dimdoors.dungeons.maxDungeonDepth.tooltip=The depth at which limbo is located. If a Rift reaches any deeper than this while searching for a new destination, the player trying to enter the Rift will be sent straight to Limbo. + dimdoors.monoliths=Monolith Options dimdoors.monoliths.tooltip=Options that determine how dangerous monoliths are +dimdoors.monoliths.dangerousLimboMonoliths=Dangerous Limbo Monoliths +dimdoors.monoliths.dangerousLimboMonoliths.tooltip=When true, Monoliths in Limbo attack the player and deal damage. +dimdoors.monoliths.monolithTeleportation=Monolith Teleportation +dimdoors.monoliths.monolithTeleportation.tooltip=When true, being exposed to the gaze of Monoliths for too long, will cause the player to be teleported to the void above Limbo. + dimdoors.limbo=Limbo Options dimdoors.limbo.tooltip=Options that control various aspects of the Limbo dimension +dimdoors.limbo.universalLimbo=Universal Limbo +dimdoors.limbo.universalLimbo.tooltip=When true, players are also teleported to Limbo when they die in any non-Pocket Dimension (except Limbo itself). Otherwise, players only go to Limbo if they die in a Pocket Dimension. +dimdoors.limbo.hardcoreLimbo=Hardcore Limbo +dimdoors.limbo.hardcoreLimbo.tooltip=When true, a player dying in Limbo will respawn in Limbo, making Eternal Fluid or Golden Dimensional Doors the only way to escape Limbo. + diff --git a/src/main/resources/assets/dimdoors/textures/other/key_outline.png b/src/main/resources/assets/dimdoors/textures/other/key_outline.png new file mode 100644 index 0000000000000000000000000000000000000000..7cc27136e9bd03df33f2577a1b92d52282be23a2 GIT binary patch literal 2340 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/dimdoors/textures/other/keyhole.png b/src/main/resources/assets/dimdoors/textures/other/keyhole.png new file mode 100644 index 0000000000000000000000000000000000000000..7bb3ea329e5152d3ebb8afb07324af829cdf6ec4 GIT binary patch literal 16819 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 literal 0 HcmV?d00001