Compare commits

...
329 Commits
Author SHA1 Message Date
Christian 2f7ad51a02 Fix the ghost tile entity issue @ the client. Closes #884
Fix stairs using fungible blocks
Fix fluid draining

Updated FML:
MinecraftForge/FML@b33e7808d8 Fix for new asset URLs
MinecraftForge/FML@82851384f1 Don't delete if md5 fails. Stops derpitude with new assets stuffs.
MinecraftForge/FML@3eb3c2700c Really fix asset and library downloading -.- Wish we could switch over to gradle and not have to go through this headake.
MinecraftForge/FML@f1b3381e61 Fix the "ordering" issue on windows. Windows is poop.
2013-12-18 00:26:02 -05:00
Lex Manos 45cc0bd87c Fix NPE in FakePlayers when they are created in a purely client side environment. To remove in 1.7 as FakePlayers should be used for server side interaction with the world on a player's behalf, not for client rendering. 2013-11-16 15:26:52 -08:00
Lex Manos 77c5caffd5 Fix NPE on specific tile entities when the block break event is canceled. Closes #863 2013-11-16 15:26:00 -08:00
Christian 28abe2cc3c Updated FML:
MinecraftForge/FML@23baf3a8ce Actually fix the nethandler code

Update patches
2013-11-13 19:16:24 -05:00
Christian 745d601831 Updated FML:
MinecraftForge/FML@da72640c7e Way to go, missing import. *sigh*
2013-11-13 07:46:04 -05:00
Christian 9fd39ebe79 Updated FML:
MinecraftForge/FML@b7f34629c3 Don't try and open GUIs on the server.
2013-11-12 18:05:04 -05:00
Christian 4f05808b8e Don't send openGui commands from the fakeplayer. Fixes thaumcraft and probably others. 2013-11-12 17:33:24 -05:00
Christian c8e249f919 Updated FML:
MinecraftForge/FML@6af42bc656 Add in null protection for client/server sides of handleChat
2013-11-12 17:22:20 -05:00
LexManos 7adccac8ec Merge pull request #855 from CovertJaguar/patch-4
Fix Water/Lava Fluid Localization
2013-11-12 10:00:37 -08:00
CovertJaguar 0a12840e68 Fix Water/Lava Fluid Localization 2013-11-12 01:05:13 -08:00
Lex Manos 1bd3e96e6e Noop out FakePlayer.addStat. 2013-11-11 13:15:06 -08:00
Christian 84fd2a147e Updated FML:
MinecraftForge/FML@3d25b4e793 Add in the ability to strip interface references for specific interfaces - this is probably mostly useful for scala scenarios where sythetic methods are generated and is not a substitute for using Optional.Method where appropriate. Closes #300
2013-11-09 14:36:42 -05:00
LexManos cfd368e18f Merge pull request #852 from MinecraftForge/breakevent
Merge BreakEvent branch, as nobody has told me that it breaks everything. And in prep from 1.7.
2013-11-09 00:43:58 -08:00
Christian a9c795b54c Updated FML:
MinecraftForge/FML@f4532410ec Change a couple of warnings, as a prelude to 1.7- preinit is now required for all GameRegistry activity, and every item and block REQUIRES registration.
2013-11-06 16:19:40 -05:00
Christian 8fb4546437 Updated FML:
MinecraftForge/FML@8f87021b0f Fix derp with custom properties. They work now!
2013-11-05 22:24:36 -05:00
Christian d316d74933 Updated FML:
MinecraftForge/FML@bc57ff9e83 Fix recursive API dependency resolution. Allows nested APIs, such as BuildCraft's
2013-10-31 09:40:18 -04:00
Christian ebfaf83bd9 Updated FML:
MinecraftForge/FML@de8ab934d8 Fix up duplicate entries
2013-10-30 22:46:40 -04:00
Christian a103fbc0e6 Updated FML:
MinecraftForge/FML@81fe1c9682 Add in an API marker for API type packages. This does several things: 1. Packages marked as API will generate a new "modid" (the provides) that can be depended on. 2. Packages marked as API will be searched systemwide, and anything declaring that package (even without the API marker) will get an implicit dependency on the API package. 3. The API package itself will get a soft dependency on the "owner" package.
2013-10-30 22:30:02 -04:00
Lex Manos a4fa417114 Add new recipe sorter that is called after all mods are initalized. This is disabled by default in 1.6 to not break current worlds as it may change machine's recipy outputs. Will enable by default in 1.7. Players may enable it in the forge config. 2013-10-30 14:08:03 -07:00
LexManos a47cca7e42 Merge pull request #841 from XCompWiz/biomecheck
Adds a Check to prevent Biome Replacement
2013-10-27 22:14:54 -07:00
XCompWiz 80ac3017bd Adds a Check to prevent Biome Replacement
Splits the BiomeGenBase constructor to create one which takes a flag
that indicates whether to insert the biome object into the biomeList
array.  The standard constructor calls the new one with the default of
true.  This allows biome wrapper-objects to exist.
2013-10-28 07:11:17 +02:00
Lex Manos ec517d5f28 Format strings properly in MC's internal logger. Fixes resource pack case warnings. 2013-10-27 11:00:10 -07:00
Christian 899b28bffe Updated FML:
MinecraftForge/FML@dac7f590ea Modify ordering of networkmod registration and mod instantiation. This fixes VersionCheckHandler logging an incorrect failure message due to NPE.
MinecraftForge/FML@f0dc530b28 Fix up documentation of VersionCheckHandler - it only ever accepted a String and only works on the NetworkMod annotated class
MinecraftForge/FML@243a21a353 Wrapping coremods as tweakers. Part 1.
MinecraftForge/FML@58a299aabc Attempt to inject coremods as tweakers, so both can share a dependency ordering
2013-10-27 13:53:05 -04:00
Lex Manos 217d5562ff Fix null pointer exception in BiomeDictionary causing the ChunkManager's config to not load/save. 2013-10-19 18:31:32 -07:00
Lex Manos b0f8d495bb Updated FML: MinecraftForge/FML@bf54d4d667 Make each mod's EventBus log a child of it's main logger. 2013-10-19 18:30:19 -07:00
Lex Manos 295542c357 Add wildcard versions of OreDict replacements, Closes #827 2013-10-18 18:58:31 -07:00
Christian 4db6c4cfc4 Updated FML:
MinecraftForge/FML@da4337efbf Fix up handling the new method signature data for NetworkCheckHandlers
2013-10-14 21:30:43 -04:00
Christian efc6b9abbb Merge branch 'master' of github.com:OniBait/MinecraftForge into breakevent 2013-10-13 23:02:20 -04:00
Christian 430d94de95 Updated FML:
MinecraftForge/FML@f92962bbbb Use null to empty, so missing values work. *sigh*
2013-10-13 22:44:15 -04:00
Christian e0cb56381f And remember to make the event class static *sigh* 2013-10-13 12:23:08 -04:00
Christian f9c283a2e5 Add in an event for zombie summoning. Allows for mods to control summoning behaviour, as well as custom summoned mob. 2013-10-13 12:21:57 -04:00
Christian 6c45b43eee And set the RIGHT variable *sigh* 2013-10-13 11:55:15 -04:00
Christian de69b7dfd0 And allow for tweaking baby chance as well. 2013-10-13 11:53:48 -04:00
Christian 5f5b509c7a Allow configuration of the zombie additional summoning mechanic. The vanilla mechanic is a little borked at times. 2013-10-13 11:39:23 -04:00
Christian 29606e2c39 Updated FML:
MinecraftForge/FML@58577775d2 Very minor style fixes
MinecraftForge/FML@96be82343c Merge pull request #280 from mc10/patch-1
MinecraftForge/FML@2714da1022 Primitive capability for tweakers to order. Add a "TweakOrder" integer property to your manifest, or accept the default of zero.
2013-10-13 11:33:41 -04:00
Lex Manos 412952be5b Prevent session from being printed to the console, also make sure the username is not empty. Causes a lot of bugs further down the line. 2013-10-12 23:10:23 -07:00
OniBait 79e0165362 Cleaned up patches to BlockOre and BlockRedstoneOre
Fixed trailing whitespace (it bugs me too)
2013-10-10 17:15:38 -05:00
OniBait e47a6402e1 Fixed formatting 2013-10-10 12:45:56 -05:00
Christian 465525119c Updated FML:
MinecraftForge/FML@fc3e7647d2 Support, and fix up, interface lists for Optional
2013-10-09 21:00:07 -04:00
Lex Manos 43a16d5389 Added some missing air checks to world gen features. 2013-10-09 02:47:05 -07:00
OniBait 303288e8b1 Merge branch 'upstream/master' 2013-10-08 19:04:54 -05:00
OniBait eb5940664c Add block break events based on @bloodmc's initial 1.5.2 Pull Request 2013-10-08 19:00:02 -05:00
Lex Manos 1a6743331b Fix repeated argument in CleintCommands. 2013-10-07 14:16:04 -07:00
Lex Manos c8df5b832e MinecraftForge/FML@a381874bb9 Delay sound system backend initalization to speed up startup and prevent race condition on some computers. 2013-10-06 11:23:36 -07:00
LexManos fc1089713f Merge pull request #792 from Eurymachus/opencontainer
Added PlayerOpenContainerEvent and added ForgeHooks.canInteractWith
2013-10-06 09:12:25 -07:00
Christian 0866d88126 Updated FML:
MinecraftForge/FML@bc64ceabef Optional shouldn't be constructable itself. It's purely a wrapper thing.
MinecraftForge/FML@55525f6d2e ModLoader is officially deprecated. It will all cease to be with 1.7.
2013-10-06 11:17:58 -04:00
Eurymachus 8d0b58ee6f Added PlayerOpenContainerEvent and added ForgeHooks.canInteractWith
- Used to override the canInteractWith during player tick
- setResult to ALLOW/DENY as required
- Defaults to Vanilla behaviour in any other instance.

Required for LittleBlocks Mod and to Assist Gullivers Mod
2013-10-06 03:58:13 +01:00
Christian fa41058ba1 Updated FML:
MinecraftForge/FML@63ba3aa009 Add in support for Optional interfaces and methods. Be gone coremods!
2013-10-04 17:21:14 -04:00
OniBait 296a484f4b Add block break events based on @bloodmc's initial 1.5.2 Pull Request 2013-10-04 00:15:19 -05:00
Lex Manos 7d5d191fc2 Fix missing patch which caused per-world storage to not be saved. 2013-10-01 09:59:13 -07:00
LexManos d55ddfcebc Merge pull request #808 from rhilenova/player_list
Added pre/post to player list rendering in GuiIngameForge.
2013-09-30 22:52:59 -07:00
rhilenova 7147cdb1c1 Merging in master. 2013-09-30 20:30:08 -04:00
Lex Manos cba1de122a Bump version number for todays changes. 2013-09-30 17:17:35 -07:00
Lex Manos 68669e2679 Make isItemStackDamageable() pass the stack to getMaxDamage() to use the Forge version of getMaxDamage().
Fixes display issues with mods using getMaxDamage(ItemStack) instead of the vanilla one. Closes #805
2013-09-30 17:15:18 -07:00
LexManos 4374f67759 Merge pull request #803 from benblank/block-power
Allow blocks to choose how they handle indirect power
2013-09-30 17:12:34 -07:00
rhilenova 5e998776cb Moved PLAYER_LIST event inside display check. 2013-09-30 20:06:04 -04:00
LexManos b09e72a2fc Merge pull request #793 from jrtc27/install-args
Pass arguments to install.sh and install.cmd to install.py
2013-09-30 16:59:51 -07:00
Lex Manos 2e3d1a3c09 Add cancelable EntityStructByLightningEvent, Closes #789 2013-09-30 16:56:34 -07:00
Lex Manos 96b4fd1da1 Stack sensitive version of Item.getItemStackLimit. Closes #771 2013-09-30 16:21:40 -07:00
LexManos d3c80c326a Merge pull request #772 from Lomeli12/master
Villager Trading GUI will now not open if Player is sneaking. Allowing for bypassing of the GUI.
2013-09-30 16:01:51 -07:00
Lex Manos b74d977225 Added all the vanilla records to the ore dictionary. Closes #731 2013-09-30 14:58:03 -07:00
Lex Manos 73202259fa Direct canApplyAtEnchantingTable through canApply Closes #740 2013-09-30 14:51:39 -07:00
Lex Manos 01cf29a202 Add pre and post event to rendering Chat, allowing for placement of the chat box. Closes #733 2013-09-30 14:32:12 -07:00
Lex Manos 71ececdbb4 Set densityDir in BlockFluidBase's constructor, closes #737 2013-09-30 14:02:23 -07:00
Lex Manos 81efd38fee Fix placement of snow cover over metadata 6. Closes #724 2013-09-30 13:52:17 -07:00
Lex Manos b3c715c312 Add the ability to register chat commands that only execute on the client. Works with autocomplete.
Client commands are gray when shown in the autocomplete list (when you press tab)
Closes #640
2013-09-30 13:08:57 -07:00
Ben Blank 8c54873afd move shouldCheckWeakPower to Forge section 2013-09-30 11:54:03 -07:00
Lex Manos 50b9abc13f Vanilla hopper should obey the IInventory contract, TileEntityHopper now takes into account IInventory.getInventoryStackLimit() when inserting items Closes #597. 2013-09-30 11:37:37 -07:00
Lex Manos ca351b527d Update workspace to point at launchwrapper 1.8 2013-09-30 11:36:28 -07:00
LexManos e4714bc4c5 Merge pull request #796 from HoBoS-TaCo/master
Added ItemTooltipEvent
2013-09-29 19:55:14 -07:00
HoBoS_TaCo 06e2f914c1 Added ItemTooltipEvent
This event is fired at the end of ItemStack.getTooltip(EntityPlayer, boolean), which in turn is called from it's respective GUIContainer. It allows an itemstack's tooltip to be changed depending on the player, itemstack or whether the advanced information on item tooltips is being shown, toggled by F3+H.
2013-09-30 12:41:52 +10:00
Christian 3805eddd34 Updated FML:
MinecraftForge/FML@5265e34a35 Fix null killing the server
2013-09-29 16:15:03 -04:00
rhilenova e842fd95b4 Added pre/post to player list rendering in GuiIngameForge. 2013-09-29 11:43:29 -04:00
Lex Manos 5f752fc967 MinecraftForge/FML@35ab9f52b0 Fix md5s for new checksums.sha1 in scala libraries. 2013-09-28 19:48:50 -07:00
Ben Blank f40bdeca97 allow blocks to choose how they handle indirect power 2013-09-28 17:56:19 -07:00
Christian 24017d6810 Updated FML:
MinecraftForge/FML@e356f4d713 Cross-modsystem compatibility fix with thanks to Mumfrey @ liteloader
MinecraftForge/FML@9b55f1f48f Attempt at a shared modlist implementation - should allow visibility between liteloader and fml for "mod list display"
2013-09-27 10:49:28 -04:00
Christian 5a24b2d73c Updated FML:
MinecraftForge/FML@bfc25bc5da Add to both the classloader and the parent
2013-09-26 13:01:44 -04:00
Christian 4c38edf532 Updated FML:
MinecraftForge/FML@9f0f9e7288 Fix deobf tweaker
2013-09-26 10:11:46 -04:00
Christian af24dc6096 Updated FML:
MinecraftForge/FML@ce6404fd5b TYPOS!!!
2013-09-26 09:34:05 -04:00
Christian 865e4e2b45 Updated FML:
MinecraftForge/FML@8f18a3de9a Separate deobf tweaker so it runs last. Should fix problems with cascaded tweakers expecting an obf environment.
2013-09-26 09:24:04 -04:00
Christian 41617a0227 Updated FML:
MinecraftForge/FML@8e26c99de3 Add debugging for deobfuscation
MinecraftForge/FML@1d902df581 Use the negative cache in latest legacylauncher.
MinecraftForge/FML@9815d8c379 Update for launchwrapper 1.8
2013-09-26 07:59:15 -04:00
Lex Manos ab2d8fa01b Add wrapper exception to the new Structure ID system to point to the correct Structure. 2013-09-25 16:58:36 -07:00
Lex Manos 80dfdbf749 Updated FML:
MinecraftForge/FML@fc8c3bef03 Update to new installer that uses xz compression and better support for non-standard jvms
2013-09-24 23:22:27 -07:00
Lex Manos dbd19b0cad Fixed typo in bounding box based ladder checks that caused potential infinite loops with entities in certian positions. Thanks Overmind for reporting it. 2013-09-24 22:46:18 -07:00
Lex Manos 70671858c2 Remove some side onlys on BiomeEvents that don't need them. 2013-09-24 21:43:56 -07:00
Lex Manos 0c064485b1 Update dev workspace for 1.6.4 .. 2013-09-24 21:43:25 -07:00
Christian 0d090070a9 Updated FML:
MinecraftForge/FML@a4de22c1ad And use the parent that's actually going to be valid. *sigh*
2013-09-24 08:42:37 -04:00
Christian 9029d380a3 Updated FML:
MinecraftForge/FML@70cffe6982 Herpaderp. Make addURL accessible. *sigh*
2013-09-24 07:34:44 -04:00
CovertJaguar 71c14b815e Fluid Rarity should have a default
Oops.
2013-09-23 22:54:46 -07:00
Christian 64d7c4eaa5 Updated FML:
MinecraftForge/FML@4a94c2c71b Fix NPE when loading second single-player world
MinecraftForge/FML@0e80fcb8f7 Merge pull request #284 from smcv/uninit
MinecraftForge/FML@39620f1e41 Fix injection of tweaker into system
2013-09-23 13:34:22 -04:00
Christian 62079e3549 Updated FML:
MinecraftForge/FML@79c39f8b7c Fix classpath for launchwrapper 1.7
2013-09-21 16:16:10 -04:00
cpw a632ec6ce6 Merge pull request #794 from alexbegt/master
Correcting SoundManager Transformer
2013-09-21 12:39:00 -07:00
Alexander Behrhof be8bccc72e Correcting SoundManager Transformer 2013-09-21 14:30:22 -04:00
Christian a7fde237bb Clean patch fuzz 2013-09-20 21:17:38 -04:00
James Clarke f68bdb0493 Pass arguments to install.sh and install.cmd to install.py 2013-09-21 01:43:22 +01:00
Christian e03a4db2b9 Updated FML:
MinecraftForge/FML@f6190e8752 Update workspaces for 1.6.4
2013-09-20 17:23:39 -04:00
Christian 54594ee1de Updated FML:
MinecraftForge/FML@25981706ef Update for MC 1.6.4
MinecraftForge/FML@0950b9fc84 Fix up a deep crash in the early server init hanging the client
2013-09-20 17:17:53 -04:00
Lex Manos 98aecd7f6b Move have handler creation up, to prevent NPE. 2013-09-19 16:47:46 -07:00
Lex Manos f58df75bea Remove duplicate access transformer 2013-09-19 16:46:30 -07:00
Lex Manos 43a6d0da62 Updated FML:
MinecraftForge/FML@e7dd728f95 Format the log messages through MessageFormat. Thanks CovertJaguar for the pointer.
MinecraftForge/FML@82d896a35e Make final transformers actually work on methods as well.
2013-09-19 13:05:15 -07:00
Lex Manos a525cab5ff Move the Structure data save files to per-world data folders. Vanilla saves them to the global folder which will potentially cause conflicts if two worlds generate 'Villages'. Which in the modded world is highly likely. Refer back to the long standing vanilla issue where nether 'villages' would override the overworlds villages, it's the same situation. 2013-09-18 23:37:23 -07:00
Lex Manos d39c279203 Make MapGenStructureIO name registration functions public, Any mod that has anything extending StructureStart or StructureComponent must register there classes and create a default (no parameter) constructor. 2013-09-18 20:52:52 -07:00
Lex Manos 0a7095afa9 Unfinalized Item.getIconIndex(ItemStack) 2013-09-18 19:33:28 -07:00
Lex Manos 36672fef83 Actually push the submodule update -.- 2013-09-18 16:18:19 -07:00
Lex Manos 57ea20d083 Bump version for new MC version. 2013-09-18 16:10:55 -07:00
Lex Manos 6c5ef9347c Updated FML:
MinecraftForge/FML@da70cdd35a Update tweaker for new Launcher API
MinecraftForge/FML@352117fd78 Update for new installer and thank you.
MinecraftForge/FML@40a34af431 Merge branch 'master' into newtweak
MinecraftForge/FML@e77d2547ad Update for pre-ninja 1.6.3 update
MinecraftForge/FML@34493b0d99 Update for real 1.6.3 update
MinecraftForge/FML@95afc95b24 Update mcp mod info
MinecraftForge/FML@ff75416a32 Update mc_versions data and commands patch and eclipse workspace
MinecraftForge/FML@8f2e675581 Update the src distro's eclipse workspace.
2013-09-18 16:10:38 -07:00
Christian 60da9094ef Updated FML:
MinecraftForge/FML@81328b6684 Add in support for using a mirror list and provide checksums for packed download of libs
2013-09-15 23:00:07 -04:00
Christian f9087cb291 Revert "Added a RenderType that allows Map-style rendering w/o inheriting from"
This reverts commit eb4688bf5e.

Conflicts:
	patches/minecraft/net/minecraft/client/renderer/ItemRenderer.java.patch
2013-09-14 18:43:18 -04:00
Christian 635f13f825 Fix broken PR from vilml. TEST! 2013-09-14 18:13:58 -04:00
cpw 55830256d3 Merge pull request #784 from viliml/patch-1
Prevent NPE in fluid lookup for block
2013-09-14 11:28:06 -07:00
viliml ac58bb2f5a Prevent NPE in fluid lookup for block 2013-09-14 20:16:46 +02:00
cpw a066018c9f Merge pull request #782 from CovertJaguar/patch-1
Allow Fluids to have Rarities
2013-09-14 05:17:34 -07:00
Christian 0bc9138aa4 Fix the divider 2013-09-13 22:57:29 -05:00
CovertJaguar b626c888b0 Allow Fluids to have Rarities
Used for tool tips.
2013-09-13 20:17:12 -07:00
Christian 492cbc3628 Move stuff around a bit- also tie range and enabled to options. 2013-09-13 22:11:59 -05:00
Christian 32353f0db1 Merge branch 'master' of github.com:Adubbz/MinecraftForge into Adubbz-master 2013-09-13 21:04:54 -05:00
Adubbz 7aa43a4217 Sky colours now smoothly transition
Made transitions even smoother

Sky colours now smoothly transition
2013-09-14 12:00:06 +10:00
Christian 09580515a0 Tweak patch comment 2013-09-13 20:45:30 -05:00
Christian 65165cd41c Merge branch 'mapStyle' of github.com:Matchlighter/MinecraftForge into Matchlighter-mapStyle 2013-09-13 20:11:13 -05:00
Christian 391668114d Merge branch 'master' of github.com:micdoodle8/MinecraftForge into micdoodle8-master 2013-09-13 20:06:50 -05:00
iChun ae80a7b322 Allows proper raytracing from actual player eye position rather than hardcoded eye heights. 2013-09-13 19:56:28 -05:00
Christian 9093263d8c Merge branch 'fovhook' of github.com:MachineMuse/MinecraftForge into MachineMuse-fovhook 2013-09-13 19:40:19 -05:00
Christian e008ae3ef1 Updated FML:
MinecraftForge/FML@b5af446d71 Fix sidedness derp in LanguageRegistry.
2013-09-13 19:05:28 -05:00
Lomeli12 c0164f29cd Villager Trading GUI will not open if Player is sneaking. 2013-09-10 14:08:29 -07:00
micdoodle8 9ddb57297f Check if block is air instead of just ID zero when growing from stem block. 2013-09-09 17:53:19 -04:00
Matchlighter eb4688bf5e Added a RenderType that allows Map-style rendering w/o inheriting from
ItemMap.
2013-09-07 22:50:18 -06:00
Christian 519da32391 The partial tick should be available for all render player events. Weird it wasn't. 2013-09-07 16:25:30 -04:00
Christian f9728e8f3f Redo harvest event. This time with simpler logic, that should be less liable to weird "missing" stuff. 2013-09-07 00:10:08 -04:00
Christian 25bfc1407b Reverting HarvestEvent, for new implementation 2013-09-06 23:39:48 -04:00
Lex Manos 303bd03533 Fix bug where guis were not closed properly, resulting in signs not having there text set. 2013-09-06 15:27:02 -07:00
Christian 6b54b52ec4 Change trigger calculation so entities get some time to age before refiring the event. 2013-09-06 16:46:44 -04:00
Lex Manos 89becaca02 Create helper apply_patches script and add paramter to change patch output folder. 2013-09-06 13:32:26 -07:00
Christian d9ca67e162 Change from Cancelable to using a Result. This means you can force despawn mobs you
don't want around anymore. Also, deferred check to once every 20 ticks. May tune it
down further or make it a config if this event is a lag issue.
2013-09-06 16:05:29 -04:00
Daniel García ff655de27e Create es_ES.lang 2013-09-06 13:28:48 -04:00
MachineMuse ee0cb12810 Added fov hook
Small formatting changes (opening braces on new line)
2013-09-06 13:25:47 -04:00
Christian 6da6e9da07 Add a cancellable despawn event- allows mods to decide to prevent the despawning
of certain otherwise normally despawnable mobs.
2013-09-06 13:19:51 -04:00
MachineMuse ad41dfaeaf Small formatting changes (opening braces on new line) 2013-09-05 18:46:05 -06:00
MachineMuse 7a0a7bf8e0 fixed merge 2013-09-05 18:43:27 -06:00
MachineMuse 65551ce233 Added fov hook 2013-09-05 18:39:27 -06:00
Christian c63efa917d Add some javadoc to the HarvestBlock event. 2013-09-05 16:24:50 -04:00
Christian 7544055fa4 Clean up some formatting. 2013-09-05 13:16:01 -04:00
Christian cb5b5cde1f Use the dropchance from the event. 2013-09-05 13:01:25 -04:00
Christian a58a7fd365 Merge branch 'sometweaks' 2013-09-05 12:22:31 -04:00
Christian 99c6662f9d Add in a block reverse lookup for fluids. Closes #749 2013-09-05 12:08:16 -04:00
Christian ca0e32cfd2 Add a harvestblock event, to allow mods to intercept and change the drops for blocks. Don't abuse this, or we'll have to take safety measures.
Fires for both silktouch and non-silktouch harvesting, and provides the player. Note, you may need to
change your break overrides to pass on the player for best results.
2013-09-05 11:57:27 -04:00
Christian c84d99aa22 Defer firing CreateDecorator until it's likely mods have had a chance to register their listener. Should close #759 2013-09-05 10:08:02 -04:00
Christian 0443ef5a9e MachineMuse, remember, there's TWO model formats supported! 2013-09-05 09:14:10 -04:00
Christian e962c2a94d Merge branch 'master' of github.com:jk-5/MinecraftForge into sometweaks
Conflicts:
	patches/minecraft/net/minecraft/client/Minecraft.java.patch
2013-09-05 08:39:15 -04:00
Christian 8c2e171a16 Merge branch 'master' of github.com:mhahn1976/MinecraftForge into sometweaks 2013-09-05 08:26:11 -04:00
Christian 4fb8eb96d0 Merge branch 'french' of github.com:robin4002/MinecraftForge into sometweaks 2013-09-05 08:23:29 -04:00
Christian 7549eb90a7 Add a bit of javadoc 2013-09-05 08:22:28 -04:00
Christian df132a0296 Merge branch 'displayname' of github.com:MachineMuse/MinecraftForge into sometweaks
Conflicts:
	patches/minecraft/net/minecraft/entity/player/EntityPlayer.java.patch
2013-09-05 08:20:49 -04:00
Christian e499a6d375 Merge branch 'objTessellation' of github.com:MachineMuse/MinecraftForge into sometweaks 2013-09-05 07:58:56 -04:00
Christian fe5f5e690e Fix patch for new MCP naming. 2013-09-05 07:57:21 -04:00
Christian 21cd975ae3 Merge branch 'mouseevent2' of github.com:MachineMuse/MinecraftForge into sometweaks 2013-09-05 07:47:52 -04:00
Christian 32073a5bc1 Reduce patch size significantly 2013-09-05 07:45:29 -04:00
iChun 6cf8408752 Fix player push out of blocks clientside being hardcoded and not based on entity size.
Added player eyeHeight field to allow changeable eye heights of players rather than being hardcoded per player class as well as add a getDefaultEyeHeight function.
2013-09-05 14:57:34 +08:00
MachineMuse 7a77b61ddd fixed logic error 2013-09-04 15:27:45 -06:00
MachineMuse ad09526bee inserted hook into Minecraft.java 2013-09-04 15:05:29 -06:00
MachineMuse e3e3ea54f9 Added mouse event 2013-09-04 15:01:37 -06:00
MachineMuse cb9c26d49c Memoization of display name result 2013-09-04 14:22:22 -06:00
Christian cf88896ad7 Update version to 9.10.1 for mcp naming changes. 2013-09-03 18:09:07 -04:00
Christian 0d44234239 Update forge for MCP naming updates
Updated FML:
MinecraftForge/FML@d0c6e92900 Update MCP data
2013-09-03 18:04:12 -04:00
MachineMuse 96c045137d Merge remote-tracking branch 'forge/master' into objTessellation 2013-09-03 15:45:45 -06:00
MachineMuse 0e3037e85d Added display name hook 2013-09-03 14:55:11 -06:00
Christian 5c334d7627 Fix possible NPE in searching code. 2013-09-02 15:44:27 -04:00
Christian 7246914605 Updated FML:
MinecraftForge/FML@2a9c485edc Remove @SideOnly from 70318 (getDistance) it makes no sense that it's not on the server.
2013-09-02 12:24:57 -04:00
Christian d9b72a2282 Updated FML:
MinecraftForge/FML@a13598b17e Use java 1.6 compatible method of closing the zip file. Stops stupid compile error.
2013-09-02 00:13:23 -04:00
Christian 4eb05ed571 Small fix to container registry. emptyContainer is not null, it's "NULL_EMPTYCONTAINER" now and won't match any valid container. 2013-08-28 22:16:59 -04:00
Christian 5a8def7d00 Tweak the release to add in assets to the distributable. *sigh* 2013-08-28 07:59:45 -04:00
robin 90be31ddc8 create french localization 2013-08-28 13:14:30 +02:00
Christian dddb9b3189 Add some starting work for a forge tps command. Also update coremod for new FML behaviour 2013-08-27 23:07:30 -04:00
Christian 0c06d3b47a Updated FML:
MinecraftForge/FML@1c9a853868 Allow coremods to properly inject asset readers.
MinecraftForge/FML@40b54013b4 Allow server side lang file injection, hopefully
2013-08-27 23:04:48 -04:00
Michael Hahn cc96840aa8 capacity was not respected
Updated to properly calculate the amount of free space in the tank
before checking that against the amount of the resource.
2013-08-26 12:21:31 -05:00
jk-5 f78eba09fd Added GuiOpenEvent
You can use this for a clean way to override guis, without needing an
TickHandler to check if the gui you want to override is open and show
your own gui

