- Add netherProbability parameter to the random dungeon function, and set it to depth/50 for now (I'll make it non-linear in a future version)
- Add a reusable weightedRandom method to MathUtils
- Make config option to allow for random public pocket size, modify random template code to be able to add variations for "singular" templates
- Load all pocket sizes but only create ones smaller than maxPocketSize naturally. This way an admin can still manually create a pocket larger than the max size using /dimpocket
- Javadocs
- Null checks for a few methods
- Load schematics when plugin loads rather than when world loads
does adding to groups work?
-Enabled Door opening and closing sounds (BlockDimDoorBase L66)
-Repaired Double placement of doors and Doors swinging open upon
placement (ItemDoorBase L78)
-Added Forge version dependency
-Made sure that Warp Doors always lead to a non-pocket dimension if they
lead anywhere at all
-Added Event checks on Players entering chunks in/and pocket dimensions
-Changed the Pocket placement algorithm. Instead of following a
rectangular spiral path expanding outwards from (0;0), Pockets now get
placed in a fan-shaped area expanding from (0;0) to (infinity;infinity).
-Changed maximum configurable grid size and defaulted to that
-Added a way to retrieve the Pocket ID from a Location
-Schematic loading streams are only closed if they were opened to begin
with
-Added some easier ways of testing if a Dimension is a Pocket dimension
-Added tab completions to the teleport command
-Made tab completions for the pocket command actually complete what is
already typed
-Added some String utilities to support the previous two changes
-Added Try- Catch block to prevent a TileEntity not getting loaded right
from causing the Pocket from registering (which caused respective
Schematic placements on the same position, which replaced unregistered
Doors, to crash as well)
-Completed command to force-generate Dungeon Pocket Schematics using
their directory (/group) and name
-Schematics now inherrit their name from their file name if it's not set
in their NBT
Warning:
-Quite a few of the pockets themselves show errouneous behaviour when
you try to generate them.
-Added crude json files to load in all Dungeon schematics from previous
versions of DimDoors, into the game
-Added an extra failsafe before Teleporting to a newly generated
Dungeon, checking if the Location is not-null instead of crashing
Notes:
-Rather often, a door to a Dungeon will say that "Teleportation failed".
I think this is because the Dungeon Schematic in question fails to
include a list of its Tile-Entities and their corresponding data.
-Changed build number
-The properties of rifts do not get read from the schematic
-Added the start of what is going to be a system to force-generate a
particular Dungeon Pocket schematic
-Repaired a fault in choosing a random Dungeon Template
-Restructured the loading of Schematic files from disk, to make the code
more concise and less repetitive.
-Remedied bug where Rifts in Dungeon Schematics did not get registered,
because their ID was not -1 from the start.
-Corrected naming of Chaos Door Block in the American localization
-Added Dutch localisation
-Added json file that loads 2 of the Dungeon Schematics (for now for
testing purposes)
Todo:
-Apparently, DimDoors in the schematics don't have the right orientation
until they get rendered. Maybe they should update their orientation for
teleportation from the bottom block of the door
-Add a command to generate a specific schematic as a Dungeon Pocket.
-Repaired Chaos Doors teleporting players to Personal Dimensions, by
*actually saving* the personal-door-ids list in the riftregistry to
disk.
-Added rough method to use GradleStart in Netbeans, however this starts
Minecraft in the wrong root directory, so I commented it out for now
-Merged BlockDimWall and BlockLimbo classes into one
-Added a setup for teleportation to the overworld by Eternal Fabric
TODO
-Rename BlockDimWall to BlockFabric
-Redo the Eternal and Unraveled Fabric textures
-Make Eternal Fabric teleportation actually work on impact
-Delayed teleporting so it gets executed on DDTileEntityBase.update() to
prevent players from randomly not being moved
-Added some fields that need to be saved on worldSave
-Made Personal Pockets and Doors work
-Pockets don't register in their constructor anymore
-Repaired eternal loops in Pocket and Rift Registries
-Made the getX and getZ methods truly recursive
-Fixed TileEntity blockPos mismatch after reading from schematic.
-Tried a lot of stuff in the TeleporterDimDoors class, to finetune
teleportation.
-Teleportation doesn't seem to work flawlessly anymore (if it ever did
at all)
-included flow-math library in the jar file on "build"
-fix for public pockets' depthZeroLocation's calculation
-TeleportCommand got weakened a little
-Repaired Survival and inter-dimensional (non vanilla dimension)
teleporting
-Added some missing javadoc to utility classes
-Corrected transformLocationRandomly
-Made Location serializable
-Corrected mistake in commented out generation of and generated default
private and public pockets.
Todo:
-Loading a world with a generated pocket, crashes the game with an
infinite loop. Ergo, the registering of Pockets needs to be done
somewhere else than in their constructor.
-Implemented different variations for determining where different doors
teleport the player, if they link at all, etc.
-Implemented different variations for determining the teleport location
in case of a player teleporting to a door, rift, trapdoor, etc.
-Rifts now unregister and unpair if the doors are broken.
-Players' UUIDs now get registered to a Pocket if a player enters them
via any rift.
-Riftblade now works instantaneously, instead of placing a transient
door.
TODO
-Maybe the Transient door does not work correctly right now
-Added (auto-generated) default private and public pockets and changed
the jsons,
-Commented out auto-generation code at the bottom of Schematic.java.
-Fixed a stupid method call mistake in PocketRegistry that made stuff
fail miserably.
-Made sure that a size 0 pocket schematic can be 16 blocks.
-Added an "OverWorld location reference" to each door (that offsets more
if you go deeper into dungeon pockets)
-Made sure that the entrance door of a Pocket is a Warp Door if the
Pocket has one
-Made sure that the depth of Dungeon Pockets is always at least 1
-Added some separate teleportation behaviours for different types of
Rifts
-Minor bug fixes
-Added separate Block class for Chaos Door
-Set up Personal DimDoor to create its own type of tile-entity
-Added flag "2" to update blocks upon PocketTemplate placement to
prevent non-defaultstate doors from breaking upon placement.
-Used write- and read- Compressed instead of GZIP Streams
-Closed the output stream
-Added canRiftBePaired field to Rift tile entities
-Added Chaos- and Personal- Door Rift Tile Entities
-Removed statement where I falsely assumed that a meta of 0 meant that
the blockstate was the default.
-Corrected several other mistakes in Schematic.java
-Had to make sure that the blockstate of ancient fabric didn't get
turned into fabric of reality again...
-Prepared code accessibility for placement of Pockets
-Added method to save schematic nbt to a GZip file on disk.
Todo:
-Discovered that Schematics don't get the correct names for their blocks
upon writing themselves to NBT.
-Made the PocketRegistry use the toString() values of the
EnumPocketTypes, to save its maps in an NBTTagCompound instead of using
the indexes of those Enums to store the maps in NBTTagLists
-Implemented Pockets' UID being determined by their EnumPocketType and
an integer ID
-Fixed some double and triple registering of Pockets
-Fixed a minor major typo in SchematicHandler that prevented
old-format-schematics from being loaded from disk
-Fixed an "index-out-of-bounds-like" typo and a [ character being read
as a special character in the Schematic class
-Restructured and moved dimension files (again)
-Edited the defaultPublic- and -Personal.json files to a final-ish form
-Added another dummy schematic, but now in the new schematic format
-Added the old dungeon pocket schematics to the assets
-Tested loading of .schem and .schematic files from disk as well as from
the mod jar (successful, btw)
-Added a boolean to the config class, that shows the player a message
upon joining the world, if it is false and the mod version is not alpha.
Meant to assure that config defaults are set correctly (in code) upon
beta- or release- distribution of the mod.
# Conflicts:
# src/main/java/com/zixiken/dimdoors/shared/DDProxyCommon.java
# src/main/java/com/zixiken/dimdoors/shared/PocketPlacer.java
# src/main/java/com/zixiken/dimdoors/shared/SchematicHandler.java
# src/main/java/com/zixiken/dimdoors/shared/TeleportHelper.java
# src/main/java/com/zixiken/dimdoors/shared/world/PocketProvider.java
-Resolved all merge conflicts.
-Removed a few unused imports
-Refractored (moved) new classes from the Worlds branch to the new
package structure that came from the Pockets branch
-Changed variant size values of the default empty pocket jsons, because
otherwise they would crash the game on default config pers/pub pocket
size.
-BlockRift doesn't cause suffocation damage anymore
-Added config option for Dimension ID's
-Added correct method for opening schematic files from File
-Finished "dictionary" for converting dimdoors blocks from the old
schematics to new schematics.
-Added a special "translation-case" for Ancient Fabric, because I am not
going to write a complete method just because one block deviates.
-Added "null-checks" for each non-required field in schematics (new
format) while reading them from NBT and set some corresponding default
values for the fields that can be "null"
-Added a few default pocket jsons
-Errors on world-load were because the above were missing.
-Added a testing schematic (old schematic format)
-Made everything work somehow
-Implemented a way to write a schematic to NBT
-Implemented a way to read an old DD schematic from NBT
Todo:
-Complete the lists of old DD block names and map them to new ones.
-Implement a method to read schematics and jsons from jar as well as
from config directory
-Made sure that a BlockRift is not replacable and that you can walk
through them. (It hurts though, but we can say that that's a feature)
-Player now gets teleported on the ground in front of the rift, instead
of 1 block in the air.
-Implemented methods to register unpaired rifts at their pockets'
respective depth
-Added ItemDimDoorTrancient to make the riftblade's functionality
consistent with the placement of dimdoors on rifts
# Conflicts:
# src/main/java/com/zixiken/dimdoors/items/ItemDoorBase.java
# src/main/java/com/zixiken/dimdoors/tileentities/DDTileEntityBase.java
Conflicts were small and are resolved
-Implemented a way to load these schematics
-Implemented a way to place these schematics
-Removed "ye olde ways" (Pillar-ways)
Todo:
-Finding out how and where TileEntities are being created wrongly.
-Make pocket-generation a lot less "coupled". Just store the RiftIDs in
the Pocket and afterwards ask the pocket for a random RiftID
-Do some code cleanup in the SchematicHandler class
-Config Dim ID def: 684
-Added dependency on Vazkii's Pillar mod for "schematic" loading
-Added config directory for DimDoors
-Fixed entrance door placement coords
-Refractored some methods
-Added json-reader functionality
-Code compiles now
Todo:
-Make code added in SchematicHandler more modular
-Game gets stuck on world-load. Probably because the default json file
for "defaultPersonal" is not available yet at the saves directory.
-Changed some method names
-Fixed a mistake in registering a new pocket upon generation
-Added some get functions for privates
-Implemented functionality for randomising what dungeon pocket may be
generated upon entering an unlinked DimDoor.
Todo:
-Still the same
-Valid Pocket schematics will be loaded on world-load
-Created an EnumPocketType instead of the integer to avoid confusion and
make expansion to more types easier.
-Renamed PocketPlacer to PocketTemplate
-Implemented Pocket-Template's placement of the default walls, floor,
roof and door
-Updated Forge to latest
Todo:
-Actually reading the schematic into memory
-Placing the schematic
-Added some crafting recipes
-Made some things render correctly
-Cooler texture for the Transdimensional Trapdoor
-Made some things show their name correctly
-Added a configs class to handle the configs
-Rewrote some of the save handling of the RiftRegistry
Still needed:
-Some dimensions to place pockets in
-Actual loading of json and schematic files into memory
-Actual placement of the pockets (+ door placement and stuff)
Repo does not compile right now!¡!
Made teleporting check whether door is opened and close it again on
teleportation.
Added some more debug logging.
Made the teleportation methods one "string" of boolean methods,
returning false if anything would go amiss.
Implemented 150 ticks waiting time inbetween teleports
finetuned getTeleportTargetLocation method, but it somehow gets reset on
server restart.
Main:
Removed "custom" code for DimDoors' Placement and rewrote it
When right-clicking rifts with any Dimensional Door, the game will try to place the Dimensional Door onto the rift.
Rifts will now enherit their properties from broken DimDoors and Dimdoors will enherit their properties from rifts they are placed over.
Other:
Made the DimDoors logger a bit more powerful.
Made RiftRegistry reset on server-load
Created a setup for the RiftConnectionTool Item.
Layout:
Fixed TileEntityRift.java's indentation
Changed some variable names
Authored by Robijnvogel and squashed by Waterpicker.
-Due to testing, found out that "RiftRegistry.nextRiftID"gets saved and
loaded correctly.
-DimDoors are no longer placeable on leaves or glass (ItemDoorBase.java)
-DimDoors will no longer be placed through left-clicking
(EventHookContainer.java)
-Relocated call to DDTileEntityBase.register() from its constructor to
ItemDoorBase right after the door gets placed. Which means that that
whole constructor and its overrides in other classes are not needed
anymore.
-Added failsafe, so that a DDTileEntityBase that is already registered,
doesn't register again.
Repaired a derp I did in which the Tile Entities did not have a "World"
to get the ID from for the Location to turn into a Location. I needed to
change a lot of constructors to include said "World" as a parameter.
Set up DDTileEntityBase to save after it's paired, registered or
unpaired and actually wrote the readFromNBT and writeToNBT for that.
Merged functionality of "RiftHandler" class into "RiftRegistry" class
Moved the "Location" class
Why the RiftRegistry couples the Rift ID to the Rift **location** and
the PocketRegistry couples the Pocket ID to the actual Pocket
**instance**:
-Each Rift is a Tile-Entity, which means that it has its infromation can
be stored using the Tile-Entitiy's information saving system.
-Each Pocket is barely more than an information storage container, which
depends on having an external information saving system, which the
PocketRegistry provides for it.
If there is a problem reading the blacklist file from disk, previously,
null would be returned from the DDSaveHandler.readBlacklist method. This
would result in a crash later on down the line when we tried to iterate
the blacklist. Now we return an empty array. I'd like to be able to
diagnose the issues causing the blacklist file to be corrupted, but
unfortunately when this issue crops up, people only post the crash :(
If the server disconnected you due to a timeout or whatever, the pocket
manager would appropriately unload all dimension & pocket data, but it
would do so moments before the world unloaded, meaning that entities would
sometimes, on update or as part of their renderer, attempt to access the
dimensional data. This places a new guard condition that attempts to stop
that from crashing the client.
On startup, existing sub-dimensions of personal dimensions were being
given the wrong worldprovider by the launch code. The reason for this is
that subdimensions are not added to the player -> dimension mapping for
personal dimensions, because there is only one canonical "personal"
dimension. The launch code was using presence or absence in the mapping
to determine whether a dimension is personal, rather than the dimension
type. This is now fixed.
Some users were reporting very sporatic crashes in
generateLightBrightnessTable() when the server was starting up. It's
possible that very occasionally, the server will register the pocket
dimension before any pocket dimension data is initialized, forcing the
light brightness table to get generated server side with bad values.
In some cases (such as another mod crashing on startup or something), the
server shutdown even was getting called before anything was actually
initialize. In these cases, some uninitialized objects were having
cleanup methods called on them, when they were null. There are now guard
conditions to prevent the resulting NPE's.
Major change is addition of fractal rift rendering, currently first
pass.
Curves are registered and pregenerated in mod_pocketDim.
Rifts look up these curves, choose one, rotate it, and render it.
The render is a TESR that does stuff. Hard to explain, look at
RenderRift in the code and look at the actual rifts in game to get an
idea of what it does.
I had to add a triangulation library to accomplish this. Will hopefully
do something else that drag around all this.
(I tried(and used comments))
Fixed a crash from manipulating rift data on the client side. I let this
happen because it seemed like TileEntityRift already did that before.
This crash also exposed another issue: that server-side functions are
being used on the client side. I'm not sure how pervasive this is but
some client dimensions are being constructed with the server-side
constructor.
1. Fixed a design flaw in PocketManager. We originally assumed that all
requests to PocketManager.getDimensionData() had to be legitimate
requests for dimensions that existed. That was true in most cases, but
for things like processing user commands, it was dangerously optimistic.
It was possible that a flaw in DD's usage of that function could be
exploited by a player to trick the mod into pre-registering dimension
data for a non-existent dimension. That would declare the dimension as a
root. DD would crash later if Forge ever allocated that ID for a pocket
dimension. The new implementation is almost the same as the old one, but
allows us to differentiate between cases when we can eagerly create
dimension data, and cases in which the absence of a dimension should
cause a crash to alert us of a design flaw.
2. Remove the pocket regeneration code from PocketBuilder. We simply
don't support pocket regeneration and it's unlikely it'll ever be
implemented because it's a difficult issue. Wiping out pockets
completely is easier. We can always recover the code from this commit if
it's needed later.
3. Minor changes: removed some debug prints from PocketManager and
changed some static accesses in PocketBuilder.
Fixed an issue. DD would crash when MC created a completely new world
because onChunkLoad() would be called before onWorldLoad(). That's not
the usual order. PocketManager would be unloaded at that point and would
return a null dimension.
Autocorrected indentation in PocketManager. I'll be working on changing
PocketManager to prevent the risk of creating data for a non-existent
dimension through a bad call to getDimensionData().
Made some improvements to TileEntityRift. The main reason for these
changes was to remove the field nearestRift - we should not hold on to
references to links. Now we simply track the location of the nearest
rift. I also confirmed that closeRift() and updateNearestRift() must be
allowed to run on both the client and the server. If the client doesn't
run those functions, then adjacent rifts don't connect as expected and
the rift removal animation doesn't work.
Removed a pointless check in yCoordHelper and corrected some comments in
RiftRegenerator. It turns out that ChunkProviderServer.chunkExists()
returns whether a chunk is loaded, not whether it has already been
created.
Removed unnecessary code for the Transdimensional Trapdoor. Most of it
was code dedicated to updating TileEntityTransTrapdoor.hasRift. That
flag was never used for anything.
1. Added code so that Transdimensional Trapdoors detect that they have
been broken and schedule rift regeneration at their location. This had
previously been neglected. Trapdoors deserve a little more attention.
2. Tweaked the breakBlock() code for BlockRift and BaseDimDoor so that
rift regeneration is only scheduled if the underlying block was removed.
We don't want that to happen if the only change was for metadata.
1. Removed code from BaseDimDoor that was already implemented almost
identically in BlockDoor. Clarified some uses of setBlock() by changing
them to setBlockToAir() instead.
2. Removed TileEntityDimDoor.invalidate() and moved the regeneration
scheduling code to BaseDimDoor.breakBlock(). I would prefer to move away
from overriding the invalidate() method. This also simplifies the code
since we don't need to perform some of the checks we had in
breakBlock().
1. Made it so that rifts regenerate when rift blocks are replaced by
other blocks.
2. Changed the rift regeneration scheduling functions to streamline
their use in other classes. Common code that was needed to validate
links before calling those functions has been moved into them so that
the checks are always performed internally.
1. Implemented scheduled rift regeneration in RiftRegenerator. The
previous randomized selection algorithm has been removed completely. All
regeneration is scheduled now. We perform numerous checks to make sure
that regenerating a rift is safe.
2. Removed FastRiftRegenerator as RiftRegenerator performs roughly the
same task but with more flexibility. Updated TileEntityDimDoor to use
RiftRegenerator instead for creating rifts when doors are broken.
3. Modified EventHookContainer to receive the chunk loaded event. We
iterate over the list of links in a loaded chunk and schedule them for
regeneration.
4. Reorganized the code in BlockRift. Divided the list of immune blocks
into two lists - one for DD blocks and one for regular MC blocks.
RiftRegenerator has to be able to distinguish between the two types.
5. Factored out some duplicate code from ItemRiftSignature and
ItemStabilizedRiftSignature. Most of the block immunity checks were used
to check if it would be safe to spawn a rift when using one of those
items. BlockRift.tryPlacingRift() covers all that logic in a single
function and makes the item code a little simpler.
Minor changes to DimLink to simplify DimLink.getDestinationOrientation()
and to clarify the output of DimLink.toString() when no destination is
available.
Rewrote the NewDimData.deleteLink() version that would accept x, y, and
z as parameters. There was some redundant code for getting the
parameters from a Point4D instance just to create another one to find
the target link. Now we pass the source point in directly.
Made some minor changes to NewDimData. Fixed some comments for the rift
search functions that incorrectly indicated the search would not detect
rifts adjacent to the center of the search range. That behavior changed
some time ago. Also added an unused field called "chunkMapping" for
associating chunks with lists of links. It'll be used for implementing
queuing of rift regeneration when chunks load.
1. Reorganized our code to initialize tick receivers each time the
server starts rather than once when the mod is initialized. This is
needed because reusing a single instance of each class across different
single-player sessions could cause scheduled events for one world to
leak into another world. This approach ensures that we discard all
pending events.
2. Separated the implementation of Limbo decay from a tick receiver that
periodically triggers fast decay. All of the decay code has been kept in
LimboDecay, while the ticking is handled by LimboDecayScheduler. This
change separates some functionality that should be independent, but
also, it's needed so that BlockLimbo can have access to LimboDecay's
methods without holding on to a tick receiver instance.
3. Minor change: renamed ChunkLoaderHelper.loadChunkForcedWorlds() to
loadForcedChunkWorlds().
1. Renamed CommonTickHandler to ServerTickHandler. Given that it only
handles server ticks, this seems like a reasonable name. Also changed
its profiler label to the new name.
2. Deleted ClientTickHandler and removed any references to it in
mod_pocketDim. It was never used for anything.
Made various changes to clarify code in DDTeleporter. For instance, we
had a whole switch block that was used to give the same outcome on every
case except the default. I rewrote the code there to remove the block.
Also changed DDTeleporter.checkDestination() since it was redoing the
destination orientation checks unnecessarily, changing the entity's yaw
when it shouldn't have side effects, and some other little things.
1. Changed build.gradle so that it edits the version numbers in
mod_pocketDim.java and mcmod.info.
2. Changed mod_pocketDim to use a placeholder for its version number and
fixed an annotation that was wrong. It would cause our mod_pocketDim
instance to not initialize properly. I removed what seemed to be
workarounds that were hiding the problem.
3. Fixed space in TileEntityDimDoor.invalidate() and corrected a
non-static access to a static field in mod_pocketDim.
4. Changed mcmod.info so that it users placeholders for the mod version
and MC version values.
We previously returned the Vanilla counterparts to our doors as the
items to be used by the pick block button - used in Creative mode for
replicating nearby blocks. This was incorrect because we would want to
return the actual door item needed to place the particular door in
question.
More importantly, this might solve our issues with WAILA reporting the
wrong information when players look at our doors. I read the code for
the most recent version of WAILA and it uses various functions to choose
how to identify a block. The result of Block.idPicked() is probably used
as the main source for the identities of our blocks.
Fixed the way in which we handle redirecting links to blacklisted
dimensions. The previous method always converted links into safe exits.
This lead to strange situations that could be seen as bugs. For
instance, using a dungeon entrance in a root dimension would generate an
exit door and a supporting platform directly above the entrance door.
That also meant that any visited dungeons would be unusable if they were
reset.
We now do different things depending on the location of the link and its
type. If the link is a dungeon link, then its destination is reset to
allow a new dungeon to form. For other link types, if the link is in a
pocket dimension, then it becomes a safe exit link, because it could be
the only way out. If it's in a root dimension, then there are no
reasonable destinations, so the teleport request is cancelled.
Made some minor changes to DDTeleporter to get rid of a few warnings.
Also tweaked and commented DDTeleporter.initializeDestination(). There
were inappropriate references to a link's internal variables instead of
using its getters and there was a subtle link overwrite for blacklist
destinations. Without comments, it would probably be unclear that
overwriting that link is safe. This changes are in preparation for
fixing issues with blacklisted destination redirection.
Rewrote CommandTeleportPlayer for the same reason as usual. There were a
few bugs before, such as that lookups for players were limited to within
the world from which the command sender was using the command. Players
in other dimensions could not be teleported. The command would also
place people in the ground because it did not adjust its coordinates for
the way that DDTeleporter interprets them - as the location of the top
block of a door and the player's head.
I removed CommandDeleteAllLinks because of the significant risk that it
would harm a server. It's possible that someone could run this by
accident instead of CommandDeleteRifts. It takes the same arguments or
even no arguments and it would immediately wipe all links in a
dimension. We can restore it later if it's really needed.
Added a minor check to PocketManager.loadDimension() so that an attempt
to load an unregistered dimension won't be passed on to Forge where it
would cause an exception - which is then caught by Forge before it can
cause problems. This isn't strictly necessary, but it's a nice
consideration.
Increased the maximum Monolith aggro level and the cap range values by a
factor of 1.25. The max aggro increase is to slow down how long it takes
Monoliths to max out because they're just a little too fast right now.
The cap adjustments will preserve the range of texture states they can
have while idling.
1. Rewrote CommandResetDungeons to improve clarity and remove bugs. This
version of the command preserves valid links. Those were previously
removed, which would break some dungeons unnecessarily.
2. Fixed NewDimData.setParentToRoot(). The function did not account for
the possibility that the target's parent might still exist and would
need to be updated, leading to conflicting data. It also did not reset
pack depth. We now correctly update a dimension and all its descendants.
1. Rewrote or removed a few bits that were causing minor warnings.
2. Rewrote deleteDimensionFiles() and deleteDimensionData() to remove
unnecessary casts and checks. We can confirm that those checks are
unnecessary because those functions are only used inside PocketManager.
If they were ever exposed externally, then we would need to add checks
again.
Rewrote CommandDeleteRifts for clarity and to remove several flaws.
Previously, the command would have removed non-immune blocks that were
in the same location as a rift. It also set blocks in the command
sender's dimension rather than the target dimension, so blocks would
have potentially disappeared from the wrong world.
1. Fixed some warnings in the affected commands.
2. Removed checks for whether a command is running on the server or
client side. We have performed those checks inconsistently throughout
our commands without problems. I assume that they must be running on the
server side only. If I'm wrong, we can add a check to DDCommandBase.
3. Minor punctuation change in DDCommandResult
1. We weren't giving old tickets to the doors that owned them. That
would result in doors requesting new tickets and the old ones wouldn't
be released. Each time a server rebooted, a new ticket would be created.
Then Opis would report that many chunks were forcefully loaded in a
pocket because it doesn't consider overlapping tickets. We now give
doors their old tickets when they're reloaded and we release extra
tickets referring to the same door. That will also deal with the excess
tickets that already exist on servers.
2. Rewrote the logic for checking if a Golden Dimensional Door is
allowed to force-load a pocket. We now check if the door is within the
horizontal bounds of the pocket. This prevents the confusing scenario
where someone places a door far away from the pocket but the only chunks
affected are in the pocket.
3. Fixed the calculation for determining which chunks must be
force-loaded to cover a pocket. This has the benefit that fewer chunks
should need to be loaded. It should be enough to load 16 chunks. We
previously loaded 25 chunks just to err on the side of caution.
4. Golden Dimensional Doors only try to initialize as chunk loaders
once. We previously allowed them to keep trying every tick until they
could get a ticket.
Added the Universal Limbo config option to the world config settings.
When enabled, it causes players to get teleported to Limbo if they die
in any dimension except Limbo. It's disabled by default.
This feature was requested by Mr_Turing.
Added code to EventHookContainer.revivePlayerInLimbo() so that the
player's food level is restored upon respawning in Limbo. Apparently it
was possible for players to have death loops from starving to death in
Hardcore Limbo.
Changed the function call for playing the rift-closing sound to match
other similar calls in Minecraft - the sound should target the center of
the block. I also switched the last flag argument. It seems to determine
whether distance between the player and the source should be checked
when playing back the sound, although documentation is lacking so I
can't be sure. Other blocks that use that function use "false", while
things involving sounds that should be heard uniformly, such as
rainfall, use "true".
---
I noticed that this code runs on the client and server. Some parts
modify link data and rifts on the client side. We should really stop
this from happening as it could lead to inconsistencies.
Added support for using Stabilized Rift Signatures from dispensers under
specific conditions. Everything works except for playing the sound that
occurs when an SRS is used. Not sure why that's not working.
1. Removed several fields and functions referring to the newer rendering
code. The functions were just cluttering up the code and the fields were
consuming additional memory that was never being used for anything.
2. Updated NBT reading and writing functions to give some tags proper
names and to remove references to unused fields.
Removed the tag for riftCloseTimer because it was unnecessary alongside
the shouldClose flag. If a server reboots while a rift is closing, the
rift can start over upon reloading.
3. Renamed some fields and functions to have better names.
4. Changed the various checks for closing rifts. There were a few
redundant parts. We don't have to put calls to "this.invalidate()"
everywhere on top of explicitly removing the tile entity and destroying
its block.
5. Rewrote update timing checks. The rift spread and Enderman spawning
calls have been separated to distribute the impact of updating a rift.
Also, a flaw in the timing logic meant that the calculations for
particle offsets would only run when a rift was first created. That's
been fixed.
1. Fixed the bug where the setting that controls whether Endermen can
spawn from rifts was being ignored. It was never checked at all.
2. Cleaned up some formatting and annotations.
3. Removed call to World.removeBlockTileEntity() following a call to
World.setBlockToAir(). The latter function already handles removing the
tile entity.
1. Changed hasEffect() override since we were overriding a deprecated
version.
2. Fixed a bug where we checked if a block could be edited before
deciding whether to change the Y coordinate of the rift to be placed.
Sometimes we would place the rift in a different block. This is the
result of sticking in support for special blocks like grass and snow
without considering the impact on surrounding code. It also contradicted
comments that specifically said special blocks were ignored...
3. Cleaned up the code for checking for special blocks.
4. Fixed a bug in loading NBT data. There were no null checks on
orientation data. If a Rift Signature or Stabilized Rift Signature had
been created in a version of DD before orientations were set up, then it
cause an exception when so much as looked at in later versions of DD.
5. Partially implemented free redirects for Stabilized Rift Signatures.
The check to determine if a redirect is being done is missing.
1. Changed the crafting recipes for most DD items to use Ender Pearls
instead of Stable Fabric. The items that still use Stable Fabric are
Dimensional Doors, Golden Dimensional Doors, Rift Blades, and Stabilized
Rift Signatures. Steven had already made this change in another branch
but I'd like to push this out with several bug fixes. The SRS recipe is
different from his version - it's now just 4 Iron Ingots and a Stable
Fabric.
2. Change Stabilized Rift Signatures back to consuming Ender Pearls
instead of Stable Fabric.
Finished implementing Personal Pockets
-any pocket created from within a personal pocket retains personal
status
-exit doors cannot be used in any personal pockets
-personal status is saved with dimData
fixed a bug that let trapdoors get around locks
fixed FoR not rendering properly
-inventory and world
Changed the max stack size of ItemGoldDoor to 16 as it is for Vanilla
doors on some modpacks. Later versions of Vanilla have door stacking to
64 so this will need to change eventually.
1. Changed EventHookContainer to remove a check against
BaseItemDoor.getDoorToPlace(). The checks performed there can be done
in BaseItemDoor.tryToPlaceDoor(), which removes the need for callers to
know more internal details about how doors are handled. I moved the
checks inside.
2. Renamed vanillaDoorMapping to doorItemMapping. It now maps dim door
items to themselves to remove the need for various checks we were
performing. Updated BaseItemDoor's constructor to reflect this change.
3. Removed BaseItemDoor.getDoorToPlace() and integrated its
functionality into BaseItemDoor.tryToPlaceDoor().
4. Changed BaseItemDoor.tryToPlaceDoor() so that it simply returns false
if a given item stack cannot be used to place any doors. We don't need
to check if the item is an ItemDoor or anything like that now.
1. Cleaned up some spacing and unused imports in EventHookContainer.
Also changed an indirect reference to BaseItemDoor.trytoPlaceDoor() to a
direct reference seeing as the function is static and should be accessed
that way.
2. Renamed getDoortoItemMapping() to getDoorBlock(). The original named
had a minor capitalization mistake and implied that it would return a
mapping table or would associate doors to items. The function actually
associates items to door blocks.
1. Stopped Monoliths from teleporting players while in Limbo. This was a
serious issue on some modpacks if players got unlucky.
2. Decreased the required Monolith aggro level to start spawning
particles around a target player. The required level was so high,
combined with the current Monolith speed, that players would hardly see
the particles.
3. Disabled Monolith sounds in Limbo. Some of the sounds were really
annoying in Limbo. Usually they only get to play for a moment before a
player is teleported, but since no teleports occur in Limbo and the area
is full of Monoliths, the constant noise is aggravating. It would also
drown out the background music.
* Fixed a mistake in the crafting recipe for Golden Dim Doors
* Removed static import of fields from mod_pocketDim. There were already
qualified references to those fields in some areas. We should be
consistent.
* Fixed issue with Monoliths detecting players through walls
* Changed aggro values from bytes to shorts
* Fixed aggro updates so that aggro levels can decrease
* Fixed upper bound on aggro clamping
* Added client/server-side checks to a few functions to save on
performing pointless checks, such as making calculations for spawning
particles on the server
Removed lots of obsolete and unused code from Monoliths. The code is
subdivided more clearly now. The aggro level is sent over a data watcher
instead of sending the texture state.
Keybounce noticed that he was having a persistent item ID conflict with
DD's Golden Doors - the normal doors not the dimensional variant. I
discovered that we have been assigning them the same ID as the Golden
Door block ever since they were first introduced 7 months ago. It didn't
break immediately since Forge adds +256 to item IDs.
* Changed saving code to create backups by moving existing files rather
than creating copies and deleting the originals.
* Removed final call to PocketManager.save() in PocketManager.unload().
Since we no longer check if the caller is the client or server and
unload() must be called from both, this prevents clients from trying to
save pocket data locally. A final save() call wasn't needed anyway.
Added a flag to NewDimData so that we can avoid writing dimensions to
disk if they haven't been modified. They're still rewritten when the
server shuts down.
Made saving a bit more robust, now we only delete ones that where not
modified. Also overhauled door placement, its all handled by the
eventHandler now.
* Changed DDTeleporter to stop us from generating exits to Witchery's
Spirit World - this would cause people to lose their items upon leaving
the dimension.
* Changed GatewayGenerator to stop us from generating gateways or rift
clusters in the Spirit World
Changed FillContainersOperation so that empty dispensers are not filled
with a stack of arrows on import. Just in case someone needs to use
empty dispensers in their design. As far as I can remember, this won't
affect any of our dungeons - arrow traps are rare. The only dungeon that
I can remember is one by Balgor and it was exported with all of its
dispensers loaded.
* Added a small treasure room that opens when the puzzle is solved and
made the exits in the corners slightly more apparent by placing redstone
lamps.
* Tweaked the redstone a little to correct for a brief signal cutoff.
* Tried to add fireworks that would shoot out when the puzzle was
solved, but it was too hard to secure them against theft while also
getting consistent explosions.
Updated the dungeon pistonFallRuins so that it causes less extreme lag
by slowing down and spacing out the timing for the piston traps. Also
reinforced the dungeon against tampering and added lava inside each
piston drop.
XombyCraft has been kind enough to research which provider and biome IDs
are used by major mods. He found some ranges of free IDs and suggested
changing our defaults to sidestep conflicts with Biomes o' Plenty.
Fixed a nasty crash to desktop. It happens when ChickenChunks is
installed and a new world is generated with HardcoreLimboEnabled = true.
It appears that ChickenChunks forces a chunk to generate in Limbo if
LimboProvider.canRespawnHere() = true, which is the case if hardcore
Limbo is enabled. Our Monolith and gateway generation code runs as a
tick handler instead of through standard world gen calls. I believe
Limbo is unloaded immediately after the chunks are generated because no
players are around. That would cause DimensionManager to return null for
Limbo because it's not loaded, which would crash our code. We probably
dealt with this for Monoliths by adding a check. Now it happened again
because we didn't take precautions while calling the gateway generation
method. I've added code to forcefully load Limbo if it's not loaded.
Changed the condition on LimboProvider.canRespawnHere() so that players
can respawn in Limbo even if LimboEnabled is false. LimboEnabled only
controls whether players are sent to Limbo when they die in a pocket. It
does not prevent players from ending up in Limbo because of Monoliths.
If Hardcore Limbo is enabled, it stands to reason that people should be
respawning in Limbo anyway.
After finally getting the dungeons to load, I've determined that only
half of the rooms should be included. The three remaining rooms should
definitely stay. That's not much for a pack so I'm going to make some
modifications to the schematics and include them as part of Ruins.
* Fixed Limbo gateways. I accidentally broke them while overhauling
gateways in general.
* Changed references to BaseItemDoor.placeDoorBlock() to use
ItemDoor.placeDoorBlock() instead. We should refer to the original class
that implements the function.
* Set up the necessary code in DungeonHelper so that Balgor is
registered along with the other bundled packs.
* Improved the code for registering bundled packs to reduce the number
of paths we need to hardcode and to crash DD if a pack fails to load. A
crash would be inevitable no matter what since bundled packs are
integral to DD.
* Corrected an invalid generation rule for Balgor. It's set to select
random dungeons infinitely for now. I'll add an exit room later and
change the rule to force an exit. Balgor is still unusable until its
schematics get proper doors.
* Fixed PocketBuilder to actually check the results of validating
schematics before we try to build them. This was causing cryptic error
messages when flawed schematics were loaded (e.g. rooms without proper
doors) and could have caused serious problems during dungeon
regeneration. Don't ignore validation!
* Split off schematic-related functionality into BaseSchematicGateway.
* Moved the default implementations of many methods to the base classes
because having a bunch of duplicate stubs all over the place was a
waste.
* Removed methods that were redundant or weren't being used for
anything.
* Added support for importing schematics while ignoring air blocks
through IBlockSetter - now our gateways are copied in without air by
default.
* Fixed bugs that would have prevented the sandstone gateway from
generating.
* Removed the code in generate() that would cause dungeon
pre-generation. We should solve this by attaching data to links instead
and it's not a feature that we're even using right now (everything uses
the default pack).
* Fully documented our functions - it's so beautiful...
Changed dd-rift and dd-random so that rifts are only placed after a
dungeon is generated successfully. We also delete the link if generation
fails to clean up after ourselves. Also changed
PocketBuilder.generateSelectedDungeonPocket() so that its checks are
stricter and we validate dungeons before allocating a dimension.
This resolves one of our old issues: "Rearrange workflow in dd-rift to
prevent rifts from being created if no dungeon gets loaded and to
prevent dimension registration if the dimension cannot be populated"
Changed the code for dungeon selection in various classes so that rather
than allocating and passing around the dimension where the dungeon will
be generated, we instead pass around the parent dimension. This
simplifies our code and moves us toward avoiding stray dims when dungeon
selection fails and to solving the dungeon pre-generation problem with
gateways.
Added a new setting to dungeon pack configs called
"DuplicateSearchLevels", which allows us to configure how many levels up
of the dungeon tree should be checked to avoid duplicating rooms used in
that subtree. In other words, it lets us avoid repeating rooms used in
neighboring branches of the dungeon. The setting has been added but it's
not fully supported yet - some additional code is needed in
DungeonHelper and it's not trivial to implement. I took a break because
doing it wrong could break dungeon selection.
Added a setting to DDProperties for controlling the max distance that
players can be moved randomly when they're sent to Limbo. We previously
had a setting for the same except for leaving Limbo. Cleaned up some of
the related code a little. Added another setting for the chance of rifts
dropping World Thread on block destruction. Also fixed a potential NPE
in EventHookContainer that could arise theoretically arise if a
non-Vanilla door was attached to a rift.
Cleaned up the code for placing Vanilla doors on rifts in
EventHookContainer. Unfortunately, there's a section that I don't
understand and that I feel has a bug. Remember that comments are very
helpful.
The following small change deals with a strange background-music-related
crash. Wasn't this issue fixed for Jaitsu and Aether II? I'm not sure
what's the cause but I've added a check to prevent the NPE. Please deal
with this most robustly in the future.
Removed duplicate code from ItemRiftBlade. It was code that duplicated
the functionality of ItemSword since ItemRiftBlade didn't extend
ItemSword originally. Also updated the tooltip text to remove mentions
of the old door-rotating ability. That's not provided anymore since
doors are easily broken and replaced now. Extended teleport range
slightly.
Added a check so that Dimensional Doors crashes if another registers our
provider IDs. This will show people that something needs fixing instead
of us risking strange bugs.
Set loot chests to generate 6 stacks of items instead of 5 stacks.
Increased the maximum amount of World Thread per stack from 8 to 12
threads. Increased the chance of encountering a grave chest to 1 in 6
instead of 1 in 7.
Added a configuration option for toggling whether players can teleport
out of Limbo by walking over Eternal Fabric. This became viable after
Rift Gateways began generating in Limbo again. Keybounce has expressed
an interest in using option to deal with the issue of players returning
home since his Overworld won't have gateways.
Changed dungeon exits so that they have a minimum 15% chance of exiting
to the Overworld if a dungeon's root dimension isn't the Overworld. Also
made a minor change to the existing special case for the Nether - the
minimum 20% chance only applies if the root dimension isn't the Nether.
Added a configuration option for adjusting the number of World Threads
needed to create one Stable Fabric. A few users have asked for this to
be available. The default setting is our usual 8 thread for each fabric.
Also overhauled our recipes to remove blank item slots, allowing them to
be crafted on any line of the grid, as long as all the items are aligned
properly.
Made a small correction to the condition on max ancestors. Also
thoroughly tested this code to ensure that it really does limit rift
spread. Currently, 2 initial rifts will cause 4 more rifts to be created
eventually.
Switched rifts over to using link.childCount() to track spread instead
of the hasGrownRifts flag in the tile entity. The flag had the flaw that
if the rift was replaced by a block, the flag would reset and the rift
could spread again. I think I remember this being intended as punishment
for messing with rifts but it's a problem when combined with World
Thread farming.
Fixed the issue of rifts spreading through walls. We tried using
raytracing but rifts would always "leak" out of unbreakable enclosures.
With this latest change, rifts spread with the same logic that
determines which blocks are reachable to them.
Added a per-save config file called DimDoorsWorld.cfg. Its corresponding
class is DDWorldProperties. This class supports whitelisting and
blacklisting dimensions for Rift Cluster and Rift Gateway generation.
Note that our ban against generating gateways in the Nether and The End
still applies regardless of those settings. The new config file is
loaded before the server starts initializing terrain. Also moved
DDProperties to another package alongside DDWorldProperties - that
required updating references in most of the mod's files.
Added SK-RaceTheLight to our schematics. Changed the weights on
Cere-FloatingAltar and Cere-PuzzleWall to 75 (previously 100). Fixed
what appears to be a mistake pasted into ruins.txt and also updated it
for the latest dungeons.
Fixed the way textures are applied so that doors from our mod can appear
as double doors. Renamed door textures to be consistent with Minecraft
door textures. Got rid of a few obsolete textures. Unfortunately,
something broke with door blocks updating. I need to fix that in the
next commit.
Improved some of our door code by giving some of our variables real
names. Also found a hack in BaseDimDoor.isDropped() and a strange
comment that said "I have no idea, but sometimes this is returned as the
blockID instead of metadata." I finally figured out that due to some
random mistake introduced in another function, idDropped() sometimes
received a block ID instead of metadata, which is what that comment
referred to. I fixed the cause and removed the hack.
Shifted the duplicate code from our biome classes into a single parent
class. Also added checks so that Minecraft crashes if a biome ID
conflict occurs. This is to put an end to the recent streak of posts on
our MCF thread about people experiencing issues because DD and BoP have
conflicts out of the box.
I copied two functions from CommandBase into DDCommandBase because their
absence is breaking our builds on Technic and Dryware Jenkins. I have no
idea why that's happening. My copy of MC's source code has those
functions in CommandBase and my code compiles without a problem.
Dropped support for Minecraft's structure generation flag because
several other mods ignore it and supporting it can give the appearance
that DD isn't working properly. We already have settings for disabling
gateways in our config file.
Fixed rotations for hopper and droppers. Hoppers were failing because
powered hoppers have different metadata. Droppers were just missing from
the list of oriented blocks. Fixed the wooden buttons on Cerevisiae's
altar room and added her puzzle room once hoppers were working reliably.
Made some minor changes to the way that we register commands with
Minecraft. Also changed the way that we generate onCommandUsage()
strings so that the style of our outputs is consistent with that of
Minecraft and Forge commands. It seems the way the messages were
generated changed for MC 1.6. Finally, removed compareTo() from
DDCommandBase since it was completely unnecessary (CommandBase already
does the same) and casting objects to CommandBase was causing errors
with some Chicken Bones commands that directly implemented ICommand.
Fixed the issue with clients not receiving notifications of gateways
being built into the world because we were modifying chunk data
directly. Our schematic classes now support building through World
instead of directly writing to the underlying chunks. Also fixed an NPE
that was introduced last night when I changed which line
GatewayGenerator was initialized on in mod_pocketDim.
Fixed an NPE that would occur because mod_pocketDim.deathTracker was set
to null before the last onWorldSave event was triggered when a server
was shutting down.
There is 5% chance that grave chests will contain the head of a random
player that has died in a pocket dimension; there is a 20% chance of it
being a special head. Also moved Ghast Tears to grave chests and removed
Eyes of Enders as loot. Also made FoR loot more rare but increased the
amount given out so that the average amount picked up should be the same
as before. World Thread is slightly less common in response to being
easier to farm from rifts.
Added code to save DeathTracker data when then Overworld saves, but only
if it's been modified since the last time it was saved. Also changed how
we handle player deaths in pocket dimensions. Now we have two death
handlers. There is a high-priority one that sends players to Limbo only
when Limbo preserves their inventories. The other is a low-priority
handler that sends players to Limbo only when inventory preservation is
disabled. This gives players a chance to keep their inventories if
another mod would have revived them without that penalty.
Added DeathTracker - a class for tracking the deaths of players on the
server while in pocket dimensions. It'll be used for generating skulls
for grave chests. Also removed PlayerTracker since it wasn't being used
for anything at all. I'm guessing it was supposed to be used for
something later. We can restore it if it's ever needed.
Cleaned up the code for initializing GatewayGenerator. We had some
static fields that didn't need to be static and we could just initialize
gateways from the class's constructor.
Moved a little of the regeneration code to BlockRift to reduce duplicate
code. Changed RiftRegenerator to iterate over loaded worlds instead of
all worlds. Removed forced rift generation call in
EventHookContainer.onWorldLoad() - I feel it would have minimal
benefits. Rifts now drop World Thread upon regeneration. Generally
cleaned up the code in FastRiftRegenerator and RiftRegenerator.