129 Commits

Author SHA1 Message Date
4b2caf33d3 readme containing info about what this is for 2026-05-30 20:08:16 +00:00
StevenRS11
7b77b268bf rift render growth and removal 2014-08-21 18:42:24 -05:00
StevenRS11
910f991734 render color final 2014-08-20 22:55:29 -05:00
StevenRS11
a55fdbfd0f rift render canidate 2014-08-20 21:44:16 -05:00
StevenRS11
0dd1f1b293 more changes 2014-08-20 17:15:04 -05:00
StevenRS11
dc7a19c2f3 render effect iteration 2014-08-20 16:58:52 -05:00
StevenRS11
04ec4b3d2d jitter together! 2014-08-19 18:50:18 -05:00
StevenRS11
68ff8f6921 Added triangulation library and rift render
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))
2014-08-19 17:36:07 -05:00
StevenRS11
499c7d91d8 Formatting change
Aformentioned merge wouldnt commit for some reason

PLEASE REVIEW THIS AND THE PREVIOUS COMMIT
2014-07-16 10:41:27 -05:00
StevenRS11
7c7129914a Merging murder 2014-07-16 10:24:24 -05:00
StevenRS11
60bc8090f2 Merge pull request #179 from SenseiKiwi/master
Fixed Crash on Rift Removal
2014-07-15 14:14:22 -05:00
SenseiKiwi
20db828ac0 Fixed Crash on Rift Removal
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.
2014-07-15 14:51:46 -04:00
StevenRS11
12a2a8eb0d Merge pull request #175 from SenseiKiwi/master
Fixed Eager Dimension Data Creation
2014-07-13 21:50:37 -05:00
SenseiKiwi
e793493331 Fixed Eager Dimension Data Creation
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.
2014-07-13 20:03:00 -04:00
StevenRS11
7f99801e1b Merge pull request #174 from SenseiKiwi/master
Fixed Crash on World Creation
2014-07-13 14:36:14 -05:00
SenseiKiwi
8544aa17ee Fixed Crash on World Creation
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.
2014-07-13 14:22:23 -04:00
SenseiKiwi
b20a0a74d2 Minor Change
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().
2014-07-13 07:17:30 -04:00
SenseiKiwi
fb1713ae0e Improvements to TileEntityRift
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.
2014-07-12 03:36:56 -04:00
StevenRS11
eff7abcbbc Merge pull request #173 from SenseiKiwi/master
Fixed Slow Rift Regeneration and Various Improvements
2014-07-11 15:12:08 -05:00
SenseiKiwi
2c7435585d Minor Changes
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.
2014-07-11 15:44:01 -04:00
StevenRS11
349f162a7c Merge pull request #170 from SenseiKiwi/master
Fixed Pick Block Results
2014-07-11 10:38:21 -05:00
SenseiKiwi
107aa4b7f2 Cleaned up Transdimensional Trapdoor Code
Removed unnecessary code for the Transdimensional Trapdoor. Most of it
was code dedicated to updating TileEntityTransTrapdoor.hasRift. That
flag was never used for anything.
2014-07-11 04:33:19 -04:00
SenseiKiwi
1bf1f4f78c Improved Regeneration Code
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.
2014-07-11 04:10:12 -04:00
SenseiKiwi
29c8a09218 Improved Door Code
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().
2014-07-11 03:44:26 -04:00
SenseiKiwi
71e7fdaafc Implemented Regeneration for BlockRift
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.
2014-07-11 03:26:40 -04:00
SenseiKiwi
1f59dc17d9 Implemented Scheduled Rift Regeneration
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.
2014-07-11 01:21:43 -04:00
SenseiKiwi
79bd5102ba Minor Changes
Minor changes to DimLink to simplify DimLink.getDestinationOrientation()
and to clarify the output of DimLink.toString() when no destination is
available.
2014-07-10 18:29:48 -04:00
SenseiKiwi
b197237dfd Minor Change
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.
2014-07-10 18:25:41 -04:00
SenseiKiwi
85ff28298e Implemented Chunk-Links Mapping
Implemented support for tracking the list of links in each chunk in a
dimension. This will be used for scheduling rift regeneration when
chunks load.
2014-07-10 18:21:10 -04:00
SenseiKiwi
782c6d5e50 Minor Changes to NewDimData
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.
2014-07-10 17:13:10 -04:00
SenseiKiwi
c00c65eeee Reorganized Tick Receivers
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().
2014-07-10 15:11:44 -04:00
SenseiKiwi
c22479c0e8 Tick Handler Changes
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.
2014-07-10 08:28:42 -04:00
SenseiKiwi
8da0339c78 Improved DDTeleporter
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.
2014-07-09 23:44:49 -04:00
SenseiKiwi
83998969f6 Fixed Version in mod_pocketDim
Forgot to change the placeholder in mod_pocketDim
2014-07-09 15:14:56 -04:00
SenseiKiwi
c4abae8fdd Fixed build.gradle (again)
Made some more changes to build.gradle in the hopes that the version
information will automatically update in mod_pocketDim.java. It has only
worked on mcmod.info in previous attempts.
2014-07-09 15:11:16 -04:00
SenseiKiwi
1106319f8c Fixed build.gradle
Fixed a mistake in specifying the path for mod_pocketDim.java.
2014-07-09 04:15:37 -04:00
SenseiKiwi
2904ec146d Implemented Automatic Versioning in Build Script
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.
2014-07-09 04:01:37 -04:00
SenseiKiwi
7d840ff895 Fixed Pick Block Results
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.
2014-07-06 04:31:42 -04:00
SenseiKiwi
52bae00dc6 Minor Change
Minor change to remove a warning
2014-07-06 04:01:07 -04:00
SenseiKiwi
dc55359aaf Minor Changes
Made various minor changes to eliminate warnings or to improve clarity.
2014-07-07 03:56:47 -04:00
SenseiKiwi
58d5f6dd14 Minor Changes
Minor annotation changes to remove some warnings... and keep up my
GitHub spree.
2014-07-07 01:59:26 -04:00
StevenRS11
b40141f99d Merge pull request #169 from SenseiKiwi/master
Reviewed and Rewrote Commands
2014-07-05 20:59:42 -05:00
SenseiKiwi
06cf72f9f7 Fixed Flawed Link Redirection
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.
2014-07-05 21:28:10 -04:00
SenseiKiwi
100fa38c52 Minor Changes to DDTeleporter
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.
2014-07-05 14:18:18 -04:00
SenseiKiwi
17a770eaf0 Minor Change
Added two comments to CommandTeleportPlayer
2014-07-04 20:55:57 -04:00
SenseiKiwi
16f0a8303a Rewrote CommandTeleportPlayer
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.
2014-07-04 20:20:46 -04:00
SenseiKiwi
1e3b32a15c Minor Change
Removed a reference to CommandDeleteAllLinks from mod_pocketDim.
2014-07-04 14:06:41 -04:00
SenseiKiwi
4d53ae5f6a Removed CommandDeleteAllLinks
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.
2014-07-04 13:53:44 -04:00
SenseiKiwi
d3860119e9 Minor Change to PocketManager
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.
2014-07-04 13:05:08 -04:00
SenseiKiwi
f64768ed16 Rewrote DeleteFolder
Rewrote the helper class DeleteFolder. It was leaving behind empty
directories when pockets were deleted.
2014-07-04 02:14:24 -04:00
SenseiKiwi
c1e58c25cc Increased Max Monolith Aggro
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.
2014-07-04 01:17:25 -04:00
SenseiKiwi
805e9dd040 Minor Changes
Fixed up a few spots to clear some warnings.
2014-07-03 22:49:15 -04:00
SenseiKiwi
972a67de76 Rewrote CommandResetDungeons
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.
2014-07-03 22:46:31 -04:00
SenseiKiwi
592aabf627 Minor Change
Added a comment in PocketManager to explain why we don't unregister
pocket dimensions with Forge when we delete them.
2014-07-03 17:32:40 -04:00
SenseiKiwi
b4a58f5c88 Simplified PocketManager
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.
2014-07-03 17:20:59 -04:00
SenseiKiwi
80bb87dac6 Rewrote CommandDeleteRifts
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.
2014-07-03 14:19:08 -04:00
SenseiKiwi
c5a77268fc Changes to Commands
Removed a few server-side checks that I missed on the previous commit.
2014-07-03 14:08:51 -04:00
SenseiKiwi
262595ff4d Changes to Commands
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
2014-07-03 12:25:00 -04:00
SenseiKiwi
c29db9b729 Minor Changes
Cleaned up the code in DDCommandBase a little.
2014-07-03 12:02:36 -04:00
StevenRS11
689df1ad6d Merge pull request #167 from SenseiKiwi/master
Fixed Bugs in Golden Dimensional Doors
2014-07-02 13:21:38 -05:00
SenseiKiwi
ec290b0dc1 Increased Version Number
Increased the mod's version number to account for recent fixes and small
features.
2014-07-02 13:59:55 -04:00
SenseiKiwi
3d88e72ecb Fixed Bugs in Golden Dimensional Doors
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.
2014-07-02 13:38:57 -04:00
SenseiKiwi
b2e086e7c1 Added the Universal Limbo Setting
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.
2014-07-01 21:55:57 -04:00
SenseiKiwi
e3665c09dd Added Hunger Restoration on Limbo Respawn
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.
2014-06-28 13:06:22 -04:00
StevenRS11
fb4643d7cf deleted renderRift 2014-06-27 16:27:23 -04:00
StevenRS11
5ba58dc91b Merge remote-tracking branch 'origin/master' into StevenRS
Conflicts:
	src/main/java/StevenDimDoors/mod_pocketDim/CraftingManager.java
	src/main/java/StevenDimDoors/mod_pocketDim/EventHookContainer.java
	src/main/java/StevenDimDoors/mod_pocketDim/core/DDTeleporter.java
	src/main/java/StevenDimDoors/mod_pocketDim/core/DimLink.java
	src/main/java/StevenDimDoors/mod_pocketDim/items/ItemRiftSignature.java

	src/main/java/StevenDimDoors/mod_pocketDim/items/ItemStabilizedRiftSignature.java
	src/main/java/StevenDimDoors/mod_pocketDim/mod_pocketDim.java
	src/main/java/StevenDimDoors/mod_pocketDim/world/PocketBuilder.java
	src/main/java/StevenDimDoors/mod_pocketDimClient/RenderRift.java
2014-06-27 16:26:46 -04:00
StevenRS11
dea76b1a7e Merge pull request #166 from SenseiKiwi/master
Various Fixes
2014-06-26 18:17:34 -05:00
SenseiKiwi
42568a1864 Removed RenderRift
Removed the RenderRift class since it relates to unused functionality
and references fields that I removed from TileEntityRift.
2014-06-26 12:20:19 -04:00
SenseiKiwi
e40168954f Minor Change to TileEntityRift
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.
2014-06-26 12:17:59 -04:00
SenseiKiwi
59f335ac8c Added Dispenser Support for SRS
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.
2014-06-26 12:11:51 -04:00
SenseiKiwi
444b862b12 Minor Change
Renamed the field mod_pocketDim.itemStabilizedLinkSignature to
itemStabilizedRiftSignature to follow the item's actual name.
2014-06-26 09:19:04 -04:00
SenseiKiwi
a0629b51a3 Improvements to TileEntityRift
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.
2014-06-26 07:06:17 -04:00
SenseiKiwi
364ba11f81 Updates to TileEntityRift
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.
2014-06-26 05:40:35 -04:00
SenseiKiwi
96238d6b53 Minor Change
Minor spacing and annotation changes.
2014-06-26 04:52:32 -04:00
SenseiKiwi
448890207f Completed Changes to Stabilized Rift Signature
Completed the change to Stabilized Rift Signatures so that overwriting
links that already belonged to an SRS is done for free.
2014-06-26 04:52:03 -04:00
StevenRS11
46f55b22d9 restricted brightness inversion to dungeons only 2014-06-26 02:16:57 -04:00
StevenRS11
9baceb8e3c Added backwards light and bugfixes
Light in pockets is now reversed
added sound to lock removal
fixed monolith name
fixed other names
2014-06-26 00:08:20 -04:00
SenseiKiwi
fe035f6677 Renamed Function in NewDimData
Renamed NewDimData.setDestination() to setLinkDestination(). I realized
that the name was a little confusing at first sight - it confused me!
2014-06-25 20:15:43 -04:00
SenseiKiwi
4192270ef3 Changes and Fixes to Rift Signature Variants
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.
2014-06-25 20:13:03 -04:00
SenseiKiwi
0029d9dac0 Reduced Usage of Stable Fabric
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.
2014-06-25 19:00:41 -04:00
StevenRS11
eff8379325 Added lock removal ability to keys
also fixed a network bug
2014-06-25 17:46:33 -04:00
StevenRS11
96d84ed2fa Fixed Json Schema
The schema incorrectly listed the array of children in LinkData as an
Array of numbers, not an array of objects with properties.
2014-06-25 16:17:26 -04:00
StevenRS11
0f3d40ba60 Various
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
2014-06-25 15:26:42 -04:00
SenseiKiwi
794310bd98 Fixed Max Stack Size of ItemGoldDoor
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.
2014-06-25 15:18:50 -04:00
SenseiKiwi
a4d0f39390 Minor Change
Cleaned up comments for BaseItemDoor.tryToPlaceDoor()
2014-06-25 15:08:30 -04:00
SenseiKiwi
e4e84644ac Changed Door Item Mapping Code
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.
2014-06-25 14:56:59 -04:00
SenseiKiwi
660ff4255e Code Cleaning
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.
2014-06-25 14:33:19 -04:00
StevenRS11
1410d4b251 made versioning slightly better 2014-06-25 14:13:49 -04:00
SenseiKiwi
161da193ad Merge remote-tracking branch 'upstream/master' 2014-06-25 14:04:56 -04:00
SenseiKiwi
4d39d13703 Changes to Monolith Behavior
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.
2014-06-25 14:04:08 -04:00
StevenRS11
18666f58b1 Added versioning to save files and DimensionType 2014-06-25 04:37:40 -04:00
StevenRS11
9e720cb458 Changed linkTypes to linkType, an enum 2014-06-25 02:12:07 -04:00
StevenRS11
968653e4ab fixed typo in DimDataProcessor and DungeonHelper 2014-06-20 14:13:33 -04:00
StevenRS11
eeb5f9aea1 added json validation for saves 2014-06-20 14:04:07 -04:00
StevenRS11
117ed69bf7 added dimdata schema 2014-06-20 13:46:36 -04:00
StevenRS11
0d53f6c029 Actually fix door crash 2014-05-31 06:43:28 -04:00
StevenRS11
dccb12116d Naming improvements
Clarified naming in DDLock and associated methods. Still not quite done.
2014-05-31 06:39:26 -04:00
StevenRS11
e8fa928c50 lock tweaks
Changed how locks are modified so all modifications occur through
NewDimData
2014-05-29 19:04:23 -04:00
SenseiKiwi
f9331e4f2d Merge remote-tracking branch 'upstream/master' 2014-05-29 17:20:30 -04:00
StevenRS11
7da3b7fc62 Patched a door crash bug
thanks LClouds
2014-05-26 22:23:36 -04:00
StevenRS11
77241e6f90 limbo fix 2014-05-26 22:14:20 -04:00
StevenRS11
844950b39e teaked personal pocket generation rules 2014-05-26 21:31:14 -04:00
StevenRS11
16d7bfcda6 personal pockets DONE 2014-05-26 19:38:01 -04:00
StevenRS11
d8fecd07b3 render tweaks 2014-05-22 01:48:21 -04:00
StevenRS11
86cfcdeee8 last few changes 2014-05-22 01:37:04 -04:00
StevenRS11
3f6e32dcbf last tweaks done 2014-05-22 01:03:17 -04:00
StevenRS11
3fcc55b5e1 finished networking changes for locks 2014-05-22 00:15:27 -04:00
StevenRS11
ef860e295e more stuffs
Lock render is still wip, as are most things. That said, I can render
monolith eyes anywhere now.
2014-05-20 19:13:26 -04:00
StevenRS11
8f9dfea947 added locking doors and cleaned up 2014-05-20 03:17:32 -04:00
StevenRS11
ac9b3d73e8 Various
Fixed bug in converting old saves
Started color work
2014-05-16 21:42:59 -04:00
SenseiKiwi
8d1028ccb5 Changes to CraftingManager
* 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.
2014-05-15 06:45:26 -04:00
StevenRS11
d020dd384b toString ftw 2014-05-15 05:53:28 -04:00
StevenRS11
8562456203 Merge pull request #162 from SenseiKiwi/master
Tweaked Monolith Aggro Rate
2014-05-06 03:48:03 -04:00
SenseiKiwi
af77f8b2dc Fighting with Git
Someday git won't randomly explode all over my face
2014-05-06 03:45:21 -04:00
SenseiKiwi
3a2c87cce9 Tweaked Monolith Aggro Rate
* Decreased aggro rate to 3 to compensate for Monoliths pre-aggroing up
to aggroCap
* Clarified aggroCap selection
2014-05-06 03:32:14 -04:00
StevenRS11
03ab75b80c tweak 2014-05-06 03:32:14 -04:00
StevenRS11
f4efa7dca2 codemunching 2014-05-06 03:32:13 -04:00
StevenRS11
79edf1004b tweak 2014-05-06 03:08:46 -04:00
StevenRS11
aab818d948 codemunching 2014-05-06 02:23:03 -04:00
StevenRS11
68f2654000 Merge pull request #160 from SenseiKiwi/master
More Changes to Monoliths
2014-05-05 22:38:46 -04:00
SenseiKiwi
f427e66f6e More Changes to Monoliths
* 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
2014-05-05 22:37:14 -04:00
StevenRS11
472704fe51 Merge pull request #159 from SenseiKiwi/master
Various Updates
2014-05-05 20:02:09 -04:00
SenseiKiwi
928adab4cf Minor Change in RiftRegenerator
Removed an unnecessary cast in RiftRegenerator
2014-05-05 19:56:21 -04:00
SenseiKiwi
ef2e9cc561 Merge remote-tracking branch 'upstream/master' 2014-05-05 19:55:43 -04:00
SenseiKiwi
7cabf75128 Overhauled Monoliths
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.
2014-05-05 19:55:16 -04:00
StevenRS11
9003d924ea Fixed Door Render 2014-05-05 19:10:58 -04:00
SenseiKiwi
b15a8af299 Minor Change
Minor change to a line in CustomLimboPopulator. We should access static
fields through their classes, not instances.
2014-04-30 04:40:33 -04:00
StevenRS11
19be17fa44 Merge pull request #156 from SenseiKiwi/master
Fixed Golden Door Item ID Mishandling
2014-04-29 13:15:51 -04:00
SenseiKiwi
871d2ff1c2 Fixed Golden Door Item ID Mishandling
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.
2014-04-19 04:28:12 -04:00
190 changed files with 11642 additions and 2933 deletions

2
README.md Normal file
View File

@@ -0,0 +1,2 @@
# Dimensional Doors legacy mirror
This repository is a mirror of the legacy github repo for dimensional doors, its mostly just for a sort of lost media search to get all of the old versions of the mod built.

View File

@@ -13,14 +13,15 @@ buildscript {
apply plugin: 'forge'
version = "2.2.3-" + System.getenv("BUILD_NUMBER")
group= "com.stevenrs11.dimdoors" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
version = "2.2.4-" + System.getenv("BUILD_NUMBER")
group = "com.stevenrs11.dimdoors" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "DimensionalDoors"
minecraft {
version = "1.6.4-9.11.1.964"
version = "1.6.4-9.11.1.964"
replaceIn "mod_pocketDim.java"
replace "@VERSION@", project.version
}
targetCompatibility = '1.6'
@@ -28,15 +29,15 @@ sourceCompatibility = '1.6'
processResources
{
// replace stuff in mcmod.info, nothing else
// Replace stuff $version and $mcversion in mcmod.info
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// replace version and mcversion
// Replace version and mcversion
expand 'version':project.version, 'mcversion':project.minecraft.version
}
// copy everything else, thats not the mcmod.info
// Copy everything else
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}

View File

@@ -1,11 +1,14 @@
package StevenDimDoors.mod_pocketDim;
import java.io.File;
import java.io.FileOutputStream;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.IGuiHandler;
@@ -18,7 +21,6 @@ public class CommonProxy implements IGuiHandler
public static String WARP_PNG = "/WARP.png";
public void registerRenderers()
{
}
public void registerEntity(Class <? extends Entity > entity, String entityname, int id, Object mod, int trackingrange, int updateFreq, boolean updatevelo)
@@ -130,6 +132,20 @@ public class CommonProxy implements IGuiHandler
{
}
public void updateDoorTE(BaseDimDoor door, World world, int x, int y, int z)
{
TileEntity tile = world.getBlockTileEntity(x, y, z);
if (tile instanceof TileEntityDimDoor)
{
int metadata = world.getBlockMetadata(x, y, z);
TileEntityDimDoor dimTile = (TileEntityDimDoor) tile;
dimTile.openOrClosed = door.isDoorOnRift(world, x, y, z)&&door.isUpperDoorBlock(metadata);
dimTile.orientation = door.getFullMetadata(world, x, y, z) & 7;
dimTile.lockStatus = door.getLockStatus(world, x, y, z);
}
}
}

View File

@@ -1,17 +1,11 @@
package StevenDimDoors.mod_pocketDim;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.NetLoginHandler;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet1Login;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.network.ForgePacket;
import net.minecraftforge.common.network.packet.DimensionRegisterPacket;
@@ -65,7 +59,8 @@ public class ConnectionHandler implements IConnectionHandler
@Override
public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager)
{
PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.getDimensionData(0)));
// Hax... please don't do this! >_<
PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.createDimensionDataDangerously(0)));
}
}

View File

@@ -1,15 +1,23 @@
package StevenDimDoors.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDispenser;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.ShapedOreRecipe;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDLock;
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.items.behaviors.DispenserBehaviorStabilizedRS;
import cpw.mods.fml.common.ICraftingHandler;
import cpw.mods.fml.common.registry.GameRegistry;
import static StevenDimDoors.mod_pocketDim.mod_pocketDim.*;
public class CraftingManager
public class CraftingManager implements ICraftingHandler
{
private CraftingManager() { }
CraftingManager() { }
public static void registerRecipes(DDProperties properties)
{
@@ -18,19 +26,19 @@ public class CraftingManager
switch (properties.WorldThreadRequirementLevel)
{
case 1:
GameRegistry.addShapelessRecipe(new ItemStack(itemStableFabric, 1),
GameRegistry.addShapelessRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
Item.enderPearl, mod_pocketDim.itemWorldThread);
break;
case 2:
GameRegistry.addRecipe(new ItemStack(itemStableFabric, 1),
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
"yxy", 'x', Item.enderPearl, 'y', mod_pocketDim.itemWorldThread);
break;
case 3:
GameRegistry.addRecipe(new ItemStack(itemStableFabric, 1),
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
" y ", "yxy", " y ", 'x', Item.enderPearl, 'y', mod_pocketDim.itemWorldThread);
break;
default:
GameRegistry.addRecipe(new ItemStack(itemStableFabric, 1),
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStableFabric, 1),
"yyy", "yxy", "yyy", 'x', Item.enderPearl, 'y', mod_pocketDim.itemWorldThread);
break;
}
@@ -38,54 +46,125 @@ public class CraftingManager
if (properties.CraftingDimensionalDoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(itemDimensionalDoor, 1),
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemDimensionalDoor, 1),
"yxy", 'x', mod_pocketDim.itemStableFabric, 'y', Item.doorIron);
}
if (properties.CraftingUnstableDoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(itemUnstableDoor, 1),
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemUnstableDoor, 1),
"yxy", 'x', Item.eyeOfEnder, 'y', mod_pocketDim.itemDimensionalDoor);
}
if (properties.CraftingWarpDoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(itemWarpDoor, 1),
"yxy", 'x', mod_pocketDim.itemStableFabric, 'y', Item.doorWood);
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemWarpDoor, 1),
"yxy", 'x', Item.enderPearl, 'y', Item.doorWood);
}
if (properties.CraftingTransTrapdoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(transTrapdoor, 1),
"y", "x", "y", 'x', mod_pocketDim.itemStableFabric, 'y', Block.trapdoor);
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.transTrapdoor, 1),
"y", "x", "y", 'x', Item.enderPearl, 'y', Block.trapdoor);
}
if (properties.CraftingRiftSignatureAllowed)
{
GameRegistry.addRecipe(new ItemStack(itemRiftSignature, 1),
" y ", "yxy", " y ", 'x', mod_pocketDim.itemStableFabric, 'y', Item.ingotIron);
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemRiftSignature, 1),
" y ", "yxy", " y ", 'x', Item.enderPearl, 'y', Item.ingotIron);
}
if (properties.CraftingRiftRemoverAllowed)
{
GameRegistry.addRecipe(new ItemStack(itemRiftRemover, 1),
"yyy", "yxy", "yyy", 'x', mod_pocketDim.itemStableFabric, 'y', Item.ingotGold);
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemRiftRemover, 1),
"yyy", "yxy", "yyy", 'x', Item.enderPearl, 'y', Item.ingotGold);
}
if (properties.CraftingRiftBladeAllowed)
{
GameRegistry.addRecipe(new ItemStack(itemRiftBlade, 1),
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemRiftBlade, 1),
"x", "x", "y", 'x', mod_pocketDim.itemStableFabric, 'y', Item.blazeRod);
}
if (properties.CraftingStabilizedRiftSignatureAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStabilizedLinkSignature,1),
" y ", "yxy", " y ", 'x', mod_pocketDim.itemRiftSignature, 'y', mod_pocketDim.itemStableFabric);
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemStabilizedRiftSignature, 1),
" y ", "yxy", " y ", 'x', mod_pocketDim.itemStableFabric, 'y', Item.ingotIron);
}
if (properties.CraftingGoldenDimensionalDoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemGoldenDimensionalDoor,1),
"yxy", 'x', mod_pocketDim.itemGoldenDoor, 'y', mod_pocketDim.itemStableFabric);
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemGoldenDimensionalDoor, 1),
"yxy", 'x', mod_pocketDim.itemStableFabric, 'y', mod_pocketDim.itemGoldenDoor);
}
if (properties.CraftingGoldenDoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemGoldenDoor, 1),
"yy", "yy", "yy", 'y', Item.ingotGold);
}
if (properties.CraftingPersonalDimDoorAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemPersonalDoor,1),
"yxy", 'y', mod_pocketDim.itemGoldenDoor, 'x', mod_pocketDim.itemStableFabric);
}
if (properties.CraftingQuartzDoorAllowed)
{
GameRegistry.addRecipe(new ShapedOreRecipe(mod_pocketDim.itemQuartzDoor, new Object[]{
"yy", "yy", "yy", Character.valueOf('y'), "oreQuartz"}));
}
if (properties.CraftingDDKeysAllowed)
{
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemDDKey, 1),
" z", " y ", "y ", 'y', Item.ingotGold, 'z', Item.enderPearl);
GameRegistry.addRecipe(new ItemStack(mod_pocketDim.itemDDKey, 1),
"z", "z", 'z', mod_pocketDim.itemDDKey);
}
}
@Override
public void onCrafting(EntityPlayer player, ItemStack item, IInventory craftMatrix)
{
if(item.getItem() instanceof ItemDDKey)
{
ItemDDKey keyItem = (ItemDDKey) item.getItem();
ItemStack topKey = null;
ItemStack bottomKey = null;
int topKeySlot = 0;
for(int i = 0; i<craftMatrix.getSizeInventory();i++)
{
ItemStack slot = craftMatrix.getStackInSlot(i);
if(slot!=null)
{
if(topKey==null)
{
topKey = slot;
topKeySlot = i;
}
else
{
bottomKey = slot;
break;
}
}
}
DDLock.addKeys(bottomKey, DDLock.getKeys(topKey));
item.setTagCompound(bottomKey.getTagCompound());
player.inventory.addItemStackToInventory(topKey);
}
}
@Override
public void onSmelting(EntityPlayer player, ItemStack item)
{
// TODO Auto-generated method stub
}
public static void registerDispenserBehaviors()
{
// Register the dispenser behaviors for certain DD items
BlockDispenser.dispenseBehaviorRegistry.putObject(mod_pocketDim.itemStabilizedRiftSignature, new DispenserBehaviorStabilizedRS());
}
}

View File

@@ -1,15 +1,14 @@
package StevenDimDoors.mod_pocketDim;
import net.minecraft.block.Block;
import net.minecraft.client.audio.SoundManager;
import net.minecraft.client.audio.SoundPoolEntry;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.DamageSource;
import net.minecraft.world.World;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.client.event.sound.PlayBackgroundMusicEvent;
import net.minecraftforge.client.event.sound.SoundLoadEvent;
import net.minecraftforge.event.EventPriority;
@@ -19,12 +18,18 @@ import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
import net.minecraftforge.event.terraingen.InitMapGenEvent;
import net.minecraftforge.event.world.ChunkEvent;
import net.minecraftforge.event.world.WorldEvent;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.config.DDWorldProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.items.BaseItemDoor;
import StevenDimDoors.mod_pocketDim.items.ItemWarpDoor;
import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.world.LimboProvider;
import StevenDimDoors.mod_pocketDim.world.PocketProvider;
@@ -34,12 +39,25 @@ import cpw.mods.fml.relauncher.SideOnly;
public class EventHookContainer
{
private static final int MAX_FOOD_LEVEL = 20;
private final DDProperties properties;
private DDWorldProperties worldProperties;
private RiftRegenerator regenerator;
public EventHookContainer(DDProperties properties)
{
this.properties = properties;
}
public void setSessionFields(DDWorldProperties worldProperties, RiftRegenerator regenerator)
{
// SenseiKiwi:
// Why have a setter rather than accessing mod_pocketDim directly?
// I want to make this dependency explicit in our code.
this.worldProperties = worldProperties;
this.regenerator = regenerator;
}
@ForgeSubscribe(priority = EventPriority.LOW)
public void onInitMapGen(InitMapGenEvent event)
@@ -59,6 +77,10 @@ public class EventHookContainer
@ForgeSubscribe
public void onSoundLoad(SoundLoadEvent event)
{
event.manager.addSound(mod_pocketDim.modid + ":doorLockRemoved.ogg");
event.manager.addSound(mod_pocketDim.modid + ":doorLocked.ogg");
event.manager.addSound(mod_pocketDim.modid + ":keyLock.ogg");
event.manager.addSound(mod_pocketDim.modid + ":keyUnlock.ogg");
event.manager.addSound(mod_pocketDim.modid + ":monk.ogg");
event.manager.addSound(mod_pocketDim.modid + ":crack.ogg");
event.manager.addSound(mod_pocketDim.modid + ":tearing.ogg");
@@ -75,7 +97,6 @@ public class EventHookContainer
public void onSoundEffectResult(PlayBackgroundMusicEvent event)
{
if (FMLClientHandler.instance().getClient().thePlayer.worldObj.provider.dimensionId == mod_pocketDim.properties.LimboDimensionID)
;
{
this.playMusicForDim(FMLClientHandler.instance().getClient().thePlayer.worldObj);
}
@@ -85,21 +106,33 @@ public class EventHookContainer
public void onPlayerEvent(PlayerInteractEvent event)
{
// Handle all door placement here
if(event.action == Action.LEFT_CLICK_BLOCK)
if (event.action == Action.LEFT_CLICK_BLOCK)
{
return;
}
World world = event.entity.worldObj;
ItemStack stack = event.entityPlayer.inventory.getCurrentItem();
if (stack != null && stack.getItem() instanceof ItemDoor)
if (stack != null)
{
if (mod_pocketDim.itemDimensionalDoor.tryToPlaceDoor(stack, event.entityPlayer, world,
if(stack.getItem() instanceof ItemWarpDoor)
{
NewDimData data = PocketManager.getDimensionData(world);
if(data.type() == DimensionType.PERSONAL)
{
mod_pocketDim.sendChat(event.entityPlayer,("Something prevents the Warp Door from tunneling out here"));
event.setCanceled(true);
return;
}
}
if (BaseItemDoor.tryToPlaceDoor(stack, event.entityPlayer, world,
event.x, event.y, event.z, event.face))
{
// Cancel the event so that we don't get two doors from vanilla doors
event.setCanceled(true);
}
}
}
@ForgeSubscribe
@@ -137,13 +170,24 @@ public class EventHookContainer
Entity entity = event.entity;
if (properties.LimboEnabled && properties.LimboReturnsInventoryEnabled &&
entity instanceof EntityPlayer && entity.worldObj.provider instanceof PocketProvider)
entity instanceof EntityPlayer && isValidSourceForLimbo(entity.worldObj.provider))
{
EntityPlayer player = (EntityPlayer) entity;
mod_pocketDim.deathTracker.addUsername(player.username);
revivePlayerInLimbo(player);
event.setCanceled(true);
return false;
if(entity.worldObj.provider instanceof PocketProvider)
{
EntityPlayer player = (EntityPlayer) entity;
mod_pocketDim.deathTracker.addUsername(player.username);
revivePlayerInLimbo(player);
event.setCanceled(true);
return false;
}
else if(entity.worldObj.provider instanceof LimboProvider && event.source == DamageSource.outOfWorld)
{
EntityPlayer player = (EntityPlayer) entity;
revivePlayerInLimbo(player);
mod_pocketDim.sendChat(player, "Search for the dark red pools which accumulate in the lower reaches of Limbo");
event.setCanceled(true);
return false;
}
}
return true;
}
@@ -159,7 +203,7 @@ public class EventHookContainer
Entity entity = event.entity;
if (entity instanceof EntityPlayer && entity.worldObj.provider instanceof PocketProvider)
if (entity instanceof EntityPlayer && isValidSourceForLimbo(entity.worldObj.provider))
{
EntityPlayer player = (EntityPlayer) entity;
mod_pocketDim.deathTracker.addUsername(player.username);
@@ -174,12 +218,24 @@ public class EventHookContainer
}
return true;
}
private boolean isValidSourceForLimbo(WorldProvider provider)
{
// Returns whether a given world is a valid place for sending a player
// to Limbo. We can send someone to Limbo from a certain dimension if
// Universal Limbo is enabled and the source dimension is not Limbo, or
// if the source dimension is a pocket dimension.
return (worldProperties.UniversalLimboEnabled && provider.dimensionId != properties.LimboDimensionID) ||
(provider instanceof PocketProvider);
}
private void revivePlayerInLimbo(EntityPlayer player)
{
player.extinguish();
player.clearActivePotions();
player.setHealth(player.getMaxHealth());
player.getFoodStats().addStats(MAX_FOOD_LEVEL, 0);
Point4D destination = LimboProvider.getLimboSkySpawn(player, properties);
DDTeleporter.teleportEntity(player, destination, false);
}
@@ -197,6 +253,25 @@ public class EventHookContainer
}
}
}
@ForgeSubscribe
public void onChunkLoad(ChunkEvent.Load event)
{
// Schedule rift regeneration for any links located in this chunk.
// This event runs on both the client and server. Allow server only.
// Also, check that PocketManager is loaded, because onChunkLoad() can
// fire while chunks are being initialized in a new world, before
// onWorldLoad() fires.
Chunk chunk = event.getChunk();
if (!chunk.worldObj.isRemote && PocketManager.isLoaded())
{
NewDimData dimension = PocketManager.createDimensionData(chunk.worldObj);
for (DimLink link : dimension.getChunkLinks(chunk.xPosition, chunk.zPosition))
{
regenerator.scheduleSlowRegeneration(link);
}
}
}
public void playMusicForDim(World world)
{

View File

@@ -4,5 +4,6 @@ import net.minecraftforge.common.ForgeChunkManager.Ticket;
public interface IChunkLoader
{
public void forceChunkLoading(Ticket ticket,int x, int z);
public boolean isInitialized();
public void initialize(Ticket ticket);
}

View File

@@ -12,5 +12,6 @@ public class PacketConstants
public static final byte CREATE_LINK_PACKET_ID = 4;
public static final byte DELETE_LINK_PACKET_ID = 5;
public static final byte CLIENT_LOGIN_DIM_REGISTER = 6;
public static final byte UPDATE_LINK_PACKET_ID = 7;
}

View File

@@ -38,6 +38,13 @@ public class ServerPacketHandler implements IPacketHandler
public void onDeleted(ClientDimData message)
{
sendDimPacket(PacketConstants.DELETE_DIM_PACKET_ID, message);
}
@Override
public void update(ClientDimData message)
{
// TODO Auto-generated method stub
}
}
@@ -54,6 +61,12 @@ public class ServerPacketHandler implements IPacketHandler
{
sendLinkPacket(PacketConstants.DELETE_LINK_PACKET_ID, message);
}
@Override
public void update(ClientLinkData message)
{
sendLinkPacket(PacketConstants.UPDATE_LINK_PACKET_ID, message);
}
}
public static Packet250CustomPayload createLinkPacket(ClientLinkData data)

View File

@@ -1,7 +1,6 @@
package StevenDimDoors.mod_pocketDim.blocks;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.ITileEntityProvider;
@@ -11,7 +10,8 @@ import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Icon;
import net.minecraft.util.MathHelper;
@@ -22,7 +22,7 @@ import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.schematic.BlockRotator;
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -32,9 +32,9 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
protected final DDProperties properties;
@SideOnly(Side.CLIENT)
private Icon[] upperTextures;
protected Icon[] upperTextures;
@SideOnly(Side.CLIENT)
private Icon[] lowerTextures;
protected Icon[] lowerTextures;
public BaseDimDoor(int blockID, Material material, DDProperties properties)
{
@@ -74,6 +74,18 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ)
{
ItemStack stack = player.inventory.getCurrentItem();
if (stack != null && stack.getItem() instanceof ItemDDKey)
{
return false;
}
if(!checkCanOpen(world, x, y, z, player))
{
return false;
}
final int MAGIC_CONSTANT = 1003;
int metadata = this.getFullMetadata(world, x, y, z);
@@ -92,6 +104,7 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
}
world.playAuxSFXAtEntity(player, MAGIC_CONSTANT, x, y, z, 0);
return true;
}
@@ -159,27 +172,26 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
reversed = !reversed;
}
}
if (isUpperDoorBlock(fullMetadata))
{
return this.upperTextures[reversed ? 1 : 0];
else
return this.lowerTextures[reversed ? 1 : 0];
}
else
{
return this.lowerTextures[0];
}
return this.lowerTextures[reversed ? 1 : 0];
}
return this.lowerTextures[0];
}
//Called to update the render information on the tile entity. Could probably implement a data watcher,
//but this works fine and is more versatile I think.
public BaseDimDoor updateAttachedTile(World world, int x, int y, int z)
{
mod_pocketDim.proxy.updateDoorTE(this, world, x, y, z);
TileEntity tile = world.getBlockTileEntity(x, y, z);
if (tile instanceof TileEntityDimDoor)
{
int metadata = world.getBlockMetadata(x, y, z);
TileEntityDimDoor dimTile = (TileEntityDimDoor) tile;
dimTile.openOrClosed = this.isDoorOnRift(world, x, y, z);
dimTile.openOrClosed = isDoorOnRift(world, x, y, z) && isUpperDoorBlock(metadata);
dimTile.orientation = this.getFullMetadata(world, x, y, z) & 7;
}
return this;
@@ -187,21 +199,34 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
public boolean isDoorOnRift(World world, int x, int y, int z)
{
if(this.isUpperDoorBlock( world.getBlockMetadata(x, y, z)))
return this.getLink(world, x, y, z) != null;
}
public DimLink getLink(World world, int x, int y, int z)
{
DimLink link= PocketManager.getLink(x, y, z, world.provider.dimensionId);
if(link!=null)
{
if(PocketManager.getLink(x, y, z, world.provider.dimensionId) != null||PocketManager.getLink(x, y-1, z, world.provider.dimensionId) != null)
return link;
}
if(isUpperDoorBlock( world.getBlockMetadata(x, y, z)))
{
link = PocketManager.getLink(x, y-1, z, world.provider.dimensionId);
if(link!=null)
{
return true;
return link;
}
}
else
{
if(PocketManager.getLink(x, y, z, world.provider.dimensionId) != null||PocketManager.getLink(x, y+1, z, world.provider.dimensionId) != null)
link = PocketManager.getLink(x, y+1, z, world.provider.dimensionId);
if(link != null)
{
return true;
return link;
}
}
return false;
return null;
}
/**
@@ -311,14 +336,14 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, int neighborID)
{
int metadata = world.getBlockMetadata(x, y, z);
if (isUpperDoorBlock(metadata))
{
if (world.getBlockId(x, y - 1, z) != this.blockID)
{
world.setBlock(x, y, z, 0);
world.setBlockToAir(x, y, z);
}
if (neighborID > 0 && neighborID != this.blockID)
{
this.onNeighborBlockChange(world, x, y - 1, z, neighborID);
@@ -328,13 +353,13 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
{
if (world.getBlockId(x, y + 1, z) != this.blockID)
{
world.setBlock(x, y, z, 0);
world.setBlockToAir(x, y, z);
if (!world.isRemote)
{
this.dropBlockAsItem(world, x, y, z, metadata, 0);
}
}
else
else if(this.getLockStatus(world, x, y, z)<=1)
{
boolean powered = world.isBlockIndirectlyGettingPowered(x, y, z) || world.isBlockIndirectlyGettingPowered(x, y + 1, z);
if ((powered || neighborID > 0 && Block.blocksList[neighborID].canProvidePower()) && neighborID != this.blockID)
@@ -350,31 +375,20 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
*/
@Override
@SideOnly(Side.CLIENT)
public int idPicked(World par1World, int par2, int par3, int par4)
public int idPicked(World world, int x, int y, int z)
{
return this.getDrops();
return this.getDoorItem();
}
/**
* Returns the ID of the items to drop on destruction.
*/
public int idDropped(int metadata, Random random, int fortune)
@Override
public int idDropped(int metadata, Random random, int fortune)
{
return isUpperDoorBlock(metadata) ? 0 : this.getDrops();
}
/**
* Called when the block is attempted to be harvested
*/
@Override
public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer)
{
if (par6EntityPlayer.capabilities.isCreativeMode && (par5 & 8) != 0 && par1World.getBlockId(par2, par3 - 1, par4) == this.blockID)
{
par1World.setBlock(par2, par3 - 1, par4, 0);
}
}
@Override
public TileEntity createNewTileEntity(World world)
{
@@ -428,16 +442,77 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
}
}
public static boolean isUpperDoorBlock(int metadata)
public boolean isUpperDoorBlock(int metadata)
{
return (metadata & 8) != 0;
}
public static boolean isDoorOpen(int metadata)
public boolean isDoorOpen(int metadata)
{
return (metadata & 4) != 0;
}
/**
* 0 if link is no lock;
* 1 if there is a lock;
* 2 if the lock is locked.
* @param world
* @param x
* @param y
* @param z
* @return
*/
public byte getLockStatus(World world, int x, int y, int z)
{
byte status = 0;
DimLink link = getLink(world, x, y, z);
if(link!=null&&link.hasLock())
{
status++;
if(link.getLockState())
{
status++;
}
}
return status;
}
public boolean checkCanOpen(World world, int x, int y, int z)
{
return this.checkCanOpen(world, x, y, z, null);
}
public boolean checkCanOpen(World world, int x, int y, int z, EntityPlayer player)
{
DimLink link = getLink(world, x, y, z);
if(link==null||player==null)
{
return link==null;
}
if(!link.getLockState())
{
return true;
}
for(ItemStack item : player.inventory.mainInventory)
{
if(item != null)
{
if(item.getItem() instanceof ItemDDKey)
{
if(link.tryToOpen(item))
{
return true;
}
}
}
}
player.playSound(mod_pocketDim.modid + ":doorLocked", 1F, 1F);
return false;
}
protected static boolean isEntityFacingDoor(int metadata, EntityLivingBase entity)
{
// Although any entity has the proper fields for this check,
@@ -454,4 +529,18 @@ public abstract class BaseDimDoor extends BlockDoor implements IDimDoor, ITileEn
world.setBlockTileEntity(x, y, z, te);
return te;
}
@Override
public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta)
{
// This function runs on the server side after a block is replaced
// We MUST call super.breakBlock() since it involves removing tile entities
super.breakBlock(world, x, y, z, oldBlockID, oldMeta);
// Schedule rift regeneration for this block if it was replaced
if (world.getBlockId(x, y, z) != oldBlockID)
{
mod_pocketDim.riftRegenerator.scheduleFastRegeneration(x, y, z, world);
}
}
}

View File

@@ -14,8 +14,10 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Icon;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDimClient.PrivatePocketRender;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -23,7 +25,7 @@ public class BlockDimWall extends Block
{
private static final float SUPER_HIGH_HARDNESS = 10000000000000F;
private static final float SUPER_EXPLOSION_RESISTANCE = 18000000F;
private Icon[] blockIcon = new Icon[2];
private Icon[] blockIcon = new Icon[3];
public BlockDimWall(int blockID, int j, Material par2Material)
{
@@ -34,7 +36,7 @@ public class BlockDimWall extends Block
@Override
public float getBlockHardness(World world, int x, int y, int z)
{
if (world.getBlockMetadata(x, y, z) == 0)
if (world.getBlockMetadata(x, y, z) != 1)
{
return this.blockHardness;
}
@@ -47,7 +49,7 @@ public class BlockDimWall extends Block
@Override
public float getExplosionResistance(Entity entity, World world, int x, int y, int z, double explosionX, double explosionY, double explosionZ)
{
if (world.getBlockMetadata(x, y, z) == 0)
if (world.getBlockMetadata(x, y, z) != 1)
{
return super.getExplosionResistance(entity, world, x, y, z, explosionX, explosionY, explosionZ);
}
@@ -57,25 +59,41 @@ public class BlockDimWall extends Block
}
}
public int getRenderType()
{
return PrivatePocketRender.renderID;
}
@Override
public void registerIcons(IconRegister par1IconRegister)
{
this.blockIcon[0] = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName());
this.blockIcon[1] = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName() + "Perm");
this.blockIcon[2] = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName() + "Personal");
}
@SideOnly(Side.CLIENT)
@Override
public Icon getIcon(int par1, int par2)
{
return (par2 != 1) ? blockIcon[0] : blockIcon[1];
switch(par2)
{
case 0:
return blockIcon[0];
case 1:
return blockIcon[1];
case 2:
return blockIcon[2];
default:
return blockIcon[0];
}
}
@Override
public int damageDropped(int metadata)
{
//Return 0 to avoid dropping Ancient Fabric even if the player somehow manages to break it
return 0;
return metadata == 1 ? 0 : metadata;
}
@Override
@@ -83,11 +101,12 @@ public class BlockDimWall extends Block
@SideOnly(Side.CLIENT)
public void getSubBlocks(int unknown, CreativeTabs tab, List subItems)
{
for (int ix = 0; ix < 2; ix++)
for (int ix = 0; ix < 3; ix++)
{
subItems.add(new ItemStack(this, 1, ix));
}
}
@Override
public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) {}
@@ -110,7 +129,7 @@ public class BlockDimWall extends Block
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityPlayer, int par6, float par7, float par8, float par9)
{
//Check if the metadata value is 0 -- we don't want the user to replace Ancient Fabric
if (entityPlayer.getCurrentEquippedItem() != null && world.getBlockMetadata(x, y, z) == 0)
if (entityPlayer.getCurrentEquippedItem() != null && world.getBlockMetadata(x, y, z) != 1)
{
Item playerEquip = entityPlayer.getCurrentEquippedItem().getItem();

View File

@@ -2,123 +2,34 @@ package StevenDimDoors.mod_pocketDim.blocks;
import java.util.Random;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.IconFlipped;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.item.Item;
import net.minecraft.util.Icon;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class BlockDoorGold extends BlockDoor
{
@SideOnly(Side.CLIENT)
private Icon[] upperTextures;
@SideOnly(Side.CLIENT)
private Icon[] lowerTextures;
public BlockDoorGold(int par1, Material par2Material)
{
super(par1, par2Material);
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IconRegister iconRegister)
{
upperTextures = new Icon[2];
lowerTextures = new Icon[2];
upperTextures[0] = iconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName() + "_upper");
lowerTextures[0] = iconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName() + "_lower");
upperTextures[1] = new IconFlipped(upperTextures[0], true, false);
lowerTextures[1] = new IconFlipped(lowerTextures[0], true, false);
}
@SideOnly(Side.CLIENT)
protected String getTextureName()
{
return mod_pocketDim.modid + ":" + this.getUnlocalizedName();
}
@Override
public int idDropped(int par1, Random par2Random, int par3)
{
return (par1 & 8) != 0 ? 0 : mod_pocketDim.itemGoldenDoor.itemID;
}
/**
* From the specified side and block metadata retrieves the blocks texture. Args: side, metadata
*/
@Override
@SideOnly(Side.CLIENT)
public Icon getIcon(int side, int metadata)
{
return this.upperTextures[0];
}
/**
* Retrieves the block texture to use based on the display side. Args: iBlockAccess, x, y, z, side
*/
@Override
@SideOnly(Side.CLIENT)
public Icon getBlockTexture(IBlockAccess blockAccess, int x, int y, int z, int side)
{
if (side != 1 && side != 0)
{
int fullMetadata = this.getFullMetadata(blockAccess, x, y, z);
int orientation = fullMetadata & 3;
boolean reversed = false;
if (BaseDimDoor.isDoorOpen(fullMetadata))
{
if (orientation == 0 && side == 2)
{
reversed = !reversed;
}
else if (orientation == 1 && side == 5)
{
reversed = !reversed;
}
else if (orientation == 2 && side == 3)
{
reversed = !reversed;
}
else if (orientation == 3 && side == 4)
{
reversed = !reversed;
}
}
else
{
if (orientation == 0 && side == 5)
{
reversed = !reversed;
}
else if (orientation == 1 && side == 3)
{
reversed = !reversed;
}
else if (orientation == 2 && side == 4)
{
reversed = !reversed;
}
else if (orientation == 3 && side == 2)
{
reversed = !reversed;
}
if ((fullMetadata & 16) != 0)
{
reversed = !reversed;
}
}
if (BaseDimDoor.isUpperDoorBlock(fullMetadata))
return this.upperTextures[reversed ? 1 : 0];
else
return this.lowerTextures[reversed ? 1 : 0];
}
else
{
return this.lowerTextures[0];
}
}
}

View File

@@ -0,0 +1,28 @@
package StevenDimDoors.mod_pocketDim.blocks;
import java.util.Random;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.material.Material;
public class BlockDoorQuartz extends BlockDoor
{
public BlockDoorQuartz(int par1, Material par2Material)
{
super(par1, par2Material);
}
@SideOnly(Side.CLIENT)
protected String getTextureName()
{
return mod_pocketDim.modid + ":" + this.getUnlocalizedName();
}
@Override
public int idDropped(int par1, Random par2Random, int par3)
{
return (par1 & 8) != 0 ? 0 : mod_pocketDim.itemGoldenDoor.itemID;
}
}

View File

@@ -3,7 +3,7 @@ package StevenDimDoors.mod_pocketDim.blocks;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoorGold;
@@ -25,15 +25,21 @@ public class BlockGoldDimDoor extends BaseDimDoor
{
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{
NewDimData dimension = PocketManager.getDimensionData(world);
NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (link == null)
{
dimension.createLink(x, y, z, LinkTypes.POCKET,world.getBlockMetadata(x, y - 1, z));
dimension.createLink(x, y, z, LinkType.POCKET,world.getBlockMetadata(x, y - 1, z));
}
}
}
@Override
public int getDoorItem()
{
return mod_pocketDim.itemGoldenDimensionalDoor.itemID;
}
@Override
public int getDrops()
{

View File

@@ -9,7 +9,7 @@ import net.minecraft.util.Icon;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.ticking.LimboDecay;
import StevenDimDoors.mod_pocketDim.world.LimboDecay;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

View File

@@ -47,14 +47,28 @@ public class BlockRift extends Block implements ITileEntityProvider
public static final int MAX_WORLD_THREAD_DROP_CHANCE = 1000;
private final DDProperties properties;
private final ArrayList<Integer> blocksImmuneToRift;
private final ArrayList<Integer> blocksImmuneToRift; // List of Vanilla blocks immune to rifts
private final ArrayList<Integer> modBlocksImmuneToRift; // List of DD blocks immune to rifts
public BlockRift(int i, int j, Material par2Material, DDProperties properties)
{
super(i, par2Material);
this.setTickRandomly(true);
this.properties = properties;
this.modBlocksImmuneToRift = new ArrayList<Integer>();
this.modBlocksImmuneToRift.add(properties.FabricBlockID);
this.modBlocksImmuneToRift.add(properties.PermaFabricBlockID);
this.modBlocksImmuneToRift.add(properties.DimensionalDoorID);
this.modBlocksImmuneToRift.add(properties.WarpDoorID);
this.modBlocksImmuneToRift.add(properties.TransTrapdoorID);
this.modBlocksImmuneToRift.add(properties.UnstableDoorID);
this.modBlocksImmuneToRift.add(properties.RiftBlockID);
this.modBlocksImmuneToRift.add(properties.TransientDoorID);
this.modBlocksImmuneToRift.add(properties.GoldenDimensionalDoorID);
this.modBlocksImmuneToRift.add(properties.GoldenDoorID);
this.blocksImmuneToRift = new ArrayList<Integer>();
this.blocksImmuneToRift.add(properties.FabricBlockID);
this.blocksImmuneToRift.add(properties.PermaFabricBlockID);
this.blocksImmuneToRift.add(properties.DimensionalDoorID);
@@ -65,7 +79,7 @@ public class BlockRift extends Block implements ITileEntityProvider
this.blocksImmuneToRift.add(properties.TransientDoorID);
this.blocksImmuneToRift.add(properties.GoldenDimensionalDoorID);
this.blocksImmuneToRift.add(properties.GoldenDoorID);
this.blocksImmuneToRift.add(properties.PersonalDimDoorID);
this.blocksImmuneToRift.add(Block.blockLapis.blockID);
this.blocksImmuneToRift.add(Block.blockIron.blockID);
this.blocksImmuneToRift.add(Block.blockGold.blockID);
@@ -84,9 +98,6 @@ public class BlockRift extends Block implements ITileEntityProvider
{
return false;
}
@Override
public void onBlockDestroyedByPlayer(World par1World, int par2, int par3, int par4, int par5) {}
@Override
public boolean isOpaqueCube()
@@ -113,10 +124,10 @@ public class BlockRift extends Block implements ITileEntityProvider
return true;
}
//this doesnt do anything yet.
@Override
public int getRenderType()
{
// This doesn't do anything yet
if (mod_pocketDim.isPlayerWearingGoogles)
{
return 0;
@@ -220,7 +231,7 @@ public class BlockRift extends Block implements ITileEntityProvider
return targets;
}
private void dropWorldThread(int blockID, World world, int x, int y, int z, Random random)
public void dropWorldThread(int blockID, World world, int x, int y, int z, Random random)
{
if (blockID != 0 && (random.nextInt(MAX_WORLD_THREAD_DROP_CHANCE) < properties.WorldThreadDropChance)
&& !(Block.blocksList[blockID] instanceof BlockFlowing ||
@@ -232,7 +243,7 @@ public class BlockRift extends Block implements ITileEntityProvider
}
}
private void addAdjacentBlocks(int x, int y, int z, int distance, HashMap<Point3D, Integer> pointDistances, Queue<Point3D> points)
private static void addAdjacentBlocks(int x, int y, int z, int distance, HashMap<Point3D, Integer> pointDistances, Queue<Point3D> points)
{
Point3D[] neighbors = new Point3D[] {
new Point3D(x - 1, y, z),
@@ -251,16 +262,6 @@ public class BlockRift extends Block implements ITileEntityProvider
}
}
}
public void regenerateRift(World world, int x, int y, int z, Random random)
{
if (!this.isBlockImmune(world, x, y, z) && world.getChunkProvider().chunkExists(x >> 4, z >> 4))
{
int blockID = world.getBlockId(x, y, z);
if (world.setBlock(x, y, z, properties.RiftBlockID))
dropWorldThread(blockID, world, x, y, z, random);
}
}
public boolean spreadRift(NewDimData dimension, DimLink parent, World world, Random random)
{
@@ -306,111 +307,37 @@ public class BlockRift extends Block implements ITileEntityProvider
@Override
@SideOnly(Side.CLIENT)
public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random rand)
public void randomDisplayTick(World world, int x, int y, int z, Random rand)
{
int count;
//growth in the direction towards the nearby rift
float xGrowth=0;
float yGrowth=0;
float zGrowth=0;
//growth away from the nearby rift
float xGrowthn=0;
float yGrowthn=0;
float zGrowthn=0;
//how far the particles are away from original rift. Used to decrease noise the farther they are away.
float xChange = 0;
float yChange = 0;
float zChange = 0;
TileEntityRift tile = (TileEntityRift)par1World.getBlockTileEntity(par2, par3, par4);
float Xoffset=0;
float Yoffset=0;
float Zoffset=0;
for (count = 0; count < 12 && tile!=null; ++count)
{
//TODO change to a switch statement for clarity
if(tile.xOffset>0)
{
if(rand.nextInt(tile.xOffset)==0)
{
xGrowth =xGrowth+.15F*tile.xOffset;
}
}
else if(tile.xOffset<0)
{
if(rand.nextInt(-tile.xOffset)==0)
{
xGrowthn =xGrowthn-.15F*-tile.xOffset;
}
}
if(tile.yOffset>0)
{
if(rand.nextInt(tile.yOffset)==0)
{
yGrowth =yGrowth+.15F*tile.yOffset;
}
}
else if(tile.yOffset<0)
{
if(rand.nextInt(-tile.yOffset)==0)
{
yGrowthn =yGrowthn-.15F*-tile.yOffset;
}
}
if(tile.zOffset>0)
{
if(rand.nextInt(tile.zOffset)==0)
{
zGrowth =zGrowth+.15F*tile.zOffset;
}
}
else if(tile.zOffset<0)
{
if(rand.nextInt(-tile.zOffset)==0)
{
zGrowthn =zGrowthn-.15F*-tile.zOffset;
}
}
xChange=(float) ((xGrowth+xGrowthn)+rand.nextGaussian()*.05F);
yChange=(float) ((yGrowth+yGrowthn)+rand.nextGaussian()*.05F);
zChange=(float) ((zGrowth+zGrowthn)+rand.nextGaussian()*.05F);
Xoffset= ((0.25F/(1+Math.abs(xChange))));
Yoffset= ((0.25F/(1+Math.abs(yChange))));
Zoffset= ((0.25F/(1+Math.abs(zChange))));
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new RiftFX(par1World,par2+.5+xChange+Xoffset*rand.nextGaussian(), par3+.5+yChange+Yoffset*rand.nextGaussian() , par4+.5+zChange+Zoffset*rand.nextGaussian(), rand.nextGaussian() * 0.001D, rand.nextGaussian() * 0.001D, rand.nextGaussian() * 0.001D, FMLClientHandler.instance().getClient().effectRenderer));
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new RiftFX(par1World,par2+.5-xChange-Xoffset*rand.nextGaussian(), par3+.5-yChange-Yoffset*rand.nextGaussian() , par4+.5-zChange-Zoffset*rand.nextGaussian(), rand.nextGaussian() * 0.001D, rand.nextGaussian() * 0.001D, rand.nextGaussian() * 0.001D, FMLClientHandler.instance().getClient().effectRenderer));
ArrayList<Point3D> targets=findReachableBlocks(world, x, y, z, 2, false);
TileEntityRift tile = (TileEntityRift)world.getBlockTileEntity(x, y, z);
if(rand.nextBoolean())
{
//renders an extra little blob on top of the actual rift location so its easier to find. Eventually will only render if the player has the goggles.
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new GoggleRiftFX(par1World,par2+.5, par3+.5, par4+.5, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, FMLClientHandler.instance().getClient().effectRenderer));
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new GoggleRiftFX(world,x+.5, y+.5, z+.5, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, FMLClientHandler.instance().getClient().effectRenderer));
}
if(tile.shouldClose)
{
//renders an opposite color effect if it is being closed by the rift remover
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new ClosingRiftFX(par1World,par2+.5, par3+.5, par4+.5, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, FMLClientHandler.instance().getClient().effectRenderer));
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new ClosingRiftFX(world,x+.5, y+.5, z+.5, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, rand.nextGaussian() * 0.01D, FMLClientHandler.instance().getClient().effectRenderer));
}
}
public boolean tryPlacingRift(World world, int x, int y, int z)
{
if (world != null && !isBlockImmune(world, x, y, z))
{
return world.setBlock(x, y, z, mod_pocketDim.blockRift.blockID);
}
return false;
}
public boolean isBlockImmune(World world, int x, int y, int z)
@@ -424,7 +351,21 @@ public class BlockRift extends Block implements ITileEntityProvider
// is designed to receive an entity, the source of the blast. We have no entity so
// I've set this to access blockResistance directly. Might need changing later.
return (block.blockResistance >= MIN_IMMUNE_RESISTANCE || blocksImmuneToRift.contains(block.blockID));
return (block.blockResistance >= MIN_IMMUNE_RESISTANCE ||
modBlocksImmuneToRift.contains(block.blockID) ||
blocksImmuneToRift.contains(block.blockID));
}
return false;
}
public boolean isModBlockImmune(World world, int x, int y, int z)
{
// Check whether the block at the specified location is one of the
// rift-resistant blocks from DD.
Block block = Block.blocksList[world.getBlockId(x, y, z)];
if (block != null)
{
return modBlocksImmuneToRift.contains(block.blockID);
}
return false;
}
@@ -446,4 +387,18 @@ public class BlockRift extends Block implements ITileEntityProvider
{
return new TileEntityRift();
}
@Override
public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta)
{
// This function runs on the server side after a block is replaced
// We MUST call super.breakBlock() since it involves removing tile entities
super.breakBlock(world, x, y, z, oldBlockID, oldMeta);
// Schedule rift regeneration for this block if it was changed
if (world.getBlockId(x, y, z) != oldBlockID)
{
mod_pocketDim.riftRegenerator.scheduleSlowRegeneration(x, y, z, world);
}
}
}

View File

@@ -3,16 +3,15 @@ package StevenDimDoors.mod_pocketDim.blocks;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
@SuppressWarnings("deprecation")
public class DimensionalDoor extends BaseDimDoor
{
public DimensionalDoor(int blockID, Material material, DDProperties properties)
{
super(blockID, material, properties);
@@ -23,14 +22,21 @@ public class DimensionalDoor extends BaseDimDoor
{
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{
NewDimData dimension = PocketManager.getDimensionData(world);
NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (link == null)
{
dimension.createLink(x, y, z, LinkTypes.POCKET,world.getBlockMetadata(x, y - 1, z));
dimension.createLink(x, y, z, LinkType.POCKET,world.getBlockMetadata(x, y - 1, z));
}
}
}
@Override
public int getDoorItem()
{
return mod_pocketDim.itemDimensionalDoor.itemID;
}
@Override
public int getDrops()
{

View File

@@ -6,11 +6,39 @@ import net.minecraft.world.World;
public interface IDimDoor
{
/**
* A function to enter a dim door and traverse its link, called when a player collides with an open door
* @param world
* @param x
* @param y
* @param z
* @param entity
*/
public void enterDimDoor(World world, int x, int y, int z, Entity entity);
/**
* called when a door is placed to determine how it will place a link
* @param world
* @param x
* @param y
* @param z
*/
public void placeLink(World world, int x, int y, int z);
public int getDrops();
public int getDoorItem();
public TileEntity initDoorTE(World world, int x, int y, int z);
/**
* checks if any of this doors blocks are overlapping with a rift
* @param world
* @param x
* @param y
* @param z
* @return
*/
public boolean isDoorOnRift(World world, int x, int y, int z);
}

View File

@@ -0,0 +1,47 @@
package StevenDimDoors.mod_pocketDim.blocks;
import net.minecraft.block.material.Material;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
public class PersonalDimDoor extends BaseDimDoor
{
public PersonalDimDoor(int blockID, Material material, DDProperties properties)
{
super(blockID, material, properties);
// TODO Auto-generated constructor stub
}
@Override
public void placeLink(World world, int x, int y, int z)
{
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{
NewDimData dimension = PocketManager.getDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (link == null)
{
dimension.createLink(x, y, z, LinkType.PERSONAL, world.getBlockMetadata(x, y - 1, z));
}
}
}
@Override
public int getDrops()
{
return mod_pocketDim.itemQuartzDoor.itemID;
}
@Override
public int getDoorItem()
{
return mod_pocketDim.itemPersonalDoor.itemID;
}
}

View File

@@ -2,23 +2,28 @@ package StevenDimDoors.mod_pocketDim.blocks;
import java.util.Random;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.BlockTrapDoor;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityTransTrapdoor;
@SuppressWarnings("deprecation")
public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntityProvider
{
@@ -41,18 +46,66 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit
enterDimDoor(world, x, y, z, entity);
}
public boolean checkCanOpen(World world, int x, int y, int z)
{
return this.checkCanOpen(world, x, y, z, null);
}
public boolean checkCanOpen(World world, int x, int y, int z, EntityPlayer player)
{
DimLink link = PocketManager.getLink( x, y, z, world);
if(link==null||player==null)
{
return link==null;
}
if(!link.getLockState())
{
return true;
}
for(ItemStack item : player.inventory.mainInventory)
{
if(item != null)
{
if(item.getItem() instanceof ItemDDKey)
{
if(link.tryToOpen(item))
{
return true;
}
}
}
}
return false;
}
public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9)
{
if(this.checkCanOpen(par1World, par2, par3, par4, par5EntityPlayer))
{
return super.onBlockActivated(par1World, par2, par3, par4, par5EntityPlayer, par6, par7, par8, par9);
}
return false;
}
public void onPoweredBlockChange(World par1World, int par2, int par3, int par4, boolean par5)
{
if(this.checkCanOpen(par1World, par2, par3, par4))
{
super.onPoweredBlockChange(par1World, par2, par3, par4, par5);
}
}
@Override
public void enterDimDoor(World world, int x, int y, int z, Entity entity)
{
if (!world.isRemote && isTrapdoorOpen(world.getBlockMetadata(x, y, z)))
{
this.onPoweredBlockChange(world, x, y, z, false);
DimLink link = PocketManager.getLink(x, y, z, world);
if (link != null)
{
DDTeleporter.traverseDimDoor(world, link, entity,this);
}
super.onPoweredBlockChange(world, x, y, z, false);
}
}
@@ -61,14 +114,6 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit
{
this.placeLink(world, x, y, z);
world.setBlockTileEntity(x, y, z, this.createNewTileEntity(world));
this.updateAttachedTile(world, x, y, z);
}
@Override
public void updateTick(World world, int x, int y, int z, Random random)
{
TileEntityTransTrapdoor tile = (TileEntityTransTrapdoor) world.getBlockTileEntity(x, y, z);
tile.hasRift = PocketManager.getLink(x, y, z, world) != null;
}
@Override
@@ -76,42 +121,44 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit
{
return new TileEntityTransTrapdoor();
}
public void updateAttachedTile(World world, int x, int y, int z)
{
TileEntity tile = world.getBlockTileEntity(x, y, z);
if (tile instanceof TileEntityTransTrapdoor)
{
TileEntityTransTrapdoor trapdoorTile = (TileEntityTransTrapdoor) tile;
trapdoorTile.hasRift = (PocketManager.getLink(x, y, z, world) != null);
}
}
@Override
public void placeLink(World world, int x, int y, int z)
{
if (!world.isRemote)
{
NewDimData dimension = PocketManager.getDimensionData(world);
NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (link == null && dimension.isPocketDimension())
{
dimension.createLink(x, y, z, LinkTypes.UNSAFE_EXIT,0);
dimension.createLink(x, y, z, LinkType.UNSAFE_EXIT,0);
}
}
}
@Override
@SideOnly(Side.CLIENT)
public int idPicked(World world, int x, int y, int z)
{
return this.getDoorItem();
}
@Override
public int idDropped(int metadata, Random random, int fortuneLevel)
{
return getDrops();
return this.getDrops();
}
@Override
public int getDoorItem()
{
return mod_pocketDim.transTrapdoor.blockID;
}
@Override
public int getDrops()
{
return Block.trapdoor.blockID;
return Block.trapdoor.blockID;
}
public static boolean isTrapdoorSetLow(int metadata)
@@ -126,4 +173,24 @@ public class TransTrapdoor extends BlockTrapDoor implements IDimDoor, ITileEntit
world.setBlockTileEntity(x, y, z, te);
return te;
}
@Override
public boolean isDoorOnRift(World world, int x, int y, int z)
{
return PocketManager.getLink(x, y, z, world)!=null;
}
@Override
public void breakBlock(World world, int x, int y, int z, int oldBlockID, int oldMeta)
{
// This function runs on the server side after a block is replaced
// We MUST call super.breakBlock() since it involves removing tile entities
super.breakBlock(world, x, y, z, oldBlockID, oldMeta);
// Schedule rift regeneration for this block if it was replaced
if (world.getBlockId(x, y, z) != oldBlockID)
{
mod_pocketDim.riftRegenerator.scheduleFastRegeneration(x, y, z, world);
}
}
}

View File

@@ -9,7 +9,7 @@ import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
@@ -64,14 +64,20 @@ public class TransientDoor extends BaseDimDoor
{
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{
NewDimData dimension = PocketManager.getDimensionData(world);
NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (link == null && dimension.isPocketDimension())
{
dimension.createLink(x, y, z, LinkTypes.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
dimension.createLink(x, y, z, LinkType.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
}
}
}
@Override
public int getDoorItem()
{
return 0;
}
@Override
public int getDrops()

View File

@@ -3,8 +3,9 @@ package StevenDimDoors.mod_pocketDim.blocks;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
@@ -21,9 +22,16 @@ public class UnstableDoor extends BaseDimDoor
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{
NewDimData dimension = PocketManager.getDimensionData(world);
dimension.createLink(x, y, z, LinkTypes.RANDOM,world.getBlockMetadata(x, y - 1, z));
dimension.createLink(x, y, z, LinkType.RANDOM,world.getBlockMetadata(x, y - 1, z));
}
}
@Override
public int getDoorItem()
{
return mod_pocketDim.itemUnstableDoor.itemID;
}
@Override
public int getDrops()
{

View File

@@ -3,13 +3,13 @@ package StevenDimDoors.mod_pocketDim.blocks;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
@SuppressWarnings("deprecation")
public class WarpDoor extends BaseDimDoor
{
public WarpDoor(int blockID, Material material, DDProperties properties)
@@ -22,15 +22,21 @@ public class WarpDoor extends BaseDimDoor
{
if (!world.isRemote && world.getBlockId(x, y - 1, z) == this.blockID)
{
NewDimData dimension = PocketManager.getDimensionData(world);
NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (link == null && dimension.isPocketDimension())
{
dimension.createLink(x, y, z, LinkTypes.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
dimension.createLink(x, y, z, LinkType.SAFE_EXIT,world.getBlockMetadata(x, y - 1, z));
}
}
}
@Override
public int getDoorItem()
{
return mod_pocketDim.itemWarpDoor.itemID;
}
@Override
public int getDrops()
{

View File

@@ -1,20 +1,18 @@
package StevenDimDoors.mod_pocketDim.commands;
import java.util.Collection;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
import StevenDimDoors.mod_pocketDim.world.PocketBuilder;
import java.util.Collection;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
public class CommandCreateDungeonRift extends DDCommandBase
{
private static CommandCreateDungeonRift instance = null;
@@ -38,10 +36,6 @@ public class CommandCreateDungeonRift extends DDCommandBase
NewDimData dimension;
DungeonHelper dungeonHelper = DungeonHelper.instance();
if (sender.worldObj.isRemote)
{
return DDCommandResult.SUCCESS;
}
if (command.length == 0)
{
return DDCommandResult.TOO_FEW_ARGUMENTS;
@@ -68,7 +62,8 @@ public class CommandCreateDungeonRift extends DDCommandBase
if (result != null)
{
dimension = PocketManager.getDimensionData(sender.worldObj);
link = dimension.createLink(x, y + 1, z, LinkTypes.DUNGEON, orientation);
link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation);
if (PocketBuilder.generateSelectedDungeonPocket(link, mod_pocketDim.properties, result))
{
// Create a rift to our selected dungeon and notify the player

View File

@@ -1,6 +1,5 @@
package StevenDimDoors.mod_pocketDim.commands;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
@@ -24,26 +23,21 @@ public class CommandCreatePocket extends DDCommandBase
@Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{
//TODO: Some commands have isRemote checks, some do not. Why? Can commands even run locally anyway?
//What does it mean when you run a command locally? ~SenseiKiwi
if (!sender.worldObj.isRemote)
if (command.length > 0)
{
if (command.length > 0)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;
}
//Place a door leading to a pocket dimension where the player is standing.
//The pocket dimension will serve as a room for the player to build a dungeon.
int x = (int) sender.posX;
int y = (int) sender.posY;
int z = (int) sender.posZ;
DungeonHelper.instance().createCustomDungeonDoor(sender.worldObj, x, y, z);
//Notify the player
sendChat(sender,("Created a door to a pocket dimension. Please build your dungeon there."));
return DDCommandResult.TOO_MANY_ARGUMENTS;
}
//Place a door leading to a pocket dimension where the player is standing.
//The pocket dimension will serve as a room for the player to build a dungeon.
int x = (int) sender.posX;
int y = (int) sender.posY;
int z = (int) sender.posZ;
DungeonHelper.instance().createCustomDungeonDoor(sender.worldObj, x, y, z);
//Notify the player
sendChat(sender, "Created a door to a pocket dimension. Please build your dungeon there.");
return DDCommandResult.SUCCESS;
}
}

View File

@@ -8,7 +8,7 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.MathHelper;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
@@ -38,11 +38,7 @@ public class CommandCreateRandomRift extends DDCommandBase
{
NewDimData dimension;
DungeonHelper dungeonHelper = DungeonHelper.instance();
if (sender.worldObj.isRemote)
{
return DDCommandResult.SUCCESS;
}
if (command.length > 1)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;
@@ -58,7 +54,8 @@ public class CommandCreateRandomRift extends DDCommandBase
if (command.length == 0)
{
dimension = PocketManager.getDimensionData(sender.worldObj);
link = dimension.createLink(x, y + 1, z, LinkTypes.DUNGEON, orientation);
link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation);
sender.worldObj.setBlock(x, y + 1, z,mod_pocketDim.blockRift.blockID, 0, 3);
sendChat(sender, "Created a rift to a random dungeon.");
}
@@ -74,7 +71,8 @@ public class CommandCreateRandomRift extends DDCommandBase
if (result != null)
{
dimension = PocketManager.getDimensionData(sender.worldObj);
link = dimension.createLink(x, y + 1, z, LinkTypes.DUNGEON, orientation);
link = dimension.createLink(x, y + 1, z, LinkType.DUNGEON, orientation);
if (PocketBuilder.generateSelectedDungeonPocket(link, mod_pocketDim.properties, result))
{
// Create a rift to our selected dungeon and notify the player
@@ -118,9 +116,6 @@ public class CommandCreateRandomRift extends DDCommandBase
{
return null;
}
else
{
return matches.get( random.nextInt(matches.size()) );
}
return matches.get( random.nextInt(matches.size()) );
}
}

View File

@@ -1,69 +0,0 @@
package StevenDimDoors.mod_pocketDim.commands;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import java.util.ArrayList;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
@SuppressWarnings("deprecation")
public class CommandDeleteAllLinks extends DDCommandBase
{
private static CommandDeleteAllLinks instance = null;
private CommandDeleteAllLinks()
{
super("dd-deletelinks", "???");
}
public static CommandDeleteAllLinks instance()
{
if (instance == null)
instance = new CommandDeleteAllLinks();
return instance;
}
@Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{
int linksRemoved=0;
int targetDim;
boolean shouldGo= true;
if(command.length==1)
{
targetDim = parseInt(sender, command[0]);
}
else
{
targetDim=0;
shouldGo=false;
sendChat(sender, ("Error-Invalid argument, delete_all_links <targetDimID>"));
}
if(shouldGo)
{
NewDimData dim = PocketManager.getDimensionData(targetDim);
ArrayList<DimLink> linksInDim = dim.getAllLinks();
for (DimLink link : linksInDim)
{
World targetWorld = PocketManager.loadDimension(targetDim);
targetWorld.setBlock(link.source().getX(), link.source().getY(), link.source().getZ(), 0);
dim.deleteLink(link);
//TODO Probably should check what the block is, but thats annoying so Ill do it later.
linksRemoved++;
}
sendChat(sender,("Removed " + linksRemoved + " links."));
}
return DDCommandResult.SUCCESS; //TEMPORARY HACK
}
}

View File

@@ -2,22 +2,21 @@ package StevenDimDoors.mod_pocketDim.commands;
import java.util.ArrayList;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
@SuppressWarnings("deprecation")
public class CommandDeleteRifts extends DDCommandBase
{
private static CommandDeleteRifts instance = null;
private CommandDeleteRifts()
{
super("dd-???", "???");
super("dd-deleterifts", "[dimension number]");
}
public static CommandDeleteRifts instance()
@@ -31,47 +30,64 @@ public class CommandDeleteRifts extends DDCommandBase
@Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{
int linksRemoved=0;
int targetDim;
boolean shouldGo= true;
int linksRemoved = 0;
int targetDimension;
if(command.length==1)
if (command.length > 1)
{
targetDim = parseInt(sender, command[0]);
return DDCommandResult.TOO_MANY_ARGUMENTS;
}
if (command.length == 0)
{
targetDimension = sender.worldObj.provider.dimensionId;
}
else
{
targetDim=0;
shouldGo=false;
sendChat(sender,("Error-Invalid argument, delete_all_links <targetDimID>"));
try
{
targetDimension = Integer.parseInt(command[0]);
}
catch (NumberFormatException e)
{
return DDCommandResult.INVALID_DIMENSION_ID;
}
}
if(shouldGo)
World world = PocketManager.loadDimension(targetDimension);
if (world == null)
{
NewDimData dim = PocketManager.getDimensionData(targetDim);
ArrayList<DimLink> linksInDim = dim.getAllLinks();
for (DimLink link : linksInDim)
{
World targetWorld = PocketManager.loadDimension(targetDim);
if(!mod_pocketDim.blockRift.isBlockImmune(sender.worldObj,link.source().getX(), link.source().getY(), link.source().getZ())||
(targetWorld.getBlockId(link.source().getX(), link.source().getY(), link.source().getZ())==mod_pocketDim.blockRift.blockID))
{
linksRemoved++;
targetWorld.setBlock(link.source().getX(), link.source().getY(), link.source().getZ(), 0);
dim.deleteLink(link);
}
//TODO Probably should check what the block is, but thats annoying so Ill do it later.
}
sendChat(sender,("Removed " + linksRemoved + " links."));
return DDCommandResult.UNREGISTERED_DIMENSION;
}
return DDCommandResult.SUCCESS; //TEMPORARY HACK
int x;
int y;
int z;
Point4D location;
NewDimData dimension = PocketManager.createDimensionData(world);
ArrayList<DimLink> links = dimension.getAllLinks();
for (DimLink link : links)
{
location = link.source();
x = location.getX();
y = location.getY();
z = location.getZ();
if (world.getBlockId(x, y, z) == mod_pocketDim.blockRift.blockID)
{
// Remove the rift and its link
world.setBlockToAir(x, y, z);
dimension.deleteLink(link);
linksRemoved++;
}
else if (!mod_pocketDim.blockRift.isBlockImmune(world, x, y, z))
{
// If a block is not immune, then it must not be a DD block.
// The link would regenerate into a rift eventually.
// We only need to remove the link.
dimension.deleteLink(link);
linksRemoved++;
}
}
sendChat(sender, "Removed " + linksRemoved + " links.");
return DDCommandResult.SUCCESS;
}
}

View File

@@ -2,7 +2,6 @@ package StevenDimDoors.mod_pocketDim.commands;
import java.io.File;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
@@ -60,66 +59,51 @@ public class CommandExportDungeon extends DDCommandBase
//Export the schematic
return exportDungeon(sender, command[0]);
}
else
{
//The schematic name contains illegal characters. Inform the user.
return new DDCommandResult("Error: Invalid schematic name. Please use only letters, numbers, dashes, and underscores.");
}
}
else
{
//The command is malformed in some way. Assume that the user meant to use
//the 3-argument version and report an error.
return DDCommandResult.TOO_FEW_ARGUMENTS;
//The schematic name contains illegal characters. Inform the user.
return new DDCommandResult("Error: Invalid schematic name. Please use only letters, numbers, dashes, and underscores.");
}
//The command is malformed in some way. Assume that the user meant to use
//the 3-argument version and report an error.
return DDCommandResult.TOO_FEW_ARGUMENTS;
}
//The user must have used the 3-argument version of this command
//TODO: Why do we check remoteness here but not before? And why not for the other export case?
//Something feels wrong... ~SenseiKiwi
if (!sender.worldObj.isRemote)
//TODO: This validation should be in DungeonHelper or in another class. We should move it
//during the save file format rewrite. ~SenseiKiwi
if (!dungeonHelper.validateDungeonType(command[0], dungeonHelper.getDungeonPack("ruins")))
{
//TODO: This validation should be in DungeonHelper or in another class. We should move it
//during the save file format rewrite. ~SenseiKiwi
if (!dungeonHelper.validateDungeonType(command[0], dungeonHelper.getDungeonPack("ruins")))
{
return new DDCommandResult("Error: Invalid dungeon type. Please use one of the existing types.");
}
if (!DungeonHelper.DUNGEON_NAME_PATTERN.matcher(command[1]).matches())
{
return new DDCommandResult("Error: Invalid dungeon name. Please use only letters, numbers, and dashes.");
}
if (!command[2].equalsIgnoreCase("open") && !command[2].equalsIgnoreCase("closed"))
{
return new DDCommandResult("Error: Please specify whether the dungeon is 'open' or 'closed'.");
}
//If there are no more arguments, export the dungeon.
if (command.length == 3)
{
return exportDungeon(sender, join(command, "_", 0, 3));
}
else
{
//Validate the weight argument
try
{
int weight = Integer.parseInt(command[3]);
if (weight >= DungeonHelper.MIN_DUNGEON_WEIGHT && weight <= DungeonHelper.MAX_DUNGEON_WEIGHT)
{
return exportDungeon(sender, join(command, "_", 0, 4));
}
}
catch (Exception e) { }
}
//If we've reached this point, then we must have an invalid weight.
return new DDCommandResult("Invalid dungeon weight. Please specify a weight between "
+ DungeonHelper.MIN_DUNGEON_WEIGHT + " and " + DungeonHelper.MAX_DUNGEON_WEIGHT + ", inclusive.");
return new DDCommandResult("Error: Invalid dungeon type. Please use one of the existing types.");
}
if (!DungeonHelper.DUNGEON_NAME_PATTERN.matcher(command[1]).matches())
{
return new DDCommandResult("Error: Invalid dungeon name. Please use only letters, numbers, and dashes.");
}
if (!command[2].equalsIgnoreCase("open") && !command[2].equalsIgnoreCase("closed"))
{
return new DDCommandResult("Error: Please specify whether the dungeon is 'open' or 'closed'.");
}
return DDCommandResult.SUCCESS;
//If there are no more arguments, export the dungeon.
if (command.length == 3)
{
return exportDungeon(sender, join(command, "_", 0, 3));
}
//Validate the weight argument
try
{
int weight = Integer.parseInt(command[3]);
if (weight >= DungeonHelper.MIN_DUNGEON_WEIGHT && weight <= DungeonHelper.MAX_DUNGEON_WEIGHT)
{
return exportDungeon(sender, join(command, "_", 0, 4));
}
}
catch (Exception e) { }
//If we've reached this point, then we must have an invalid weight.
return new DDCommandResult("Invalid dungeon weight. Please specify a weight between "
+ DungeonHelper.MIN_DUNGEON_WEIGHT + " and " + DungeonHelper.MAX_DUNGEON_WEIGHT + ", inclusive.");
}
private static DDCommandResult exportDungeon(EntityPlayer player, String name)
@@ -137,10 +121,7 @@ public class CommandExportDungeon extends DDCommandBase
dungeonHelper.registerDungeon(exportPath, dungeonHelper.getDungeonPack("ruins"), false, true);
return DDCommandResult.SUCCESS;
}
else
{
return new DDCommandResult("Error: Failed to save dungeon schematic!");
}
return new DDCommandResult("Error: Failed to save dungeon schematic!");
}
private static String join(String[] source, String delimiter, int start, int end)

View File

@@ -31,10 +31,6 @@ public class CommandListDungeons extends DDCommandBase
int pageCount;
ArrayList<String> dungeonNames;
if (sender.worldObj.isRemote)
{
return DDCommandResult.SUCCESS;
}
if (command.length > 1)
{
return DDCommandResult.TOO_MANY_ARGUMENTS;

View File

@@ -1,16 +1,14 @@
package StevenDimDoors.mod_pocketDim.commands;
import java.util.ArrayList;
import net.minecraft.command.ICommandSender;
import java.util.HashSet;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
@SuppressWarnings("deprecation")
public class CommandResetDungeons extends DDCommandBase
{
private static CommandResetDungeons instance = null;
@@ -31,61 +29,78 @@ public class CommandResetDungeons extends DDCommandBase
@Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{
if(sender.worldObj.isRemote)
{
return DDCommandResult.SUCCESS;
}
if (command.length > 0)
{
return DDCommandResult.TOO_FEW_ARGUMENTS;
return DDCommandResult.TOO_MANY_ARGUMENTS;
}
int id;
int resetCount = 0;
int dungeonCount = 0;
HashSet<Integer> deletedDimensions = new HashSet<Integer>();
ArrayList<NewDimData> loadedDungeons = new ArrayList<NewDimData>();
// Copy the list of dimensions to iterate over the copy. Otherwise,
// we would trigger an exception by modifying the original list.
ArrayList<NewDimData> dimensions = new ArrayList<NewDimData>();
for (NewDimData dimension : PocketManager.getDimensions())
{
dimensions.add(dimension);
}
int dungeonCount = 0;
int resetCount = 0;
ArrayList<Integer> dimsToDelete = new ArrayList<Integer>();
ArrayList<Integer> dimsToFix = new ArrayList<Integer>();
for (NewDimData data : PocketManager.getDimensions())
// Iterate over the list of dimensions. Check which ones are dungeons.
// If a dungeon is found, try to delete it. If it can't be deleted,
// then it must be loaded and needs to be updated to prevent bugs.
for (NewDimData dimension : dimensions)
{
if(DimensionManager.getWorld(data.id())==null&&data.isDungeon())
if (dimension.type() == DimensionType.DUNGEON)
{
resetCount++;
dungeonCount++;
dimsToDelete.add(data.id());
}
else if(data.isDungeon())
{
dimsToFix.add(data.id());
dungeonCount++;
for(DimLink link : data.links())
id = dimension.id();
if (PocketManager.deletePocket(dimension, true))
{
if(link.linkType()==LinkTypes.REVERSE)
resetCount++;
deletedDimensions.add(id);
}
else
{
loadedDungeons.add(dimension);
}
}
}
// Modify the loaded dungeons to prevent bugs
for (NewDimData dungeon : loadedDungeons)
{
// Find top-most loaded dungeons and update their parents.
// They will automatically update their children.
// Dungeons with non-dungeon parents don't need to be fixed.
if (dungeon.parent() == null)
{
dungeon.setParentToRoot();
}
// Links to any deleted dungeons must be replaced
for (DimLink link : dungeon.links())
{
if (link.hasDestination() && deletedDimensions.contains(link.destination().getDimension()))
{
if (link.linkType() == LinkType.DUNGEON)
{
data.createLink(link.source(), LinkTypes.DUNGEON_EXIT, link.orientation());
dungeon.createLink(link.source(), LinkType.DUNGEON, link.orientation(), null);
}
if(link.linkType()==LinkTypes.DUNGEON)
else if (link.linkType() == LinkType.REVERSE)
{
data.createLink(link.source(), LinkTypes.DUNGEON, link.orientation());
dungeon.createLink(link.source(), LinkType.DUNGEON_EXIT, link.orientation(), null);
}
}
}
}
for(Integer dimID:dimsToDelete)
{
PocketManager.deletePocket(PocketManager.getDimensionData(dimID), true);
}
/**
* temporary workaround
*/
for(Integer dimID: dimsToFix)
{
PocketManager.getDimensionData(dimID).setParentToRoot();
}
//TODO- for some reason the parent field of loaded dimenions get reset to null if I call .setParentToRoot() before I delete the pockets.
//TODO implement blackList
//Notify the user of the results
// Notify the user of the results
sendChat(sender,("Reset complete. " + resetCount + " out of " + dungeonCount + " dungeons were reset."));
return DDCommandResult.SUCCESS;
}

View File

@@ -1,23 +1,23 @@
package StevenDimDoors.mod_pocketDim.commands;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import java.util.Arrays;
import java.util.List;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.common.DimensionManager;
public class CommandTeleportPlayer extends DDCommandBase
{
private static CommandTeleportPlayer instance = null;
private CommandTeleportPlayer()
{
super("dd-tp", new String[] {"<Player Name> <Dimension ID> <X Coord> <Y Coord> <Z Coord>","<Player Name> <Dimension ID>"} );
super("dd-tp", new String[] {
"<player name> <dimension number>",
"<player name> <x> <y> <z>",
"<player name> <dimension number> <x> <y> <z>"} );
}
public static CommandTeleportPlayer instance()
@@ -28,110 +28,119 @@ public class CommandTeleportPlayer extends DDCommandBase
return instance;
}
/**
* TODO- Change to accept variety of input, like just coords, just dim ID, or two player names.
*/
@Override
protected DDCommandResult processCommand(EntityPlayer sender, String[] command)
{
EntityPlayer targetPlayer = sender;
int dimDestinationID = sender.worldObj.provider.dimensionId;
int x;
int y;
int z;
World world;
int dimensionID;
Point4D destination;
NewDimData dimension;
boolean checkOrientation;
EntityPlayer targetPlayer;
if(command.length == 5)
if (command.length < 2)
{
for(int i= 1; i <5;i++)
{
if(!isInteger(command[i]))
{
return DDCommandResult.INVALID_ARGUMENTS;
}
}
if(sender.worldObj.getPlayerEntityByName(command[0])!=null) //Gets the targeted player
{
targetPlayer = sender.worldObj.getPlayerEntityByName(command[0]);
}
else
{
return DDCommandResult.INVALID_ARGUMENTS;
}
dimDestinationID=Integer.parseInt(command[1]);//gets the target dim ID from the command string
if(!DimensionManager.isDimensionRegistered(dimDestinationID))
{
return DDCommandResult.INVALID_DIMENSION_ID;
}
PocketManager.loadDimension(dimDestinationID);
Point4D destination = new Point4D(Integer.parseInt(command[2]),Integer.parseInt(command[3]),Integer.parseInt(command[4]),dimDestinationID);
DDTeleporter.teleportEntity(targetPlayer, destination, false);
return DDCommandResult.TOO_FEW_ARGUMENTS;
}
else if(command.length == 2 && isInteger(command[1]))
if (command.length > 5)
{
if(sender.worldObj.getPlayerEntityByName(command[0])!=null) //Gets the targeted player
{
targetPlayer = sender.worldObj.getPlayerEntityByName(command[0]);
}
else
{
return DDCommandResult.INVALID_ARGUMENTS;
}
dimDestinationID=Integer.parseInt(command[1]);//gets the target dim ID from the command string
if(!DimensionManager.isDimensionRegistered(dimDestinationID))
{
return DDCommandResult.INVALID_DIMENSION_ID;
}
Point4D destination = PocketManager.getDimensionData(dimDestinationID).origin();
if(!PocketManager.getDimensionData(dimDestinationID).isPocketDimension())
{
destination = new Point4D(destination.getX(),PocketManager.loadDimension(dimDestinationID).getTopSolidOrLiquidBlock(
destination.getX(), destination.getZ()),
destination.getZ(),destination.getDimension());
}
DDTeleporter.teleportEntity(targetPlayer, destination, false);
return DDCommandResult.TOO_MANY_ARGUMENTS;
}
else if(command.length == 1 && isInteger(command[0]))
{
targetPlayer = sender;
dimDestinationID=Integer.parseInt(command[0]);//gets the target dim ID from the command string
if(!DimensionManager.isDimensionRegistered(dimDestinationID))
{
return DDCommandResult.INVALID_DIMENSION_ID;
}
Point4D destination = PocketManager.getDimensionData(dimDestinationID).origin();
if(!PocketManager.getDimensionData(dimDestinationID).isPocketDimension())
{
destination = new Point4D(destination.getX(),PocketManager.loadDimension(dimDestinationID).getTopSolidOrLiquidBlock(
destination.getX(), destination.getZ()),
destination.getZ(),destination.getDimension());
}
DDTeleporter.teleportEntity(targetPlayer, destination, false);
}
else
if (command.length == 3)
{
return DDCommandResult.INVALID_ARGUMENTS;
}
// Check that all arguments after the username are integers
for (int k = 1; k < command.length; k++)
{
if (!isInteger(command[k]))
{
return DDCommandResult.INVALID_ARGUMENTS;
}
}
// Check if the target player is logged in
targetPlayer = MinecraftServer.getServer().getConfigurationManager().getPlayerForUsername(command[0]);
if (targetPlayer == null)
{
return DDCommandResult.PLAYER_OFFLINE;
}
// If a dimension ID was provided, try to load it
if (command.length != 4)
{
dimensionID = Integer.parseInt(command[1]);
world = PocketManager.loadDimension(dimensionID);
if (world == null)
{
return DDCommandResult.UNREGISTERED_DIMENSION;
}
}
else
{
dimensionID = targetPlayer.worldObj.provider.dimensionId;
world = targetPlayer.worldObj;
}
// If we teleport to a pocket dimension, set checkOrientation to true
// so the player is placed correctly relative to the entrance door.
checkOrientation = false;
// Parse or calculate the destination as necessary
// The Y coordinate must be increased by 1 because of the way that
// DDTeleporter considers destination points. It assumes that the
// point provided is the upper block of a door.
if (command.length == 2)
{
// Check if the destination is a pocket dimension
dimension = PocketManager.createDimensionData(world);
if (dimension.isPocketDimension())
{
// The destination is a pocket dimension.
// Teleport the player to its original entrance (the origin).
destination = dimension.origin();
checkOrientation = true;
}
else
{
// The destination is not a pocket dimension, which means we
// don't automatically know a safe location where we can send
// the player. Send the player to (0, Y, 0), where Y is chosen
// by searching. Add 2 to place the player ABOVE the top block.
y = world.getTopSolidOrLiquidBlock(0, 0) + 2;
destination = new Point4D(0, y, 0, dimensionID);
}
}
else if (command.length == 4)
{
x = Integer.parseInt(command[1]);
y = Integer.parseInt(command[2]) + 1; // Correct the Y value
z = Integer.parseInt(command[3]);
destination = new Point4D(x, y, z, dimensionID);
}
else
{
x = Integer.parseInt(command[2]);
y = Integer.parseInt(command[3]) + 1; // Correct the Y value
z = Integer.parseInt(command[4]);
destination = new Point4D(x, y, z, dimensionID);
}
// Teleport!
DDTeleporter.teleportEntity(targetPlayer, destination, checkOrientation);
return DDCommandResult.SUCCESS;
}
public boolean isInteger( String input )
{
try
{
Integer.parseInt( input );
return true;
}
catch(Exception e )
{
return false;
}
}
private static boolean isInteger(String input)
{
try
{
Integer.parseInt(input);
return true;
}
catch(Exception e)
{
return false;
}
}
}

View File

@@ -5,7 +5,6 @@ import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ChatMessageComponent;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
/*
* An abstract base class for our Dimensional Doors commands. This cleans up the code a little and provides
@@ -96,13 +95,15 @@ public abstract class DDCommandBase extends CommandBase
* that Dryware and Technic Jenkins don't have those functions defined. How in the world?
* I have no idea. But it's breaking our builds. -_- ~SenseiKiwi
*/
public int compareTo(ICommand par1ICommand)
@Override
public int compareTo(ICommand command)
{
return this.getCommandName().compareTo(par1ICommand.getCommandName());
return this.getCommandName().compareTo(command.getCommandName());
}
public int compareTo(Object par1Obj)
@Override
public int compareTo(Object other)
{
return this.compareTo((ICommand)par1Obj);
return this.compareTo((ICommand) other);
}
}

View File

@@ -8,7 +8,8 @@ public class DDCommandResult {
public static final DDCommandResult TOO_MANY_ARGUMENTS = new DDCommandResult(2, "Error: Too many arguments passed to the command", true);
public static final DDCommandResult INVALID_DIMENSION_ID = new DDCommandResult(3, "Error: Invalid dimension ID", true);
public static final DDCommandResult UNREGISTERED_DIMENSION = new DDCommandResult(4, "Error: Dimension is not registered", false);
public static final DDCommandResult INVALID_ARGUMENTS = new DDCommandResult(5, "Error: Invalid arguments passed to the command.", true);
public static final DDCommandResult INVALID_ARGUMENTS = new DDCommandResult(5, "Error: Invalid arguments passed to the command", true);
public static final DDCommandResult PLAYER_OFFLINE = new DDCommandResult(6, "Error: Player is not online", false);
public static final int CUSTOM_ERROR_CODE = -1;

View File

@@ -23,6 +23,9 @@ public class DDProperties
public final int TransientDoorID;
public final int FabricBlockID;
public final int RiftBlockID;
public final int QuartzDoorID;
public final int PersonalDimDoorID;
/**
* World Generation Block IDs
@@ -46,7 +49,9 @@ public class DDProperties
public final int UnstableDoorItemID;
public final int WarpDoorItemID;
public final int WorldThreadItemID;
public final int DDKeyItemID;
public final int ItemQuartzDoorID;
public final int ItemPersonalDimDoorID;
/**
* Other IDs
@@ -57,6 +62,7 @@ public class DDProperties
public final int LimboDimensionID;
public final int LimboProviderID;
public final int PocketProviderID;
public final int PersonalPocketProviderID;
public final int DoorRenderEntityID;
public final int MonolithEntityID;
@@ -75,6 +81,9 @@ public class DDProperties
public final boolean CraftingStableFabricAllowed;
public final boolean CraftingGoldenDimensionalDoorAllowed;
public final boolean CraftingGoldenDoorAllowed;
public final boolean CraftingDDKeysAllowed;
public final boolean CraftingQuartzDoorAllowed;
public final boolean CraftingPersonalDimDoorAllowed;
/**
* Loot Flags
@@ -147,7 +156,10 @@ public class DDProperties
CraftingStableFabricAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Stable Fabric", true).getBoolean(true);
CraftingGoldenDoorAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Golden Door", true).getBoolean(true);
CraftingGoldenDimensionalDoorAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Golden Dimensional Door", true).getBoolean(true);
CraftingDDKeysAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Rift Keys", true).getBoolean(true);
CraftingQuartzDoorAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Quartz Doors", true).getBoolean(true);
CraftingPersonalDimDoorAllowed = config.get(CATEGORY_CRAFTING, "Allow Crafting Personal Dim Doors", true).getBoolean(true);
WorldThreadRequirementLevel = config.get(CATEGORY_CRAFTING, "World Thread Requirement Level", 4,
"Controls the amount of World Thread needed to craft Stable Fabric. The number must be an " +
"integer from 1 to 4. The levels change the recipe to use 1, 2, 4, or 8 threads, respectively. The default level is 4.").getInt();
@@ -192,6 +204,8 @@ public class DDProperties
TransientDoorID = config.getBlock("Transient Door Block ID", 1979).getInt();
GoldenDoorID = config.getBlock("Gold Door Block ID", 1980).getInt();
GoldenDimensionalDoorID = config.getBlock("Gold Dim Door Block ID", 1981).getInt();
QuartzDoorID = config.getBlock("Quartz Door Block ID", 1982).getInt();
PersonalDimDoorID = config.getBlock("Personal Dim Door ID", 1983).getInt();
WarpDoorItemID = config.getItem("Warp Door Item ID", 5670).getInt();
RiftRemoverItemID = config.getItem("Rift Remover Item ID", 5671).getInt();
@@ -204,6 +218,9 @@ public class DDProperties
GoldenDoorItemID = config.getItem("Gold Door Item ID", 5678).getInt();
GoldenDimensionalDoorItemID = config.getItem("Gold Dim Door Item ID", 5679).getInt();
WorldThreadItemID = config.getItem("World Thread Item ID", 5680).getInt();
DDKeyItemID = config.getItem("Rift Key Item ID", 5681).getInt();
ItemQuartzDoorID = config.getItem("Quartz Door Item ID", 5681).getInt();
ItemPersonalDimDoorID = config.getItem("Personal Dim Door ID", 5681).getInt();
LimboBlockID = config.getTerrainBlock("World Generation Block IDs - must be less than 256", "Limbo Block ID", 217,
"Blocks used for the terrain in Limbo").getInt();
@@ -213,6 +230,7 @@ public class DDProperties
LimboDimensionID = config.get(CATEGORY_DIMENSION, "Limbo Dimension ID", -23).getInt();
PocketProviderID = config.get(CATEGORY_PROVIDER, "Pocket Provider ID", 124).getInt();
LimboProviderID = config.get(CATEGORY_PROVIDER, "Limbo Provider ID", 113).getInt();
PersonalPocketProviderID = config.get(CATEGORY_PROVIDER, "Personal Pocket Provider ID", 125).getInt();
MonolithTeleportationEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Monolith Teleportation", true,
"Sets whether Monoliths can teleport players").getBoolean(true);

View File

@@ -9,7 +9,6 @@ public class DDWorldProperties
/**
* World Generation Settings
*/
public final DimensionFilter RiftClusterDimensions;
public final DimensionFilter RiftGatewayDimensions;
@@ -17,7 +16,7 @@ public class DDWorldProperties
* General Flags
*/
public final boolean LimboEscapeEnabled;
public final boolean UniversalLimboEnabled;
//Names of categories
private static final String CATEGORY_WORLD_GENERATION = "world generation";
@@ -44,6 +43,12 @@ public class DDWorldProperties
"generates near the bottom of the dimension. If disabled, players could still leave through " +
"dungeons in Limbo or by dying (if Hardcore Limbo is disabled). The default value is true.").getBoolean(true);
UniversalLimboEnabled = config.get(Configuration.CATEGORY_GENERAL, "Enable Universal Limbo", false,
"Sets whether players are teleported to Limbo when they die in any dimension (except Limbo). " +
"Normally, players only go to Limbo if they die in a pocket dimension. This setting will not " +
"affect deaths in Limbo, which can be set with the Hardcore Limbo option. " +
"The default value is false.").getBoolean(false);
config.save();
}

View File

@@ -0,0 +1,169 @@
package StevenDimDoors.mod_pocketDim.core;
import java.io.IOException;
import com.google.gson.stream.JsonReader;
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.saving.IPackable;
import StevenDimDoors.mod_pocketDim.saving.PackedDimData;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagIntArray;
import net.minecraft.nbt.NBTTagList;
public class DDLock
{
private boolean lockState;
private final int lockKey;
public DDLock(boolean isLocked, int lockKey)
{
this.lockState = isLocked;
this.lockKey = lockKey;
}
public int getLockKey()
{
return this.lockKey;
}
/**
* See if the lock is currently locked. False if there is no lock.
* @return
*/
public boolean getLockState()
{
return this.lockState;
}
/**
* set the state of the lock. Returns false if there is no lock to set,
* otherwise returns true
* @param flag
*/
protected void setLockState(boolean flag)
{
this.lockState = flag;
}
/**
* see if we could unlock this door if it where locked.
* @param link
* @param itemStack
* @return
*/
public boolean doesKeyUnlock(ItemStack itemStack)
{
for(int key :getKeys(itemStack))
{
if(this.lockKey == key)
{
return true;
}
}
return false;
}
/**
* Tries to open this lock
* @param item
* @return
*/
public boolean tryToOpen(ItemStack itemStack)
{
return (!this.lockState)||this.doesKeyUnlock(itemStack);
}
/**
* sets the key/s to the given key/s
* @return
* @return
*/
/**
* gets all the keys stored on a single key item
* @return
*/
public static int[] getKeys(ItemStack itemStack)
{
if (!itemStack.hasTagCompound())
{
initNBTTags(itemStack);
}
return itemStack.getTagCompound().getIntArray("DDKeys");
}
/**
* adds the key/s to the given key
* @return
* @return
*/
public static void addKeys(ItemStack itemStack, int[] keysToAdd)
{
int[] oldKeys = DDLock.getKeys(itemStack);
int[] newKeys = new int[keysToAdd.length+oldKeys.length];
System.arraycopy(oldKeys, 0, newKeys, 0, oldKeys.length);
System.arraycopy(keysToAdd, 0, newKeys, oldKeys.length, keysToAdd.length);
setKeys(itemStack,newKeys);
}
/**
* sets the key/s to the given key/s
* @return
* @return
*/
public static void setKeys(ItemStack itemStack, int[] keys)
{
if (!itemStack.hasTagCompound())
{
initNBTTags(itemStack);
}
NBTTagCompound tag = itemStack.getTagCompound();
tag.setIntArray("DDKeys", keys);
itemStack.setTagCompound(tag);
}
/**
* Gives the key a new NBTTag
* @param itemStack
*/
public static void initNBTTags(ItemStack itemStack)
{
itemStack.setTagCompound(new NBTTagCompound());
NBTTagCompound tag = itemStack.getTagCompound();
tag.setIntArray("DDKeys", new int[0]);
tag.setBoolean("HasCreatedLock", false);
itemStack.setTagCompound(tag);
}
public static boolean hasCreatedLock(ItemStack key)
{
if(isItemKey(key))
{
if(key.hasTagCompound())
{
return key.getTagCompound().getBoolean("HasCreatedLock");
}
initNBTTags(key);
}
return false;
}
public static boolean isItemKey(ItemStack key)
{
return key.getItem() instanceof ItemDDKey;
}
protected static DDLock generateLockKeyPair(ItemStack itemStack, int lockKey2)
{
itemStack.getTagCompound().setBoolean("HasCreatedLock", true);
DDLock.setKeys(itemStack, new int[]{lockKey2});
return new DDLock(true, lockKey2);
}
}

View File

@@ -2,7 +2,6 @@ package StevenDimDoors.mod_pocketDim.core;
import java.util.ArrayList;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
@@ -23,9 +22,9 @@ import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
import StevenDimDoors.mod_pocketDim.blocks.IDimDoor;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.helpers.yCoordHelper;
import StevenDimDoors.mod_pocketDim.items.ItemDimensionalDoor;
import StevenDimDoors.mod_pocketDim.schematic.BlockRotator;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
import StevenDimDoors.mod_pocketDim.util.Point4D;
@@ -52,59 +51,49 @@ public class DDTeleporter
private DDTeleporter() { }
/**Checks if the destination supplied is valid, ie, filled by any non-replaceable block.
*
* @param entity
* @param world
* @param destination
* @param properties
* @return
/**
* Checks if the destination supplied is safe (i.e. filled by any replaceable or non-opaque blocks)
*/
private static boolean checkDestination(Entity entity, WorldServer world, Point4D destination,DDProperties properties)
private static boolean checkDestination(WorldServer world, Point4D destination, int orientation)
{
int x = destination.getX();
int y = destination.getY();
int z = destination.getZ();
int blockIDTop;
int blockIDBottom;
int blockIDBottom;
Point3D point;
int orientation;
orientation = getDestinationOrientation(destination, properties);
entity.rotationYaw = (orientation * 90) + 90;
switch (orientation)
{
case 0:
point = new Point3D(MathHelper.floor_double(x - 0.5), y - 1, MathHelper.floor_double(z + 0.5));
point = new Point3D(x - 1, y - 1, z);
break;
case 1:
point = new Point3D(MathHelper.floor_double(x + 0.5), y - 1, MathHelper.floor_double(z - 0.5));
point = new Point3D(x, y - 1, z - 1);
break;
case 2:
point = new Point3D(MathHelper.floor_double(x + 1.5), y - 1, MathHelper.floor_double(z + 0.5));
point = new Point3D(x + 1, y - 1, z);
break;
case 3:
point = new Point3D(MathHelper.floor_double(x + 0.5), y - 1, MathHelper.floor_double(z + 1.5));
point = new Point3D(x, y - 1, z + 1);
break;
default:
point = new Point3D(x, y - 1, z);
break;
}
blockIDBottom = world.getBlockId(point.getX(), point.getY(), point.getZ());
blockIDTop = world.getBlockId(point.getX(), point.getY()+1, point.getZ());
blockIDTop = world.getBlockId(point.getX(), point.getY() + 1, point.getZ());
if (Block.blocksList[blockIDBottom] != null)
{
if(!Block.blocksList[blockIDBottom].isBlockReplaceable(world, point.getX(), point.getY(), point.getZ())&&world.isBlockOpaqueCube(point.getX(), point.getY(), point.getZ()))
if (!Block.blocksList[blockIDBottom].isBlockReplaceable(world, point.getX(), point.getY(), point.getZ()) && world.isBlockOpaqueCube(point.getX(), point.getY(), point.getZ()))
{
return false;
}
}
if (Block.blocksList[blockIDTop] != null)
{
if (!Block.blocksList[blockIDTop].isBlockReplaceable(world, point.getX(), point.getY()+1, point.getZ()))
if (!Block.blocksList[blockIDTop].isBlockReplaceable(world, point.getX(), point.getY() + 1, point.getZ()))
{
return false;
}
@@ -126,56 +115,37 @@ public class DDTeleporter
}
else
{
//Teleport the entity to the precise destination point
// Teleport the entity to the precise destination point
orientation = -1;
}
if (!checkDestination(entity, world, destination, properties))
{
if (entity instanceof EntityPlayerMP)
{
EntityPlayer player = (EntityPlayer) entity;
player.rotationYaw = (orientation * 90) + 90;
switch (orientation)
{
case 0:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
case 1:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
case 2:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
case 3:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
default:
player.setPositionAndUpdate(x, y - 1, z);
break;
}
}
}
else if (entity instanceof EntityPlayer)
if (entity instanceof EntityPlayer)
{
EntityPlayer player = (EntityPlayer) entity;
switch (orientation)
if (checkDestination(world, destination, orientation))
{
case 0:
player.setPositionAndUpdate(x - 0.5, y - 1, z + 0.5);
break;
case 1:
player.setPositionAndUpdate(x + 0.5, y - 1, z - 0.5);
break;
case 2:
player.setPositionAndUpdate(x + 1.5, y - 1, z + 0.5);
break;
case 3:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 1.5);
break;
default:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
switch (orientation)
{
case 0:
player.setPositionAndUpdate(x - 0.5, y - 1, z + 0.5);
break;
case 1:
player.setPositionAndUpdate(x + 0.5, y - 1, z - 0.5);
break;
case 2:
player.setPositionAndUpdate(x + 1.5, y - 1, z + 0.5);
break;
case 3:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 1.5);
break;
default:
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
break;
}
}
else
{
player.setPositionAndUpdate(x + 0.5, y - 1, z + 0.5);
}
}
else if (entity instanceof EntityMinecart)
@@ -201,7 +171,7 @@ public class DDTeleporter
entity.worldObj.updateEntityWithOptionalForce(entity, false);
break;
case 3:
DDTeleporter.setEntityPosition(entity, x + 0.5, y, z + 1.5 );
DDTeleporter.setEntityPosition(entity, x + 0.5, y, z + 1.5);
entity.motionZ = 0.39;
entity.worldObj.updateEntityWithOptionalForce(entity, false);
break;
@@ -251,15 +221,14 @@ public class DDTeleporter
}
//Check if the block below that point is actually a door
int blockID = world.getBlockId(door.getX(), door.getY() - 1, door.getZ());
if (blockID != properties.DimensionalDoorID && blockID != properties.WarpDoorID &&
blockID != properties.TransientDoorID && blockID != properties.UnstableDoorID
&& blockID != properties.GoldenDimensionalDoorID)
Block block = Block.blocksList[world.getBlockId(door.getX(), door.getY() - 1, door.getZ())];
if (block==null || !(block instanceof IDimDoor))
{
//Return the pocket's orientation instead
return PocketManager.getDimensionData(door.getDimension()).orientation();
return PocketManager.createDimensionData(world).orientation();
}
//Return the orientation portion of its metadata
return world.getBlockMetadata(door.getX(), door.getY() - 1, door.getZ()) & 3;
}
@@ -324,7 +293,7 @@ public class DDTeleporter
// to prevent us from doing bad things. Moreover, no dimension is being created, so if we ever
// tie code to that, it could cause confusing bugs.
// No hacky for you! ~SenseiKiwi
PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.getDimensionData(destination.getDimension())));
PocketManager.getDimwatcher().onCreated(new ClientDimData(PocketManager.createDimensionData(newWorld)));
// Set the new dimension and inform the client that it's moving to a new world.
player.dimension = destination.getDimension();
@@ -458,11 +427,11 @@ public class DDTeleporter
return;
}
if (!initializeDestination(link, DDProperties.instance(),door))
if (!initializeDestination(link, DDProperties.instance(),entity,door))
{
return;
}
if (link.linkType() == LinkTypes.RANDOM)
if (link.linkType() == LinkType.RANDOM)
{
Point4D randomDestination = getRandomDestination();
if (randomDestination != null)
@@ -471,21 +440,46 @@ public class DDTeleporter
entity.worldObj.playSoundEffect(entity.posX, entity.posY, entity.posZ, "mob.endermen.portal", 1.0F, 1.0F);
}
}
else
else
{
buildExitDoor(door, link, DDProperties.instance());
entity = teleportEntity(entity, link.destination(), link.linkType() != LinkTypes.UNSAFE_EXIT);
entity = teleportEntity(entity, link.destination(), link.linkType() != LinkType.UNSAFE_EXIT);
entity.worldObj.playSoundEffect(entity.posX, entity.posY, entity.posZ, "mob.endermen.portal", 1.0F, 1.0F);
}
}
private static boolean initializeDestination(DimLink link, DDProperties properties, Block door)
private static boolean initializeDestination(DimLink link, DDProperties properties, Entity entity, Block door)
{
if (link.hasDestination())
if (link.hasDestination()&&link.linkType()!=LinkType.PERSONAL)
{
if(PocketManager.isBlackListed(link.destination().getDimension()))
if (PocketManager.isBlackListed(link.destination().getDimension()))
{
link=PocketManager.getDimensionData(link.source().getDimension()).createLink(link.link.point,LinkTypes.SAFE_EXIT,link.link.orientation);
// This link leads to a dimension that has been blacklisted.
// That means that it was a pocket and it was deleted.
// Depending on the link type, we must overwrite it or cancel
// the teleport operation. We don't need to assign 'link' with
// a different value. NewDimData will overwrite it in-place.
NewDimData start = PocketManager.getDimensionData(link.source().getDimension());
if (link.linkType() == LinkType.DUNGEON)
{
// Ovewrite the link into a dungeon link with no destination
start.createLink(link.source(), LinkType.DUNGEON, link.orientation(), null);
}
else
{
if (start.isPocketDimension())
{
// Ovewrite the link into a safe exit link, because
// this could be the only way out from a pocket.
start.createLink(link.source(), LinkType.SAFE_EXIT, link.orientation(), null);
}
else
{
// Cancel the teleport attempt
return false;
}
}
}
else
{
@@ -496,24 +490,49 @@ public class DDTeleporter
// Check the destination type and respond accordingly
switch (link.linkType())
{
case LinkTypes.DUNGEON:
case DUNGEON:
return PocketBuilder.generateNewDungeonPocket(link, properties);
case LinkTypes.POCKET:
return PocketBuilder.generateNewPocket(link, properties,door);
case LinkTypes.SAFE_EXIT:
case POCKET:
return PocketBuilder.generateNewPocket(link, properties, door, DimensionType.POCKET);
case PERSONAL:
return setupPersonalLink(link, properties, entity, door);
case SAFE_EXIT:
return generateSafeExit(link, properties);
case LinkTypes.DUNGEON_EXIT:
case DUNGEON_EXIT:
return generateDungeonExit(link, properties);
case LinkTypes.UNSAFE_EXIT:
case UNSAFE_EXIT:
return generateUnsafeExit(link);
case LinkTypes.NORMAL:
case LinkTypes.REVERSE:
case LinkTypes.RANDOM:
case NORMAL:
case REVERSE:
case RANDOM:
return true;
default:
throw new IllegalArgumentException("link has an unrecognized link type.");
}
}
private static boolean setupPersonalLink(DimLink link, DDProperties properties,Entity player, Block door)
{
if(!(player instanceof EntityPlayer))
{
return false;
}
NewDimData dim = PocketManager.getPersonalDimensionForPlayer(player.getEntityName());
if(dim == null)
{
return PocketBuilder.generateNewPersonalPocket(link, properties, player, door);
}
DimLink personalHomeLink = dim.getLink(dim.origin());
if(personalHomeLink!=null)
{
PocketManager.getDimensionData(link.source().getDimension()).setLinkDestination(personalHomeLink, link.source().getX(), link.source().getY(), link.source().getZ());
}
dim.setLinkDestination(link, dim.origin.getX(), dim.origin.getY(), dim.origin.getZ());
return true;
}
private static Point4D getRandomDestination()
{
@@ -532,7 +551,7 @@ public class DDTeleporter
{
for (DimLink link : dimension.getAllLinks())
{
if (link.linkType() != LinkTypes.RANDOM)
if (link.linkType() != LinkType.RANDOM)
{
matches.add(link.source());
}
@@ -544,10 +563,7 @@ public class DDTeleporter
{
return matches.get( random.nextInt(matches.size()) );
}
else
{
return null;
}
return null;
}
private static boolean generateUnsafeExit(DimLink link)
@@ -561,7 +577,8 @@ public class DDTeleporter
// To avoid loops, don't generate a destination if the player is
// already in a non-pocket dimension.
NewDimData current = PocketManager.getDimensionData(link.link.point.getDimension());
NewDimData current = PocketManager.getDimensionData(link.point.getDimension());
if (current.isPocketDimension())
{
Point4D source = link.source();
@@ -574,7 +591,7 @@ public class DDTeleporter
Point3D destination = yCoordHelper.findDropPoint(world, source.getX(), source.getY() + 1, source.getZ());
if (destination != null)
{
current.root().setDestination(link, destination.getX(), destination.getY(), destination.getZ());
current.root().setLinkDestination(link, destination.getX(), destination.getY(), destination.getZ());
return true;
}
}
@@ -585,7 +602,7 @@ public class DDTeleporter
{
World startWorld = PocketManager.loadDimension(link.source().getDimension());
World destWorld = PocketManager.loadDimension(link.destination().getDimension());
TileEntity doorTE = startWorld.getBlockTileEntity(link.source().getX(), link.source().getY(), link.link.point.getZ());
TileEntity doorTE = startWorld.getBlockTileEntity(link.source().getX(), link.source().getY(), link.point.getZ());
if(doorTE instanceof TileEntityDimDoor)
{
if((TileEntityDimDoor.class.cast(doorTE).hasGennedPair))
@@ -615,9 +632,10 @@ public class DDTeleporter
}
}
}
private static boolean generateSafeExit(DimLink link, DDProperties properties)
{
NewDimData current = PocketManager.getDimensionData(link.link.point.getDimension());
NewDimData current = PocketManager.getDimensionData(link.point.getDimension());
return generateSafeExit(current.root(), link, properties);
}
@@ -628,7 +646,8 @@ public class DDTeleporter
// There is a chance of choosing the Nether first before other root dimensions
// to compensate for servers with many Mystcraft ages or other worlds.
NewDimData current = PocketManager.getDimensionData(link.link.point.getDimension());
NewDimData current = PocketManager.getDimensionData(link.point.getDimension());
ArrayList<NewDimData> roots = PocketManager.getRootDimensions();
int shiftChance = START_ROOT_SHIFT_CHANCE + ROOT_SHIFT_CHANCE_PER_LEVEL * (current.packDepth() - 1);
@@ -636,11 +655,11 @@ public class DDTeleporter
{
if (current.root().id() != OVERWORLD_DIMENSION_ID && random.nextInt(MAX_OVERWORLD_EXIT_CHANCE) < OVERWORLD_EXIT_CHANCE)
{
return generateSafeExit(PocketManager.getDimensionData(OVERWORLD_DIMENSION_ID), link, properties);
return generateSafeExit(PocketManager.createDimensionDataDangerously(OVERWORLD_DIMENSION_ID), link, properties);
}
if (current.root().id() != NETHER_DIMENSION_ID && random.nextInt(MAX_NETHER_EXIT_CHANCE) < NETHER_EXIT_CHANCE)
{
return generateSafeExit(PocketManager.getDimensionData(NETHER_DIMENSION_ID), link, properties);
return generateSafeExit(PocketManager.createDimensionDataDangerously(NETHER_DIMENSION_ID), link, properties);
}
for (int attempts = 0; attempts < 10; attempts++)
{
@@ -744,16 +763,17 @@ public class DDTeleporter
// Create a reverse link for returning
int orientation = getDestinationOrientation(source, properties);
NewDimData sourceDim = PocketManager.getDimensionData(link.source().getDimension());
DimLink reverse = destinationDim.createLink(x, y + 2, z, LinkTypes.REVERSE,orientation);
sourceDim.setDestination(reverse, source.getX(), source.getY(), source.getZ());
DimLink reverse = destinationDim.createLink(x, y + 2, z, LinkType.REVERSE,orientation);
sourceDim.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ());
// Set up the warp door at the destination
orientation = BlockRotator.transformMetadata(orientation, 2, properties.WarpDoorID);
ItemDimensionalDoor.placeDoorBlock(world, x, y + 1, z, orientation, mod_pocketDim.warpDoor);
ItemDoor.placeDoorBlock(world, x, y + 1, z, orientation, mod_pocketDim.warpDoor);
// Complete the link to the destination
// This comes last so the destination isn't set unless everything else works first
destinationDim.setDestination(link, x, y + 2, z);
destinationDim.setLinkDestination(link, x, y + 2, z);
}
return (destination != null);

View File

@@ -2,73 +2,99 @@ package StevenDimDoors.mod_pocketDim.core;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.item.ItemStack;
import net.minecraft.world.ChunkCoordIntPair;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
public abstract class DimLink
{
protected ClientLinkData link;
protected Point4D point;
protected int orientation;
protected DDLock lock;
protected DimLink parent;
protected LinkTail tail;
protected List<DimLink> children;
protected DimLink(ClientLinkData link, DimLink parent)
protected DimLink(Point4D point, int orientation, DDLock lock, DimLink parent)
{
if (parent.link.point.getDimension() != link.point.getDimension())
if (parent.point.getDimension() != point.getDimension())
{
// Ban having children in other dimensions to avoid serialization issues with cross-dimensional tails
throw new IllegalArgumentException("source and parent.source must have the same dimension.");
}
this.lock = lock;
this.parent = parent;
this.link = link;
this.point = point;
this.tail = parent.tail;
this.orientation = orientation;
this.children = new LinkedList<DimLink>();
parent.children.add(this);
}
protected DimLink(ClientLinkData link, int linkType)
protected DimLink(Point4D point, int orientation, DDLock lock, LinkType linkType)
{
/**This really cant happen anymore, I guess.
*
if ((linkType < LinkTypes.ENUM_MIN || linkType > LinkTypes.ENUM_MAX) && linkType != LinkTypes.CLIENT_SIDE)
{
throw new IllegalArgumentException("The specified link type is invalid.");
}
**/
this.lock = lock;
this.parent = null;
this.link = link;
this.point = point;
this.orientation = orientation;
this.tail = new LinkTail(linkType, null);
this.children = new LinkedList<DimLink>();
}
public Point4D source()
{
return link.point;
return point;
}
public void clear()
{
//Release children
for (DimLink child : children)
{
child.parent = null;
}
children.clear();
//Release parent
if (parent != null)
{
parent.children.remove(this);
}
parent = null;
point = null;
tail = new LinkTail(LinkType.NORMAL, null);
}
public int orientation()
{
return link.orientation;
}
public ClientLinkData link()
{
return link;
return orientation;
}
public Point4D destination()
{
return tail.getDestination();
}
public int getDestinationOrientation()
{
DimLink link = PocketManager.getLink(this.destination().getX(), this.destination().getY(), this.destination().getZ(), this.destination().getDimension());
if(link !=null)
DimLink destinationLink = PocketManager.getLink(tail.getDestination());
if (destinationLink != null)
{
return link.orientation();
return destinationLink.orientation();
}
return (this.orientation()+2)%4;
return (orientation + 2) % 4;
}
public boolean hasDestination()
{
return (tail.getDestination() != null);
@@ -89,13 +115,65 @@ public abstract class DimLink
return parent;
}
public int linkType()
public LinkType linkType()
{
return tail.getLinkType();
}
/**
* Tries to open this lock. Returns true if the lock is open or if the key can open it
* @return
*/
public boolean tryToOpen(ItemStack item)
{
return lock.tryToOpen(item);
}
/**
* Tests if the given key item fits this lock
* @return
*/
public boolean doesKeyUnlock(ItemStack item)
{
return lock.doesKeyUnlock(item);
}
/**
* test if there is a lock, regardless if it is locked or not.
* @return
*/
public boolean hasLock()
{
return this.lock!=null;
}
/**
* Tests if the lock is open or not
*
*/
public boolean getLockState()
{
return this.hasLock()&&this.lock.getLockState();
}
/**
* gets the actual lock object
* @return
*/
public DDLock getLock()
{
return this.lock;
}
public ChunkCoordIntPair getChunkCoordinates()
{
return new ChunkCoordIntPair(point.getX() >> 4, point.getZ() >> 4);
}
@Override
public String toString()
{
return link.point + " -> " + (hasDestination() ? destination() : "");
return point + " -> " + (hasDestination() ? destination() : "()");
}
}

View File

@@ -0,0 +1,41 @@
package StevenDimDoors.mod_pocketDim.core;
public enum DimensionType
{
// WARNING: Don't modify these values carelessly or you'll risk breaking existing worlds!
ROOT(0,false),
POCKET(1,true),
DUNGEON(2,true),
PERSONAL(3,true);
DimensionType(int index, boolean isPocket)
{
this.index = index;
this.isPocket = isPocket;
}
public final int index;
public final boolean isPocket;
/**
* Get the DimensionType given an index. I feel like there should be a better way to do this.
* @param index
* @return
*/
public static DimensionType getTypeFromIndex(int index)
{
for(DimensionType type : DimensionType.values())
{
if(type.index == index)
{
return type;
}
}
return null;
}
public boolean isPocketDimension()
{
return this.isPocket;
}
}

View File

@@ -2,5 +2,5 @@ package StevenDimDoors.mod_pocketDim.core;
public interface IDimRegistrationCallback
{
public NewDimData registerDimension(int dimensionID, int rootID);
public NewDimData registerDimension(int dimensionID, int rootID, DimensionType type);
}

View File

@@ -5,9 +5,9 @@ import StevenDimDoors.mod_pocketDim.util.Point4D;
class LinkTail
{
private Point4D destination;
private int linkType;
private LinkType linkType;
public LinkTail(int linkType, Point4D destination)
public LinkTail(LinkType linkType, Point4D destination)
{
this.linkType = linkType;
this.destination = destination;
@@ -21,12 +21,11 @@ class LinkTail
this.destination = destination;
}
public int getLinkType() {
public LinkType getLinkType() {
return linkType;
}
public void setLinkType(int linkType) {
public void setLinkType(LinkType linkType) {
this.linkType = linkType;
}
}

View File

@@ -0,0 +1,42 @@
package StevenDimDoors.mod_pocketDim.core;
import java.util.HashMap;
public enum LinkType
{
// WARNING: Don't modify these values carelessly or you'll risk breaking links in existing worlds!
NORMAL(0),
POCKET(1),
DUNGEON(2),
RANDOM(3),
DUNGEON_EXIT(4),
SAFE_EXIT(5),
UNSAFE_EXIT(6),
REVERSE(7),
PERSONAL(8),
CLIENT(-1337);
LinkType(int index)
{
this.index = index;
}
public final int index;
/**
* Get the LinkType given an index. I feel like there should be a better way to do this.
* @param index
* @return
*/
public static LinkType getLinkTypeFromIndex(int index)
{
for(LinkType type : LinkType.values())
{
if(type.index == index)
{
return type;
}
}
return null;
}
}

View File

@@ -1,21 +0,0 @@
package StevenDimDoors.mod_pocketDim.core;
public class LinkTypes
{
private LinkTypes() { }
public static final int ENUM_MIN = 0;
public static final int ENUM_MAX = 7;
public static final int CLIENT_SIDE = -1337;
// WARNING: Don't modify these values carelessly or you'll risk breaking links in existing worlds!
public static final int NORMAL = 0;
public static final int POCKET = 1;
public static final int DUNGEON = 2;
public static final int RANDOM = 3;
public static final int DUNGEON_EXIT = 4;
public static final int SAFE_EXIT = 5;
public static final int UNSAFE_EXIT = 6;
public static final int REVERSE = 7;
}

View File

@@ -1,32 +1,42 @@
package StevenDimDoors.mod_pocketDim.core;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Stack;
import java.util.TreeMap;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
import net.minecraft.item.ItemStack;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
import StevenDimDoors.mod_pocketDim.dungeon.pack.DungeonPack;
import StevenDimDoors.mod_pocketDim.saving.IPackable;
import StevenDimDoors.mod_pocketDim.saving.PackedDimData;
import StevenDimDoors.mod_pocketDim.saving.PackedDungeonData;
import StevenDimDoors.mod_pocketDim.saving.PackedLinkData;
import StevenDimDoors.mod_pocketDim.saving.PackedLinkTail;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher;
public abstract class NewDimData
public abstract class NewDimData implements IPackable<PackedDimData>
{
private static class InnerDimLink extends DimLink
{
public InnerDimLink(Point4D source, DimLink parent, int orientation)
public InnerDimLink(Point4D source, DimLink parent, int orientation, DDLock lock)
{
super(new ClientLinkData(source, orientation), parent);
super(source, orientation, lock, parent);
}
public InnerDimLink(Point4D source, int linkType, int orientation)
public InnerDimLink(Point4D source, LinkType linkType, int orientation, DDLock lock)
{
super(new ClientLinkData(source, orientation), linkType);
super(source, orientation, lock, linkType);
}
public void setDestination(int x, int y, int z, NewDimData dimension)
@@ -34,26 +44,6 @@ public abstract class NewDimData
tail.setDestination(new Point4D(x, y, z, dimension.id()));
}
public void clear()
{
//Release children
for (DimLink child : children)
{
((InnerDimLink) child).parent = null;
}
children.clear();
//Release parent
if (parent != null)
{
parent.children.remove(this);
}
parent = null;
link = null;
tail = new LinkTail(0, null);
}
public boolean overwrite(InnerDimLink nextParent,int orientation)
{
if (nextParent == null)
@@ -65,7 +55,7 @@ public abstract class NewDimData
//Ignore this request silently
return false;
}
if (nextParent.link.point.getDimension() != link.point.getDimension())
if (nextParent.point.getDimension() != point.getDimension())
{
// Ban having children in other dimensions to avoid serialization issues with cross-dimensional tails
throw new IllegalArgumentException("source and parent.source must have the same dimension.");
@@ -88,11 +78,11 @@ public abstract class NewDimData
parent = nextParent;
tail = nextParent.tail;
nextParent.children.add(this);
this.link.orientation=orientation;
this.orientation=orientation;
return true;
}
public void overwrite(int linkType, int orientation)
public void overwrite(LinkType linkType, int orientation)
{
//Release children
for (DimLink child : children)
@@ -111,19 +101,54 @@ public abstract class NewDimData
parent = null;
tail = new LinkTail(linkType, null);
//Set new orientation
this.link.orientation=orientation;
this.orientation=orientation;
}
/**
* only use this on the client to update errything
* @param lock
*/
public void setLock(DDLock lock)
{
this.lock = lock;
}
/**
* create a lock from a key. Returns false if this door already has a lock, or if they has already locked a door
* @param itemStack
* @return
*/
public boolean createLock(ItemStack itemStack, int lockKey)
{
if(this.hasLock()||DDLock.hasCreatedLock(itemStack))
{
return false;
}
this.lock = DDLock.generateLockKeyPair(itemStack, lockKey);
return true;
}
public void removeLock(ItemStack itemStack, InnerDimLink link)
{
if(link.doesKeyUnlock(itemStack))
{
link.lock = null;
}
}
}
private static int EXPECTED_LINKS_PER_CHUNK = 2;
protected static Random random = new Random();
protected int id;
protected Map<Point4D, InnerDimLink> linkMapping;
protected List<InnerDimLink> linkList;
protected boolean isDungeon;
protected boolean isFilled;
protected int depth;
protected int packDepth;
protected DimensionType type;
protected NewDimData parent;
protected NewDimData root;
protected List<NewDimData> children;
@@ -133,18 +158,16 @@ public abstract class NewDimData
protected boolean modified;
public IUpdateWatcher<ClientLinkData> linkWatcher;
protected NewDimData(int id, NewDimData parent, boolean isPocket, boolean isDungeon,
IUpdateWatcher<ClientLinkData> linkWatcher)
// Don't write this field to a file - it should be recreated on startup
private Map<ChunkCoordIntPair, List<InnerDimLink>> chunkMapping;
protected NewDimData(int id, NewDimData parent, DimensionType type, IUpdateWatcher<ClientLinkData> linkWatcher)
{
// The isPocket flag is redundant. It's meant as an integrity safeguard.
if (isPocket && (parent == null))
if (type != DimensionType.ROOT && (parent == null))
{
throw new NullPointerException("Dimensions can be pocket dimensions if and only if they have a parent dimension.");
}
if (isDungeon && !isPocket)
{
throw new IllegalArgumentException("A dimensional dungeon must also be a pocket dimension.");
}
this.id = id;
this.linkMapping = new TreeMap<Point4D, InnerDimLink>(); //Should be stored in oct tree -- temporary solution
@@ -152,12 +175,13 @@ public abstract class NewDimData
this.children = new ArrayList<NewDimData>();
this.parent = parent;
this.packDepth = 0;
this.isDungeon = isDungeon;
this.type = type;
this.isFilled = false;
this.orientation = 0;
this.origin = null;
this.dungeon = null;
this.linkWatcher = linkWatcher;
this.chunkMapping = new HashMap<ChunkCoordIntPair, List<InnerDimLink>>();
this.modified = true;
//Register with parent
@@ -176,7 +200,7 @@ public abstract class NewDimData
}
}
protected NewDimData(int id, NewDimData root)
protected NewDimData(int id, NewDimData root, DimensionType type)
{
// This constructor is meant for client-side code only
if (root == null)
@@ -190,7 +214,7 @@ public abstract class NewDimData
this.children = new ArrayList<NewDimData>();
this.parent = null;
this.packDepth = 0;
this.isDungeon = false;
this.type = type;
this.isFilled = false;
this.orientation = 0;
this.origin = null;
@@ -198,28 +222,26 @@ public abstract class NewDimData
this.linkWatcher = null;
this.depth = 0;
this.root = root;
this.chunkMapping = null;
}
public DimLink findNearestRift(World world, int range, int x, int y, int z)
{
//TODO: Rewrite this later to use an octtree
//Sanity check...
// Sanity check...
if (world.provider.dimensionId != id)
{
throw new IllegalArgumentException("Attempted to search for links in a World instance for a different dimension!");
}
//Note: Only detect rifts at a distance > 1, so we ignore the rift
//that called this function and any adjacent rifts.
DimLink nearest = null;
// Note: Only detect rifts at a distance > 0, so we ignore the rift
// at the center of the search space.
DimLink link;
DimLink nearest = null;
int i, j, k;
int distance;
int minDistance = Integer.MAX_VALUE;
int i, j, k;
DDProperties properties = DDProperties.instance();
for (i = -range; i <= range; i++)
@@ -231,7 +253,7 @@ public abstract class NewDimData
distance = getAbsoluteSum(i, j, k);
if (distance > 0 && distance < minDistance && world.getBlockId(x + i, y + j, z + k) == properties.RiftBlockID)
{
link = getLink(x+i, y+j, z+k);
link = getLink(x + i, y + j, z + k);
if (link != null)
{
nearest = link;
@@ -247,24 +269,20 @@ public abstract class NewDimData
public ArrayList<DimLink> findRiftsInRange(World world, int range, int x, int y, int z)
{
ArrayList<DimLink> links = new ArrayList<DimLink>();
//TODO: Rewrite this later to use an octtree
//Sanity check...
// Sanity check...
if (world.provider.dimensionId != id)
{
throw new IllegalArgumentException("Attempted to search for links in a World instance for a different dimension!");
}
//Note: Only detect rifts at a distance > 1, so we ignore the rift
//that called this function and any adjacent rifts.
DimLink link;
int distance;
int i, j, k;
DDProperties properties = DDProperties.instance();
// Note: Only detect rifts at a distance > 0, so we ignore the rift
// at the center of the search space.
int i, j, k;
int distance;
DimLink link;
DDProperties properties = DDProperties.instance();
ArrayList<DimLink> links = new ArrayList<DimLink>();
for (i = -range; i <= range; i++)
{
for (j = -range; j <= range; j++)
@@ -274,7 +292,7 @@ public abstract class NewDimData
distance = getAbsoluteSum(i, j, k);
if (distance > 0 && world.getBlockId(x + i, y + j, z + k) == properties.RiftBlockID)
{
link = getLink(x+i, y+j, z+k);
link = getLink(x + i, y + j, z + k);
if (link != null)
{
links.add(link);
@@ -292,20 +310,33 @@ public abstract class NewDimData
return Math.abs(i) + Math.abs(j) + Math.abs(k);
}
public DimLink createLink(int x, int y, int z, int linkType, int orientation)
public DimLink createLink(int x, int y, int z, LinkType linkType, int orientation)
{
return createLink(new Point4D(x, y, z, id), linkType, orientation);
return createLink(new Point4D(x, y, z, id), linkType, orientation, null);
}
public DimLink createLink(Point4D source, int linkType, int orientation)
public DimLink createLink(Point4D source, LinkType linkType, int orientation, DDLock locked)
{
//Return an existing link if there is one to avoid creating multiple links starting at the same point.
// Return an existing link if there is one to avoid creating multiple links starting at the same point.
InnerDimLink link = linkMapping.get(source);
if (link == null)
{
link = new InnerDimLink(source, linkType, orientation);
link = new InnerDimLink(source, linkType, orientation, locked);
linkMapping.put(source, link);
linkList.add(link);
// If this code is running on the server side, add this link to chunkMapping.
if (linkType != LinkType.CLIENT)
{
ChunkCoordIntPair chunk = link.getChunkCoordinates();
List<InnerDimLink> chunkLinks = chunkMapping.get(chunk);
if (chunkLinks == null)
{
chunkLinks = new ArrayList<InnerDimLink>(EXPECTED_LINKS_PER_CHUNK);
chunkMapping.put(chunk, chunkLinks);
}
chunkLinks.add(link);
}
}
else
{
@@ -314,44 +345,59 @@ public abstract class NewDimData
modified = true;
//Link created!
if (linkType != LinkTypes.CLIENT_SIDE)
if (linkType != LinkType.CLIENT)
{
linkWatcher.onCreated(link.link);
linkWatcher.onCreated(new ClientLinkData(link));
}
return link;
}
public DimLink createChildLink(int x, int y, int z, DimLink parent)
{
return createChildLink(new Point4D(x, y, z, id), (InnerDimLink) parent, null);
}
public DimLink createChildLink(Point4D source, DimLink parent, DDLock locked)
{
// To avoid having multiple links at a single point, if we find an existing link then we overwrite
// its destination data instead of creating a new instance.
if (parent == null)
{
throw new IllegalArgumentException("parent cannot be null.");
}
return createChildLink(new Point4D(x, y, z, id), (InnerDimLink) parent);
}
private DimLink createChildLink(Point4D source, InnerDimLink parent)
{
//To avoid having multiple links at a single point, if we find an existing link then we overwrite
//its destination data instead of creating a new instance.
InnerDimLink link = linkMapping.get(source);
if (link == null)
{
link = new InnerDimLink(source, parent, parent.link.orientation);
link = new InnerDimLink(source, parent, parent.orientation, locked);
linkMapping.put(source, link);
linkList.add(link);
//Link created!
linkWatcher.onCreated(link.link);
// If this code is running on the server side, add this link to chunkMapping.
// Granted, the client side code should never create child links anyway...
if (link.linkType() != LinkType.CLIENT)
{
ChunkCoordIntPair chunk = link.getChunkCoordinates();
List<InnerDimLink> chunkLinks = chunkMapping.get(chunk);
if (chunkLinks == null)
{
chunkLinks = new ArrayList<InnerDimLink>(EXPECTED_LINKS_PER_CHUNK);
chunkMapping.put(chunk, chunkLinks);
}
chunkLinks.add(link);
}
// Link created!
linkWatcher.onCreated(new ClientLinkData(link));
}
else
{
if (link.overwrite(parent, parent.link.orientation))
if (link.overwrite((InnerDimLink) parent, parent.orientation))
{
//Link created!
linkWatcher.onCreated(link.link);
linkWatcher.onCreated(new ClientLinkData(link));
}
}
modified = true;
@@ -368,8 +414,20 @@ public abstract class NewDimData
if (target != null)
{
linkList.remove(target);
//Raise deletion event
linkWatcher.onDeleted(target.link);
// If this code is running on the server side, remove this link to chunkMapping.
if (link.linkType() != LinkType.CLIENT)
{
ChunkCoordIntPair chunk = target.getChunkCoordinates();
List<InnerDimLink> chunkLinks = chunkMapping.get(chunk);
if (chunkLinks != null)
{
chunkLinks.remove(target);
}
}
// Raise deletion event
linkWatcher.onDeleted(new ClientLinkData(link));
target.clear();
modified = true;
}
@@ -378,7 +436,10 @@ public abstract class NewDimData
public boolean deleteLink(int x, int y, int z)
{
Point4D location = new Point4D(x, y, z, id);
return this.deleteLink(this.getLink(x, y, z));
}
public boolean deleteLink(Point4D location)
{
return this.deleteLink(this.getLink(location));
}
@@ -390,7 +451,7 @@ public abstract class NewDimData
public DimLink getLink(Point3D location)
{
return linkMapping.get(new Point4D(location.getX(),location.getY(),location.getZ(),this.id));
return linkMapping.get(new Point4D(location.getX(), location.getY(), location.getZ(), this.id));
}
public DimLink getLink(Point4D location)
@@ -413,11 +474,10 @@ public abstract class NewDimData
return (root != this);
}
public boolean isDungeon()
public DimensionType type()
{
return isDungeon;
return this.type;
}
public boolean isFilled()
{
return isFilled;
@@ -491,7 +551,7 @@ public abstract class NewDimData
public void initializeDungeon(int originX, int originY, int originZ, int orientation, DimLink incoming, DungeonData dungeon)
{
if (!isDungeon)
if (this.type != DimensionType.DUNGEON)
{
throw new IllegalStateException("Cannot invoke initializeDungeon() on a non-dungeon dimension.");
}
@@ -503,7 +563,7 @@ public abstract class NewDimData
{
throw new IllegalArgumentException("orientation must be between 0 and 3, inclusive.");
}
setDestination(incoming, originX, originY, originZ);
setLinkDestination(incoming, originX, originY, originZ);
this.origin = incoming.destination();
this.orientation = orientation;
this.dungeon = dungeon;
@@ -516,11 +576,42 @@ public abstract class NewDimData
*/
public void setParentToRoot()
{
// Update this dimension's information
if (parent != null)
{
parent.children.remove(this);
}
this.depth = 1;
this.parent = this.root;
this.root.children.add(this);
this.root.modified = true;
this.modified = true;
if (this.type == DimensionType.DUNGEON)
{
this.packDepth = calculatePackDepth(this.parent, this.dungeon);
}
// Update the depths for child dimensions using a depth-first traversal
Stack<NewDimData> ordering = new Stack<NewDimData>();
ordering.addAll(this.children);
while (!ordering.isEmpty())
{
NewDimData current = ordering.pop();
current.resetDepth();
ordering.addAll(current.children);
}
}
private void resetDepth()
{
// We assume that this is only applied to dimensions with parents
this.depth = this.parent.depth + 1;
if (this.type == DimensionType.DUNGEON)
{
this.packDepth = calculatePackDepth(this.parent, this.dungeon);
}
this.modified = true;
}
public static int calculatePackDepth(NewDimData parent, DungeonData current)
@@ -549,10 +640,7 @@ public abstract class NewDimData
{
return parent.packDepth + 1;
}
else
{
return 1;
}
return 1;
}
public void initializePocket(int originX, int originY, int originZ, int orientation, DimLink incoming)
@@ -566,18 +654,46 @@ public abstract class NewDimData
throw new IllegalStateException("The dimension has already been initialized.");
}
setDestination(incoming, originX, originY, originZ);
setLinkDestination(incoming, originX, originY, originZ);
this.origin = incoming.destination();
this.orientation = orientation;
this.modified = true;
}
public void setDestination(DimLink incoming, int x, int y, int z)
public void setLinkDestination(DimLink incoming, int x, int y, int z)
{
InnerDimLink link = (InnerDimLink) incoming;
link.setDestination(x, y, z, this);
this.modified = true;
}
public void lock(DimLink link, boolean locked)
{
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.lock.setLockState(locked);
modified = true;
}
public void setLock(DimLink link, DDLock lock)
{
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.setLock(lock);
modified = true;
}
public void createLock(DimLink link, ItemStack item, int lockKey)
{
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.createLock(item, lockKey);
modified = true;
}
public void removeLock(DimLink link, ItemStack item)
{
InnerDimLink innerLink = (InnerDimLink)link;
innerLink.removeLock(item, innerLink);
modified = true;
}
public DimLink getRandomLink()
{
@@ -589,10 +705,17 @@ public abstract class NewDimData
{
return linkList.get(random.nextInt(linkList.size()));
}
else
return linkList.get(0);
}
public Iterable<? extends DimLink> getChunkLinks(int chunkX, int chunkZ)
{
List<InnerDimLink> chunkLinks = chunkMapping.get(new ChunkCoordIntPair(chunkX, chunkZ));
if (chunkLinks != null)
{
return linkList.get(0);
return chunkLinks;
}
return new ArrayList<InnerDimLink>(0);
}
public boolean isModified()
@@ -605,6 +728,101 @@ public abstract class NewDimData
this.modified = false;
}
public void clear()
{
// If this dimension has a parent, remove it from its parent's list of children
if (parent != null)
{
parent.children.remove(this);
}
// Remove this dimension as the parent of its children
for (NewDimData child : children)
{
child.parent = null;
}
// Clear all fields
id = Integer.MIN_VALUE;
linkMapping.clear();
linkMapping = null;
linkList.clear();
linkList = null;
children.clear();
children = null;
type = null;
isFilled = false;
depth = Integer.MIN_VALUE;
packDepth = Integer.MIN_VALUE;
origin = null;
orientation = Integer.MIN_VALUE;
dungeon = null;
linkWatcher = null;
}
public PackedDimData pack()
{
ArrayList<Integer> ChildIDs = new ArrayList<Integer>();
ArrayList<PackedLinkData> Links = new ArrayList<PackedLinkData>();
ArrayList<PackedLinkTail> Tails = new ArrayList<PackedLinkTail>();
PackedDungeonData packedDungeon=null;
if(this.dungeon!=null)
{
packedDungeon= new PackedDungeonData(dungeon.weight(), dungeon.isOpen(), dungeon.isInternal(),
dungeon.schematicPath(), dungeon.schematicName(), dungeon.dungeonType().Name,
dungeon.dungeonType().Owner.getName());
}
//Make a list of children
for(NewDimData data : this.children)
{
ChildIDs.add(data.id);
}
for(DimLink link:this.links())
{
ArrayList<Point3D> children = new ArrayList<Point3D>();
Point3D parentPoint = new Point3D(-1,-1,-1);
if(link.parent!=null)
{
parentPoint=link.parent.point.toPoint3D();
}
for(DimLink childLink : link.children)
{
children.add(childLink.source().toPoint3D());
}
PackedLinkTail tail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType());
Links.add(new PackedLinkData(link.point,parentPoint,tail,link.orientation,children,link.lock));
PackedLinkTail tempTail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType());
if(Tails.contains(tempTail))
{
Tails.add(tempTail);
}
}
int parentID=this.id;
Point3D originPoint=new Point3D(0,0,0);
if(this.parent!=null)
{
parentID = this.parent.id;
}
if(this.origin!=null)
{
originPoint=this.origin.toPoint3D();
}
return new PackedDimData(this.id, depth, this.packDepth, parentID, this.root().id(), orientation,
type, isFilled,packedDungeon, originPoint, ChildIDs, Links, Tails);
// FIXME: IMPLEMENTATION PLZTHX
//I tried
}
@Override
public String name()
{
return String.valueOf(id);
}
@Override
public String toString()
{
return "DimID= " + this.id;

View File

@@ -7,181 +7,94 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.helpers.Compactor;
import StevenDimDoors.mod_pocketDim.helpers.DeleteFolder;
import StevenDimDoors.mod_pocketDim.saving.DDSaveHandler;
import StevenDimDoors.mod_pocketDim.saving.IPackable;
import StevenDimDoors.mod_pocketDim.saving.OldSaveImporter;
import StevenDimDoors.mod_pocketDim.saving.PackedDimData;
import StevenDimDoors.mod_pocketDim.saving.PackedDungeonData;
import StevenDimDoors.mod_pocketDim.saving.PackedLinkData;
import StevenDimDoors.mod_pocketDim.saving.PackedLinkTail;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.watcher.ClientDimData;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
import StevenDimDoors.mod_pocketDim.watcher.IUpdateSource;
import StevenDimDoors.mod_pocketDim.watcher.IUpdateWatcher;
import StevenDimDoors.mod_pocketDim.watcher.UpdateWatcherProxy;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* This class regulates all the operations involving the storage and manipulation of dimensions.
* It handles saving dim data, teleporting the player, and creating/registering new dimensions as
* well as loading old dimensions on startup
* This class regulates all the operations involving the storage and
* manipulation of dimensions. It handles saving dim data, teleporting the
* player, and creating/registering new dimensions as well as loading old
* dimensions on startup
*/
public class PocketManager
{
private static class InnerDimData extends NewDimData implements IPackable<PackedDimData>
{
private static class InnerDimData extends NewDimData
{
// This class allows us to instantiate NewDimData indirectly without exposing
// a public constructor from NewDimData. It's meant to stop us from constructing
// instances of NewDimData going through PocketManager. In turn, that enforces
// that any link destinations must be real dimensions controlled by PocketManager.
// This class allows us to instantiate NewDimData indirectly without
// exposing
// a public constructor from NewDimData. It's meant to stop us from
// constructing
// instances of NewDimData going through PocketManager. In turn, that
// enforces
// that any link destinations must be real dimensions controlled by
// PocketManager.
public InnerDimData(int id, InnerDimData parent, boolean isPocket, boolean isDungeon,
IUpdateWatcher<ClientLinkData> linkWatcher)
public InnerDimData(int id, InnerDimData parent, DimensionType type, IUpdateWatcher<ClientLinkData> linkWatcher)
{
super(id, parent, isPocket, isDungeon, linkWatcher);
super(id, parent, type, linkWatcher);
}
public InnerDimData(int id, InnerDimData root)
public InnerDimData(int id, NewDimData root, DimensionType type)
{
// This constructor is meant for client-side code only
super(id, root);
super(id, root, type);
}
public void clear()
}
private static class ClientLinkWatcher implements IUpdateWatcher<ClientLinkData>
{
@Override
public void onCreated(ClientLinkData link)
{
// If this dimension has a parent, remove it from its parent's list of children
if (parent != null)
{
parent.children.remove(this);
}
// Remove this dimension as the parent of its children
for (NewDimData child : children)
{
child.parent = null;
}
// Clear all fields
id = Integer.MIN_VALUE;
linkMapping.clear();
linkMapping = null;
linkList.clear();
linkList = null;
children.clear();
children = null;
isDungeon = false;
isFilled = false;
depth = Integer.MIN_VALUE;
packDepth = Integer.MIN_VALUE;
origin = null;
orientation = Integer.MIN_VALUE;
dungeon = null;
linkWatcher = null;
Point4D source = link.point;
NewDimData dimension = getDimensionData(source.getDimension());
dimension.createLink(source, LinkType.CLIENT, 0, link.lock);
}
@Override
public String name()
public void onDeleted(ClientLinkData link)
{
return String.valueOf(id);
Point4D source = link.point;
NewDimData dimension = getDimensionData(source.getDimension());
dimension.deleteLink(source.getX(), source.getY(), source.getZ());
}
@Override
public PackedDimData pack()
public void update(ClientLinkData link)
{
ArrayList<Integer> ChildIDs = new ArrayList<Integer>();
ArrayList<PackedLinkData> Links = new ArrayList<PackedLinkData>();
ArrayList<PackedLinkTail> Tails = new ArrayList<PackedLinkTail>();
PackedDungeonData packedDungeon=null;
if(this.dungeon!=null)
{
packedDungeon= new PackedDungeonData(dungeon.weight(), dungeon.isOpen(), dungeon.isInternal(),
dungeon.schematicPath(), dungeon.schematicName(), dungeon.dungeonType().Name,
dungeon.dungeonType().Owner.getName());
}
//Make a list of children
for(NewDimData data : this.children)
{
ChildIDs.add(data.id);
}
for(DimLink link:this.links())
{
ArrayList<Point3D> children = new ArrayList<Point3D>();
Point3D parentPoint = new Point3D(-1,-1,-1);
if(link.parent!=null)
{
parentPoint=link.parent.link.point.toPoint3D();
}
for(DimLink childLink : link.children)
{
children.add(childLink.source().toPoint3D());
}
PackedLinkTail tail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType());
Links.add(new PackedLinkData(link.link.point,parentPoint,tail,link.link.orientation,children));
PackedLinkTail tempTail = new PackedLinkTail(link.tail.getDestination(),link.tail.getLinkType());
if(Tails.contains(tempTail))
{
Tails.add(tempTail);
Point4D source = link.point;
NewDimData dimension = getDimensionData(source.getDimension());
DimLink dLink = dimension.getLink(source);
dLink.lock = link.lock;
}
}
int parentID=this.id;
Point3D originPoint=new Point3D(0,0,0);
if(this.parent!=null)
{
parentID = this.parent.id;
}
if(this.origin!=null)
{
originPoint=this.origin.toPoint3D();
}
return new PackedDimData(this.id, depth, this.packDepth, parentID, this.root().id(), orientation,
isDungeon, isFilled,packedDungeon, originPoint, ChildIDs, Links, Tails);
// FIXME: IMPLEMENTATION PLZTHX
//I tried
}
}
private static class ClientLinkWatcher implements IUpdateWatcher<ClientLinkData>
{
@Override
public void onCreated(ClientLinkData link)
{
Point4D source = link.point;
NewDimData dimension = getDimensionData(source.getDimension());
dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.CLIENT_SIDE,link.orientation);
}
@Override
public void onDeleted(ClientLinkData link)
{
Point4D source = link.point;
NewDimData dimension = getDimensionData(source.getDimension());
dimension.deleteLink(source.getX(), source.getY(), source.getZ());
}
}
private static class ClientDimWatcher implements IUpdateWatcher<ClientDimData>
{
@Override
public void onCreated(ClientDimData data)
{
registerClientDimension(data.ID, data.RootID);
registerClientDimension(data.ID, data.rootID, data.type);
}
@Override
@@ -189,22 +102,31 @@ public class PocketManager
{
deletePocket(getDimensionData(data.ID), false);
}
@Override
public void update(ClientDimData message)
{
// TODO Auto-generated method stub
}
}
private static class DimRegistrationCallback implements IDimRegistrationCallback
{
// We use this class to provide Compactor with the ability to send us dim data without
// having to instantiate a bunch of data containers and without exposing an "unsafe"
// creation method for anyone to call. Integrity protection for the win! It's like
// We use this class to provide Compactor with the ability to send us
// dim data without
// having to instantiate a bunch of data containers and without exposing
// an "unsafe"
// creation method for anyone to call. Integrity protection for the win!
// It's like
// exposing a private constructor ONLY to a very specific trusted class.
@Override
public NewDimData registerDimension(int dimensionID, int rootID)
public NewDimData registerDimension(int dimensionID, int rootID, DimensionType type)
{
return registerClientDimension(dimensionID, rootID);
return registerClientDimension(dimensionID, rootID, type);
}
}
private static int OVERWORLD_DIMENSION_ID = 0;
private static volatile boolean isLoading = false;
@@ -218,18 +140,25 @@ public class PocketManager
private static final UpdateWatcherProxy<ClientDimData> dimWatcher = new UpdateWatcherProxy<ClientDimData>();
private static ArrayList<NewDimData> rootDimensions = null;
//HashMap that maps all the dimension IDs registered with DimDoors to their DD data.
// HashMap that maps all the dimension IDs registered with DimDoors to their
// DD data.
private static HashMap<Integer, InnerDimData> dimensionData = null;
//ArrayList that stores the dimension IDs of any dimension that has been deleted.
// ArrayList that stores the dimension IDs of any dimension that has been
// deleted.
private static ArrayList<Integer> dimensionIDBlackList = null;
// Stores all the personal pocket mappings
private static HashMap<String, NewDimData> personalPocketsMapping = null;
public static boolean isLoaded()
{
return isLoaded;
}
/**
* simple method called on startup to register all dims saved in the dim list. Only tries to register pocket dims, though. Also calls load()
* simple method called on startup to register all dims saved in the dim
* list. Only tries to register pocket dims, though. Also calls load()
*
* @return
*/
public static void load()
@@ -243,59 +172,65 @@ public class PocketManager
return;
}
isLoading = true;
dimensionData = new HashMap<Integer, InnerDimData>();
rootDimensions = new ArrayList<NewDimData>();
dimensionIDBlackList = new ArrayList<Integer>();
if(FMLCommonHandler.instance().getEffectiveSide().isClient())
personalPocketsMapping = new HashMap<String, NewDimData>();
if (FMLCommonHandler.instance().getEffectiveSide().isClient())
{
//Shouldnt try to load everything if we are a client
//This was preventing onPacket from loading properly
isLoading=false;
isLoaded=true;
// Shouldnt try to load everything if we are a client
// This was preventing onPacket from loading properly
isLoading = false;
isLoaded = true;
return;
}
//Register Limbo
// Register Limbo
DDProperties properties = DDProperties.instance();
registerDimension(properties.LimboDimensionID, null, false, false);
registerDimension(properties.LimboDimensionID, null, DimensionType.ROOT);
loadInternal();
//Register pocket dimensions
// Register pocket dimensions
registerPockets(properties);
isLoaded = true;
isLoading = false;
}
public static boolean registerPackedDimData(PackedDimData packedData)
{
InnerDimData dimData;
//register roots
if(packedData.ID==packedData.ParentID)
DimensionType type = DimensionType.getTypeFromIndex(packedData.DimensionType);
if (type == null)
{
dimData = new InnerDimData(packedData.ID, null, false, false, linkWatcher);
dimData.root=dimData;
dimData.parent=dimData;
dimData.depth=packedData.Depth;
dimData.isFilled=packedData.IsFilled;
dimData.origin = new Point4D(packedData.Origin.getX(),packedData.Origin.getY(),packedData.Origin.getZ(),packedData.ID);
throw new IllegalArgumentException("Invalid dimension type");
}
// register roots
if (packedData.ID == packedData.ParentID)
{
dimData = new InnerDimData(packedData.ID, null, type, linkWatcher);
dimData.root = dimData;
dimData.parent = dimData;
dimData.depth = packedData.Depth;
dimData.isFilled = packedData.IsFilled;
dimData.origin = new Point4D(packedData.Origin.getX(), packedData.Origin.getY(), packedData.Origin.getZ(), packedData.ID);
PocketManager.rootDimensions.add(dimData);
}
else //register children
else
// register children
{
InnerDimData test = PocketManager.dimensionData.get(packedData.ParentID);
dimData = new InnerDimData(packedData.ID, test,true, packedData.IsDungeon, linkWatcher);
dimData.isFilled=packedData.IsFilled;
dimData.origin = new Point4D(packedData.Origin.getX(),packedData.Origin.getY(),packedData.Origin.getZ(),packedData.ID);
dimData.root=PocketManager.getDimensionData(packedData.RootID);
if(packedData.DungeonData!=null)
dimData = new InnerDimData(packedData.ID, test, type, linkWatcher);
dimData.isFilled = packedData.IsFilled;
dimData.origin = new Point4D(packedData.Origin.getX(), packedData.Origin.getY(), packedData.Origin.getZ(), packedData.ID);
dimData.root = PocketManager.createDimensionData(packedData.RootID);
if (packedData.DungeonData != null)
{
dimData.dungeon=DDSaveHandler.unpackDungeonData(packedData.DungeonData);
dimData.dungeon = DDSaveHandler.unpackDungeonData(packedData.DungeonData);
}
}
@@ -304,57 +239,63 @@ public class PocketManager
return true;
}
public static boolean deletePocket(NewDimData target, boolean deleteFolder)
{
// We can't delete the dimension if it's currently loaded or if it's not actually a pocket.
// We cast to InnerDimData so that if anyone tries to be a smartass and create their
// We can't delete the dimension if it's currently loaded or if it's not
// actually a pocket.
// We cast to InnerDimData so that if anyone tries to be a smartass and
// create their
// own version of NewDimData, this will throw an exception.
InnerDimData dimension = (InnerDimData) target;
if (dimension.isPocketDimension() && DimensionManager.getWorld(dimension.id()) == null)
{
if (deleteFolder)
{
deleteDimensionFiles(target);
deleteDimensionFiles(dimension);
}
// Note: We INTENTIONALLY don't unregister the dimensions that we
// delete with Forge. Instead, we keep them registered to stop Forge
// from reallocating those IDs to other mods such as Mystcraft. This
// is to prevent bugs. Blacklisted dimensions are still properly
// unregistered when the server shuts down.
dimensionIDBlackList.add(dimension.id);
deleteDimensionData(dimension.id);
deleteDimensionData(dimension);
return true;
}
return false;
}
private static boolean deleteDimensionFiles(NewDimData target)
{
InnerDimData dimension = (InnerDimData) target;
if (dimension.isPocketDimension() && DimensionManager.getWorld(dimension.id()) == null)
{
String saveRootPath = DimensionManager.getCurrentSaveRootDirectory().getAbsolutePath();
File saveDirectory = new File(saveRootPath + "/DimensionalDoors/pocketDimID" + dimension.id());
DeleteFolder.deleteFolder(saveDirectory);
File dataFile = new File(saveRootPath + "/DimensionalDoors/data/dim_" + dimension.id() + ".txt");
dataFile.delete();
return true;
}
return false;
}
private static boolean deleteDimensionData(int dimensionID)
{
if (dimensionData.containsKey(dimensionID) && DimensionManager.getWorld(dimensionID) == null)
{
NewDimData target = PocketManager.getDimensionData(dimensionID);
InnerDimData dimension = (InnerDimData) target;
dimensionData.remove(dimensionID);
private static void deleteDimensionFiles(InnerDimData dimension)
{
// We assume that the caller checks if the dimension is loaded, for the
// sake of efficiency. Don't call this on a loaded dimension or bad
// things will happen!
String saveRootPath = DimensionManager.getCurrentSaveRootDirectory().getAbsolutePath();
File saveDirectory = new File(saveRootPath + "/DimensionalDoors/pocketDimID" + dimension.id());
DeleteFolder.deleteFolder(saveDirectory);
File dataFile = new File(saveRootPath + "/DimensionalDoors/data/dim_" + dimension.id() + ".txt");
dataFile.delete();
}
private static void deleteDimensionData(InnerDimData dimension)
{
// We assume that the caller checks if the dimension is loaded, for the
// sake of efficiency. Don't call this on a loaded dimension or bad
// things will happen!
if (dimensionData.remove(dimension.id()) != null)
{
// Raise the dim deleted event
getDimwatcher().onDeleted(new ClientDimData(dimension));
dimension.clear();
return true;
}
return false;
else
{
// This should never happen. A simple sanity check.
throw new IllegalArgumentException("The specified dimension is not listed with PocketManager.");
}
}
private static void registerPockets(DDProperties properties)
{
for (NewDimData dimension : dimensionData.values())
@@ -363,11 +304,19 @@ public class PocketManager
{
try
{
DimensionManager.registerDimension(dimension.id(), properties.PocketProviderID);
if (personalPocketsMapping.containsValue(dimension))
{
DimensionManager.registerDimension(dimension.id(), properties.PersonalPocketProviderID);
}
else
{
DimensionManager.registerDimension(dimension.id(), properties.PocketProviderID);
}
}
catch (Exception e)
{
System.err.println("Could not register pocket dimension #" + dimension.id() + ". Probably caused by a version update/save data corruption/other mods.");
System.err.println("Could not register pocket dimension #" + dimension.id()
+ ". Probably caused by a version update/save data corruption/other mods.");
e.printStackTrace();
}
}
@@ -389,9 +338,9 @@ public class PocketManager
System.err.println("An unexpected error occurred while unregistering pocket dimension #" + dimension.id() + ":");
e.printStackTrace();
}
}
}
}
for(Integer dimID : dimensionIDBlackList)
for (Integer dimID : dimensionIDBlackList)
{
try
{
@@ -406,37 +355,37 @@ public class PocketManager
}
/**
* loads the dim data from the saved hashMap. Also handles compatibility with old saves, see OldSaveHandler
* loads the dim data from the saved hashMap. Also handles compatibility
* with old saves, see OldSaveHandler
*/
private static void loadInternal()
{
//System.out.println(!FMLCommonHandler.instance().getSide().isClient());
{
File saveDir = DimensionManager.getCurrentSaveRootDirectory();
if (saveDir != null)
{
//Try to import data from old DD versions
//TODO - remove this code in a few versions
File oldSaveData = new File(saveDir+"/DimensionalDoorsData");
if(oldSaveData.exists())
// Try to import data from old DD versions
// TODO - remove this code in a few versions
File oldSaveData = new File(saveDir + "/DimensionalDoorsData");
if (oldSaveData.exists())
{
try
{
System.out.println("Importing old DD save data...");
OldSaveImporter.importOldSave(oldSaveData);
oldSaveData.delete();
oldSaveData.renameTo(new File(oldSaveData.getAbsolutePath() + "_IMPORTED"));
System.out.println("Import Succesful!");
}
catch (Exception e)
{
//TODO handle fail cases
// TODO handle fail cases
System.out.println("Import failed!");
e.printStackTrace();
}
return;
}
// Load save data
System.out.println("Loading Dimensional Doors save data...");
if (DDSaveHandler.loadAll())
@@ -445,20 +394,20 @@ public class PocketManager
}
}
}
public static void save(boolean checkModified)
{
if (!isLoaded)
{
return;
}
//Check this last to make sure we set the flag shortly after.
// Check this last to make sure we set the flag shortly after.
if (isSaving)
{
return;
}
isSaving = true;
try
{
DDSaveHandler.saveAll(dimensionData.values(), dimensionIDBlackList, checkModified);
@@ -475,9 +424,14 @@ public class PocketManager
isSaving = false;
}
}
public static WorldServer loadDimension(int id)
{
if (!DimensionManager.isDimensionRegistered(id))
{
return null;
}
WorldServer world = DimensionManager.getWorld(id);
if (world == null)
{
@@ -494,61 +448,104 @@ public class PocketManager
public static NewDimData registerDimension(World world)
{
return registerDimension(world.provider.dimensionId, null, false, false);
return registerDimension(world.provider.dimensionId, null, DimensionType.ROOT);
}
public static NewDimData registerPocket(NewDimData parent, boolean isDungeon)
/**
* method to register a new pocket with DD and with forge.
*
* @param parent
* @param type
* @param playername
* @return
*/
public static NewDimData registerPocket(NewDimData parent, DimensionType type, String playername)
{
if (parent == null)
{
throw new IllegalArgumentException("parent cannot be null. A pocket dimension must always have a parent dimension.");
}
DDProperties properties = DDProperties.instance();
int dimensionID = DimensionManager.getNextFreeDimId();
DimensionManager.registerDimension(dimensionID, properties.PocketProviderID);
return registerDimension(dimensionID, (InnerDimData) parent, true, isDungeon);
// register a personal pocket
if (type == DimensionType.PERSONAL)
{
if (playername == null)
{
throw new IllegalArgumentException("A personal pocket must be attached to a playername");
}
DimensionManager.registerDimension(dimensionID, properties.PersonalPocketProviderID);
NewDimData data = registerDimension(dimensionID, (InnerDimData) parent, type);
personalPocketsMapping.put(playername, data);
return data;
}
else
{ // register a pocket as personal if its parents are personal, but
// without a mapping.
if (parent.type == DimensionType.PERSONAL)
{
DimensionManager.registerDimension(dimensionID, properties.PersonalPocketProviderID);
NewDimData data = registerDimension(dimensionID, (InnerDimData) parent, DimensionType.PERSONAL);
return data;
}
// register a standard pocket
DimensionManager.registerDimension(dimensionID, properties.PocketProviderID);
return registerDimension(dimensionID, (InnerDimData) parent, type);
}
}
public static NewDimData registerPocket(NewDimData parent, DimensionType type)
{
return registerPocket(parent, type, null);
}
/**
* Registers a dimension with DD but NOT with forge.
*
* @param dimensionID
* @param parent
* @param isPocket
* @param isDungeon
* @return
*/
private static NewDimData registerDimension(int dimensionID, InnerDimData parent, boolean isPocket, boolean isDungeon)
{
private static NewDimData registerDimension(int dimensionID, InnerDimData parent, DimensionType type)
{
if (dimensionData.containsKey(dimensionID))
{
if(PocketManager.dimensionIDBlackList.contains(dimensionID))
if (PocketManager.dimensionIDBlackList.contains(dimensionID))
{
throw new IllegalArgumentException("Cannot register a dimension with ID = " + dimensionID + " because it has been blacklisted.");
}
throw new IllegalArgumentException("Cannot register a dimension with ID = " + dimensionID + " because it has already been registered.");
}
InnerDimData dimension = new InnerDimData(dimensionID, parent, isPocket, isDungeon, linkWatcher);
InnerDimData dimension = new InnerDimData(dimensionID, parent, type, linkWatcher);
dimensionData.put(dimensionID, dimension);
if (!dimension.isPocketDimension())
{
rootDimensions.add(dimension);
}
getDimwatcher().onCreated(new ClientDimData(dimension));
return dimension;
}
@SideOnly(Side.CLIENT)
private static NewDimData registerClientDimension(int dimensionID, int rootID)
{
System.out.println("Registered dim "+dimensionID+" on the client.");
// No need to raise events heres since this code should only run on the client side
// getDimensionData() always handles root dimensions properly, even if the weren't defined before
// SenseiKiwi: I'm a little worried about how getDimensionData will raise
@SideOnly(Side.CLIENT)
private static NewDimData registerClientDimension(int dimensionID, int rootID, DimensionType type)
{
// No need to raise events heres since this code should only run on the
// client side. createDimensionData() always handles root dimensions
// properly, even if they weren't defined before.
// SenseiKiwi: I'm a little worried about how createDimensionData will
// raise
// an event when it creates any root dimensions... Needs checking later.
InnerDimData root = (InnerDimData) getDimensionData(rootID);
InnerDimData root = (InnerDimData) createDimensionData(rootID);
InnerDimData dimension;
if (rootID != dimensionID)
@@ -556,7 +553,7 @@ public class PocketManager
dimension = dimensionData.get(dimensionID);
if (dimension == null)
{
dimension = new InnerDimData(dimensionID, root);
dimension = new InnerDimData(dimensionID, root, type);
dimensionData.put(dimension.id(), dimension);
}
}
@@ -564,41 +561,58 @@ public class PocketManager
{
dimension = root;
}
if(dimension.isPocketDimension()&&!DimensionManager.isDimensionRegistered(dimension.id()))
if (dimension.isPocketDimension() && !DimensionManager.isDimensionRegistered(dimension.id()))
{
//Im registering pocket dims here. I *think* we can assume that if its a pocket and we are
//registering its dim data, we also need to register it with forge.
//New packet stuff prevents this from always being true, unfortuantly. I send the dimdata to the client when they teleport.
//Steven
// Im registering pocket dims here. I *think* we can assume that if
// its a pocket and we are
// registering its dim data, we also need to register it with forge.
// New packet stuff prevents this from always being true,
// unfortuantly. I send the dimdata to the client when they
// teleport.
// Steven
DimensionManager.registerDimension(dimensionID, mod_pocketDim.properties.PocketProviderID);
}
return dimension;
}
public static NewDimData getDimensionData(World world)
{
return getDimensionData(world.provider.dimensionId);
return dimension;
}
public static NewDimData getDimensionData(int dimensionID)
{
//Retrieve the data for a dimension. If we don't have a record for that dimension,
//assume it's a non-pocket dimension that hasn't been initialized with us before
//and create a NewDimData instance for it.
//Any pocket dimension must be listed with PocketManager to have a dimension ID
//assigned, so it's safe to assume that any unknown dimensions don't belong to us.
//FIXME: What's the point of this condition? Most calls to this function will crash anyway! ~SenseiKiwi
if(PocketManager.dimensionData == null)
{
System.out.println("Something odd happend during shutdown");
return null;
}
return PocketManager.dimensionData.get(dimensionID);
}
public static NewDimData getDimensionData(World dimension)
{
return PocketManager.dimensionData.get(dimension.provider.dimensionId);
}
public static NewDimData createDimensionData(World world)
{
return createDimensionData(world.provider.dimensionId);
}
public static NewDimData createDimensionDataDangerously(int dimensionID)
{
// Same as createDimensionData(int), but public. Meant to discourage
// anyone from
// using it unless absolutely needed! We'll probably phase this out
// eventually.
return createDimensionData(dimensionID);
}
protected static NewDimData createDimensionData(int dimensionID)
{
// Retrieve the data for a dimension. If we don't have a record for that
// dimension,
// assume it's a non-pocket dimension that hasn't been initialized with
// us before
// and create a NewDimData instance for it.
NewDimData dimension = PocketManager.dimensionData.get(dimensionID);
// if we do not have a record of it, then it must be a root
if (dimension == null)
{
dimension = registerDimension(dimensionID, null, false, false);
dimension = registerDimension(dimensionID, null, DimensionType.ROOT);
}
return dimension;
}
@@ -621,14 +635,15 @@ public class PocketManager
{
throw new IllegalStateException("Pocket dimensions have already been unloaded!");
}
unregisterPockets();
dimensionData = null;
personalPocketsMapping = null;
rootDimensions = null;
isLoaded = false;
isConnected = false;
}
public static DimLink getLink(int x, int y, int z, World world)
{
return getLink(x, y, z, world.provider.dimensionId);
@@ -638,7 +653,7 @@ public class PocketManager
{
return getLink(point.getX(), point.getY(), point.getZ(), point.getDimension());
}
public static DimLink getLink(int x, int y, int z, int dimensionID)
{
NewDimData dimension = dimensionData.get(dimensionID);
@@ -646,30 +661,29 @@ public class PocketManager
{
return dimension.getLink(x, y, z);
}
else
{
return null;
}
return null;
}
public static boolean isBlackListed(int dimensionID)
{
return PocketManager.dimensionIDBlackList.contains(dimensionID);
}
public static void registerDimWatcher(IUpdateWatcher<ClientDimData> watcher)
{
getDimwatcher().registerReceiver(watcher);
}
public static boolean unregisterDimWatcher(IUpdateWatcher<ClientDimData> watcher)
{
return getDimwatcher().unregisterReceiver(watcher);
}
public static void registerLinkWatcher(IUpdateWatcher<ClientLinkData> watcher)
{
linkWatcher.registerReceiver(watcher);
}
public static boolean unregisterLinkWatcher(IUpdateWatcher<ClientLinkData> watcher)
{
return linkWatcher.unregisterReceiver(watcher);
@@ -679,33 +693,35 @@ public class PocketManager
{
updateSource.registerWatchers(new ClientDimWatcher(), new ClientLinkWatcher());
}
public static void writePacket(DataOutputStream output) throws IOException
{
// Write a very compact description of our dimensions and links to be sent to a client
// Write a very compact description of our dimensions and links to be
// sent to a client
Compactor.write(dimensionData.values(), output);
}
public static boolean isRegisteredInternally(int dimensionID)
{
return dimensionData.containsKey(dimensionID);
}
public static void createAndRegisterBlacklist(List<Integer> blacklist)
{
//TODO - create a special blacklist provider
for(Integer dimID : blacklist)
// TODO - create a special blacklist provider
for (Integer dimID : blacklist)
{
PocketManager.dimensionIDBlackList.add(dimID);
DimensionManager.registerDimension(dimID, DDProperties.instance().PocketProviderID);
}
}
}
public static void readPacket(DataInputStream input) throws IOException
{
//TODO- figure out why this is getting called so frequently
// TODO- figure out why this is getting called so frequently
if (isLoaded)
{
return;
return;
}
if (isLoading)
{
@@ -714,17 +730,39 @@ public class PocketManager
// Load compacted client-side dimension data
load();
Compactor.readDimensions(input, new DimRegistrationCallback());
// Register pocket dimensions
DDProperties properties = DDProperties.instance();
isLoaded = true;
isLoading = false;
isConnected = true;
}
public static UpdateWatcherProxy<ClientDimData> getDimwatcher()
public static UpdateWatcherProxy<ClientDimData> getDimwatcher()
{
return dimWatcher;
}
public static UpdateWatcherProxy<ClientLinkData> getLinkWatcher()
{
return linkWatcher;
}
public static NewDimData getPersonalDimensionForPlayer(String name)
{
if (personalPocketsMapping.containsKey(name))
{
return personalPocketsMapping.get(name);
}
return null;
}
public static void setPersonalPocketsMapping(HashMap<String, NewDimData> ppMap)
{
personalPocketsMapping = ppMap;
}
public static HashMap<String, NewDimData> getPersonalPocketMapping()
{
// TODO Auto-generated method stub
return personalPocketsMapping;
}
}

View File

@@ -9,7 +9,6 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.TreeMap;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.nbt.NBTTagCompound;
@@ -20,7 +19,7 @@ import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.blocks.IDimDoor;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.schematic.BlockRotator;
@@ -162,7 +161,7 @@ public class DungeonSchematic extends Schematic {
applyFilter(standardizer);
}
private Map<Short, Short> getAssignedToStandardIDMapping(DDProperties properties)
private static Map<Short, Short> getAssignedToStandardIDMapping(DDProperties properties)
{
//If we ever need this broadly or support other mods, this should be moved to a separate class
TreeMap<Short, Short> mapping = new TreeMap<Short, Short>();
@@ -247,7 +246,7 @@ public class DungeonSchematic extends Schematic {
world.setBlockTileEntity(pocketPoint.getX(), pocketPoint.getY(), pocketPoint.getZ(), TileEntity.createAndLoadEntity(tileTag));
}
setUpDungeon(PocketManager.getDimensionData(world), world, pocketCenter, turnAngle, entryLink, random, properties, blockSetter);
setUpDungeon(PocketManager.createDimensionData(world), world, pocketCenter, turnAngle, entryLink, random, properties, blockSetter);
}
private void setUpDungeon(NewDimData dimension, World world, Point3D pocketCenter, int turnAngle, DimLink entryLink, Random random, DDProperties properties, IBlockSetter blockSetter)
@@ -322,10 +321,10 @@ public class DungeonSchematic extends Schematic {
private static void createEntranceReverseLink(World world, NewDimData dimension, Point3D pocketCenter, DimLink entryLink)
{
int orientation = world.getBlockMetadata(pocketCenter.getX(), pocketCenter.getY() - 1, pocketCenter.getZ());
DimLink reverseLink = dimension.createLink(pocketCenter.getX(), pocketCenter.getY(), pocketCenter.getZ(), LinkTypes.REVERSE, orientation);
DimLink reverseLink = dimension.createLink(pocketCenter.getX(), pocketCenter.getY(), pocketCenter.getZ(), LinkType.REVERSE, orientation);
Point4D destination = entryLink.source();
NewDimData prevDim = PocketManager.getDimensionData(destination.getDimension());
prevDim.setDestination(reverseLink, destination.getX(), destination.getY(), destination.getZ());
prevDim.setLinkDestination(reverseLink, destination.getX(), destination.getY(), destination.getZ());
initDoorTileEntity(world, pocketCenter);
}
@@ -335,7 +334,7 @@ public class DungeonSchematic extends Schematic {
Point3D location = point.clone();
BlockRotator.transformPoint(location, entrance, rotation, pocketCenter);
int orientation = world.getBlockMetadata(location.getX(), location.getY() - 1, location.getZ());
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkTypes.DUNGEON_EXIT, orientation);
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkType.DUNGEON_EXIT, orientation);
//Replace the sandstone block under the exit door with the same block as the one underneath it
int x = location.getX();
int y = location.getY() - 3;
@@ -356,7 +355,7 @@ public class DungeonSchematic extends Schematic {
BlockRotator.transformPoint(location, entrance, rotation, pocketCenter);
int orientation = world.getBlockMetadata(location.getX(), location.getY() - 1, location.getZ());
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkTypes.DUNGEON, orientation);
dimension.createLink(location.getX(), location.getY(), location.getZ(), LinkType.DUNGEON, orientation);
initDoorTileEntity(world, location);
}

View File

@@ -298,4 +298,9 @@ public class DungeonPack
WeightedContainer<DungeonData> resultContainer = (WeightedContainer<DungeonData>) WeightedRandom.getRandomItem(random, weights);
return (resultContainer != null) ? resultContainer.getData() : null;
}
@Override
public String toString()
{
return this.name;
}
}

View File

@@ -45,4 +45,9 @@ public class DungeonType implements Comparable<DungeonType>
final int prime = 2039;
return prime * ID;
}
@Override
public String toString()
{
return this.Name+" owned by "+this.Owner;
}
}

View File

@@ -1,54 +1,98 @@
package StevenDimDoors.mod_pocketDim.helpers;
import StevenDimDoors.mod_pocketDim.IChunkLoader;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
import java.io.File;
import java.util.List;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.ForgeChunkManager;
import net.minecraftforge.common.ForgeChunkManager.LoadingCallback;
import net.minecraftforge.common.ForgeChunkManager.Ticket;
import net.minecraftforge.common.ForgeChunkManager.Type;
import StevenDimDoors.experimental.BoundingBox;
import StevenDimDoors.mod_pocketDim.IChunkLoader;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.world.PocketBuilder;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
public class ChunkLoaderHelper implements LoadingCallback
{
@Override
public void ticketsLoaded(List<Ticket> tickets, World world)
{
for (Ticket ticket : tickets)
{
int goldDimDoorX = ticket.getModData().getInteger("goldDimDoorX");
int goldDimDoorY = ticket.getModData().getInteger("goldDimDoorY");
int goldDimDoorZ = ticket.getModData().getInteger("goldDimDoorZ");
if(world.getBlockId(goldDimDoorX, goldDimDoorY, goldDimDoorZ) != mod_pocketDim.properties.GoldenDimensionalDoorID)
boolean loaded = false;
int x = ticket.getModData().getInteger("goldDimDoorX");
int y = ticket.getModData().getInteger("goldDimDoorY");
int z = ticket.getModData().getInteger("goldDimDoorZ");
if (world.getBlockId(x, y, z) == mod_pocketDim.properties.GoldenDimensionalDoorID)
{
IChunkLoader loader = (IChunkLoader) world.getBlockTileEntity(x, y, z);
if (!loader.isInitialized())
{
loader.initialize(ticket);
loaded = true;
}
}
if (!loaded)
{
ForgeChunkManager.releaseTicket(ticket);
}
else
{
IChunkLoader tile = (IChunkLoader) world.getBlockTileEntity(goldDimDoorX, goldDimDoorY, goldDimDoorZ);
tile.forceChunkLoading(ticket,goldDimDoorX,goldDimDoorZ);
}
}
}
public static void loadChunkForcedWorlds(FMLServerStartingEvent event)
public static Ticket createTicket(int x, int y, int z, World world)
{
for(NewDimData data : PocketManager.getDimensions())
NBTTagCompound data;
Ticket ticket = ForgeChunkManager.requestTicket(mod_pocketDim.instance, world, Type.NORMAL);
if (ticket != null)
{
data = ticket.getModData();
data.setInteger("goldDimDoorX", x);
data.setInteger("goldDimDoorY", y);
data.setInteger("goldDimDoorZ", z);
}
return ticket;
}
public static void forcePocketChunks(NewDimData pocket, Ticket ticket)
{
BoundingBox bounds = PocketBuilder.calculateDefaultBounds(pocket);
Point3D minCorner = bounds.minCorner();
Point3D maxCorner = bounds.maxCorner();
int minX = minCorner.getX() >> 4;
int minZ = minCorner.getZ() >> 4;
int maxX = maxCorner.getX() >> 4;
int maxZ = maxCorner.getZ() >> 4;
int chunkX;
int chunkZ;
for (chunkX = minX; chunkX <= maxX; chunkX++)
{
for (chunkZ = minZ; chunkZ <= maxZ; chunkZ++)
{
ForgeChunkManager.forceChunk(ticket, new ChunkCoordIntPair(chunkX, chunkZ));
}
}
}
public static void loadForcedChunkWorlds(FMLServerStartingEvent event)
{
for (NewDimData data : PocketManager.getDimensions())
{
if(data.isPocketDimension())
{
String chunkDir = DimensionManager.getCurrentSaveRootDirectory()+"/DimensionalDoors/pocketDimID" + data.id();
File file = new File(chunkDir);
if(file.exists())
{
if(ForgeChunkManager.savedWorldHasForcedChunkTickets(file))

View File

@@ -6,10 +6,10 @@ import java.io.IOException;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.IDimRegistrationCallback;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
@@ -68,19 +68,20 @@ public class Compactor
{
int id = input.readInt();
int rootID = input.readInt();
DimensionType type = DimensionType.getTypeFromIndex(input.readInt());
if (rootIDs.add(rootID))
{
callback.registerDimension(rootID, rootID);
callback.registerDimension(rootID, rootID, type);
}
// Don't check if (id != rootID) - we want to retrieve the reference anyway
NewDimData dimension = callback.registerDimension(id, rootID);
NewDimData dimension = callback.registerDimension(id, rootID, type);
int linkCount = input.readInt();
for (int h = 0; h < linkCount; h++)
{
ClientLinkData link = ClientLinkData.read(input);
Point4D source = link.point;
dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.CLIENT_SIDE,link.orientation);
dimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.CLIENT,0);
}
}
}

View File

@@ -2,31 +2,33 @@ package StevenDimDoors.mod_pocketDim.helpers;
import java.io.File;
public class DeleteFolder
{
public static boolean deleteFolder(File file)
public static boolean deleteFolder(File directory)
{
try
{
File[] files = file.listFiles();
if(files==null)
File[] contents = directory.listFiles();
if (contents != null)
{
file.delete();
return true;
for (File entry : contents)
{
if (entry.isDirectory())
{
deleteFolder(entry);
}
else
{
entry.delete();
}
}
}
for(File inFile : files)
{
DeleteFolder.deleteFolder(inFile);
}
return directory.delete();
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
return true;
}
}

View File

@@ -16,13 +16,12 @@ import java.util.List;
import java.util.Queue;
import java.util.Random;
import java.util.regex.Pattern;
import net.minecraft.util.WeightedRandom;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
@@ -46,7 +45,7 @@ public class DungeonHelper
public static final String SCHEMATIC_FILE_EXTENSION = ".schematic";
private static final String DEFAULT_ERROR_SCHEMATIC_PATH = "/schematics/core/somethingBroke.schematic";
private static final String DUNGEON_CREATION_GUIDE_SOURCE_PATH = "/mods/DimDoors/text/How_to_add_dungeons.txt";
private static final String DUNGEON_CREATION_GUIDE_SOURCE_PATH = "/assets/dimdoors/text/How_to_add_dungeons.txt";
private static final String BUNDLED_PACK_BASE_PATH = "/schematics/";
private static final String STANDARD_CONFIG_FILE_NAME = "rules.txt";
@@ -264,8 +263,8 @@ public class DungeonHelper
{
//Create a link above the specified position. Link to a new pocket dimension.
NewDimData dimension = PocketManager.getDimensionData(world);
DimLink link = dimension.createLink(x, y + 1, z, LinkTypes.POCKET, 3);
DimLink link = dimension.createLink(x, y + 1, z, LinkType.POCKET, 3);
//Place a Warp Door linked to that pocket
ItemDimensionalDoor.placeDoorBlock(world, x, y, z, 3, mod_pocketDim.warpDoor);

View File

@@ -0,0 +1,6 @@
package StevenDimDoors.mod_pocketDim.helpers;
public class PersonalPocketHelper
{
}

View File

@@ -215,10 +215,7 @@ public class yCoordHelper
{
for (int dz = -1; dz <= 1; dz++)
{
if (!provider.chunkExists(chunkX + dx, chunkZ + dz))
{
provider.loadChunk(chunkX, chunkZ);
}
provider.loadChunk(chunkX, chunkZ);
}
}
return target;

View File

@@ -2,6 +2,7 @@ package StevenDimDoors.mod_pocketDim.items;
import java.util.HashMap;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
@@ -23,9 +24,9 @@ import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
public abstract class BaseItemDoor extends ItemDoor
{
// maps non-dimensional door items to their corresponding dimensional door
// item
private static HashMap<ItemDoor, BaseItemDoor> vanillaDoorMapping = new HashMap<ItemDoor, BaseItemDoor>();
// Maps non-dimensional door items to their corresponding dimensional door item
// Also maps dimensional door items to themselves for simplicity
private static HashMap<ItemDoor, BaseItemDoor> doorItemMapping = new HashMap<ItemDoor, BaseItemDoor>();
private static DDProperties properties = null;
/**
@@ -34,7 +35,7 @@ public abstract class BaseItemDoor extends ItemDoor
* @param material
* @param door
*/
public BaseItemDoor(int itemID, Material material, ItemDoor door)
public BaseItemDoor(int itemID, Material material, ItemDoor vanillaDoor)
{
super(itemID, material);
this.setMaxStackSize(64);
@@ -42,9 +43,10 @@ public abstract class BaseItemDoor extends ItemDoor
if (properties == null)
properties = DDProperties.instance();
if(door!=null)
doorItemMapping.put(this, this);
if (vanillaDoor != null)
{
vanillaDoorMapping.put(door, this);
doorItemMapping.put(vanillaDoor, this);
}
}
@@ -64,7 +66,7 @@ public abstract class BaseItemDoor extends ItemDoor
*
* @return
*/
protected abstract BaseDimDoor getDoortoItemMapping();
protected abstract BaseDimDoor getDoorBlock();
/**
* Overriden here to remove vanilla block placement functionality from
@@ -73,23 +75,12 @@ public abstract class BaseItemDoor extends ItemDoor
@Override
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ)
{
// TODO Auto-generated method stub
return false;
}
public static BaseDimDoor getDoorToPlace(Item item)
{
if (!(item instanceof BaseItemDoor))
{
item = BaseItemDoor.vanillaDoorMapping.get(item);
}
return ((BaseItemDoor) item).getDoortoItemMapping();
}
/**
* Tries to place a door block, called in EventHookContainer
* Tries to place a door as a dimensional door
*
* @param doorBlock
* @param stack
* @param player
* @param world
@@ -97,8 +88,6 @@ public abstract class BaseItemDoor extends ItemDoor
* @param y
* @param z
* @param side
* @param requireLink
* @param reduceStack
* @return
*/
public static boolean tryToPlaceDoor(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side)
@@ -107,15 +96,20 @@ public abstract class BaseItemDoor extends ItemDoor
{
return false;
}
if (!(stack.getItem() instanceof ItemDoor))
// Retrieve the actual door type that we want to use here.
// It's okay if stack isn't an ItemDoor. In that case, the lookup will
// return null, just as if the item was an unrecognized door type.
BaseItemDoor mappedItem = doorItemMapping.get(stack.getItem());
if (mappedItem == null)
{
throw new IllegalArgumentException("The itemstack must correspond to some type of door");
return false;
}
if (BaseItemDoor.placeDoorOnBlock(getDoorToPlace(stack.getItem()), stack, player, world, x, y, z, side))
BaseDimDoor doorBlock = mappedItem.getDoorBlock();
if (BaseItemDoor.placeDoorOnBlock(doorBlock, stack, player, world, x, y, z, side))
{
return true;
}
return BaseItemDoor.placeDoorOnRift(getDoorToPlace(stack.getItem()), world, player, stack);
return BaseItemDoor.placeDoorOnRift(doorBlock, world, player, stack);
}
/**

View File

@@ -7,7 +7,7 @@ import StevenDimDoors.mod_pocketDim.mod_pocketDim;
public class ItemBlockDimWall extends ItemBlock
{
private final static String[] subNames = {"Fabric of Reality", "Ancient Fabric"};
private final static String[] subNames = {"Fabric of Reality", "Ancient Fabric" , "Altered Fabric"};
public ItemBlockDimWall(int par1)
{

View File

@@ -0,0 +1,213 @@
package StevenDimDoors.mod_pocketDim.items;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.EnumAction;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumMovingObjectType;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.IDimDoor;
import StevenDimDoors.mod_pocketDim.core.DDLock;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
public class ItemDDKey extends Item
{
public static final int TIME_TO_UNLOCK = 30;
public ItemDDKey(int itemID)
{
super(itemID);
this.setCreativeTab(mod_pocketDim.dimDoorsCreativeTab);
this.setMaxStackSize(1);
}
public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{
}
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
{
if (DDLock.hasCreatedLock(par1ItemStack))
{
par3List.add("Bound");
}
else
{
par3List.add("Unbound");
}
}
@Override
public void registerIcons(IconRegister par1IconRegister)
{
this.itemIcon = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName().replace("item.", ""));
}
@Override
@SideOnly(Side.CLIENT)
public boolean hasEffect(ItemStack par1ItemStack)
{
return !DDLock.hasCreatedLock(par1ItemStack);
}
public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World par3World, int par4, int par5, int par6, int par7, float par8, float par9,
float par10)
{
player.setItemInUse(itemStack, this.getMaxItemUseDuration(itemStack));
return false;
}
public boolean onItemUseFirst(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int side, float playerX, float playerY,
float playerZ)
{
if (world.isRemote)
{
return false;
}
if (player.getItemInUse() != null)
{
return true;
}
int blockID = world.getBlockId(x, y, z);
// make sure we are dealing with a door
if (!(Block.blocksList[blockID] instanceof IDimDoor))
{
return false;
}
DimLink link = PocketManager.getLink(x, y, z, world);
// dont do anything to doors without links
if (link == null)
{
return false;
}
// what to do if the door has a lock already
if (link.hasLock())
{
if (link.doesKeyUnlock(itemStack))
{
if (link.getLockState())
{
world.playSoundAtEntity(player, mod_pocketDim.modid + ":keyUnlock", 1F, 1F);
}
else
{
world.playSoundAtEntity(player, mod_pocketDim.modid + ":keyLock", 1F, 1F);
}
PocketManager.getDimensionData(world).lock(link, !link.getLockState());
PocketManager.getLinkWatcher().update(new ClientLinkData(link));
}
else
{
world.playSoundAtEntity(player, mod_pocketDim.modid + ":doorLocked", 1F, 1F);
}
}
else
{
if (!DDLock.hasCreatedLock(itemStack))
{
world.playSoundAtEntity(player, mod_pocketDim.modid + ":keyLock", 1F, 1F);
PocketManager.getDimensionData(world).createLock(link, itemStack, world.rand.nextInt(Integer.MAX_VALUE));
PocketManager.getLinkWatcher().update(new ClientLinkData(link));
}
}
return false;
}
/**
* Handle removal of locks here
*/
@Override
public void onPlayerStoppedUsing(ItemStack itemStack, World world, EntityPlayer player, int heldTime)
{
int j = this.getMaxItemUseDuration(itemStack) - heldTime;
if (j >= TIME_TO_UNLOCK)
{
//Raytrace to make sure we are still looking at a door
MovingObjectPosition pos = getMovingObjectPositionFromPlayer(player.worldObj, player, true);
if (pos != null && pos.typeOfHit == EnumMovingObjectType.TILE)
{
//make sure we have a link and it has a lock
DimLink link = PocketManager.getLink(pos.blockX, pos.blockY, pos.blockZ, player.worldObj);
if (link != null && link.hasLock())
{
//make sure the given key is able to access the lock
if (link.doesKeyUnlock(itemStack) && !world.isRemote)
{
PocketManager.getDimensionData(world).removeLock(link, itemStack);
world.playSoundAtEntity(player, mod_pocketDim.modid + ":doorLockRemoved", 1F, 1F);
}
}
}
}
player.clearItemInUse();
}
/**
* Raytrace to make sure we are still looking at the right block while preparing to remove the lock
*/
@Override
public void onUsingItemTick(ItemStack stack, EntityPlayer player, int count)
{
// no need to check every tick, twice a second instead
if (count % 10 == 0)
{
MovingObjectPosition pos = getMovingObjectPositionFromPlayer(player.worldObj, player, true);
if (pos != null && pos.typeOfHit == EnumMovingObjectType.TILE)
{
DimLink link = PocketManager.getLink(pos.blockX, pos.blockY, pos.blockZ, player.worldObj);
if (link != null && link.hasLock())
{
if (link.doesKeyUnlock(stack))
{
return;
}
}
}
player.clearItemInUse();
}
}
public EnumAction getItemUseAction(ItemStack par1ItemStack)
{
return EnumAction.bow;
}
public ItemStack onEaten(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer)
{
return par1ItemStack;
}
public int getMaxItemUseDuration(ItemStack par1ItemStack)
{
return 72000;
}
public String getItemStackDisplayName(ItemStack par1ItemStack)
{
return StatCollector.translateToLocal(this.getUnlocalizedName(par1ItemStack));
}
}

View File

@@ -28,7 +28,7 @@ public class ItemDimensionalDoor extends BaseItemDoor
}
@Override
protected BaseDimDoor getDoortoItemMapping()
protected BaseDimDoor getDoorBlock()
{
return (BaseDimDoor) mod_pocketDim.dimensionalDoor;
}

View File

@@ -28,7 +28,7 @@ public class ItemGoldDimDoor extends BaseItemDoor
}
@Override
protected BaseDimDoor getDoortoItemMapping()
protected BaseDimDoor getDoorBlock()
{
return (BaseDimDoor) mod_pocketDim.goldenDimensionalDoor;
}

View File

@@ -15,6 +15,7 @@ public class ItemGoldDoor extends ItemDoor
public ItemGoldDoor(int par1, Material par2Material)
{
super(par1, par2Material);
this.setMaxStackSize(16);
}
@Override

View File

@@ -0,0 +1,35 @@
package StevenDimDoors.mod_pocketDim.items;
import java.util.List;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
public class ItemPersonalDoor extends BaseItemDoor
{
public ItemPersonalDoor(int itemID, Material material, ItemDoor door)
{
super(itemID, material, door);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
{
par3List.add("Creates a pathway to");
par3List.add("Your personal pocket");
}
@Override
protected BaseDimDoor getDoorBlock()
{
return (BaseDimDoor) mod_pocketDim.personalDimDoor;
}
}

View File

@@ -0,0 +1,58 @@
package StevenDimDoors.mod_pocketDim.items;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemDoor;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
public class ItemQuartzDoor extends ItemDoor
{
public ItemQuartzDoor(int par1, Material par2Material)
{
super(par1, par2Material);
}
@Override
public void registerIcons(IconRegister par1IconRegister)
{
this.itemIcon = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName().replace("item.", ""));
}
@Override
public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, float par9, float par10)
{
if (par7 != 1)
{
return false;
}
else
{
++par5;
Block block = mod_pocketDim.quartzDoor;
if (par2EntityPlayer.canPlayerEdit(par4, par5, par6, par7, par1ItemStack) && par2EntityPlayer.canPlayerEdit(par4, par5 + 1, par6, par7, par1ItemStack))
{
if (!block.canPlaceBlockAt(par3World, par4, par5, par6))
{
return false;
}
else
{
int i1 = MathHelper.floor_double((par2EntityPlayer.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3;
placeDoorBlock(par3World, par4, par5, par6, i1, block);
--par1ItemStack.stackSize;
return true;
}
}
else
{
return false;
}
}
}
}

View File

@@ -1,7 +1,6 @@
package StevenDimDoors.mod_pocketDim.items;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer;
@@ -14,7 +13,7 @@ import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BaseDimDoor;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
@@ -34,12 +33,13 @@ public class ItemRiftSignature extends Item
@SideOnly(Side.CLIENT)
@Override
public boolean hasEffect(ItemStack stack)
public boolean hasEffect(ItemStack stack, int pass)
{
//Make the item glow if it has one endpoint stored
return (stack.getItemDamage() != 0);
}
@Override
public void registerIcons(IconRegister par1IconRegister)
{
this.itemIcon = par1IconRegister.registerIcon(mod_pocketDim.modid + ":" + this.getUnlocalizedName().replace("item.", ""));
@@ -60,50 +60,47 @@ public class ItemRiftSignature extends Item
return false;
}
y += 2; //Increase y by 2 to place the rift at head level
if (!player.canPlayerEdit(x, y, z, side, stack))
//Increase y by 2 to place the rift at head level
int adjustedY = adjustYForSpecialBlocks(world, x, y + 2, z);
if (!player.canPlayerEdit(x, adjustedY, z, side, stack))
{
return true;
}
int adjustedY = adjustYForSpecialBlocks(world,x,y,z);
Point4DOrientation source = getSource(stack);
int orientation = MathHelper.floor_double((double) ((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3;
int orientation = MathHelper.floor_double(((player.rotationYaw + 180.0F) * 4.0F / 360.0F) - 0.5D) & 3;
if (source != null)
{
//The link was used before and already has an endpoint stored. Create links connecting the two endpoints.
// The link was used before and already has an endpoint stored.
// Create links connecting the two endpoints.
NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension());
NewDimData destinationDimension = PocketManager.getDimensionData(world);
DimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.NORMAL,source.getOrientation());
DimLink reverse = destinationDimension.createLink(x, adjustedY, z, LinkTypes.NORMAL,orientation);
destinationDimension.setDestination(link, x, adjustedY, z);
sourceDimension.setDestination(reverse, source.getX(), source.getY(), source.getZ());
//Try placing a rift at the destination point
if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z))
{
world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID);
}
DimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.NORMAL,source.getOrientation());
DimLink reverse = destinationDimension.createLink(x, adjustedY, z, LinkType.NORMAL,orientation);
//Try placing a rift at the source point, but check if its world is loaded first
destinationDimension.setLinkDestination(link, x, adjustedY, z);
sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ());
// Try placing a rift at the destination point
mod_pocketDim.blockRift.tryPlacingRift(world, x, adjustedY, z);
// Try placing a rift at the source point
// We don't need to check if sourceWorld is null - that's already handled.
World sourceWorld = DimensionManager.getWorld(sourceDimension.id());
if (sourceWorld != null &&
!mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ()))
{
sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID);
}
mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
if (!player.capabilities.isCreativeMode)
{
stack.stackSize--;
}
clearSource(stack);
mod_pocketDim.sendChat(player,("Rift Created"));
world.playSoundAtEntity(player,mod_pocketDim.modid+":riftEnd", 0.6f, 1);
mod_pocketDim.sendChat(player, "Rift Created");
world.playSoundAtEntity(player, mod_pocketDim.modid + ":riftEnd", 0.6f, 1);
}
else
{
//The link signature has not been used. Store its current target as the first location.
setSource(stack, x, adjustedY, z,orientation, PocketManager.getDimensionData(world));
setSource(stack, x, adjustedY, z, orientation, PocketManager.createDimensionData(world));
mod_pocketDim.sendChat(player,("Location Stored in Rift Signature"));
world.playSoundAtEntity(player,mod_pocketDim.modid+":riftStart", 0.6f, 1);
}
@@ -113,6 +110,7 @@ public class ItemRiftSignature extends Item
/**
* allows items to add custom lines of information to the mouseover description
*/
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
@SideOnly(Side.CLIENT)
public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4)
@@ -140,26 +138,28 @@ public class ItemRiftSignature extends Item
*/
public static int adjustYForSpecialBlocks(World world, int x, int y, int z)
{
y=y-2;//get the block the player actually clicked on
Block block = Block.blocksList[world.getBlockId(x, y, z)];
if(block==null)
int targetY = y - 2; // Get the block the player actually clicked on
Block block = Block.blocksList[world.getBlockId(x, targetY, z)];
if (block == null)
{
return y+2;
return targetY + 2;
}
if(block.isBlockReplaceable(world, x, y, z))
if (block.isBlockReplaceable(world, x, targetY, z))
{
return y+1;//move block placement down (-2+1) one so its directly over things like snow
return targetY + 1; // Move block placement down (-2+1) one so its directly over things like snow
}
if(block instanceof BaseDimDoor)
if (block instanceof BaseDimDoor)
{
if(world.getBlockId(x, y-1, z)==block.blockID&&world.getBlockMetadata(x, y, z)==8)
if (((BaseDimDoor) block).isUpperDoorBlock(world.getBlockMetadata(x, targetY, z)))
{
return y;//move rift placement down two so its in the right place on the door.
return targetY; // Move rift placement down two so its in the right place on the door.
}
return y+1;
// Move rift placement down one so its in the right place on the door.
return targetY + 1;
}
return y+2;
return targetY + 2;
}
public static void setSource(ItemStack itemStack, int x, int y, int z, int orientation, NewDimData dimension)
{
NBTTagCompound tag = new NBTTagCompound();
@@ -200,11 +200,12 @@ public class ItemRiftSignature extends Item
Integer orientation = tag.getInteger("orientation");
Integer dimID = tag.getInteger("linkDimID");
if (x != null && y != null && z != null && dimID != null)
if (x != null && y != null && z != null && orientation != null && dimID != null)
{
return new Point4DOrientation(x, y, z,orientation, dimID);
return new Point4DOrientation(x, y, z, orientation, dimID);
}
}
// Mark the item as uninitialized if its source couldn't be read
itemStack.setItemDamage(0);
}
return null;
@@ -214,10 +215,11 @@ public class ItemRiftSignature extends Item
{
private Point4D point;
private int orientation;
Point4DOrientation(int x, int y, int z, int orientation, int dimID)
{
this.point= new Point4D(x,y,z,dimID);
this.orientation=orientation;
this.point = new Point4D(x, y, z, dimID);
this.orientation = orientation;
}
int getX()
@@ -239,10 +241,16 @@ public class ItemRiftSignature extends Item
{
return point.getDimension();
}
int getOrientation()
{
return orientation;
}
Point4D getPoint()
{
return point;
}
}
}

View File

@@ -1,7 +1,6 @@
package StevenDimDoors.mod_pocketDim.items;
import java.util.List;
import net.minecraft.client.renderer.texture.IconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
@@ -11,10 +10,9 @@ import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@@ -40,69 +38,124 @@ public class ItemStabilizedRiftSignature extends ItemRiftSignature
return false;
}
// We don't check for replaceable blocks. The user can deal with that. <_<
y += 2; //Increase y by 2 to place the rift at head level
if (!player.canPlayerEdit(x, y, z, side, stack))
// Adjust Y so the rift is at head level, depending on the presence of certain blocks
int adjustedY = adjustYForSpecialBlocks(world, x, y + 2, z);
if (!player.canPlayerEdit(x, adjustedY, z, side, stack))
{
return true;
}
Point4DOrientation source = getSource(stack);
int adjustedY = adjustYForSpecialBlocks(world,x,y,z);
int orientation = MathHelper.floor_double((player.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3;
// Check if the Stabilized Rift Signature has been initialized
int orientation = MathHelper.floor_double((player.rotationYaw + 180.0F) * 4.0F / 360.0F - 0.5D) & 3;
Point4DOrientation source = getSource(stack);
if (source != null)
{
// Yes, it's initialized. Check if the player is in creative
// or if the player can pay with Stable Fabric to create a rift.
if (!player.capabilities.isCreativeMode && !player.inventory.hasItem(mod_pocketDim.itemStableFabric.itemID))
{
mod_pocketDim.sendChat(player, "You don't have any Stable Fabric!");
// I won't do this, but this is the chance to localize chat
// messages sent to the player; look at ChatMessageComponent
// and how MFR does it with items like the safari net launcher
return true;
}
//The link was used before and already has an endpoint stored. Create links connecting the two endpoints.
// Yes, it's initialized.
NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension());
NewDimData destinationDimension = PocketManager.getDimensionData(world);
DimLink link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkTypes.NORMAL,source.getOrientation());
DimLink reverse = destinationDimension.createLink(x, adjustedY, z, LinkTypes.NORMAL,orientation);
destinationDimension.setDestination(link, x, adjustedY, z);
sourceDimension.setDestination(reverse, source.getX(), source.getY(), source.getZ());
//Try placing a rift at the destination point
if (!mod_pocketDim.blockRift.isBlockImmune(world, x, adjustedY, z))
NewDimData destinationDimension = PocketManager.createDimensionData(world);
DimLink reverse = destinationDimension.getLink(x, adjustedY, z);
DimLink link;
// Check whether the SRS is being used to restore one of its previous
// link pairs. In other words, the SRS is being used on a location
// that already has a link pointing to the SRS's source, with the
// intention of overwriting the source-side link to point there.
// Those benign redirection operations will be handled for free.
if (reverse != null && source.getPoint().equals(reverse.destination()))
{
world.setBlock(x, adjustedY, z, mod_pocketDim.blockRift.blockID);
// Only the source-to-destination link is needed.
link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.NORMAL, source.getOrientation());
destinationDimension.setLinkDestination(link, x, adjustedY, z);
}
//Try placing a rift at the source point, but check if its world is loaded first
else
{
// Check if the player is in creative mode,
// or if the player can pay with an Ender Pearl to create a rift.
if (!player.capabilities.isCreativeMode &&
!player.inventory.consumeInventoryItem(Item.enderPearl.itemID))
{
mod_pocketDim.sendChat(player, "You don't have any Ender Pearls!");
// I won't do this, but this is the chance to localize chat
// messages sent to the player; look at ChatMessageComponent
// and how MFR does it with items like the safari net launcher
return true;
}
// Create links connecting the two endpoints.
link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.NORMAL, source.getOrientation());
reverse = destinationDimension.createLink(x, adjustedY, z, LinkType.NORMAL, orientation);
destinationDimension.setLinkDestination(link, x, adjustedY, z);
sourceDimension.setLinkDestination(reverse, source.getX(), source.getY(), source.getZ());
// Try placing a rift at the destination point
mod_pocketDim.blockRift.tryPlacingRift(world, x, adjustedY, z);
}
// Try placing a rift at the source point
// We don't need to check if sourceWorld is null - that's already handled.
World sourceWorld = DimensionManager.getWorld(sourceDimension.id());
if (sourceWorld != null &&
!mod_pocketDim.blockRift.isBlockImmune(sourceWorld, source.getX(), source.getY(), source.getZ()))
{
sourceWorld.setBlock(source.getX(), source.getY(), source.getZ(), mod_pocketDim.blockRift.blockID);
}
if (!player.capabilities.isCreativeMode)
{
player.inventory.consumeInventoryItem(mod_pocketDim.itemStableFabric.itemID);
}
mod_pocketDim.sendChat(player,"Rift Created");
world.playSoundAtEntity(player,"mods.DimDoors.sfx.riftEnd", 0.6f, 1);
mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
mod_pocketDim.sendChat(player, "Rift Created");
world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftEnd", 0.6f, 1);
}
else
{
//The link signature has not been used. Store its current target as the first location.
setSource(stack, x, adjustedY, z, orientation, PocketManager.getDimensionData(world));
mod_pocketDim.sendChat(player,"Location Stored in Stabilized Rift Signature");
world.playSoundAtEntity(player,"mods.DimDoors.sfx.riftStart", 0.6f, 1);
// The link signature has not been used. Store its current target as the first location.
setSource(stack, x, adjustedY, z, orientation, PocketManager.createDimensionData(world));
mod_pocketDim.sendChat(player, "Location Stored in Stabilized Rift Signature");
world.playSoundAtEntity(player, "mods.DimDoors.sfx.riftStart", 0.6f, 1);
}
return true;
}
public static boolean useFromDispenser(ItemStack stack, World world, int x, int y, int z)
{
// Stabilized Rift Signatures can only be used from dispensers to restore
// a previous link pair. The operation would be free for a player, so
// dispensers can also perform it for free. Otherwise, the item does nothing.
if (world.isRemote)
{
return false;
}
// Adjust Y so the rift is at head level, depending on the presence of certain blocks
int adjustedY = adjustYForSpecialBlocks(world, x, y + 2, z);
Point4DOrientation source = getSource(stack);
// The SRS must have been initialized
if (source != null)
{
NewDimData sourceDimension = PocketManager.getDimensionData(source.getDimension());
NewDimData destinationDimension = PocketManager.createDimensionData(world);
DimLink reverse = destinationDimension.getLink(x, adjustedY, z);
DimLink link;
// Check whether the SRS is being used to restore one of its previous
// link pairs. In other words, the SRS is being used on a location
// that already has a link pointing to the SRS's source, with the
// intention of overwriting the source-side link to point there.
if (reverse != null && source.getPoint().equals(reverse.destination()))
{
// Only the source-to-destination link is needed.
link = sourceDimension.createLink(source.getX(), source.getY(), source.getZ(), LinkType.NORMAL, source.getOrientation());
destinationDimension.setLinkDestination(link, x, adjustedY, z);
// Try placing a rift at the source point
// We don't need to check if sourceWorld is null - that's already handled.
World sourceWorld = DimensionManager.getWorld(sourceDimension.id());
mod_pocketDim.blockRift.tryPlacingRift(sourceWorld, source.getX(), source.getY(), source.getZ());
// This call doesn't seem to be working...
world.playSoundEffect(x + 0.5, adjustedY + 0.5, z + 0.5, "mods.DimDoors.sfx.riftEnd", 0.6f, 1);
return true;
}
}
return false;
}
/**
* allows items to add custom lines of information to the mouseover description
*/

View File

@@ -25,7 +25,7 @@ public class ItemUnstableDoor extends BaseItemDoor
}
@Override
protected BaseDimDoor getDoortoItemMapping()
protected BaseDimDoor getDoorBlock()
{
return (BaseDimDoor) mod_pocketDim.unstableDoor;
}

View File

@@ -28,7 +28,7 @@ public class ItemWarpDoor extends BaseItemDoor
}
@Override
protected BaseDimDoor getDoortoItemMapping()
protected BaseDimDoor getDoorBlock()
{
return (BaseDimDoor) mod_pocketDim.warpDoor;
}

View File

@@ -0,0 +1,42 @@
package StevenDimDoors.mod_pocketDim.items.behaviors;
import net.minecraft.block.BlockDispenser;
import net.minecraft.dispenser.BehaviorDefaultDispenseItem;
import net.minecraft.dispenser.IBlockSource;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.items.ItemStabilizedRiftSignature;
public class DispenserBehaviorStabilizedRS extends BehaviorDefaultDispenseItem
{
@Override
public ItemStack dispenseStack(IBlockSource dispenser, ItemStack stack)
{
// Search for a non-air block up to 3 blocks in front of a dispenser.
// If it's found, call ItemStabilizedRiftSignature.useFromDispenser().
int x = dispenser.getXInt();
int y = dispenser.getYInt();
int z = dispenser.getZInt();
EnumFacing facing = BlockDispenser.getFacing(dispenser.getBlockMetadata());
int dx = facing.getFrontOffsetX();
int dy = facing.getFrontOffsetY();
int dz = facing.getFrontOffsetZ();
World world = dispenser.getWorld();
for (int k = 1; k <= 3; k++)
{
x += dx;
y += dy;
z += dz;
if (!world.isAirBlock(x, y, z))
{
// Found a block. Activate the item.
ItemStabilizedRiftSignature.useFromDispenser(stack, world, x, y, z);
break;
}
}
// The item stack isn't modified
return stack;
}
}

View File

@@ -54,7 +54,7 @@ public class itemRiftRemover extends Item
int hx = hit.blockX;
int hy = hit.blockY;
int hz = hit.blockZ;
NewDimData dimension = PocketManager.getDimensionData(world);
NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(hx, hy, hz);
if (world.getBlockId(hx, hy, hz) == mod_pocketDim.blockRift.blockID && link != null &&
player.canPlayerEdit(hx, hy, hz, hit.sideHit, stack))
@@ -85,7 +85,7 @@ public class itemRiftRemover extends Item
y = hit.blockY;
z = hit.blockZ;
NewDimData dimension = PocketManager.getDimensionData(world);
NewDimData dimension = PocketManager.createDimensionData(world);
DimLink link = dimension.getLink(x, y, z);
if (world.getBlockId(x, y, z) == mod_pocketDim.blockRift.blockID && link != null &&
player.canPlayerEdit(x, y, z, side, stack))

View File

@@ -1,7 +1,6 @@
package StevenDimDoors.mod_pocketDim;
import java.io.File;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.creativetab.CreativeTabs;
@@ -19,10 +18,12 @@ import net.minecraftforge.common.MinecraftForge;
import StevenDimDoors.mod_pocketDim.blocks.BlockDimWall;
import StevenDimDoors.mod_pocketDim.blocks.BlockDimWallPerm;
import StevenDimDoors.mod_pocketDim.blocks.BlockDoorGold;
import StevenDimDoors.mod_pocketDim.blocks.BlockDoorQuartz;
import StevenDimDoors.mod_pocketDim.blocks.BlockGoldDimDoor;
import StevenDimDoors.mod_pocketDim.blocks.BlockLimbo;
import StevenDimDoors.mod_pocketDim.blocks.BlockRift;
import StevenDimDoors.mod_pocketDim.blocks.DimensionalDoor;
import StevenDimDoors.mod_pocketDim.blocks.PersonalDimDoor;
import StevenDimDoors.mod_pocketDim.blocks.TransTrapdoor;
import StevenDimDoors.mod_pocketDim.blocks.TransientDoor;
import StevenDimDoors.mod_pocketDim.blocks.UnstableDoor;
@@ -30,7 +31,6 @@ import StevenDimDoors.mod_pocketDim.blocks.WarpDoor;
import StevenDimDoors.mod_pocketDim.commands.CommandCreateDungeonRift;
import StevenDimDoors.mod_pocketDim.commands.CommandCreatePocket;
import StevenDimDoors.mod_pocketDim.commands.CommandCreateRandomRift;
import StevenDimDoors.mod_pocketDim.commands.CommandDeleteAllLinks;
import StevenDimDoors.mod_pocketDim.commands.CommandDeleteRifts;
import StevenDimDoors.mod_pocketDim.commands.CommandExportDungeon;
import StevenDimDoors.mod_pocketDim.commands.CommandListDungeons;
@@ -42,9 +42,12 @@ import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.helpers.ChunkLoaderHelper;
import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
import StevenDimDoors.mod_pocketDim.items.ItemBlockDimWall;
import StevenDimDoors.mod_pocketDim.items.ItemDDKey;
import StevenDimDoors.mod_pocketDim.items.ItemDimensionalDoor;
import StevenDimDoors.mod_pocketDim.items.ItemGoldDimDoor;
import StevenDimDoors.mod_pocketDim.items.ItemGoldDoor;
import StevenDimDoors.mod_pocketDim.items.ItemPersonalDoor;
import StevenDimDoors.mod_pocketDim.items.ItemQuartzDoor;
import StevenDimDoors.mod_pocketDim.items.ItemRiftBlade;
import StevenDimDoors.mod_pocketDim.items.ItemRiftSignature;
import StevenDimDoors.mod_pocketDim.items.ItemStabilizedRiftSignature;
@@ -53,25 +56,25 @@ import StevenDimDoors.mod_pocketDim.items.ItemUnstableDoor;
import StevenDimDoors.mod_pocketDim.items.ItemWarpDoor;
import StevenDimDoors.mod_pocketDim.items.ItemWorldThread;
import StevenDimDoors.mod_pocketDim.items.itemRiftRemover;
import StevenDimDoors.mod_pocketDim.ticking.CommonTickHandler;
import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator;
import StevenDimDoors.mod_pocketDim.ticking.FastRiftRegenerator;
import StevenDimDoors.mod_pocketDim.ticking.LimboDecay;
import StevenDimDoors.mod_pocketDim.ticking.LimboDecayScheduler;
import StevenDimDoors.mod_pocketDim.ticking.MobMonolith;
import StevenDimDoors.mod_pocketDim.ticking.RiftRegenerator;
import StevenDimDoors.mod_pocketDim.ticking.ServerTickHandler;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoor;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityDimDoorGold;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityRift;
import StevenDimDoors.mod_pocketDim.tileentities.TileEntityTransTrapdoor;
import StevenDimDoors.mod_pocketDim.util.DDLogger;
import StevenDimDoors.mod_pocketDim.util.l_systems.LSystem;
import StevenDimDoors.mod_pocketDim.world.BiomeGenLimbo;
import StevenDimDoors.mod_pocketDim.world.BiomeGenPocket;
import StevenDimDoors.mod_pocketDim.world.DDBiomeGenBase;
import StevenDimDoors.mod_pocketDim.world.LimboDecay;
import StevenDimDoors.mod_pocketDim.world.LimboProvider;
import StevenDimDoors.mod_pocketDim.world.PersonalPocketProvider;
import StevenDimDoors.mod_pocketDim.world.PocketProvider;
import StevenDimDoors.mod_pocketDim.world.gateways.GatewayGenerator;
import StevenDimDoors.mod_pocketDimClient.ClientPacketHandler;
import StevenDimDoors.mod_pocketDimClient.ClientTickHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.Mod.Instance;
@@ -99,16 +102,21 @@ serverPacketHandlerSpec =
@SidedPacketHandler(channels = {PacketConstants.CHANNEL_NAME}, packetHandler = ServerPacketHandler.class))
public class mod_pocketDim
{
public static final String version = "1.6.4-R2.2.3";
public static final String version = "@VERSION@";
public static final String modid = "dimdoors";
//TODO need a place to stick all these constants
public static final int NETHER_DIMENSION_ID = -1;
//need to clean up
@SidedProxy(clientSide = "StevenDimDoors.mod_pocketDimClient.ClientProxy", serverSide = "StevenDimDoors.mod_pocketDim.CommonProxy")
public static CommonProxy proxy;
@Instance("PocketDimensions")
public static mod_pocketDim instance = new mod_pocketDim();
@Instance(mod_pocketDim.modid)
public static mod_pocketDim instance;
public static Block quartzDoor;
public static Block personalDimDoor;
public static Block transientDoor;
public static Block warpDoor;
public static Block goldenDoor;
@@ -132,7 +140,10 @@ public class mod_pocketDim
public static Item itemRiftSignature;
public static Item itemStableFabric;
public static Item itemUnstableDoor;
public static Item itemStabilizedLinkSignature;
public static Item itemDDKey;
public static Item itemQuartzDoor;
public static Item itemPersonalDoor;
public static Item itemStabilizedRiftSignature;
public static BiomeGenBase limboBiome;
public static BiomeGenBase pocketBiome;
@@ -142,9 +153,13 @@ public class mod_pocketDim
public static DDProperties properties;
public static DDWorldProperties worldProperties;
public static CustomLimboPopulator spawner; //Added this field temporarily. Will be refactored out later.
public static FastRiftRegenerator fastRiftRegenerator;
public static RiftRegenerator riftRegenerator;
public static GatewayGenerator gatewayGenerator;
public static DeathTracker deathTracker;
private static ServerTickHandler serverTickHandler;
private static LimboDecayScheduler limboDecayScheduler;
private static LimboDecay limboDecay;
private static EventHookContainer hooks;
//TODO this is a temporary workaround for saving data
private String currrentSaveRootDirectory;
@@ -167,14 +182,13 @@ public class mod_pocketDim
@EventHandler
public void onPreInitialization(FMLPreInitializationEvent event)
{
instance = this;
//This should be the FIRST thing that gets done.
String path = event.getSuggestedConfigurationFile().getAbsolutePath().replace(modid, "DimDoors");
properties = DDProperties.initialize(new File(path));
//Now do other stuff
EventHookContainer hooks = new EventHookContainer(properties);
hooks = new EventHookContainer(properties);
MinecraftForge.EVENT_BUS.register(hooks);
MinecraftForge.TERRAIN_GEN_BUS.register(hooks);
}
@@ -182,31 +196,34 @@ public class mod_pocketDim
@EventHandler
public void onInitialization(FMLInitializationEvent event)
{
CommonTickHandler commonTickHandler = new CommonTickHandler();
TickRegistry.registerTickHandler(new ClientTickHandler(), Side.CLIENT);
TickRegistry.registerTickHandler(commonTickHandler, Side.SERVER);
//MonolithSpawner should be initialized before any provider instances are created
//Register the other regular tick receivers as well
spawner = new CustomLimboPopulator(commonTickHandler, properties);
new RiftRegenerator(commonTickHandler); //No need to store the reference
LimboDecay decay = new LimboDecay(commonTickHandler, properties);
fastRiftRegenerator = new FastRiftRegenerator(commonTickHandler);
// Initialize ServerTickHandler instance
serverTickHandler = new ServerTickHandler();
TickRegistry.registerTickHandler(serverTickHandler, Side.SERVER);
// Initialize LimboDecay instance: required for BlockLimbo
limboDecay = new LimboDecay(properties);
// Initialize blocks and items
transientDoor = new TransientDoor(properties.TransientDoorID, Material.iron, properties).setHardness(1.0F) .setUnlocalizedName("transientDoor");
goldenDimensionalDoor = new BlockGoldDimDoor(properties.GoldenDimensionalDoorID, Material.iron, properties).setHardness(1.0F) .setUnlocalizedName("dimDoorGold");
quartzDoor = new BlockDoorQuartz(properties.QuartzDoorID, Material.rock).setHardness(0.1F).setUnlocalizedName("doorQuartz");
personalDimDoor = new PersonalDimDoor(properties.PersonalDimDoorID, Material.rock,properties).setHardness(0.1F).setUnlocalizedName("dimDoorPersonal");
goldenDoor = new BlockDoorGold(properties.GoldenDoorID, Material.iron).setHardness(0.1F).setUnlocalizedName("doorGold");
blockDimWall = new BlockDimWall(properties.FabricBlockID, 0, Material.iron).setLightValue(1.0F).setHardness(0.1F).setUnlocalizedName("blockDimWall");
blockDimWallPerm = (new BlockDimWallPerm(properties.PermaFabricBlockID, 0, Material.iron)).setLightValue(1.0F).setBlockUnbreakable().setResistance(6000000.0F).setUnlocalizedName("blockDimWallPerm");
warpDoor = new WarpDoor(properties.WarpDoorID, Material.wood, properties).setHardness(1.0F) .setUnlocalizedName("dimDoorWarp");
blockRift = (BlockRift) (new BlockRift(properties.RiftBlockID, 0, Material.air, properties).setHardness(1.0F) .setUnlocalizedName("rift"));
blockLimbo = new BlockLimbo(properties.LimboBlockID, 15, Material.iron, properties.LimboDimensionID, decay).setHardness(.2F).setUnlocalizedName("BlockLimbo").setLightValue(.0F);
blockLimbo = new BlockLimbo(properties.LimboBlockID, 15, Material.iron, properties.LimboDimensionID, limboDecay).setHardness(.2F).setUnlocalizedName("BlockLimbo").setLightValue(.0F);
unstableDoor = (new UnstableDoor(properties.UnstableDoorID, Material.iron, properties).setHardness(.2F).setUnlocalizedName("chaosDoor").setLightValue(.0F) );
dimensionalDoor = (DimensionalDoor) (new DimensionalDoor(properties.DimensionalDoorID, Material.iron, properties).setHardness(1.0F).setResistance(2000.0F) .setUnlocalizedName("dimDoor"));
transTrapdoor = (TransTrapdoor) (new TransTrapdoor(properties.TransTrapdoorID, Material.wood).setHardness(1.0F) .setUnlocalizedName("dimHatch"));
itemGoldenDoor = (new ItemGoldDoor(properties.GoldenDoorID, Material.wood)).setUnlocalizedName("itemGoldDoor");
itemDDKey = (new ItemDDKey(properties.DDKeyItemID)).setUnlocalizedName("itemDDKey");
itemQuartzDoor = (new ItemQuartzDoor(properties.QuartzDoorID, Material.rock)).setUnlocalizedName("itemQuartzDoor");
itemPersonalDoor = (new ItemPersonalDoor(properties.PersonalDimDoorID, Material.rock, (ItemDoor)this.itemQuartzDoor)).setUnlocalizedName("itemQuartzDimDoor");
itemGoldenDoor = (new ItemGoldDoor(properties.GoldenDoorItemID, Material.wood)).setUnlocalizedName("itemGoldDoor");
itemGoldenDimensionalDoor = (new ItemGoldDimDoor(properties.GoldenDimensionalDoorItemID, Material.iron, (ItemDoor)this.itemGoldenDoor)).setUnlocalizedName("itemGoldDimDoor");
itemDimensionalDoor = (ItemDimensionalDoor) (new ItemDimensionalDoor(properties.DimensionalDoorItemID, Material.iron, (ItemDoor)Item.doorIron)).setUnlocalizedName("itemDimDoor");
itemWarpDoor = (new ItemWarpDoor(properties.WarpDoorItemID, Material.wood,(ItemDoor)Item.doorWood)).setUnlocalizedName("itemDimDoorWarp");
@@ -215,7 +232,7 @@ public class mod_pocketDim
itemStableFabric = (new ItemStableFabric(properties.StableFabricItemID, 0)).setUnlocalizedName("itemStableFabric");
itemUnstableDoor = (new ItemUnstableDoor(properties.UnstableDoorItemID, Material.iron, null)).setUnlocalizedName("itemChaosDoor");
itemRiftBlade = (new ItemRiftBlade(properties.RiftBladeItemID, properties)).setUnlocalizedName("ItemRiftBlade");
itemStabilizedLinkSignature = (new ItemStabilizedRiftSignature(properties.StabilizedRiftSignatureItemID)).setUnlocalizedName("itemStabilizedRiftSig");
itemStabilizedRiftSignature = (new ItemStabilizedRiftSignature(properties.StabilizedRiftSignatureItemID)).setUnlocalizedName("itemStabilizedRiftSig");
itemWorldThread = (new ItemWorldThread(properties.WorldThreadItemID)).setUnlocalizedName("itemWorldThread");
// Check if other biomes have been registered with the same IDs we want. If so, crash Minecraft
@@ -226,6 +243,8 @@ public class mod_pocketDim
mod_pocketDim.limboBiome = (new BiomeGenLimbo(properties.LimboBiomeID));
mod_pocketDim.pocketBiome = (new BiomeGenPocket(properties.PocketBiomeID));
GameRegistry.registerBlock(quartzDoor, "Quartz Door");
GameRegistry.registerBlock(personalDimDoor, "Personal Dimensional Door");
GameRegistry.registerBlock(goldenDoor, "Golden Door");
GameRegistry.registerBlock(goldenDimensionalDoor, "Golden Dimensional Door");
GameRegistry.registerBlock(unstableDoor, "Unstable Door");
@@ -243,6 +262,8 @@ public class mod_pocketDim
throw new IllegalStateException("There is a provider ID conflict between PocketProvider from Dimensional Doors and another provider type. Fix your configuration!");
if (!DimensionManager.registerProviderType(properties.LimboProviderID, LimboProvider.class, false))
throw new IllegalStateException("There is a provider ID conflict between LimboProvider from Dimensional Doors and another provider type. Fix your configuration!");
if (!DimensionManager.registerProviderType(properties.PersonalPocketProviderID, PersonalPocketProvider.class, false))
throw new IllegalStateException("There is a provider ID conflict between PersonalPocketProvider from Dimensional Doors and another provider type. Fix your configuration!");
DimensionManager.registerDimension(properties.LimboDimensionID, properties.LimboProviderID);
@@ -262,19 +283,24 @@ public class mod_pocketDim
LanguageRegistry.addName(itemRiftSignature, "Rift Signature");
LanguageRegistry.addName(itemGoldenDoor, "Golden Door");
LanguageRegistry.addName(itemGoldenDimensionalDoor, "Golden Dimensional Door");
LanguageRegistry.addName(itemStabilizedLinkSignature, "Stabilized Rift Signature");
LanguageRegistry.addName(itemStabilizedRiftSignature, "Stabilized Rift Signature");
LanguageRegistry.addName(itemRiftRemover, "Rift Remover");
LanguageRegistry.addName(itemStableFabric, "Stable Fabric");
LanguageRegistry.addName(itemUnstableDoor, "Unstable Door");
LanguageRegistry.addName(itemDimensionalDoor, "Dimensional Door");
LanguageRegistry.addName(itemRiftBlade, "Rift Blade");
LanguageRegistry.addName(itemWorldThread, "World Thread");
LanguageRegistry.addName(itemDDKey, "Rift Key");
LanguageRegistry.addName(itemQuartzDoor, "Quartz Door");
LanguageRegistry.addName(itemPersonalDoor, "Personal Dimensional Door");
/**
* Add names for multiblock inventory item
*/
LanguageRegistry.addName(new ItemStack(blockDimWall, 1, 0), "Fabric of Reality");
LanguageRegistry.addName(new ItemStack(blockDimWall, 1, 1), "Ancient Fabric");
LanguageRegistry.addName(new ItemStack(blockDimWall, 1, 2), "Altered Fabric");
LanguageRegistry.instance().addStringLocalization("itemGroup.dimDoorsCustomTab", "en_US", "Dimensional Doors Items");
@@ -286,9 +312,12 @@ public class mod_pocketDim
EntityRegistry.registerModEntity(MobMonolith.class, "Monolith", properties.MonolithEntityID, this, 70, 1, true);
EntityList.IDtoClassMapping.put(properties.MonolithEntityID, MobMonolith.class);
EntityList.entityEggs.put(properties.MonolithEntityID, new EntityEggInfo(properties.MonolithEntityID, 0, 0xffffff));
LanguageRegistry.instance().addStringLocalization("entity.DimDoors.Obelisk.name", "Monolith");
LanguageRegistry.instance().addStringLocalization("entity.dimdoors.Monolith.name", "Monolith");
CraftingManager.registerRecipes(properties);
CraftingManager.registerDispenserBehaviors();
GameRegistry.registerCraftingHandler(new CraftingManager());
DungeonHelper.initialize();
gatewayGenerator = new GatewayGenerator(properties);
GameRegistry.registerWorldGenerator(mod_pocketDim.gatewayGenerator);
@@ -297,6 +326,36 @@ public class mod_pocketDim
DDLoot.registerInfo(properties);
proxy.loadTextures();
proxy.registerRenderers();
LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 4);
LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 5);
// LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 6); //degenerate
LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 7);
// LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 8);
// LSystem.generateLSystem("terdragon", LSystem.TERDRAGON, 9);
// LSystem.generateLSystem("vortex", LSystem.VORTEX, 8);
LSystem.generateLSystem("vortex", LSystem.VORTEX, 9);
LSystem.generateLSystem("vortex", LSystem.VORTEX, 10);
LSystem.generateLSystem("vortex", LSystem.VORTEX, 11);
// LSystem.generateLSystem("vortex", LSystem.VORTEX, 12);
LSystem.generateLSystem("twindragon", LSystem.TWINDRAGON, 7);
LSystem.generateLSystem("twindragon", LSystem.TWINDRAGON, 8);
LSystem.generateLSystem("twindragon", LSystem.TWINDRAGON, 9);
LSystem.generateLSystem("twindragon", LSystem.TWINDRAGON, 10);
// LSystem.generateLSystem("twindragon", LSystem.TWINDRAGON, 11);
LSystem.generateLSystem("dragon", LSystem.DRAGON, 8);
LSystem.generateLSystem("dragon", LSystem.DRAGON, 9);
LSystem.generateLSystem("dragon", LSystem.DRAGON, 10);
LSystem.generateLSystem("dragon", LSystem.DRAGON, 11);
// LSystem.generateLSystem("dragon", LSystem.DRAGON, 12);
// LSystem.generateLSystem("dragon", LSystem.DRAGON, 13);
}
@EventHandler
@@ -317,7 +376,14 @@ public class mod_pocketDim
deathTracker.writeToFile();
deathTracker = null;
worldProperties = null;
this.currrentSaveRootDirectory=null;
currrentSaveRootDirectory = null;
// Unregister all tick receivers from serverTickHandler to avoid leaking
// scheduled tasks between single-player game sessions
serverTickHandler.unregisterReceivers();
spawner = null;
riftRegenerator = null;
limboDecayScheduler = null;
}
catch (Exception e)
{
@@ -332,9 +398,17 @@ public class mod_pocketDim
// Load the config file that's specific to this world
worldProperties = new DDWorldProperties(new File(currrentSaveRootDirectory + "/DimensionalDoors/DimDoorsWorld.cfg"));
// Initialize a new DeathTracker
deathTracker = new DeathTracker(currrentSaveRootDirectory + "/DimensionalDoors/data/deaths.txt");
// Register regular tick receivers
// CustomLimboPopulator should be initialized before any provider instances are created
spawner = new CustomLimboPopulator(serverTickHandler, properties);
riftRegenerator = new RiftRegenerator(serverTickHandler, blockRift);
limboDecayScheduler = new LimboDecayScheduler(serverTickHandler, limboDecay);
hooks.setSessionFields(worldProperties, riftRegenerator);
}
@EventHandler
@@ -345,19 +419,14 @@ public class mod_pocketDim
event.registerServerCommand( CommandCreateDungeonRift.instance() );
event.registerServerCommand( CommandListDungeons.instance() );
event.registerServerCommand( CommandCreateRandomRift.instance() );
event.registerServerCommand( CommandDeleteAllLinks.instance() );
//CommandDeleteDimensionData.instance().register(event);
event.registerServerCommand( CommandDeleteRifts.instance() );
event.registerServerCommand( CommandExportDungeon.instance() );
//CommandPrintDimensionData.instance().register(event);
//CommandPruneDimensions.instance().register(event);
event.registerServerCommand( CommandCreatePocket.instance() );
event.registerServerCommand( CommandTeleportPlayer.instance() );
try
{
ChunkLoaderHelper.loadChunkForcedWorlds(event);
ChunkLoaderHelper.loadForcedChunkWorlds(event);
}
catch (Exception e)
{

View File

@@ -7,12 +7,13 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkTypes;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.dungeon.DungeonData;
@@ -20,7 +21,6 @@ import StevenDimDoors.mod_pocketDim.helpers.DungeonHelper;
import StevenDimDoors.mod_pocketDim.util.DDLogger;
import StevenDimDoors.mod_pocketDim.util.FileFilters;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import com.google.common.io.Files;
public class DDSaveHandler
@@ -59,6 +59,15 @@ public class DDSaveHandler
PocketManager.createAndRegisterBlacklist(blacklist);
}
// Load the personal pockets mapping
File personalPocketMap = new File(basePath+"personalPockets.txt");
HashMap<String, Integer> ppMap = new HashMap<String, Integer>();
if(personalPocketMap.exists())
{
PersonalPocketMappingProcessor ppMappingProcessor = new PersonalPocketMappingProcessor();
ppMap = readPersonalPocketsMapping(personalPocketMap,ppMappingProcessor);
}
// List any dimension data files and read each dimension
DimDataProcessor reader = new DimDataProcessor();
HashMap<Integer, PackedDimData> packedDims = new HashMap<Integer, PackedDimData>();
@@ -82,7 +91,17 @@ public class DDSaveHandler
{
linksToUnpack.addAll(packedDim.Links);
}
return unpackDimData(packedDims) && unpackLinkData(linksToUnpack);
unpackDimData(packedDims);
unpackLinkData(linksToUnpack);
HashMap<String, NewDimData> personalPocketsMap = new HashMap<String, NewDimData>();
for(Entry<String, Integer> pair : ppMap.entrySet())
{
personalPocketsMap.put(pair.getKey(), PocketManager.getDimensionData(pair.getValue()));
}
PocketManager.setPersonalPocketsMapping(personalPocketsMap);
return true;
}
/**
@@ -139,7 +158,7 @@ public class DDSaveHandler
}
if(isMissing)
{
packedDim=(new PackedDimData(packedDim.ID, packedDim.Depth, packedDim.PackDepth, packedDim.ParentID, packedDim.RootID, packedDim.Orientation, packedDim.IsDungeon, packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, children, packedDim.Links, packedDim.Tails));
packedDim=(new PackedDimData(packedDim.ID, packedDim.Depth, packedDim.PackDepth, packedDim.ParentID, packedDim.RootID, packedDim.Orientation, DimensionType.getTypeFromIndex(packedDim.DimensionType), packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, children, packedDim.Links, packedDim.Tails));
packedDims.put(packedDim.ID, packedDim);
}
return children;
@@ -157,12 +176,12 @@ public class DDSaveHandler
{
ArrayList<Integer> fosterChildren = new ArrayList<Integer>();
fosterChildren.add(packedDim.ID);
DimensionType type = DimensionType.getTypeFromIndex(packedDim.DimensionType);
//fix pockets without parents
if(!packedDims.containsKey(packedDim.ParentID))
{
//Fix the orphan by changing its root to its parent, re-connecting it to the list
packedDim=(new PackedDimData(packedDim.ID, 1, packedDim.PackDepth, packedDim.RootID, packedDim.RootID, packedDim.Orientation, packedDim.IsDungeon, packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, packedDim.ChildIDs, packedDim.Links, packedDim.Tails));
packedDim=(new PackedDimData(packedDim.ID, 1, packedDim.PackDepth, packedDim.RootID, packedDim.RootID, packedDim.Orientation,type, packedDim.IsFilled, packedDim.DungeonData, packedDim.Origin, packedDim.ChildIDs, packedDim.Links, packedDim.Tails));
packedDims.put(packedDim.ID, packedDim);
}
//fix pockets whose parents have forgotten about them
@@ -171,7 +190,7 @@ public class DDSaveHandler
{
//find the root, and fix it by adding the orphan's ID to its children
fosterChildren.addAll(fosterParent.ChildIDs);
fosterParent=(new PackedDimData(fosterParent.ID, fosterParent.Depth, fosterParent.PackDepth, fosterParent.ParentID, fosterParent.RootID, fosterParent.Orientation, fosterParent.IsDungeon, fosterParent.IsFilled, fosterParent.DungeonData, fosterParent.Origin, fosterChildren, fosterParent.Links, fosterParent.Tails));
fosterParent=(new PackedDimData(fosterParent.ID, fosterParent.Depth, fosterParent.PackDepth, fosterParent.ParentID, fosterParent.RootID, fosterParent.Orientation, type, fosterParent.IsFilled, fosterParent.DungeonData, fosterParent.Origin, fosterChildren, fosterParent.Links, fosterParent.Tails));
packedDims.put(fosterParent.ID, fosterParent);
}
@@ -190,18 +209,14 @@ public class DDSaveHandler
if(packedLink.parent.equals(fakePoint))
{
NewDimData data = PocketManager.getDimensionData(packedLink.source.getDimension());
int linkType = packedLink.tail.linkType;
LinkType linkType = LinkType.getLinkTypeFromIndex(packedLink.tail.linkType);
if((linkType < LinkTypes.ENUM_MIN || linkType > LinkTypes.ENUM_MAX) && linkType != LinkTypes.CLIENT_SIDE)
{
linkType = LinkTypes.NORMAL;
}
DimLink link = data.createLink(packedLink.source, linkType, packedLink.orientation);
DimLink link = data.createLink(packedLink.source, linkType, packedLink.orientation, packedLink.lock);
Point4D destination = packedLink.tail.destination;
if(destination!=null)
{
PocketManager.getDimensionData(destination.getDimension()).setDestination(link, destination.getX(),destination.getY(),destination.getZ());
PocketManager.createDimensionDataDangerously(destination.getDimension()).setLinkDestination(link, destination.getX(),destination.getY(),destination.getZ());
}
unpackedLinks.add(packedLink);
}
@@ -213,10 +228,10 @@ public class DDSaveHandler
{
for(PackedLinkData packedLink : linksToUnpack)
{
NewDimData data = PocketManager.getDimensionData(packedLink.source.getDimension());
NewDimData data = PocketManager.createDimensionDataDangerously(packedLink.source.getDimension());
if(data.getLink(packedLink.parent)!=null)
{
data.createChildLink(packedLink.source.getX(), packedLink.source.getY(), packedLink.source.getZ(), data.getLink(packedLink.parent));
data.createChildLink(packedLink.source, data.getLink(packedLink.parent), packedLink.lock);
}
unpackedLinks.add(packedLink);
}
@@ -224,7 +239,7 @@ public class DDSaveHandler
}
return true;
}
private static PackedDimData readDimension(File dataFile, DimDataProcessor reader)
{
@@ -270,6 +285,9 @@ public class DDSaveHandler
// Create and write the blackList
writeBlacklist(blacklist, savePath);
//create and write personal pocket mapping
writePersonalPocketMap(PocketManager.getPersonalPocketMapping(), savePath);
// Write the dimension save data
boolean succeeded = true;
DimDataProcessor writer = new DimDataProcessor();
@@ -312,6 +330,32 @@ public class DDSaveHandler
}
}
private static boolean writePersonalPocketMap(HashMap<String, NewDimData> hashMap, String savePath)
{
try
{
HashMap<String, Integer> ppMap = new HashMap<String, Integer>();
for(Entry<String, NewDimData> pair : hashMap.entrySet())
{
ppMap.put(pair.getKey(), pair.getValue().id());
}
PersonalPocketMappingProcessor writer = new PersonalPocketMappingProcessor();
File tempFile = new File(savePath + "/personalPockets.tmp");
File saveFile = new File(savePath + "/personalPockets.txt");
writer.writeToFile(tempFile, ppMap);
saveFile.delete();
tempFile.renameTo(saveFile);
return true;
}
catch (Exception e)
{
System.err.println("Could not save personal pockets mapping. The following error occurred:");
printException(e, true);
return false;
}
}
private static boolean writeDimension(IPackable<PackedDimData> dimension, DimDataProcessor writer, String basePath, String backupPath)
{
try
@@ -378,7 +422,6 @@ public class DDSaveHandler
public static List<Integer> readBlacklist(File blacklistFile, BlacklistProcessor reader)
{
try
{
return reader.readFromFile(blacklistFile);
@@ -388,6 +431,18 @@ public class DDSaveHandler
e.printStackTrace();
return null;
}
}
public static HashMap<String,Integer> readPersonalPocketsMapping(File ppMap, PersonalPocketMappingProcessor reader)
{
try
{
return reader.readFromFile(ppMap);
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
}
}

View File

@@ -4,33 +4,60 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import StevenDimDoors.mod_pocketDim.Point3D;
import java.util.HashMap;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.util.BaseConfigurationProcessor;
import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.util.JSONValidator;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
public class DimDataProcessor extends BaseConfigurationProcessor<PackedDimData>
{
//The name of the version ID where it is stored in the JSON
public final String JSON_VERSION_PROPERTY_NAME = "SAVE_DATA_VERSION_ID_INSTANCE";
//mapping of version IDs to their corresponding schema. Prevents reloading of schema during save/load cycles
private HashMap<Integer, JsonObject> SAVE_DATA_SCHEMA;
//The parser used to read in the JSON Files
private static final JsonParser jsonParser = new JsonParser();
//The directory for JSON schema files
public static final String BASE_SCHEMA_PATH = "/assets/dimdoors/text/";
/**
* Need to manually include a schema defintion for every save file version currently supported
*/
public DimDataProcessor()
{
SAVE_DATA_SCHEMA = new HashMap<Integer, JsonObject>();
//Load the old schema/s
SAVE_DATA_SCHEMA.put(982405775, loadSchema(BASE_SCHEMA_PATH+"Dim_Data_Schema_v982405775.json"));
//load the schema representing the current save data format
SAVE_DATA_SCHEMA.put(PackedDimData.SAVE_DATA_VERSION_ID, loadSchema(BASE_SCHEMA_PATH+"Dim_Data_Schema_v1-0-0.json"));
}
@Override
public PackedDimData readFromStream(InputStream inputStream)
throws ConfigurationProcessingException
{
try
{
//read in the json save file represeting a single dimension
JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));
PackedDimData data = this.createDImDataFromJson(reader);
PackedDimData data = this.readDimDataJson(reader);
reader.close();
return data;
}
catch (IOException e)
catch (Exception e)
{
e.printStackTrace();
throw new ConfigurationProcessingException("Could not read packedDimData");
@@ -42,259 +69,143 @@ public class DimDataProcessor extends BaseConfigurationProcessor<PackedDimData>
public void writeToStream(OutputStream outputStream, PackedDimData data)
throws ConfigurationProcessingException
{
/** Print out dimData using the GSON built in serializer. I dont feel bad doing this because
* 1- We can read it
* 2- We are manually reading the data in.
* 3- The error messages tell us exactly where its failing, so its easy to fix
*/
//create a json object from a packedDimData instance
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.setPrettyPrinting().create();
gsonBuilder.setPrettyPrinting();
Gson gson = gsonBuilder.create();
JsonElement ele = gson.toJsonTree(data);
try
{
outputStream.write(gson.toJson(data).getBytes("UTF-8"));
//ensure our json object corresponds to our schema
JSONValidator.validate(getSaveDataSchema(ele.getAsJsonObject()), ele);
outputStream.write(gson.toJson(ele).getBytes("UTF-8"));
outputStream.close();
}
catch (IOException e)
catch (Exception e)
{
// not sure if this is kosher, we need it to explode, but not by throwing the IO exception.
throw new ConfigurationProcessingException("Incorrectly formatted save data");
}
throw new ConfigurationProcessingException("Could not access save data");
}
}
/**
* Nightmare method that takes a JsonReader pointed at a serialized instance of PackedDimData
* validates the save file against it's current version, then updates and validates it again if it needs it
* then it loads it
* @param reader
* @return
* @throws IOException
*/
public PackedDimData createDImDataFromJson(JsonReader reader) throws IOException
public PackedDimData readDimDataJson(JsonReader reader) throws IOException
{
int ID;
boolean IsDungeon;
boolean IsFilled;
int Depth;
int PackDepth;
int ParentID;
int RootID;
PackedDungeonData Dungeon = null;
Point3D Origin;
int Orientation;
List<Integer> ChildIDs;
List<PackedLinkData> Links;
List<PackedLinkTail> Tails = new ArrayList<PackedLinkTail>();
//read the save file into a Json element
JsonElement ele = jsonParser.parse(reader);
reader.beginObject();
//get the schema that corresponds to the save file's listed version number
JsonObject schema = this.getSaveDataSchema(ele.getAsJsonObject());
reader.nextName();
if (reader.nextLong() != PackedDimData.SAVE_DATA_VERSION_ID)
//validate the save file against its schema
JSONValidator.validate(schema, ele);
//handle updating old save data
ele = processSaveData(schema, ele.getAsJsonObject());
//convert the updated and verified json into an instance of PackedDimData
GsonBuilder gsonBuilder = new GsonBuilder();
return gsonBuilder.create().fromJson(ele, PackedDimData.class);
}
/**
* Gets the schema that corresponds to a version of our save data
* @param obj
* @return
* @throws IOException
*/
public JsonObject getSaveDataSchema(JsonObject obj)
{
JsonObject schema = this.SAVE_DATA_SCHEMA.get(obj.get(JSON_VERSION_PROPERTY_NAME).getAsInt());
if(schema == null)
{
throw new IOException("Save data version mismatch");
throw new IllegalStateException("Invalid save data version");
}
reader.nextName();
ID = reader.nextInt();
reader.nextName();
IsDungeon = reader.nextBoolean();
reader.nextName();
IsFilled = reader.nextBoolean();
reader.nextName();
Depth = reader.nextInt();
reader.nextName();
PackDepth = reader.nextInt();
reader.nextName();
ParentID=reader.nextInt();
reader.nextName();
RootID= reader.nextInt();
if(reader.nextName().equals("DungeonData"))
return schema;
}
/**
* Internally load the save data schema so we dont load them every single time we validate save data
* @param path
* @return
*/
private JsonObject loadSchema(String path)
{
InputStream in = this.getClass().getResourceAsStream(path);
JsonReader reader = new JsonReader(new InputStreamReader(in));
JsonObject schema = jsonParser.parse(reader).getAsJsonObject();
try
{
Dungeon = createDungeonDataFromJson(reader);
reader.nextName();
reader.close();
in.close();
}
catch (IOException e)
{
System.err.println("Could not load Json Save Data definitions");
e.printStackTrace();
throw new IllegalStateException("Could not load Json Save Data definitions");
}
Origin = createPointFromJson(reader);
reader.nextName();
Orientation = reader.nextInt();
reader.nextName();
ChildIDs = this.createIntListFromJson(reader);
reader.nextName();
Links = this.createLinksListFromJson(reader);
return new PackedDimData(ID, Depth, PackDepth, ParentID, RootID, Orientation, IsDungeon, IsFilled, Dungeon, Origin, ChildIDs, Links, Tails);
return schema;
}
private Point3D createPointFromJson(JsonReader reader) throws IOException
/**
* I use this method to update old save data files to the new format before actually loading them.
* @return
*/
public JsonObject processSaveData(JsonObject schema, JsonObject save)
{
reader.beginObject();
int incomingSaveVersionID = save.get(JSON_VERSION_PROPERTY_NAME).getAsInt();
reader.nextName();
int x = reader.nextInt();
reader.nextName();
int y = reader.nextInt();
reader.nextName();
int z = reader.nextInt();
reader.endObject();
return new Point3D(x,y,z);
}
private Point4D createPoint4DFromJson(JsonReader reader) throws IOException
{
reader.beginObject();
reader.nextName();
int x = reader.nextInt();
reader.nextName();
int y = reader.nextInt();
reader.nextName();
int z = reader.nextInt();
reader.nextName();
int dimension = reader.nextInt();
reader.endObject();
return new Point4D(x,y,z,dimension);
}
private List<Integer> createIntListFromJson(JsonReader reader) throws IOException
{
List<Integer> list = new ArrayList<Integer>();
reader.beginArray();
while (reader.peek() != JsonToken.END_ARRAY)
// Handle save data versions that are current
if(incomingSaveVersionID == PackedDimData.SAVE_DATA_VERSION_ID)
{
list.add(reader.nextInt());
JSONValidator.validate(this.getSaveDataSchema(save), save);
return save;
}
// Handle save data versions that are older, starting with the random one.
// We have to
if(incomingSaveVersionID== 982405775)
{
DimensionType type;
}
reader.endArray();
return list;
}
private List<PackedLinkData> createLinksListFromJson(JsonReader reader) throws IOException
{
List<PackedLinkData> list = new ArrayList<PackedLinkData>();
reader.beginArray();
while (reader.peek() != JsonToken.END_ARRAY)
{
list.add(createLinkDataFromJson(reader));
}
reader.endArray();
return list;
}
private PackedLinkData createLinkDataFromJson(JsonReader reader) throws IOException
{
Point4D source;
Point3D parent;
PackedLinkTail tail;
int orientation;
List<Point3D> children = new ArrayList<Point3D>();
reader.beginObject();
reader.nextName();
source = this.createPoint4DFromJson(reader);
reader.nextName();
parent = this.createPointFromJson(reader);
reader.nextName();
tail = this.createLinkTailFromJson(reader);
reader.nextName();
orientation = reader.nextInt();
reader.nextName();
reader.beginArray();
while (reader.peek() != JsonToken.END_ARRAY)
{
children.add(this.createPointFromJson(reader));
}
reader.endArray();
reader.endObject();
return new PackedLinkData(source, parent, tail, orientation, children);
}
private PackedDungeonData createDungeonDataFromJson(JsonReader reader) throws IOException
{
int Weight;
boolean IsOpen;
boolean IsInternal;
String SchematicPath;
String SchematicName;
String DungeonTypeName;
String DungeonPackName;
reader.beginObject();
@SuppressWarnings("unused")
JsonToken test = reader.peek();
if(reader.peek() == JsonToken.END_OBJECT)
{
return null;
//see if the dim is a pocket
if(save.get("RootID").getAsInt() != save.get("ID").getAsInt())
{
if(save.get("IsDungeon").getAsBoolean())
{
type = DimensionType.DUNGEON;
}
else
{
type = DimensionType.POCKET;
}
}
else
{
type = DimensionType.ROOT;
}
save.remove("IsDungeon");
save.addProperty("DimensionType",type.index);
save.remove(this.JSON_VERSION_PROPERTY_NAME);
//Need to hardcode the version number here, so if we change the current version then this still updates to the proper version
save.addProperty(this.JSON_VERSION_PROPERTY_NAME, 100);
}
reader.nextName();
Weight=reader.nextInt();
reader.nextName();
IsOpen=reader.nextBoolean();
reader.nextName();
IsInternal=reader.nextBoolean();
reader.nextName();
SchematicPath=reader.nextString();
reader.nextName();
SchematicName=reader.nextString();
reader.nextName();
DungeonTypeName=reader.nextString();
reader.nextName();
DungeonPackName=reader.nextString();
reader.endObject();
return new PackedDungeonData(Weight, IsOpen, IsInternal, SchematicPath, SchematicName, DungeonTypeName, DungeonPackName);
}
private PackedLinkTail createLinkTailFromJson(JsonReader reader) throws IOException
{
Point4D destination = null;
int linkType;
reader.beginObject();
reader.nextName();
@SuppressWarnings("unused")
JsonToken test = reader.peek();
if (reader.peek() == JsonToken.BEGIN_OBJECT)
{
destination = this.createPoint4DFromJson(reader);
reader.nextName();
}
linkType = reader.nextInt();
reader.endObject();
return new PackedLinkTail(destination, linkType);
return processSaveData(this.getSaveDataSchema(save), save);
}
}

View File

@@ -2,17 +2,16 @@ package StevenDimDoors.mod_pocketDim.saving;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import StevenDimDoors.mod_pocketDim.DimData;
import StevenDimDoors.mod_pocketDim.LinkData;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.ObjectSaveInputStream;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class OldSaveImporter
@@ -39,35 +38,83 @@ public class OldSaveImporter
return;
}
//build the child list
HashMap<Integer, ArrayList<Integer>> parentChildMapping = new HashMap<Integer, ArrayList<Integer>>();
for(DimData data : dimMap.values())
{
if(data.isPocket)
{
LinkData link = data.exitDimLink;
if(parentChildMapping.containsKey(link.destDimID))
{
parentChildMapping.get(link.destDimID).add(data.dimID);
}
else
{
parentChildMapping.put(link.destDimID, new ArrayList<Integer>());
parentChildMapping.get(link.destDimID).add(data.dimID);
}
parentChildMapping.remove(data.dimID);
}
}
for(DimData data : dimMap.values())
{
List<PackedLinkData> newPackedLinkData = new ArrayList<PackedLinkData>();
List<Integer> childDims = new ArrayList<Integer>();
List<Integer> childDims;
if(parentChildMapping.containsKey(data.dimID))
{
childDims =parentChildMapping.get(data.dimID);
}
else
{
childDims = new ArrayList<Integer>();
}
for(LinkData link : data.getLinksInDim())
{
Point4D source = new Point4D(link.locXCoord,link.locYCoord,link.locZCoord,link.locDimID);
Point4D destintion = new Point4D(link.destXCoord,link.destYCoord,link.destZCoord,link.destDimID);
PackedLinkTail tail = new PackedLinkTail(destintion, link.linkOrientation);
PackedLinkTail tail = new PackedLinkTail(destintion, LinkType.NORMAL);
List<Point3D> children = new ArrayList<Point3D>();
PackedLinkData newPackedLink = new PackedLinkData(source, new Point3D(-1,-1,-1), tail, link.linkOrientation,children);
PackedLinkData newPackedLink = new PackedLinkData(source, new Point3D(-1,-1,-1), tail, link.linkOrientation,children, null);
newPackedLinkData.add(newPackedLink);
allPackedLinks.add(newPackedLink);
}
PackedDimData dim;
DimensionType type;
PackedDimData dim = new PackedDimData(data.dimID, data.depth, data.depth, data.exitDimLink.locDimID, data.exitDimLink.locDimID, 0, data.dungeonGenerator!=null, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null);
if(data.isPocket)
{
if(data.dungeonGenerator!=null)
{
type = DimensionType.DUNGEON;
}
else
{
type = DimensionType.POCKET;
}
}
else
{
type = DimensionType.ROOT;
}
if(data.isPocket)
{
dim = new PackedDimData(data.dimID, data.depth, data.depth, data.exitDimLink.locDimID, data.exitDimLink.locDimID, 0, type, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null);
}
else
{
dim = new PackedDimData(data.dimID, data.depth, data.depth, data.dimID, data.dimID, 0, type, data.hasBeenFilled, null, new Point3D(0,64,0), childDims, newPackedLinkData, null);
}
newPackedDimData.put(dim.ID,dim);
DDSaveHandler.unpackDimData(newPackedDimData);
DDSaveHandler.unpackLinkData(allPackedLinks);
}
DDSaveHandler.unpackDimData(newPackedDimData);
DDSaveHandler.unpackLinkData(allPackedLinks);
}
}

View File

@@ -3,14 +3,15 @@ package StevenDimDoors.mod_pocketDim.saving;
import java.util.List;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
public class PackedDimData
{
// These fields will be public since this is a simple data container
public final static long SAVE_DATA_VERSION_ID = 982405775L;
public final static int SAVE_DATA_VERSION_ID = 100;
public final long SAVE_DATA_VERSION_ID_INSTANCE = SAVE_DATA_VERSION_ID;
public final int ID;
public final boolean IsDungeon;
public final int DimensionType;
public final boolean IsFilled;
public final int Depth;
public final int PackDepth;
@@ -26,7 +27,7 @@ public class PackedDimData
// FIXME Missing dungeon data, not sure how to include it
public PackedDimData(int id, int depth, int packDepth, int parentID, int rootID, int orientation,
boolean isDungeon, boolean isFilled,PackedDungeonData dungeonData, Point3D origin, List<Integer> childIDs, List<PackedLinkData> links,
DimensionType type, boolean isFilled,PackedDungeonData dungeonData, Point3D origin, List<Integer> childIDs, List<PackedLinkData> links,
List<PackedLinkTail> tails)
{
ID = id;
@@ -35,7 +36,7 @@ public class PackedDimData
ParentID = parentID;
RootID = rootID;
Orientation = orientation;
IsDungeon = isDungeon;
DimensionType = type.index;
IsFilled = isFilled;
DungeonData = dungeonData;
Origin = origin;
@@ -49,4 +50,6 @@ public class PackedDimData
{
return "ID= "+this.ID;
}
}

View File

@@ -3,6 +3,7 @@ package StevenDimDoors.mod_pocketDim.saving;
import java.util.List;
import StevenDimDoors.mod_pocketDim.Point3D;
import StevenDimDoors.mod_pocketDim.core.DDLock;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class PackedLinkData
@@ -12,13 +13,15 @@ public class PackedLinkData
public final PackedLinkTail tail;
public final int orientation;
public final List<Point3D> children;
public final DDLock lock;
public PackedLinkData(Point4D source, Point3D parent, PackedLinkTail tail, int orientation, List<Point3D> children)
public PackedLinkData(Point4D source, Point3D parent, PackedLinkTail tail, int orientation, List<Point3D> children, DDLock lock)
{
this.source=source;
this.parent=parent;
this.tail=tail;
this.orientation=orientation;
this.children=children;
this.lock = lock;
}
}

View File

@@ -1,5 +1,6 @@
package StevenDimDoors.mod_pocketDim.saving;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class PackedLinkTail
@@ -7,10 +8,10 @@ public class PackedLinkTail
public final Point4D destination;
public final int linkType;
public PackedLinkTail(Point4D destination, int linkType)
public PackedLinkTail(Point4D destination, LinkType linkType)
{
this.destination=destination;
this.linkType=linkType;
this.linkType=linkType.index;
}
}

View File

@@ -0,0 +1,79 @@
package StevenDimDoors.mod_pocketDim.saving;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import StevenDimDoors.mod_pocketDim.util.BaseConfigurationProcessor;
import StevenDimDoors.mod_pocketDim.util.ConfigurationProcessingException;
public class PersonalPocketMappingProcessor extends BaseConfigurationProcessor<HashMap<String, Integer>>
{
@Override
public HashMap<String, Integer> readFromStream(InputStream inputStream) throws ConfigurationProcessingException
{
try
{
JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));
HashMap<String, Integer> data = this.createPersonalPocketsMapFromJson(reader);
reader.close();
return data;
}
catch (IOException e)
{
e.printStackTrace();
throw new ConfigurationProcessingException("Could not read personal pocket mapping");
}
}
private HashMap<String, Integer> createPersonalPocketsMapFromJson(JsonReader reader) throws IOException
{
HashMap<String, Integer> ppMap;
ppMap = this.createMapFromJson(reader);
return ppMap;
}
private HashMap<String, Integer> createMapFromJson(JsonReader reader) throws IOException
{
HashMap<String, Integer> map = new HashMap<String, Integer>();
reader.beginObject();
while(reader.peek()!= JsonToken.END_OBJECT)
{
map.put(reader.nextName(), reader.nextInt());
}
reader.endObject();
return map;
}
@Override
public void writeToStream(OutputStream outputStream, HashMap<String, Integer> data) throws ConfigurationProcessingException
{
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.setPrettyPrinting().create();
try
{
outputStream.write(gson.toJson(data).getBytes("UTF-8"));
outputStream.close();
}
catch (IOException e)
{
// not sure if this is kosher, we need it to explode, but not by throwing the IO exception.
throw new ConfigurationProcessingException("Incorrectly formatted save data");
}
}
}

View File

@@ -70,6 +70,8 @@ public class BlockRotator
hasOrientations[mod_pocketDim.dimensionalDoor.blockID] = true;
hasOrientations[mod_pocketDim.warpDoor.blockID] = true;
hasOrientations[mod_pocketDim.goldenDimensionalDoor.blockID] = true;
hasOrientations[mod_pocketDim.personalDimDoor.blockID] = true;
}

View File

@@ -1,6 +1,5 @@
package StevenDimDoors.mod_pocketDim.ticking;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -31,7 +30,7 @@ public class CustomLimboPopulator implements IRegularTickReceiver {
{
this.properties = properties;
this.locations = new ConcurrentLinkedQueue<ChunkLocation>();
sender.registerForTicking(this, MONOLITH_SPAWNING_INTERVAL, false);
sender.registerReceiver(this, MONOLITH_SPAWNING_INTERVAL, false);
}
@Override
@@ -65,7 +64,7 @@ public class CustomLimboPopulator implements IRegularTickReceiver {
limboWorld = PocketManager.loadDimension(properties.LimboDimensionID);
}
placeMonolithsInLimbo(limboWorld, location.ChunkX, location.ChunkZ);
mod_pocketDim.instance.gatewayGenerator.generate(limboWorld.rand, location.ChunkX, location.ChunkZ,
mod_pocketDim.gatewayGenerator.generate(limboWorld.rand, location.ChunkX, location.ChunkZ,
limboWorld, limboWorld.getChunkProvider(), limboWorld.getChunkProvider());
}
else

View File

@@ -1,53 +0,0 @@
package StevenDimDoors.mod_pocketDim.ticking;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class FastRiftRegenerator implements IRegularTickReceiver {
private static final int RIFT_REGENERATION_INTERVAL = 10; //Regenerate scheduled rifts every 10 ticks
private static Random random = new Random();
private ArrayList<Point4D> locationsToRegen = new ArrayList<Point4D>();
public FastRiftRegenerator(IRegularTickSender sender)
{
sender.registerForTicking(this, RIFT_REGENERATION_INTERVAL, false);
}
@Override
public void notifyTick()
{
regenerateScheduledRifts();
}
public void regenerateScheduledRifts()
{
if (!locationsToRegen.isEmpty())
{
List<Integer> loadedWorlds = (List<Integer>) Arrays.asList(DimensionManager.getIDs());
for (Point4D point: locationsToRegen)
{
if (loadedWorlds.contains(point.getDimension()) && PocketManager.getLink(point) != null)
{
World world = DimensionManager.getWorld(point.getDimension());
mod_pocketDim.blockRift.regenerateRift(world, point.getX(), point.getY(), point.getZ(), random);
}
}
locationsToRegen.clear();
}
}
public void registerRiftForRegen(int x, int y, int z, int dimID)
{
this.locationsToRegen.add(new Point4D(x, y, z, dimID));
}
}

View File

@@ -3,6 +3,7 @@ package StevenDimDoors.mod_pocketDim.ticking;
public interface IRegularTickSender {
public void registerForTicking(IRegularTickReceiver receiver, int interval, boolean onTickStart);
public void registerReceiver(IRegularTickReceiver receiver, int interval, boolean onTickStart);
public void unregisterReceivers();
}

View File

@@ -0,0 +1,28 @@
package StevenDimDoors.mod_pocketDim.ticking;
import StevenDimDoors.mod_pocketDim.world.LimboDecay;
/**
* Handles scheduling of periodic fast Limbo decay operations.
*/
public class LimboDecayScheduler implements IRegularTickReceiver {
private static final int LIMBO_DECAY_INTERVAL = 10; //Apply fast decay every 10 ticks
private LimboDecay decay;
public LimboDecayScheduler(IRegularTickSender tickSender, LimboDecay decay)
{
this.decay = decay;
tickSender.registerReceiver(this, LIMBO_DECAY_INTERVAL, false);
}
/**
* Applies fast Limbo decay periodically.
*/
@Override
public void notifyTick()
{
decay.applyRandomFastDecay();
}
}

View File

@@ -2,22 +2,16 @@ package StevenDimDoors.mod_pocketDim.ticking;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.DataWatcher;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityFlying;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.monster.IMob;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeHooks;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
@@ -27,26 +21,31 @@ import StevenDimDoors.mod_pocketDim.world.PocketProvider;
public class MobMonolith extends EntityFlying implements IMob
{
public static final int MAX_AGGRO_RANGE = 35;
public static final int MAX_SOUND_COOLDOWN = 200;
public static final float MAX_AGGRO = 100;
public static final int TEXTURE_STATES = 18;
private static final short MAX_AGGRO = 250;
private static final short MAX_AGGRO_CAP = 100;
private static final short MIN_AGGRO_CAP = 25;
private static final int MAX_TEXTURE_STATE = 18;
private static final int MAX_SOUND_COOLDOWN = 200;
private static final int MAX_AGGRO_RANGE = 35;
private static final int AGGRO_WATCHER_INDEX = 16;
private static final float WIDTH = 3f;
private static final float HEIGHT = 3f;
private static final float EYE_HEIGHT = HEIGHT / 2;
public float pitchLevel;
public float aggro = 0;
private float soundTime = 0;
private byte textureState = 0;
private int aggroMax;
private short aggro = 0;
private int soundTime = 0;
private final short aggroCap;
private static DDProperties properties = null;
public MobMonolith(World par1World)
public MobMonolith(World world)
{
super(par1World);
this.setSize(3F, 3F);
this.noClip=true;
this.aggroMax = rand.nextInt(245)+200;
super(world);
this.setSize(WIDTH, HEIGHT);
this.noClip = true;
this.aggroCap = (short) MathHelper.getRandomIntegerInRange(this.rand, MIN_AGGRO_CAP, MAX_AGGRO_CAP);
if (properties == null)
properties = DDProperties.instance();
}
@@ -60,16 +59,19 @@ public class MobMonolith extends EntityFlying implements IMob
@Override
public boolean attackEntityFrom(DamageSource par1DamageSource, float par2)
{
if (par1DamageSource == DamageSource.inWall)
if (par1DamageSource != DamageSource.inWall)
{
this.posY = posY + 1;
}
else
{
this.aggro = this.aggroMax;
this.aggro = MAX_AGGRO;
}
return false;
}
@Override
public boolean canBreatheUnderwater()
{
return true;
}
@Override
public AxisAlignedBB getBoundingBox()
{
@@ -92,7 +94,7 @@ public class MobMonolith extends EntityFlying implements IMob
protected void applyEntityAttributes()
{
super.applyEntityAttributes();
this.getAttributeMap().getAttributeInstance(SharedMonsterAttributes.maxHealth).setAttribute(10);
this.getAttributeMap().getAttributeInstance(SharedMonsterAttributes.maxHealth).setAttribute(57005);
}
@Override
@@ -104,22 +106,15 @@ public class MobMonolith extends EntityFlying implements IMob
@Override
public float getEyeHeight()
{
return this.height +2F;
}
public void setEntityPosition(Entity entity, double x, double y, double z)
{
entity.lastTickPosX = entity.prevPosX = entity.posX = x;
entity.lastTickPosY = entity.prevPosY = entity.posY = y + entity.yOffset;
entity.lastTickPosZ = entity.prevPosZ = entity.posZ = z;
entity.setPosition(x, y, z);
return EYE_HEIGHT;
}
@Override
protected void entityInit()
{
super.entityInit();
this.dataWatcher.addObject(16, Byte.valueOf((byte)0));
// Add a short for the aggro level
this.dataWatcher.addObject(AGGRO_WATCHER_INDEX, Short.valueOf((short) 0));
}
@Override
@@ -131,103 +126,136 @@ public class MobMonolith extends EntityFlying implements IMob
@Override
public void onEntityUpdate()
{
// Remove this Monolith if it's not in Limbo or in a pocket dimension
if (!(this.worldObj.provider instanceof LimboProvider || this.worldObj.provider instanceof PocketProvider))
{
this.setDead();
super.onEntityUpdate();
return;
}
super.onEntityUpdate();
EntityPlayer entityPlayer = this.worldObj.getClosestPlayerToEntity(this,MAX_AGGRO_RANGE);
//need to always manage aggro level, even if player is out of range.
this.setAggroLevel(entityPlayer);
//these things only matter if the player is in range.
if (entityPlayer != null)
super.onEntityUpdate();
// Check for players and update aggro levels even if there are no players in range
EntityPlayer player = this.worldObj.getClosestPlayerToEntity(this, MAX_AGGRO_RANGE);
boolean visibility = (player != null) ? player.canEntityBeSeen(this) : false;
this.updateAggroLevel(player, visibility);
// Change orientation and face a player if one is in range
if (player != null)
{
this.faceEntity(entityPlayer, 1, 1);
this.playSounds(entityPlayer);
//teleport the player if the conditions are met
if (aggro >= MAX_AGGRO && !this.worldObj.isRemote && properties.MonolithTeleportationEnabled && !entityPlayer.capabilities.isCreativeMode)
this.facePlayer(player);
if (!this.worldObj.isRemote && !(this.worldObj.provider instanceof LimboProvider))
{
Point4D destination = LimboProvider.getLimboSkySpawn(entityPlayer, properties);
DDTeleporter.teleportEntity(entityPlayer, destination, false);
this.aggro = 0;
entityPlayer.worldObj.playSoundAtEntity(entityPlayer,mod_pocketDim.modid+":crack",13, 1);
// 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.
this.playSounds(player);
}
if (visibility)
{
// Only spawn particles on the client side and outside Limbo
if (this.worldObj.isRemote && !(this.worldObj.provider instanceof LimboProvider))
{
this.spawnParticles(player);
}
// Teleport the target player if various conditions are met
if (aggro >= MAX_AGGRO && !this.worldObj.isRemote &&
properties.MonolithTeleportationEnabled && !player.capabilities.isCreativeMode &&
!(this.worldObj.provider instanceof LimboProvider))
{
this.aggro = 0;
Point4D destination = LimboProvider.getLimboSkySpawn(player, properties);
DDTeleporter.teleportEntity(player, destination, false);
player.worldObj.playSoundAtEntity(player, mod_pocketDim.modid + ":crack", 13, 1);
}
}
}
}
private void setAggroLevel(EntityPlayer player)
private void updateAggroLevel(EntityPlayer player, boolean visibility)
{
//aggro constantly decreases at a rate that varies with the current amount of aggro.
if(aggro > 0)
// If we're working on the server side, adjust aggro level
// If we're working on the client side, retrieve aggro level from dataWatcher
if (!this.worldObj.isRemote)
{
this.aggro = this.aggro -(this.aggro/25);
}
if(player != null)
{
//monoliths increase aggro slightly if the player is near, but slowly and to a cap.
float distance = this.getDistanceToEntity(player);
aggro+= 1.5-(distance/this.MAX_AGGRO_RANGE);
//rapidly increase aggro if the monolith has line of sight to the player.
if(player.canEntityBeSeen(this))
{
//prevent monoliths from teleporting the player in limbo
if(this.worldObj.provider instanceof LimboProvider)
// Server side...
// Rapidly increase the aggro level if this Monolith can see the player
if (visibility)
{
if (this.worldObj.provider instanceof LimboProvider)
{
aggro+=1.5;
aggro++;
}
else
{
this.spawnParticles(player);
aggro+=3;
// Aggro increases faster outside of Limbo
aggro += 3;
}
}
else
{
if (aggro > aggroCap)
{
// Decrease aggro over time
aggro--;
}
else if (player != null && (aggro < aggroCap))
{
// Increase aggro if a player is within range and aggro < aggroCap
aggro++;
}
}
// Clamp the aggro level
aggro = (short) MathHelper.clamp_int(aggro, 0, MAX_AGGRO);
this.dataWatcher.updateObject(AGGRO_WATCHER_INDEX, Short.valueOf(aggro));
}
//convert the aggro counter to one of the texture states, and set it.
this.textureState = (byte) ((this.TEXTURE_STATES/this.MAX_AGGRO)*this.aggro);
if(this.textureState>TEXTURE_STATES)
else
{
textureState = TEXTURE_STATES;
}
if (!this.worldObj.isRemote)
{
this.dataWatcher.updateObject(16, Byte.valueOf(this.textureState));
// Client side...
aggro = this.dataWatcher.getWatchableObjectShort(AGGRO_WATCHER_INDEX);
}
}
public int getTextureState()
{
// Determine texture state from aggro progress
return MathHelper.clamp_int(MAX_TEXTURE_STATE * aggro / MAX_AGGRO, 0, MAX_TEXTURE_STATE);
}
/**
* Plays sounds at different levels of aggro, using soundTime to prevent too many sounds at once.
* @param entityPlayer
*/
private void playSounds(EntityPlayer entityPlayer)
{
float aggroPercent = (aggro/MAX_AGGRO);
if(this.soundTime<=0)
float aggroPercent = this.getAggroProgress();
if (this.soundTime <= 0)
{
this.playSound(mod_pocketDim.modid+":monk", 1F, 1F);
this.soundTime=100;
this.playSound(mod_pocketDim.modid + ":monk", 1F, 1F);
this.soundTime = 100;
}
if ((aggroPercent>.70)&&this.soundTime<100)
if ((aggroPercent > 0.70) && this.soundTime < 100)
{
this.worldObj.playSoundEffect(entityPlayer.posX, entityPlayer.posY, entityPlayer.posZ,mod_pocketDim.modid+":tearing",1F, (float) (1+this.rand.nextGaussian()));
this.soundTime=100+this.rand.nextInt(75);
this.worldObj.playSoundEffect(entityPlayer.posX, entityPlayer.posY, entityPlayer.posZ, mod_pocketDim.modid + ":tearing", 1F, (float) (1 + this.rand.nextGaussian()));
this.soundTime = 100 + this.rand.nextInt(75);
}
if ((aggroPercent>.90)&&this.soundTime<200)
if ((aggroPercent > 0.80) && this.soundTime < 200)
{
this.worldObj.playSoundEffect(entityPlayer.posX, entityPlayer.posY, entityPlayer.posZ,mod_pocketDim.modid+":tearing",7, 1F);
this.soundTime=250;
this.worldObj.playSoundEffect(entityPlayer.posX, entityPlayer.posY, entityPlayer.posZ, mod_pocketDim.modid + ":tearing", 7, 1F);
this.soundTime = 250;
}
this.soundTime--;
}
private void spawnParticles(EntityPlayer player)
{
for (int i = 1; i < (10*(aggro/MAX_AGGRO)); ++i)
int count = 10 * aggro / MAX_AGGRO;
for (int i = 1; i < count; ++i)
{
player.worldObj.spawnParticle("portal", player.posX + (this.rand.nextDouble() - 0.5D) * this.width,
player.posY + this.rand.nextDouble() * player.height - 0.75D,
@@ -237,43 +265,38 @@ public class MobMonolith extends EntityFlying implements IMob
}
}
@Override
public void faceEntity(Entity par1Entity, float par2, float par3)
public float getAggroProgress()
{
double d0 = par1Entity.posX - this.posX;
double d1 = par1Entity.posZ - this.posZ;
double d2 = (par1Entity.posY + par1Entity.getEyeHeight()) - (this.posY +this.getEyeHeight());
return ((float) aggro) / MAX_AGGRO;
}
private void facePlayer(EntityPlayer player)
{
double d0 = player.posX - this.posX;
double d1 = player.posZ - this.posZ;
double d2 = (player.posY + player.getEyeHeight()) - (this.posY + this.getEyeHeight());
double d3 = MathHelper.sqrt_double(d0 * d0 + d1 * d1);
float f2 = (float)(Math.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F;
this.pitchLevel = (float)-((Math.atan(d2/d3) )* 180.0D / Math.PI);
this.pitchLevel = (float) -((Math.atan(d2/d3) )* 180.0D / Math.PI);
this.rotationYaw = f2;
this.rotationYawHead=f2;
this.renderYawOffset=this.rotationYaw;
}
@Override
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound)
{
super.writeEntityToNBT(par1NBTTagCompound);
par1NBTTagCompound.setFloat("soundTime", this.soundTime);
par1NBTTagCompound.setFloat("aggro", this.aggro);
par1NBTTagCompound.setInteger("aggroMax", this.aggroMax);
par1NBTTagCompound.setByte("textureState", this.textureState);
this.rotationYawHead = f2;
this.renderYawOffset = this.rotationYaw;
}
@Override
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound)
public void writeEntityToNBT(NBTTagCompound rootTag)
{
super.readEntityFromNBT(par1NBTTagCompound);
this.soundTime = par1NBTTagCompound.getFloat("soundTime");
super.writeEntityToNBT(rootTag);
rootTag.setInteger("Aggro", this.aggro);
}
@Override
public void readEntityFromNBT(NBTTagCompound rootTag)
{
super.readEntityFromNBT(rootTag);
//make them load with half aggro so they dont instantly teleport players
this.aggro = par1NBTTagCompound.getFloat("aggro")/2;
this.aggroMax = par1NBTTagCompound.getInteger("aggroMax");
this.textureState = par1NBTTagCompound.getByte("textureState");
// Load Monoliths with half aggro so they don't teleport players instantly
this.aggro = (short) (rootTag.getInteger("Aggro") / 2);
}
@Override
@@ -282,7 +305,7 @@ public class MobMonolith extends EntityFlying implements IMob
@SuppressWarnings("rawtypes")
List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, AxisAlignedBB.getBoundingBox( this.posX-15, posY-4, this.posZ-15, this.posX+15, this.posY+15, this.posZ+15));
if(this.worldObj.provider.dimensionId==DDProperties.instance().LimboDimensionID)
if (this.worldObj.provider.dimensionId == DDProperties.instance().LimboDimensionID)
{
if(list.size()>0)
{
@@ -290,7 +313,7 @@ public class MobMonolith extends EntityFlying implements IMob
}
}
else if(this.worldObj.provider instanceof PocketProvider)
else if(this.worldObj.provider instanceof PocketProvider)
{
if (list.size() > 5 ||
this.worldObj.canBlockSeeTheSky((int)this.posX, (int)this.posY, (int)this.posZ))
@@ -302,9 +325,4 @@ public class MobMonolith extends EntityFlying implements IMob
this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() &&
!this.worldObj.isAnyLiquid(this.boundingBox);
}
public DataWatcher getDataWatcher()
{
return this.dataWatcher;
}
}

View File

@@ -1,56 +1,121 @@
package StevenDimDoors.mod_pocketDim.ticking;
import java.util.Arrays;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Random;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.BlockRift;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class RiftRegenerator implements IRegularTickReceiver {
private static final int RIFT_REGENERATION_INTERVAL = 200; //Regenerate random rifts every 200 ticks
private static final int RIFTS_REGENERATED_PER_DIMENSION = 5;
// Ranges of regeneration delays, in seconds
private static final int MIN_FAST_DELAY = 1;
private static final int MAX_FAST_DELAY = 3;
private static final int MIN_SLOW_DELAY = 5;
private static final int MAX_SLOW_DELAY = 15;
private static final int MIN_RESCHEDULE_DELAY = 4 * 60;
private static final int MAX_RESCHEDULE_DELAY = 6 * 60;
private static final int TICKS_PER_SECOND = 20;
private static final int RIFT_REGENERATION_INTERVAL = 1; // Check the regeneration queue every tick
private static Random random = new Random();
public RiftRegenerator(IRegularTickSender sender)
private long tickCount = 0;
private PriorityQueue<RiftTicket> ticketQueue;
private BlockRift blockRift;
public RiftRegenerator(IRegularTickSender sender, BlockRift blockRift)
{
sender.registerForTicking(this, RIFT_REGENERATION_INTERVAL, false);
this.ticketQueue = new PriorityQueue<RiftTicket>();
this.blockRift = blockRift;
sender.registerReceiver(this, RIFT_REGENERATION_INTERVAL, false);
}
@Override
public void notifyTick()
{
regenerateRiftsInLoadedWorlds();
processTicketQueue();
tickCount++;
}
private static void regenerateRiftsInLoadedWorlds()
public void scheduleSlowRegeneration(DimLink link)
{
// Regenerate rifts that have been replaced (not permanently removed) by players
// Only do this in dimensions that are currently loaded
List<Integer> loadedWorlds = (List<Integer>) Arrays.asList(DimensionManager.getIDs());
for (Integer dimensionID : loadedWorlds)
{
NewDimData dimension = PocketManager.getDimensionData(dimensionID);
if (dimension.linkCount() > 0)
{
World world = DimensionManager.getWorld(dimension.id());
if (world != null)
{
for (int count = 0; count < RIFTS_REGENERATED_PER_DIMENSION; count++)
{
DimLink link = dimension.getRandomLink();
Point4D source = link.source();
mod_pocketDim.blockRift.regenerateRift(world, source.getX(), source.getY(), source.getZ(), random);
}
}
}
}
scheduleRegeneration(link, MIN_SLOW_DELAY, MAX_SLOW_DELAY);
}
public void scheduleSlowRegeneration(int x, int y, int z, World world)
{
scheduleRegeneration(PocketManager.getLink(x, y, z, world), MIN_SLOW_DELAY, MAX_SLOW_DELAY);
}
public void scheduleFastRegeneration(int x, int y, int z, World world)
{
scheduleRegeneration(PocketManager.getLink(x, y, z, world), MIN_FAST_DELAY, MAX_FAST_DELAY);
}
private void scheduleRegeneration(DimLink link, int minDelay, int maxDelay)
{
if (link != null)
{
int tickDelay = MathHelper.getRandomIntegerInRange(random, minDelay * TICKS_PER_SECOND, maxDelay * TICKS_PER_SECOND);
ticketQueue.add(new RiftTicket(link.source(), tickCount + tickDelay));
}
}
private void processTicketQueue()
{
RiftTicket ticket;
while (!ticketQueue.isEmpty() && ticketQueue.peek().timestamp() <= tickCount)
{
ticket = ticketQueue.remove();
regenerateRift(ticket.location());
}
}
private void regenerateRift(Point4D location)
{
int x = location.getX();
int y = location.getY();
int z = location.getZ();
// Try to regenerate a rift, or possibly reschedule its regeneration.
// The world for the given location must be loaded.
World world = DimensionManager.getWorld(location.getDimension());
if (world == null)
return;
// There must be a link at the given location.
DimLink link = PocketManager.getLink(location);
if (link == null)
return;
// The chunk at the given location must be loaded.
// Note: ChunkProviderServer.chunkExists() returns whether a chunk is
// loaded, not whether it has already been created.
if (!world.getChunkProvider().chunkExists(x >> 4, z >> 4))
return;
// If the location is occupied by an immune DD block, then don't regenerate.
if (blockRift.isModBlockImmune(world, x, y, z))
return;
// If the location is occupied by an immune block, then reschedule.
if (blockRift.isBlockImmune(world, x, y, z))
{
scheduleRegeneration(link, MIN_RESCHEDULE_DELAY, MAX_RESCHEDULE_DELAY);
}
else
{
// All of the necessary conditions have been met. Restore the rift!
int blockID = world.getBlockId(x, y, z);
if (world.setBlock(x, y, z, blockRift.blockID))
blockRift.dropWorldThread(blockID, world, x, y, z, random);
}
}
}

View File

@@ -0,0 +1,40 @@
package StevenDimDoors.mod_pocketDim.ticking;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class RiftTicket implements Comparable<RiftTicket> {
private long timestamp;
private Point4D location;
public RiftTicket(Point4D location, long timestamp)
{
this.timestamp = timestamp;
this.location = location;
}
@Override
public int compareTo(RiftTicket other)
{
if (this.timestamp < other.timestamp)
{
return -1;
}
else if (this.timestamp > other.timestamp)
{
return 1;
}
return 0;
}
public long timestamp()
{
return timestamp;
}
public Point4D location()
{
return location;
}
}

View File

@@ -7,25 +7,30 @@ import StevenDimDoors.mod_pocketDim.core.DDTeleporter;
import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.TickType;
public class CommonTickHandler implements ITickHandler, IRegularTickSender
public class ServerTickHandler implements ITickHandler, IRegularTickSender
{
private static final String PROFILING_LABEL = "Dimensional Doors: Common Tick";
private static final String PROFILING_LABEL = "Dimensional Doors: Server Tick";
private int tickCount = 0;
private ArrayList<RegularTickReceiverInfo> receivers;
public CommonTickHandler()
public ServerTickHandler()
{
this.receivers = new ArrayList<RegularTickReceiverInfo>();
}
@Override
public void registerForTicking(IRegularTickReceiver receiver, int interval, boolean onTickStart)
public void registerReceiver(IRegularTickReceiver receiver, int interval, boolean onTickStart)
{
RegularTickReceiverInfo info = new RegularTickReceiverInfo(receiver, interval, onTickStart);
receivers.add(info);
}
@Override
public void unregisterReceivers()
{
receivers.clear();
}
@Override
public void tickStart(EnumSet<TickType> type, Object... tickData)

View File

@@ -0,0 +1,13 @@
package StevenDimDoors.mod_pocketDim.tileentities;
import java.util.Random;
import net.minecraft.tileentity.TileEntity;
public abstract class DDTileEntityBase extends TileEntity
{
/**
*
* @return an array of floats representing RGBA color where 1.0 = 255.
*/
public abstract float[] getRenderColor(Random rand);
}

View File

@@ -1,9 +1,15 @@
package StevenDimDoors.mod_pocketDim.tileentities;
import java.util.Random;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet;
import StevenDimDoors.mod_pocketDim.ServerPacketHandler;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.blocks.IDimDoor;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
import net.minecraft.block.Block;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.packet.Packet;
@@ -11,46 +17,32 @@ import net.minecraft.network.packet.Packet130UpdateSign;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.tileentity.TileEntity;
public class TileEntityDimDoor extends TileEntity
public class TileEntityDimDoor extends DDTileEntityBase
{
public boolean openOrClosed;
public int orientation;
public boolean hasExit;
public byte lockStatus;
public boolean isDungeonChainLink;
public boolean hasGennedPair=false;
@Override
public boolean canUpdate()
{
return true;
return false;
}
@Override
public void updateEntity()
{
}
@Override
public Packet getDescriptionPacket()
{
if(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)!=null)
{
return ServerPacketHandler.createLinkPacket(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj).link());
return ServerPacketHandler.createLinkPacket(new ClientLinkData(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)));
}
return null;
}
public void invalidate()
{
this.tileEntityInvalid = true;
if(this.worldObj.getBlockId(xCoord, yCoord, zCoord)==0&&!this.worldObj.isRemote)
{
if(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)!=null)
{
mod_pocketDim.instance.fastRiftRegenerator.registerRiftForRegen(xCoord, yCoord, zCoord, this.worldObj.provider.dimensionId);
}
}
}
@Override
public void readFromNBT(NBTTagCompound nbt)
@@ -75,7 +67,7 @@ public class TileEntityDimDoor extends TileEntity
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
nbt.setBoolean("openOrClosed", this.openOrClosed);
nbt.setBoolean("hasExit", this.hasExit);
nbt.setInteger("orientation", this.orientation);
@@ -83,5 +75,22 @@ public class TileEntityDimDoor extends TileEntity
nbt.setBoolean("hasGennedPair", hasGennedPair);
}
@Override
public float[] getRenderColor(Random rand)
{
float[] rgbaColor = {1,1,1,1};
if (this.worldObj.provider.dimensionId == mod_pocketDim.NETHER_DIMENSION_ID)
{
rgbaColor[0] = rand.nextFloat() * 0.5F + 0.4F;
rgbaColor[1] = rand.nextFloat() * 0.05F;
rgbaColor[2] = rand.nextFloat() * 0.05F;
}
else
{
rgbaColor[0] = rand.nextFloat() * 0.5F + 0.1F;
rgbaColor[1] = rand.nextFloat() * 0.4F + 0.4F;
rgbaColor[2] = rand.nextFloat() * 0.6F + 0.5F;
}
return rgbaColor;
}
}

View File

@@ -1,85 +1,93 @@
package StevenDimDoors.mod_pocketDim.tileentities;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraftforge.common.ForgeChunkManager;
import net.minecraftforge.common.ForgeChunkManager.Ticket;
import net.minecraftforge.common.ForgeChunkManager.Type;
import StevenDimDoors.mod_pocketDim.IChunkLoader;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.helpers.ChunkLoaderHelper;
import StevenDimDoors.mod_pocketDim.world.PocketBuilder;
public class TileEntityDimDoorGold extends TileEntityDimDoor implements IChunkLoader
{
private Ticket chunkTicket;
private boolean initialized = false;
@Override
public boolean canUpdate()
{
return true;
return !initialized;
}
@Override
public boolean isInitialized()
{
return initialized;
}
@Override
public void updateEntity()
{ // every tick?
if (PocketManager.getDimensionData(this.worldObj) != null &&
PocketManager.getDimensionData(this.worldObj).isPocketDimension() &&
!this.worldObj.isRemote)
{
if(PocketManager.getLink(this.xCoord,this.yCoord,this.zCoord,this.worldObj)==null)
{
if (!initialized)
{
initialize(null);
}
}
@Override
public void initialize(Ticket ticket)
{
initialized = true;
chunkTicket = ticket;
// Only do anything if this function is running on the server side
// NOTE: We don't have to check whether this block is the upper door
// block or the lower one because only one of them should have a
// link associated with it.
if (!worldObj.isRemote)
{
NewDimData dimension = PocketManager.createDimensionData(worldObj);
// Check whether a ticket has already been assigned to this door
if (chunkTicket == null)
{
return;
}
if (this.chunkTicket == null)
{
chunkTicket = ForgeChunkManager.requestTicket(mod_pocketDim.instance, worldObj, Type.NORMAL);
if(chunkTicket == null)
// No ticket yet.
// Check if this area should be loaded and request a new ticket.
if (isValidChunkLoaderSetup(dimension))
{
return;
chunkTicket = ChunkLoaderHelper.createTicket(xCoord, yCoord, zCoord, worldObj);
}
chunkTicket.getModData().setInteger("goldDimDoorX", xCoord);
chunkTicket.getModData().setInteger("goldDimDoorY", yCoord);
chunkTicket.getModData().setInteger("goldDimDoorZ", zCoord);
forceChunkLoading(chunkTicket,this.xCoord,this.zCoord);
}
else
{
// A ticket has already been provided.
// Check if this area should be loaded. If not, release the ticket.
if (!isValidChunkLoaderSetup(dimension))
{
ForgeChunkManager.releaseTicket(chunkTicket);
chunkTicket = null;
}
}
// If chunkTicket isn't null at this point, then this is a valid door setup.
// The last step is to request force loading of the pocket's chunks.
if (chunkTicket != null)
{
ChunkLoaderHelper.forcePocketChunks(dimension, chunkTicket);
}
}
}
@Override
public void forceChunkLoading(Ticket chunkTicket,int x,int z)
private boolean isValidChunkLoaderSetup(NewDimData dimension)
{
Point4D origin = PocketManager.getDimensionData(this.worldObj).origin();
int orientation = PocketManager.getDimensionData(this.worldObj).orientation();
// Check the various conditions that make this a valid door setup.
// 1. The door must be inside the pocket's XZ boundaries,
// to prevent loading of chunks with a distant door
// 2. The dimension must be a pocket dimension
// 3. The door must be linked so that it's clear that it's not a normal door
int xOffset=0;
int zOffset=0;
switch(orientation)
{
case 0:
xOffset = PocketBuilder.DEFAULT_POCKET_SIZE/2;
break;
case 1:
zOffset = PocketBuilder.DEFAULT_POCKET_SIZE/2;
break;
case 2:
xOffset = -PocketBuilder.DEFAULT_POCKET_SIZE/2;
break;
case 3:
zOffset = -PocketBuilder.DEFAULT_POCKET_SIZE/2;
break;
}
for(int chunkX = -2; chunkX<3;chunkX++)
{
for(int chunkZ = -2; chunkZ<3;chunkZ++)
{
ForgeChunkManager.forceChunk(chunkTicket, new ChunkCoordIntPair((origin.getX()+xOffset >> 4)+chunkX, (origin.getZ()+zOffset >> 4)+chunkZ));
}
}
return (dimension.isPocketDimension() && dimension.getLink(xCoord, yCoord, zCoord) != null &&
PocketBuilder.calculateDefaultBounds(dimension).contains(xCoord, yCoord, zCoord));
}
@Override

View File

@@ -1,17 +1,8 @@
package StevenDimDoors.mod_pocketDim.tileentities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.PacketDispatcher;
import net.minecraft.block.Block;
import net.minecraft.entity.DataWatcher;
import net.minecraft.entity.Entity;
import net.minecraft.entity.monster.EntityEnderman;
import net.minecraft.entity.player.EntityPlayer;
@@ -19,12 +10,8 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet132TileEntityData;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import StevenDimDoors.mod_pocketDim.ServerPacketHandler;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
@@ -32,8 +19,11 @@ import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.util.Point4D;
import StevenDimDoors.mod_pocketDim.util.l_systems.LSystem;
import StevenDimDoors.mod_pocketDim.util.l_systems.LSystem.PolygonStorage;
import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData;
public class TileEntityRift extends TileEntity
public class TileEntityRift extends DDTileEntityBase
{
private static final int RIFT_INTERACTION_RANGE = 5;
private static final int MAX_ANCESTOR_LINKS = 2;
@@ -44,121 +34,94 @@ public class TileEntityRift extends TileEntity
private static final int MAX_RIFT_SPREAD_CHANCE = 256;
private static final int HOSTILE_ENDERMAN_CHANCE = 1;
private static final int MAX_HOSTILE_ENDERMAN_CHANCE = 3;
private static final int UPDATE_PERIOD = 200;
private static final int CLOSING_PERIOD = 40;
private static Random random = new Random();
private int age = 0;
private int updateTimer = 0;
private int riftCloseTimer = 0;
private int updateTimer;
private int closeTimer = 0;
public int xOffset = 0;
public int yOffset = 0;
public int zOffset = 0;
public boolean shouldClose = false;
private boolean hasUpdated = false;
public DimLink nearestRiftData;
public Point4D nearestRiftLocation = null;
public int spawnedEndermenID = 0;
public HashMap<Integer, double[]> renderingCenters = new HashMap<Integer, double[]>();
public int riftRotation = random.nextInt(360);
public int renderKey = random.nextInt(LSystem.curves.size());
public float growth = 0;
public TileEntityRift()
{
// Vary the update times of rifts to prevent all the rifts in a cluster
// from updating at the same time.
updateTimer = random.nextInt(UPDATE_PERIOD);
}
@Override
public void updateEntity()
{
//Determines if rift should render white closing particles and spread closing effect to other rifts nearby
if (this.shouldClose)
if (PocketManager.getLink(xCoord, yCoord, zCoord, worldObj.provider.dimensionId) == null)
{
closeRift();
}
else if( PocketManager.getLink(xCoord, yCoord, zCoord, worldObj.provider.dimensionId) == null)
{
this.invalidate();
if (worldObj.getBlockId(xCoord, yCoord, zCoord) == mod_pocketDim.blockRift.blockID)
{
worldObj.setBlockToAir(xCoord, yCoord, zCoord);
worldObj.removeBlockTileEntity(xCoord, yCoord, zCoord);
this.invalidate();
return;
}
}
if (worldObj.getBlockId(xCoord, yCoord, zCoord) != mod_pocketDim.blockRift.blockID)
{
worldObj.removeBlockTileEntity(xCoord, yCoord, zCoord);
this.invalidate();
else
{
invalidate();
}
return;
}
//The code for the new rift rendering hooks in here, as well as in the ClientProxy to bind the TESR to the rift.
//It is inactive for now.
/**
if(rand.nextInt(15) == 1)
{
age = age + 1;
this.calculateNextRenderQuad(age, rand);
}
this.clearBlocksOnRift();
**/
//This code should execute once every 10 seconds
if (updateTimer > 200)
if (worldObj.getBlockId(xCoord, yCoord, zCoord) != mod_pocketDim.blockRift.blockID)
{
this.spawnEndermen();
this.grow(mod_pocketDim.properties);
invalidate();
return;
}
// Check if this rift should render white closing particles and
// spread the closing effect to other rifts nearby.
if (shouldClose)
{
closeRift();
return;
}
if (updateTimer >= UPDATE_PERIOD)
{
spawnEndermen(mod_pocketDim.properties);
updateTimer = 0;
}
else if(updateTimer==0)
else if (updateTimer == UPDATE_PERIOD / 2)
{
this.calculateOldParticleOffset(); //this also calculates the distance for the particle stuff.
updateNearestRift();
spread(mod_pocketDim.properties);
}
growth += 1F/(growth+1);
updateTimer++;
}
@Override
public boolean canUpdate()
private void spawnEndermen(DDProperties properties)
{
return true;
}
private void clearBlocksOnRift()
{
//clears blocks for the new rending effect
for (double[] coord : this.renderingCenters.values())
{
int x = MathHelper.floor_double(coord[0] + 0.5);
int y = MathHelper.floor_double(coord[1] + 0.5);
int z = MathHelper.floor_double(coord[2] + 0.5);
// Right side
if (!mod_pocketDim.blockRift.isBlockImmune(worldObj, this.xCoord + x, this.yCoord + y, this.zCoord + z))
{
worldObj.setBlockToAir(this.xCoord + x, this.yCoord + y, this.zCoord + z);
}
// Left side
if (!mod_pocketDim.blockRift.isBlockImmune(worldObj, this.xCoord - x, this.yCoord - y, this.zCoord - z))
{
worldObj.setBlockToAir(this.xCoord - x, this.yCoord - y, this.zCoord - z);
}
}
}
private void spawnEndermen()
{
if (worldObj.isRemote)
if (worldObj.isRemote || !properties.RiftsSpawnEndermenEnabled)
{
return;
}
NewDimData dimension = PocketManager.getDimensionData(worldObj);
//Ensure that this rift is only spawning one enderman at a time, to prevent hordes of endermen
// Ensure that this rift is only spawning one Enderman at a time, to prevent hordes of Endermen
Entity entity = worldObj.getEntityByID(this.spawnedEndermenID);
if (entity != null && entity instanceof EntityEnderman)
{
return;
}
//enderman will only spawn in groups of rifts
if (random.nextInt(MAX_ENDERMAN_SPAWNING_CHANCE) < ENDERMAN_SPAWNING_CHANCE)
{
// Endermen will only spawn from groups of rifts
if (updateNearestRift())
{
List<Entity> list = worldObj.getEntitiesWithinAABB(EntityEnderman.class,
@@ -182,123 +145,71 @@ public class TileEntityRift extends TileEntity
}
}
}
public boolean updateNearestRift()
{
nearestRiftData = PocketManager.getDimensionData(worldObj).findNearestRift(this.worldObj, 5, xCoord, yCoord, zCoord);
return (nearestRiftData != null);
}
private void closeRift()
{
NewDimData dimension = PocketManager.getDimensionData(worldObj);
if (riftCloseTimer == 20)
NewDimData dimension = PocketManager.createDimensionData(worldObj);
if (growth < CLOSING_PERIOD / 2)
{
ArrayList<DimLink> rifts= dimension.findRiftsInRange(worldObj, 6, xCoord, yCoord, zCoord);
if (rifts.size()>0)
for (DimLink riftLink : dimension.findRiftsInRange(worldObj, 6, xCoord, yCoord, zCoord))
{
for(DimLink riftToClose : rifts)
Point4D location = riftLink.source();
TileEntityRift rift = (TileEntityRift) worldObj.getBlockTileEntity(location.getX(), location.getY(), location.getZ());
if (rift != null && !rift.shouldClose)
{
Point4D location = riftToClose.source();
TileEntityRift rift = (TileEntityRift) worldObj.getBlockTileEntity(location.getX(), location.getY(), location.getZ());
if (rift != null)
{
rift.shouldClose = true;
rift.onInventoryChanged();
}
rift.shouldClose = true;
rift.onInventoryChanged();
}
}
}
if (riftCloseTimer > 40)
if (growth == 0 && !worldObj.isRemote)
{
this.invalidate();
if(!this.worldObj.isRemote)
DimLink link = PocketManager.getLink(this.xCoord, this.yCoord, this.zCoord, worldObj);
if (link != null)
{
DimLink link = PocketManager.getLink(this.xCoord, this.yCoord, this.zCoord, worldObj);
if(link!=null)
{
dimension.deleteLink(link);
}
dimension.deleteLink(link);
}
worldObj.setBlockToAir(xCoord, yCoord, zCoord);
worldObj.playSound(xCoord, yCoord, zCoord, "mods.DimDoors.sfx.riftClose", (float) .7, 1, true);
this.worldObj.removeBlockTileEntity(xCoord, yCoord, zCoord);
return;
worldObj.playSound(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5, "mods.DimDoors.sfx.riftClose", 0.7f, 1, false);
}
riftCloseTimer++;
growth --;
}
public boolean updateNearestRift()
{
Point4D previousNearest = nearestRiftLocation;
DimLink nearestRiftLink = PocketManager.createDimensionData(worldObj).findNearestRift(
worldObj, RIFT_INTERACTION_RANGE, xCoord, yCoord, zCoord);
nearestRiftLocation = (nearestRiftLink == null) ? null : nearestRiftLink.source();
// If the nearest rift location changed, then update particle offsets
if (previousNearest != nearestRiftLocation &&
(previousNearest == null || nearestRiftLocation == null || !previousNearest.equals(nearestRiftLocation)))
{
updateParticleOffsets();
}
return (nearestRiftLocation != null);
}
private void calculateOldParticleOffset()
private void updateParticleOffsets()
{
updateNearestRift();
if (nearestRiftData != null)
if (nearestRiftLocation != null)
{
Point4D location = nearestRiftData.source();
this.xOffset = this.xCoord - location.getX();
this.yOffset = this.yCoord - location.getY();
this.zOffset = this.zCoord - location.getZ();
int distance = Math.abs(xOffset) + Math.abs(yOffset) + Math.abs(zOffset);
this.xOffset = this.xCoord - nearestRiftLocation.getX();
this.yOffset = this.yCoord - nearestRiftLocation.getY();
this.zOffset = this.zCoord - nearestRiftLocation.getZ();
}
else
{
this.xOffset=0;
this.yOffset=0;
this.xOffset=0;
this.xOffset = 0;
this.yOffset = 0;
this.xOffset = 0;
}
this.onInventoryChanged();
}
private void calculateNextRenderQuad(float age, Random rand)
{
int maxSize = MathHelper.floor_double((Math.log(Math.pow(age+1,2))));
int iteration=0;
while(iteration< maxSize)
{
iteration++;
double fl =Math.log(iteration+1)/(iteration);
double[] coords= new double[4];
double noise = ((rand.nextGaussian())/(2+iteration/3+1));
if(!this.renderingCenters.containsKey(iteration-1))
{
if (rand.nextBoolean())
{
coords[0] = fl*1.5;
coords[1] = rand.nextGaussian()/5;
coords[2] = 0;
coords[3] = 1;
}
else
{
coords[0] = 0;
coords[1] = rand.nextGaussian()/5;
coords[2] = fl*1.5;
coords[3] = 0;
}
this.renderingCenters.put(iteration-1,coords);
iteration--;
}
else if(!this.renderingCenters.containsKey(iteration))
{
if(this.renderingCenters.get(iteration-1)[3]==0)
{
coords[0]=noise/2+this.renderingCenters.get(iteration-1)[0];
coords[1]=noise/2+this.renderingCenters.get(iteration-1)[1];
coords[2]= this.renderingCenters.get(iteration-1)[2]+fl;
coords[3] = 0;
}
else
{
coords[0]=this.renderingCenters.get(iteration-1)[0]+fl;
coords[1]=noise/2+this.renderingCenters.get(iteration-1)[1];
coords[2]=noise/2+this.renderingCenters.get(iteration-1)[2];
coords[3] = 1;
}
this.renderingCenters.put(iteration,coords);
}
}
}
@Override
public boolean shouldRenderInPass(int pass)
{
@@ -311,13 +222,10 @@ public class TileEntityRift extends TileEntity
{
return countAncestorLinks(link.parent()) + 1;
}
else
{
return 0;
}
return 0;
}
public void grow(DDProperties properties)
public void spread(DDProperties properties)
{
if (worldObj.isRemote || !properties.RiftSpreadEnabled
|| random.nextInt(MAX_RIFT_SPREAD_CHANCE) < RIFT_SPREAD_CHANCE || this.shouldClose)
@@ -325,7 +233,7 @@ public class TileEntityRift extends TileEntity
return;
}
NewDimData dimension = PocketManager.getDimensionData(worldObj);
NewDimData dimension = PocketManager.createDimensionData(worldObj);
DimLink link = dimension.getLink(xCoord, yCoord, zCoord);
if (link.childCount() >= MAX_CHILD_LINKS || countAncestorLinks(link) >= MAX_ANCESTOR_LINKS)
@@ -348,36 +256,40 @@ public class TileEntityRift extends TileEntity
public void readFromNBT(NBTTagCompound nbt)
{
super.readFromNBT(nbt);
this.renderingCenters = new HashMap<Integer, double[]>();
this.updateTimer = nbt.getInteger("count");
this.riftCloseTimer = nbt.getInteger("count2");
this.updateTimer = nbt.getInteger("updateTimer");
this.xOffset = nbt.getInteger("xOffset");
this.yOffset = nbt.getInteger("yOffset");
this.zOffset = nbt.getInteger("zOffset");
this.age = nbt.getInteger("age");
this.shouldClose = nbt.getBoolean("shouldClose");
this.spawnedEndermenID = nbt.getInteger("spawnedEndermenID");
this.riftRotation = nbt.getInteger("riftRotation");
this.renderKey = nbt.getInteger("renderKey");
this.growth = nbt.getFloat("growth");
}
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
nbt.setInteger("age", this.age);
nbt.setInteger("count", this.updateTimer);
nbt.setInteger("count2", this.riftCloseTimer);
nbt.setInteger("updateTimer", this.updateTimer);
nbt.setInteger("xOffset", this.xOffset);
nbt.setInteger("yOffset", this.yOffset);
nbt.setInteger("zOffset", this.zOffset);
nbt.setBoolean("shouldClose", this.shouldClose);
nbt.setInteger("spawnedEndermenID", this.spawnedEndermenID);
nbt.setInteger("renderKey", this.renderKey);
nbt.setInteger("riftRotation", this.riftRotation);
nbt.setFloat("growth", this.growth);
}
@Override
public Packet getDescriptionPacket()
{
if (PocketManager.getLink(xCoord, yCoord, zCoord, worldObj) != null)
{
return ServerPacketHandler.createLinkPacket(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj).link());
return ServerPacketHandler.createLinkPacket(new ClientLinkData(PocketManager.getLink(xCoord, yCoord, zCoord, worldObj)));
}
return null;
}
@@ -387,4 +299,17 @@ public class TileEntityRift extends TileEntity
{
readFromNBT(pkt.data);
}
@Override
public float[] getRenderColor(Random rand)
{
return null;
}
public PolygonStorage getCurve()
{
return (LSystem.curves.get(renderKey));
}
}

View File

@@ -1,44 +1,33 @@
package StevenDimDoors.mod_pocketDim.tileentities;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import java.util.Random;
public class TileEntityTransTrapdoor extends TileEntity
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
public class TileEntityTransTrapdoor extends DDTileEntityBase
{
public boolean hasRift;
@Override
public boolean canUpdate()
{
return true;
return false;
}
@Override
public void updateEntity()
public float[] getRenderColor(Random rand)
{
}
@Override
public void readFromNBT(NBTTagCompound nbt)
{
super.readFromNBT(nbt);
try
float[] rgbaColor = {1,1,1,1};
if (this.worldObj.provider.dimensionId == mod_pocketDim.NETHER_DIMENSION_ID)
{
this.hasRift = nbt.getBoolean("hasRift");
rgbaColor[0] = worldObj.rand.nextFloat() * 0.5F + 0.4F;
rgbaColor[1] = worldObj.rand.nextFloat() * 0.05F;
rgbaColor[2] = worldObj.rand.nextFloat() * 0.05F;
}
catch (Exception e)
else
{
rgbaColor[0] = worldObj.rand.nextFloat() * 0.5F + 0.1F;
rgbaColor[1] = worldObj.rand.nextFloat() * 0.4F + 0.4F;
rgbaColor[2] = worldObj.rand.nextFloat() * 0.6F + 0.5F;
}
}
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
nbt.setBoolean("hasRift", this.hasRift);
return rgbaColor;
}
}

View File

@@ -0,0 +1,544 @@
package StevenDimDoors.mod_pocketDim.util;
import static java.util.Collections.singleton;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
public class JSONValidator
{
static final public String TYPE = "type";
static final public String ANY = "any";
static final public String PROPERTIES = "properties";
static final public String OPTIONAL = "optional";
static final public String ADDITIONAL_PROPERTIES = "additionalProperties";
static final public String MIN_LENGTH = "minLength";
static final public String MAX_LENGTH = "maxLength";
static final public String MINIMUM = "minimum";
static final public String MAXIMUM = "maximum";
static final public String PATTERN = "pattern";
static final public String ITEMS = "items";
static final public String ENUM = "enum";
static final public String REQUIRED = "required";
JsonObject schema;
public JsonObject getSchema()
{
return schema;
}
public JSONValidator(JsonObject schema)
{
this.schema = schema;
}
static class WrongType extends JsonParseException
{
/**
*
*/
private static final long serialVersionUID = 1L;
WrongType(String msg)
{
super(msg);
}
static WrongType generate(String path, Set<Type> types, Type found)
{
boolean first = true;
String typeList = "'unknown'";
for (Type type : types)
{
if (first)
{
typeList = "'" + type.getTypeString() + "'";
first = false;
}
else
{
typeList += " or '" + type.getTypeString() + "'";
}
}
return new WrongType("Invalid: Expected type " + typeList + " at '" + path + "', but " + "found type '" + found.getTypeString() + "'");
}
}
static enum Type
{
STRING("string"), NUMBER("number"), INTEGER("integer"), BOOLEAN("boolean"), OBJECT("object"), ARRAY("array"), NULL("null");
String typeString;
Type(String typeString)
{
this.typeString = typeString;
}
public String getTypeString()
{
return typeString;
}
}
static Set<Type> anyTypeSet()
{
HashSet<Type> hashSet = new HashSet<Type>();
hashSet.add(Type.STRING);
hashSet.add(Type.NUMBER);
hashSet.add(Type.INTEGER);
hashSet.add(Type.BOOLEAN);
hashSet.add(Type.OBJECT);
hashSet.add(Type.ARRAY);
hashSet.add(Type.NULL);
return hashSet;
}
static Set<Type> getSimpleType(String path, String type)
{
for (Type t : Type.values())
{
if (t.getTypeString().equals(type))
{
if (t != Type.NUMBER)
{
return singleton(t);
}
else
{
HashSet<Type> set = new HashSet<Type>();
set.add(Type.NUMBER);
set.add(Type.INTEGER);
return set;
}
}
}
if (ANY.equals(type))
{
return anyTypeSet();
}
// Unknown type, spec says to allow any.
return anyTypeSet();
}
static Set<Type> getTypeSet(String path, JsonObject schema) throws JsonParseException
{
JsonElement typeElement = schema.get(TYPE);
if (typeElement == null)
{
// Spec says that a missing type object means accept any type.
return anyTypeSet();
}
if (typeElement.isJsonPrimitive())
{
JsonPrimitive primitive = typeElement.getAsJsonPrimitive();
if (primitive.isString())
{
return getSimpleType(path, primitive.getAsString());
}
}
if (typeElement.isJsonArray())
{
HashSet<Type> set = new HashSet<Type>();
JsonArray array = typeElement.getAsJsonArray();
for (JsonElement element : array)
{
if (element.isJsonPrimitive())
{
JsonPrimitive primitive = element.getAsJsonPrimitive();
if (primitive.isString())
{
set.addAll(getSimpleType(path, primitive.getAsString()));
}
}
// Unknown type. Accept all.
return anyTypeSet();
}
}
// Don't know what this is, assume any.
return anyTypeSet();
}
static Type getType(JsonElement element)
{
if (element.isJsonArray())
{
return Type.ARRAY;
}
if (element.isJsonObject())
{
return Type.OBJECT;
}
if (element.isJsonNull())
{
return Type.NULL;
}
JsonPrimitive primitive = element.getAsJsonPrimitive();
if (primitive.isString())
{
return Type.STRING;
}
if (primitive.isBoolean())
{
return Type.BOOLEAN;
}
if (primitive.isNumber())
{
BigDecimal decimal = primitive.getAsBigDecimal();
int scale = decimal.scale();
if (scale > 0)
{
return Type.NUMBER;
}
else
{
return Type.INTEGER;
}
}
// Don't know. Punt and call it a string.
return Type.STRING;
}
static void validateObject(String path, JsonObject schema, JsonObject obj) throws JsonParseException
{
Set<String> propertiesSeen = new HashSet<String>();
JsonArray required = schema.getAsJsonArray(REQUIRED);
JsonObject properties = schema.getAsJsonObject(PROPERTIES);
if (properties == null)
{
return;
}
Set<Map.Entry<String, JsonElement>> propertySet = properties.entrySet();
ArrayList<String> requiredFields = new ArrayList<String>();
for(JsonElement st : required.getAsJsonArray())
{
requiredFields.add(st.getAsString());
}
for (Map.Entry<String, JsonElement> property : propertySet)
{
String name = property.getKey();
String newPath = path + "['" + name + "']";
JsonElement element = property.getValue();
propertiesSeen.add(name);
if (!element.isJsonObject())
{
throw new JsonParseException("Bad Schema: property definition not an object at '" + newPath + "'");
}
JsonObject definition = element.getAsJsonObject();
JsonElement newTarget = obj.get(name);
if (newTarget == null)
{
JsonPrimitive optional = definition.getAsJsonPrimitive(OPTIONAL);
boolean needed = ((optional==null) && requiredFields.contains(name)) || (optional != null && !optional.getAsBoolean());
if (needed)
{
throw new JsonParseException("Invalid: Required property '" + newPath + "' not found");
}
}
else
{
validate(newPath, definition, newTarget);
}
}
JsonElement additionalProperties = schema.get(ADDITIONAL_PROPERTIES);
JsonObject additionalSchema = null;
if (additionalProperties == null)
{
additionalSchema = new JsonObject();
}
else
{
if (additionalProperties.isJsonObject())
{
additionalSchema = additionalProperties.getAsJsonObject();
}
}
/*
* if (additionalSchema == null) {
* logger.debug("No additional schema for '"+path+"'"); } else {
* logger.debug("Additional schema for '"+path+"': "+
* additionalSchema.toString()); }
*/
Set<Map.Entry<String, JsonElement>> objectProperties = obj.entrySet();
for (Map.Entry<String, JsonElement> property : objectProperties)
{
String name = property.getKey();
String newPath = path + "['" + name + "']";
if (!propertiesSeen.contains(name))
{
if (additionalSchema == null)
{
throw new JsonParseException("Invalid: Found additional property '" + newPath + "'");
}
validate(newPath, additionalSchema, property.getValue());
}
}
}
static Integer getInt(String path, String attributeName, JsonObject schema) throws JsonParseException
{
JsonElement attributeElement = schema.get(attributeName);
if (attributeElement == null)
{
return null;
}
if (!attributeElement.isJsonPrimitive())
{
throw new JsonParseException("Bad Schema: '" + attributeName + "' attribute is not an integer at '" + path + "'");
}
JsonPrimitive attributePrimitive = attributeElement.getAsJsonPrimitive();
if (!attributePrimitive.isNumber())
{
throw new JsonParseException("Bad Schema: '" + attributeName + "' attribute is not an integer at '" + path + "'");
}
return attributePrimitive.getAsInt();
}
static String getString(String path, String attributeName, JsonObject schema) throws JsonParseException
{
JsonElement attributeElement = schema.get(attributeName);
if (attributeElement == null)
{
return null;
}
if (!attributeElement.isJsonPrimitive())
{
throw new JsonParseException("Bad Schema: '" + attributeName + "' attribute is not a string at '" + path + "'");
}
JsonPrimitive attributePrimitive = attributeElement.getAsJsonPrimitive();
if (!attributePrimitive.isString())
{
throw new JsonParseException("Bad Schema: '" + attributeName + "' attribute is not a string at '" + path + "'");
}
return attributePrimitive.getAsString();
}
static BigDecimal getBigDecimal(String path, String attributeName, JsonObject schema) throws JsonParseException
{
JsonElement attributeElement = schema.get(attributeName);
if (attributeElement == null)
{
return null;
}
if (!attributeElement.isJsonPrimitive())
{
throw new JsonParseException("Bad Schema: '" + attributeName + "' attribute is not a number at '" + path + "'");
}
JsonPrimitive attributePrimitive = attributeElement.getAsJsonPrimitive();
if (!attributePrimitive.isNumber())
{
throw new JsonParseException("Bad Schema: '" + attributeName + "' attribute is not a number at '" + path + "'");
}
return attributePrimitive.getAsBigDecimal();
}
static void validateString(String path, JsonObject schema, String str) throws JsonParseException
{
Integer minLength = getInt(path, MIN_LENGTH, schema);
Integer maxLength = getInt(path, MAX_LENGTH, schema);
if ((minLength != null) && (str.length() < minLength))
{
throw new JsonParseException("Invalid: String '" + path + "' is too short. The string needs to be more than " + minLength + " characters");
}
if ((maxLength != null) && (str.length() > maxLength))
{
throw new JsonParseException("Invalid: String '" + path + "' is too long. The string needs to be less than " + maxLength + " characters");
}
String pattern = getString(path, PATTERN, schema);
if ((pattern != null) && (!str.matches(pattern)))
{
throw new JsonParseException("Invalid: String '" + path + "' does not match pattern '" + pattern + "'");
}
}
static void validateTuple(String path, JsonArray tupleSchema, JsonObject additionalSchema, JsonArray array) throws JsonParseException
{
return;
}
static void validateArray(String path, JsonObject schema, JsonArray array) throws JsonParseException
{
JsonElement additionalProperties = schema.get(ADDITIONAL_PROPERTIES);
JsonObject additionalSchema = null;
if (additionalProperties == null)
{
additionalSchema = new JsonObject();
}
else
{
if (additionalProperties.isJsonObject())
{
additionalSchema = additionalProperties.getAsJsonObject();
}
}
JsonElement itemsElement = schema.get(ITEMS);
if (itemsElement == null)
{
return;
}
if (itemsElement.isJsonArray())
{
validateTuple(path, itemsElement.getAsJsonArray(), additionalSchema, array);
return;
}
JsonObject itemsSchema = null;
if (itemsElement.isJsonObject())
{
itemsSchema = itemsElement.getAsJsonObject();
}
else
{
// Bogus items parameter, assume everything is valid.
itemsSchema = new JsonObject();
}
int i = 0;
for (JsonElement element : array)
{
++i;
String curPath = path + "[" + i + "]";
validate(curPath, itemsSchema, element);
}
}
static void validateEnum(String path, JsonObject schema, JsonElement element) throws JsonParseException
{
JsonElement enumElement = schema.get(ENUM);
if (enumElement == null)
{
return;
}
if (!enumElement.isJsonArray())
{}
JsonArray enumArray = enumElement.getAsJsonArray();
for (JsonElement curElement : enumArray)
{
if (element.equals(curElement))
{
// We found a valid value.
return;
}
}
throw new JsonParseException("Invalid: Property '" + path + "' is not one of the enum values.");
}
static void validateNumber(String path, JsonObject schema, BigDecimal number) throws JsonParseException
{
BigDecimal minimum = getBigDecimal(path, MINIMUM, schema);
if (minimum != null)
{
if (number.compareTo(minimum) < 0)
{
throw new JsonParseException("Invalid: Property '" + path + "' has a value of '" + number + "' which is less than the minimum of '" + minimum
+ "'.");
}
}
BigDecimal maximum = getBigDecimal(path, MAXIMUM, schema);
if (maximum != null)
{
if (number.compareTo(maximum) > 0)
{
throw new JsonParseException("Invalid: Property '" + path + "' has a value of '" + number + "' which is greater than the maximum of '"
+ maximum + "'.");
}
}
}
static void validate(String path, JsonObject schema, JsonElement element) throws JsonParseException
{
Set<Type> typeSet = getTypeSet(path, schema);
Type type = getType(element);
if (!typeSet.contains(type))
{
throw WrongType.generate(path, typeSet, type);
}
switch (type)
{
case BOOLEAN:
case NULL:
break;
case NUMBER:
case INTEGER:
validateNumber(path, schema, element.getAsBigDecimal());
break;
case ARRAY:
validateArray(path, schema, element.getAsJsonArray());
break;
case STRING:
validateString(path, schema, element.getAsString());
break;
case OBJECT:
validateObject(path, schema, element.getAsJsonObject());
break;
default:
// Unknown type
throw new JsonParseException("Internal Error");
}
validateEnum(path, schema, element);
}
static public void validate(JsonObject schema, JsonElement element) throws JsonParseException
{
validate("$", schema, element);
}
public void validate(JsonElement element) throws JsonParseException
{
validate(getSchema(), element);
}
}

View File

@@ -141,12 +141,14 @@ public final class Point4D implements Comparable<Point4D>
public Point3D toPoint3D()
{
return new Point3D(this.x,this.y,this.z);
return new Point3D(this.x, this.y, this.z);
}
public int[] toIntArray()
{
return new int[]{x,y,z,dimension};
return new int[] {x, y, z, dimension};
}
public boolean equals(Point4D other)
{
if (this == other)

View File

@@ -0,0 +1,557 @@
package StevenDimDoors.mod_pocketDim.util.l_systems;
import java.awt.Point;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import javax.swing.SwingUtilities;
import org.poly2tri.Poly2Tri;
import org.poly2tri.geometry.polygon.Polygon;
import org.poly2tri.geometry.polygon.PolygonPoint;
import org.poly2tri.triangulation.TriangulationPoint;
import org.poly2tri.triangulation.delaunay.DelaunayTriangle;
public class LSystem
{
public static ArrayList<PolygonStorage> curves = new ArrayList<PolygonStorage>();
/**
* An array containing the args to generate a curve.
* index 0 = rules
* index 1 = angle
* index 2 = start string
*/
public static final String[] TERDRAGON = {"F>+F----F++++F-","60","F"};
public static final String[] DRAGON = {"X>X+YF:Y>FX-Y","90","FX"};
public static final String[] TWINDRAGON = {"X>X+YF:Y>FX-Y","90","FX--FX"};
public static final String[] VORTEX = {"X>X+YF:Y>FX-Y","90","FX---FX"};
/**
* Generates a fractal curve
* @param args: 0 = rules, 1 = angle, 2 = start
* @param steps
* @return
*/
public static void generateLSystem(String key, String[] args, int steps)
{
//Parse the rules from the first index
String[] rules = args[0].split(":");
HashMap<String, String> lSystemsRule = new HashMap<String, String>();
for (String rule : rules)
{
String[] parts = rule.split(">");
lSystemsRule.put(parts[0], parts[1]);
}
//get the angle for each turn
int angle = Integer.parseInt(args[1]);
//String to hold the output
//Initialize with starting string
String output = args[2];
//generate the l-system
output = (generate(args[2], steps, lSystemsRule));
//get the boundary of the polygon
PolygonStorage polygon = getBoundary(convertToPoints(angle, output, (steps)));
//replace the boundary of the polygon with a series of points representing triangles for rendering
polygon.points = tesselate(polygon);
curves.add(polygon);
}
/**
* Naively returns all of the points comprising the fractal
* @param input
* @return
*/
public static PolygonStorage getSpaceFillingCurve(ArrayList<double[]> input)
{
// store max x and y values to create bounding box
int maxY = Integer.MIN_VALUE;
int maxX = Integer.MIN_VALUE;
int minY = Integer.MAX_VALUE;
int minX = Integer.MAX_VALUE;
// store confirmed duplicates here
HashSet<Point> duplicates = new HashSet<Point>();
// store possible singles here
HashSet<Point> singles = new HashSet<Point>();
// list to store confirmed singles and output in the correct order
ArrayList<Point> output = new ArrayList<Point>();
// sort into Hashmaps and hashsets to make contains operations possible,
// while testing for duplicates
for (double[] point : input)
{
// convert doubles to ints and record min/max values
int xCoord = (int) Math.round(point[0]);
int yCoord = (int) Math.round(point[1]);
if (xCoord > maxX)
{
maxX = xCoord;
}
if (xCoord < minX)
{
minX = xCoord;
}
if (yCoord > maxY)
{
maxY = yCoord;
}
if (yCoord < minY)
{
minY = yCoord;
}
output.add(new Point(xCoord, yCoord));
}
return new PolygonStorage(output, maxX, maxY, minX, minY);
}
/**
* Takes an unordered list of points comprising a fractal curve and builds a
* closed polygon around it
*
* @param input
* @return
*/
public static PolygonStorage getBoundary(ArrayList<double[]> input)
{
// store max x and y values to create bounding box
int maxY = Integer.MIN_VALUE;
int maxX = Integer.MIN_VALUE;
int minY = Integer.MAX_VALUE;
int minX = Integer.MAX_VALUE;
// store confirmed duplicates here
HashSet<Point> duplicates = new HashSet<Point>();
// store possible singles here
HashSet<Point> singles = new HashSet<Point>();
// list to store confirmed singles and output in the correct order
ArrayList<Point> output = new ArrayList<Point>();
// sort into Hashmaps and hashsets to make contains operations possible,
// while testing for duplicates
for (double[] point : input)
{
// convert doubles to ints and record min/max values
int xCoord = (int) Math.round(point[0]);
int yCoord = (int) Math.round(point[1]);
if (xCoord > maxX)
{
maxX = xCoord;
}
if (xCoord < minX)
{
minX = xCoord;
}
if (yCoord > maxY)
{
maxY = yCoord;
}
if (yCoord < minY)
{
minY = yCoord;
}
singles.add(new Point(xCoord, yCoord));
}
// find a suitable starting point
Point startPoint = new Point(minX, minY);
Point prevPoint = (Point) startPoint.clone();
while (startPoint.y < maxY)
{
if (singles.contains(startPoint))
{
break;
}
startPoint.y++;
}
// record the first point so we know where to stop
final Point firstPoint = (Point) startPoint.clone();
// determine the direction to start searching from
Point direction = getVector(prevPoint, startPoint);
//output.add(startPoint);
// loop around in a clockwise circle, jumping to the next point when we
// find it and resetting the direction to start seaching from
// to the last found point. This ensures we always find the next
// *outside* point
do
{
// get the next point
direction = rotateCounterClockwise(direction);
Point target = new Point(startPoint.x + direction.x, startPoint.y + direction.y);
// see if that point is part of our fractal curve
if (singles.contains(target))
{
if(target.equals(firstPoint))
{
output.remove(output.get(output.size()-1));
break;
}
// get the vector to start from for the next cycle
direction = getVector(startPoint, target);
// prune zero width spikes
if ((output.size() > 1 && output.get(output.size() - 2).equals(target)))
{
output.remove(output.size() - 1);
}
else
{
if(output.contains(target)&&!target.equals(output.get(0)))
{
int index = output.indexOf(target);
while(output.size()>index)
{
output.remove(output.size()-1);
}
}
output.add(target);
}
startPoint = target;
}
}
while (!(output.get(output.size() - 1).equals(firstPoint) && output.size() > 1) && output.size() < singles.size());
return new PolygonStorage(output, maxX, maxY, minX, minY);
}
/**
* using a point as a 2d vector, normalize it (sorta)
*
* @param origin
* @param destination
* @return
*/
public static Point getVector(Point origin, Point destination)
{
int[] normals = { origin.x - destination.x, origin.y - destination.y };
for (int i = 0; i < normals.length; i++)
{
if (normals[i] > 0)
{
normals[i] = 1;
}
else if (normals[i] == 0)
{
normals[i] = 0;
}
else if (normals[i] < 0)
{
normals[i] = -1;
}
}
return new Point(normals[0], normals[1]);
}
/**
* rotate a normal around the origin
*
* @param previous
* @return
*/
public static Point rotateCounterClockwise(Point previous)
{
Point point = new Point();
point.x = (int) (previous.x * Math.cos(Math.toRadians(90)) - previous.y * Math.sin(Math.toRadians(90)));
point.y = (int) (previous.x * Math.sin(Math.toRadians(90)) + previous.y * Math.cos(Math.toRadians(90)));
return point;
}
/**
* Take an l-system string and convert it into a series of points on a
* cartesian grid. Designed to keep terdragons oriented the same direction
* regardless of iterations
*
* @param angle
* @param system
* @param generations
* @return
*/
public static ArrayList<double[]> convertToPoints(double angle, String system, int generations)
{
// determine the starting point and rotation to begin drawing from
int rotation = (generations % 2) == 0 ? 2 : 4;
double[] currentState = { ((generations + rotation) % 4) * 90, 0, 0 };
// the output for a totally unordered list of points defining the curve
ArrayList<double[]> output = new ArrayList<double[]>();
// the stack used to deal with branching l-systems that use [ and ]
ArrayDeque<double[]> state = new ArrayDeque<double[]>();
// perform the rules corresponding to each symbol in the l-system
for (Character ch : system.toCharArray())
{
double motion = 1;
// move forward
if (ch == 'F')
{
currentState[1] -= (Math.cos(Math.toRadians(currentState[0])) * motion);
currentState[2] -= (Math.sin(Math.toRadians(currentState[0])) * motion);
output.add(new double[] { currentState[1], currentState[2] });
}
// start branch
if (ch == '[')
{
state.push(currentState.clone());
}
// turn left
if (ch == '-')
{
currentState = new double[] { (double) ((currentState[0] - angle) % 360), currentState[1], currentState[2] };
}
// turn right
if (ch == '+')
{
currentState[0] = ((currentState[0] + angle) % 360);
}
// end branch and return to previous fork
if (ch == ']')
{
currentState = state.pop();
}
}
return output;
}
/**
* grow and l-system string based on the rules provided in the args
*
* @param start
* @param steps
* @param lSystemsRule
* @return
*/
public static String generate(String start, int steps, HashMap<String, String> lSystemsRule)
{
while (steps > 0)
{
StringBuilder output = new StringBuilder();
for (Character ch : start.toCharArray())
{
// get the rule applicable for the variable
String data = lSystemsRule.get(ch.toString());
// handle constants for rule-less symbols
if (data == null)
{
data = ch.toString();
}
output.append(data);
}
steps--;
start = output.toString();
}
return start;
}
// a data container class to transmit the important information about the polygon
public static class PolygonStorage
{
public PolygonStorage(ArrayList<Point> points, int maxX, int maxY, int minX, int minY)
{
this.points = points;
this.maxX = maxX;
this.maxY = maxY;
this.minX = minX;
this.minY = minY;
}
public ArrayList<Point> points;
public int maxX;
public int maxY;
public int minX;
public int minY;
}
public static ArrayList<Point> tesselate(PolygonStorage polygon)
{
ArrayList <Point> points = new ArrayList<Point>();
ArrayList <PolygonPoint> polyPoints = new ArrayList<PolygonPoint>();
for(int i = 0; i<polygon.points.size();i++)
{
polyPoints.add(new PolygonPoint(polygon.points.get(i).x, polygon.points.get(i).y));
}
Polygon poly = new Polygon(polyPoints);
Poly2Tri.triangulate(poly);
ArrayList<DelaunayTriangle> tris =(ArrayList<DelaunayTriangle>) poly.getTriangles();
for(DelaunayTriangle tri : tris)
{
for(TriangulationPoint tpoint : tri.points)
{
points.add(new Point((int)tpoint.getX(),(int) tpoint.getY()));
}
}
return points;
}
/**
public static ArrayList<Point> tesselate(Polygon polygon)
{
ArrayList<Point> points = new ArrayList<Point>();
Tessellator tess = new Tessellator();
double[] verticesC1 = new double[polygon.points.size()*3];
for(int i = 0; i< verticesC1.length; i+=3)
{
Point point = polygon.points.get(i/3);
verticesC1[i]= point.x;
verticesC1[i+1]= point.y;
verticesC1[i+2]= 0;
}
tess.gluBeginPolygon();
for(int i = 0; i <polygon.points.size(); i++)
{
tess.gluTessVertex(verticesC1, i*3, i);
}
tess.gluEndPolygon();
//Prints out the result of the tessellation.
for(int i = 0; i < tess.primitives.size(); i++) {
System.out.println(tess.primitives.get(i).toString());
}
//To draw the shape it is now a simple matter to put the vertex data you passed in initially into a VBO, and the indices returned
//into an IBO (Index VBO). You have the types of the primitives and the number of indices for each one. Drawing the result should
//be a walk in the park, as long as you have read the appropriate tutorials here or elsewhere.
for(int i = 0; i < tess.primitives.size(); i++)
{
Primitive prim = tess.primitives.get(i);
ArrayList<Integer> vIndex = prim.vertices;
if(prim.type==GL11.GL_TRIANGLE_STRIP)
{
for(Integer ii = 0; ii < vIndex.size()-1;ii++)
{
points.add(new Point((int)verticesC1[vIndex.get(ii)*3],(int) verticesC1[vIndex.get(ii)*3+1]));
points.add(new Point((int)verticesC1[vIndex.get(ii+1)*3],(int) verticesC1[vIndex.get(ii+1)*3+1]));
}
}
if(prim.type==GL11.GL_TRIANGLES)
{
for(Integer ii = 0; ii < vIndex.size();ii++)
{
points.add(new Point((int)verticesC1[vIndex.get(ii)*3],(int) verticesC1[vIndex.get(ii)*3+1]));
}
}
{
if(prim.type==GL11.GL_TRIANGLE_FAN)
{
Integer firstIndex = vIndex.get(0);
// points.add(new Point((int)verticesC1[vIndex.get(firstIndex)],(int) verticesC1[vIndex.get(firstIndex)+1]));
Integer[] vertexList = new Integer[vIndex.size()*3];
for(Integer ii = 0; ii < vIndex.size()-2;ii++)
{
vertexList[ii*3] = vIndex.get(0);
vertexList[ii*3+1] = vIndex.get(ii+1);
vertexList[ii*3+2] = vIndex.get(ii+2);
}
for(Integer vertex : vertexList)
{
if(vertex!=null)
{
points.add(new Point((int)(verticesC1[vertex*3]),(int)(verticesC1[vertex*3+1])));
}
else
{
break;
}
}
System.out.println(vertexList);
}
//points.add(new Point((int)verticesC1[vIndex.get(firstIndex)],(int) verticesC1[vIndex.get(firstIndex)+1]));
// points.add(new Point((int)verticesC1[vIndex.get(ii)*3],(int) verticesC1[vIndex.get(ii)+1]));
// points.add(new Point((int)verticesC1[vIndex.get(ii+1)*3],(int) verticesC1[vIndex.get(ii+1)*3+1]));
// points.add(new Point((int)verticesC1[index],(int)verticesC1[index+1]));
// System.out.println(verticesC1[index]+","+verticesC1[index+1]+","+verticesC1[index+2]);
}
//System.out.println(tess.primitives.get(i).toString());
}
return points;
}
**/
}

View File

@@ -3,37 +3,42 @@ package StevenDimDoors.mod_pocketDim.watcher;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import StevenDimDoors.mod_pocketDim.core.DimensionType;
import StevenDimDoors.mod_pocketDim.core.NewDimData;
public class ClientDimData
{
//We'll use public fields since this is just a data container and it's immutable
public final int ID;
public final int RootID;
public final int rootID;
public final DimensionType type;
public ClientDimData(int id, int rootID)
public ClientDimData(int id, int rootID, DimensionType type)
{
ID = id;
RootID = rootID;
this.rootID = rootID;
this.type = type;
}
public ClientDimData(NewDimData dimension)
{
ID = dimension.id();
RootID = dimension.root().id();
this.rootID = dimension.root().id();
this.type = dimension.type();
}
public void write(DataOutputStream output) throws IOException
{
output.writeInt(ID);
output.writeInt(RootID);
output.writeInt(rootID);
output.writeInt(type.index);
}
public static ClientDimData read(DataInputStream input) throws IOException
{
int id = input.readInt();
int rootId = input.readInt();
return new ClientDimData(id, rootId);
int rootID = input.readInt();
int index = input.readInt();
return new ClientDimData(id, rootID, DimensionType.getTypeFromIndex(index));
}
}

View File

@@ -3,38 +3,62 @@ package StevenDimDoors.mod_pocketDim.watcher;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import StevenDimDoors.mod_pocketDim.core.DDLock;
import StevenDimDoors.mod_pocketDim.core.DimLink;
import StevenDimDoors.mod_pocketDim.core.LinkType;
import StevenDimDoors.mod_pocketDim.util.Point4D;
public class ClientLinkData
{
public Point4D point;
public int orientation;
public ClientLinkData(DimLink link)
{
this.point= link.source();
this.orientation=link.orientation();
}
public ClientLinkData(Point4D point, int orientation)
{
this.point = point;
this.orientation=orientation;
}
public void write(DataOutputStream output) throws IOException
{
Point4D.write(point, output);
output.writeInt(orientation);
}
public static ClientLinkData read(DataInputStream input) throws IOException
{
Point4D point = Point4D.read(input);
int orientation = input.readInt();
return new ClientLinkData(point, orientation);
}
public final Point4D point;
public final DDLock lock;
public final LinkType type;
public ClientLinkData(DimLink link)
{
this.point = link.source();
this.type = link.linkType();
if (link.hasLock())
{
lock = link.getLock();
}
else
{
lock = null;
}
}
public ClientLinkData(Point4D point, LinkType type, DDLock lock)
{
this.point = point;
this.lock = lock;
this.type = type;
}
public void write(DataOutputStream output) throws IOException
{
Point4D.write(point, output);
output.writeInt(this.type.index);
boolean hasLock = this.lock != null;
output.writeBoolean(hasLock);
if (hasLock)
{
output.writeBoolean(lock.getLockState());
output.writeInt(lock.getLockKey());
}
}
public static ClientLinkData read(DataInputStream input) throws IOException
{
Point4D point = Point4D.read(input);
LinkType type = LinkType.getLinkTypeFromIndex(input.readInt());
DDLock lock = null;
if (input.readBoolean())
{
lock = new DDLock(input.readBoolean(), input.readInt());
}
return new ClientLinkData(point, type, lock);
}
}

View File

@@ -3,5 +3,6 @@ package StevenDimDoors.mod_pocketDim.watcher;
public interface IUpdateWatcher<T>
{
public void onCreated(T message);
public void update(T message);
public void onDeleted(T message);
}

View File

@@ -39,4 +39,13 @@ public class UpdateWatcherProxy<T> implements IUpdateWatcher<T>
{
return watchers.remove(receiver);
}
@Override
public void update(T message)
{
for (IUpdateWatcher<T> receiver : watchers)
{
receiver.update(message);
}
}
}

View File

@@ -1,4 +1,4 @@
package StevenDimDoors.mod_pocketDim.ticking;
package StevenDimDoors.mod_pocketDim.world;
import java.util.Random;
@@ -13,13 +13,12 @@ import StevenDimDoors.mod_pocketDim.config.DDProperties;
* Provides methods for applying Limbo decay. Limbo decay refers to the effect that most blocks placed in Limbo
* naturally change into stone, then cobble, then gravel, and finally Unraveled Fabric as time passes.
*/
public class LimboDecay implements IRegularTickReceiver {
public class LimboDecay {
private static final int MAX_DECAY_SPREAD_CHANCE = 100;
private static final int DECAY_SPREAD_CHANCE = 50;
private static final int CHUNK_SIZE = 16;
private static final int SECTION_HEIGHT = 16;
private static final int LIMBO_DECAY_INTERVAL = 10; //Apply spread decay every 10 ticks
//Provides a reversed list of the block IDs that blocks cycle through during decay.
private final int[] decaySequence;
@@ -28,7 +27,7 @@ public class LimboDecay implements IRegularTickReceiver {
private final DDProperties properties;
private final int[] blocksImmuneToDecay;
public LimboDecay(IRegularTickSender tickSender, DDProperties properties)
public LimboDecay(DDProperties properties)
{
decaySequence = new int[] {
properties.LimboBlockID,
@@ -51,16 +50,6 @@ public class LimboDecay implements IRegularTickReceiver {
this.properties = properties;
this.random = new Random();
tickSender.registerForTicking(this, LIMBO_DECAY_INTERVAL, false);
}
/**
* Applies fast Limbo decay periodically.
*/
@Override
public void notifyTick()
{
applyRandomFastDecay();
}
/**
@@ -88,7 +77,7 @@ public class LimboDecay implements IRegularTickReceiver {
* Picks random blocks from each active chunk in Limbo and, if decay is applicable, converts them directly to Unraveled Fabric.
* This decay method is designed to stop players from avoiding Limbo decay by building floating structures.
*/
private void applyRandomFastDecay()
public void applyRandomFastDecay()
{
int x, y, z;
int sectionY;

View File

@@ -0,0 +1,72 @@
package StevenDimDoors.mod_pocketDim.world;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.Vec3;
import net.minecraft.world.WorldProvider;
import net.minecraft.world.biome.WorldChunkManagerHell;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraftforge.client.IRenderHandler;
import net.minecraftforge.common.DimensionManager;
import StevenDimDoors.mod_pocketDim.CloudRenderBlank;
import StevenDimDoors.mod_pocketDim.mod_pocketDim;
import StevenDimDoors.mod_pocketDim.config.DDProperties;
import StevenDimDoors.mod_pocketDim.core.PocketManager;
import StevenDimDoors.mod_pocketDim.ticking.CustomLimboPopulator;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class PersonalPocketProvider extends PocketProvider
{
private DDProperties properties;
private CustomLimboPopulator spawner;
private IRenderHandler skyRenderer;
public PersonalPocketProvider()
{
super();
}
@Override
public Vec3 getSkyColor(Entity cameraEntity, float partialTicks)
{
setCloudRenderer( new CloudRenderBlank());
return this.worldObj.getWorldVec3Pool().getVecFromPool(1,1,1);
}
public boolean isSurfaceWorld()
{
return false;
}
@Override
protected void generateLightBrightnessTable()
{
float f = 0.0F;
for (int i = 0; i <= 15; ++i)
{
float f1 = 1.0F - (float)i / 15.0F;
this.lightBrightnessTable[i] = (15);
}
}
@Override
public double getHorizon()
{
return worldObj.getHeight()-256;
}
@SideOnly(Side.CLIENT)
@Override
public Vec3 getFogColor(float par1, float par2)
{
return this.worldObj.getWorldVec3Pool().getVecFromPool(1,1,1);
}
@Override
public int getActualHeight()
{
return -256;
}
}

Some files were not shown because too many files have changed in this diff Show More