Proper close check
2013-08-24 09:32:34 +02:00
Christian b2c1eae652 Updated FML:
MinecraftForge/FML@b993cf4a98 More exception handling for less derpiness.
2013-08-20 21:01:02 -04:00
Christian 8fed427251 In the time honoured tradition of trying to fix vanilla, we today attempt to patch the pathfinding AI so that it doesn't lag when
there's a lot of entities. Basically, if the zombie can't reach the villager, backoff subsequent pathfinding attempts. Hopefully
should really help with lag caused by zombie swarms.
2013-08-20 11:55:57 -04:00
Christian b2d309b17e Allow multipass RenderItem rendering for terrain icons too. Should fix sengir's saplings. 2013-08-19 16:32:47 -04:00
Christian 8d6f893083 Updated FML:
MinecraftForge/FML@913f6f6d36 Try and use the relaunch log, which should be classloaded..
MinecraftForge/FML@ac065ff5f7 Reset the IWorldGenerator seed for each mod, before calling. That should mean worldgen is consistent and not dependent on mod ordering, or mod sideeffects.
2013-08-19 15:28:50 -04:00
LexManos faba7e2a07 Skipp toss event for null entity items. Closes #732 2013-08-19 10:45:57 -07:00
LexManos baf1e771e9 Cache world on all render passes in case some mod disables the first pass. 2013-08-19 10:45:29 -07:00
LexManos 461a30812b Fix bug with custom Fluids. You can now drown in them! 2013-08-18 23:16:36 -07:00
Christian 4b64c15ae8 Updated FML:
MinecraftForge/FML@9468e41bbf Fix up scala refs, for better results
2013-08-18 19:02:20 -04:00
cpw 3625a409a5 Merge pull request #730 from Soaryn/patch-1
Adds Temperature to Lava
2013-08-17 11:17:34 -07:00
Christian 8533f974e8 Updated FML:
MinecraftForge/FML@ffdd056a18 Check keys, not values *sigh*
2013-08-17 13:28:06 -04:00
Christian 667db45b1d Updated FML:
MinecraftForge/FML@f157e7a6ec And more coremod logging
2013-08-17 13:15:18 -04:00
Christian bafbac3d51 Updated FML:
MinecraftForge/FML@4a9d0f9bd5 Add in some log information
2013-08-17 13:10:43 -04:00
Christian 92c095412d Updated FML:
MinecraftForge/FML@0398916666 And actually instantiate the collection *sigh*
2013-08-17 12:57:37 -04:00
Christian ea31a51285 Updated FML:
MinecraftForge/FML@dec9a3924d Add in "FMLCorePluginContainsMod" in the manifest. If this value is present, FML will attempt to parse your mod jar file as a normal mod file as well, instantiating mod containers there.
2013-08-17 12:49:37 -04:00
Christian 8f66346aeb Updated FML:
MinecraftForge/FML@2470120680 Clean up a couple of resources. Also, don't parse jars just because they're in the mods dir
2013-08-17 11:44:06 -04:00
Christian 9741d6348f Updated FML:
MinecraftForge/FML@9a5e24e338 Fix stupid derp is stupid. Closes #275 and means sp614x can do his thing
MinecraftForge/FML@ba90b61607 Make sure we only add args to the argument list if a tweaker hasn't already. Should fix LiteLoader compatibility issue.
2013-08-17 11:13:02 -04:00
Soaryn 8c762223a4 Adds Temperature to Lava
Missing lava temperature. Feel free to change it to any value. 
1300K is the typical max for Magma so wasn't sure what was desired. Regardless, better than the same temp as water at 295K 😄
2013-08-15 19:55:15 -04:00
LexManos ffd2fbcc84 Fix NPE in enchangint books. 2013-08-13 15:25:09 -07:00
LexManos b0f4497bbe Fix inverted case, search works now. 2013-08-11 16:01:27 -07:00
LexManos 97f6138cf8 Merge pull request #606 from Shukaro/master
Add stone and cobblestone to ore dictionary
2013-08-10 23:29:01 -07:00
LexManos f65f042910 Addition: Added isAllowedOnBooks hook to Enchantments Closes #589 2013-08-10 23:23:41 -07:00
LexManos 7ad79b42bc Deprecate Block.addCreativeItems, Kill in 1.6.3+ Closes #655 2013-08-10 23:07:49 -07:00
LexManos 4f172ae9a5 Merge pull request #679 from Chicken-Bones/invchanged
Add onNeighborTileChange callback to block by generalizing func_96440_m ...
2013-08-10 22:53:43 -07:00
LexManos 5fadba7ddc Merge pull request #702 from MrMasochism/master
Added new function for control over dismount underwater
2013-08-10 22:07:02 -07:00
LexManos ffd4d4afc3 Allow creative tabs to have a search box if they want to Closes #592 2013-08-10 22:04:58 -07:00
LexManos d304f40295 Merge pull request #717 from tommy1019/patch-3
Fixed Fluid Non-Solid Block Duplication
2013-08-10 19:47:21 -07:00
LexManos ffd4b38801 Add optional feature to check entire bounding box for ladders. Closes #709 2013-08-10 19:39:06 -07:00
tommy1019 efb27ed1ea Fixed Classic Checking 2013-08-09 12:25:56 -05:00
tommy1019 aab3385c2d Fixed Double Item Drop 2013-08-09 12:23:05 -05:00
tommy1019 9e732ee935 Fixed Fluid Non-Solid Block Duplication 2013-08-08 18:38:46 -05:00
LexManos 571e441502 Only refresh vanilla tile entities when IDs change. 2013-08-07 18:24:50 -07:00
LexManos 18c8ac0b31 Updated FML:
MinecraftForge/FML@f275a24b43 Add in some reverse lookup methods for game registry data
MinecraftForge/FML@cb05c8c4aa Add missing SideOnly in BaseMod
MinecraftForge/FML@1857064afa Merge pull request #266 from grompe/patch-1
MinecraftForge/FML@182aa9c0cb Fixed install.sh not passing arguments to install.py
MinecraftForge/FML@f46a538b41 Merge pull request #268 from Bo98/sh-args-fix
MinecraftForge/FML@29ef3d5ab4 Update installer.
2013-08-06 11:49:39 -07:00
Christian 7d700916d9 Merge branch 'miscchanges' 2013-08-04 22:27:55 -04:00
LexManos b0f5f88482 Merge pull request #610 from purpleposeidon/patch-1
Add an InputStream constructor to WavefrontObject
2013-08-04 16:56:26 -07:00
LexManos c6030b9125 Merge pull request #704 from StormTiberius/master
Adds cloud height to WorldType
2013-08-04 16:54:44 -07:00
cpw 81e4ae2af9 Merge pull request #706 from heldplayer/fluidRendering
Fix small derp
2013-08-03 17:29:04 -07:00
cpw 543535e1a0 Merge pull request #705 from heldplayer/fluids
Fix render colour on bottom of fluids
2013-08-03 17:28:53 -07:00
Heldplayer 647f6fdf34 Fix small derp 2013-08-03 23:42:38 +02:00
Heldplayer 90e0eaf5f5 Fix render colour on bottom of fluids 2013-08-03 23:20:34 +02:00
StormTiberius 4ea7e8d828 Add cloud height to WorldType 2013-08-03 05:45:22 +03:00
Christian cf4f1377d4 Merge branch 'master' of github.com:EnderShadow/MinecraftForge into miscchanges 2013-08-01 07:20:30 -04:00
Matthew Warren bf8f5aa306 added temperature to fluids
it could be useful for blocks that are affected by temperature
2013-07-31 22:15:42 -05:00
MrMasochism 9564575d77 Added a new function to allow control over whether an entity is dismounted when the entity it is riding goes under water 2013-08-01 08:02:19 +12:00
cpw 9776e0937a Merge pull request #700 from iChun/miscchanges
Fix RenderLivingEvent.Pre/Post not being fired by most Renders.
2013-07-31 01:35:18 -07:00
iChun 7b9971b20f Fix RenderLivingEvent.Pre/Post not being fired by most Renders. 2013-07-31 08:03:10 +08:00
cpw 89d9fb3556 Updated FML:
MinecraftForge/FML@57befa89bb Fix keybindings being derped
MinecraftForge/FML@1d84e8063e Temporarily add a version of 'reobfuscate.py' that will resolve complex reobfuscation graph issues with specialsource. Copy it over 'reobfuscate.py' in the mcp runtime dir. Hopefully will have an MCP/specialsource fix in the coming days.
2013-07-28 22:40:13 +02:00
cpw c3f62ed8bf Tweak setBlock in update tick - it should only send serverside updates for
source blocks. Experimental attempt to fix worldgen issues for fluid blocks
2013-07-28 19:25:51 +02:00
cpw 5c5cf3e7e7 Fix formatting error in PR 2013-07-28 19:15:00 +02:00
cpw 94045ea73e Merge pull request #695 from tommy1019/master
Fluid Rendering Fixes
2013-07-28 02:17:16 -07:00
tommy1019 e15c596e42 Fluid Rendering Fixes 2013-07-27 20:32:21 -05:00
cpw b317d10ade Add a translation map for looking up legacy liquid names to convert
to new fluid names.
2013-07-28 01:06:16 +02:00
cpw 31bd8d438d Add support for loading legacy liquid stacks as new fluid stacks.
Requires having been written with the "liquidname" code from forge 1.5.x
2013-07-28 00:53:23 +02:00
cpw 8b78f21199 Merge branch 'master' of github.com:tommy1019/MinecraftForge into miscchanges 2013-07-27 23:59:51 +02:00
cpw 8a8f5af084 Fix names for water/lava fluids. Closes #689 2013-07-27 23:37:06 +02:00
cpw f5a8974bb6 Merge branch 'master' of github.com:iChun/MinecraftForge into miscchanges 2013-07-27 22:57:44 +02:00
CovertJaguar fd5b7359e2 Add SneakClick bypass to client 2013-07-27 00:30:54 -07:00
tommy1019 077e05e0ed Fixed fluids eating each other
Fluids check for other fluids density before flowing, if their density
is higher they can flow into the other fluid, if not they can't.
2013-07-26 16:25:40 -05:00
iChun abdcd23d8b Update RendererLivingEntity.java.patch 2013-07-26 12:51:42 +08:00
iChun fb04d10886 if statement added 2013-07-26 12:49:14 +08:00
iChun 3e8711580e Add Pre and Post events firing for RendererLivingEntity 2013-07-26 12:46:52 +08:00
iChun f48dafda7e Add Pre and Post events for RenderLivingEvent 2013-07-26 12:38:17 +08:00
tommy1019 a42369e081 Fluid Render Fix
Formatting
2013-07-25 18:38:29 -05:00
LexManos 6397939c9e Merge pull request #665 from copyboy/master
Fix getArmorTexture by passing it the subtype
2013-07-24 13:18:31 -07:00
copyboy c9af365d44 Fix getArmorTexture by passing it the subtype 2013-07-24 22:12:38 +02:00
LexManos b6d543f15e Re-added deprecated liquids system. To be removed next major MC versions after issues with Fluids are fixed. (reverse-merged from commit 9b5208fa30)
This WILL be removed and should not be developed against aside for a temporary 1.6 release.
2013-07-22 15:19:35 -07:00
LexManos 8c3ebc7f87 Remove SideOnly(Client) in IBlockAccess.isAirBlock 2013-07-21 11:01:38 -07:00
LexManos ee70b21460 MinecraftForge/FML@10b16d32da Use json 2.9.1 nightly for OSX in release json like vanilla does. 2013-07-17 12:38:53 -07:00
LexManos acb6777ab5 General code cleanup of Fluid system. Made Fluid icons and associated functions non-sided. 2013-07-16 21:40:49 -07:00
LexManos f7ab5684e9 MinecraftForge/FML@3f21a2c1b4 Stupid spaces and windows escaping -.- 2013-07-16 14:35:22 -07:00
LexManos 8a8af5265e Package 'version.json' with universal jar for maunchers to use. It's the json used by the vanilla Minecraft launcher for Forge. 2013-07-16 13:55:31 -07:00
LexManos f72d672e0d MinecraftForge/FML@b2958c9066 Add quotes for paths with spaces -.- 2013-07-16 13:54:08 -07:00
LexManos 094c2bca2e MinecraftForge/FML@9520978b81 Use a temporary file for recompile's command line to combat command length to long issues. 2013-07-16 13:12:46 -07:00
Chicken Bones 5d5d4cb448 Add onNeighborTileChange callback to block by generalizing func_96440_m to all blocks rather than just comparators. 2013-07-17 04:42:45 +10:00
LexManos 380c4ad2da Updated FML: MinecraftForge/FML@4981aa3421 Fix potential NPE in villager skin registry. Closes #678 2013-07-16 10:34:54 -07:00
LexManos e57f1c230c Merge pull request #675 from Soaryn/patch-1
Fixes Vanilla Fluid Still Icon Setters
2013-07-15 22:36:56 -07:00
Soaryn 88e0ecf2cf Fixes Vanilla Fluid Still Icon Setters
Fixes null icons from being set for both the still water/lava icons, and sets the correct Icon.
2013-07-16 01:27:39 -04:00
LexManos 56ab2fd797 Updated FML: MinecraftForge/FML@c48b48ee15 Fix server launching. 2013-07-15 10:58:11 -07:00
Christian 81cce7b6ac Fix for new location of mcp logo. 2013-07-14 14:22:57 -04:00
Christian 745fa93f3f Updated FML:
MinecraftForge/FML@0378355c37 The server.classpath generates the runtime manifest, so it needs the non-debug asm jars.
MinecraftForge/FML@a3f48734ff Fix up jar sanity check code. FML validation of the jar works now and doesn't derp classloading.
MinecraftForge/FML@9947ba8503 Fix logo handling. no more NPE if the logo can't be found. Also, fix location of mcp logo now.
2013-07-14 13:47:53 -04:00
LexManos c5af747da9 Monkey patch to try and make print flush properly. 2013-07-12 04:08:29 -07:00
LexManos c40499ab05 Update changelog generator to point to new jenkins. 2013-07-12 03:09:54 -07:00
LexManos 2e1aa99f54 MinecraftForge/FML@c625ef3009 Update Forge signature for new private key 2013-07-12 03:09:24 -07:00
LexManos 70a6a316d7 Updated FML:
MinecraftForge/FML@7348929819 Kill release time scala libraries, to be re-evaluated after all movement is done and shit is fixed. May require manual instalation for mods that use scala.
MinecraftForge/FML@6de36d78f5 Coremods now have a primitive dependency capability. Also, we search mods dir for special "TweakClass" manifests. These are using the vanilla tweak mechanism to inject into Minecraft. Helpful for other "platform" systems, when you don't want to have to deal with json changes!
MinecraftForge/FML@d4b30422b6 Update build and eclipse workspaces for debug asm.
2013-07-12 00:34:32 -07:00
LexManos e418dddbcf MinecraftForge/FML@b9f4b02cb0 Kill mcp's truncate method, for more useful logs. 2013-07-10 15:24:53 -07:00
LexManos bf127348c9 Merge pull request #661 from Adubbz/master
Made eating particles compatible with metadata
2013-07-10 15:24:07 -07:00
Christian 75907e3815 Updated FML:
MinecraftForge/FML@e44e8b3112 Force a global asset scan prior to mod construction : you should be able to reference assets anywhere in your mod now.
MinecraftForge/FML@20e93a412e Fix up logos in the mod screen. Clean up some unnecessary casts and suppressions, use the -debug asm library at dev time, since it contains full symbols and code in compiled form.
2013-07-10 17:30:45 -04:00
Adubbz c4ad7c3e2c Made eating particles compatible with metadata
Removed extra spaces

Made eating particles compatible with metadata
2013-07-10 20:39:15 +10:00
LexManos 562e8e8021 Re-add reverted patch AGAIN cpw check your commits -.- 2013-07-09 12:56:34 -07:00
Christian c3fbd27a8d Updated FML:
MinecraftForge/FML@bab4d87ce7 Update FML for new stealth update for 1.6.2
2013-07-09 15:36:47 -04:00
Christian a990c0bdc8 Remove forge ISidedInventory, deprecated since 1.5. 2013-07-09 11:38:54 -04:00
Christian 561b0fbe55 Allow optional rider interaction for entities, thanks for the suggestion Vswe.
Updated FML:
MinecraftForge/FML@7af5c21d74 @InstanceFactory was set to look for Fields instead of methods
MinecraftForge/FML@bc9d1fe657 Merge pull request #254 from CaptainShadows/patch-1
2013-07-09 11:23:49 -04:00
Christian 475918a1ca Updated FML:
MinecraftForge/FML@97269a5e3d Decode the file URL. Hopefully will make things work more..
MinecraftForge/FML@d4d522c597 And don't forget to remove the test code
2013-07-09 08:33:05 -04:00
LexManos a85d82a859 MinecraftForge/FML@c913258ca3 Disable signature check of client for now, it's broken. 2013-07-09 05:04:50 -07:00
LexManos ae97ad2bca Updated FML:
MinecraftForge/FML@dfa3a2665d Add MC Version to installed version name.
MinecraftForge/FML@e91431fb70 Don't validate signatures on servers, they are not signed.
MinecraftForge/FML@c7ab872c85 Temporarily disable GuiModList's Mod logos.
2013-07-09 03:35:52 -07:00
LexManos 8eddb7f1b9 Updated FML:
MinecraftForge/FML@c997f2adbc FML now verifies that the minecraft jar is correct and intact. This is intended to discourage those who think that modifying the minecraft jar is still acceptable.
MinecraftForge/FML@0db4624b27 Don't initialize the server.
MinecraftForge/FML@4fa375683f Fix NPE in new debug line when patch targets don't exist.
2013-07-09 01:30:22 -07:00
LexManos 29fabb12e0 Proper return for getRegisteredFluidContainerData thanks Soaryn. Ref issue #634 2013-07-08 18:54:03 -07:00
LexManos 34bcca2640 Fix accedential reverted patch. 2013-07-08 18:35:34 -07:00
Christian 38bd039a93 Make resourcelocation the class available on the server. 2013-07-08 19:40:15 -04:00
Christian 033eedb50f Drop two domain related fixes that have been applied in vanilla.
Updated FML:
MinecraftForge/FML@c47d08c89d Tweak debug data on patched classes
MinecraftForge/FML@dbf5fe38ce We now generate an adler32 checksum for each patched file and verify at load time that they match. Mismatch won't crash, but will emit a big warning..
MinecraftForge/FML@e88a0cd13f Update for stealth update. Thanks mojang!
MinecraftForge/FML@2336002f20 The game is going to exit in face of patch mismatch, unless you force it to run with fml.ignorePatchDiscrepancies in the system properties.
2013-07-08 14:44:51 -04:00
LexManos 51ca5e028b Bump version to 9.10 for new MC version and removal of Fluids. 2013-07-07 14:05:48 -07:00
LexManos 9b5208fa30 Remove deprecated Liquids API, Use new Fluids system as replacement. 2013-07-07 14:05:23 -07:00
LexManos 85fd1d010d Updated FML:
MinecraftForge/FML@1d0384f8f6 Update for 1.6.2 and MCP 8.04
MinecraftForge/FML@111b0216fd Add the jsons for 1.6.2
MinecraftForge/FML@6f96d89e2b Update eclipse workspaces for 1.6.2
2013-07-07 14:03:26 -07:00
Christian 499610e44f Updated FML:
MinecraftForge/FML@c97ac284a5 Update ModLoaderFuelHelper.java
MinecraftForge/FML@3a200e901e Fix coremod injection into main system. Should stop double-dipping coremods.
MinecraftForge/FML@2676c8999c Update mcp data. fixes #248
MinecraftForge/FML@5990e29af7 Merge pull request #247 from jk-5/patch-1
MinecraftForge/FML@adc8972277 Add cascadedTweaks. This will allow simple coexistence for any other mod framework using the tweaker system as well. Hi Voxel and LiteLoader!
2013-07-07 00:58:32 -04:00
LexManos 13294083a9 Merge pull request #645 from XCompWiz/bedspawn
Makes player-specific spawnpoints dimension aware
2013-07-06 14:41:07 -07:00
XCompWiz 5f203ce808 Makes player-specific spawnpoints dimension aware
Makes ServerConfigurationManager correctly get player-specific spawn
point for the target dimension
Changes EntityPlayer to store and save a (bed) spawn point for every
dimension, as well as transfer them to respawn "clones"
2013-07-06 16:24:37 +03:00
LexManos dfc26937ca Re-gather list of Icons when atlas textures are stitched, allows for addition/removal of blocks/items after the atlas's inital constrction. 2013-07-05 22:50:55 -07:00
LexManos 22be4b49d5 Fix enchantment effect on single pass items. Closes #644 2013-07-05 16:55:42 -07:00
LexManos bc932a28ae Merge pull request #642 from MinecraftForge/newliquid
New liquid system
2013-07-04 13:11:36 -07:00
LexManos e9f1c83ff8 Mark old liquid system as deperated to be removed next Minecraft release. 2013-07-04 12:39:49 -07:00
LexManos 30be6d4bab Merge remote-tracking branch 'refs/remotes/origin/newliquid' into newliquid 2013-07-04 12:17:36 -07:00
Christian 1169ba9efb Merge branch 'master' into newliquid 2013-07-04 12:07:32 -07:00
LexManos 33ec5cdc44 Updated FML: MinecraftForge/FML@54e06e841d Move Resource refreshing until affter postInit. 2013-07-03 22:29:42 -07:00
LexManos be14c33ed1 Add missing air checks to WorldGenTrees and ChunkCache Closes #593 2013-07-03 21:48:51 -07:00
LexManos b12872eed1 Fix compile errors temporarily, dont use till updated to new system. 2013-07-03 21:34:49 -07:00
LexManos 35caa32ad1 Merge pull request #539 from richardg867/techne-1
Techne model importer
2013-07-03 21:21:16 -07:00
LexManos 98aab2083b Render pass sensitive version of Item.hasEffect, Closes #517 2013-07-03 21:14:59 -07:00
LexManos 2b588ebce6 Fix lether item rendering colors. 2013-07-03 20:41:27 -07:00
LexManos d4ba95f606 Add hook for EntityWither trying to destroy a block. 2013-07-03 20:29:41 -07:00
LexManos 83504eb2e1 Merge pull request #600 from Lunatrius/rotation
Added rotation support for all vanilla blocks that can be rotated.
2013-07-03 20:16:25 -07:00
LexManos 7f5ec0eaef Fix domain issue with SoundPool entries. 2013-07-03 19:31:54 -07:00
LexManos 68ba3a84d6 Updated FML:
MinecraftForge/FML@7ce84491d1 Fix missing argument and startclient/startserver support.
2013-07-03 19:31:31 -07:00
LexManos 125b134d87 Updated FML:
MinecraftForge/FML@155e846818 Add in support for mods/<mcversion> as a mod location. Also drop coremods as a location. They go in mods too now.
MinecraftForge/FML@3f4bf61ae6 Update key
MinecraftForge/FML@4545beb49d Add deobf-data to setup env.
MinecraftForge/FML@e24f949517 Fix eclipse workspaces and launch configurations.
MinecraftForge/FML@532bee7ce1 Update to new MCP bugfix version, Fixes: Missing Armor/Item rendering, and Boss health mapping issues.
2013-07-03 18:54:47 -07:00
LexManos f9236c4c98 Include MANIFEST file from FML's universal.jar, makes the jar runnable now! 2013-07-03 06:26:47 -07:00
LexManos 02e857827d TEMPORARY fix for MCP mapping issue. 2013-07-03 06:26:12 -07:00
LexManos 7e5560e60d Update dev worksapce: Proper natives location and new server launch profile. 2013-07-03 06:25:40 -07:00
LexManos f35783f0fb Updated FML:
MinecraftForge/FML@6f0eedc9a6 Fixed ClassCastException when loading ModLoader mods
MinecraftForge/FML@8844554da6 Merge pull request #243 from jrtc27/modclassloader
MinecraftForge/FML@7aa7221756 Fix transformer search
MinecraftForge/FML@5f7df5e742 Revert "Keep these on our servers until the launcher is actually fixed -.-"
MinecraftForge/FML@ad79b9ed86 Fix up some deprecation warnings, and clean up coremod code that's going away.
MinecraftForge/FML@ba3707af22 More javadoc cleanup
2013-07-02 18:16:04 -07:00
LexManos e74ef3e86e Attempt to gather lastBuild information to fix ChangeLog's off-by-one issue. 2013-07-02 15:18:23 -07:00
LexManos ae59f1abb4 Move resource location resolution down to TextureAtlasSprite and allow for sprites that are not stitched. 2013-07-02 13:57:50 -07:00
Christian c0b09854b3 Start: f1b533ad87
End: f21cd286ca
Updated FML:
MinecraftForge/FML@f21cd286ca Resource packs, part two. FML mods are now resource packs. Vanilla will scan anything under 'assets' and turn it into a resource prefix. Use resourcelocations to look stuff up.
2013-07-02 13:53:28 -04:00
LexManos 2b61ea417b Update ChestGenHooks for new Dungeon chest strcture. 2013-07-02 02:37:05 -07:00
LexManos e57886e05a Fix resource domain when loading icon. Textures should be located in /assets/{domain}/textures/{block|item}/{name}.png Same strcutre as before except 'assets' instead of 'mods'. 2013-07-02 02:06:12 -07:00
LexManos b0520f3656 Update filler block to prevent useless console warning. 2013-07-02 02:04:28 -07:00
LexManos 3e9349bf7b Make Block.setIconName public 2013-07-02 02:04:04 -07:00
LexManos d5549d770d Fix bound texture in Controls screen, Closes #631 and #629 2013-07-01 23:35:03 -07:00
LexManos 4034cfe9dc Updated FML:
MinecraftForge/FML@5a97d183df Remember to update your patches!!!!
MinecraftForge/FML@f1b533ad87 Keep these on our servers until the launcher is actually fixed -.-
2013-07-01 23:33:48 -07:00
LexManos 7864f2c8ea Updated FML:
MinecraftForge/FML@91ecf71109 Fix -rel json
MinecraftForge/FML@efc369ee83 Fix EventHandler annotation.
MinecraftForge/FML@fbd57b3264 Mods are now loaded as resource packs. Vanilla will scan for valid prefixes based on subdirs of 'ass
ets' which can then be referenced as ResourceLocations with the "<prefix>:path" notation.
2013-07-01 22:54:19 -07:00
LexManos c157875ecd Fix installer unintended replace.
Updated FML:
MinecraftForge/FML@9b6525e805 Point scala downloads to our servers, Launcher doesn't like standard maven repos.
2013-07-01 21:54:10 -07:00
LexManos dac329bcf1 Updated FML:
MinecraftForge/FML@29d6c875d0 Add FML Installer logo crated by @ZaverSLO https://twitter.com/ZaverSLO/status/349947190300508162
MinecraftForge/FML@3d17434510 Build installer package for the new client launcher.
MinecraftForge/FML@bf38d94756 Update json samples
MinecraftForge/FML@7037184a4e Fix up release JSON
MinecraftForge/FML@dc7d02ebf6 Fix json syntax error.
2013-07-01 21:42:52 -07:00
LexManos d072d91081 Release will now build a installer jar and use the standard 'target' output folder. 2013-07-01 21:42:33 -07:00
LexManos e156ec2940 Update ToolMaterial enum helper. 2013-07-01 21:41:47 -07:00
LexManos 14295fd4b3 Merge pull request #627 from MinecraftForge/1.6
Merge 1.6 branch
2013-07-01 16:51:27 -07:00
LexManos 895580de42 Merge pull request #626 from MinecraftForge/1.6
1.6.1 Branch Merge
2013-07-01 14:16:37 -07:00
RedmenNL 2c9e11299e Added more render methods to IModelCustom interface. 2013-06-29 23:26:39 -06:00
MachineMuse ca011729d3 Fixed both RenderAllExcept behaviours 2013-06-29 23:24:03 -06:00
MachineMuse 0f25e6ec6b Added tessellation methods to obj model, for ISBRH-friendliness 2013-06-29 04:35:57 -06:00
James af2b5eb6f6 Add an InputStream constructor to WavefrontObject
It is said that Resource Packs will return InputStreams. And I like putting my models into texture packs which, obviously, give InputStreams rather than URLs.
2013-06-19 15:57:44 -06:00
Ross Swartz b207111c50 Update OreDictionary.java 2013-06-17 19:09:40 -03:00
Ross Swartz 05b2a19bac Add stone and cobblestone to Ore Dictionary 2013-06-11 23:58:05 -03:00
Lunatrius 0c308a5f07 Added rotation support for all vanilla blocks that can be rotated. 2013-06-08 21:35:42 +02:00
Christian ab62ca7b1f Merge branch 'master' into newliquid 2013-06-06 09:39:19 -04:00
Christian 50992f2112 Merge branch 'master' of github.com:KingLemming/MinecraftForge into newliquid
Conflicts:
	common/net/minecraftforge/common/network/ForgePacket.java
2013-05-27 18:16:24 -04:00
King Lemming 6cd56ebed6 Forge Fluid System!
Signed-off-by: King Lemming <[email protected]>
2013-05-27 00:56:58 -04:00
richardg867 f3caada13a Complete it, got the bug figured out 2013-04-22 13:08:59 -03:00
richardg867 27d922d470 Techne model loader (incomplete for debugging) 2013-04-21 21:32:23 -03:00
205 changed files with 8676 additions and 1103 deletions

No files matched your search

+2
View File
@@ -5,3 +5,5 @@
/patches-old/
/mcp/
/eclipse/
/target/
/temp/
-6
View File
@@ -1,6 +0,0 @@
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.8.2
Created-By: 1.7.0_09-b30 (Oracle Corporation)
Main-Class: net.minecraft.server.MinecraftServer
Class-Path: minecraft_server.jar
+95
View File
@@ -0,0 +1,95 @@
import os
import sys
import fnmatch
import shlex
import difflib
import time, subprocess
from optparse import OptionParser
def cmdsplit(args):
if os.sep == '\\':
args = args.replace('\\', '\\\\')
return shlex.split(args)
def main():
print("Applying patches")
parser = OptionParser()
parser.add_option('-m', '--mcp-dir', action='store', dest='mcp_dir', help='Path to MCP', default=None)
parser.add_option('-p', '--patch-dir', action='store', dest='patch_dir', help='Patches Directory', default=None)
parser.add_option('-t', '--target-dir', action='store', dest='target_dir', help='Target Directory', default=None)
options, _ = parser.parse_args()
if options.mcp_dir is None:
print 'Must supply MCP directory with --mcp-dir'
return
elif options.patch_dir is None:
print 'Must supply patches directory with --patch-dir'
return
elif options.target_dir is None:
print 'Must supplt target directory with --target-dir'
return
print "Applying patches from '%s' to '%s'" % (options.patch_dir, options.target_dir)
apply_patches(options.mcp_dir, options.patch_dir, options.target_dir)
def apply_patches(mcp_dir, patch_dir, target_dir, find=None, rep=None):
# Attempts to apply a directory full of patch files onto a target directory.
sys.path.append(mcp_dir)
temp = os.path.abspath('temp.patch')
cmd = cmdsplit('patch -p2 -i "%s" ' % temp)
if os.name == 'nt':
applydiff = os.path.abspath(os.path.join(mcp_dir, 'runtime', 'bin', 'applydiff.exe'))
cmd = cmdsplit('"%s" -uf -p2 -i "%s"' % (applydiff, temp))
for path, _, filelist in os.walk(patch_dir, followlinks=True):
for cur_file in fnmatch.filter(filelist, '*.patch'):
patch_file = os.path.normpath(os.path.join(patch_dir, path[len(patch_dir)+1:], cur_file))
target_file = os.path.join(target_dir, fix_patch(patch_file, temp, find, rep))
process = subprocess.Popen(cmd, cwd=target_dir, bufsize=-1)
process.communicate()
if os.path.isfile(temp):
os.remove(temp)
def fix_patch(in_file, out_file, find=None, rep=None):
#Fixes the following issues in the patch file if they exist:
# Normalizes the path seperators for the current OS
# Normalizes the line endings
# Returns the path that the file wants to apply to
in_file = os.path.normpath(in_file)
if out_file is None:
tmp_file = in_file + '.tmp'
else:
out_file = os.path.normpath(out_file)
tmp_file = out_file
dir_name = os.path.dirname(out_file)
if dir_name:
if not os.path.exists(dir_name):
os.makedirs(dir_name)
file = 'not found'
with open(in_file, 'rb') as inpatch:
with open(tmp_file, 'wb') as outpatch:
for line in inpatch:
line = line.rstrip('\r\n')
if line[:3] in ['+++', '---', 'Onl', 'dif']:
if not find == None and not rep == None:
line = line.replace('\\', '/').replace(find, rep).replace('/', os.sep)
else:
line = line.replace('\\', '/').replace('/', os.sep)
outpatch.write(line + os.linesep)
else:
outpatch.write(line + os.linesep)
if line[:3] == '---':
file = line[line.find(os.sep, line.find(os.sep)+1)+1:]
if out_file is None:
shutil.move(tmp_file, in_file)
return file
if __name__ == '__main__':
main()
+27 -3
View File
@@ -24,12 +24,16 @@ class PreemptiveBasicAuthHandler(urllib2.BaseHandler):
def https_request(self,req):
return self.http_request(req)
def getBuildInfo(url, current_version=None):
def read_url(url):
handler = PreemptiveBasicAuthHandler()
handler.add_password(None, 'jenkins.minecraftforge.net:81', 'console_script', 'fd584bffa72fcac12181f37f80001200')
handler.add_password(None, 'ci.jenkins.minecraftforge.net', 'console_script', 'dc6d48ca20a474beeac280a9a16a926e')
file = urllib2.build_opener(handler).open(url)
data = file.read()
file.close()
return data
def getBuildInfo(url, current_version=None):
data = read_url(url)
data = ast.literal_eval(data)['allBuilds']
data = sorted(data, key=lambda key: key['number'], reverse=False)
@@ -57,9 +61,29 @@ def getBuildInfo(url, current_version=None):
build.pop('changeSet')
build.pop('actions')
return sorted(output, key=lambda key: key['number'], reverse=True)
def add_latest_build(url, builds, current_version=None):
data = read_url(url)
data = ast.literal_eval(data)
number = data['number']
if builds[0]['number'] == data['number']:
return builds
for item in data['changeSet']['items']:
item['author'] = item['author']['fullName']
build = {
'number' : data['number'],
'result' : 'SUCCESS', #Currently build should always be success... Else things derp after words
'version' : current_version,
'items' : data['changeSet']['items']
}
return [build] + builds
def make_changelog(job_path, target_build, change_file, current_version=None):
builds = getBuildInfo('%s/api/python?tree=allBuilds[result,number,actions[text],changeSet[items[author[fullName],comment]]]&pretty=true' % job_path, current_version)
builds = add_latest_build('%s/lastBuild/api/python?pretty=true&tree=number,changeSet[items[author[fullName],comment]]' % job_path, builds, current_version)
log = [ "Changelog:" ]
@@ -86,4 +110,4 @@ def make_changelog(job_path, target_build, change_file, current_version=None):
file.close()
if __name__ == '__main__':
make_changelog("http://jenkins.minecraftforge.net:81/job/minecraftforge/", 70000, 'changelog.txt', 'pinecone')
make_changelog("http://ci.jenkins.minecraftforge.net/job/minecraftforge/", 70000, 'changelog.txt', 'pinecone')
@@ -0,0 +1,141 @@
package net.minecraftforge.client;
import java.util.List;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiChat;
import net.minecraft.command.CommandException;
import net.minecraft.command.CommandHandler;
import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.WrongUsageException;
import net.minecraft.util.ChatMessageComponent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.CommandEvent;
import cpw.mods.fml.client.FMLClientHandler;
import static net.minecraft.util.EnumChatFormatting.*;
/**
* The class that handles client-side chat commands. You should register any
* commands that you want handled on the client with this command handler.
*
* If there is a command with the same name registered both on the server and
* client, the client takes precedence!
*
*/
public class ClientCommandHandler extends CommandHandler
{
public static final ClientCommandHandler instance = new ClientCommandHandler();
public String[] latestAutoComplete = null;
/**
* @return 1 if successfully executed, 0 if wrong usage, it doesn't exist or
* it was canceled.
*/
@Override
public int executeCommand(ICommandSender sender, String message)
{
message = message.trim();
if (message.startsWith("/"))
{
message = message.substring(1);
}
String[] temp = message.split(" ");
String[] args = new String[temp.length - 1];
String commandName = temp[0];
System.arraycopy(temp, 1, args, 0, args.length);
ICommand icommand = (ICommand) getCommands().get(commandName);
try
{
if (icommand == null)
{
return 0;
}
if (icommand.canCommandSenderUseCommand(sender))
{
CommandEvent event = new CommandEvent(icommand, sender, args);
if (MinecraftForge.EVENT_BUS.post(event))
{
if (event.exception != null)
{
throw event.exception;
}
return 0;
}
icommand.processCommand(sender, args);
return 1;
}
else
{
sender.sendChatToPlayer(format("commands.generic.permission").setColor(RED));
}
}
catch (WrongUsageException wue)
{
sender.sendChatToPlayer(format("commands.generic.usage", format(wue.getMessage(), wue.getErrorOjbects())).setColor(RED));
}
catch (CommandException ce)
{
sender.sendChatToPlayer(format(ce.getMessage(), ce.getErrorOjbects()).setColor(RED));
}
catch (Throwable t)
{
sender.sendChatToPlayer(format("commands.generic.exception").setColor(RED));
t.printStackTrace();
}
return 0;
}
//Couple of helpers because the mcp names are stupid and long...
private ChatMessageComponent format(String str, Object... args)
{
return ChatMessageComponent.createFromTranslationWithSubstitutions(str, args);
}
private ChatMessageComponent format(String str)
{
return ChatMessageComponent.createFromTranslationKey(str);
}
public void autoComplete(String leftOfCursor, String full)
{
latestAutoComplete = null;
if (leftOfCursor.charAt(0) == '/')
{
leftOfCursor = leftOfCursor.substring(1);
Minecraft mc = FMLClientHandler.instance().getClient();
if (mc.currentScreen instanceof GuiChat)
{
List<String> commands = getPossibleCommands(mc.thePlayer, leftOfCursor);
if (commands != null && !commands.isEmpty())
{
if (leftOfCursor.indexOf(' ') == -1)
{
for (int i = 0; i < commands.size(); i++)
{
commands.set(i, GRAY + "/" + commands.get(i) + RESET);
}
}
else
{
for (int i = 0; i < commands.size(); i++)
{
commands.set(i, GRAY + commands.get(i) + RESET);
}
}
latestAutoComplete = commands.toArray(new String[commands.size()]);
}
}
}
}
}
@@ -6,6 +6,9 @@ import java.util.TreeSet;
import javax.imageio.ImageIO;
import net.minecraftforge.client.event.MouseEvent;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraftforge.client.event.FOVUpdateEvent;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GL11;
@@ -13,19 +16,22 @@ import org.lwjgl.opengl.GL12;
import org.lwjgl.opengl.PixelFormat;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.client.registry.RenderingRegistry;
import net.minecraft.client.Minecraft;
import net.minecraft.block.Block;
import net.minecraft.block.BlockFluid;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.RenderGlobal;
@@ -37,20 +43,31 @@ import net.minecraftforge.client.IItemRenderer.ItemRenderType;
import net.minecraftforge.client.event.DrawBlockHighlightEvent;
import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.common.ForgeDummyContainer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.RenderBlockFluid;
import static net.minecraftforge.client.IItemRenderer.ItemRenderType.*;
import static net.minecraftforge.client.IItemRenderer.ItemRendererHelper.*;
public class ForgeHooksClient
{
private static final ResourceLocation ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png");
static TextureManager engine()
{
return FMLClientHandler.instance().getClient().renderEngine;
}
@Deprecated
public static String getArmorTexture(Entity entity, ItemStack armor, String _default, int slot, int layer, String type)
{
String result = armor.getItem().getArmorTexture(armor, entity, slot, layer);
return getArmorTexture(entity, armor, _default, slot, type);
}
public static String getArmorTexture(Entity entity, ItemStack armor, String _default, int slot, String type)
{
String result = armor.getItem().getArmorTexture(armor, entity, slot, type);
return result != null ? result : _default;
}
@@ -72,7 +89,7 @@ public class ForgeHooksClient
}
boolean is3D = customRenderer.shouldUseRenderHelper(ENTITY, item, BLOCK_3D);
engine.func_110577_a(item.getItemSpriteNumber() == 0 ? TextureMap.field_110575_b : TextureMap.field_110576_c);
engine.bindTexture(item.getItemSpriteNumber() == 0 ? TextureMap.locationBlocksTexture : TextureMap.locationItemsTexture);
Block block = (item.itemID < Block.blocksList.length ? Block.blocksList[item.itemID] : null);
if (is3D || (block != null && RenderBlocks.renderItemIn3d(block.getRenderType())))
{
@@ -87,7 +104,7 @@ public class ForgeHooksClient
}
GL11.glScalef(scale, scale, scale);
int size = item.stackSize;
int count = (size > 40 ? 5 : (size > 20 ? 4 : (size > 5 ? 3 : (size > 1 ? 2 : 1))));
@@ -121,7 +138,7 @@ public class ForgeHooksClient
return false;
}
engine.func_110577_a(item.getItemSpriteNumber() == 0 ? TextureMap.field_110575_b : TextureMap.field_110576_c);
engine.bindTexture(item.getItemSpriteNumber() == 0 ? TextureMap.locationBlocksTexture : TextureMap.locationItemsTexture);
if (customRenderer.shouldUseRenderHelper(INVENTORY, item, INVENTORY_BLOCK))
{
GL11.glPushMatrix();
@@ -166,9 +183,14 @@ public class ForgeHooksClient
GL11.glPopMatrix();
GL11.glEnable(GL11.GL_LIGHTING);
}
return true;
}
public static void renderEffectOverlay(TextureManager manager, RenderItem render)
{
}
public static void renderEquippedItem(ItemRenderType type, IItemRenderer customRenderer, RenderBlocks renderBlocks, EntityLivingBase entity, ItemStack item)
{
if (customRenderer.shouldUseRenderHelper(type, item, EQUIPPED_BLOCK))
@@ -228,6 +250,9 @@ public class ForgeHooksClient
public static void onTextureStitchedPost(TextureMap map)
{
MinecraftForge.EVENT_BUS.post(new TextureStitchEvent.Post(map));
FluidRegistry.WATER.setIcons(BlockFluid.getFluidIcon("water_still"), BlockFluid.getFluidIcon("water_flow"));
FluidRegistry.LAVA.setIcons(BlockFluid.getFluidIcon("lava_still"), BlockFluid.getFluidIcon("lava_flow"));
}
/**
@@ -283,4 +308,86 @@ public class ForgeHooksClient
stencilBits = 0;
}
}
//This properly moves the domain, if provided, to the front of the string before concatenating
public static String fixDomain(String base, String complex)
{
int idx = complex.indexOf(':');
if (idx == -1)
{
return base + complex;
}
String name = complex.substring(idx + 1, complex.length());
if (idx > 1)
{
String domain = complex.substring(0, idx);
return domain + ':' + base + name;
}
else
{
return base + name;
}
}
public static boolean postMouseEvent()
{
return MinecraftForge.EVENT_BUS.post(new MouseEvent());
}
public static float getOffsetFOV(EntityPlayerSP entity, float fov)
{
FOVUpdateEvent fovUpdateEvent = new FOVUpdateEvent(entity, fov);
MinecraftForge.EVENT_BUS.post(fovUpdateEvent);
return fovUpdateEvent.newfov;
}
private static int skyX, skyZ;
private static boolean skyInit;
private static int skyRGBMultiplier;
public static int getSkyBlendColour(World world, int playerX, int playerZ)
{
if (playerX == skyX && playerZ == skyZ && skyInit)
{
return skyRGBMultiplier;
}
skyInit = true;
int distance = Minecraft.getMinecraft().gameSettings.fancyGraphics ? ForgeDummyContainer.blendRanges[Minecraft.getMinecraft().gameSettings.renderDistance] : 0;
int r = 0;
int g = 0;
int b = 0;
int divider = 0;
for (int x = -distance; x <= distance; ++x)
{
for (int z = -distance; z <= distance; ++z)
{
BiomeGenBase biome = world.getBiomeGenForCoords(playerX + x, playerZ + z);
int colour = biome.getSkyColorByTemp(biome.getFloatTemperature());
r += (colour & 0xFF0000) >> 16;
g += (colour & 0x00FF00) >> 8;
b += colour & 0x0000FF;
divider++;
}
}
int multiplier = (r / divider & 255) << 16 | (g / divider & 255) << 8 | b / divider & 255;
skyX = playerX;
skyZ = playerZ;
skyRGBMultiplier = multiplier;
return skyRGBMultiplier;
}
/**
* Initialization of Forge Renderers.
*/
static
{
FluidRegistry.renderIdFluid = RenderingRegistry.getNextAvailableRenderId();
RenderingRegistry.registerBlockHandler(RenderBlockFluid.instance);
}
}
@@ -11,9 +11,11 @@ import net.minecraft.client.settings.KeyBinding;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
public class GuiControlsScrollPanel extends GuiSlot
{
protected static final ResourceLocation WIDGITS = new ResourceLocation("textures/gui/widgets.png");
private GuiControls controls;
private GameSettings options;
private Minecraft mc;
@@ -61,7 +63,7 @@ public class GuiControlsScrollPanel extends GuiSlot
}
@Override
protected void func_130003_c() {}
protected void drawBackground() {}
@Override
public void drawScreen(int mX, int mY, float f)
@@ -73,7 +75,6 @@ public class GuiControlsScrollPanel extends GuiSlot
{
if (Mouse.next() && Mouse.getEventButtonState())
{
System.out.println(Mouse.getEventButton());
options.setKeyBinding(selected, -100 + Mouse.getEventButton());
selected = -1;
KeyBinding.resetKeyBindingArrayAndHash();
@@ -92,7 +93,7 @@ public class GuiControlsScrollPanel extends GuiSlot
boolean flag = _mouseX >= xPosition && _mouseY >= yPosition && _mouseX < xPosition + width && _mouseY < yPosition + height;
int k = (flag ? 2 : 1);
mc.renderEngine.func_110577_a(TextureMap.field_110576_c);
mc.renderEngine.bindTexture(WIDGITS);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
controls.drawTexturedModalRect(xPosition, yPosition, 0, 46 + k * 20, width / 2, height);
controls.drawTexturedModalRect(xPosition + width / 2, yPosition, 200 - width / 2, 46 + k * 20, width / 2, height);
@@ -17,7 +17,6 @@ import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.multiplayer.NetClientHandler;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.resources.ResourceLocation;
import net.minecraft.crash.CallableMinecraftVersion;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
@@ -33,6 +32,7 @@ import net.minecraft.util.Direction;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.FoodStats;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import net.minecraft.util.StringUtils;
import net.minecraft.world.EnumSkyBlock;
@@ -52,7 +52,7 @@ public class GuiIngameForge extends GuiIngame
private static final ResourceLocation VIGNETTE = new ResourceLocation("textures/misc/vignette.png");
private static final ResourceLocation WIDGITS = new ResourceLocation("textures/gui/widgets.png");
private static final ResourceLocation PUMPKIN_BLUR = new ResourceLocation("textures/misc/pumpkinblur.png");
private static final int WHITE = 0xFFFFFF;
//Flags to toggle the rendering of certain aspects of the HUD, valid conditions
@@ -71,7 +71,7 @@ public class GuiIngameForge extends GuiIngame
public static boolean renderExperiance = true;
public static boolean renderJumpBar = true;
public static boolean renderObjective = true;
public static int left_height = 39;
public static int right_height = 39;
@@ -94,8 +94,8 @@ public class GuiIngameForge extends GuiIngame
int height = res.getScaledHeight();
renderHealthMount = mc.thePlayer.ridingEntity instanceof EntityLivingBase;
renderFood = mc.thePlayer.ridingEntity == null;
renderJumpBar = mc.thePlayer.func_110317_t();
renderJumpBar = mc.thePlayer.isRidingHorse();
right_height = 39;
left_height = 39;
@@ -129,7 +129,7 @@ public class GuiIngameForge extends GuiIngame
if (renderCrosshairs) renderCrosshairs(width, height);
if (renderBossHealth) renderBossHealth();
if (this.mc.playerController.shouldDrawHUD())
{
if (renderHealth) renderHealth(width, height);
@@ -145,7 +145,7 @@ public class GuiIngameForge extends GuiIngame
{
renderJumpBar(width, height);
}
else if (renderExperiance)
else if (renderExperiance)
{
renderExperience(width, height);
}
@@ -189,7 +189,7 @@ public class GuiIngameForge extends GuiIngame
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
mc.renderEngine.func_110577_a(WIDGITS);
mc.renderEngine.bindTexture(WIDGITS);
InventoryPlayer inv = mc.thePlayer.inventory;
drawTexturedModalRect(width / 2 - 91, height - 22, 0, 0, 182, 22);
@@ -215,7 +215,7 @@ public class GuiIngameForge extends GuiIngame
protected void renderCrosshairs(int width, int height)
{
if (pre(CROSSHAIRS)) return;
bind(Gui.field_110324_m);
bind(Gui.icons);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_ONE_MINUS_DST_COLOR, GL11.GL_ONE_MINUS_SRC_COLOR);
drawTexturedModalRect(width / 2 - 7, height / 2 - 7, 0, 0, 16, 16);
@@ -325,7 +325,7 @@ public class GuiIngameForge extends GuiIngame
public void renderHealth(int width, int height)
{
bind(field_110324_m);
bind(icons);
if (pre(HEALTH)) return;
mc.mcProfiler.startSection("health");
@@ -336,17 +336,17 @@ public class GuiIngameForge extends GuiIngame
highlight = false;
}
AttributeInstance attrMaxHealth = this.mc.thePlayer.func_110148_a(SharedMonsterAttributes.field_111267_a);
int health = MathHelper.ceiling_float_int(mc.thePlayer.func_110143_aJ());
AttributeInstance attrMaxHealth = this.mc.thePlayer.getEntityAttribute(SharedMonsterAttributes.maxHealth);
int health = MathHelper.ceiling_float_int(mc.thePlayer.getHealth());
int healthLast = MathHelper.ceiling_float_int(mc.thePlayer.prevHealth);
float healthMax = (float)attrMaxHealth.func_111126_e();
float absorb = this.mc.thePlayer.func_110139_bj();
float healthMax = (float)attrMaxHealth.getAttributeValue();
float absorb = this.mc.thePlayer.getAbsorptionAmount();
int healthRows = MathHelper.ceiling_float_int((healthMax + absorb) / 2.0F / 10.0F);
int rowHeight = Math.max(10 - (healthRows - 2), 3);
this.rand.setSeed((long)(updateCounter * 312871));
int left = width / 2 - 91;
int top = height - left_height;
left_height += (healthRows * rowHeight);
@@ -357,14 +357,14 @@ public class GuiIngameForge extends GuiIngame
{
regen = updateCounter % 25;
}
final int TOP = 9 * (mc.theWorld.getWorldInfo().isHardcoreModeEnabled() ? 5 : 0);
final int BACKGROUND = (highlight ? 25 : 16);
int MARGIN = 16;
if (mc.thePlayer.isPotionActive(Potion.poison)) MARGIN += 36;
else if (mc.thePlayer.isPotionActive(Potion.wither)) MARGIN += 72;
float absorbRemaining = absorb;
for (int i = MathHelper.ceiling_float_int((healthMax + absorb) / 2.0F) - 1; i >= 0; --i)
{
int b0 = (highlight ? 1 : 0);
@@ -373,7 +373,7 @@ public class GuiIngameForge extends GuiIngame
int y = top - row * rowHeight;
if (health <= 4) y += rand.nextInt(2);
if (i == regen) y -= 2;
if (i == regen) y -= 2;
drawTexturedModalRect(x, y, BACKGROUND, TOP, 9, 9);
@@ -401,7 +401,7 @@ public class GuiIngameForge extends GuiIngame
drawTexturedModalRect(x, y, MARGIN + 45, TOP, 9, 9); //5
}
}
mc.mcProfiler.endSection();
post(HEALTH);
}
@@ -484,23 +484,23 @@ public class GuiIngameForge extends GuiIngame
protected void renderExperience(int width, int height)
{
bind(field_110324_m);
bind(icons);
if (pre(EXPERIENCE)) return;
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
if (mc.playerController.func_78763_f())
{
mc.mcProfiler.startSection("expBar");
int cap = this.mc.thePlayer.xpBarCap();
int left = width / 2 - 91;
if (cap > 0)
{
short barWidth = 182;
int filled = (int)(mc.thePlayer.experience * (float)(barWidth + 1));
int top = height - 32 + 3;
drawTexturedModalRect(left, top, 0, 64, barWidth, 5);
if (filled > 0)
{
drawTexturedModalRect(left, top, 0, 69, filled, 5);
@@ -508,8 +508,8 @@ public class GuiIngameForge extends GuiIngame
}
this.mc.mcProfiler.endSection();
if (mc.playerController.func_78763_f() && mc.thePlayer.experienceLevel > 0)
{
mc.mcProfiler.startSection("expLevel");
@@ -533,12 +533,12 @@ public class GuiIngameForge extends GuiIngame
protected void renderJumpBar(int width, int height)
{
bind(field_110324_m);
bind(icons);
if (pre(JUMPBAR)) return;
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
mc.mcProfiler.startSection("jumpBar");
float charge = mc.thePlayer.func_110319_bJ();
float charge = mc.thePlayer.getHorseJumpPower();
final int barWidth = 182;
int x = (width / 2) - (barWidth / 2);
int filled = (int)(charge * (float)(barWidth + 1));
@@ -723,12 +723,19 @@ public class GuiIngameForge extends GuiIngame
protected void renderChat(int width, int height)
{
GL11.glPushMatrix();
GL11.glTranslatef(0.0F, (float)(height - 48), 0.0F);
mc.mcProfiler.startSection("chat");
RenderGameOverlayEvent.Chat event = new RenderGameOverlayEvent.Chat(eventParent, 0, height - 48);
if (MinecraftForge.EVENT_BUS.post(event)) return;
GL11.glPushMatrix();
GL11.glTranslatef((float)event.posX, (float)event.posY, 0.0F);
persistantChatGUI.drawChat(updateCounter);
mc.mcProfiler.endSection();
GL11.glPopMatrix();
post(CHAT);
mc.mcProfiler.endSection();
}
protected void renderPlayerList(int width, int height)
@@ -738,6 +745,7 @@ public class GuiIngameForge extends GuiIngame
if (mc.gameSettings.keyBindPlayerList.pressed && (!mc.isIntegratedServerRunning() || handler.playerInfoList.size() > 1 || scoreobjective != null))
{
if (pre(PLAYER_LIST)) return;
this.mc.mcProfiler.startSection("playerList");
List players = handler.playerInfoList;
int maxPlayers = handler.currentServerMaxPlayers;
@@ -772,7 +780,7 @@ public class GuiIngameForge extends GuiIngame
{
GuiPlayerInfo player = (GuiPlayerInfo)players.get(i);
ScorePlayerTeam team = mc.theWorld.getScoreboard().getPlayersTeam(player.name);
String displayName = ScorePlayerTeam.func_96667_a(team, player.name);
String displayName = ScorePlayerTeam.formatPlayerName(team, player.name);
fontrenderer.drawStringWithShadow(displayName, xPos, yPos, 16777215);
if (scoreobjective != null)
@@ -783,14 +791,14 @@ public class GuiIngameForge extends GuiIngame
if (maxX - endX > 5)
{
Score score = scoreobjective.getScoreboard().func_96529_a(player.name, scoreobjective);
String scoreDisplay = EnumChatFormatting.YELLOW + "" + score.func_96652_c();
String scoreDisplay = EnumChatFormatting.YELLOW + "" + score.getScorePoints();
fontrenderer.drawStringWithShadow(scoreDisplay, maxX - fontrenderer.getStringWidth(scoreDisplay), yPos, 16777215);
}
}
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
mc.func_110434_K().func_110577_a(Gui.field_110324_m);
mc.getTextureManager().bindTexture(Gui.icons);
int pingIndex = 4;
int ping = player.responseTime;
if (ping < 0) pingIndex = 5;
@@ -804,6 +812,7 @@ public class GuiIngameForge extends GuiIngame
zLevel -= 100.0F;
}
}
post(PLAYER_LIST);
}
}
@@ -812,21 +821,21 @@ public class GuiIngameForge extends GuiIngame
Entity tmp = mc.thePlayer.ridingEntity;
if (!(tmp instanceof EntityLivingBase)) return;
bind(field_110324_m);
bind(icons);
if (pre(HEALTHMOUNT)) return;
boolean unused = false;
int left_align = width / 2 + 91;
mc.mcProfiler.endStartSection("mountHealth");
EntityLivingBase mount = (EntityLivingBase)tmp;
int health = (int)Math.ceil((double)mount.func_110143_aJ());
float healthMax = mount.func_110138_aP();
int health = (int)Math.ceil((double)mount.getHealth());
float healthMax = mount.getMaxHealth();
int hearts = (int)(healthMax + 0.5F) / 2;
if (hearts > 30) hearts = 30;
final int MARGIN = 52;
final int BACKGROUND = MARGIN + (unused ? 1 : 0);
final int HALF = MARGIN + 45;
@@ -835,7 +844,7 @@ public class GuiIngameForge extends GuiIngame
for (int heart = 0; hearts > 0; heart += 20)
{
int top = height - right_height;
int rowCount = Math.min(hearts, 10);
hearts -= rowCount;
@@ -866,6 +875,6 @@ public class GuiIngameForge extends GuiIngame
}
private void bind(ResourceLocation res)
{
mc.func_110434_K().func_110577_a(res);
mc.getTextureManager().bindTexture(res);
}
}
@@ -0,0 +1,23 @@
package net.minecraftforge.client.event;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.renderer.EntityRenderer;
import net.minecraftforge.event.Event;
/**
* Author: MachineMuse (Claire Semple)
* Created: 6:07 PM, 9/5/13
*/
public class FOVUpdateEvent extends Event
{
public final EntityPlayerSP entity;
public final float fov;
public float newfov;
public FOVUpdateEvent(EntityPlayerSP entity, float fov)
{
this.entity = entity;
this.fov = fov;
this.newfov = fov;
}
}
@@ -0,0 +1,22 @@
package net.minecraftforge.client.event;
import net.minecraft.client.gui.GuiScreen;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event;
/**
* This event is called before any Gui will open.
* If you don't want this to happen, cancel the event.
* If you want to override this Gui, simply set the gui variable to your own Gui.
*
* @author jk-5
*/
@Cancelable
public class GuiOpenEvent extends Event
{
public GuiScreen gui;
public GuiOpenEvent(GuiScreen gui)
{
this.gui = gui;
}
}
@@ -0,0 +1,34 @@
package net.minecraftforge.client.event;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event;
import org.lwjgl.input.Mouse;
/**
* Author: MachineMuse (Claire Semple)
* Created: 2:46 PM, 9/4/13
*/
@Cancelable
public class MouseEvent extends Event
{
public final int x;
public final int y;
public final int dx;
public final int dy;
public final int dwheel;
public final int button;
public final boolean buttonstate;
public final long nanoseconds;
public MouseEvent()
{
this.x = Mouse.getEventX();
this.y = Mouse.getEventY();
this.dx = Mouse.getEventDX();
this.dy = Mouse.getEventDY();
this.dwheel = Mouse.getEventDWheel();
this.button = Mouse.getEventButton();
this.buttonstate = Mouse.getEventButtonState();
this.nanoseconds = Mouse.getEventNanoseconds();
}
}
@@ -24,7 +24,9 @@ public class RenderGameOverlayEvent extends Event
EXPERIENCE,
TEXT,
HEALTHMOUNT,
JUMPBAR
JUMPBAR,
CHAT,
PLAYER_LIST
}
public final float partialTicks;
@@ -79,4 +81,17 @@ public class RenderGameOverlayEvent extends Event
this.right = right;
}
}
public static class Chat extends Pre
{
public int posX;
public int posY;
public Chat(RenderGameOverlayEvent parent, int posX, int posY)
{
super(parent, ElementType.CHAT);
this.posX = posX;
this.posY = posY;
}
}
}
@@ -15,6 +15,16 @@ public abstract class RenderLivingEvent extends Event
this.entity = entity;
this.renderer = renderer;
}
@Cancelable
public static class Pre extends RenderLivingEvent
{
public Pre(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
}
public static class Post extends RenderLivingEvent
{
public Post(EntityLivingBase entity, RendererLivingEntity renderer){ super(entity, renderer); }
}
public abstract static class Specials extends RenderLivingEvent
{
@@ -9,30 +9,33 @@ import net.minecraftforge.event.entity.player.PlayerEvent;
public abstract class RenderPlayerEvent extends PlayerEvent
{
public final RenderPlayer renderer;
public final float partialRenderTick;
public RenderPlayerEvent(EntityPlayer player, RenderPlayer renderer)
public RenderPlayerEvent(EntityPlayer player, RenderPlayer renderer, float partialRenderTick)
{
super(player);
this.renderer = renderer;
this.partialRenderTick = partialRenderTick;
}
@Cancelable
public static class Pre extends RenderPlayerEvent
{
public Pre(EntityPlayer player, RenderPlayer renderer){ super(player, renderer); }
public Pre(EntityPlayer player, RenderPlayer renderer, float tick){ super(player, renderer, tick); }
}
public static class Post extends RenderPlayerEvent
{
public Post(EntityPlayer player, RenderPlayer renderer){ super(player, renderer); }
public Post(EntityPlayer player, RenderPlayer renderer, float tick){ super(player, renderer, tick); }
}
public abstract static class Specials extends RenderPlayerEvent
{
@Deprecated
public final float partialTicks;
public Specials(EntityPlayer player, RenderPlayer renderer, float partialTicks)
{
super(player, renderer);
super(player, renderer, partialTicks);
this.partialTicks = partialTicks;
}
@@ -59,11 +62,12 @@ public abstract class RenderPlayerEvent extends PlayerEvent
*/
public int result = -1;
public final int slot;
@Deprecated
public final float partialTick;
public final ItemStack stack;
public SetArmorModel(EntityPlayer player, RenderPlayer renderer, int slot, float partialTick, ItemStack stack)
{
super(player, renderer);
super(player, renderer, partialTick);
this.slot = slot;
this.partialTick = partialTick;
this.stack = stack;
@@ -6,6 +6,7 @@ import java.util.Collection;
import java.util.Map;
import net.minecraftforge.client.model.obj.ObjModelLoader;
import net.minecraftforge.client.model.techne.TechneModelLoader;
import com.google.common.collect.Maps;
@@ -78,5 +79,6 @@ public class AdvancedModelLoader {
static
{
registerModelHandler(new ObjModelLoader());
registerModelHandler(new TechneModelLoader());
}
}
@@ -5,5 +5,7 @@ package net.minecraftforge.client.model;
public interface IModelCustom {
String getType();
void renderAll();
void renderOnly(String... groupNames);
void renderPart(String partName);
void renderAllExcept(String... excludedGroupNames);
}
@@ -49,20 +49,32 @@ public class WavefrontObject implements IModelCustom
public WavefrontObject(String fileName, URL resource) throws ModelFormatException
{
this.fileName = fileName;
loadObjModel(resource);
try
{
loadObjModel(resource.openStream());
}
catch (IOException e)
{
throw new ModelFormatException("IO Exception reading model format", e);
}
}
public WavefrontObject(String filename, InputStream inputStream) throws ModelFormatException
{
this.fileName = filename;
loadObjModel(inputStream);
}
private void loadObjModel(URL fileURL) throws ModelFormatException
private void loadObjModel(InputStream inputStream) throws ModelFormatException
{
BufferedReader reader = null;
InputStream inputStream = null;
String currentLine = null;
int lineCount = 0;
try
{
inputStream = fileURL.openStream();
reader = new BufferedReader(new InputStreamReader(inputStream));
while ((currentLine = reader.readLine()) != null)
@@ -157,6 +169,7 @@ public class WavefrontObject implements IModelCustom
}
}
@Override
public void renderAll()
{
Tessellator tessellator = Tessellator.instance;
@@ -169,15 +182,20 @@ public class WavefrontObject implements IModelCustom
{
tessellator.startDrawing(GL11.GL_TRIANGLES);
}
for (GroupObject groupObject : groupObjects)
{
groupObject.render(tessellator);
}
tessellateAll(tessellator);
tessellator.draw();
}
public void tessellateAll(Tessellator tessellator)
{
for (GroupObject groupObject : groupObjects)
{
groupObject.render(tessellator);
}
}
@Override
public void renderOnly(String... groupNames)
{
for (GroupObject groupObject : groupObjects)
@@ -192,6 +210,20 @@ public class WavefrontObject implements IModelCustom
}
}
public void tessellateOnly(Tessellator tessellator, String... groupNames) {
for (GroupObject groupObject : groupObjects)
{
for (String groupName : groupNames)
{
if (groupName.equalsIgnoreCase(groupObject.name))
{
groupObject.render(tessellator);
}
}
}
}
@Override
public void renderPart(String partName)
{
for (GroupObject groupObject : groupObjects)
@@ -203,17 +235,52 @@ public class WavefrontObject implements IModelCustom
}
}
public void tessellatePart(Tessellator tessellator, String partName) {
for (GroupObject groupObject : groupObjects)
{
if (partName.equalsIgnoreCase(groupObject.name))
{
groupObject.render(tessellator);
}
}
}
public void renderAllExcept(String... excludedGroupNames)
{
for (GroupObject groupObject : groupObjects)
{
boolean skipPart=false;
for (String excludedGroupName : excludedGroupNames)
{
if (!excludedGroupName.equalsIgnoreCase(groupObject.name))
if (excludedGroupName.equalsIgnoreCase(groupObject.name))
{
groupObject.render();
skipPart=true;
}
}
if(!skipPart)
{
groupObject.render();
}
}
}
public void tessellateAllExcept(Tessellator tessellator, String... excludedGroupNames)
{
boolean exclude;
for (GroupObject groupObject : groupObjects)
{
exclude=false;
for (String excludedGroupName : excludedGroupNames)
{
if (excludedGroupName.equalsIgnoreCase(groupObject.name))
{
exclude=true;
}
}
if(!exclude)
{
groupObject.render(tessellator);
}
}
}
@@ -347,7 +414,7 @@ public class WavefrontObject implements IModelCustom
face.vertices = new Vertex[tokens.length];
face.textureCoordinates = new TextureCoordinate[tokens.length];
face.vertexNormals = new Vertex[tokens.length];
for (int i = 0; i < tokens.length; ++i)
{
subTokens = tokens[i].split("/");
@@ -364,7 +431,7 @@ public class WavefrontObject implements IModelCustom
{
face.vertices = new Vertex[tokens.length];
face.textureCoordinates = new TextureCoordinate[tokens.length];
for (int i = 0; i < tokens.length; ++i)
{
subTokens = tokens[i].split("/");
@@ -380,7 +447,7 @@ public class WavefrontObject implements IModelCustom
{
face.vertices = new Vertex[tokens.length];
face.vertexNormals = new Vertex[tokens.length];
for (int i = 0; i < tokens.length; ++i)
{
subTokens = tokens[i].split("//");
@@ -395,7 +462,7 @@ public class WavefrontObject implements IModelCustom
else if (isValidFace_V_Line(line))
{
face.vertices = new Vertex[tokens.length];
for (int i = 0; i < tokens.length; ++i)
{
face.vertices[i] = vertices.get(Integer.parseInt(tokens[i]) - 1);
@@ -0,0 +1,338 @@
package net.minecraftforge.client.model.techne;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import javax.imageio.ImageIO;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.lwjgl.opengl.GL11;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer;
import net.minecraftforge.client.model.IModelCustom;
import net.minecraftforge.client.model.ModelFormatException;
import net.minecraftforge.client.model.obj.GroupObject;
/**
* Techne model importer, based on iChun's Hats importer
*/
@SideOnly(Side.CLIENT)
public class TechneModel extends ModelBase implements IModelCustom {
public static final List<String> cubeTypes = Arrays.asList(
"d9e621f7-957f-4b77-b1ae-20dcd0da7751",
"de81aa14-bd60-4228-8d8d-5238bcd3caaa"
);
private String fileName;
private Map<String, byte[]> zipContents = new HashMap<String, byte[]>();
private Map<String, ModelRenderer> parts = new LinkedHashMap<String, ModelRenderer>();
private String texture = null;
private int textureName;
private boolean textureNameSet = false;
public TechneModel(String fileName, URL resource) throws ModelFormatException
{
this.fileName = fileName;
loadTechneModel(resource);
}
private void loadTechneModel(URL fileURL) throws ModelFormatException
{
try
{
ZipInputStream zipInput = new ZipInputStream(fileURL.openStream());
ZipEntry entry;
while ((entry = zipInput.getNextEntry()) != null)
{
byte[] data = new byte[(int) entry.getSize()];
// For some reason, using read(byte[]) makes reading stall upon reaching a 0x1E byte
int i = 0;
while (zipInput.available() > 0 && i < data.length)
{
data[i++] = (byte)zipInput.read();
}
zipContents.put(entry.getName(), data);
}
byte[] modelXml = zipContents.get("model.xml");
if (modelXml == null)
{
throw new ModelFormatException("Model " + fileName + " contains no model.xml file");
}
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(new ByteArrayInputStream(modelXml));
NodeList nodeListTechne = document.getElementsByTagName("Techne");
if (nodeListTechne.getLength() < 1)
{
throw new ModelFormatException("Model " + fileName + " contains no Techne tag");
}
NodeList nodeListModel = document.getElementsByTagName("Model");
if (nodeListModel.getLength() < 1)
{
throw new ModelFormatException("Model " + fileName + " contains no Model tag");
}
NamedNodeMap modelAttributes = nodeListModel.item(0).getAttributes();
if (modelAttributes == null)
{
throw new ModelFormatException("Model " + fileName + " contains a Model tag with no attributes");
}
Node modelTexture = modelAttributes.getNamedItem("texture");
if (modelTexture != null)
{
texture = modelTexture.getTextContent();
}
NodeList shapes = document.getElementsByTagName("Shape");
for (int i = 0; i < shapes.getLength(); i++)
{
Node shape = shapes.item(i);
NamedNodeMap shapeAttributes = shape.getAttributes();
if (shapeAttributes == null)
{
throw new ModelFormatException("Shape #" + (i + 1) + " in " + fileName + " has no attributes");
}
Node name = shapeAttributes.getNamedItem("name");
String shapeName = null;
if (name != null)
{
shapeName = name.getNodeValue();
}
if (shapeName == null)
{
shapeName = "Shape #" + (i + 1);
}
String shapeType = null;
Node type = shapeAttributes.getNamedItem("type");
if (type != null)
{
shapeType = type.getNodeValue();
}
if (shapeType != null && !cubeTypes.contains(shapeType))
{
FMLLog.warning("Model shape [" + shapeName + "] in " + fileName + " is not a cube, ignoring");
continue;
}
try
{
boolean mirrored = false;
String[] offset = new String[3];
String[] position = new String[3];
String[] rotation = new String[3];
String[] size = new String[3];
String[] textureOffset = new String[2];
NodeList shapeChildren = shape.getChildNodes();
for (int j = 0; j < shapeChildren.getLength(); j++)
{
Node shapeChild = shapeChildren.item(j);
String shapeChildName = shapeChild.getNodeName();
String shapeChildValue = shapeChild.getTextContent();
if (shapeChildValue != null)
{
shapeChildValue = shapeChildValue.trim();
if (shapeChildName.equals("IsMirrored"))
{
mirrored = !shapeChildValue.equals("False");
}
else if (shapeChildName.equals("Offset"))
{
offset = shapeChildValue.split(",");
}
else if (shapeChildName.equals("Position"))
{
position = shapeChildValue.split(",");
}
else if (shapeChildName.equals("Rotation"))
{
rotation = shapeChildValue.split(",");
}
else if (shapeChildName.equals("Size"))
{
size = shapeChildValue.split(",");
}
else if (shapeChildName.equals("TextureOffset"))
{
textureOffset = shapeChildValue.split(",");
}
}
}
// That's what the ModelBase subclassing is needed for
ModelRenderer cube = new ModelRenderer(this, Integer.parseInt(textureOffset[0]), Integer.parseInt(textureOffset[1]));
cube.mirror = mirrored;
cube.addBox(Float.parseFloat(offset[0]), Float.parseFloat(offset[1]), Float.parseFloat(offset[2]), Integer.parseInt(size[0]), Integer.parseInt(size[1]), Integer.parseInt(size[2]));
cube.setRotationPoint(Float.parseFloat(position[0]), Float.parseFloat(position[1]) - 23.4F, Float.parseFloat(position[2]));
cube.rotateAngleX = (float)Math.toRadians(Float.parseFloat(rotation[0]));
cube.rotateAngleY = (float)Math.toRadians(Float.parseFloat(rotation[1]));
cube.rotateAngleZ = (float)Math.toRadians(Float.parseFloat(rotation[2]));
parts.put(shapeName, cube);
}
catch (NumberFormatException e)
{
FMLLog.warning("Model shape [" + shapeName + "] in " + fileName + " contains malformed integers within its data, ignoring");
e.printStackTrace();
}
}
}
catch (ZipException e)
{
throw new ModelFormatException("Model " + fileName + " is not a valid zip file");
}
catch (IOException e)
{
throw new ModelFormatException("Model " + fileName + " could not be read", e);
}
catch (ParserConfigurationException e)
{
// hush
}
catch (SAXException e)
{
throw new ModelFormatException("Model " + fileName + " contains invalid XML", e);
}
}
private void bindTexture()
{
/* TODO: Update to 1.6
if (texture != null)
{
if (!textureNameSet)
{
try
{
byte[] textureEntry = zipContents.get(texture);
if (textureEntry == null)
{
throw new ModelFormatException("Model " + fileName + " has no such texture " + texture);
}
BufferedImage image = ImageIO.read(new ByteArrayInputStream(textureEntry));
textureName = Minecraft.getMinecraft().renderEngine.allocateAndSetupTexture(image);
textureNameSet = true;
}
catch (ZipException e)
{
throw new ModelFormatException("Model " + fileName + " is not a valid zip file");
}
catch (IOException e)
{
throw new ModelFormatException("Texture for model " + fileName + " could not be read", e);
}
}
if (textureNameSet)
{
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureName);
Minecraft.getMinecraft().renderEngine.resetBoundTexture();
}
}
*/
}
@Override
public String getType()
{
return "tcn";
}
@Override
public void renderAll()
{
bindTexture();
for (ModelRenderer part : parts.values())
{
part.renderWithRotation(1.0F);
}
}
@Override
public void renderPart(String partName)
{
ModelRenderer part = parts.get(partName);
if (part != null)
{
bindTexture();
part.renderWithRotation(1.0F);
}
}
@Override
public void renderOnly(String... groupNames)
{
bindTexture();
for (ModelRenderer part : parts.values())
{
for (String groupName : groupNames)
{
if (groupName.equalsIgnoreCase(part.boxName))
{
part.render(1.0f);
}
}
}
}
@Override
public void renderAllExcept(String... excludedGroupNames)
{
for (ModelRenderer part : parts.values())
{
boolean skipPart=false;
for (String excludedGroupName : excludedGroupNames)
{
if (excludedGroupName.equalsIgnoreCase(part.boxName))
{
skipPart=true;
}
}
if(!skipPart)
{
part.render(1.0f);
}
}
}
}
@@ -0,0 +1,33 @@
package net.minecraftforge.client.model.techne;
import java.net.URL;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraftforge.client.model.IModelCustom;
import net.minecraftforge.client.model.IModelCustomLoader;
import net.minecraftforge.client.model.ModelFormatException;
public class TechneModelLoader implements IModelCustomLoader {
@Override
public String getType()
{
return "Techne model";
}
private static final String[] types = { "tcn" };
@Override
public String[] getSuffixes()
{
return types;
}
@Override
public IModelCustom loadInstance(String resourceName, URL resource) throws ModelFormatException
{
return new TechneModel(resourceName, resource);
}
}
+5
View File
@@ -0,0 +1,5 @@
commands.forge.usage=Use /forge <subcommand>. Subcommands are tps, track
commands.forge.usage.tracking=Use /forge track <type> <duration>. Valid types are te (Tile Entities). Duration is < 60.
commands.forge.tps.summary=%s : Mean tick time: %d ms. Mean TPS: %d
commands.forge.tracking.te.enabled=Tile Entity tracking enabled for %d seconds.
+5
View File
@@ -0,0 +1,5 @@
commands.forge.usage=Usa /forge <subcomando>. Los subcomandos son tps, track
commands.forge.usage.tracking=Usa /forge track <tipo> <duración>. Los tipos válidos te (Tile Entities). La duración es < 60.
commands.forge.tps.summary=%s : Tiempo de tick medio: %d ms. TPS medio: %d
commands.forge.tracking.te.enabled=Rastreo de Tile Entity activado durante %d segundos.
+5
View File
@@ -0,0 +1,5 @@
commands.forge.usage=Utilisez /forge <sous-commande>. Les sous-commandes sont tps, track
commands.forge.usage.tracking=Utilisez /forge track <type> <durée>. Les types valides sont te (Tile Entities). La durée doit être inférieur à 60.
commands.forge.tps.summary=%s : Duré de tick : %d ms. TPS moyen : %d
commands.forge.tracking.te.enabled=Trackage des Tile Entity activé pour %d secondes.
+111 -113
View File
@@ -1,162 +1,160 @@
#Main Forge Access Transformer configuration file
# Tessellator
public-f bff.a #FD:Tessellator/field_78398_a #instance
public bff.u #FD:Tessellator/field_78409_u #drawMode
public bff.v #FD:Tessellator/field_78408_v #xOffset
public bff.w #FD:Tessellator/field_78407_w #yOffset
public bff.x #FD:Tessellator/field_78417_x #zOffset
public bff.z #FD:Tessellator/field_78415_z #isDrawing
public-f bfq.a #FD:Tessellator/field_78398_a #instance
public bfq.u #FD:Tessellator/field_78409_u #drawMode
public bfq.v #FD:Tessellator/field_78408_v #xOffset
public bfq.w #FD:Tessellator/field_78407_w #yOffset
public bfq.x #FD:Tessellator/field_78417_x #zOffset
public bfq.z #FD:Tessellator/field_78415_z #isDrawing
# ItemPickaxe
public yi.<init>(ILxy;)V #MD:ItemPickaxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f yi.c #FD:ItemPickaxe/field_77867_c #blocksEffectiveAgainst
public yn.<init>(ILyd;)V #MD:ItemPickaxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f yn.c #FD:ItemPickaxe/field_77867_c #blocksEffectiveAgainst
# ItemAxe
public xv.<init>(ILxy;)V #MD:ItemAxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f xv.c #FD:ItemAxe/field_77868_c #blocksEffectiveAgainst
public ya.<init>(ILyd;)V #MD:ItemAxe/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f ya.c #FD:ItemAxe/field_77868_c #blocksEffectiveAgainst
# ItemSpade
public yt.<init>(ILxy;)V #MD:ItemSpade/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f yt.c #FD:ItemSpade/field_77866_c #blocksEffectiveAgainst
public yy.<init>(ILyd;)V #MD:ItemSpade/<init>(ILnet/minecraft/src/EnumToolMaterial;) #constructor
public+f yy.c #FD:ItemSpade/field_77866_c #blocksEffectiveAgainst
# ItemTool
public xe.a #FD:ItemTool/field_77864_a #efficiencyOnProperMaterial
public xe.d #FD:ItemTool/field_77865_bY #damageVsEntity
public xj.a #FD:ItemTool/field_77864_a #efficiencyOnProperMaterial
public xj.d #FD:ItemTool/field_77865_bY #damageVsEntity
# EntityEnderman
public td.br #FD:EntityEnderman/field_70827_d #carriableBlocks
# RenderEngine
# -- MISSING MAPPING public bge.f(Ljava/lang/String;)I #MD:RenderEngine/func_78341_b #getTexture
# -- MISSING MAPPING public bge.i #FD:RenderEngine/field_94154_l #terrainTextureMap
# -- MISSING MAPPING public bge.j #FD:RenderEngine/field_94155_m #itemTextureMap
public tg.br #FD:EntityEnderman/field_70827_d #carriableBlocks
# RenderGlobal
public bfa.k #FD:RenderGlobal/field_72769_h #theWorld
public bfa.l #FD:RenderGlobal/field_72770_i #renderEngine
public bfa.t #FD:RenderGlobal/field_72777_q #mc
public bfa.u #FD:RenderGlobal/field_72776_r #globalRenderBlocks
public bfa.H #FD:RenderGlobal/field_72738_E #damagedBlocks
public bfl.k #FD:RenderGlobal/field_72769_h #theWorld
public bfl.l #FD:RenderGlobal/field_72770_i #renderEngine
public bfl.t #FD:RenderGlobal/field_72777_q #mc
public bfl.u #FD:RenderGlobal/field_72776_r #globalRenderBlocks
public bfl.H #FD:RenderGlobal/field_72738_E #damagedBlocks
# SoundManager
public blc.b #FD:SoundManager/field_77381_a #sndSystem
public blc.d #FD:SoundManager/field_77379_b #soundPoolSounds
public blc.e #FD:SoundManager/field_77380_c #soundPoolStreaming
public blc.f #FD:SoundManager/field_77377_d #soundPoolMusic
public bln.b #FD:SoundManager/field_77381_a #sndSystem
public bln.d #FD:SoundManager/field_77379_b #soundPoolSounds
public bln.e #FD:SoundManager/field_77380_c #soundPoolStreaming
public bln.f #FD:SoundManager/field_77377_d #soundPoolMusic
# EntityMinecart
protected sq.* #FD:EntityMinecart/* # All private -> protected
# -- MISSING MAPPING public py.h()Z #MD:EntityMinecart/func_70490_h #isMinecartPowered
protected st.* #FD:EntityMinecart/* # All private -> protected
# Block
public aqs.<init>(ILajv;)V #MD:Block/<init>(ILnet/minecraft/src/Material;) #Constructor
public aqs.<init>(IILajv;)V #MD:Block/<init>(IILnet/minecraft/src/Material;) #Constructor
public aqs.cH #FD:Block/field_72029_cc #blockResistance
public aqs.cG #FD:Block/field_71989_cb #blockHardness
# -- MISSING MAPPING public amq.r()Lamq; #MD:Block/func_71912_p #setRequiresSelfNotify
public aqs.a(Laqw;)Laqs; #MD:Block/func_71884_a #setStepSound
public aqs.b(F)Laqs; #MD:Block/func_71894_b #setResistance
public aqs.c(F)Laqs; #MD:Block/func_71848_c #setHardness
public aqs.k(I)Laqs; #MD:Block/func_71868_h #setLightOpacity
public aqs.a(F)Laqs; #MD:Block/func_71900_a #setLightValue
public aqs.r()Laqs; #MD:Block/func_71875_q #setBlockUnbreakable
public aqs.b(Z)Laqs; #MD:Block/func_71907_b #setTickRandomly
public aqs.a(FFFFFF)V #MD:Block/func_71905_a #setBlockBounds
public aqz.<init>(ILakc;)V #MD:Block/<init>(ILnet/minecraft/src/Material;) #Constructor
public aqz.<init>(IILakc;)V #MD:Block/<init>(IILnet/minecraft/src/Material;) #Constructor
public aqz.cH #FD:Block/field_72029_cc #blockResistance
public aqz.cG #FD:Block/field_71989_cb #blockHardness
public aqz.d(Ljava/lang/String;)Laqz; #MD:Block/func_111022_d #setIconName
public aqz.a(Lard;)Laqz; #MD:Block/func_71884_a #setStepSound
public aqz.b(F)Laqz; #MD:Block/func_71894_b #setResistance
public aqz.c(F)Laqz; #MD:Block/func_71848_c #setHardness
public aqz.k(I)Laqz; #MD:Block/func_71868_h #setLightOpacity
public aqz.a(F)Laqz; #MD:Block/func_71900_a #setLightValue
public aqz.r()Laqz; #MD:Block/func_71875_q #setBlockUnbreakable
public aqz.b(Z)Laqz; #MD:Block/func_71907_b #setTickRandomly
public aqz.a(FFFFFF)V #MD:Block/func_71905_a #setBlockBounds
public aqz.j(Labw;IIII)V #MD:Block/func_71923_g #dropXpOnBlockBreak
# NetServerHandler
public jx.f #FD:NetServerHandler/field_72572_g #playerInAirTime
public ka.f #FD:NetServerHandler/field_72572_g #playerInAirTime
# TileEntity
public asi.k #FD:TileEntity/field_70331_k #worldObj
public asp.k #FD:TileEntity/field_70331_k #worldObj
# BlockLeavesBase
public ara.d #FD:BlockLeavesBase/field_72131_c #graphicsLevel
public arh.d #FD:BlockLeavesBase/field_72131_c #graphicsLevel
# Item
public xx.<init>(I)V #MD:Item/<init>(I) #Constructor
public xx.e(I)Lxx; #MD:Item/func_77656_e #setMaxDamage
public-f xx.h(Lxz;)Lmp; #MD:Item/func_77650_f #getIconIndex
public xx.c(Ljava/lang/String;)Lxx; #MD:Item/func_77631_c #setPotionEffect
public yc.<init>(I)V #MD:Item/<init>(I) #Constructor
public yc.e(I)Lyc; #MD:Item/func_77656_e #setMaxDamage
public-f yc.h(Lye;)Lms; #MD:Item/func_77650_f #getIconIndex
public yc.c(Ljava/lang/String;)Lyc; #MD:Item/func_77631_c #setPotionEffect
public yc.d(Ljava/lang/String;)Lyc; #MD:Item/func_111206_d #setIconName
# RailLogic
public ams #CL:BlockBaseRailLogic
public ams.a()I #MD:BlockBaseRailLogic/func_94505_a #getNAdjacentTiles
public amz #CL:BlockBaseRailLogic
public amz.a()I #MD:BlockBaseRailLogic/func_94505_a #getNAdjacentTiles
# EntityPlayer
public ua.a(Lsp;)V #MD:EntityPlayer/func_71012_a #joinEntityItemWithWorld
public ua.i()V #MD:EntityPlayer/func_71053_j #closeScreen
public ua.b #FD:EntityPlayer/field_71076_b #sleepTimer
public uf.a(Lss;)V #MD:EntityPlayer/func_71012_a #joinEntityItemWithWorld
public uf.i()V #MD:EntityPlayer/func_71053_j #closeScreen
public uf.b #FD:EntityPlayer/field_71076_b #sleepTimer
# EntityPlayerMP
public bcx.a(Lsp;)V #MD:EntityClientPlayerMP/func_71012_a #joinEntityItemWithWorld
public bdi.a(Lss;)V #MD:EntityClientPlayerMP/func_71012_a #joinEntityItemWithWorld
# World Gen Chests Related
public mh.* #FD:WeightedRandomChestContent/* #all
public jp.T #FD:WorldServer/field_73069_S #bonusChestContent
public agc.a #FD:StructureMineshaftPieces/field_78818_a #mineshaftChestContents
public ahg.i #FD:ComponentScatteredFeatureDesertPyramid/field_74941_i #itemsToGenerateInTemple
public ahh.l #FD:ComponentScatteredFeatureJunglePyramid/field_74943_l #junglePyramidsChestContents
public ahh.m #FD:ComponentScatteredFeatureJunglePyramid/field_74944_m #junglePyramidsDispenserContents
public ahr.a #FD:ComponentStrongholdChestCorridor/field_75003_a #strongholdChestContents
public ahv.b #FD:ComponentStrongholdLibrary/field_75007_b #strongholdLibraryChestContents
public aia.c #FD:ComponentStrongholdRoomCrossing/field_75014_c #strongholdCorridorChestContents
public ajb.a #FD:ComponentVillageHouse2/field_74918_a #villageBlacksmithChestContents
public mk.* #FD:WeightedRandomChestContent/* #all
public js.T #FD:WorldServer/field_73069_S #bonusChestContent
public agh.a #FD:StructureMineshaftPieces/field_78818_a #mineshaftChestContents
public ahl.i #FD:ComponentScatteredFeatureDesertPyramid/field_74941_i #itemsToGenerateInTemple
public ahm.l #FD:ComponentScatteredFeatureJunglePyramid/field_74943_l #junglePyramidsChestContents
public ahm.m #FD:ComponentScatteredFeatureJunglePyramid/field_74944_m #junglePyramidsDispenserContents
public ahw.a #FD:ComponentStrongholdChestCorridor/field_75003_a #strongholdChestContents
public aia.a #FD:ComponentStrongholdLibrary/field_75007_b #strongholdLibraryChestContents
public aif.b #FD:ComponentStrongholdRoomCrossing/field_75014_c #strongholdCorridorChestContents
public aji.a #FD:ComponentVillageHouse2/field_74918_a #villageBlacksmithChestContents
public afp.a #FD:WorldGenDungeons/field_111189_a #chestContents
# AnvilChunkLoader.chunkSaveLocation
public adz.d #FD:AnvilChunkLoader/field_75825_d
public aee.d #FD:AnvilChunkLoader/field_75825_d
# ChunkProviderServer.currentChunkLoader
public jo.e #FD:ChunkProviderServer/field_73247_e
public jr.e #FD:ChunkProviderServer/field_73247_e
# PlayerManager
public jm.a(IIZ)Ljn; #MD:PlayerManager/func_72690_a #getOrCreateChunkWatcher
public jp.a(IIZ)Ljq; #MD:PlayerManager/func_72690_a #getOrCreateChunkWatcher
# PlayerInstance
public jn #CL:PlayerInstance
public jq #CL:PlayerInstance
# World
public-f abr.A #FD:World/field_72982_D #villageCollectionObj
public abr.G #FD:World/field_72993_I #activeChunkSet
public-f abw.A #FD:World/field_72982_D #villageCollectionObj
public abw.G #FD:World/field_72993_I #activeChunkSet
# EntityLiving
public od.b #FD:EntityLiving/field_70728_aV #experienceValue
# -- MISSING MAPPING public ng.bt #FD:EntityLiving/field_94063_bt #combatTracker
public od.d #FD:EntityLiving/field_70715_bh #targetTasks
public og.b #FD:EntityLiving/field_70728_aV #experienceValue
public og.d #FD:EntityLiving/field_70715_bh #targetTasks
# GuiFlatPresets
public avq.a(Ljava/lang/String;ILacl;Ljava/util/List;[Lafy;)V #MD:GuiFlatPresets/func_82294_a
public avq.a(Ljava/lang/String;ILacl;[Lafy;)V #MD:GuiFlatPresets/func_82297_a
public avz.a(Ljava/lang/String;ILacq;Ljava/util/List;[Lagd;)V #MD:GuiFlatPresets/func_82294_a
public avz.a(Ljava/lang/String;ILacq;[Lagd;)V #MD:GuiFlatPresets/func_82297_a
# BiomeGenBase
public acl.*() #MD:BiomeGenBase/* #Everything protected->public
public acq.*() #MD:BiomeGenBase/* #Everything protected->public
# MapGenVillage
public-f aip.e #FD:MapGenVillage/field_75055_e #villageSpawnBiomes
public-f aiw.e #FD:MapGenVillage/field_75055_e #villageSpawnBiomes
# ShapedRecipes
public+f aad.d #FD:ShapedRecipes/field_77574_d #recipeItems
public+f aad.b #FD:ShapedRecipes/field_77576_b #recipeWidth
public+f aad.c #FD:ShapedRecipes/field_77577_c #recipeHeight
public+f aai.d #FD:ShapedRecipes/field_77574_d #recipeItems
public+f aai.b #FD:ShapedRecipes/field_77576_b #recipeWidth
public+f aai.c #FD:ShapedRecipes/field_77577_c #recipeHeight
# ShapelessRecipes
public aae.b #FD:ShapelessRecipes/field_77579_b #recipeItems
public aaj.b #FD:ShapelessRecipes/field_77579_b #recipeItems
# GuiContainer
protected awp.a(Lvz;)V #MD:GuiContainer/func_74192_a #drawSlotInventory
protected awy.a(Lwe;)V #MD:GuiContainer/func_74192_a #drawSlotInventory
# ContainerPlayer
protected vq.h #FD:ContainerPlayer/field_82862_h #player
protected vv.h #FD:ContainerPlayer/field_82862_h #player
# BlockButton
protected amy.n(Labr;III)V #MD:BlockButton/func_82535_o #checkActivation
protected-f amy.a #FD:BlockButton/field_82537_a #sensible
protected anf.n(Labw;III)V #MD:BlockButton/func_82535_o #checkActivation
protected-f anf.a #FD:BlockButton/field_82537_a #sensible
# BiomeDecorator
public acp.* #FD:BiomeDecorator/* # All private -> protected
public acu.* #FD:BiomeDecorator/* # All private -> protected
# CreativeTabs
public-f wr.a #FD:CreativeTabs/field_78032_a # creativeTabArray non-final
public-f ww.a #FD:CreativeTabs/field_78032_a # creativeTabArray non-final
# Packet
public ex.a(IZZLjava/lang/Class;)V #MD:Packet/func_73285_a #addIdClassMapping
public ey.a(IZZLjava/lang/Class;)V #MD:Packet/func_73285_a #addIdClassMapping
# SaveHandler
public alj.b()Ljava/io/File; #MD:SaveHandler/func_75765_b
public alq.b()Ljava/io/File; #MD:SaveHandler/func_75765_b
# World stuff
public abr.b(Lnk;)V #MD:World/func_72847_b #releaseEntitySkin
public abr.m #FD:World/field_73003_n #prevRainingStrength
public abr.n #FD:World/field_73004_o #rainingStrength
public abr.p #FD:World/field_73017_q #thunderingStrength
public abr.o #FD:World/field_73018_p #prevThunderingStrength
public abw.b(Lnn;)V #MD:World/func_72847_b #releaseEntitySkin
public abw.m #FD:World/field_73003_n #prevRainingStrength
public abw.n #FD:World/field_73004_o #rainingStrength
public abw.p #FD:World/field_73017_q #thunderingStrength
public abw.o #FD:World/field_73018_p #prevThunderingStrength
#WorldClient
public bcu.b(Lnk;)V #MD:WorldClient/func_72847_b #releaseEntitySkin
public bdd.b(Lnn;)V #MD:WorldClient/func_72847_b #releaseEntitySkin
#WorldServer
public jp.b(Lnk;)V #MD:WorldServer/func_72847_b #releaseEntitySkin
public jp.N #FD:WorldServer/field_73068_P #allPlayersSleeping
public js.b(Lnn;)V #MD:WorldServer/func_72847_b #releaseEntitySkin
public js.N #FD:WorldServer/field_73068_P #allPlayersSleeping
#TextureMap
public bhz.g #FD:TextureMap/field_94255_a
# -- MISSING MAPPING public bir.b #FD:TextureMap/field_94253_b
public bhz.h #FD:TextureMap/field_94254_c
# -- MISSING MAPPING public bir.d #FD:TextureMap/field_94251_d
public bik.g #FD:TextureMap/field_94255_a
public bik.h #FD:TextureMap/field_94254_c
#Potion
public nf.b(II)Lnf; #MD:Potion/func_76399_b #setIconIndex
public ni.b(II)Lni; #MD:Potion/func_76399_b #setIconIndex
#PotionHelper
public zk.m #FD:PotionHelper/field_77927_l #potionRequirements
public zk.n #FD:PotionHelper/field_77928_m #potionAmplifiers
public zp.m #FD:PotionHelper/field_77927_l #potionRequirements
public zp.n #FD:PotionHelper/field_77928_m #potionAmplifiers
#PotionEffect
public ng.b #FD:PotionEffect/field_76460_b #duration
public nj.b #FD:PotionEffect/field_76460_b #duration
#BlockFluid
protected aov.a #FD:BlockFluid/field_94425_a #theIcon
protected apc.a #FD:BlockFluid/field_94425_a #theIcon
#GuiIngame
protected ava.* #FD:GuiIngame/* # All private -> protected
protected ava.*() #MD:GuiIngame/* # All private -> protected
protected avj.* #FD:GuiIngame/* # All private -> protected
protected avj.*() #MD:GuiIngame/* # All private -> protected
#ItemStack
default xz.f #FD:ItemStack/field_77991_e # make default access for itemDamage
default ye.f #FD:ItemStack/field_77991_e # make default access for itemDamage
#GuiSlot
protected avx.b(IIII)V #MD:GuiSlot/func_77206_b #overlayBackground
protected awg.b(IIII)V #MD:GuiSlot/func_77206_b #overlayBackground
#EntityPlayer
public ua.bu #FD:EntityPlayer/field_71092_bJ #username
public uf.bu #FD:EntityPlayer/field_71092_bJ #username
#MapGenStructureIO
public air.b(Ljava/lang/Class;Ljava/lang/String;)V #MD:MapGenStructureIO/func_143034_b #registerStart
public air.a(Ljava/lang/Class;Ljava/lang/String;)V #MD:MapGenStructureIO/func_143031_a #registerPiece
@@ -1,5 +1,6 @@
package net.minecraftforge.classloading;
import java.io.File;
import java.util.Map;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
@@ -7,6 +8,7 @@ import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
public class FMLForgePlugin implements IFMLLoadingPlugin
{
public static boolean RUNTIME_DEOBF = false;
public static File forgeLocation;
@Override
public String[] getLibraryRequestClass()
@@ -39,5 +41,6 @@ public class FMLForgePlugin implements IFMLLoadingPlugin
public void injectData(Map<String, Object> data)
{
RUNTIME_DEOBF = (Boolean)data.get("runtimeDeobfuscationEnabled");
forgeLocation = (File)data.get("coremodLocation");
}
}
@@ -1,7 +1,10 @@
package net.minecraftforge.common;
import java.util.*;
import cpw.mods.fml.common.FMLLog;
import net.minecraft.world.biome.*;
import net.minecraftforge.event.terraingen.DeferredBiomeDecorator;
import static net.minecraft.world.biome.BiomeGenBase.*;
import static net.minecraftforge.common.BiomeDictionary.Type.*;
@@ -185,20 +188,35 @@ public class BiomeDictionary
return biomeList[biomeID] != null;
}
public static void registerAllBiomes()
{
FMLLog.warning("Redundant call to BiomeDictionary.registerAllBiomes ignored");
}
/**
* Loops through the biome list and automatically adds tags to any biome that does not have any
* This should be called in postInit to make sure all biomes have been registered
* This is called by Forge at postinit time. It will additionally dispatch any deferred decorator
* creation events.
*
* DO NOT call this during world generation
*/
public static void registerAllBiomes()
public static void registerAllBiomesAndGenerateEvents()
{
for(int i = 0; i < BIOME_LIST_SIZE; i++)
for(int i = 0; i < BiomeGenBase.biomeList.length; i++)
{
if(BiomeGenBase.biomeList[i] != null)
BiomeGenBase biome = BiomeGenBase.biomeList[i];
if(biome == null)
{
checkRegistration(BiomeGenBase.biomeList[i]);
continue;
}
if (biome.theBiomeDecorator instanceof DeferredBiomeDecorator)
{
DeferredBiomeDecorator decorator = (DeferredBiomeDecorator) biome.theBiomeDecorator;
decorator.fireCreateEventAndReplace();
}
checkRegistration(biome);
}
}
@@ -7,6 +7,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.WeightedRandom;
import net.minecraft.util.WeightedRandomChestContent;
import net.minecraft.world.WorldServer;
import net.minecraft.world.gen.feature.WorldGenDungeons;
import net.minecraft.world.gen.structure.*;
import net.minecraftforge.oredict.OreDictionary;
@@ -49,6 +50,7 @@ public class ChestGenHooks
addInfo(STRONGHOLD_CROSSING, ComponentStrongholdRoomCrossing.strongholdRoomCrossingChestContents, 1, 5);
addInfo(VILLAGE_BLACKSMITH, ComponentVillageHouse2.villageBlacksmithChestContents, 3, 9);
addInfo(BONUS_CHEST, WorldServer.bonusChestContent, 10, 10);
addInfo(DUNGEON_CHEST, WorldGenDungeons.field_111189_a, 8, 8);
ItemStack book = new ItemStack(Item.enchantedBook, 1, 0);
WeightedRandomChestContent tmp = new WeightedRandomChestContent(book, 1, 1, 1);
@@ -58,25 +60,7 @@ public class ChestGenHooks
getInfo(STRONGHOLD_CORRIDOR ).addItem(tmp);
getInfo(STRONGHOLD_LIBRARY ).addItem(new WeightedRandomChestContent(book, 1, 5, 2));
getInfo(STRONGHOLD_CROSSING ).addItem(tmp);
//Wish Dungeons would get on the same wave length as other world gen...
ChestGenHooks d = new ChestGenHooks(DUNGEON_CHEST);
d.countMin = 8;
d.countMax = 8;
chestInfo.put(DUNGEON_CHEST, d);
addDungeonLoot(d, new ItemStack(Item.saddle), 100, 1, 1);
addDungeonLoot(d, new ItemStack(Item.ingotIron), 100, 1, 4);
addDungeonLoot(d, new ItemStack(Item.bread), 100, 1, 1);
addDungeonLoot(d, new ItemStack(Item.wheat), 100, 1, 4);
addDungeonLoot(d, new ItemStack(Item.gunpowder), 100, 1, 4);
addDungeonLoot(d, new ItemStack(Item.silk), 100, 1, 4);
addDungeonLoot(d, new ItemStack(Item.bucketEmpty), 100, 1, 1);
addDungeonLoot(d, new ItemStack(Item.appleGold), 1, 1, 1);
addDungeonLoot(d, new ItemStack(Item.redstone), 50, 1, 4);
addDungeonLoot(d, new ItemStack(Item.record13), 5, 1, 1);
addDungeonLoot(d, new ItemStack(Item.recordCat), 5, 1, 1);
addDungeonLoot(d, new ItemStack(Item.dyePowder, 1, 3), 100, 1, 1);
addDungeonLoot(d, book, 100, 1, 1);
getInfo(DUNGEON_CHEST ).addItem(tmp);
}
static void addDungeonLoot(ChestGenHooks dungeon, ItemStack item, int weight, int min, int max)
@@ -124,7 +108,7 @@ public class ChestGenHooks
{
ret = new ItemStack[0];
}
else if (count > source.getItem().getItemStackLimit())
else if (count > source.getMaxStackSize())
{
ret = new ItemStack[count];
for (int x = 0; x < count; x++)
@@ -197,12 +197,15 @@ public class DimensionManager
public static void setWorld(int id, WorldServer world)
{
if (world != null) {
if (world != null)
{
worlds.put(id, world);
weakWorldMap.put(world, world);
MinecraftServer.getServer().worldTickTimes.put(id, new long[100]);
FMLLog.info("Loading dimension %d (%s) (%s)", id, world.getWorldInfo().getWorldName(), world.getMinecraftServer());
} else {
}
else
{
worlds.remove(id);
MinecraftServer.getServer().worldTickTimes.remove(id);
FMLLog.info("Unloading dimension %d", id);
@@ -231,14 +234,18 @@ public class DimensionManager
public static void initDimension(int dim) {
WorldServer overworld = getWorld(0);
if (overworld == null) {
if (overworld == null)
{
throw new RuntimeException("Cannot Hotload Dim: Overworld is not Loaded!");
}
try {
try
{
DimensionManager.getProviderType(dim);
} catch (Exception e) {
}
catch (Exception e)
{
System.err.println("Cannot Hotload Dim: " + e.getMessage());
return; //If a provider hasn't been registered then we can't hotload the dim
return; // If a provider hasn't been registered then we can't hotload the dim
}
MinecraftServer mcServer = overworld.getMinecraftServer();
ISaveHandler savehandler = overworld.getSaveHandler();
@@ -46,7 +46,7 @@ public class EnumHelper
{EnumMovingObjectType.class},
{EnumSkyBlock.class, int.class},
{EnumStatus.class},
{EnumToolMaterial.class, int.class, int.class, float.class, int.class, int.class}
{EnumToolMaterial.class, int.class, int.class, float.class, float.class, int.class}
};
public static EnumAction addAction(String name)
@@ -102,7 +102,7 @@ public class EnumHelper
{
return addEnum(EnumStatus.class, name);
}
public static EnumToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, int damage, int enchantability)
public static EnumToolMaterial addToolMaterial(String name, int harvestLevel, int maxUses, float efficiency, float damage, int enchantability)
{
return addEnum(EnumToolMaterial.class, name, harvestLevel, maxUses, efficiency, damage, enchantability);
}
@@ -1,16 +1,23 @@
package net.minecraftforge.common;
import cpw.mods.fml.common.FMLCommonHandler;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.ItemInWorldManager;
import net.minecraft.network.packet.Packet204ClientInfo;
import net.minecraft.server.MinecraftServer;
import net.minecraft.stats.StatBase;
import net.minecraft.util.ChatMessageComponent;
import net.minecraft.util.ChunkCoordinates;
import net.minecraft.util.DamageSource;
import net.minecraft.world.World;
//Preliminary, simple Fake Player class
public class FakePlayer extends EntityPlayer
public class FakePlayer extends EntityPlayerMP
{
public FakePlayer(World world, String name)
{
super(world, name);
super(FMLCommonHandler.instance().getMinecraftServerInstance(), world, name, new ItemInWorldManager(world));
}
public void sendChatToPlayer(String s){}
@@ -21,5 +28,21 @@ public class FakePlayer extends EntityPlayer
}
@Override
public void func_110122_a(ChatMessageComponent chatmessagecomponent){}
public void sendChatToPlayer(ChatMessageComponent chatmessagecomponent){}
@Override
public void addStat(StatBase par1StatBase, int par2){}
@Override
public void openGui(Object mod, int modGuiId, World world, int x, int y, int z){}
@Override
public boolean isEntityInvulnerable(){ return true; }
@Override
public boolean canAttackPlayer(EntityPlayer player){ return false; }
@Override
public void onDeath(DamageSource source){ return; }
@Override
public void onUpdate(){ return; }
@Override
public void travelToDimension(int dim){ return; }
@Override
public void updateClientInfo(Packet204ClientInfo pkt){ return; }
}
@@ -5,14 +5,30 @@ import net.minecraft.world.World;
//To be expanded for generic Mod fake players?
public class FakePlayerFactory
{
// Map of all active fake player usernames to their entities
private static java.util.Map<String, FakePlayer> fakePlayers = new java.util.HashMap<String, FakePlayer>();
private static FakePlayer MINECRAFT_PLAYER = null;
public static FakePlayer getMinecraft(World world)
{
if (MINECRAFT_PLAYER == null)
{
MINECRAFT_PLAYER = new FakePlayer(world, "[Minecraft]");
MINECRAFT_PLAYER = FakePlayerFactory.get(world, "[Minecraft]");
}
return MINECRAFT_PLAYER;
}
/**
* Get a fake player with a given username
*/
public static FakePlayer get(World world, String username)
{
if (!fakePlayers.containsKey(username))
{
FakePlayer fakePlayer = new FakePlayer(world, username);
fakePlayers.put(username, fakePlayer);
}
return fakePlayers.get(username);
}
}
@@ -22,8 +22,10 @@ import com.google.common.collect.BiMap;
import com.google.common.collect.ForwardingSet;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.LinkedHashMultimap;
@@ -34,6 +36,7 @@ import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Multiset;
import com.google.common.collect.Multisets;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.common.collect.TreeMultiset;
@@ -813,7 +816,10 @@ public class ForgeChunkManager
static void saveWorld(World world)
{
// only persist persistent worlds
if (!(world instanceof WorldServer)) { return; }
if (!(world instanceof WorldServer))
{
return;
}
WorldServer worldServer = (WorldServer) world;
File chunkDir = worldServer.getChunkSaveLocation();
File chunkLoaderData = new File(chunkDir, "forcedchunks.dat");
@@ -846,7 +852,7 @@ public class ForgeChunkManager
{
ticket.setCompoundTag("ModData", tick.modData);
}
if (tick.ticketType == Type.ENTITY && tick.entity != null && tick.entity.addEntityID(new NBTTagCompound()))
if (tick.ticketType == Type.ENTITY && tick.entity != null && tick.entity.writeToNBTOptional(new NBTTagCompound()))
{
ticket.setInteger("chunkX", MathHelper.floor_double(tick.entity.chunkCoordX));
ticket.setInteger("chunkZ", MathHelper.floor_double(tick.entity.chunkCoordZ));
@@ -10,14 +10,19 @@ import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.management.PlayerInstance;
import net.minecraft.world.storage.SaveHandler;
import net.minecraft.world.storage.WorldInfo;
import net.minecraftforge.classloading.FMLForgePlugin;
import net.minecraftforge.common.network.ForgeConnectionHandler;
import net.minecraftforge.common.network.ForgeNetworkHandler;
import net.minecraftforge.common.network.ForgePacketHandler;
import net.minecraftforge.common.network.ForgeTinyPacketHandler;
import net.minecraftforge.oredict.RecipeSorter;
import net.minecraftforge.server.command.ForgeCommand;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import cpw.mods.fml.client.FMLFileResourcePack;
import cpw.mods.fml.client.FMLFolderResourcePack;
import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.LoadController;
@@ -25,12 +30,14 @@ import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModMetadata;
import cpw.mods.fml.common.WorldAccessContainer;
import cpw.mods.fml.common.event.FMLConstructionEvent;
import cpw.mods.fml.common.event.FMLLoadCompleteEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLServerStartingEvent;
import cpw.mods.fml.common.network.FMLNetworkHandler;
import cpw.mods.fml.common.network.NetworkMod;
import static net.minecraftforge.common.ForgeVersion.*;
import static net.minecraftforge.common.Configuration.*;
@NetworkMod(
channels = "FORGE",
@@ -41,10 +48,15 @@ import static net.minecraftforge.common.ForgeVersion.*;
public class ForgeDummyContainer extends DummyModContainer implements WorldAccessContainer
{
public static int clumpingThreshold = 64;
public static boolean legacyFurnaceSides = false;
public static boolean removeErroringEntities = false;
public static boolean removeErroringTileEntities = false;
public static boolean disableStitchedFileSaving = false;
public static boolean forceDuplicateFluidBlockCrash = true;
public static boolean fullBoundingBoxLadders = false;
public static double zombieSummonBaseChance = 0.1;
public static int[] blendRanges = { 20, 15, 10, 5 };
public static float zombieBabyChance = 0.05f;
public static boolean shouldSortRecipies = false;
public ForgeDummyContainer()
{
@@ -98,17 +110,13 @@ public class ForgeDummyContainer extends DummyModContainer implements WorldAcces
prop.set(64);
}
prop = config.get(Configuration.CATEGORY_GENERAL, "legacyFurnaceOutput", false);
prop.comment = "Controls the sides of vanilla furnaces for Forge's ISidedInventroy, Vanilla defines the output as the bottom, but mods/Forge define it as the sides. Settings this to true will restore the old side relations.";
legacyFurnaceSides = prop.getBoolean(false);
prop = config.get(Configuration.CATEGORY_GENERAL, "removeErroringEntities", false);
prop.comment = "Set this to just remove any TileEntity that throws a error in there update method instead of closing the server and reporting a crash log. BE WARNED THIS COULD SCREW UP EVERYTHING USE SPARINGLY WE ARE NOT RESPONSIBLE FOR DAMAGES.";
removeErroringEntities = prop.getBoolean(false);
if (removeErroringEntities)
{
FMLLog.warning("Enableing removal of erroring Entities USE AT YOUR OWN RISK");
FMLLog.warning("Enabling removal of erroring Entities - USE AT YOUR OWN RISK");
}
prop = config.get(Configuration.CATEGORY_GENERAL, "removeErroringTileEntities", false);
@@ -117,12 +125,41 @@ public class ForgeDummyContainer extends DummyModContainer implements WorldAcces
if (removeErroringTileEntities)
{
FMLLog.warning("Enableing removal of erroring Tile Entities USE AT YOUR OWN RISK");
FMLLog.warning("Enabling removal of erroring Tile Entities - USE AT YOUR OWN RISK");
}
prop = config.get(Configuration.CATEGORY_GENERAL, "disableStitchedFileSaving", true);
prop.comment = "Set this to just disable the texture stitcher from writing the 'debug.stitched_{name}.png file to disc. Just a small performance tweak. Default: true";
disableStitchedFileSaving = prop.getBoolean(true);
//prop = config.get(Configuration.CATEGORY_GENERAL, "disableStitchedFileSaving", true);
//prop.comment = "Set this to just disable the texture stitcher from writing the 'debug.stitched_{name}.png file to disc. Just a small performance tweak. Default: true";
//disableStitchedFileSaving = prop.getBoolean(true);
prop = config.get(Configuration.CATEGORY_GENERAL, "fullBoundingBoxLadders", false);
prop.comment = "Set this to check the entire entity's collision bounding box for ladders instead of just the block they are in. Causes noticable differences in mechanics so default is vanilla behavior. Default: false";
fullBoundingBoxLadders = prop.getBoolean(false);
prop = config.get(Configuration.CATEGORY_GENERAL, "forceDuplicateFluidBlockCrash", true);
prop.comment = "Set this to force a crash if more than one block attempts to link back to the same Fluid. Enabled by default.";
forceDuplicateFluidBlockCrash = prop.getBoolean(true);
if (!forceDuplicateFluidBlockCrash)
{
FMLLog.warning("Disabling forced crashes on duplicate Fluid Blocks - USE AT YOUR OWN RISK");
}
prop = config.get(Configuration.CATEGORY_GENERAL, "biomeSkyBlendRange", new int[] { 20, 15, 10, 5 });
prop.comment = "Control the range of sky blending for colored skies in biomes.";
blendRanges = prop.getIntList();
prop = config.get(Configuration.CATEGORY_GENERAL, "zombieBaseSummonChance", 0.1);
prop.comment = "Base zombie summoning spawn chance. Allows changing the bonus zombie summoning mechanic.";
zombieSummonBaseChance = prop.getDouble(0.1);
prop = config.get(Configuration.CATEGORY_GENERAL, "zombieBabyChance", 0.05);
prop.comment = "Chance that a zombie (or subclass) is a baby. Allows changing the zombie spawning mechanic.";
zombieBabyChance = (float) prop.getDouble(0.05);
prop = config.get(CATEGORY_GENERAL, "sortRecipies", shouldSortRecipies);
prop.comment = "Set to true to enable the post initlization sorting of crafting recipes using Froge's sorter. May cause desyncing on conflicting recipies. ToDo: Set to true by default in 1.7";
shouldSortRecipies = prop.getBoolean(shouldSortRecipies);
if (config.hasChanged())
{
@@ -133,7 +170,7 @@ public class ForgeDummyContainer extends DummyModContainer implements WorldAcces
@Override
public boolean registerBus(EventBus bus, LoadController controller)
{
bus.register(this);
bus.register(this);
return true;
}
@@ -161,9 +198,24 @@ public class ForgeDummyContainer extends DummyModContainer implements WorldAcces
@Subscribe
public void postInit(FMLPostInitializationEvent evt)
{
ForgeChunkManager.loadConfiguration();
BiomeDictionary.registerAllBiomesAndGenerateEvents();
ForgeChunkManager.loadConfiguration();
}
@Subscribe
public void onAvalible(FMLLoadCompleteEvent evt)
{
if (shouldSortRecipies)
{
RecipeSorter.sortCraftManager();
}
}
@Subscribe
public void serverStarting(FMLServerStartingEvent evt)
{
evt.registerServerCommand(new ForgeCommand(evt.getServer()));
}
@Override
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info)
{
@@ -181,4 +233,22 @@ public class ForgeDummyContainer extends DummyModContainer implements WorldAcces
DimensionManager.loadDimensionDataMap(tag.hasKey("DimensionData") ? tag.getCompoundTag("DimensionData") : null);
}
}
@Override
public File getSource()
{
return FMLForgePlugin.forgeLocation;
}
@Override
public Class<?> getCustomResourcePackClass()
{
if (getSource().isDirectory())
{
return FMLFolderResourcePack.class;
}
else
{
return FMLFileResourcePack.class;
}
}
}
@@ -7,24 +7,35 @@ import java.util.HashSet;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.Container;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemAxe;
import net.minecraft.item.ItemPickaxe;
import net.minecraft.item.ItemSpade;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemSword;
import net.minecraft.network.NetServerHandler;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet53BlockChange;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ChatMessageComponent;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumMovingObjectType;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.WeightedRandom;
import net.minecraft.util.WeightedRandomItem;
import net.minecraft.world.EnumGameType;
import net.minecraft.world.World;
import net.minecraftforge.event.Event;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.event.ServerChatEvent;
import net.minecraftforge.event.entity.item.ItemTossEvent;
@@ -36,6 +47,8 @@ import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent;
import net.minecraftforge.event.entity.player.PlayerOpenContainerEvent;
import net.minecraftforge.event.world.BlockEvent;
public class ForgeHooks
{
@@ -353,7 +366,32 @@ public class ForgeHooks
public static boolean isLivingOnLadder(Block block, World world, int x, int y, int z, EntityLivingBase entity)
{
return block != null && block.isLadder(world, x, y, z, entity);
if (!ForgeDummyContainer.fullBoundingBoxLadders)
{
return block != null && block.isLadder(world, x, y, z, entity);
}
else
{
AxisAlignedBB bb = entity.boundingBox;
int mX = MathHelper.floor_double(bb.minX);
int mY = MathHelper.floor_double(bb.minY);
int mZ = MathHelper.floor_double(bb.minZ);
for (int y2 = mY; y2 < bb.maxY; y2++)
{
for (int x2 = mX; x2 < bb.maxX; x2++)
{
for (int z2 = mZ; z2 < bb.maxZ; z2++)
{
block = Block.blocksList[world.getBlockId(x2, y2, z2)];
if (block != null && block.isLadder(world, x2, y2, z2, entity))
{
return true;
}
}
}
}
return false;
}
}
public static void onLivingJump(EntityLivingBase entity)
@@ -368,6 +406,11 @@ public class ForgeHooks
player.capturedDrops.clear();
player.captureDrops = false;
if (ret == null)
{
return null;
}
ItemTossEvent event = new ItemTossEvent(ret, player);
if (MinecraftForge.EVENT_BUS.post(event))
{
@@ -398,4 +441,60 @@ public class ForgeHooks
}
return event.component;
}
public static boolean canInteractWith(EntityPlayer player, Container openContainer)
{
PlayerOpenContainerEvent event = new PlayerOpenContainerEvent(player, openContainer);
MinecraftForge.EVENT_BUS.post(event);
return event.getResult() == Event.Result.DEFAULT ? event.canInteractWith : event.getResult() == Event.Result.ALLOW ? true : false;
}
public static BlockEvent.BreakEvent onBlockBreakEvent(World world, EnumGameType gameType, EntityPlayerMP entityPlayer, int x, int y, int z)
{
// Logic from tryHarvestBlock for pre-canceling the event
boolean preCancelEvent = false;
if (gameType.isAdventure() && !entityPlayer.isCurrentToolAdventureModeExempt(x, y, z))
{
preCancelEvent = true;
}
else if (gameType.isCreative() && entityPlayer.getHeldItem() != null && entityPlayer.getHeldItem().getItem() instanceof ItemSword)
{
preCancelEvent = true;
}
// Tell client the block is gone immediately then process events
if (world.getBlockTileEntity(x, y, z) == null)
{
Packet53BlockChange packet = new Packet53BlockChange(x, y, z, world);
packet.type = 0;
packet.metadata = 0;
entityPlayer.playerNetServerHandler.sendPacketToPlayer(packet);
}
// Post the block break event
Block block = Block.blocksList[world.getBlockId(x, y, z)];
int blockMetadata = world.getBlockMetadata(x, y, z);
BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(x, y, z, world, block, blockMetadata, entityPlayer);
event.setCanceled(preCancelEvent);
MinecraftForge.EVENT_BUS.post(event);
// Handle if the event is canceled
if (event.isCanceled())
{
// Let the client know the block still exists
entityPlayer.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(x, y, z, world));
// Update any tile entity data for this block
TileEntity tileentity = world.getBlockTileEntity(x, y, z);
if (tileentity != null)
{
Packet pkt = tileentity.getDescriptionPacket();
if (pkt != null)
{
entityPlayer.playerNetServerHandler.sendPacketToPlayer(pkt);
}
}
}
return event;
}
}
@@ -8,11 +8,11 @@ package net.minecraftforge.common;
public class ForgeVersion
{
//This number is incremented every time we remove deprecated code/major API changes, never reset
public static final int majorVersion = 8;
public static final int majorVersion = 9;
//This number is incremented every minecraft release, never reset
public static final int minorVersion = 9;
public static final int minorVersion = 11;
//This number is incremented every time a interface changes or new major feature is added, and reset every Minecraft version
public static final int revisionVersion = 0;
public static final int revisionVersion = 1;
//This number is incremented every time Jenkins builds Forge, and never reset. Should always be 0 in the repo code.
public static final int buildVersion = 0;
@@ -1,31 +0,0 @@
/**
* This software is provided under the terms of the Minecraft Forge Public
* License v1.0.
*/
package net.minecraftforge.common;
import net.minecraft.inventory.IInventory;
/** Inventory ranges mapped by side. This class is implemented by TileEntities
* that provide different inventory slot ranges to different sides.
*/
@Deprecated //A equivalent Interface is now in Minecraft Vanilla will be removed next major MC version
public interface ISidedInventory extends IInventory
{
/**
* Get the start of the side inventory.
* @param side The global side to get the start of range.
*/
@Deprecated
int getStartInventorySide(ForgeDirection side);
/**
* Get the size of the side inventory.
* @param side The global side.
*/
@Deprecated
int getSizeInventorySide(ForgeDirection side);
}
@@ -187,7 +187,9 @@ public class MinecraftForge
Block filler = new Block(0, Material.air)
{
@SideOnly(Side.CLIENT) public void func_94332_a(IconRegister register){}
@SideOnly(Side.CLIENT)
@Override
public void registerIcons(IconRegister register){}
};
Block.blocksList[0] = null;
Block.opaqueCubeLookup[0] = false;
@@ -1,19 +1,82 @@
package net.minecraftforge.common;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import net.minecraft.block.Block;
import net.minecraft.block.BlockAnvil;
import net.minecraft.block.BlockBed;
import net.minecraft.block.BlockButton;
import net.minecraft.block.BlockChest;
import net.minecraft.block.BlockCocoa;
import net.minecraft.block.BlockComparator;
import net.minecraft.block.BlockDetectorRail;
import net.minecraft.block.BlockDispenser;
import net.minecraft.block.BlockDropper;
import net.minecraft.block.BlockDoor;
import net.minecraft.block.BlockEndPortalFrame;
import net.minecraft.block.BlockEnderChest;
import net.minecraft.block.BlockFenceGate;
import net.minecraft.block.BlockFurnace;
import net.minecraft.block.BlockHopper;
import net.minecraft.block.BlockLadder;
import net.minecraft.block.BlockLever;
import net.minecraft.block.BlockLog;
import net.minecraft.block.BlockMushroomCap;
import net.minecraft.block.BlockPistonBase;
import net.minecraft.block.BlockPistonExtension;
import net.minecraft.block.BlockPumpkin;
import net.minecraft.block.BlockRail;
import net.minecraft.block.BlockRailPowered;
import net.minecraft.block.BlockRedstoneRepeater;
import net.minecraft.block.BlockSkull;
import net.minecraft.block.BlockStairs;
import net.minecraft.block.BlockTorch;
import net.minecraft.block.BlockTrapDoor;
import net.minecraft.block.BlockTripWireSource;
import net.minecraft.block.BlockVine;
import net.minecraft.world.World;
import java.util.HashMap;
import java.util.Map;
import static net.minecraftforge.common.ForgeDirection.*;
public class RotationHelper {
/**
* Some blocks have the same rotation.
* The first of these blocks (sorted by itemID) should be listed as a type.
* Some of the types aren't actual blocks (helper types).
*/
private static enum BlockType {
LOG,
DISPENSER,
BED,
RAIL,
RAIL_POWERED,
RAIL_ASCENDING,
RAIL_CORNER,
TORCH,
STAIR,
CHEST,
SIGNPOST,
DOOR,
LEVER,
BUTTON,
REDSTONE_REPEATER,
TRAPDOOR,
MUSHROOM_CAP,
MUSHROOM_CAP_CORNER,
MUSHROOM_CAP_SIDE,
VINE,
SKULL,
ANVIL
}
private static final ForgeDirection[] UP_DOWN_AXES = new ForgeDirection[] { UP, DOWN };
private static final Map<BlockType, BiMap<Integer, ForgeDirection>> MAPPINGS = new HashMap<BlockType, BiMap<Integer, ForgeDirection>>();
public static ForgeDirection[] getValidVanillaBlockRotations(Block block)
{
return block instanceof BlockChest ? UP_DOWN_AXES : VALID_DIRECTIONS;
return (block instanceof BlockBed || block instanceof BlockPumpkin || block instanceof BlockFenceGate || block instanceof BlockEndPortalFrame || block instanceof BlockTripWireSource || block instanceof BlockCocoa || block instanceof BlockRailPowered || block instanceof BlockDetectorRail || block instanceof BlockStairs || block instanceof BlockChest || block instanceof BlockEnderChest || block instanceof BlockFurnace || block instanceof BlockLadder || block.blockID == Block.signWall.blockID || block.blockID == Block.signPost.blockID || block instanceof BlockDoor || block instanceof BlockRail || block instanceof BlockButton || block instanceof BlockRedstoneRepeater || block instanceof BlockComparator || block instanceof BlockTrapDoor || block instanceof BlockMushroomCap || block instanceof BlockVine || block instanceof BlockSkull || block instanceof BlockAnvil) ? UP_DOWN_AXES : VALID_DIRECTIONS;
}
public static boolean rotateVanillaBlock(Block block, World worldObj, int x, int y, int z, ForgeDirection axis)
@@ -23,25 +86,323 @@ public class RotationHelper {
return false;
}
if (block instanceof BlockChest && (axis == UP || axis == DOWN))
if (axis == UP || axis == DOWN)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7);
if (block instanceof BlockBed || block instanceof BlockPumpkin || block instanceof BlockFenceGate || block instanceof BlockEndPortalFrame || block instanceof BlockTripWireSource || block instanceof BlockCocoa)
{
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.BED);
}
if (block instanceof BlockRail)
{
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.RAIL);
}
if (block instanceof BlockRailPowered || block instanceof BlockDetectorRail)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.RAIL_POWERED);
}
if (block instanceof BlockStairs)
{
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.STAIR);
}
if (block instanceof BlockChest || block instanceof BlockEnderChest || block instanceof BlockFurnace || block instanceof BlockLadder || block.blockID == Block.signWall.blockID)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.CHEST);
}
if (block.blockID == Block.signPost.blockID)
{
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.SIGNPOST);
}
if (block instanceof BlockDoor)
{
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.DOOR);
}
if (block instanceof BlockButton)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.BUTTON);
}
if (block instanceof BlockRedstoneRepeater || block instanceof BlockComparator)
{
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.REDSTONE_REPEATER);
}
if (block instanceof BlockTrapDoor)
{
return rotateBlock(worldObj, x, y, z, axis, 0x3, BlockType.TRAPDOOR);
}
if (block instanceof BlockMushroomCap)
{
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.MUSHROOM_CAP);
}
if (block instanceof BlockVine)
{
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.VINE);
}
if (block instanceof BlockSkull)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.SKULL);
}
if (block instanceof BlockAnvil)
{
return rotateBlock(worldObj, x, y, z, axis, 0x1, BlockType.ANVIL);
}
}
if (block instanceof BlockPistonBase || block instanceof BlockDropper || block instanceof BlockDispenser)
if (block instanceof BlockLog)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7);
return rotateBlock(worldObj, x, y, z, axis, 0xC, BlockType.LOG);
}
if (block instanceof BlockDispenser || block instanceof BlockPistonBase || block instanceof BlockPistonExtension || block instanceof BlockHopper)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.DISPENSER);
}
if (block instanceof BlockTorch)
{
return rotateBlock(worldObj, x, y, z, axis, 0xF, BlockType.TORCH);
}
if (block instanceof BlockLever)
{
return rotateBlock(worldObj, x, y, z, axis, 0x7, BlockType.LEVER);
}
return false;
}
private static boolean rotateBlock(World worldObj, int x, int y, int z, ForgeDirection axis, int mask)
private static boolean rotateBlock(World worldObj, int x, int y, int z, ForgeDirection axis, int mask, BlockType blockType)
{
int rotMeta = worldObj.getBlockMetadata(x, y, z);
if (blockType == BlockType.DOOR && (rotMeta & 0x8) == 0x8)
{
return false;
}
int masked = rotMeta & ~mask;
ForgeDirection orientation = ForgeDirection.getOrientation(rotMeta & mask);
ForgeDirection rotated = orientation.getRotation(axis);
worldObj.setBlockMetadataWithNotify(x,y,z,rotated.ordinal() & mask | masked,3);
int meta = rotateMetadata(axis, blockType, rotMeta & mask);
if (meta == -1)
{
return false;
}
worldObj.setBlockMetadataWithNotify(x, y, z, meta & mask | masked, 3);
return true;
}
private static int rotateMetadata(ForgeDirection axis, BlockType blockType, int meta)
{
if (blockType == BlockType.RAIL || blockType == BlockType.RAIL_POWERED)
{
if (meta == 0x0 || meta == 0x1)
{
return ~meta & 0x1;
}
if (meta >= 0x2 && meta <= 0x5)
{
blockType = BlockType.RAIL_ASCENDING;
}
if (meta >= 0x6 && meta <= 0x9 && blockType == BlockType.RAIL)
{
blockType = BlockType.RAIL_CORNER;
}
}
if (blockType == BlockType.SIGNPOST)
{
return (axis == UP) ? (meta + 0x4) % 0x10 : (meta + 0xC) % 0x10;
}
if (blockType == BlockType.LEVER && (axis == UP || axis == DOWN))
{
switch (meta)
{
case 0x5:
return 0x6;
case 0x6:
return 0x5;
case 0x7:
return 0x0;
case 0x0:
return 0x7;
}
}
if (blockType == BlockType.MUSHROOM_CAP)
{
if (meta % 0x2 == 0)
{
blockType = BlockType.MUSHROOM_CAP_SIDE;
}
else
{
blockType = BlockType.MUSHROOM_CAP_CORNER;
}
}
if (blockType == BlockType.VINE)
{
return ((meta << 1) | ((meta & 0x8) >> 3));
}
ForgeDirection orientation = metadataToDirection(blockType, meta);
ForgeDirection rotated = orientation.getRotation(axis);
return directionToMetadata(blockType, rotated);
}
private static ForgeDirection metadataToDirection(BlockType blockType, int meta)
{
if (blockType == BlockType.LEVER)
{
if (meta == 0x6)
{
meta = 0x5;
}
else if (meta == 0x0)
{
meta = 0x7;
}
}
if (MAPPINGS.containsKey(blockType))
{
BiMap<Integer, ForgeDirection> biMap = MAPPINGS.get(blockType);
if (biMap.containsKey(meta))
{
return biMap.get(meta);
}
}
if (blockType == BlockType.TORCH)
{
return ForgeDirection.getOrientation(6 - meta);
}
if (blockType == BlockType.STAIR)
{
return ForgeDirection.getOrientation(5 - meta);
}
if (blockType == BlockType.CHEST || blockType == BlockType.DISPENSER || blockType == BlockType.SKULL)
{
return ForgeDirection.getOrientation(meta);
}
if (blockType == BlockType.BUTTON)
{
return ForgeDirection.getOrientation(6 - meta);
}
if (blockType == BlockType.TRAPDOOR)
{
return ForgeDirection.getOrientation(meta + 2).getOpposite();
}
return ForgeDirection.UNKNOWN;
}
private static int directionToMetadata(BlockType blockType, ForgeDirection direction)
{
if ((blockType == BlockType.LOG || blockType == BlockType.ANVIL) && (direction.offsetX + direction.offsetY + direction.offsetZ) < 0)
{
direction = direction.getOpposite();
}
if (MAPPINGS.containsKey(blockType))
{
BiMap<ForgeDirection, Integer> biMap = MAPPINGS.get(blockType).inverse();
if (biMap.containsKey(direction))
{
return biMap.get(direction);
}
}
if (blockType == BlockType.TORCH)
{
if (direction.ordinal() >= 1)
{
return 6 - direction.ordinal();
}
}
if (blockType == BlockType.STAIR)
{
return 5 - direction.ordinal();
}
if (blockType == BlockType.CHEST || blockType == BlockType.DISPENSER || blockType == BlockType.SKULL)
{
return direction.ordinal();
}
if (blockType == BlockType.BUTTON)
{
if (direction.ordinal() >= 2)
{
return 6 - direction.ordinal();
}
}
if (blockType == BlockType.TRAPDOOR)
{
return direction.getOpposite().ordinal() - 2;
}
return -1;
}
static
{
BiMap<Integer, ForgeDirection> biMap;
biMap = HashBiMap.create(3);
biMap.put(0x0, UP);
biMap.put(0x4, EAST);
biMap.put(0x8, SOUTH);
MAPPINGS.put(BlockType.LOG, biMap);
biMap = HashBiMap.create(4);
biMap.put(0x0, SOUTH);
biMap.put(0x1, WEST);
biMap.put(0x2, NORTH);
biMap.put(0x3, EAST);
MAPPINGS.put(BlockType.BED, biMap);
biMap = HashBiMap.create(4);
biMap.put(0x2, EAST);
biMap.put(0x3, WEST);
biMap.put(0x4, NORTH);
biMap.put(0x5, SOUTH);
MAPPINGS.put(BlockType.RAIL_ASCENDING, biMap);
biMap = HashBiMap.create(4);
biMap.put(0x6, WEST);
biMap.put(0x7, NORTH);
biMap.put(0x8, EAST);
biMap.put(0x9, SOUTH);
MAPPINGS.put(BlockType.RAIL_CORNER, biMap);
biMap = HashBiMap.create(6);
biMap.put(0x1, EAST);
biMap.put(0x2, WEST);
biMap.put(0x3, SOUTH);
biMap.put(0x4, NORTH);
biMap.put(0x5, UP);
biMap.put(0x7, DOWN);
MAPPINGS.put(BlockType.LEVER, biMap);
biMap = HashBiMap.create(4);
biMap.put(0x0, WEST);
biMap.put(0x1, NORTH);
biMap.put(0x2, EAST);
biMap.put(0x3, SOUTH);
MAPPINGS.put(BlockType.DOOR, biMap);
biMap = HashBiMap.create(4);
biMap.put(0x0, NORTH);
biMap.put(0x1, EAST);
biMap.put(0x2, SOUTH);
biMap.put(0x3, WEST);
MAPPINGS.put(BlockType.REDSTONE_REPEATER, biMap);
biMap = HashBiMap.create(4);
biMap.put(0x1, EAST);
biMap.put(0x3, SOUTH);
biMap.put(0x7, NORTH);
biMap.put(0x9, WEST);
MAPPINGS.put(BlockType.MUSHROOM_CAP_CORNER, biMap);
biMap = HashBiMap.create(4);
biMap.put(0x2, NORTH);
biMap.put(0x4, WEST);
biMap.put(0x6, EAST);
biMap.put(0x8, SOUTH);
MAPPINGS.put(BlockType.MUSHROOM_CAP_SIDE, biMap);
biMap = HashBiMap.create(2);
biMap.put(0x0, SOUTH);
biMap.put(0x1, EAST);
MAPPINGS.put(BlockType.ANVIL, biMap);
}
}
@@ -4,8 +4,11 @@ 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.minecraftforge.fluids.FluidIdMapPacket;
import cpw.mods.fml.common.network.IConnectionHandler;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;
public class ForgeConnectionHandler implements IConnectionHandler {
@@ -13,7 +16,10 @@ public class ForgeConnectionHandler implements IConnectionHandler {
@Override
public void playerLoggedIn(Player player, NetHandler netHandler, INetworkManager manager)
{
Packet250CustomPayload[] fluidPackets = ForgePacket.makePacketSet(new FluidIdMapPacket());
for (int i = 0; i < fluidPackets.length; i++) {
PacketDispatcher.sendPacketToPlayer(fluidPackets[i], player);
}
}
@Override
@@ -9,6 +9,7 @@ import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.NetHandler;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraftforge.common.network.packet.DimensionRegisterPacket;
import net.minecraftforge.fluids.FluidIdMapPacket;
import com.google.common.base.Throwables;
import com.google.common.collect.MapMaker;
@@ -29,7 +30,11 @@ public abstract class ForgePacket
/**
* Registers a dimension for a provider on client
*/
REGISTERDIMENSION(DimensionRegisterPacket.class);
REGISTERDIMENSION(DimensionRegisterPacket.class),
/**
* The Fluid ID map to send to the client
*/
FLUID_IDMAP(FluidIdMapPacket.class);
private Class<? extends ForgePacket> packetType;
private ConcurrentMap<INetworkManager, ForgePacket> partTracker;
@@ -1,10 +1,13 @@
package net.minecraftforge.event;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
@@ -13,10 +16,14 @@ import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.Event.Result;
import net.minecraftforge.event.entity.living.LivingPackSizeEvent;
import net.minecraftforge.event.entity.living.LivingSpawnEvent;
import net.minecraftforge.event.entity.living.LivingSpawnEvent.AllowDespawn;
import net.minecraftforge.event.entity.living.ZombieEvent.SummonAidEvent;
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.event.world.WorldEvent;
@SuppressWarnings("deprecation")
@@ -59,6 +66,13 @@ public class ForgeEventFactory
return MinecraftForge.EVENT_BUS.post(new LivingSpawnEvent.SpecialSpawn(entity, world, x, y, z));
}
public static Result canEntityDespawn(EntityLiving entity)
{
AllowDespawn event = new AllowDespawn(entity);
MinecraftForge.EVENT_BUS.post(event);
return event.getResult();
}
public static List getPotentialSpawns(WorldServer world, EnumCreatureType type, int x, int y, int z, List oldList)
{
WorldEvent.PotentialSpawns event = new WorldEvent.PotentialSpawns(world, type, x, y, z, oldList);
@@ -75,4 +89,32 @@ public class ForgeEventFactory
MinecraftForge.EVENT_BUS.post(maxCanSpawnEvent);
return maxCanSpawnEvent.getResult() == Result.ALLOW ? maxCanSpawnEvent.maxPackSize : entity.getMaxSpawnedInChunk();
}
public static String getPlayerDisplayName(EntityPlayer player, String username)
{
PlayerEvent.NameFormat event = new PlayerEvent.NameFormat(player, username);
MinecraftForge.EVENT_BUS.post(event);
return event.displayname;
}
public static float fireBlockHarvesting(ArrayList<ItemStack> drops, World world, Block block, int x, int y, int z, int meta, int fortune, float dropChance, boolean silkTouch, EntityPlayer player)
{
BlockEvent.HarvestDropsEvent event = new BlockEvent.HarvestDropsEvent(x, y, z, world, block, meta, fortune, dropChance, drops, player, silkTouch);
MinecraftForge.EVENT_BUS.post(event);
return event.dropChance;
}
public static ItemTooltipEvent onItemTooltip(ItemStack itemStack, EntityPlayer entityPlayer, List<String> toolTip, boolean showAdvancedItemTooltips)
{
ItemTooltipEvent event = new ItemTooltipEvent(itemStack, entityPlayer, toolTip, showAdvancedItemTooltips);
MinecraftForge.EVENT_BUS.post(event);
return event;
}
public static SummonAidEvent fireZombieSummonAid(EntityZombie zombie, World world, int x, int y, int z, EntityLivingBase attacker, double summonChance)
{
SummonAidEvent summonEvent = new SummonAidEvent(zombie, world, x, y, z, attacker, summonChance);
MinecraftForge.EVENT_BUS.post(summonEvent);
return summonEvent;
}
}
@@ -0,0 +1,17 @@
package net.minecraftforge.event.entity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.effect.EntityLightningBolt;
import net.minecraftforge.event.Cancelable;
@Cancelable
public class EntityStruckByLightningEvent extends EntityEvent
{
public final EntityLightningBolt lightning;
public EntityStruckByLightningEvent(Entity entity, EntityLightningBolt lightning)
{
super(entity);
this.lightning = lightning;
}
}
@@ -47,4 +47,27 @@ public class LivingSpawnEvent extends LivingEvent
super(entity, world, x, y, z);
}
}
/**
* Fired each tick for despawnable mobs to allow control over despawning.
* {@link Result#DEFAULT} will pass the mob on to vanilla despawn mechanics.
* {@link Result#ALLOW} will force the mob to despawn.
* {@link Result#DENY} will force the mob to remain.
* This is fired every tick for every despawnable entity. Be efficient in your handlers.
*
* Note: this is not fired <em>if</em> the mob is definitely going to otherwise despawn. It is fired to check if
* the mob can be allowed to despawn. See {@link EntityLiving#despawnEntity}
*
* @author cpw
*
*/
@HasResult
public static class AllowDespawn extends LivingSpawnEvent
{
public AllowDespawn(EntityLiving entity)
{
super(entity, entity.worldObj, (float)entity.posX, (float)entity.posY, (float)entity.posZ);
}
}
}
@@ -0,0 +1,48 @@
package net.minecraftforge.event.entity.living;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.world.World;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.entity.EntityEvent;
public class ZombieEvent extends EntityEvent {
public ZombieEvent(EntityZombie entity)
{
super(entity);
}
public EntityZombie getSummoner()
{
return (EntityZombie) entity;
}
@HasResult
public static class SummonAidEvent extends ZombieEvent {
/**
* Populate this field to have a custom zombie instead of a normal zombie summoned
*/
public EntityZombie customSummonedAid;
public final World world;
public final int x;
public final int y;
public final int z;
public final EntityLivingBase attacker;
public final double summonChance;
public SummonAidEvent(EntityZombie entity, World world, int x, int y, int z, EntityLivingBase attacker, double summonChance)
{
super(entity);
this.world = world;
this.x = x;
this.y = y;
this.z = z;
this.attacker = attacker;
this.summonChance = summonChance;
}
}
}
@@ -0,0 +1,32 @@
package net.minecraftforge.event.entity.player;
import java.util.List;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
public class ItemTooltipEvent extends PlayerEvent
{
/**
* Whether the advanced information on item tooltips is being shown, toggled by F3+H.
*/
public final boolean showAdvancedItemTooltips;
/**
* The {@link ItemStack} with the tooltip.
*/
public final ItemStack itemStack;
/**
* The {@link ItemStack} tooltip.
*/
public final List<String> toolTip;
/**
* This event is fired in {@link ItemStack#getTooltip(EntityPlayer, boolean)}, which in turn is called from it's respective GUIContainer.
*/
public ItemTooltipEvent(ItemStack itemStack, EntityPlayer entityPlayer, List<String> toolTip, boolean showAdvancedItemTooltips)
{
super(entityPlayer);
this.itemStack = itemStack;
this.toolTip = toolTip;
this.showAdvancedItemTooltips = showAdvancedItemTooltips;
}
}
@@ -45,4 +45,16 @@ public class PlayerEvent extends LivingEvent
this.newSpeed = original;
}
}
public static class NameFormat extends PlayerEvent
{
public final String username;
public String displayname;
public NameFormat(EntityPlayer player, String username) {
super(player);
this.username = username;
this.displayname = username;
}
}
}
@@ -0,0 +1,29 @@
package net.minecraftforge.event.entity.player;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraftforge.event.Event.HasResult;
@HasResult
public class PlayerOpenContainerEvent extends PlayerEvent
{
public final boolean canInteractWith;
/**
* This event is fired when a player attempts to view a container during
* player tick.
*
* setResult ALLOW to allow the container to stay open
* setResult DENY to force close the container (denying access)
*
* DEFAULT is vanilla behaviour
*
*/
public PlayerOpenContainerEvent(EntityPlayer player, Container openContainer)
{
super(player);
this.canInteractWith = openContainer.canInteractWith(player);
}
}
@@ -1,5 +1,6 @@
package net.minecraftforge.event.terraingen;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.world.biome.BiomeDecorator;
@@ -40,9 +41,7 @@ public class BiomeEvent extends Event
this.replacement = replacement;
}
}
@SideOnly(Side.CLIENT)
public static class BiomeColor extends BiomeEvent
{
public final int originalColor;
@@ -89,8 +88,6 @@ public class BiomeEvent extends Event
/**
* This event is fired when a biome is queried for its grass color.
*/
@SideOnly(Side.CLIENT)
public static class GetGrassColor extends BiomeColor
{
public GetGrassColor(BiomeGenBase biome, int original)
@@ -102,7 +99,6 @@ public class BiomeEvent extends Event
/**
* This event is fired when a biome is queried for its grass color.
*/
@SideOnly(Side.CLIENT)
public static class GetFoliageColor extends BiomeColor
{
public GetFoliageColor(BiomeGenBase biome, int original)
@@ -114,7 +110,6 @@ public class BiomeEvent extends Event
/**
* This event is fired when a biome is queried for its water color.
*/
@SideOnly(Side.CLIENT)
public static class GetWaterColor extends BiomeColor
{
public GetWaterColor(BiomeGenBase biome, int original)
@@ -0,0 +1,47 @@
package net.minecraftforge.event.terraingen;
import java.util.Random;
import net.minecraft.world.World;
import net.minecraft.world.biome.BiomeDecorator;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraftforge.common.MinecraftForge;
public class DeferredBiomeDecorator extends BiomeDecorator {
private BiomeDecorator wrapped;
public DeferredBiomeDecorator(BiomeGenBase biomeGenBase, BiomeDecorator wrappedOriginal)
{
super(biomeGenBase);
this.wrapped = wrappedOriginal;
}
@Override
public void decorate(World par1World, Random par2Random, int par3, int par4)
{
fireCreateEventAndReplace();
// On first call to decorate, we fire and substitute ourselves, if we haven't already done so
biome.theBiomeDecorator.decorate(par1World, par2Random, par3, par4);
}
public void fireCreateEventAndReplace()
{
// Copy any configuration from us to the real instance.
wrapped.bigMushroomsPerChunk = bigMushroomsPerChunk;
wrapped.cactiPerChunk = cactiPerChunk;
wrapped.clayPerChunk = clayPerChunk;
wrapped.deadBushPerChunk = deadBushPerChunk;
wrapped.flowersPerChunk = flowersPerChunk;
wrapped.generateLakes = generateLakes;
wrapped.grassPerChunk = grassPerChunk;
wrapped.mushroomsPerChunk = mushroomsPerChunk;
wrapped.reedsPerChunk = reedsPerChunk;
wrapped.sandPerChunk = sandPerChunk;
wrapped.sandPerChunk2 = sandPerChunk2;
wrapped.treesPerChunk = treesPerChunk;
wrapped.waterlilyPerChunk = waterlilyPerChunk;
BiomeEvent.CreateDecorator event = new BiomeEvent.CreateDecorator(biome, wrapped);
MinecraftForge.TERRAIN_GEN_BUS.post(event);
biome.theBiomeDecorator = event.newBiomeDecorator;
}
}
@@ -0,0 +1,113 @@
package net.minecraftforge.event.world;
import java.util.ArrayList;
import net.minecraft.block.Block;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.event.Cancelable;
import net.minecraftforge.event.Event;
public class BlockEvent extends Event {
public final int x;
public final int y;
public final int z;
public final World world;
public final Block block;
public final int blockMetadata;
public BlockEvent(int x, int y, int z, World world, Block block, int blockMetadata)
{
this.x = x;
this.y = y;
this.z = z;
this.world = world;
this.block = block;
this.blockMetadata = blockMetadata;
}
/**
* Fired when a block is about to drop it's harvested items. The {@link #drops} array can be amended, as can the {@link #dropChance}.
* <strong>Note well:</strong> the {@link #harvester} player field is null in a variety of scenarios. Code expecting null.
*
* The {@link #dropChance} is used to determine which items in this array will actually drop, compared to a random number. If you wish, you
* can pre-filter yourself, and set {@link #dropChance} to 1.0f to always drop the contents of the {@link #drops} array.
*
* {@link #isSilkTouching} is set if this is considered a silk touch harvesting operation, vs a normal harvesting operation. Act accordingly.
*
* @author cpw
*/
public static class HarvestDropsEvent extends BlockEvent {
public final int fortuneLevel;
public final ArrayList<ItemStack> drops;
public final boolean isSilkTouching;
public float dropChance; // Change to e.g. 1.0f, if you manipulate the list and want to guarantee it always drops
public final EntityPlayer harvester; // May be null for non-player harvesting such as explosions or machines
public HarvestDropsEvent(int x, int y, int z, World world, Block block, int blockMetadata, int fortuneLevel, float dropChance, ArrayList<ItemStack> drops, EntityPlayer harvester, boolean isSilkTouching)
{
super(x, y, z, world, block, blockMetadata);
this.fortuneLevel = fortuneLevel;
this.dropChance = dropChance;
this.drops = drops;
this.isSilkTouching = isSilkTouching;
this.harvester = harvester;
}
}
/**
* Event that is fired when an Block is about to be broken by a player
* Canceling this event will prevent the Block from being broken.
*/
@Cancelable
public static class BreakEvent extends BlockEvent
{
/** Reference to the Player who broke the block. If no player is available, use a EntityFakePlayer */
private final EntityPlayer player;
private int exp;
public BreakEvent(int x, int y, int z, World world, Block block, int blockMetadata, EntityPlayer player)
{
super(x, y, z, world, block, blockMetadata);
this.player = player;
if (block == null || !player.canHarvestBlock(block) || // Handle empty block or player unable to break block scenario
block.canSilkHarvest(world, player, x, y, z, blockMetadata) && EnchantmentHelper.getSilkTouchModifier(player)) // If the block is being silk harvested, the exp dropped is 0
{
this.exp = 0;
}
else
{
int meta = block.getDamageValue(world, x, y, z);
int bonusLevel = EnchantmentHelper.getFortuneModifier(player);
this.exp = block.getExpDrop(world, meta, bonusLevel);
}
}
public EntityPlayer getPlayer()
{
return player;
}
/**
* Get the experience dropped by the block after the event has processed
*
* @return The experience to drop or 0 if the event was canceled
*/
public int getExpToDrop()
{
return this.isCanceled() ? 0 : exp;
}
/**
* Set the amount of experience dropped by the block after the event has processed
*
* @param exp 1 or higher to drop experience, else nothing will drop
*/
public void setExpToDrop(int exp)
{
this.exp = exp;
}
}
}
@@ -0,0 +1,464 @@
package net.minecraftforge.fluids;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.Vec3;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
/**
* This is a base implementation for Fluid blocks.
*
* It is highly recommended that you extend this class or one of the Forge-provided child classes.
*
* @author King Lemming, OvermindDL1
*
*/
public abstract class BlockFluidBase extends Block implements IFluidBlock
{
protected final static Map<Integer, Boolean> defaultDisplacementIds = new HashMap<Integer, Boolean>();
static
{
defaultDisplacementIds.put(Block.doorWood.blockID, false);
defaultDisplacementIds.put(Block.doorIron.blockID, false);
defaultDisplacementIds.put(Block.signPost.blockID, false);
defaultDisplacementIds.put(Block.signWall.blockID, false);
defaultDisplacementIds.put(Block.reed.blockID, false);
}
protected Map<Integer, Boolean> displacementIds = new HashMap<Integer, Boolean>();
protected int quantaPerBlock = 8;
protected float quantaPerBlockFloat = 8F;
protected int density = 1;
protected int densityDir = -1;
protected int temperature = 295;
protected int tickRate = 20;
protected int renderPass = 1;
protected int maxScaledLight = 0;
protected final String fluidName;
public BlockFluidBase(int id, Fluid fluid, Material material)
{
super(id, material);
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
this.setTickRandomly(true);
this.disableStats();
this.fluidName = fluid.getName();
this.density = fluid.density;
this.temperature = fluid.temperature;
this.maxScaledLight = fluid.luminosity;
this.tickRate = fluid.viscosity / 200;
this.densityDir = fluid.density > 0 ? -1 : 1;
fluid.setBlockID(id);
displacementIds.putAll(defaultDisplacementIds);
}
public BlockFluidBase setQuantaPerBlock(int quantaPerBlock)
{
if (quantaPerBlock > 16 || quantaPerBlock < 1) quantaPerBlock = 8;
this.quantaPerBlock = quantaPerBlock;
this.quantaPerBlockFloat = quantaPerBlock;
return this;
}
public BlockFluidBase setDensity(int density)
{
if (density == 0) density = 1;
this.density = density;
this.densityDir = density > 0 ? -1 : 1;
return this;
}
public BlockFluidBase setTemperature(int temperature)
{
this.temperature = temperature;
return this;
}
public BlockFluidBase setTickRate(int tickRate)
{
if (tickRate <= 0) tickRate = 20;
this.tickRate = tickRate;
return this;
}
public BlockFluidBase setRenderPass(int renderPass)
{
this.renderPass = renderPass;
return this;
}
public BlockFluidBase setMaxScaledLight(int maxScaledLight)
{
this.maxScaledLight = maxScaledLight;
return this;
}
/**
* Returns true if the block at (x, y, z) is displaceable. Does not displace the block.
*/
public boolean canDisplace(IBlockAccess world, int x, int y, int z)
{
if (world.isAirBlock(x, y, z)) return true;
int bId = world.getBlockId(x, y, z);
if (bId == blockID)
{
return false;
}
if (displacementIds.containsKey(bId))
{
return displacementIds.get(bId);
}
Material material = Block.blocksList[bId].blockMaterial;
if (material.blocksMovement() || material == Material.portal)
{
return false;
}
int density = getDensity(world, x, y, z);
if (density == Integer.MAX_VALUE)
{
return true;
}
if (this.density > density)
{
return true;
}
else
{
return false;
}
}
/**
* Attempt to displace the block at (x, y, z), return true if it was displaced.
*/
public boolean displaceIfPossible(World world, int x, int y, int z)
{
if (world.isAirBlock(x, y, z))
{
return true;
}
int bId = world.getBlockId(x, y, z);
if (bId == blockID)
{
return false;
}
if (displacementIds.containsKey(bId))
{
if (displacementIds.get(bId))
{
Block.blocksList[bId].dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0);
return true;
}
return false;
}
Material material = Block.blocksList[bId].blockMaterial;
if (material.blocksMovement() || material == Material.portal)
{
return false;
}
int density = getDensity(world, x, y, z);
if (density == Integer.MAX_VALUE)
{
Block.blocksList[bId].dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0);
return true;
}
if (this.density > density)
{
return true;
}
else
{
return false;
}
}
public abstract int getQuantaValue(IBlockAccess world, int x, int y, int z);
@Override
public abstract boolean canCollideCheck(int meta, boolean fullHit);
public abstract int getMaxRenderHeightMeta();
/* BLOCK FUNCTIONS */
@Override
public void onBlockAdded(World world, int x, int y, int z)
{
world.scheduleBlockUpdate(x, y, z, blockID, tickRate);
}
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, int blockId)
{
world.scheduleBlockUpdate(x, y, z, blockID, tickRate);
}
// Used to prevent updates on chunk generation
@Override
public boolean func_82506_l()
{
return false;
}
@Override
public boolean getBlocksMovement(IBlockAccess world, int x, int y, int z)
{
return true;
}
@Override
public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z)
{
return null;
}
@Override
public int idDropped(int par1, Random par2Random, int par3)
{
return 0;
}
@Override
public int quantityDropped(Random par1Random)
{
return 0;
}
@Override
public int tickRate(World world)
{
return tickRate;
}
@Override
public void velocityToAddToEntity(World world, int x, int y, int z, Entity entity, Vec3 vec)
{
if (densityDir > 0) return;
Vec3 vec_flow = this.getFlowVector(world, x, y, z);
vec.xCoord += vec_flow.xCoord * (quantaPerBlock * 4);
vec.yCoord += vec_flow.yCoord * (quantaPerBlock * 4);
vec.zCoord += vec_flow.zCoord * (quantaPerBlock * 4);
}
@Override
public int getLightValue(IBlockAccess world, int x, int y, int z)
{
if (maxScaledLight == 0)
{
return super.getLightValue(world, x, y, z);
}
int data = world.getBlockMetadata(x, y, z);
return (int) (data / quantaPerBlockFloat * maxScaledLight);
}
@Override
public int getRenderType()
{
return FluidRegistry.renderIdFluid;
}
@Override
public boolean isOpaqueCube()
{
return false;
}
@Override
public boolean renderAsNormalBlock()
{
return false;
}
@Override
public float getBlockBrightness(IBlockAccess world, int x, int y, int z)
{
float lightThis = world.getLightBrightness(x, y, z);
float lightUp = world.getLightBrightness(x, y + 1, z);
return lightThis > lightUp ? lightThis : lightUp;
}
@Override
public int getMixedBrightnessForBlock(IBlockAccess world, int x, int y, int z)
{
int lightThis = world.getLightBrightnessForSkyBlocks(x, y, z, 0);
int lightUp = world.getLightBrightnessForSkyBlocks(x, y + 1, z, 0);
int lightThisBase = lightThis & 255;
int lightUpBase = lightUp & 255;
int lightThisExt = lightThis >> 16 & 255;
int lightUpExt = lightUp >> 16 & 255;
return (lightThisBase > lightUpBase ? lightThisBase : lightUpBase) |
((lightThisExt > lightUpExt ? lightThisExt : lightUpExt) << 16);
}
@Override
public int getRenderBlockPass()
{
return renderPass;
}
@Override
public boolean shouldSideBeRendered(IBlockAccess world, int x, int y, int z, int side)
{
if (world.getBlockId(x, y, z) != blockID)
{
return !world.isBlockOpaqueCube(x, y, z);
}
Material mat = world.getBlockMaterial(x, y, z);
return mat == this.blockMaterial ? false : super.shouldSideBeRendered(world, x, y, z, side);
}
/* FLUID FUNCTIONS */
public static final int getDensity(IBlockAccess world, int x, int y, int z)
{
Block block = Block.blocksList[world.getBlockId(x, y, z)];
if (!(block instanceof BlockFluidBase))
{
return Integer.MAX_VALUE;
}
return ((BlockFluidBase)block).density;
}
public static final int getTemperature(IBlockAccess world, int x, int y, int z)
{
Block block = Block.blocksList[world.getBlockId(x, y, z)];
if (!(block instanceof BlockFluidBase))
{
return Integer.MAX_VALUE;
}
return ((BlockFluidBase)block).temperature;
}
public static double getFlowDirection(IBlockAccess world, int x, int y, int z)
{
Block block = Block.blocksList[world.getBlockId(x, y, z)];
if (!world.getBlockMaterial(x, y, z).isLiquid())
{
return -1000.0;
}
Vec3 vec = ((BlockFluidBase) block).getFlowVector(world, x, y, z);
return vec.xCoord == 0.0D && vec.zCoord == 0.0D ? -1000.0D : Math.atan2(vec.zCoord, vec.xCoord) - Math.PI / 2D;
}
public final int getQuantaValueBelow(IBlockAccess world, int x, int y, int z, int belowThis)
{
int quantaRemaining = getQuantaValue(world, x, y, z);
if (quantaRemaining >= belowThis)
{
return -1;
}
return quantaRemaining;
}
public final int getQuantaValueAbove(IBlockAccess world, int x, int y, int z, int aboveThis)
{
int quantaRemaining = getQuantaValue(world, x, y, z);
if (quantaRemaining <= aboveThis)
{
return -1;
}
return quantaRemaining;
}
public final float getQuantaPercentage(IBlockAccess world, int x, int y, int z)
{
int quantaRemaining = getQuantaValue(world, x, y, z);
return quantaRemaining / quantaPerBlockFloat;
}
public Vec3 getFlowVector(IBlockAccess world, int x, int y, int z)
{
Vec3 vec = world.getWorldVec3Pool().getVecFromPool(0.0D, 0.0D, 0.0D);
int decay = quantaPerBlock - getQuantaValue(world, x, y, z);
for (int side = 0; side < 4; ++side)
{
int x2 = x;
int z2 = z;
switch (side)
{
case 0: --x2; break;
case 1: --z2; break;
case 2: ++x2; break;
case 3: ++z2; break;
}
int otherDecay = quantaPerBlock - getQuantaValue(world, x2, y, z2);
if (otherDecay >= quantaPerBlock)
{
if (!world.getBlockMaterial(x2, y, z2).blocksMovement())
{
otherDecay = quantaPerBlock - getQuantaValue(world, x2, y - 1, z2);
if (otherDecay >= 0)
{
int power = otherDecay - (decay - quantaPerBlock);
vec = vec.addVector((x2 - x) * power, (y - y) * power, (z2 - z) * power);
}
}
}
else if (otherDecay >= 0)
{
int power = otherDecay - decay;
vec = vec.addVector((x2 - x) * power, (y - y) * power, (z2 - z) * power);
}
}
if (world.getBlockId(x, y + 1, z) == blockID)
{
boolean flag =
isBlockSolid(world, x, y, z - 1, 2) ||
isBlockSolid(world, x, y, z + 1, 3) ||
isBlockSolid(world, x - 1, y, z, 4) ||
isBlockSolid(world, x + 1, y, z, 5) ||
isBlockSolid(world, x, y + 1, z - 1, 2) ||
isBlockSolid(world, x, y + 1, z + 1, 3) ||
isBlockSolid(world, x - 1, y + 1, z, 4) ||
isBlockSolid(world, x + 1, y + 1, z, 5);
if (flag)
{
vec = vec.normalize().addVector(0.0D, -6.0D, 0.0D);
}
}
vec = vec.normalize();
return vec;
}
/* IFluidBlock */
@Override
public Fluid getFluid()
{
return FluidRegistry.getFluid(fluidName);
}
@Override
public float getFilledPercentage(World world, int x, int y, int z)
{
int quantaRemaining = getQuantaValue(world, x, y, z) + 1;
float remaining = quantaRemaining / quantaPerBlockFloat;
if (remaining > 1) remaining = 1.0f;
return remaining * (density > 0 ? 1 : -1);
}
}
@@ -0,0 +1,354 @@
package net.minecraftforge.fluids;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
/**
* This is a fluid block implementation which emulates vanilla Minecraft fluid behavior.
*
* It is highly recommended that you use/extend this class for "classic" fluid blocks.
*
* @author King Lemming
*
*/
public class BlockFluidClassic extends BlockFluidBase
{
protected boolean[] isOptimalFlowDirection = new boolean[4];
protected int[] flowCost = new int[4];
protected FluidStack stack;
public BlockFluidClassic(int id, Fluid fluid, Material material)
{
super(id, fluid, material);
stack = new FluidStack(fluid, FluidContainerRegistry.BUCKET_VOLUME);
}
public BlockFluidClassic setFluidStack(FluidStack stack)
{
this.stack = stack;
return this;
}
public BlockFluidClassic setFluidStackAmount(int amount)
{
this.stack.amount = amount;
return this;
}
@Override
public int getQuantaValue(IBlockAccess world, int x, int y, int z)
{
if (world.getBlockId(x, y, z) == 0)
{
return 0;
}
if (world.getBlockId(x, y, z) != blockID)
{
return -1;
}
int quantaRemaining = quantaPerBlock - world.getBlockMetadata(x, y, z);
return quantaRemaining;
}
@Override
public boolean canCollideCheck(int meta, boolean fullHit)
{
return fullHit && meta == 0;
}
@Override
public int getMaxRenderHeightMeta()
{
return 0;
}
@Override
public int getLightValue(IBlockAccess world, int x, int y, int z)
{
if (maxScaledLight == 0)
{
return super.getLightValue(world, x, y, z);
}
int data = quantaPerBlock - world.getBlockMetadata(x, y, z) - 1;
return (int) (data / quantaPerBlockFloat * maxScaledLight);
}
@Override
public void updateTick(World world, int x, int y, int z, Random rand)
{
int quantaRemaining = quantaPerBlock - world.getBlockMetadata(x, y, z);
int expQuanta = -101;
// check adjacent block levels if non-source
if (quantaRemaining < quantaPerBlock)
{
int y2 = y - densityDir;
if (world.getBlockId(x, y2, z ) == blockID ||
world.getBlockId(x - 1, y2, z ) == blockID ||
world.getBlockId(x + 1, y2, z ) == blockID ||
world.getBlockId(x, y2, z - 1) == blockID ||
world.getBlockId(x, y2, z + 1) == blockID)
{
expQuanta = quantaPerBlock - 1;
}
else
{
int maxQuanta = -100;
maxQuanta = getLargerQuanta(world, x - 1, y, z, maxQuanta);
maxQuanta = getLargerQuanta(world, x + 1, y, z, maxQuanta);
maxQuanta = getLargerQuanta(world, x, y, z - 1, maxQuanta);
maxQuanta = getLargerQuanta(world, x, y, z + 1, maxQuanta);
expQuanta = maxQuanta - 1;
}
// decay calculation
if (expQuanta != quantaRemaining)
{
quantaRemaining = expQuanta;
if (expQuanta <= 0)
{
world.setBlockToAir(x, y, z);
}
else
{
world.setBlockMetadataWithNotify(x, y, z, quantaPerBlock - expQuanta, 3);
world.scheduleBlockUpdate(x, y, z, blockID, tickRate);
world.notifyBlocksOfNeighborChange(x, y, z, blockID);
}
}
}
// This is a "source" block, set meta to zero, and send a server only update
else if (quantaRemaining >= quantaPerBlock)
{
world.setBlockMetadataWithNotify(x, y, z, 0, 2);
}
// Flow vertically if possible
if (canDisplace(world, x, y + densityDir, z))
{
flowIntoBlock(world, x, y + densityDir, z, 1);
return;
}
// Flow outward if possible
int flowMeta = quantaPerBlock - quantaRemaining + 1;
if (flowMeta >= quantaPerBlock)
{
return;
}
if (isSourceBlock(world, x, y, z) || !isFlowingVertically(world, x, y, z))
{
if (world.getBlockId(x, y - densityDir, z) == blockID)
{
flowMeta = 1;
}
boolean flowTo[] = getOptimalFlowDirections(world, x, y, z);
if (flowTo[0]) flowIntoBlock(world, x - 1, y, z, flowMeta);
if (flowTo[1]) flowIntoBlock(world, x + 1, y, z, flowMeta);
if (flowTo[2]) flowIntoBlock(world, x, y, z - 1, flowMeta);
if (flowTo[3]) flowIntoBlock(world, x, y, z + 1, flowMeta);
}
}
public boolean isFlowingVertically(IBlockAccess world, int x, int y, int z)
{
return world.getBlockId(x, y + densityDir, z) == blockID ||
(world.getBlockId(x, y, z) == blockID && canFlowInto(world, x, y + densityDir, z));
}
public boolean isSourceBlock(IBlockAccess world, int x, int y, int z)
{
return world.getBlockId(x, y, z) == blockID && world.getBlockMetadata(x, y, z) == 0;
}
protected boolean[] getOptimalFlowDirections(World world, int x, int y, int z)
{
for (int side = 0; side < 4; side++)
{
flowCost[side] = 1000;
int x2 = x;
int y2 = y;
int z2 = z;
switch (side)
{
case 0: --x2; break;
case 1: ++x2; break;
case 2: --z2; break;
case 3: ++z2; break;
}
if (!canFlowInto(world, x2, y2, z2) || isSourceBlock(world, x2, y2, z2))
{
continue;
}
if (canFlowInto(world, x2, y2 + densityDir, z2))
{
flowCost[side] = 0;
}
else
{
flowCost[side] = calculateFlowCost(world, x2, y2, z2, 1, side);
}
}
int min = flowCost[0];
for (int side = 1; side < 4; side++)
{
if (flowCost[side] < min)
{
min = flowCost[side];
}
}
for (int side = 0; side < 4; side++)
{
isOptimalFlowDirection[side] = flowCost[side] == min;
}
return isOptimalFlowDirection;
}
protected int calculateFlowCost(World world, int x, int y, int z, int recurseDepth, int side)
{
int cost = 1000;
for (int adjSide = 0; adjSide < 4; adjSide++)
{
if ((adjSide == 0 && side == 1) ||
(adjSide == 1 && side == 0) ||
(adjSide == 2 && side == 3) ||
(adjSide == 3 && side == 2))
{
continue;
}
int x2 = x;
int y2 = y;
int z2 = z;
switch (adjSide)
{
case 0: --x2; break;
case 1: ++x2; break;
case 2: --z2; break;
case 3: ++z2; break;
}
if (!canFlowInto(world, x2, y2, z2) || isSourceBlock(world, x2, y2, z2))
{
continue;
}
if (canFlowInto(world, x2, y2 + densityDir, z2))
{
return recurseDepth;
}
if (recurseDepth >= 4)
{
continue;
}
int min = calculateFlowCost(world, x2, y2, z2, recurseDepth + 1, adjSide);
if (min < cost)
{
cost = min;
}
}
return cost;
}
protected void flowIntoBlock(World world, int x, int y, int z, int meta)
{
if (meta < 0) return;
if (displaceIfPossible(world, x, y, z))
{
world.setBlock(x, y, z, this.blockID, meta, 3);
}
}
protected boolean canFlowInto(IBlockAccess world, int x, int y, int z)
{
if (world.isAirBlock(x, y, z)) return true;
int bId = world.getBlockId(x, y, z);
if (bId == blockID)
{
return true;
}
if (displacementIds.containsKey(bId))
{
return displacementIds.get(bId);
}
Material material = Block.blocksList[bId].blockMaterial;
if (material.blocksMovement() ||
material == Material.water ||
material == Material.lava ||
material == Material.portal)
{
return false;
}
int density = getDensity(world, x, y, z);
if (density == Integer.MAX_VALUE)
{
return true;
}
if (this.density > density)
{
return true;
}
else
{
return false;
}
}
protected int getLargerQuanta(IBlockAccess world, int x, int y, int z, int compare)
{
int quantaRemaining = getQuantaValue(world, x, y, z);
if (quantaRemaining <= 0)
{
return compare;
}
return quantaRemaining >= compare ? quantaRemaining : compare;
}
/* IFluidBlock */
@Override
public FluidStack drain(World world, int x, int y, int z, boolean doDrain)
{
if (!isSourceBlock(world, x, y, z))
{
return null;
}
if (doDrain)
{
world.setBlockToAir(x, y, z);
}
return stack.copy();
}
@Override
public boolean canDrain(World world, int x, int y, int z)
{
return isSourceBlock(world, x, y, z);
}
}
@@ -0,0 +1,323 @@
package net.minecraftforge.fluids;
import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
/**
* This is a cellular-automata based finite fluid block implementation.
*
* It is highly recommended that you use/extend this class for finite fluid blocks.
*
* @author OvermindDL1, KingLemming
*
*/
public class BlockFluidFinite extends BlockFluidBase
{
public BlockFluidFinite(int id, Fluid fluid, Material material)
{
super(id, fluid, material);
}
@Override
public int getQuantaValue(IBlockAccess world, int x, int y, int z)
{
if (world.isAirBlock(x, y, z))
{
return 0;
}
if (world.getBlockId(x, y, z) != blockID)
{
return -1;
}
int quantaRemaining = world.getBlockMetadata(x, y, z) + 1;
return quantaRemaining;
}
@Override
public boolean canCollideCheck(int meta, boolean fullHit)
{
return fullHit && meta == quantaPerBlock - 1;
}
@Override
public int getMaxRenderHeightMeta()
{
return quantaPerBlock - 1;
}
@Override
public void updateTick(World world, int x, int y, int z, Random rand)
{
boolean changed = false;
int quantaRemaining = world.getBlockMetadata(x, y, z) + 1;
// Flow vertically if possible
int prevRemaining = quantaRemaining;
quantaRemaining = tryToFlowVerticallyInto(world, x, y, z, quantaRemaining);
if (quantaRemaining < 1)
{
return;
}
else if (quantaRemaining != prevRemaining)
{
changed = true;
if (quantaRemaining == 1)
{
world.setBlockMetadataWithNotify(x, y, z, quantaRemaining - 1, 2);
return;
}
}
else if (quantaRemaining == 1)
{
return;
}
// Flow out if possible
int lowerthan = quantaRemaining - 1;
if (displaceIfPossible(world, x, y, z - 1)) world.setBlock(x, y, z - 1, 0);
if (displaceIfPossible(world, x, y, z + 1)) world.setBlock(x, y, z + 1, 0);
if (displaceIfPossible(world, x - 1, y, z )) world.setBlock(x - 1, y, z, 0);
if (displaceIfPossible(world, x + 1, y, z )) world.setBlock(x + 1, y, z, 0);
int north = getQuantaValueBelow(world, x, y, z - 1, lowerthan);
int south = getQuantaValueBelow(world, x, y, z + 1, lowerthan);
int west = getQuantaValueBelow(world, x - 1, y, z, lowerthan);
int east = getQuantaValueBelow(world, x + 1, y, z, lowerthan);
int total = quantaRemaining;
int count = 1;
if (north >= 0)
{
count++;
total += north;
}
if (south >= 0)
{
count++;
total += south;
}
if (west >= 0)
{
count++;
total += west;
}
if (east >= 0)
{
++count;
total += east;
}
if (count == 1)
{
if (changed)
{
world.setBlockMetadataWithNotify(x, y, z, quantaRemaining - 1, 2);
}
return;
}
int each = total / count;
int rem = total % count;
if (north >= 0)
{
int newnorth = each;
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
{
++newnorth;
--rem;
}
if (newnorth != north)
{
if (newnorth == 0)
{
world.setBlock(x, y, z - 1, 0);
}
else
{
world.setBlock(x, y, z - 1, blockID, newnorth - 1, 2);
}
world.scheduleBlockUpdate(x, y, z - 1, blockID, tickRate);
}
--count;
}
if (south >= 0)
{
int newsouth = each;
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
{
++newsouth;
--rem;
}
if (newsouth != south)
{
if (newsouth == 0)
{
world.setBlock(x, y, z + 1, 0);
}
else
{
world.setBlock(x, y, z + 1, blockID, newsouth - 1, 2);
}
world.scheduleBlockUpdate(x, y, z + 1, blockID, tickRate);
}
--count;
}
if (west >= 0)
{
int newwest = each;
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
{
++newwest;
--rem;
}
if (newwest != west)
{
if (newwest == 0)
{
world.setBlock(x - 1, y, z, 0);
}
else
{
world.setBlock(x - 1, y, z, blockID, newwest - 1, 2);
}
world.scheduleBlockUpdate(x - 1, y, z, blockID, tickRate);
}
--count;
}
if (east >= 0)
{
int neweast = each;
if (rem == count || rem > 1 && rand.nextInt(count - rem) != 0)
{
++neweast;
--rem;
}
if (neweast != east)
{
if (neweast == 0)
{
world.setBlock(x + 1, y, z, 0);
}
else
{
world.setBlock(x + 1, y, z, blockID, neweast - 1, 2);
}
world.scheduleBlockUpdate(x + 1, y, z, blockID, tickRate);
}
--count;
}
if (rem > 0)
{
++each;
}
world.setBlockMetadataWithNotify(x, y, z, each - 1, 2);
}
public int tryToFlowVerticallyInto(World world, int x, int y, int z, int amtToInput)
{
int otherY = y + densityDir;
if (otherY < 0 || otherY >= world.getHeight())
{
world.setBlockToAir(x, y, z);
return 0;
}
int amt = getQuantaValueBelow(world, x, otherY, z, quantaPerBlock);
if (amt >= 0)
{
amt += amtToInput;
if (amt > quantaPerBlock)
{
world.setBlock(x, otherY, z, blockID, quantaPerBlock - 1, 3);
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
return amt - quantaPerBlock;
}
else if (amt > 0)
{
world.setBlock(x, otherY, z, blockID, amt - 1, 3);
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
world.setBlockToAir(x, y, z);
return 0;
}
return amtToInput;
}
else
{
int density_other = getDensity(world, x, otherY, z);
if (density_other == Integer.MAX_VALUE)
{
if (displaceIfPossible(world, x, otherY, z))
{
world.setBlock(x, otherY, z, blockID, amtToInput - 1, 3);
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
world.setBlockToAir(x, y, z);
return 0;
}
else
{
return amtToInput;
}
}
if (densityDir < 0)
{
if (density_other < density) // then swap
{
int bId = world.getBlockId(x, otherY, z);
BlockFluidBase block = (BlockFluidBase) Block.blocksList[bId];
int otherData = world.getBlockMetadata(x, otherY, z);
world.setBlock(x, otherY, z, blockID, amtToInput - 1, 3);
world.setBlock(x, y, z, bId, otherData, 3);
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
world.scheduleBlockUpdate(x, y, z, bId, block.tickRate(world));
return 0;
}
}
else
{
if (density_other > density)
{
int bId = world.getBlockId(x, otherY, z);
BlockFluidBase block = (BlockFluidBase) Block.blocksList[bId];
int otherData = world.getBlockMetadata(x, otherY, z);
world.setBlock(x, otherY, z, blockID, amtToInput - 1, 3);
world.setBlock(x, y, z, bId, otherData, 3);
world.scheduleBlockUpdate(x, otherY, z, blockID, tickRate);
world.scheduleBlockUpdate(x, y, z, bId, block.tickRate(world));
return 0;
}
}
return amtToInput;
}
}
/* IFluidBlock */
@Override
public FluidStack drain(World world, int x, int y, int z, boolean doDrain)
{
return null;
}
@Override
public boolean canDrain(World world, int x, int y, int z)
{
return false;
}
}
+324
View File
@@ -0,0 +1,324 @@
package net.minecraftforge.fluids;
import java.util.Locale;
import java.util.Map;
import com.google.common.collect.Maps;
import net.minecraft.block.Block;
import net.minecraft.util.Icon;
import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDummyContainer;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.LoaderException;
import net.minecraft.item.EnumRarity;
/**
* Minecraft Forge Fluid Implementation
*
* This class is a fluid (liquid or gas) equivalent to "Item." It describes the nature of a fluid
* and contains its general properties.
*
* These properties do not have inherent gameplay mechanics - they are provided so that mods may
* choose to take advantage of them.
*
* Fluid implementations are not required to actively use these properties, nor are objects
* interfacing with fluids required to make use of them, but it is encouraged.
*
* The default values can be used as a reference point for mods adding fluids such as oil or heavy
* water.
*
* @author King Lemming
*
*/
public class Fluid
{
/** The unique identification name for this fluid. */
protected final String fluidName;
/** The unlocalized name of this fluid. */
protected String unlocalizedName;
/** The Icons for this fluid. */
protected Icon stillIcon;
protected Icon flowingIcon;
/**
* The light level emitted by this fluid.
*
* Default value is 0, as most fluids do not actively emit light.
*/
protected int luminosity = 0;
/**
* Density of the fluid - completely arbitrary; negative density indicates that the fluid is
* lighter than air.
*
* Default value is approximately the real-life density of water in kg/m^3.
*/
protected int density = 1000;
/**
* Temperature of the fluid - completely arbitrary; higher temperature indicates that the fluid is
* hotter than air.
*
* Default value is approximately the real-life room temperature of water in degrees Kelvin.
*/
protected int temperature = 295;
/**
* Viscosity ("thickness") of the fluid - completely arbitrary; negative values are not
* permissible.
*
* Default value is approximately the real-life density of water in m/s^2 (x10^-3).
*/
protected int viscosity = 1000;
/**
* This indicates if the fluid is gaseous.
*
* Useful for rendering the fluid in containers and the world.
*
* Generally this is associated with negative density fluids.
*/
protected boolean isGaseous;
/**
* The rarity of the fluid.
*
* Used primarily in tool tips.
*/
protected EnumRarity rarity = EnumRarity.common;
/**
* If there is a Block implementation of the Fluid, the BlockID is linked here.
*
* The default value of -1 should remain for any Fluid without a Block implementation.
*/
protected int blockID = -1;
public Fluid(String fluidName)
{
this.fluidName = fluidName.toLowerCase(Locale.ENGLISH);
this.unlocalizedName = fluidName;
}
public Fluid setUnlocalizedName(String unlocalizedName)
{
this.unlocalizedName = unlocalizedName;
return this;
}
public Fluid setBlockID(int blockID)
{
if (this.blockID == -1 || this.blockID == blockID)
{
this.blockID = blockID;
}
else if (!ForgeDummyContainer.forceDuplicateFluidBlockCrash)
{
FMLLog.warning("A mod has attempted to assign BlockID " + blockID + " to the Fluid '" + fluidName + "' but this Fluid has already been linked to BlockID "
+ this.blockID + ". Configure your mods to prevent this from happening.");
}
else
{
FMLLog.severe("A mod has attempted to assign BlockID " + blockID + " to the Fluid '" + fluidName + "' but this Fluid has already been linked to BlockID "
+ this.blockID + ". Configure your mods to prevent this from happening.");
throw new LoaderException(new RuntimeException("A mod has attempted to assign BlockID " + blockID + " to the Fluid '" + fluidName
+ "' but this Fluid has already been linked to BlockID " + this.blockID + ". Configure your mods to prevent this from happening."));
}
return this;
}
public Fluid setBlockID(Block block)
{
return setBlockID(block.blockID);
}
public Fluid setLuminosity(int luminosity)
{
this.luminosity = luminosity;
return this;
}
public Fluid setDensity(int density)
{
this.density = density;
return this;
}
public Fluid setTemperature(int temperature)
{
this.temperature = temperature;
return this;
}
public Fluid setViscosity(int viscosity)
{
this.viscosity = viscosity;
return this;
}
public Fluid setGaseous(boolean isGaseous)
{
this.isGaseous = isGaseous;
return this;
}
public Fluid setRarity(EnumRarity rarity)
{
this.rarity = rarity;
return this;
}
public final String getName()
{
return this.fluidName;
}
public final int getID()
{
return FluidRegistry.getFluidID(this.fluidName);
}
public final int getBlockID()
{
return blockID;
}
public final boolean canBePlacedInWorld()
{
return blockID != -1;
}
/**
* Returns the localized name of this fluid.
*/
public String getLocalizedName()
{
String s = this.getUnlocalizedName();
return s == null ? "" : StatCollector.translateToLocal(s);
}
/**
* Returns the unlocalized name of this fluid.
*/
public String getUnlocalizedName()
{
return "fluid." + this.unlocalizedName;
}
/**
* Returns 0 for "/terrain.png". ALL FLUID TEXTURES MUST BE ON THIS SHEET.
*/
public final int getSpriteNumber()
{
return 0;
}
/* Default Accessors */
public final int getLuminosity()
{
return this.luminosity;
}
public final int getDensity()
{
return this.density;
}
public final int getTemperature()
{
return this.temperature;
}
public final int getViscosity()
{
return this.viscosity;
}
public final boolean isGaseous()
{
return this.isGaseous;
}
public EnumRarity getRarity()
{
return rarity;
}
public int getColor()
{
return 0xFFFFFF;
}
public final Fluid setStillIcon(Icon stillIcon)
{
this.stillIcon = stillIcon;
return this;
}
public final Fluid setFlowingIcon(Icon flowingIcon)
{
this.flowingIcon = flowingIcon;
return this;
}
public final Fluid setIcons(Icon stillIcon, Icon flowingIcon)
{
return this.setStillIcon(stillIcon).setFlowingIcon(flowingIcon);
}
public final Fluid setIcons(Icon commonIcon)
{
return this.setStillIcon(commonIcon).setFlowingIcon(commonIcon);
}
public Icon getIcon(){ return getStillIcon(); }
public Icon getStillIcon()
{
return this.stillIcon;
}
public Icon getFlowingIcon()
{
return this.flowingIcon;
}
/* Stack-based Accessors */
public int getLuminosity(FluidStack stack){ return getLuminosity(); }
public int getDensity(FluidStack stack){ return getDensity(); }
public int getTemperature(FluidStack stack){ return getTemperature(); }
public int getViscosity(FluidStack stack){ return getViscosity(); }
public boolean isGaseous(FluidStack stack){ return isGaseous(); }
public EnumRarity getRarity(FluidStack stack){ return getRarity(); }
public int getColor(FluidStack stack){ return getColor(); }
public Icon getIcon(FluidStack stack){ return getIcon(); }
/* World-based Accessors */
public int getLuminosity(World world, int x, int y, int z){ return getLuminosity(); }
public int getDensity(World world, int x, int y, int z){ return getDensity(); }
public int getTemperature(World world, int x, int y, int z){ return getTemperature(); }
public int getViscosity(World world, int x, int y, int z){ return getViscosity(); }
public boolean isGaseous(World world, int x, int y, int z){ return isGaseous(); }
public EnumRarity getRarity(World world, int x, int y, int z){ return getRarity(); }
public int getColor(World world, int x, int y, int z){ return getColor(); }
public Icon getIcon(World world, int x, int y, int z){ return getIcon(); }
private static Map<String, String> legacyNames = Maps.newHashMap();
static String convertLegacyName(String fluidName)
{
return fluidName != null && legacyNames.containsKey(fluidName) ? legacyNames.get(fluidName) : fluidName;
}
/**
* Register a legacy liquid name with the Fluids system
* @param legacyName The legacy name to recognize
* @param canonicalName The canonical fluid name it will become
*/
public static void registerLegacyName(String legacyName, String canonicalName)
{
legacyNames.put(legacyName.toLowerCase(Locale.ENGLISH), canonicalName);
}
}
@@ -0,0 +1,278 @@
package net.minecraftforge.fluids;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.Event;
/**
* Register simple items that contain fluids here. Useful for buckets, bottles, and things that have
* ID/metadata mappings.
*
* For more complex items, use {@link IFluidContainerItem} instead.
*
* @author King Lemming
*
*/
public abstract class FluidContainerRegistry
{
private static Map<List, FluidContainerData> containerFluidMap = new HashMap();
private static Map<List, FluidContainerData> filledContainerMap = new HashMap();
private static Set<List> emptyContainers = new HashSet();
public static final int BUCKET_VOLUME = 1000;
public static final ItemStack EMPTY_BUCKET = new ItemStack(Item.bucketEmpty);
public static final ItemStack EMPTY_BOTTLE = new ItemStack(Item.glassBottle);
private static final ItemStack NULL_EMPTYCONTAINER = new ItemStack(Item.bucketEmpty);
static
{
registerFluidContainer(FluidRegistry.WATER, new ItemStack(Item.bucketWater), EMPTY_BUCKET);
registerFluidContainer(FluidRegistry.LAVA, new ItemStack(Item.bucketLava), EMPTY_BUCKET);
registerFluidContainer(FluidRegistry.WATER, new ItemStack(Item.potion), EMPTY_BOTTLE);
}
private FluidContainerRegistry(){}
/**
* Register a new fluid containing item.
*
* @param stack
* FluidStack containing the type and amount of the fluid stored in the item.
* @param filledContainer
* ItemStack representing the container when it is full.
* @param emptyContainer
* ItemStack representing the container when it is empty.
* @return True if container was successfully registered; false if it already is.
*/
public static boolean registerFluidContainer(FluidStack stack, ItemStack filledContainer, ItemStack emptyContainer)
{
return registerFluidContainer(new FluidContainerData(stack, filledContainer, emptyContainer));
}
/**
* Register a new fluid containing item. The item is assumed to hold 1000 mB of fluid. Also
* registers the Fluid if possible.
*
* @param fluid
* Fluid type that is stored in the item.
* @param filledContainer
* ItemStack representing the container when it is full.
* @param emptyContainer
* ItemStack representing the container when it is empty.
* @return True if container was successfully registered; false if it already is.
*/
public static boolean registerFluidContainer(Fluid fluid, ItemStack filledContainer, ItemStack emptyContainer)
{
if (!FluidRegistry.isFluidRegistered(fluid))
{
FluidRegistry.registerFluid(fluid);
}
return registerFluidContainer(new FluidStack(fluid, BUCKET_VOLUME), filledContainer, emptyContainer);
}
/**
* Register a new fluid containing item that does not have an empty container.
*
* @param stack
* FluidStack containing the type and amount of the fluid stored in the item.
* @param filledContainer
* ItemStack representing the container when it is full.
* @return True if container was successfully registered; false if it already is.
*/
public static boolean registerFluidContainer(FluidStack stack, ItemStack filledContainer)
{
return registerFluidContainer(new FluidContainerData(stack, filledContainer, null, true));
}
/**
* Register a new fluid containing item that does not have an empty container. The item is
* assumed to hold 1000 mB of fluid. Also registers the Fluid if possible.
*
* @param fluid
* Fluid type that is stored in the item.
* @param filledContainer
* ItemStack representing the container when it is full.
* @return True if container was successfully registered; false if it already is.
*/
public static boolean registerFluidContainer(Fluid fluid, ItemStack filledContainer)
{
if (!FluidRegistry.isFluidRegistered(fluid))
{
FluidRegistry.registerFluid(fluid);
}
return registerFluidContainer(new FluidStack(fluid, BUCKET_VOLUME), filledContainer);
}
/**
* Register a new fluid containing item.
*
* @param data
* See {@link FluidContainerData}.
* @return True if container was successfully registered; false if it already is.
*/
public static boolean registerFluidContainer(FluidContainerData data)
{
if (isFilledContainer(data.filledContainer))
{
return false;
}
containerFluidMap.put(Arrays.asList(data.filledContainer.itemID, data.filledContainer.getItemDamage()), data);
if (data.emptyContainer != null && data.emptyContainer != NULL_EMPTYCONTAINER)
{
filledContainerMap.put(Arrays.asList(data.emptyContainer.itemID, data.emptyContainer.getItemDamage(), data.fluid.fluidID), data);
emptyContainers.add(Arrays.asList(data.emptyContainer.itemID, data.emptyContainer.getItemDamage()));
}
MinecraftForge.EVENT_BUS.post(new FluidContainerRegisterEvent(data));
return true;
}
/**
* Determines the fluid type and amount inside a container.
*
* @param container
* The fluid container.
* @return FluidStack representing stored fluid.
*/
public static FluidStack getFluidForFilledItem(ItemStack container)
{
if (container == null)
{
return null;
}
FluidContainerData data = containerFluidMap.get(Arrays.asList(container.itemID, container.getItemDamage()));
return data == null ? null : data.fluid.copy();
}
/**
* Attempts to fill an empty container with a fluid.
*
* NOTE: Returns null on fail, NOT the empty container.
*
* @param fluid
* FluidStack containing the type and amount of fluid to fill.
* @param container
* ItemStack representing the empty container.
* @return Filled container if successful, otherwise null.
*/
public static ItemStack fillFluidContainer(FluidStack fluid, ItemStack container)
{
if (container == null || fluid == null)
{
return null;
}
FluidContainerData data = filledContainerMap.get(Arrays.asList(container.itemID, container.getItemDamage(), fluid.fluidID));
if (data != null && fluid.amount >= data.fluid.amount)
{
return data.filledContainer.copy();
}
return null;
}
/**
* Determines if a container holds a specific fluid.
*/
public static boolean containsFluid(ItemStack container, FluidStack fluid)
{
if (container == null || fluid == null)
{
return false;
}
FluidContainerData data = filledContainerMap.get(Arrays.asList(container.itemID, container.getItemDamage(), fluid.fluidID));
return data == null ? false : data.fluid.isFluidEqual(fluid);
}
public static boolean isBucket(ItemStack container)
{
if (container == null)
{
return false;
}
if (container.isItemEqual(EMPTY_BUCKET))
{
return true;
}
FluidContainerData data = containerFluidMap.get(Arrays.asList(container.itemID, container.getItemDamage()));
return data != null && data.emptyContainer.isItemEqual(EMPTY_BUCKET);
}
public static boolean isContainer(ItemStack container)
{
return isEmptyContainer(container) || isFilledContainer(container);
}
public static boolean isEmptyContainer(ItemStack container)
{
return container != null && emptyContainers.contains(Arrays.asList(container.itemID, container.getItemDamage()));
}
public static boolean isFilledContainer(ItemStack container)
{
return container != null && getFluidForFilledItem(container) != null;
}
public static FluidContainerData[] getRegisteredFluidContainerData()
{
return containerFluidMap.values().toArray(new FluidContainerData[containerFluidMap.size()]);
}
/**
* Wrapper class for the registry entries. Ensures that none of the attempted registrations
* contain null references unless permitted.
*/
public static class FluidContainerData
{
public final FluidStack fluid;
public final ItemStack filledContainer;
public final ItemStack emptyContainer;
public FluidContainerData(FluidStack stack, ItemStack filledContainer, ItemStack emptyContainer)
{
this(stack, filledContainer, emptyContainer, false);
}
public FluidContainerData(FluidStack stack, ItemStack filledContainer, ItemStack emptyContainer, boolean nullEmpty)
{
this.fluid = stack;
this.filledContainer = filledContainer;
this.emptyContainer = emptyContainer == null ? NULL_EMPTYCONTAINER : emptyContainer;
if (stack == null || filledContainer == null || emptyContainer == null && !nullEmpty)
{
throw new RuntimeException("Invalid FluidContainerData - a parameter was null.");
}
}
public FluidContainerData copy()
{
return new FluidContainerData(fluid, filledContainer, emptyContainer, true);
}
}
public static class FluidContainerRegisterEvent extends Event
{
public final FluidContainerData data;
public FluidContainerRegisterEvent(FluidContainerData data)
{
this.data = data.copy();
}
}
}
@@ -0,0 +1,97 @@
package net.minecraftforge.fluids;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.Event;
public class FluidEvent extends Event
{
public final FluidStack fluid;
public final int x;
public final int y;
public final int z;
public final World world;
public FluidEvent(FluidStack fluid, World world, int x, int y, int z)
{
this.fluid = fluid;
this.world = world;
this.x = x;
this.y = y;
this.z = z;
}
/**
* Mods should fire this event when they move fluids around.
*
* @author cpw
*
*/
public static class FluidMotionEvent extends FluidEvent
{
public FluidMotionEvent(FluidStack fluid, World world, int x, int y, int z)
{
super(fluid, world, x, y, z);
}
}
/**
* Mods should fire this event when a fluid is {@link IFluidTank#fill(FluidStack, boolean)}
* their tank implementation. {@link FluidTank} does.
*
* @author cpw
*
*/
public static class FluidFillingEvent extends FluidEvent
{
public final IFluidTank tank;
public FluidFillingEvent(FluidStack fluid, World world, int x, int y, int z, IFluidTank tank)
{
super(fluid, world, x, y, z);
this.tank = tank;
}
}
/**
* Mods should fire this event when a fluid is {@link IFluidTank#drain(int, boolean)} from their
* tank.
*
* @author cpw
*
*/
public static class FluidDrainingEvent extends FluidEvent
{
public final IFluidTank tank;
public FluidDrainingEvent(FluidStack fluid, World world, int x, int y, int z, IFluidTank tank)
{
super(fluid, world, x, y, z);
this.tank = tank;
}
}
/**
* Mods should fire this event when a fluid "spills", for example, if a block containing fluid
* is broken.
*
* @author cpw
*
*/
public static class FluidSpilledEvent extends FluidEvent
{
public FluidSpilledEvent(FluidStack fluid, World world, int x, int y, int z)
{
super(fluid, world, x, y, z);
}
}
/**
* A handy shortcut for firing the various fluid events.
*
* @param event
*/
public static final void fireEvent(FluidEvent event)
{
MinecraftForge.EVENT_BUS.post(event);
}
}
@@ -0,0 +1,52 @@
package net.minecraftforge.fluids;
import java.util.Map;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.INetworkManager;
import net.minecraftforge.common.network.ForgePacket;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
public class FluidIdMapPacket extends ForgePacket
{
private BiMap<String, Integer> fluidIds = HashBiMap.create();
@Override
public byte[] generatePacket()
{
ByteArrayDataOutput dat = ByteStreams.newDataOutput();
dat.writeInt(FluidRegistry.maxID);
for (Map.Entry<String, Integer> entry : FluidRegistry.fluidIDs.entrySet())
{
dat.writeUTF(entry.getKey());
dat.writeInt(entry.getValue());
}
return dat.toByteArray();
}
@Override
public ForgePacket consumePacket(byte[] data)
{
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
int listSize = dat.readInt();
for (int i = 0; i < listSize; i++) {
String fluidName = dat.readUTF();
int fluidId = dat.readInt();
fluidIds.put(fluidName, fluidId);
}
return this;
}
@Override
public void execute(INetworkManager network, EntityPlayer player)
{
FluidRegistry.initFluidIDs(fluidIds);
}
}
@@ -0,0 +1,170 @@
package net.minecraftforge.fluids;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.block.Block;
import net.minecraft.util.StatCollector;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.Event;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableMap;
/**
* Handles Fluid registrations. Fluids MUST be registered in order to function.
*
* @author King Lemming, CovertJaguar (LiquidDictionary)
*
*/
public abstract class FluidRegistry
{
static int maxID = 0;
static HashMap<String, Fluid> fluids = new HashMap();
static BiMap<String, Integer> fluidIDs = HashBiMap.create();
static BiMap<Block, Fluid> fluidBlocks;
public static final Fluid WATER = new Fluid("water") {
@Override
public String getLocalizedName() {
return StatCollector.translateToLocal("tile.water.name");
}
}.setBlockID(Block.waterStill.blockID).setUnlocalizedName(Block.waterStill.getUnlocalizedName());
public static final Fluid LAVA = new Fluid("lava") {
@Override
public String getLocalizedName() {
return StatCollector.translateToLocal("tile.lava.name");
}
}.setBlockID(Block.lavaStill.blockID).setLuminosity(15).setDensity(3000).setViscosity(6000).setTemperature(1300).setUnlocalizedName(Block.lavaStill.getUnlocalizedName());
public static int renderIdFluid = -1;
static
{
registerFluid(WATER);
registerFluid(LAVA);
}
private FluidRegistry(){}
/**
* Called by Forge to prepare the ID map for server -> client sync.
*/
static void initFluidIDs(BiMap<String, Integer> newfluidIDs)
{
maxID = newfluidIDs.size();
fluidIDs.clear();
fluidIDs.putAll(newfluidIDs);
}
/**
* Register a new Fluid. If a fluid with the same name already exists, registration is denied.
*
* @param fluid
* The fluid to register.
* @return True if the fluid was successfully registered; false if there is a name clash.
*/
public static boolean registerFluid(Fluid fluid)
{
if (fluidIDs.containsKey(fluid.getName()))
{
return false;
}
fluids.put(fluid.getName(), fluid);
fluidIDs.put(fluid.getName(), ++maxID);
MinecraftForge.EVENT_BUS.post(new FluidRegisterEvent(fluid.getName(), maxID));
return true;
}
public static boolean isFluidRegistered(Fluid fluid)
{
return fluidIDs.containsKey(fluid.getName());
}
public static boolean isFluidRegistered(String fluidName)
{
return fluidIDs.containsKey(fluidName);
}
public static Fluid getFluid(String fluidName)
{
return fluids.get(fluidName);
}
public static Fluid getFluid(int fluidID)
{
return fluids.get(getFluidName(fluidID));
}
public static String getFluidName(int fluidID)
{
return fluidIDs.inverse().get(fluidID);
}
public static String getFluidName(FluidStack stack)
{
return getFluidName(stack.fluidID);
}
public static int getFluidID(String fluidName)
{
return fluidIDs.get(fluidName);
}
public static FluidStack getFluidStack(String fluidName, int amount)
{
if (!fluidIDs.containsKey(fluidName))
{
return null;
}
return new FluidStack(getFluidID(fluidName), amount);
}
/**
* Returns a read-only map containing Fluid Names and their associated Fluids.
*/
public static Map<String, Fluid> getRegisteredFluids()
{
return ImmutableMap.copyOf(fluids);
}
/**
* Returns a read-only map containing Fluid Names and their associated IDs.
*/
public static Map<String, Integer> getRegisteredFluidIDs()
{
return ImmutableMap.copyOf(fluidIDs);
}
public static Fluid lookupFluidForBlock(Block block)
{
if (fluidBlocks == null)
{
fluidBlocks = HashBiMap.create();
for (Fluid fluid : fluids.values())
{
if (fluid.canBePlacedInWorld() && Block.blocksList[fluid.getBlockID()] != null)
{
fluidBlocks.put(Block.blocksList[fluid.getBlockID()], fluid);
}
}
}
return fluidBlocks.get(block);
}
public static class FluidRegisterEvent extends Event
{
public final String fluidName;
public final int fluidID;
public FluidRegisterEvent(String fluidName, int fluidID)
{
this.fluidName = fluidName;
this.fluidID = fluidID;
}
}
}
@@ -0,0 +1,203 @@
package net.minecraftforge.fluids;
import java.util.Locale;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
/**
* ItemStack substitute for Fluids.
*
* NOTE: Equality is based on the Fluid, not the amount. Use
* {@link #isFluidStackIdentical(FluidStack)} to determine if FluidID, Amount and NBT Tag are all
* equal.
*
* @author King Lemming, SirSengir (LiquidStack)
*
*/
public class FluidStack
{
public int fluidID;
public int amount;
public NBTTagCompound tag;
public FluidStack(Fluid fluid, int amount)
{
this.fluidID = fluid.getID();
this.amount = amount;
}
public FluidStack(int fluidID, int amount)
{
this.fluidID = fluidID;
this.amount = amount;
}
public FluidStack(int fluidID, int amount, NBTTagCompound nbt)
{
this(fluidID, amount);
if (nbt != null)
{
tag = (NBTTagCompound) nbt.copy();
}
}
public FluidStack(FluidStack stack, int amount)
{
this(stack.fluidID, amount, stack.tag);
}
/**
* This provides a safe method for retrieving a FluidStack - if the Fluid is invalid, the stack
* will return as null.
*/
public static FluidStack loadFluidStackFromNBT(NBTTagCompound nbt)
{
if (nbt == null)
{
return null;
}
String fluidName = nbt.getString("FluidName");
if (fluidName == null)
{
fluidName = nbt.hasKey("LiquidName") ? nbt.getString("LiquidName").toLowerCase(Locale.ENGLISH) : null;
fluidName = Fluid.convertLegacyName(fluidName);
}
if (fluidName ==null || FluidRegistry.getFluid(fluidName) == null)
{
return null;
}
FluidStack stack = new FluidStack(FluidRegistry.getFluidID(fluidName), nbt.getInteger("Amount"));
if (nbt.hasKey("Tag"))
{
stack.tag = nbt.getCompoundTag("Tag");
}
else if (nbt.hasKey("extra"))
{
stack.tag = nbt.getCompoundTag("extra");
}
return stack;
}
public NBTTagCompound writeToNBT(NBTTagCompound nbt)
{
nbt.setString("FluidName", FluidRegistry.getFluidName(fluidID));
nbt.setInteger("Amount", amount);
if (tag != null)
{
nbt.setTag("Tag", tag);
}
return nbt;
}
public final Fluid getFluid()
{
return FluidRegistry.getFluid(fluidID);
}
/**
* @return A copy of this FluidStack
*/
public FluidStack copy()
{
return new FluidStack(fluidID, amount, tag);
}
/**
* Determines if the FluidIDs and NBT Tags are equal. This does not check amounts.
*
* @param other
* The FluidStack for comparison
* @return true if the Fluids (IDs and NBT Tags) are the same
*/
public boolean isFluidEqual(FluidStack other)
{
return other != null && fluidID == other.fluidID && isFluidStackTagEqual(other);
}
private boolean isFluidStackTagEqual(FluidStack other)
{
return tag == null ? other.tag == null : other.tag == null ? false : tag.equals(other.tag);
}
/**
* Determines if the NBT Tags are equal. Useful if the FluidIDs are known to be equal.
*/
public static boolean areFluidStackTagsEqual(FluidStack stack1, FluidStack stack2)
{
return stack1 == null && stack2 == null ? true : stack1 == null || stack2 == null ? false : stack1.isFluidStackTagEqual(stack2);
}
/**
* Determines if the Fluids are equal and this stack is larger.
*
* @param other
* @return true if this FluidStack contains the other FluidStack (same fluid and >= amount)
*/
public boolean containsFluid(FluidStack other)
{
return isFluidEqual(other) && amount >= other.amount;
}
/**
* Determines if the FluidIDs, Amounts, and NBT Tags are all equal.
*
* @param other
* - the FluidStack for comparison
* @return true if the two FluidStacks are exactly the same
*/
public boolean isFluidStackIdentical(FluidStack other)
{
return isFluidEqual(other) && amount == other.amount;
}
/**
* Determines if the FluidIDs and NBT Tags are equal compared to a registered container
* ItemStack. This does not check amounts.
*
* @param other
* The ItemStack for comparison
* @return true if the Fluids (IDs and NBT Tags) are the same
*/
public boolean isFluidEqual(ItemStack other)
{
if (other == null)
{
return false;
}
if (other.getItem() instanceof IFluidContainerItem)
{
return isFluidEqual(((IFluidContainerItem) other.getItem()).getFluid(other));
}
return isFluidEqual(FluidContainerRegistry.getFluidForFilledItem(other));
}
@Override
public final int hashCode()
{
return fluidID;
}
/**
* Default equality comparison for a FluidStack. Same functionality as isFluidEqual().
*
* This is included for use in data structures.
*/
@Override
public final boolean equals(Object o)
{
if (!(o instanceof FluidStack))
{
return false;
}
return isFluidEqual((FluidStack) o);
}
}
@@ -0,0 +1,188 @@
package net.minecraftforge.fluids;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
/**
* Reference implementation of {@link IFluidTank}. Use/extend this or implement your own.
*
* @author King Lemming, cpw (LiquidTank)
*
*/
public class FluidTank implements IFluidTank
{
protected FluidStack fluid;
protected int capacity;
protected TileEntity tile;
public FluidTank(int capacity)
{
this(null, capacity);
}
public FluidTank(FluidStack stack, int capacity)
{
this.fluid = stack;
this.capacity = capacity;
}
public FluidTank(Fluid fluid, int amount, int capacity)
{
this(new FluidStack(fluid, amount), capacity);
}
public FluidTank readFromNBT(NBTTagCompound nbt)
{
if (!nbt.hasKey("Empty"))
{
FluidStack fluid = FluidStack.loadFluidStackFromNBT(nbt);
if (fluid != null)
{
setFluid(fluid);
}
}
return this;
}
public NBTTagCompound writeToNBT(NBTTagCompound nbt)
{
if (fluid != null)
{
fluid.writeToNBT(nbt);
}
else
{
nbt.setString("Empty", "");
}
return nbt;
}
public void setFluid(FluidStack fluid)
{
this.fluid = fluid;
}
public void setCapacity(int capacity)
{
this.capacity = capacity;
}
/* IFluidTank */
@Override
public FluidStack getFluid()
{
return fluid;
}
@Override
public int getFluidAmount()
{
if (fluid == null)
{
return 0;
}
return fluid.amount;
}
@Override
public int getCapacity()
{
return capacity;
}
@Override
public FluidTankInfo getInfo()
{
return new FluidTankInfo(this);
}
@Override
public int fill(FluidStack resource, boolean doFill)
{
if (resource == null)
{
return 0;
}
if (!doFill)
{
if (fluid == null)
{
return Math.min(capacity, resource.amount);
}
if (!fluid.isFluidEqual(resource))
{
return 0;
}
return Math.min(capacity - fluid.amount, resource.amount);
}
if (fluid == null)
{
fluid = new FluidStack(resource, Math.min(capacity, resource.amount));
if (tile != null)
{
FluidEvent.fireEvent(new FluidEvent.FluidFillingEvent(fluid, tile.worldObj, tile.xCoord, tile.yCoord, tile.zCoord, this));
}
return fluid.amount;
}
if (!fluid.isFluidEqual(resource))
{
return 0;
}
int filled = capacity - fluid.amount;
if (resource.amount < filled)
{
fluid.amount += resource.amount;
filled = resource.amount;
}
else
{
fluid.amount = capacity;
}
if (tile != null)
{
FluidEvent.fireEvent(new FluidEvent.FluidFillingEvent(fluid, tile.worldObj, tile.xCoord, tile.yCoord, tile.zCoord, this));
}
return filled;
}
@Override
public FluidStack drain(int maxDrain, boolean doDrain)
{
if (fluid == null)
{
return null;
}
int drained = maxDrain;
if (fluid.amount < drained)
{
drained = fluid.amount;
}
FluidStack stack = new FluidStack(fluid, drained);
if (doDrain)
{
fluid.amount -= drained;
if (fluid.amount <= 0)
{
fluid = null;
}
if (tile != null)
{
FluidEvent.fireEvent(new FluidEvent.FluidDrainingEvent(fluid, tile.worldObj, tile.xCoord, tile.yCoord, tile.zCoord, this));
}
}
return stack;
}
}
@@ -0,0 +1,25 @@
package net.minecraftforge.fluids;
/**
* Wrapper class used to encapsulate information about an IFluidTank.
*
* @author King Lemming
*
*/
public final class FluidTankInfo
{
public final FluidStack fluid;
public final int capacity;
public FluidTankInfo(FluidStack fluid, int capacity)
{
this.fluid = fluid;
this.capacity = capacity;
}
public FluidTankInfo(IFluidTank tank)
{
this.fluid = tank.getFluid();
this.capacity = tank.getCapacity();
}
}
@@ -0,0 +1,51 @@
package net.minecraftforge.fluids;
import net.minecraft.world.World;
/**
* Implement this interface on Block classes which represent world-placeable Fluids.
*
* NOTE: Using/extending the reference implementations {@link BlockFluidBase} is encouraged.
*
* @author King Lemming
*
*/
public interface IFluidBlock
{
/**
* Returns the Fluid associated with this Block.
*/
Fluid getFluid();
/**
* Attempt to drain the block. This method should be called by devices such as pumps.
*
* NOTE: The block is intended to handle its own state changes.
*
* @param doDrain
* If false, the drain will only be simulated.
* @return
*/
FluidStack drain(World world, int x, int y, int z, boolean doDrain);
/**
* Check to see if a block can be drained. This method should be called by devices such as
* pumps.
*
* @param doDrain
* If false, the drain will only be simulated.
* @return
*/
boolean canDrain(World world, int x, int y, int z);
/**
* Returns the amount of a single block is filled. Value between 0 and 1.
* 1 meaning the entire 1x1x1 cube is full, 0 meaning completely empty.
*
* If the return value is negative. It will be treated as filling the block
* from the top down instead of bottom up.
*
* @return
*/
float getFilledPercentage(World world, int x, int y, int z);
}
@@ -0,0 +1,59 @@
package net.minecraftforge.fluids;
import net.minecraft.item.ItemStack;
/**
* Implement this interface on Item classes that support external manipulation of their internal
* fluid storage.
*
* A reference implementation is provided {@link ItemFluidContainer}.
*
* NOTE: Use of NBT data on the containing ItemStack is encouraged.
*
* @author King Lemming
*
*/
public interface IFluidContainerItem
{
/**
*
* @param container
* ItemStack which is the fluid container.
* @return FluidStack representing the fluid in the container, null if the container is empty.
*/
FluidStack getFluid(ItemStack container);
/**
*
* @param container
* ItemStack which is the fluid container.
* @return Capacity of this fluid container.
*/
int getCapacity(ItemStack container);
/**
*
* @param container
* ItemStack which is the fluid container.
* @param resource
* FluidStack attempting to fill the container.
* @param doFill
* If false, the fill will only be simulated.
* @return Amount of fluid that was (or would have been, if simulated) filled into the
* container.
*/
int fill(ItemStack container, FluidStack resource, boolean doFill);
/**
*
* @param container
* ItemStack which is the fluid container.
* @param maxDrain
* Maximum amount of fluid to be removed from the container.
* @param doFill
* If false, the drain will only be simulated.
* @return Amount of fluid that was (or would have been, if simulated) drained from the
* container.
*/
FluidStack drain(ItemStack container, int maxDrain, boolean doDrain);
}
@@ -0,0 +1,82 @@
package net.minecraftforge.fluids;
import net.minecraftforge.common.ForgeDirection;
/**
* Implement this interface on TileEntities which should handle fluids, generally storing them in
* one or more internal {@link IFluidTank} objects.
*
* A reference implementation is provided {@link TileFluidHandler}.
*
* @author King Lemming
*
*/
public interface IFluidHandler
{
/**
* Fills fluid into internal tanks, distribution is left entirely to the IFluidHandler.
*
* @param from
* Orientation the Fluid is pumped in from.
* @param resource
* FluidStack representing the Fluid and maximum amount of fluid to be filled.
* @param doFill
* If false, fill will only be simulated.
* @return Amount of resource that was (or would have been, if simulated) filled.
*/
int fill(ForgeDirection from, FluidStack resource, boolean doFill);
/**
* Drains fluid out of internal tanks, distribution is left entirely to the IFluidHandler.
*
* @param from
* Orientation the Fluid is drained to.
* @param resource
* FluidStack representing the Fluid and maximum amount of fluid to be drained.
* @param doDrain
* If false, drain will only be simulated.
* @return FluidStack representing the Fluid and amount that was (or would have been, if
* simulated) drained.
*/
FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain);
/**
* Drains fluid out of internal tanks, distribution is left entirely to the IFluidHandler.
*
* This method is not Fluid-sensitive.
*
* @param from
* Orientation the fluid is drained to.
* @param maxDrain
* Maximum amount of fluid to drain.
* @param doDrain
* If false, drain will only be simulated.
* @return FluidStack representing the Fluid and amount that was (or would have been, if
* simulated) drained.
*/
FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain);
/**
* Returns true if the given fluid can be inserted into the given direction.
*
* More formally, this should return true if fluid is able to enter from the given direction.
*/
boolean canFill(ForgeDirection from, Fluid fluid);
/**
* Returns true if the given fluid can be extracted from the given direction.
*
* More formally, this should return true if fluid is able to leave from the given direction.
*/
boolean canDrain(ForgeDirection from, Fluid fluid);
/**
* Returns an array of objects which represent the internal tanks. These objects cannot be used
* to manipulate the internal tanks. See {@link FluidTankInfo}.
*
* @param from
* Orientation determining which tanks should be queried.
* @return Info for the relevant internal tanks.
*/
FluidTankInfo[] getTankInfo(ForgeDirection from);
}
@@ -0,0 +1,57 @@
package net.minecraftforge.fluids;
/**
* A tank is the unit of interaction with Fluid inventories.
*
* A reference implementation can be found at {@link FluidTank}.
*
* @author King Lemming, cpw (ILiquidTank)
*
*/
public interface IFluidTank
{
/**
* @return FluidStack representing the fluid in the tank, null if the tank is empty.
*/
FluidStack getFluid();
/**
* @return Current amount of fluid in the tank.
*/
int getFluidAmount();
/**
* @return Capacity of this fluid tank.
*/
int getCapacity();
/**
* Returns a wrapper object {@link FluidTankInfo } containing the capacity of the tank and the
* FluidStack it holds.
*
* Should prevent manipulation of the IFluidTank. See {@link FluidTank}.
*
* @return State information for the IFluidTank.
*/
FluidTankInfo getInfo();
/**
*
* @param resource
* FluidStack attempting to fill the tank.
* @param doFill
* If false, the fill will only be simulated.
* @return Amount of fluid that was accepted by the tank.
*/
int fill(FluidStack resource, boolean doFill);
/**
*
* @param maxDrain
* Maximum amount of fluid to be removed from the container.
* @param doFill
* If false, the fill will only be simulated.
* @return Amount of fluid that was removed from the tank.
*/
FluidStack drain(int maxDrain, boolean doDrain);
}
@@ -0,0 +1,159 @@
package net.minecraftforge.fluids;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
/**
* Reference implementation of {@link IFluidContainerItem}. Use/extend this or implement your own.
*
* @author King Lemming
*
*/
public class ItemFluidContainer extends Item implements IFluidContainerItem
{
protected int capacity;
public ItemFluidContainer(int itemID)
{
super(itemID);
}
public ItemFluidContainer(int itemID, int capacity)
{
super(itemID);
this.capacity = capacity;
}
public ItemFluidContainer setCapacity(int capacity)
{
this.capacity = capacity;
return this;
}
/* IFluidContainerItem */
@Override
public FluidStack getFluid(ItemStack container)
{
if (container.stackTagCompound == null || !container.stackTagCompound.hasKey("Fluid"))
{
return null;
}
return FluidStack.loadFluidStackFromNBT(container.stackTagCompound.getCompoundTag("Fluid"));
}
@Override
public int getCapacity(ItemStack container)
{
return capacity;
}
@Override
public int fill(ItemStack container, FluidStack resource, boolean doFill)
{
if (resource == null)
{
return 0;
}
if (!doFill)
{
if (container.stackTagCompound == null || !container.stackTagCompound.hasKey("Fluid"))
{
return Math.min(capacity, resource.amount);
}
FluidStack stack = FluidStack.loadFluidStackFromNBT(container.stackTagCompound.getCompoundTag("Fluid"));
if (stack == null)
{
return Math.min(capacity, resource.amount);
}
if (!stack.isFluidEqual(resource))
{
return 0;
}
return Math.min(capacity - stack.amount, resource.amount);
}
if (container.stackTagCompound == null)
{
container.stackTagCompound = new NBTTagCompound();
}
if (!container.stackTagCompound.hasKey("Fluid"))
{
NBTTagCompound fluidTag = resource.writeToNBT(new NBTTagCompound());
if (capacity < resource.amount)
{
fluidTag.setInteger("Amount", capacity);
container.stackTagCompound.setTag("Fluid", fluidTag);
return capacity;
}
container.stackTagCompound.setTag("Fluid", fluidTag);
return resource.amount;
}
NBTTagCompound fluidTag = container.stackTagCompound.getCompoundTag("Fluid");
FluidStack stack = FluidStack.loadFluidStackFromNBT(fluidTag);
if (!stack.isFluidEqual(resource))
{
return 0;
}
int filled = capacity - stack.amount;
if (resource.amount < filled)
{
stack.amount += resource.amount;
filled = resource.amount;
}
else
{
stack.amount = capacity;
}
container.stackTagCompound.setTag("Fluid", stack.writeToNBT(fluidTag));
return filled;
}
@Override
public FluidStack drain(ItemStack container, int maxDrain, boolean doDrain)
{
if (container.stackTagCompound == null || !container.stackTagCompound.hasKey("Fluid") || maxDrain == 0)
{
return null;
}
FluidStack stack = FluidStack.loadFluidStackFromNBT(container.stackTagCompound.getCompoundTag("Fluid"));
if (stack == null)
{
return null;
}
int drained = Math.min(stack.amount, maxDrain);
if (doDrain)
{
if (maxDrain >= stack.amount)
{
container.stackTagCompound.removeTag("Fluid");
if (container.stackTagCompound.hasNoTags())
{
container.stackTagCompound = null;
}
return stack;
}
NBTTagCompound fluidTag = container.stackTagCompound.getCompoundTag("Fluid");
fluidTag.setInteger("Amount", fluidTag.getInteger("Amount") - maxDrain);
container.stackTagCompound.setTag("Fluid", fluidTag);
}
stack.amount = drained;
return stack;
}
}
@@ -0,0 +1,327 @@
package net.minecraftforge.fluids;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.Icon;
import net.minecraft.util.MathHelper;
import net.minecraft.world.IBlockAccess;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
/**
* Default renderer for Forge fluid blocks.
*
* @author King Lemming
*
*/
public class RenderBlockFluid implements ISimpleBlockRenderingHandler
{
public static RenderBlockFluid instance = new RenderBlockFluid();
static final float LIGHT_Y_NEG = 0.5F;
static final float LIGHT_Y_POS = 1.0F;
static final float LIGHT_XZ_NEG = 0.8F;
static final float LIGHT_XZ_POS = 0.6F;
static final double RENDER_OFFSET = 0.0010000000474974513D;
public float getFluidHeightAverage(float[] flow)
{
float total = 0;
int count = 0;
float end = 0;
for (int i = 0; i < flow.length; i++)
{
if (flow[i] >= 0.875F && end != 1F)
{
end = flow[i];
}
if (flow[i] >= 0)
{
total += flow[i];
count++;
}
}
if (end == 0)
end = total / count;
return end;
}
public float getFluidHeightForRender(IBlockAccess world, int x, int y, int z, BlockFluidBase block)
{
if (world.getBlockId(x, y, z) == block.blockID)
{
if (world.getBlockMaterial(x, y - block.densityDir, z).isLiquid())
{
return 1;
}
if (world.getBlockMetadata(x, y, z) == block.getMaxRenderHeightMeta())
{
return 0.875F;
}
}
return !world.getBlockMaterial(x, y, z).isSolid() && world.getBlockId(x, y - block.densityDir, z) == block.blockID ? 1 : block.getQuantaPercentage(world, x, y, z) * 0.875F;
}
/* ISimpleBlockRenderingHandler */
@Override
public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer){}
@Override
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer)
{
if (!(block instanceof BlockFluidBase))
{
return false;
}
Tessellator tessellator = Tessellator.instance;
int color = block.colorMultiplier(world, x, y, z);
float red = (color >> 16 & 255) / 255.0F;
float green = (color >> 8 & 255) / 255.0F;
float blue = (color & 255) / 255.0F;
BlockFluidBase theFluid = (BlockFluidBase) block;
int bMeta = world.getBlockMetadata(x, y, z);
boolean renderTop = world.getBlockId(x, y - theFluid.densityDir, z) != theFluid.blockID;
boolean renderBottom = block.shouldSideBeRendered(world, x, y + theFluid.densityDir, z, 0) && world.getBlockId(x, y + theFluid.densityDir, z) != theFluid.blockID;
boolean[] renderSides = new boolean[]
{
block.shouldSideBeRendered(world, x, y, z - 1, 2),
block.shouldSideBeRendered(world, x, y, z + 1, 3),
block.shouldSideBeRendered(world, x - 1, y, z, 4),
block.shouldSideBeRendered(world, x + 1, y, z, 5)
};
if (!renderTop && !renderBottom && !renderSides[0] && !renderSides[1] && !renderSides[2] && !renderSides[3])
{
return false;
}
else
{
boolean rendered = false;
double heightNW, heightSW, heightSE, heightNE;
float flow11 = getFluidHeightForRender(world, x, y, z, theFluid);
if (flow11 != 1)
{
float flow00 = getFluidHeightForRender(world, x - 1, y, z - 1, theFluid);
float flow01 = getFluidHeightForRender(world, x - 1, y, z, theFluid);
float flow02 = getFluidHeightForRender(world, x - 1, y, z + 1, theFluid);
float flow10 = getFluidHeightForRender(world, x, y, z - 1, theFluid);
float flow12 = getFluidHeightForRender(world, x, y, z + 1, theFluid);
float flow20 = getFluidHeightForRender(world, x + 1, y, z - 1, theFluid);
float flow21 = getFluidHeightForRender(world, x + 1, y, z, theFluid);
float flow22 = getFluidHeightForRender(world, x + 1, y, z + 1, theFluid);
heightNW = getFluidHeightAverage(new float[]{ flow00, flow01, flow10, flow11 });
heightSW = getFluidHeightAverage(new float[]{ flow01, flow02, flow12, flow11 });
heightSE = getFluidHeightAverage(new float[]{ flow12, flow21, flow22, flow11 });
heightNE = getFluidHeightAverage(new float[]{ flow10, flow20, flow21, flow11 });
}
else
{
heightNW = flow11;
heightSW = flow11;
heightSE = flow11;
heightNE = flow11;
}
boolean rises = theFluid.densityDir == 1;
if (renderer.renderAllFaces || renderTop)
{
rendered = true;
Icon iconStill = block.getIcon(1, bMeta);
float flowDir = (float) BlockFluidBase.getFlowDirection(world, x, y, z);
if (flowDir > -999.0F)
{
iconStill = block.getIcon(2, bMeta);
}
heightNW -= RENDER_OFFSET;
heightSW -= RENDER_OFFSET;
heightSE -= RENDER_OFFSET;
heightNE -= RENDER_OFFSET;
double u1, u2, u3, u4, v1, v2, v3, v4;
if (flowDir < -999.0F)
{
u2 = iconStill.getInterpolatedU(0.0D);
v2 = iconStill.getInterpolatedV(0.0D);
u1 = u2;
v1 = iconStill.getInterpolatedV(16.0D);
u4 = iconStill.getInterpolatedU(16.0D);
v4 = v1;
u3 = u4;
v3 = v2;
}
else
{
float xFlow = MathHelper.sin(flowDir) * 0.25F;
float zFlow = MathHelper.cos(flowDir) * 0.25F;
u2 = iconStill.getInterpolatedU(8.0F + (-zFlow - xFlow) * 16.0F);
v2 = iconStill.getInterpolatedV(8.0F + (-zFlow + xFlow) * 16.0F);
u1 = iconStill.getInterpolatedU(8.0F + (-zFlow + xFlow) * 16.0F);
v1 = iconStill.getInterpolatedV(8.0F + (zFlow + xFlow) * 16.0F);
u4 = iconStill.getInterpolatedU(8.0F + (zFlow + xFlow) * 16.0F);
v4 = iconStill.getInterpolatedV(8.0F + (zFlow - xFlow) * 16.0F);
u3 = iconStill.getInterpolatedU(8.0F + (zFlow - xFlow) * 16.0F);
v3 = iconStill.getInterpolatedV(8.0F + (-zFlow - xFlow) * 16.0F);
}
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x, y, z));
tessellator.setColorOpaque_F(LIGHT_Y_POS * red, LIGHT_Y_POS * green, LIGHT_Y_POS * blue);
if (!rises)
{
tessellator.addVertexWithUV(x + 0, y + heightNW, z + 0, u2, v2);
tessellator.addVertexWithUV(x + 0, y + heightSW, z + 1, u1, v1);
tessellator.addVertexWithUV(x + 1, y + heightSE, z + 1, u4, v4);
tessellator.addVertexWithUV(x + 1, y + heightNE, z + 0, u3, v3);
}
else
{
tessellator.addVertexWithUV(x + 1, y + 1 - heightNE, z + 0, u3, v3);
tessellator.addVertexWithUV(x + 1, y + 1 - heightSE, z + 1, u4, v4);
tessellator.addVertexWithUV(x + 0, y + 1 - heightSW, z + 1, u1, v1);
tessellator.addVertexWithUV(x + 0, y + 1 - heightNW, z + 0, u2, v2);
}
}
if (renderer.renderAllFaces || renderBottom)
{
rendered = true;
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x, y - 1, z));
if (!rises)
{
tessellator.setColorOpaque_F(LIGHT_Y_NEG * red, LIGHT_Y_NEG * green, LIGHT_Y_NEG * blue);
renderer.renderFaceYNeg(block, x, y + RENDER_OFFSET, z, block.getIcon(0, bMeta));
}
else
{
tessellator.setColorOpaque_F(LIGHT_Y_POS * red, LIGHT_Y_POS * green, LIGHT_Y_POS * blue);
renderer.renderFaceYPos(block, x, y + RENDER_OFFSET, z, block.getIcon(1, bMeta));
}
}
for (int side = 0; side < 4; ++side)
{
int x2 = x;
int z2 = z;
switch (side)
{
case 0: --z2; break;
case 1: ++z2; break;
case 2: --x2; break;
case 3: ++x2; break;
}
Icon iconFlow = block.getIcon(side + 2, bMeta);
if (renderer.renderAllFaces || renderSides[side])
{
rendered = true;
double ty1;
double tx1;
double ty2;
double tx2;
double tz1;
double tz2;
if (side == 0)
{
ty1 = heightNW;
ty2 = heightNE;
tx1 = x;
tx2 = x + 1;
tz1 = z + RENDER_OFFSET;
tz2 = z + RENDER_OFFSET;
}
else if (side == 1)
{
ty1 = heightSE;
ty2 = heightSW;
tx1 = x + 1;
tx2 = x;
tz1 = z + 1 - RENDER_OFFSET;
tz2 = z + 1 - RENDER_OFFSET;
}
else if (side == 2)
{
ty1 = heightSW;
ty2 = heightNW;
tx1 = x + RENDER_OFFSET;
tx2 = x + RENDER_OFFSET;
tz1 = z + 1;
tz2 = z;
}
else
{
ty1 = heightNE;
ty2 = heightSE;
tx1 = x + 1 - RENDER_OFFSET;
tx2 = x + 1 - RENDER_OFFSET;
tz1 = z;
tz2 = z + 1;
}
float u1Flow = iconFlow.getInterpolatedU(0.0D);
float u2Flow = iconFlow.getInterpolatedU(8.0D);
float v1Flow = iconFlow.getInterpolatedV((1.0D - ty1) * 16.0D * 0.5D);
float v2Flow = iconFlow.getInterpolatedV((1.0D - ty2) * 16.0D * 0.5D);
float v3Flow = iconFlow.getInterpolatedV(8.0D);
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x2, y, z2));
float sideLighting = 1.0F;
if (side < 2)
{
sideLighting = LIGHT_XZ_NEG;
}
else
{
sideLighting = LIGHT_XZ_POS;
}
tessellator.setColorOpaque_F(LIGHT_Y_POS * sideLighting * red, LIGHT_Y_POS * sideLighting * green, LIGHT_Y_POS * sideLighting * blue);
if (!rises)
{
tessellator.addVertexWithUV(tx1, y + ty1, tz1, u1Flow, v1Flow);
tessellator.addVertexWithUV(tx2, y + ty2, tz2, u2Flow, v2Flow);
tessellator.addVertexWithUV(tx2, y + 0, tz2, u2Flow, v3Flow);
tessellator.addVertexWithUV(tx1, y + 0, tz1, u1Flow, v3Flow);
}
else
{
tessellator.addVertexWithUV(tx1, y + 1 - 0, tz1, u1Flow, v3Flow);
tessellator.addVertexWithUV(tx2, y + 1 - 0, tz2, u2Flow, v3Flow);
tessellator.addVertexWithUV(tx2, y + 1 - ty2, tz2, u2Flow, v2Flow);
tessellator.addVertexWithUV(tx1, y + 1 - ty1, tz1, u1Flow, v1Flow);
}
}
}
renderer.renderMinY = 0;
renderer.renderMaxY = 1;
return rendered;
}
}
@Override
public boolean shouldRender3DInInventory(){ return false; }
@Override
public int getRenderId()
{
return FluidRegistry.renderIdFluid;
}
}
@@ -0,0 +1,72 @@
package net.minecraftforge.fluids;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.ForgeDirection;
/**
* Reference Tile Entity implementation of {@link IFluidHandler}. Use/extend this or write your own.
*
* @author King Lemming
*
*/
public class TileFluidHandler extends TileEntity implements IFluidHandler
{
protected FluidTank tank = new FluidTank(FluidContainerRegistry.BUCKET_VOLUME);
@Override
public void readFromNBT(NBTTagCompound tag)
{
super.readFromNBT(tag);
tank.writeToNBT(tag);
}
@Override
public void writeToNBT(NBTTagCompound tag)
{
super.writeToNBT(tag);
tank.readFromNBT(tag);
}
/* IFluidHandler */
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
{
return tank.fill(resource, doFill);
}
@Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
{
if (resource == null || !resource.isFluidEqual(tank.getFluid()))
{
return null;
}
return tank.drain(resource.amount, doDrain);
}
@Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
{
return tank.drain(maxDrain, doDrain);
}
@Override
public boolean canFill(ForgeDirection from, Fluid fluid)
{
return true;
}
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid)
{
return true;
}
@Override
public FluidTankInfo[] getTankInfo(ForgeDirection from)
{
return new FluidTankInfo[] { tank.getInfo() };
}
}
@@ -8,6 +8,7 @@ import net.minecraft.nbt.NBTTagCompound;
* @author cpw
*
*/
@Deprecated //See new net.minecraftforge.fluids
public interface IBlockLiquid extends ILiquid {
/**
* Controls the type of block that is generated by this IBlockLiquid
@@ -13,6 +13,7 @@ package net.minecraftforge.liquids;
* Liquids implement this interface
*
*/
@Deprecated //See new net.minecraftforge.fluids
public interface ILiquid {
/**
@@ -5,6 +5,7 @@ package net.minecraftforge.liquids;
*
* @author cpw
*/
@Deprecated //See new net.minecraftforge.fluids
public interface ILiquidTank {
/**
@@ -1,7 +1,7 @@
package net.minecraftforge.liquids;
import net.minecraftforge.common.ForgeDirection;
@Deprecated //See new net.minecraftforge.fluids
public interface ITankContainer {
/**
@@ -11,7 +11,7 @@ package net.minecraftforge.liquids;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@Deprecated //See new net.minecraftforge.fluids
public class LiquidContainerData {
public final LiquidStack stillLiquid;
@@ -12,7 +12,7 @@ import java.util.Set;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@Deprecated //See new net.minecraftforge.fluids
public class LiquidContainerRegistry
{
public static final int BUCKET_VOLUME = 1000;
@@ -16,6 +16,7 @@ import com.google.common.collect.ImmutableMap;
*
* @author CovertJaguar <railcraft.wikispaces.com>
*/
@Deprecated //See new net.minecraftforge.fluids
public abstract class LiquidDictionary
{
@@ -4,7 +4,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.Event;
@Deprecated //See new net.minecraftforge.fluids
public class LiquidEvent extends Event {
public final LiquidStack liquid;
public final int x;
@@ -22,6 +22,7 @@ import net.minecraft.util.Icon;
*
* @author SirSengir
*/
@Deprecated //See new net.minecraftforge.fluids
public class LiquidStack
{
public final int itemID;
@@ -202,11 +203,11 @@ public class LiquidStack
{
if (itemID == Block.waterStill.blockID)
{
return BlockFluid.func_94424_b("water");
return BlockFluid.getFluidIcon("water");
}
else if (itemID == Block.lavaStill.blockID)
{
return BlockFluid.func_94424_b("lava");
return BlockFluid.getFluidIcon("lava");
}
return renderingIcon;
}
@@ -6,6 +6,7 @@ import net.minecraft.tileentity.TileEntity;
/**
* Reference implementation of ILiquidTank. Use this or implement your own.
*/
@Deprecated //See new net.minecraftforge.fluids
public class LiquidTank implements ILiquidTank {
private LiquidStack liquid;
private int capacity;
@@ -49,19 +49,38 @@ public class OreDictionary
registerOre("stickWood", Item.stick);
registerOre("treeSapling", new ItemStack(Block.sapling, 1, WILDCARD_VALUE));
registerOre("treeLeaves", new ItemStack(Block.leaves, 1, WILDCARD_VALUE));
registerOre("oreGold", Block.oreGold);
registerOre("oreIron", Block.oreIron);
registerOre("oreLapis", Block.oreLapis);
registerOre("oreDiamond", Block.oreDiamond);
registerOre("oreGold", Block.oreGold);
registerOre("oreIron", Block.oreIron);
registerOre("oreLapis", Block.oreLapis);
registerOre("oreDiamond", Block.oreDiamond);
registerOre("oreRedstone", Block.oreRedstone);
registerOre("oreEmerald", Block.oreEmerald);
registerOre("oreQuartz", Block.oreNetherQuartz);
registerOre("oreEmerald", Block.oreEmerald);
registerOre("oreQuartz", Block.oreNetherQuartz);
registerOre("stone", Block.stone);
registerOre("cobblestone", Block.cobblestone);
registerOre("record", Item.record13);
registerOre("record", Item.recordCat);
registerOre("record", Item.recordBlocks);
registerOre("record", Item.recordChirp);
registerOre("record", Item.recordFar);
registerOre("record", Item.recordMall);
registerOre("record", Item.recordMellohi);
registerOre("record", Item.recordStal);
registerOre("record", Item.recordStrad);
registerOre("record", Item.recordWard);
registerOre("record", Item.record11);
registerOre("record", Item.recordWait);
}
// Build our list of items to replace with ore tags
Map<ItemStack, String> replacements = new HashMap<ItemStack, String>();
replacements.put(new ItemStack(Block.planks, 1, WILDCARD_VALUE), "plankWood");
replacements.put(new ItemStack(Item.stick), "stickWood");
replacements.put(new ItemStack(Block.planks), "plankWood");
replacements.put(new ItemStack(Block.planks, 1, WILDCARD_VALUE), "plankWood");
replacements.put(new ItemStack(Block.stone), "stone");
replacements.put(new ItemStack(Block.stone, 1, WILDCARD_VALUE), "stone");
replacements.put(new ItemStack(Block.cobblestone), "cobblestone");
replacements.put(new ItemStack(Block.cobblestone, 1, WILDCARD_VALUE), "cobblestone");
// Register dyes
String[] dyes =
@@ -102,6 +121,14 @@ public class OreDictionary
{
new ItemStack(Block.blockLapis),
new ItemStack(Item.cookie),
new ItemStack(Block.stoneBrick),
new ItemStack(Block.stoneSingleSlab),
new ItemStack(Block.stairsCobblestone),
new ItemStack(Block.cobblestoneWall),
new ItemStack(Block.stairsWoodOak),
new ItemStack(Block.stairsWoodBirch),
new ItemStack(Block.stairsWoodJungle),
new ItemStack(Block.stairsWoodSpruce)
};
List recipes = CraftingManager.getInstance().getRecipeList();
@@ -0,0 +1,276 @@
package net.minecraftforge.oredict;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.toposort.TopologicalSort;
import cpw.mods.fml.common.toposort.TopologicalSort.DirectedGraph;
import cpw.mods.fml.common.versioning.ArtifactVersion;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.RecipeFireworks;
import net.minecraft.item.crafting.RecipesArmorDyes;
import net.minecraft.item.crafting.RecipesMapCloning;
import net.minecraft.item.crafting.RecipesMapExtending;
import net.minecraft.item.crafting.ShapedRecipes;
import net.minecraft.item.crafting.ShapelessRecipes;
import static net.minecraftforge.oredict.RecipeSorter.Category.*;
public class RecipeSorter implements Comparator<IRecipe>
{
public enum Category
{
UNKNOWN,
SHAPELESS,
SHAPED
};
private static class SortEntry
{
private String name;
private Class cls;
private Category cat;
List<String> before = Lists.newArrayList();
List<String> after = Lists.newArrayList();
private SortEntry(String name, Class cls, Category cat, String deps)
{
this.name = name;
this.cls = cls;
this.cat = cat;
parseDepends(deps);
}
private void parseDepends(String deps)
{
if (deps.isEmpty()) return;
for (String dep : deps.split(" "))
{
if (dep.startsWith("before:"))
{
before.add(dep.substring(7));
}
else if (dep.startsWith("after:"))
{
after.add(dep.substring(6));
}
else
{
throw new IllegalArgumentException("Invalid dependancy: " + dep);
}
}
}
@Override
public String toString()
{
StringBuilder buf = new StringBuilder();
buf.append("RecipeEntry(\"").append(name).append("\", ");
buf.append(cat.name()).append(", ");
buf.append(cls == null ? "" : cls.getName()).append(")");
if (before.size() > 0)
{
buf.append(" Before: ").append(Joiner.on(", ").join(before));
}
if (after.size() > 0)
{
buf.append(" After: ").append(Joiner.on(", ").join(after));
}
return buf.toString();
}
@Override
public int hashCode()
{
return name.hashCode();
}
};
private static Map<Class, Category> categories = Maps.newHashMap();
private static Map<String, Class> types = Maps.newHashMap();
private static Map<String, SortEntry> entries = Maps.newHashMap();
private static Map<Class, Integer> priorities = Maps.newHashMap();
public static RecipeSorter INSTANCE = new RecipeSorter();
private static boolean isDirty = true;
private static SortEntry before = new SortEntry("Before", null, UNKNOWN, "");
private static SortEntry after = new SortEntry("After", null, UNKNOWN, "");
private RecipeSorter()
{
register("minecraft:shaped", ShapedRecipes.class, SHAPED, "before:minecraft:shapeless");
register("minecraft:mapextending", RecipesMapExtending.class, SHAPED, "after:minecraft:shaped before:minecraft:shapeless");
register("minecraft:shapeless", ShapelessRecipes.class, SHAPELESS, "after:minecraft:shaped");
register("minecraft:fireworks", RecipeFireworks.class, SHAPELESS, "after:minecraft:shapeless");
register("minecraft:armordyes", RecipesArmorDyes.class, SHAPELESS, "after:minecraft:shapeless");
register("minecraft:mapcloning", RecipesMapCloning.class, SHAPELESS, "after:minecraft:shapeless");
register("forge:shapedore", ShapedOreRecipe.class, SHAPED, "after:minecraft:shaped before:minecraft:shapeless");
register("forge:shapelessore", ShapelessOreRecipe.class, SHAPELESS, "after:minecraft:shapeless");
}
@Override
public int compare(IRecipe r1, IRecipe r2)
{
Category c1 = getCategory(r1);
Category c2 = getCategory(r2);
if (c1 == SHAPELESS && c2 == SHAPED) return 1;
if (c1 == SHAPED && c2 == SHAPELESS) return -1;
if (r2.getRecipeSize() < r1.getRecipeSize()) return -1;
if (r2.getRecipeSize() > r1.getRecipeSize()) return 1;
return getPriority(r2) - getPriority(r1); // high priority value first!
}
private static Set<Class> warned = Sets.newHashSet();
public static void sortCraftManager()
{
bake();
FMLLog.fine("Sorting recipies");
warned.clear();
Collections.sort(CraftingManager.getInstance().getRecipeList(), INSTANCE);
}
public static void register(String name, Class recipe, Category category, String dependancies)
{
assert(category != UNKNOWN) : "Category must not be unknown!";
isDirty = true;
SortEntry entry = new SortEntry(name, recipe, category, dependancies);
entries.put(name, entry);
setCategory(recipe, category);
}
public static void setCategory(Class recipe, Category category)
{
assert(category != UNKNOWN) : "Category must not be unknown!";
categories.put(recipe, category);
}
public static Category getCategory(IRecipe recipe)
{
return getCategory(recipe.getClass());
}
public static Category getCategory(Class recipe)
{
Class cls = recipe;
Category ret = categories.get(cls);
if (ret == null)
{
cls = cls.getSuperclass();
while (cls != Object.class)
{
ret = categories.get(cls);
if (ret != null)
{
categories.put(recipe, ret);
return ret;
}
}
}
return ret == null ? UNKNOWN : ret;
}
private static int getPriority(IRecipe recipe)
{
Class cls = recipe.getClass();
Integer ret = priorities.get(cls);
if (ret == null)
{
if (!INSTANCE.warned.contains(cls))
{
FMLLog.fine(" Unknown recipe class! %s Modder please refer to %s", cls.getName(), RecipeSorter.class.getName());
warned.add(cls);
}
cls = cls.getSuperclass();
while (cls != Object.class)
{
ret = priorities.get(cls);
if (ret != null)
{
priorities.put(recipe.getClass(), ret);
FMLLog.fine(" Parent Found: %d - %s", ret.intValue(), cls.getName());
return ret.intValue();
}
}
}
return ret == null ? 0 : ret.intValue();
}
private static void bake()
{
if (!isDirty) return;
FMLLog.fine("Forge RecipeSorter Baking:");
DirectedGraph<SortEntry> sorter = new DirectedGraph<SortEntry>();
sorter.addNode(before);
sorter.addNode(after);
sorter.addEdge(before, after);
for (Map.Entry<String, SortEntry> entry : entries.entrySet())
{
sorter.addNode(entry.getValue());
}
for (Map.Entry<String, SortEntry> e : entries.entrySet())
{
SortEntry entry = e.getValue();
boolean postAdded = false;
sorter.addEdge(before, entry);
for (String dep : entry.after)
{
if (entries.containsKey(dep))
{
sorter.addEdge(entries.get(dep), entry);
}
}
for (String dep : entry.before)
{
postAdded = true;
sorter.addEdge(entry, after);
if (entries.containsKey(dep))
{
sorter.addEdge(entry, entries.get(dep));
}
}
if (!postAdded)
{
sorter.addEdge(entry, after);
}
}
List<SortEntry> sorted = TopologicalSort.topologicalSort(sorter);
int x = sorted.size();
for (SortEntry entry : sorted)
{
FMLLog.fine(" %d: %s", x, entry);
priorities.put(entry.cls, x--);
}
}
}
@@ -0,0 +1,113 @@
package net.minecraftforge.server;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Map;
import java.util.Map.Entry;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.MapMaker;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity;
public class ForgeTimeTracker {
public static boolean tileEntityTracking;
public static int tileEntityTrackingDuration;
public static long tileEntityTrackingTime;
private Map<TileEntity,int[]> tileEntityTimings;
private Map<Entity,int[]> entityTimings;
private static final ForgeTimeTracker INSTANCE = new ForgeTimeTracker();
private WeakReference<TileEntity> tile;
private WeakReference<Entity> entity;
private long timing;
private ForgeTimeTracker()
{
MapMaker mm = new MapMaker();
mm.weakKeys();
tileEntityTimings = mm.makeMap();
entityTimings = mm.makeMap();
}
private void trackTileStart(TileEntity tileEntity, long nanoTime)
{
if (tileEntityTrackingTime == 0)
{
tileEntityTrackingTime = nanoTime;
}
else if (tileEntityTrackingTime + tileEntityTrackingDuration < nanoTime)
{
tileEntityTracking = false;
tileEntityTrackingTime = 0;
return;
}
tile = new WeakReference<TileEntity>(tileEntity);
timing = nanoTime;
}
private void trackTileEnd(TileEntity tileEntity, long nanoTime)
{
if (tile == null || tile.get() != tileEntity)
{
tile = null;
// race, exit
return;
}
int[] timings = tileEntityTimings.get(tileEntity);
if (timings == null)
{
timings = new int[101];
tileEntityTimings.put(tileEntity, timings);
}
int idx = timings[100] = (timings[100] + 1) % 100;
timings[idx] = (int) (nanoTime - timing);
}
public static ImmutableMap<TileEntity,int[]> getTileTimings()
{
return INSTANCE.buildImmutableTileEntityTimingMap();
}
private ImmutableMap<TileEntity, int[]> buildImmutableTileEntityTimingMap()
{
Builder<TileEntity, int[]> builder = ImmutableMap.<TileEntity,int[]>builder();
for (Entry<TileEntity, int[]> entry : tileEntityTimings.entrySet())
{
builder.put(entry.getKey(), Arrays.copyOfRange(entry.getValue(), 0, 100));
}
return builder.build();
}
public static void trackStart(TileEntity tileEntity)
{
if (!tileEntityTracking) return;
INSTANCE.trackTileStart(tileEntity, System.nanoTime());
}
public static void trackEnd(TileEntity tileEntity)
{
if (!tileEntityTracking) return;
INSTANCE.trackTileEnd(tileEntity, System.nanoTime());
}
public static void trackStart(Entity par1Entity)
{
}
public static void trackEnd(Entity par1Entity)
{
}
}
@@ -0,0 +1,147 @@
package net.minecraftforge.server.command;
import java.text.DecimalFormat;
import java.util.List;
import com.google.common.collect.Multiset;
import net.minecraft.command.CommandBase;
import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.WrongUsageException;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ChatMessageComponent;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.ForgeChunkManager;
import net.minecraftforge.server.ForgeTimeTracker;
public class ForgeCommand extends CommandBase {
private MinecraftServer server;
public ForgeCommand(MinecraftServer server)
{
this.server = server;
}
private static final DecimalFormat timeFormatter = new DecimalFormat("########0.000");
@Override
public String getCommandName()
{
return "forge";
}
@Override
public String getCommandUsage(ICommandSender icommandsender)
{
return "commands.forge.usage";
}
@Override
public int getRequiredPermissionLevel()
{
return 2;
}
@Override
public void processCommand(ICommandSender sender, String[] args)
{
if (args.length == 0)
{
throw new WrongUsageException("commands.forge.usage");
}
else if ("help".equals(args[0]))
{
throw new WrongUsageException("commands.forge.usage");
}
else if ("tps".equals(args[0]))
{
displayTPS(sender,args);
}
else if ("tpslog".equals(args[0]))
{
doTPSLog(sender,args);
}
else if ("track".equals(args[0]))
{
handleTracking(sender, args);
}
else
{
throw new WrongUsageException("commands.forge.usage");
}
}
private void handleTracking(ICommandSender sender, String[] args)
{
if (args.length != 3)
{
throw new WrongUsageException("commands.forge.usage.tracking");
}
String type = args[1];
int duration = parseIntBounded(sender, args[2], 1, 60);
if ("te".equals(type))
{
doTurnOnTileEntityTracking(sender, duration);
}
else
{
throw new WrongUsageException("commands.forge.usage.tracking");
}
}
private void doTurnOnTileEntityTracking(ICommandSender sender, int duration)
{
ForgeTimeTracker.tileEntityTrackingDuration = duration;
ForgeTimeTracker.tileEntityTracking = true;
sender.sendChatToPlayer(ChatMessageComponent.createFromTranslationWithSubstitutions("commands.forge.tracking.te.enabled", duration));
}
private void doTPSLog(ICommandSender sender, String[] args)
{
}
private void displayTPS(ICommandSender sender, String[] args)
{
int dim = 0;
boolean summary = true;
if (args.length > 1)
{
dim = parseInt(sender, args[1]);
summary = false;
}
if (summary)
{
for (Integer dimId : DimensionManager.getIDs())
{
double worldTickTime = ForgeCommand.mean(this.server.worldTickTimes.get(dimId)) * 1.0E-6D;
double worldTPS = Math.min(1000.0/worldTickTime, 20);
sender.sendChatToPlayer(ChatMessageComponent.createFromTranslationWithSubstitutions("commands.forge.tps.summary",String.format("Dim %d", dimId), timeFormatter.format(worldTickTime), timeFormatter.format(worldTPS)));
}
double meanTickTime = ForgeCommand.mean(this.server.tickTimeArray) * 1.0E-6D;
double meanTPS = Math.min(1000.0/meanTickTime, 20);
sender.sendChatToPlayer(ChatMessageComponent.createFromTranslationWithSubstitutions("commands.forge.tps.summary","Overall", timeFormatter.format(meanTickTime), timeFormatter.format(meanTPS)));
}
else
{
double worldTickTime = ForgeCommand.mean(this.server.worldTickTimes.get(dim)) * 1.0E-6D;
double worldTPS = Math.min(1000.0/worldTickTime, 20);
sender.sendChatToPlayer(ChatMessageComponent.createFromTranslationWithSubstitutions("commands.forge.tps.summary",String.format("Dim %d", dim), timeFormatter.format(worldTickTime), timeFormatter.format(worldTPS)));
}
}
private static long mean(long[] values)
{
long sum = 0l;
for (long v : values)
{
sum+=v;
}
return sum / values.length;
}
}
Binary file not shown.
+1 -1
Submodule fml updated: 902772ed0c...23baf3a8ce.
+1 -1
View File
@@ -1,3 +1,3 @@
@echo off
.\fml\python\python_fml install.py
.\fml\python\python_fml install.py %*
pause
+1 -1
View File
@@ -1,2 +1,2 @@
#!/bin/bash
python install.py
python install.py "$@"
@@ -1,6 +1,6 @@
--- ../src_base/minecraft/net/minecraft/block/Block.java
+++ ../src_work/minecraft/net/minecraft/block/Block.java
@@ -1,15 +1,20 @@
@@ -1,15 +1,22 @@
package net.minecraft.block;
-import cpw.mods.fml.relauncher.Side;
@@ -20,10 +20,12 @@
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.EnumCreatureType;
+import net.minecraft.entity.boss.EntityDragon;
+import net.minecraft.entity.boss.EntityWither;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.entity.player.EntityPlayer;
@@ -26,8 +31,10 @@
@@ -26,8 +33,10 @@
import net.minecraft.item.ItemSnow;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.StatList;
@@ -34,7 +36,7 @@
import net.minecraft.util.Icon;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.StatCollector;
@@ -35,9 +42,19 @@
@@ -35,9 +44,20 @@
import net.minecraft.world.Explosion;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
@@ -44,6 +46,7 @@
+import net.minecraftforge.common.ForgeHooks;
+import net.minecraftforge.common.IPlantable;
+import net.minecraftforge.common.RotationHelper;
+import net.minecraftforge.event.ForgeEventFactory;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
@@ -54,7 +57,7 @@
/**
* used as foreach item, if item.tab = current tab, display it on the screen
*/
@@ -460,9 +477,10 @@
@@ -460,9 +480,10 @@
return this.needsRandomTick;
}
@@ -66,7 +69,7 @@
}
/**
@@ -485,7 +503,7 @@
@@ -485,7 +506,7 @@
*/
public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
@@ -75,7 +78,7 @@
}
@SideOnly(Side.CLIENT)
@@ -495,7 +513,7 @@
@@ -495,7 +516,7 @@
*/
public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
@@ -84,9 +87,9 @@
}
@SideOnly(Side.CLIENT)
@@ -645,7 +663,13 @@
/**
* ejects contained items into the world, and notifies neighbours of an update, as appropriate
@@ -648,7 +669,13 @@
* different metadata value, but before the new metadata value is set. Args: World, x, y, z, old block ID, old
* metadata
*/
- public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6) {}
+ public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
@@ -99,7 +102,7 @@
/**
* Returns the quantity of items to drop on block destruction.
@@ -670,7 +694,7 @@
@@ -673,7 +700,7 @@
public float getPlayerRelativeBlockHardness(EntityPlayer par1EntityPlayer, World par2World, int par3, int par4, int par5)
{
float f = this.getBlockHardness(par2World, par3, par4, par5);
@@ -108,7 +111,7 @@
}
/**
@@ -688,18 +712,13 @@
@@ -691,18 +718,14 @@
{
if (!par1World.isRemote)
{
@@ -116,7 +119,8 @@
-
- for (int k1 = 0; k1 < j1; ++k1)
+ ArrayList<ItemStack> items = getBlockDropped(par1World, par2, par3, par4, par5, par7);
+
+ par6 = ForgeEventFactory.fireBlockHarvesting(items, par1World, this, par2, par3, par4, par5, par7, par6, false, harvesters.get());
+
+ for (ItemStack item : items)
{
if (par1World.rand.nextFloat() <= par6)
@@ -131,7 +135,7 @@
}
}
}
@@ -932,7 +951,8 @@
@@ -935,7 +958,8 @@
public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
{
int l = par1World.getBlockId(par2, par3, par4);
@@ -141,19 +145,48 @@
}
/**
@@ -1092,7 +1112,7 @@
@@ -1086,6 +1110,7 @@
*/
public void setBlockBoundsForItemRender() {}
+ private ThreadLocal<EntityPlayer> harvesters = new ThreadLocal();
/**
* Called when the player destroys a block with an item that can harvest it. (i, j, k) are the coordinates of the
* block and l is the block's subtype/damage.
@@ -1095,28 +1120,37 @@
par2EntityPlayer.addStat(StatList.mineBlockStatArray[this.blockID], 1);
par2EntityPlayer.addExhaustion(0.025F);
- if (this.canSilkHarvest() && EnchantmentHelper.getSilkTouchModifier(par2EntityPlayer))
- {
+ if (this.canSilkHarvest(par1World, par2EntityPlayer, par3, par4, par5, par6) && EnchantmentHelper.getSilkTouchModifier(par2EntityPlayer))
{
+ {
+ ArrayList<ItemStack> items = new ArrayList<ItemStack>();
ItemStack itemstack = this.createStackedBlock(par6);
@@ -1108,12 +1128,13 @@
if (itemstack != null)
{
- this.dropBlockAsItem_do(par1World, par3, par4, par5, itemstack);
+ items.add(itemstack);
}
+ ForgeEventFactory.fireBlockHarvesting(items, par1World, this, par3, par4, par5, par6, 0, 1.0f, true, par2EntityPlayer);
+ for (ItemStack is : items)
+ {
+ this.dropBlockAsItem_do(par1World, par3, par4, par5, is);
+ }
}
}
else
{
+ harvesters.set(par2EntityPlayer);
int i1 = EnchantmentHelper.getFortuneModifier(par2EntityPlayer);
this.dropBlockAsItem(par1World, par3, par4, par5, par6, i1);
- }
- }
-
+ harvesters.set(null);
+ }
+ }
+
+ private int silk_check_meta = -1; //Dirty hack to stop us from needing to special case the silk check hook.
/**
* Return true if a player with Silk Touch can harvest this block directly, and not its normal drops.
@@ -165,7 +198,7 @@
}
/**
@@ -1453,4 +1474,939 @@
@@ -1457,4 +1491,1001 @@
canBlockGrass[0] = true;
StatList.initBreakableStats();
}
@@ -347,6 +380,7 @@
+ *
+ * @param itemList The list of items to display on the creative inventory.
+ */
+ @Deprecated
+ public void addCreativeItems(ArrayList itemList)
+ {
+ }
@@ -1006,8 +1040,7 @@
+ }
+
+ /**
+ * Determines if this block is destroyed when a ender dragon tries to fly through it.
+ * The block will be set to 0, nothing will drop.
+ * Determines if this block is can be destroyed by the specified entities normal behavior.
+ *
+ * @param world The current world
+ * @param x X Position
@@ -1015,6 +1048,20 @@
+ * @param z Z position
+ * @return True to allow the ender dragon to destroy this block
+ */
+ public boolean canEntityDestroy(World world, int x, int y, int z, Entity entity)
+ {
+ if (entity instanceof EntityWither)
+ {
+ return blockID != Block.bedrock.blockID && blockID != Block.endPortal.blockID && blockID != Block.endPortalFrame.blockID;
+ }
+ else if (entity instanceof EntityDragon)
+ {
+ return canDragonDestroy(world, x, y, z);
+ }
+
+ return true;
+ }
+ @Deprecated
+ public boolean canDragonDestroy(World world, int x, int y, int z)
+ {
+ return blockID != obsidian.blockID && blockID != whiteStone.blockID && blockID != bedrock.blockID;
@@ -1104,4 +1151,52 @@
+ }
+ return false;
+ }
+
+ /**
+ * @return the amount of XP that this block should drop when it is broken
+ */
+ public int getExpDrop(World world, int data, int enchantmentLevel)
+ {
+ return 0;
+ }
+
+ /**
+ * Called when a tile entity on a side of this block changes is created or is destroyed.
+ * @param world The world
+ * @param x The x position of this block instance
+ * @param y The y position of this block instance
+ * @param z The z position of this block instance
+ * @param tileX The x position of the tile that changed
+ * @param tileY The y position of the tile that changed
+ * @param tileZ The z position of the tile that changed
+ */
+ public void onNeighborTileChange(World world, int x, int y, int z, int tileX, int tileY, int tileZ)
+ {
+ }
+
+ /**
+ * @return true if this block is to be notified of TileEntity changes directly through one solid block like comparators
+ */
+ public boolean weakTileChanges()
+ {
+ return false;
+ }
+
+ /**
+ * Called to determine whether to allow the a block to handle its own indirect power rather than using the default rules.
+ * @param world The world
+ * @param x The x position of this block instance
+ * @param y The y position of this block instance
+ * @param z The z position of this block instance
+ * @param side The INPUT side of the block to be powered - ie the opposite of this block's output side
+ * @return Whether Block#isProvidingWeakPower should be called when determining indirect power
+ */
+ public boolean shouldCheckWeakPower(World world, int x, int y, int z, int side)
+ {
+ return !this.isNormalCube(world.getBlockId(x, y, z));
+ }
+
+ @Deprecated //Implemented here as we changed the IFluidBlock interface, and this allows us to do so without breaking exisitng mods.
+ // To be removed next MC version {1.6.3+}
+ public float getFilledPercentage(World world, int x, int y, int z){ return 1; }
}
@@ -23,8 +23,8 @@
}
@@ -182,4 +186,22 @@
this.cactusTopIcon = par1IconRegister.registerIcon(this.func_111023_E() + "_top");
this.cactusBottomIcon = par1IconRegister.registerIcon(this.func_111023_E() + "_bottom");
this.cactusTopIcon = par1IconRegister.registerIcon(this.getTextureName() + "_top");
this.cactusBottomIcon = par1IconRegister.registerIcon(this.getTextureName() + "_bottom");
}
+
+ @Override
@@ -9,7 +9,7 @@
public class BlockChest extends BlockContainer
{
private final Random random = new Random();
@@ -444,7 +446,7 @@
@@ -446,7 +448,7 @@
{
return null;
}
@@ -18,7 +18,7 @@
{
return null;
}
@@ -452,19 +454,19 @@
@@ -454,19 +456,19 @@
{
return null;
}
@@ -38,7 +38,7 @@
@SideOnly(Side.CLIENT)
@@ -248,4 +258,10 @@
this.iconArray[i] = par1IconRegister.registerIcon(this.func_111023_E() + "_stage_" + i);
this.iconArray[i] = par1IconRegister.registerIcon(this.getTextureName() + "_stage_" + i);
}
}
+
@@ -0,0 +1,20 @@
--- ../src_base/minecraft/net/minecraft/block/BlockComparator.java
+++ ../src_work/minecraft/net/minecraft/block/BlockComparator.java
@@ -268,4 +268,17 @@
{
return new TileEntityComparator();
}
+
+ @Override
+ public void onNeighborTileChange(World world, int x, int y, int z, int tileX, int tileY, int tileZ)
+ {
+ if(y == tileY)
+ onNeighborBlockChange(world, x, y, z, world.getBlockId(tileX, tileY, tileZ));
+ }
+
+ @Override
+ public boolean weakTileChanges()
+ {
+ return true;
+ }
}
@@ -9,3 +9,17 @@
l += (i2 & 16711680) >> 16;
i1 += (i2 & 65280) >> 8;
j1 += i2 & 255;
@@ -81,6 +81,13 @@
}
return (float)(par0 + 1) / 9.0F;
+ }
+
+
+ @Deprecated //Implemented here for compatibility, need to change this when we make vanilla fluids use our fluid methods.
+ public float getFilledPercentage(IBlockAccess world, int x, int y, int z)
+ {
+ return 1 - BlockFluid.getFluidHeightPercent(world.getBlockMetadata(x, y, z));
}
@SideOnly(Side.CLIENT)
@@ -20,7 +20,7 @@
{
public static final String[] LEAF_TYPES = new String[] {"oak", "spruce", "birch", "jungle"};
public static final String[][] field_94396_b = new String[][] {{"leaves_oak", "leaves_spruce", "leaves_birch", "leaves_jungle"}, {"leaves_oak_opaque", "leaves_spruce_opaque", "leaves_birch_opaque", "leaves_jungle_opaque"}};
@@ -107,10 +111,9 @@
@@ -111,10 +115,9 @@
{
int j2 = par1World.getBlockId(par2 + k1, par3 + l1, par4 + i2);
@@ -33,7 +33,7 @@
}
}
}
@@ -156,11 +159,13 @@
@@ -160,11 +163,13 @@
{
k2 = par1World.getBlockId(par2 + l1, par3 + i2, par4 + j2);
@@ -49,7 +49,7 @@
{
this.adjacentTreeBlocks[(l1 + k1) * j1 + (i2 + k1) * b1 + j2 + k1] = -2;
}
@@ -325,15 +330,7 @@
@@ -329,15 +334,7 @@
*/
public void harvestBlock(World par1World, EntityPlayer par2EntityPlayer, int par3, int par4, int par5, int par6)
{
@@ -66,7 +66,7 @@
}
/**
@@ -414,4 +411,30 @@
@@ -418,4 +415,30 @@
}
}
}
@@ -1,6 +1,6 @@
--- ../src_base/minecraft/net/minecraft/block/BlockLog.java
+++ ../src_work/minecraft/net/minecraft/block/BlockLog.java
@@ -60,14 +60,9 @@
@@ -62,14 +62,9 @@
{
int j2 = par1World.getBlockId(par2 + k1, par3 + l1, par4 + i2);
@@ -17,8 +17,8 @@
}
}
}
@@ -125,4 +120,16 @@
this.tree_top[i] = par1IconRegister.registerIcon(this.func_111023_E() + "_" + woodType[i] + "_top");
@@ -135,4 +130,16 @@
this.tree_top[i] = par1IconRegister.registerIcon(this.getTextureName() + "_" + woodType[i] + "_top");
}
}
+
@@ -0,0 +1,17 @@
--- ../src_base/minecraft/net/minecraft/block/BlockMobSpawner.java
+++ ../src_work/minecraft/net/minecraft/block/BlockMobSpawner.java
@@ -45,8 +45,12 @@
public void dropBlockAsItemWithChance(World par1World, int par2, int par3, int par4, int par5, float par6, int par7)
{
super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7);
- int j1 = 15 + par1World.rand.nextInt(15) + par1World.rand.nextInt(15);
- this.dropXpOnBlockBreak(par1World, par2, par3, par4, j1);
+ }
+
+ @Override
+ public int getExpDrop(World world, int data, int enchantmentLevel)
+ {
+ return 15 + world.rand.nextInt(15) + world.rand.nextInt(15);
}
/**
@@ -55,7 +55,7 @@
/**
@@ -142,4 +128,23 @@
this.iconArray[i] = par1IconRegister.registerIcon(this.func_111023_E() + "_stage_" + i);
this.iconArray[i] = par1IconRegister.registerIcon(this.getTextureName() + "_stage_" + i);
}
}
+
@@ -0,0 +1,27 @@
--- ../src_base/minecraft/net/minecraft/block/BlockOre.java
+++ ../src_work/minecraft/net/minecraft/block/BlockOre.java
@@ -60,6 +60,11 @@
{
super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7);
+ }
+
+ @Override
+ public int getExpDrop(World par1World, int par5, int par7)
+ {
if (this.idDropped(par5, par1World.rand, par7) != this.blockID)
{
int j1 = 0;
@@ -84,9 +89,10 @@
{
j1 = MathHelper.getRandomIntegerInRange(par1World.rand, 2, 5);
}
+ return j1;
+ }
- this.dropXpOnBlockBreak(par1World, par2, par3, par4, j1);
- }
+ return 0;
}
/**
@@ -26,7 +26,7 @@
}
/**
@@ -242,4 +243,107 @@
@@ -244,4 +245,107 @@
par1World.notifyBlocksOfNeighborChange(par2, par3 - 1, par4, par5);
}
}
@@ -0,0 +1,22 @@
--- ../src_base/minecraft/net/minecraft/block/BlockRedstoneOre.java
+++ ../src_work/minecraft/net/minecraft/block/BlockRedstoneOre.java
@@ -116,11 +116,17 @@
{
super.dropBlockAsItemWithChance(par1World, par2, par3, par4, par5, par6, par7);
+ }
+
+ @Override
+ public int getExpDrop(World par1World, int par5, int par7)
+ {
if (this.idDropped(par5, par1World.rand, par7) != this.blockID)
{
int j1 = 1 + par1World.rand.nextInt(5);
- this.dropXpOnBlockBreak(par1World, par2, par3, par4, j1);
- }
+ return j1;
+ }
+ return 0;
}
@SideOnly(Side.CLIENT)
@@ -1,6 +1,6 @@
--- ../src_base/minecraft/net/minecraft/block/BlockRedstoneWire.java
+++ ../src_work/minecraft/net/minecraft/block/BlockRedstoneWire.java
@@ -473,7 +473,7 @@
@@ -475,7 +475,7 @@
}
else if (!Block.redstoneRepeaterIdle.func_94487_f(i1))
{
@@ -21,16 +21,16 @@
* Called when the block is attempted to be harvested
*/
public void onBlockHarvested(World par1World, int par2, int par3, int par4, int par5, EntityPlayer par6EntityPlayer)
@@ -150,6 +147,8 @@
@@ -149,6 +146,8 @@
par5 |= 8;
par1World.setBlockMetadataWithNotify(par2, par3, par4, par5, 4);
}
+ dropBlockAsItem(par1World, par2, par3, par4, par5, 0);
+
+ dropBlockAsItem(par1World, par2, par3, par4, par5, 0);
super.onBlockHarvested(par1World, par2, par3, par4, par5, par6EntityPlayer);
}
@@ -158,24 +157,30 @@
@@ -160,24 +159,30 @@
*/
public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
{
Loaded 100 of 205 files, more files were not shown because too many files have changed in this diff. Show more