Compare commits

...
200 Commits
Author SHA1 Message Date
CPFe1 eb0b7ab7c3 Fix acceleration of gendustry machines (#6) 2026-10-25 05:25:03 -05:00
Martin Robertz 870d288f83 update 2025-06-21 00:10:12 +02:00
koolkrafter5 b0f714052e Update dev username (#5) 2025-06-19 11:02:39 +02:00
Raven Szewczyk 63dd261042 [ci skip] upgraded build system 2024-02-04 19:56:50 +00:00
Martin Robertz c2a936e036 update bs+gitignore 2024-01-11 22:48:38 +01:00
Raven Szewczyk d03ff4cc5f [ci skip] upgraded build system 2024-01-08 21:23:55 +00:00
Raven Szewczyk 598bc2a720 [ci skip] upgraded build system 2023-01-31 09:51:07 +00:00
Jason Mitchell 5a505bae0d [ci skip] Add git-blame-ignore-revs for spotlessApply 2023-01-29 13:17:27 -08:00
Jason Mitchell 071ca10757 [ci skip] spotlessApply with the new settings 2023-01-29 13:17:27 -08:00
Jason Mitchell d60edbb369 [ci skip] Update buildscript to RetroFuturaGradle 2023-01-29 13:16:37 -08:00
Jason Mitchell c726751100 [ci skip] Migrate github actions to GTNH-Actions-Workflows 2022-07-16 10:46:49 -07:00
Martin Robertz 0258a19bb9 Merge pull request #3 from Pa4ok/master
add compacter classes to network filter
2022-05-29 15:58:09 +02:00
Pa4ok 9acb61025e add compacter classes to network filter 2022-05-29 16:54:44 +03:00
Martin Robertz 98f7ce3ef3 Merge pull request #2 from GTNewHorizons/fix/net-filter-too-strict
Add byte array to whitelisted classes
2022-05-03 22:28:53 +02:00
Glease d00f0ba704 Add byte array to whitelisted classes 2022-05-03 23:30:48 +08:00
Martin Robertz b9bced832f Merge pull request #1 from GTNewHorizons/fix/unchecked-deserialize
Add checks in deserialization code
2022-03-27 16:03:34 +02:00
Glease d0f0e8225b Add checks in deserialization code
Signed-off-by: Glease <4586901+Glease@users.noreply.github.com>
2022-03-27 20:07:08 +08:00
Jason Mitchell 70e34b9265 maven publish buildscript update 2022-01-18 09:40:13 -08:00
Johann Bernhardt 5599113c05 Migrated to unified build script 2021-11-30 15:59:08 +01:00
Johann Bernhardt 12653d1295 moved sources and resources 2021-11-30 15:58:37 +01:00
bdew 57a1192dc0 Fixed nbsp characters in number formatting (again...) 2015-12-04 12:46:38 +02:00
bdew 81e051b592 update to recommended forge 1558, gradle 2.9 2015-12-04 11:25:52 +02:00
bdew a6eb495fe1 bump version 2015-10-02 15:31:08 +03:00
bdew 2d539e8013 Don't try to open GUIs of nonexistant TEs if crap is passed to the gui handler 2015-10-01 00:11:05 +03:00
bdew c44729536c Replace NBSP with space in number formatting (for those locales that use it) - minecraft doesn't render NBSP correctly. 2015-09-18 17:32:36 +03:00
bdew 35def010a3 Merge pull request #19 from Mazdallier/patch-2
Update fr_FR.lang
2015-09-01 14:18:36 +03:00
Mazdallier 911f7aa159 Update fr_FR.lang
before other mod updates
2015-09-01 09:38:27 +02:00
bdew 3aef519c25 Added some hooks to cover system, fixed rendering covers when breaking blocks 2015-08-25 15:52:45 +03:00
bdew 6c59b25e2c Force US locale on all upper/lower case conversions + normalized icon registration across all mods. 2015-08-09 15:03:21 +03:00
bdew 014c1c5e6e Fixed rotatable blocks not always triggering chunk update when rotated 2015-08-05 02:08:26 +03:00
bdew 7fd040e65a Added detailed tooltips to multiblock controllers/modules 2015-08-02 16:34:28 +03:00
bdew ece84599f9 Added misc.withAutoClose - Provides something like java try-with-resources in scala 2015-07-30 15:50:53 +03:00
bdew 174af254e8 Added ChatHelper - allows building chat message with less boilerplate 2015-07-30 14:30:59 +03:00
bdew 71185838f6 Added WidgetInfoMulti 2015-07-23 15:06:50 +03:00
bdew f2cdba7800 Prevent fractional charge leftovers in capacitors (bdew/generators#43) 2015-07-19 22:56:14 +03:00
bdew 89b54300e3 Added tooltip handler system 2015-07-16 12:37:06 +03:00
bdew 9ee12091e6 Modules dataslot in multiblock controlers should not trigger render updates 2015-06-27 19:00:12 +03:00
bdew 08ccf07dfb Don't trigger chunk updates if somethings changes UpdateKind.WORLD dataslot on client. 2015-06-27 18:59:35 +03:00
bdew 382c21f732 Added KeepData mixins for blocks that keep their stuff when broken. 2015-06-24 15:50:23 +03:00
bdew 17e4bf3a2f BlockTooltip will now use the new HasItemBlock trait 2015-06-24 15:50:09 +03:00
bdew ebe2c1f34a Added HasItemBlock - trait that tells BlockManager and Machine to register custom ItemBlocks. Replaces old itemClass parameter. Version bumped to 1.9.0 2015-06-24 15:49:00 +03:00
bdew fae2825e7b Added RichNBTTagCompound.toItemStack 2015-06-24 12:05:48 +03:00
bdew b2e138f3cd TileBaseProcessor shouldn't include BreakableInventoryTile 2015-06-24 12:05:02 +03:00
bdew 9d897d0663 getActiveModId will return <unknown> instead of null 2015-06-24 12:03:58 +03:00
bdew 497917185c BreakableInventoryBlock now checks that the TileEntity extends BreakableInventoryTile at compile time 2015-06-23 11:19:03 +03:00
bdew 9ff7a75604 Build against forge 10.13.4.1448, updated to gradle 2.4 2015-06-10 11:24:27 +03:00
bdew f8bb1e8fbb Added a way to manually run ServerTickExecutionContext 2015-06-08 15:44:16 +03:00
bdew a530c66680 Added ItemBlock with tooltip 2015-06-02 16:45:22 +03:00
bdew 26af828491 Added BlockManager.registerLegacyTileEntity 2015-06-02 14:37:27 +03:00
bdew 1c0913d674 Code cleanup 2015-06-02 13:52:51 +03:00
bdew 895cfd9cb6 Improved NBT constructor 2015-05-31 15:40:08 +03:00
bdew f43dd28e03 Added easy NBT constructor - see https://gist.github.com/bdew/0a44363dcac4be85415c 2015-05-25 15:29:31 +03:00
bdew 289f8f7120 derp 2015-05-24 04:03:23 +03:00
bdew e7787fb9ca bumped version to 1.8.0, removed deprecated methods 2015-05-24 04:01:36 +03:00
bdew 58e336f8a9 Misc.haveModVersion should check APIs too, added getModVersion 2015-05-24 04:00:23 +03:00
bdew bea6a13896 Added async helpers and ServerTickExecutionContext (executes futures in server thread using tick event) 2015-05-21 18:05:33 +03:00
bdew 793ceb0024 Merge pull request #16 from Mazdallier/patch-1
Create fr_FR.lang
2015-05-13 12:07:16 +03:00
Yves 66d9be58c8 Update fr_FR.lang
--file return back
2015-05-12 17:13:57 +02:00
Yves 87d64208c8 Create fr_FR.lang 2015-05-12 15:59:10 +02:00
bdew 6f6496c1e3 /oredistribution - added dense ore support 2015-05-12 16:04:44 +03:00
bdew 934e984abf /oredistribution - Added option to dump to file 2015-05-12 16:02:03 +03:00
bdew 4900537a82 /oredistribution - Fixed meta detection with some ores (e.g. lapis) 2015-05-12 10:19:37 +03:00
bdew 31b5ab9d52 Added /oredistribution command 2015-05-10 22:37:04 +03:00
bdew 8a4ccf7d81 Prevent build failure when CF api key is not available 2015-05-10 15:49:37 +03:00
bdew 429107215f Allow fractional chances in config lootlists 2015-05-10 15:36:31 +03:00
bdew 0c60d596b6 Jenkins will now upload builds to curseforge 2015-05-10 15:35:45 +03:00
bdew da35094895 Merge pull request #14 from theelixzammuto/mc1710
Added Italian Localization
2015-04-27 23:30:19 +03:00
theelixzammuto 83d30f12c2 Added Italian Localization 2015-04-26 21:42:29 +02:00
bdew 8d4484ca18 DataSlotTankRestricted now takes fluid object instead of fluid ID 2015-04-20 14:53:25 +03:00
bdew 624df87299 Updated to grade 2.3, reworked build script to use properties file, changed version format to include MC version 2015-04-20 14:37:23 +03:00
bdew 18b4f19dab Compatibility fix for forge 10.13.3.x 2015-04-14 19:29:13 +03:00
bdew 00b32712a0 Added TankEmulator 2015-04-02 11:22:47 +03:00
bdew 2a008aa093 Refactored nbt helper 2015-04-02 10:29:28 +03:00
bdew 745170415e changed SimpleGenericSensor.parameters back to GenericSensorParameter for greater flexibility 2015-03-30 14:50:48 +03:00
bdew 69b8e80c5f Removed unused field from DataSlotResource and fixed warning 2015-03-30 14:49:54 +03:00
bdew 93ccc42429 Refactored some common code into bdlib, added ability for modules to decide if they can connect to a controller 2015-03-25 17:34:13 +02:00
bdew dc567bd1be More work on sensors 2015-03-25 16:34:46 +02:00
bdew 516133ee0a Fixed multiple derps in 61ba86d451 2015-03-25 16:18:54 +02:00
bdew 28de3620a2 Added human readable errors to NBTTypes 2015-03-25 13:28:18 +02:00
bdew 61ba86d451 Added NBTHelper, changed OutputConfigFluid to use moving average 2015-03-25 13:11:52 +02:00
bdew 8e65772cae More work on sensor system 2015-03-25 10:46:18 +02:00
bdew 284cdfc970 Fixed crash on dedicated servers (bdew/generators#29) 2015-03-24 13:47:58 +02:00
bdew bae688c366 More sensor changes 2015-03-23 17:42:36 +02:00
bdew d3952b69d0 More work on sensor system 2015-03-22 16:14:29 +02:00
bdew 399abf1054 Attempt to Fix getWorldObj reobfuscation shenanigans 2015-03-18 10:40:16 +02:00
bdew f66b97d0cc Refactored TileDataSlots into a base trait DataSlotContainer that can be implemented by other things 2015-03-15 10:20:19 +02:00
bdew 13778072c0 derp 2015-03-12 17:03:39 +02:00
bdew 7dc95fcce1 Give a sensible error if trying to use a Block with no matching ItemBlock in recipes 2015-03-12 17:01:11 +02:00
bdew b71db73b11 Allowed custom ItemBlock registration in BlockManager 2015-03-11 18:00:58 +02:00
bdew 530d5add82 Moved block rotation from player camera logic into a separate object 2015-03-11 18:00:32 +02:00
bdew 3dd917b2a0 Added BlockAccessProxy 2015-03-11 17:06:53 +02:00
bdew 8f44111b4c Fixed item rendering for rotated blocks 2015-03-06 20:56:23 +02:00
bdew 8415ee7a00 Added slot types for sensors 2015-03-04 11:03:06 +02:00
bdew 6439ef8f08 Added Misc.prevInSeq, Added SimpleInventory 2015-03-04 11:02:37 +02:00
bdew dc59ee3d31 Added RotatedBlockRenderer and support for rotated blocks to ConnectedRenderer 2015-03-03 17:47:32 +02:00
bdew 9ae4935fd9 Added sensor system
Bump version
2015-03-03 17:46:45 +02:00
bdew 0929ba9278 Java 6 doesn't have System.lineSeparator *facepalm* 2015-02-26 14:55:18 +02:00
bdew 1003aa1d6a Prevent update spam in tank and resource dataslots when they don't actually change (bdew/pressure#34) 2015-02-26 14:29:04 +02:00
bdew 64c0484c2d Added ApiReporter 2015-02-24 17:23:45 +02:00
bdew 8e90643ea1 GUI update packets are now timestamped, packets from the past will be ignored 2015-02-22 11:12:16 +02:00
bdew a232ce52f3 Build against forge 10.13.2.1291 2015-02-20 13:23:11 +02:00
bdew 35b3a77582 Fixed BlockRef crash on dedicated servers (bdew/generators#26) 2015-02-20 13:23:11 +02:00
bdew be3a1cf2aa Merge pull request #10 from DragonsLover/mc1710
Adding French Canadian language
2015-02-20 06:15:21 +02:00
DragonsLover e0f5d0ceda Adding French Canadian language 2015-02-19 23:14:00 -05:00
bdew e4169f7a5d Fixed Rect.contains being off by 1 2015-02-19 17:56:50 +02:00
bdew eb75a26c40 Moving dataslot classes to bdlib 2015-02-19 12:04:13 +02:00
bdew 3431a6910e Prevent access to invalid coordinates from BlockRef 2015-02-19 01:44:07 +02:00
bdew 02598183b8 Added CIItemInput 2015-02-18 17:52:40 +02:00
bdew 70c19bff5b Lowered log level of some spammy messages in config system to Debug (bdew/gendustry#81) 2015-02-18 12:01:31 +02:00
bdew 6a78467232 Fixed DataSlotResource.drainFluid draining 2x (bdew/generators#21) 2015-02-09 00:21:38 +02:00
bdew 561833db33 Refactored SlotSet to prevent textures being initialized on dedicated servers (bdew/generators#23) 2015-02-08 23:39:37 +02:00
bdew 0e345e6675 Added DecFormat.short 2015-02-05 00:52:42 +02:00
bdew e78e565ec8 Less retarded way to prevent duplicate class files in deobf 2015-02-04 21:57:52 +02:00
bdew 573330efd3 Prevent leftover fractional resources due to FP rounding errors 2015-02-04 20:27:51 +02:00
bdew 5e7c8bda2f attempt to de-derpify unobfuscated jars 2015-01-05 16:03:05 +02:00
bdew 9346d95052 Huge typos and code style cleanup 2014-12-23 17:54:59 +02:00
bdew f0169a15e5 updated copyright header and minor cleanup 2014-12-23 14:41:32 +02:00
bdew 1da90af3f1 Added multiblock stuff for item output and slot selection 2014-12-23 14:34:54 +02:00
bdew b015636514 Added InventoryProxy and MultipleInventoryAdapter 2014-12-23 14:29:13 +02:00
bdew 610be18c74 Added resource system 2014-12-23 14:27:21 +02:00
bdew 9c977904ab Added hack to the gradle script to prevent IDEA14 from derping 2014-12-18 16:43:11 +02:00
bdew cc107d7466 Version bump 2014-12-18 11:26:55 +02:00
bdew 4284f11ec4 Added DataSlotDouble 2014-12-18 11:26:25 +02:00
bdew 300726e660 reworked OutputConfig &co to be easier to extend 2014-12-18 11:26:12 +02:00
bdew 02850b9f85 added DecFormat, some cleanup 2014-12-18 11:20:18 +02:00
bdew 1618931c6d Allow fluid gauge to have no overlay, fixed typo 2014-11-05 16:29:59 +02:00
bdew 5854625700 Added serialization helpers for ItemStack and NBTTagCompound 2014-10-28 10:04:57 +02:00
bdew 8bbab862ab Added RecipesHelper with some shared code for config system loading 2014-10-19 17:16:59 +03:00
bdew 9e83d04487 Build with newer forge 2014-10-19 17:16:15 +03:00
bdew 9202b27340 Added renderer for covers (to allow partially showing the underlying texture) - bdew/gendustry#57 2014-10-15 12:09:08 +03:00
bdew 70ee9fabd6 Added BaseBlockRenderHandler and RenderUtils (some common code moved there) 2014-10-15 12:09:08 +03:00
bdew 78d9bed924 Merge pull request #7 from nalimleinad/mc1710
Create cs_CZ.lang
2014-10-14 13:44:19 +03:00
nalimleinad 92517cdcec Create cs_CZ.lang 2014-10-13 15:30:59 +02:00
bdew bcb8edc8a5 Improved handling of missing icons of fluids and in Texture class 2014-10-08 12:11:53 +03:00
bdew 9a837361e7 /dumpregistry will now show actual items registered in OD 2014-10-06 13:51:40 +03:00
bdew 5ae0461f10 Recipe parser/loader rework, see http://bdew.net/bacon/ for description of new format 2014-10-06 13:51:38 +03:00
bdew b3f8fb3c56 Added PlayerCache - a generic player->whatever map that auto-clears on server restart, logoff, respawn, etc. 2014-09-23 14:12:13 +03:00
bdew 023ae4d77f Added another version of Misc.asInstanceOpt that's easier to use with map, etc. 2014-09-23 14:12:13 +03:00
bdew b1e0e70fc4 Added WidgetSimpleIcon 2014-09-23 14:12:13 +03:00
bdew 5f01716310 Made network message type bound to a specific channel, this should give compile-time errors for sending messages on the wrong channel. Messages should now inherit from YourChannelObject.Message 2014-09-23 14:12:13 +03:00
bdew 0976fb4acc Merge pull request #5 from ViKaleidoscope/patch-1
Create zh_CN.lang
2014-09-19 09:25:35 +03:00
∑( ° △ °|||) 4effeafbb7 Create zh_CN.lang 2014-09-19 12:54:59 +08:00
bdew e0d3609e66 Add ability to customize on what updates DataSlotTank sends it's capacity (default unchanged - only on GUI) 2014-09-18 10:07:56 +03:00
bdew 5a1c150a03 Fixed DrawTarget.drawTextureInterpolate ignoring color parameter 2014-09-16 14:57:37 +03:00
bdew c5a7fc3d51 Fixed WidgetFluidGauge not respecting fluid color 2014-09-16 14:51:33 +03:00
bdew 9787c4836e WidgetOutputs + WidgetPowerOutput moved back to generators as it's mod-specific. WidgetRSConfig refactored from them 2014-09-16 09:44:03 +03:00
bdew cd833163af MsgOutputCfgPower/Fluid (That only had RS configuration) replaced by MsgOutputCfgRSMode 2014-09-16 09:43:13 +03:00
bdew 5a9aedb4d5 Refactoring multiblock outputs, TileOutput (&co) now has a type parameter for config object type 2014-09-04 15:54:35 +03:00
bdew 2a7bbaeb97 prevent outputs connecting back to the same structure 2014-09-03 17:37:00 +03:00
bdew 58125ee291 TileModule.getCoreAs reworked for better type safety 2014-09-03 17:36:19 +03:00
bdew d9cc8ace82 Fixed fluid config save/load 2014-09-02 17:23:36 +03:00
bdew 32617ff592 Added DataSlotInventory 2014-09-02 14:10:50 +03:00
bdew 64683a0208 Refactored output config for multiblocks, added config object for fluid outputs 2014-09-02 14:10:36 +03:00
bdew f593458511 Allow quoted strings as config keys 2014-08-31 10:44:35 +03:00
bdew e6b38472ce Ensure tanks are marked for saving when content changes 2014-08-24 09:58:51 +03:00
bdew e6c0ef2c68 Merge pull request #4 from Adaptivity/patch-1
Create ru_RU.lang
2014-08-21 13:46:48 +03:00
Anton 56110d8ec5 Create ru_RU.lang 2014-08-21 14:09:51 +04:00
bdew f000d11c54 Added ConfigSection.keys 2014-08-20 14:17:13 +03:00
bdew 913d4f48a6 Added localization file 2014-08-20 10:49:06 +03:00
bdew a25553edaf Force block update when connections change for output modules 2014-08-20 10:48:21 +03:00
bdew 82328d10ec Aded multiblock system (moved from DCM) 2014-08-14 15:13:31 +03:00
bdew 12f19fc410 BlockManager.regBlock should looke for NamedBlock trait, not SimpleBlock 2014-08-14 10:04:26 +03:00
bdew 7c275f434a bump version 2014-08-12 13:05:52 +03:00
bdew f960050f9c Added creative tabs helper 2014-08-12 12:41:23 +03:00
bdew 87dd7c34c5 Added DataSlotOption 2014-08-12 12:41:10 +03:00
bdew 9fdc6bd880 Added connected textures renderer 2014-08-11 16:51:18 +03:00
bdew 490433a7f4 Added BlockFace, HasTE can now work with BlockRef, Fixed missing copyrights 2014-08-11 16:45:01 +03:00
bdew 71bef762a6 Added BlockRef (from pressure pipes) 2014-08-07 12:46:21 +03:00
bdew 5eef56811b Fixed InventoryItemAdapter not loading properly 2014-07-29 17:19:39 +03:00
bdew 5a3fa7ef75 Added a statement to check if an API is present in configs 2014-07-29 16:19:05 +03:00
bdew 2d799bb797 Code style 2014-07-29 12:44:05 +03:00
bdew 03d9b0fef0 Rewrote networking system (experimental) 2014-07-29 12:43:53 +03:00
bdew 9b0ed5b0b5 Merge remote-tracking branch 'remotes/origin/mc172' into mc1710 2014-07-15 14:02:45 +03:00
bdew e2c7940539 fixed getConcreteStack in RecipeLoader ignoring size 2014-07-15 14:01:47 +03:00
bdew cd85553fa1 Bump forge to recommended 1180 2014-07-14 10:26:52 +03:00
bdew bbe994c28c Added DataSlotGameProfile 2014-07-14 10:26:34 +03:00
bdew 79e308941d Update to 1.7.10 2014-07-08 11:36:18 +03:00
bdew 7a5982bf37 Cleanup and update changes to 1.7.2 2014-06-18 11:37:56 +03:00
bdew 5166576d30 Merge remote-tracking branch 'remotes/origin/master' into mc172 2014-06-18 11:25:59 +03:00
bdew 35be9bff77 Merge remote-tracking branch 'remotes/origin/master' into mc172 2014-05-04 15:48:48 +03:00
bdew d67bd24eda added IStackBlock for pattern matching with ItemBlocks 2014-04-30 11:18:39 +03:00
bdew a10e90a1e1 Merge remote-tracking branch 'remotes/origin/master' into mc172 2014-04-30 11:16:57 +03:00
bdew 517c3f347f Fixed build script 2014-04-30 09:33:43 +03:00
bdew ecdcdfb05f Added /dumpregistry command 2014-04-23 15:11:07 +03:00
bdew d1d3df184f Don't register custom item stacks from Machine.regBlock - not needed anymore 2014-04-23 14:09:01 +03:00
bdew 522ac5b57b Proper exception logging in RecipeLoader statements 2014-04-23 13:37:09 +03:00
bdew 7acca5475f Added NamedItem trait (which SimpleItem extends now) 2014-04-23 13:36:42 +03:00
bdew 1b86f5f7cc Merge remote-tracking branch 'remotes/origin/mc172' into mc172 2014-04-20 13:46:06 +03:00
bdew 819197cf1e Block and Item Manager should not register itemstacks by default in 1.7 since the normal block/item registry is now usable 2014-04-20 13:44:42 +03:00
bdew 1e71bf7dd9 Fixed RecipeLoader logging error 2014-04-20 13:44:10 +03:00
bdew 0549f95088 Fix project name 2014-04-14 09:50:22 +03:00
bdew 06f0007bca oops wrong version 2014-04-14 09:36:21 +03:00
bdew 54499cdb2e Update to Forge 1057 (FG 1.2) 2014-04-13 15:25:20 +03:00
bdew d80d89acf1 Merge remote-tracking branch 'remotes/origin/master' into mc172 2014-04-13 15:24:45 +03:00
bdew 78c5ec1362 Merge branch 'master' of github.com:bdew/bdlib into mc172 2014-02-27 10:06:58 +02:00
bdew 005c300d8f Added experimental network stuff 2014-02-12 17:03:34 +02:00
bdew 4754c209ae oops, i an annotation 2014-02-12 14:19:24 +02:00
bdew b89d445b17 Updated Recipe Loader for 1.7.2 changes 2014-02-12 14:18:57 +02:00
bdew 7eefbb1a31 Updated HasTE, BaseInventory and Block/Item Manager for 1.7.2 changes 2014-02-12 12:39:10 +02:00
bdew 4268019935 Initial port to MC 1.7.2 2014-02-10 14:28:05 +02:00
279 changed files with 10888 additions and 2830 deletions

No files matched your search

+19
View File
@@ -0,0 +1,19 @@
# This is the universal Text Editor Configuration
# for all GTNewHorizons projects
# See: https://editorconfig.org/
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.{bat,ini}]
end_of_line = crlf
[*.{dtd,json,info,mcmeta,md,sh,svg,xml,xsd,xsl,yaml,yml}]
indent_size = 2
+2
View File
@@ -0,0 +1,2 @@
# Ignore spotlessApply reformat
071ca107572c7626deb5c378724e008b8b6a5be5
+44
View File
@@ -0,0 +1,44 @@
* text eol=lf
*.[jJ][aA][rR] binary
*.[pP][nN][gG] binary
*.[jJ][pP][gG] binary
*.[jJ][pP][eE][gG] binary
*.[gG][iI][fF] binary
*.[tT][iI][fF] binary
*.[tT][iI][fF][fF] binary
*.[iI][cC][oO] binary
*.[sS][vV][gG] text
*.[eE][pP][sS] binary
*.[xX][cC][fF] binary
*.[kK][aA][rR] binary
*.[mM]4[aA] binary
*.[mM][iI][dD] binary
*.[mM][iI][dD][iI] binary
*.[mM][pP]3 binary
*.[oO][gG][gG] binary
*.[rR][aA] binary
*.7[zZ] binary
*.[gG][zZ] binary
*.[tT][aA][rR] binary
*.[tT][gG][zZ] binary
*.[zZ][iI][pP] binary
*.[tT][cC][nN] binary
*.[sS][oO] binary
*.[dD][lL][lL] binary
*.[dD][yY][lL][iI][bB] binary
*.[pP][sS][dD] binary
*.[tT][tT][fF] binary
*.[oO][tT][fF] binary
*.[pP][aA][tT][cC][hH] -text
*.[bB][aA][tT] text eol=crlf
*.[cC][mM][dD] text eol=crlf
*.[pP][sS]1 text eol=crlf
*[aA][uU][tT][oO][gG][eE][nN][eE][rR][aA][tT][eE][dD]* binary
+51
View File
@@ -0,0 +1,51 @@
#!/usr/bin/env bash
# bashsupport disable=BP5006 # Global environment variables
RUNDIR="run" \
CRASH="crash-reports" \
SERVERLOG="server.log"
# enable nullglob to get 0 results when no match rather than the pattern
shopt -s nullglob
# store matches in array
crash_reports=("$RUNDIR/$CRASH/crash"*.txt)
# if array not empty there are crash_reports
if [ "${#crash_reports[@]}" -gt 0 ]; then
# get the latest crash_report from array
latest_crash_report="${crash_reports[-1]}"
{
printf 'Latest crash report detected %s:\n' "${latest_crash_report##*/}"
cat "$latest_crash_report"
} >&2
exit 1
fi
if grep --quiet --fixed-strings 'Fatal errors were detected' "$SERVERLOG"; then
{
printf 'Fatal errors detected:\n'
cat server.log
} >&2
exit 1
fi
if grep --quiet --fixed-strings 'The state engine was in incorrect state ERRORED and forced into state SERVER_STOPPED' \
"$SERVERLOG"; then
{
printf 'Server force stopped:'
cat server.log
} >&2
exit 1
fi
if ! grep --quiet --perl-regexp --only-matching '.+Done \(.+\)\! For help, type "help" or "\?"' "$SERVERLOG"; then
{
printf 'Server did not finish startup:'
cat server.log
} >&2
exit 1
fi
printf 'No crash reports detected'
exit 0
+13
View File
@@ -0,0 +1,13 @@
name: Build and test
on:
pull_request:
branches: [ master, main ]
push:
branches: [ master, main ]
jobs:
build-and-test:
uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/build-and-test.yml@master
secrets: inherit
+14
View File
@@ -0,0 +1,14 @@
name: Release tagged build
on:
push:
tags: [ '*' ]
permissions:
contents: write
jobs:
release-tags:
uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/release-tags.yml@master
secrets: inherit
+27 -7
View File
@@ -1,9 +1,29 @@
/.gradle
/build
/deps
/eclipse
/out
*.ipr
.gradle
.settings
/.idea/
/run/
/build/
/eclipse/
.classpath
.project
/bin/
/config/
/crash-reports/
/logs/
options.txt
/saves/
usernamecache.json
banned-ips.json
banned-players.json
eula.txt
ops.json
server.properties
servers.dat
usercache.json
whitelist.json
/out/
*.iml
*.ipr
*.iws
src/main/resources/mixins.*.json
*.bat
+3
View File
@@ -0,0 +1,3 @@
# Any Github changes require admin approval
/.github/** @GTNewHorizons/admin
+4 -93
View File
@@ -1,94 +1,5 @@
buildscript {
repositories {
mavenCentral()
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
}
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:1.0-SNAPSHOT'
}
//version: 1707058017
plugins {
id 'com.gtnewhorizons.gtnhconvention'
}
apply plugin: 'forge'
apply plugin: 'scala'
version = "1.2.3"
if (project.hasProperty('buildnum')) {
project.version = project.version + '.' + project.buildnum
} else {
project.version = "0-SNAPSHOT"
}
group = "net.bdew"
archivesBaseName = "bdlib"
ext.versuffix = "mc164"
minecraft {
version = "1.6.4-9.11.1.964"
replace("BDLIB_VER", project.version)
}
import org.apache.tools.ant.filters.ReplaceTokens
sourceSets {
main {
scala {
srcDir 'src'
}
resources {
srcDir 'resources'
}
}
}
processResources {
inputs.property "tokens", minecraft.replacements
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
filter(ReplaceTokens, tokens: minecraft.replacements)
}
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}
}
task sourceJar(type: Jar) {
from sourceSets.main.allSource
}
task deobfJar(type: Jar) {
from sourceSets.main.output
}
jar {
appendix = project.versuffix
}
artifacts {
archives sourceJar
archives deobfJar
}
apply plugin: 'maven-publish'
publishing {
publications {
maven(MavenPublication) {
artifact deobfJar
artifact sourceJar {
classifier "sources"
}
}
}
repositories {
maven {
url "file://var/www/maven"
}
}
}
+5
View File
@@ -0,0 +1,5 @@
// Add your dependencies here
dependencies {
}
+203
View File
@@ -0,0 +1,203 @@
# ExampleMod tag to use as Blowdryer (Spotless, etc.) settings version, leave empty to disable.
# LOCAL to test local config updates.
gtnh.settings.blowdryerTag = 0.2.0
# Human-readable mod name, available for mcmod.info population.
modName = BD lib
# Case-sensitive identifier string, available for mcmod.info population and used for automatic mixin JSON generation.
# Conventionally lowercase.
modId = bdlib
# Root package of the mod, used to find various classes in other properties,
# mcmod.info substitution, enabling assertions in run tasks, etc.
modGroup = net.bdew.lib
# Whether to use modGroup as the maven publishing group.
# When false, com.github.GTNewHorizons is used.
useModGroupForPublishing = false
# Updates your build.gradle and settings.gradle automatically whenever an update is available.
autoUpdateBuildScript = false
# Version of Minecraft to target
minecraftVersion = 1.7.10
# Version of Minecraft Forge to target
forgeVersion = 10.13.4.1614
# Specify an MCP channel for dependency deobfuscation and the deobfParams task.
channel = stable
# Specify an MCP mappings version for dependency deobfuscation and the deobfParams task.
mappingsVersion = 12
# Defines other MCP mappings for dependency deobfuscation.
remoteMappings = https\://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/
# Select a default username for testing your mod. You can always override this per-run by running
# `./gradlew runClient --username=AnotherPlayer`, or configuring this command in your IDE.
developmentEnvironmentUserName = Developer
# Enables using modern Java syntax (up to version 17) via Jabel, while still targeting JVM 8.
# See https://github.com/bsideup/jabel for details on how this works.
enableModernJavaSyntax = false
# Enables injecting missing generics into the decompiled source code for a better coding experience.
# Turns most publicly visible List, Map, etc. into proper List<E>, Map<K, V> types.
enableGenericInjection = false
# Generate a class with a String field for the mod version named as defined below.
# If generateGradleTokenClass is empty or not missing, no such class will be generated.
# If gradleTokenVersion is empty or missing, the field will not be present in the class.
generateGradleTokenClass =
# Name of the token containing the project's current version to generate/replace.
gradleTokenVersion = GRADLETOKEN_VERSION
# [DEPRECATED] Mod ID replacement token.
gradleTokenModId =
# [DEPRECATED] Mod name replacement token.
gradleTokenModName =
# [DEPRECATED] Mod Group replacement token.
gradleTokenGroupName =
# [DEPRECATED]
# Multiple source files can be defined here by providing a comma-separated list: Class1.java,Class2.java,Class3.java
# public static final String VERSION = "GRADLETOKEN_VERSION";
# The string's content will be replaced with your mod's version when compiled. You should use this to specify your mod's
# version in @Mod([...], version = VERSION, [...]).
# Leave these properties empty to skip individual token replacements.
replaceGradleTokenInFile = BdLib.scala
# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can
# leave this property empty.
# Example value: (apiPackage = api) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.api
apiPackage =
# Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/META-INF/
# There can be multiple files in a space-separated list.
# Example value: mymodid_at.cfg nei_at.cfg
accessTransformersFile =
# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled!
usesMixins = false
# Set to a non-empty string to configure mixins in a separate source set under src/VALUE, instead of src/main.
# This can speed up compile times thanks to not running the mixin annotation processor on all input sources.
# Mixin classes will have access to "main" classes, but not the other way around.
separateMixinSourceSet =
# Adds some debug arguments like verbose output and class export.
usesMixinDebug = false
# Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise.
mixinPlugin =
# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail!
mixinsPackage =
# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin!
# This parameter is for legacy compatibility only
# Example value: (coreModClass = asm.FMLPlugin) + (modGroup = com.myname.mymodid) -> com.myname.mymodid.asm.FMLPlugin
coreModClass =
# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class
# that is annotated with @Mod) you want this to be true. When in doubt: leave it on false!
containsMixinsAndOrCoreModOnly = false
# Enables Mixins even if this mod doesn't use them, useful if one of the dependencies uses mixins.
forceEnableMixins = false
# If enabled, you may use 'shadowCompile' for dependencies. They will be integrated into your jar. It is your
# responsibility to check the license and request permission for distribution if required.
usesShadowedDependencies = false
# If disabled, won't remove unused classes from shadowed dependencies. Some libraries use reflection to access
# their own classes, making the minimization unreliable.
minimizeShadowedDependencies = true
# If disabled, won't rename the shadowed classes.
relocateShadowedDependencies = true
# Adds CurseMaven, Modrinth, and some more well-known 1.7.10 repositories.
includeWellKnownRepositories = true
# A list of repositories to exclude from the includeWellKnownRepositories setting. Should be a space separated
# list of strings, with the acceptable keys being(case does not matter):
# cursemaven
# modrinth
excludeWellKnownRepositories =
# Change these to your Maven coordinates if you want to publish to a custom Maven repository instead of the default GTNH Maven.
# Authenticate with the MAVEN_USER and MAVEN_PASSWORD environment variables.
# If you need a more complex setup disable maven publishing here and add a publishing repository to addon.gradle.
usesMavenPublishing = true
# Maven repository to publish the mod to.
# mavenPublishUrl = https\://nexus.gtnewhorizons.com/repository/releases/
# Publishing to Modrinth requires you to set the MODRINTH_TOKEN environment variable to your current Modrinth API token.
#
# The project's ID on Modrinth. Can be either the slug or the ID.
# Leave this empty if you don't want to publish to Modrinth.
modrinthProjectId =
# The project's relations on Modrinth. You can use this to refer to other projects on Modrinth.
# Syntax: scope1-type1:name1;scope2-type2:name2;...
# Where scope can be one of [required, optional, incompatible, embedded],
# type can be one of [project, version],
# and the name is the Modrinth project or version slug/id of the other mod.
# Example: required-project:fplib;optional-project:gasstation;incompatible-project:gregtech
# Note: GTNH Mixins is automatically set as a required dependency if usesMixins = true
modrinthRelations =
# Publishing to CurseForge requires you to set the CURSEFORGE_TOKEN environment variable to one of your CurseForge API tokens.
#
# The project's numeric ID on CurseForge. You can find this in the About Project box.
# Leave this empty if you don't want to publish on CurseForge.
curseForgeProjectId =
# The project's relations on CurseForge. You can use this to refer to other projects on CurseForge.
# Syntax: type1:name1;type2:name2;...
# Where type can be one of [requiredDependency, embeddedLibrary, optionalDependency, tool, incompatible],
# and the name is the CurseForge project slug of the other mod.
# Example: requiredDependency:railcraft;embeddedLibrary:cofhlib;incompatible:buildcraft
# Note: UniMixins is automatically set as a required dependency if usesMixins = true.
curseForgeRelations =
# Optional parameter to customize the produced artifacts. Use this to preserve artifact naming when migrating older
# projects. New projects should not use this parameter.
# customArchiveBaseName =
# Optional parameter to have the build automatically fail if an illegal version is used.
# This can be useful if you e.g. only want to allow versions in the form of '1.1.xxx'.
# The check is ONLY performed if the version is a git tag.
# Note: the specified string must be escaped, so e.g. 1\\.1\\.\\d+ instead of 1\.1\.\d+
# versionPattern =
# Uncomment to prevent the source code from being published.
# noPublishedSources = true
# Uncomment this to disable Spotless checks.
# This should only be uncommented to keep it easier to sync with upstream/other forks.
# That is, if there is no other active fork/upstream, NEVER change this.
# disableSpotless = true
# Uncomment this to disable Checkstyle checks (currently wildcard import check).
# disableCheckstyle = true
# Override the IDEA build type. Valid values are: "" (leave blank, do not override), "idea" (force use native IDEA build), "gradle"
# (force use delegated build).
# This is meant to be set in $HOME/.gradle/gradle.properties.
# e.g. add "systemProp.org.gradle.project.ideaOverrideBuildType=idea" will override the build type to be native build.
# WARNING: If you do use this option, it will overwrite whatever you have in your existing projects. This might not be what you want!
# Usually there is no need to uncomment this here as other developers do not necessarily use the same build type as you.
# ideaOverrideBuildType = idea
# Whether IDEA should run spotless checks when pressing the Build button.
# This is meant to be set in $HOME/.gradle/gradle.properties.
# ideaCheckSpotlessOnBuild = true
Binary file not shown.
+3 -2
View File
@@ -1,6 +1,7 @@
#Thu Nov 28 11:30:59 IST 2013
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-bin.zip
Vendored Regular → Executable
+205 -118
View File
@@ -1,79 +1,129 @@
#!/usr/bin/env bash
#!/bin/sh
#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Attempt to set APP_HOME
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Resolve links: $0 may be a link
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn ( ) {
warn () {
echo "$*"
}
} >&2
die ( ) {
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
nonstop=false
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -82,83 +132,120 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
Vendored
+46 -42
View File
@@ -1,4 +1,22 @@
@if "%DEBUG%" == "" @echo off
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -8,26 +26,30 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -35,54 +57,36 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
+2
View File
@@ -0,0 +1,2 @@
before_install:
- ./gradlew setupCIWorkspace
+5
View File
@@ -0,0 +1,5 @@
// Add any additional repositiroes for your dependencies here
repositories {
}
+23
View File
@@ -0,0 +1,23 @@
pluginManagement {
repositories {
maven {
// RetroFuturaGradle
name "GTNH Maven"
url "https://nexus.gtnewhorizons.com/repository/public/"
mavenContent {
includeGroup("com.gtnewhorizons")
includeGroupByRegex("com\\.gtnewhorizons\\..+")
}
}
gradlePluginPortal()
mavenCentral()
mavenLocal()
}
}
plugins {
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.38'
}
@@ -0,0 +1 @@
net-filter.cfg
@@ -0,0 +1,7 @@
cfg messageWhitelist {
exact = =[
]
prefix = =[
]
enforce = yes
}
@@ -0,0 +1,19 @@
bdlib.multiblock.face.north=Sever
bdlib.multiblock.face.south=Jih
bdlib.multiblock.face.east=Západ
bdlib.multiblock.face.west=Východ
bdlib.multiblock.face.up=Vršek
bdlib.multiblock.face.down=Spodek
bdlib.multiblock.disabled=Zakázáno
bdlib.multiblock.incomplete=Tento stroj není kompletní, ještě potřebuje alespoň:
bdlib.multiblock.notconnected=Nepřipojeno ke správnému stroji
bdlib.multiblock.toomanyoutputs=Připojeno příliš mnoho výstupů, nemohu získat nové připojení
bdlib.rsmode.always=Vždy ZAPNUTO
bdlib.rsmode.never=Zakázáno
bdlib.rsmode.rs_on=Povoleno při ruditovém signálu
bdlib.rsmode.rs_off=Zakázáno při ruditovém signálu
bdlib.label.empty=Prázdný
@@ -0,0 +1,30 @@
bdlib.multiblock.face.north=North
bdlib.multiblock.face.south=South
bdlib.multiblock.face.east=East
bdlib.multiblock.face.west=West
bdlib.multiblock.face.up=Top
bdlib.multiblock.face.down=Bottom
bdlib.multiblock.disabled=Disabled
bdlib.multiblock.incomplete=This machine is incomplete, it requires at least:
bdlib.multiblock.notconnected=Not connected to a valid machine
bdlib.multiblock.toomanyoutputs=Too many outputs connected, unable to attach new connection
bdlib.multiblock.tip.module=Can be installed in:
bdlib.multiblock.tip.controller=Possible modules:
bdlib.multiblock.tip.module.range= * %s (%s - %s)
bdlib.multiblock.tip.module.max= * %s (up to %s)
bdlib.rsmode.always=Always ON
bdlib.rsmode.never=Disabled
bdlib.rsmode.rs_on=Enable on redstone
bdlib.rsmode.rs_off=Disable on redstone
bdlib.label.empty=Empty
bdlib.oredistribution.usage=/oredistribution <radius> [<min height>] [<max height>] [--file]
bdlib.oredistribution.start1=Checking ore distribution in (%s,%s,%s) to (%s,%s,%s) dim %s
bdlib.oredistribution.start2=Server may lag for a while
bdlib.oredistribution.entry=%s %s - %s (%s%%)
bdlib.oredistribution.warn=%s Warning: %s has multiple variants generated:
bdlib.oredistribution.saved=Ore distribution dumped to %s
bdlib.oredistribution.error=Failed to save ore distribution dump: %s
@@ -0,0 +1,18 @@
bdlib.multiblock.face.north=Nord
bdlib.multiblock.face.south=Sud
bdlib.multiblock.face.east=Est
bdlib.multiblock.face.west=Ouest
bdlib.multiblock.face.up=Haut
bdlib.multiblock.face.down=Bas
bdlib.multiblock.disabled=Désactivé(e)
bdlib.multiblock.incomplete=Cette machine est incomplète, elle requiert au moins :
bdlib.multiblock.notconnected=Pas connecté(e) à une machine valide
bdlib.multiblock.toomanyoutputs=Trop de sorties connectées, incapable d'attacher de nouvelles connexions
bdlib.rsmode.always=Toujours en marche
bdlib.rsmode.never=Désactivé(e)
bdlib.rsmode.rs_on=Activer par la redstone
bdlib.rsmode.rs_off=Désactiver par la redstone
bdlib.label.empty=Vide
@@ -0,0 +1,30 @@
bdlib.multiblock.face.north=Nord
bdlib.multiblock.face.south=Sud
bdlib.multiblock.face.east=Est
bdlib.multiblock.face.west=Ouest
bdlib.multiblock.face.up=Dessus
bdlib.multiblock.face.down=Dessous
bdlib.multiblock.disabled=Désactivé
bdlib.multiblock.incomplete=Cette machine est incomplète, elle exige au moins :
bdlib.multiblock.notconnected=Pas connecté à une machine valide
bdlib.multiblock.toomanyoutputs=Trop de sorties connectées, impossible d'ajouter une nouvelle connexion
bdlib.multiblock.tip.module=Peut être installé dans :
bdlib.multiblock.tip.controller=Modules possibles:
bdlib.multiblock.tip.module.range= * %s (%s - %s)
bdlib.multiblock.tip.module.max= * %s (plus de %s)
bdlib.rsmode.always=Toujours actif
bdlib.rsmode.never=Désactivé
bdlib.rsmode.rs_on=Activé par redstone
bdlib.rsmode.rs_off=Désactivé par redstone
bdlib.label.empty=Vide
bdlib.oredistribution.usage=/oredistribution <rayon> [<hauteur mini>] [<hauteur maxi>] [--file]
bdlib.oredistribution.start1=Valide la distribution de minerai entre (%s,%s,%s) et (%s,%s,%s) dim %s
bdlib.oredistribution.start2=Le server peut ralentir pendantun certain temps
bdlib.oredistribution.entry=%s %s - %s (%s%%)
bdlib.oredistribution.warn=%s Attention: %s fait produire des variantes multiples :
bdlib.oredistribution.saved=Distribution de minerai déposée dans %s
bdlib.oredistribution.error=Impossible d'enregistrer la distribution de minerai : %s
@@ -0,0 +1,18 @@
bdlib.multiblock.face.north=Nord
bdlib.multiblock.face.south=Sud
bdlib.multiblock.face.east=Est
bdlib.multiblock.face.west=Ovest
bdlib.multiblock.face.up=Sopra
bdlib.multiblock.face.down=Sotto
bdlib.multiblock.disabled=Disattivo
bdlib.multiblock.incomplete=Questa macchina è incompleta, richiede almeno:
bdlib.multiblock.notconnected=Non connesso ad una macchina valida
bdlib.multiblock.toomanyoutputs=Troppi Output collegati,impossibile inserire una nuova connessione
bdlib.rsmode.always=Sempre Attivo
bdlib.rsmode.never=Disattivo
bdlib.rsmode.rs_on=Attivo su Impulso di Pietrarossa
bdlib.rsmode.rs_off=Disattivo su Impulso di Pietrarossa
bdlib.label.empty=Vuoto
@@ -0,0 +1,18 @@
bdlib.multiblock.face.north=Север
bdlib.multiblock.face.south=Юг
bdlib.multiblock.face.east=Восток
bdlib.multiblock.face.west=Запад
bdlib.multiblock.face.up=Верх
bdlib.multiblock.face.down=Низ
bdlib.multiblock.disabled=Отключено
bdlib.multiblock.incomplete=Этот механизм не завершён, ему требуется как минимум:
bdlib.multiblock.notconnected=Не подключено к верному механизму
bdlib.multiblock.toomanyoutputs=Слишком много выходов подсоединено, нельзя установить новое соединение
bdlib.rsmode.always=Всегда ВКЛ.
bdlib.rsmode.never=Отключен
bdlib.rsmode.rs_on=Включение по сигналу красного камня
bdlib.rsmode.rs_off=Отключение по сигналу красного камня
bdlib.label.empty=Пусто
@@ -0,0 +1,18 @@
bdlib.multiblock.face.north=北方
bdlib.multiblock.face.south=南方
bdlib.multiblock.face.east=东方
bdlib.multiblock.face.west=西方
bdlib.multiblock.face.up=顶部
bdlib.multiblock.face.down=底部
bdlib.multiblock.disabled=停用
bdlib.multiblock.incomplete=这台多方块结构机器未搭建完成, 它至少需要安装一个:
bdlib.multiblock.notconnected=未连接有效机器
bdlib.multiblock.toomanyoutputs=连接的输出接口过多, 无法连接新的接口
bdlib.rsmode.always=一直启用
bdlib.rsmode.never=一直停用
bdlib.rsmode.rs_on=接收到红石信号时启用
bdlib.rsmode.rs_off=接收到红石信号时停用
bdlib.label.empty=空
@@ -1,9 +1,10 @@
[
{
"modid": "bdlib",
"name": "BD Lib",
"modid": "${modId}",
"name": "${modName}",
"description": "",
"version": "@BDLIB_VER@",
"version": "${modVersion}",
"mcversion": "${minecraftVersion}",
"url": "bdew.net/mods/",
"updateUrl": "",
"authorList": [
@@ -0,0 +1,36 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib
import java.util
import java.util.Locale
import cpw.mods.fml.common.{ICrashCallable, ModAPIManager, ModContainer}
import scala.collection.JavaConversions._
object ApiReporter extends ICrashCallable {
lazy val APIs = {
val mods = new util.ArrayList[ModContainer]
val nameLookup = new util.HashMap[String, ModContainer]
ModAPIManager.INSTANCE.injectAPIModContainers(mods, nameLookup)
(for (mod <- mods.sortBy(_.getModId.toLowerCase(Locale.US)))
yield "\t\t* %s (%s) from %s".format(
mod.getModId,
mod.getVersion,
if (mod.getSource.isDirectory)
mod.getSource
else
mod.getSource.getName
)).mkString(Misc.lineSeparator)
}
override def getLabel = "List of loaded APIs"
override def call() = Misc.lineSeparator + APIs
}
+89
View File
@@ -0,0 +1,89 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib
import cpw.mods.fml.common.Mod.EventHandler
import cpw.mods.fml.common.event.{
FMLPreInitializationEvent,
FMLServerStartingEvent,
FMLServerStoppingEvent
}
import cpw.mods.fml.common.{FMLCommonHandler, Mod}
import net.bdew.lib.multiblock.data.MsgOutputCfgRSMode
import net.bdew.lib.multiblock.network.{
MsgOutputCfg,
MsgOutputCfgSlot,
NetHandler
}
import net.bdew.lib.network.{
BaseMessage,
NetworkSecurityLoader,
SerializedMessageCodec
}
import net.bdew.lib.tooltip.TooltipHandler
import net.minecraft.command.CommandHandler
import org.apache.logging.log4j.Logger
import java.io.File
@Mod(
modid = "bdlib",
name = "BD lib",
version = "GRADLETOKEN_VERSION",
modLanguage = "scala"
)
object BdLib {
var log: Logger = null
var configDir: File = null
def logDebug(msg: String, args: Any*) = log.debug(msg.format(args: _*))
def logInfo(msg: String, args: Any*) = log.info(msg.format(args: _*))
def logWarn(msg: String, args: Any*) = log.warn(msg.format(args: _*))
def logError(msg: String, args: Any*) = log.error(msg.format(args: _*))
def logWarnException(msg: String, t: Throwable, args: Any*) =
log.warn(msg.format(args: _*), t)
def logErrorException(msg: String, t: Throwable, args: Any*) =
log.error(msg.format(args: _*), t)
val onServerStarting = Event[FMLServerStartingEvent]
val onServerStopping = Event[FMLServerStoppingEvent]
@EventHandler
def preInit(ev: FMLPreInitializationEvent) {
log = ev.getModLog
log.info("bdlib GRADLETOKEN_VERSION loaded")
log.debug("List of loaded APIs: " + ApiReporter.APIs)
FMLCommonHandler.instance().registerCrashCallable(ApiReporter)
configDir = new File(ev.getModConfigurationDirectory, "bdlib")
SerializedMessageCodec.addValidClass(classOf[BaseMessage[_]])
SerializedMessageCodec.addValidClass(classOf[MsgOutputCfgRSMode])
SerializedMessageCodec.addValidClass(classOf[MsgOutputCfg])
SerializedMessageCodec.addValidClass(classOf[MsgOutputCfgSlot])
NetworkSecurityLoader.loadConfigFiles()
NetHandler.init()
if (ev.getSide.isClient) {
TooltipHandler.init()
}
}
@EventHandler
def serverStarting(event: FMLServerStartingEvent) {
val commandHandler =
event.getServer.getCommandManager.asInstanceOf[CommandHandler]
commandHandler.registerCommand(CommandDumpRegistry)
commandHandler.registerCommand(CommandOreDistribution)
onServerStarting.trigger(event)
}
@EventHandler
def serverStopping(event: FMLServerStoppingEvent) {
onServerStopping.trigger(event)
}
}
@@ -4,23 +4,33 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib
import org.lwjgl.input.Keyboard
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.texture.TextureMap
import org.lwjgl.input.Keyboard
/**
* Misc functions and shortcuts for clientside code
*/
/** Misc functions and shortcuts for client-side code
*/
object Client {
def minecraft = Minecraft.getMinecraft
def fontRenederer = Minecraft.getMinecraft.fontRenderer
def fontRenderer = Minecraft.getMinecraft.fontRenderer
def renderEngine = Minecraft.getMinecraft.renderEngine
def world = Minecraft.getMinecraft.theWorld
def player = Minecraft.getMinecraft.thePlayer
def textureManager = Minecraft.getMinecraft.getTextureManager
def blockMissingIcon = textureManager
.getTexture(TextureMap.locationBlocksTexture)
.asInstanceOf[TextureMap]
.getAtlasSprite("missingno")
def itemMissingIcon = textureManager
.getTexture(TextureMap.locationItemsTexture)
.asInstanceOf[TextureMap]
.getAtlasSprite("missingno")
def shiftDown: Boolean = {
return Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54)
@@ -0,0 +1,103 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib
import java.io.{BufferedWriter, File, FileWriter}
import com.google.common.collect.Table
import cpw.mods.fml.common.registry.GameData
import cpw.mods.fml.relauncher.FMLInjectionData
import net.minecraft.command.{CommandBase, ICommandSender}
import net.minecraft.item.ItemStack
import net.minecraftforge.fluids.FluidRegistry
import net.minecraftforge.oredict.OreDictionary
object CommandDumpRegistry extends CommandBase {
def getCommandName = "dumpregistry"
override def getRequiredPermissionLevel = 2
def getCommandUsage(c: ICommandSender) = "dumpregistry"
def processCommand(sender: ICommandSender, params: Array[String]) {
val mcHome =
FMLInjectionData
.data()(6)
.asInstanceOf[File] // is there a better way to get this?
val dumpFile = new File(mcHome, "registry.dump")
val dumpWriter = new BufferedWriter(new FileWriter(dumpFile))
import scala.collection.JavaConversions._
try {
dumpWriter.write("==== BLOCKS ====\n")
dumpWriter.write(
GameData.getBlockRegistry
.map(GameData.getBlockRegistry.getNameForObject)
.toList
.sorted
.mkString("\n")
)
dumpWriter.write("\n\n")
dumpWriter.write("==== ITEMS ====\n")
dumpWriter.write(
GameData.getItemRegistry
.map(GameData.getItemRegistry.getNameForObject)
.toList
.sorted
.mkString("\n")
)
dumpWriter.write("\n\n")
dumpWriter.write("==== CUSTOM STACKS ====\n")
val stacksField = classOf[GameData].getDeclaredField("customItemStacks")
stacksField.setAccessible(true)
val stacksData =
stacksField.get(null).asInstanceOf[Table[String, String, ItemStack]]
dumpWriter.write(
stacksData
.cellSet()
.map(x => x.getRowKey + ":" + x.getColumnKey)
.toList
.sorted
.mkString("\n")
)
dumpWriter.write("\n\n")
dumpWriter.write("==== ORE DICT ====\n")
dumpWriter.write((OreDictionary.getOreNames.sorted flatMap { name =>
List(name) ++
(OreDictionary.getOres(name) map { ore =>
" - " + ore.toString
})
}).mkString("\n"))
dumpWriter.write("\n\n")
dumpWriter.write("==== FLUIDS ====\n")
dumpWriter.write(
FluidRegistry.getRegisteredFluids.map(_._1).toList.sorted.mkString("\n")
)
dumpWriter.write("\n\n")
CommandBase.func_152373_a(
sender,
this,
"Registry dumped to " + dumpFile.getCanonicalPath
)
} catch {
case e: Throwable =>
CommandBase.func_152373_a(
sender,
this,
"Failed to save registry dump: " + e
)
BdLib.logErrorException("Failed to save registry dump", e)
} finally {
dumpWriter.close()
}
}
}
@@ -0,0 +1,220 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib
import java.io.{BufferedWriter, File, FileWriter}
import cpw.mods.fml.common.registry.GameData
import cpw.mods.fml.relauncher.FMLInjectionData
import net.minecraft.command.{CommandBase, ICommandSender, WrongUsageException}
import net.minecraft.entity.player.EntityPlayerMP
import net.minecraft.item.Item
import net.minecraft.util.EnumChatFormatting
import net.minecraftforge.oredict.OreDictionary
import scala.collection.mutable
object CommandOreDistribution extends CommandBase {
def getCommandName = "oredistribution"
override def getRequiredPermissionLevel = 2
def getCommandUsage(c: ICommandSender) = "bdlib.oredistribution.usage"
def safeInt(s: String) =
try {
s.toInt
} catch {
case e: NumberFormatException =>
throw new WrongUsageException("bdlib.oredistribution.usage")
}
def wrapColor(s: String, c: EnumChatFormatting) =
c + s + EnumChatFormatting.RESET
def processCommand(sender: ICommandSender, baseParams: Array[String]) {
val (flags, params) = baseParams.partition(_.startsWith("--"))
if (params.length < 1 || params.length > 3)
throw new WrongUsageException(getCommandUsage(sender))
val (startX, startZ, world) =
sender match {
case p: EntityPlayerMP => (p.posX.toInt, p.posZ.toInt, p.worldObj)
case _ => (0, 0, sender.getEntityWorld)
}
val radius = safeInt(params.head)
val minY = if (params.length >= 2) safeInt(params(1)) else 0
val maxY =
if (params.length >= 3) safeInt(params(2)) else world.getHeight - 1
if (minY < 0 || radius <= 0 || minY > maxY || maxY > world.getHeight - 1)
throw new WrongUsageException(getCommandUsage(sender))
val toFile = flags.contains("--file")
// why java, WHY?
CommandBase.func_152373_a(
sender,
this,
"bdlib.oredistribution.start1",
Array[Integer](
startX - radius,
minY,
startZ - radius,
startX + radius,
maxY,
startZ + radius,
world.provider.dimensionId
): _*
)
CommandBase.func_152373_a(sender, this, "bdlib.oredistribution.start2")
import scala.collection.JavaConversions._
val ores = (OreDictionary.getOreNames.filter(x =>
x.startsWith("ore") || x.startsWith("denseore")
) flatMap { name =>
val fixedName =
if (name.startsWith("ore"))
name.substring(3)
else if (name.startsWith("denseore"))
"Dense " + name.substring(8)
else name
for (s <- OreDictionary.getOres(name))
yield (s.getItem, s.getItemDamage) -> fixedName
}).toMap
val distribution = mutable.Map.empty[String, Int].withDefaultValue(0)
val kinds =
mutable.Map.empty[String, Set[(Item, Int)]].withDefaultValue(Set.empty)
for {
x <- startX - radius to startX + radius
y <- minY to maxY
z <- startZ - radius to startZ + radius
if !world.isAirBlock(x, y, z)
} {
val key = (
Item.getItemFromBlock(world.getBlock(x, y, z)),
world.getBlockMetadata(x, y, z)
)
for (ore <- ores.get(key)) {
distribution(ore) += 1
kinds(ore) += key
}
}
val total = distribution.values.sum
val warnings = kinds.filter(_._2.size > 1)
if (toFile) {
// === OUTPUT TO FILE ===
val mcHome =
FMLInjectionData
.data()(6)
.asInstanceOf[File] // is there a better way to get this?
val dumpFile = new File(mcHome, "ore_distribution.txt")
val dumpWriter = new BufferedWriter(new FileWriter(dumpFile))
try {
dumpWriter.write(
"Ore distribution report - (%d,%d,%d) to (%d,%d,%d) dim %d".format(
startX - radius,
minY,
startZ - radius,
startX + radius,
maxY,
startZ + radius,
world.provider.dimensionId
)
)
dumpWriter.newLine()
dumpWriter.newLine()
if (warnings.nonEmpty) {
for ((id, types) <- warnings.toList.sortBy(_._1)) {
dumpWriter.write(
"Warning: %s has multiple variants generated:".format(id)
)
dumpWriter.newLine()
for ((item, dmg) <- types) {
dumpWriter.write(
" - %s@%s".format(
GameData.getItemRegistry.getNameForObject(item),
dmg
)
)
dumpWriter.newLine()
}
dumpWriter.newLine()
}
dumpWriter.write("=================")
dumpWriter.newLine()
dumpWriter.newLine()
}
for ((id, num) <- distribution.filter(_._2 > 0).toList.sortBy(-_._2)) {
dumpWriter.write(
"%s - %s (%s%%)".format(
id,
DecFormat.round(num),
DecFormat.short(100f * num / total)
)
)
dumpWriter.newLine()
}
CommandBase.func_152373_a(
sender,
this,
"bdlib.oredistribution.saved",
dumpFile.getCanonicalPath
)
} catch {
case e: Throwable =>
CommandBase.func_152373_a(
sender,
this,
"bdlib.oredistribution.error",
e.toString
)
BdLib.logErrorException("Failed to save ore distribution dump", e)
} finally {
dumpWriter.close()
}
} else {
// === OUTPUT TO CHAT ===
for ((id, types) <- warnings.toList.sortBy(_._1)) {
CommandBase.func_152373_a(
sender,
this,
"bdlib.oredistribution.warn",
wrapColor(" !", EnumChatFormatting.RED),
wrapColor(id, EnumChatFormatting.RED)
)
for ((item, dmg) <- types)
CommandBase.func_152373_a(
sender,
this,
wrapColor(" - ", EnumChatFormatting.RED) + GameData.getItemRegistry
.getNameForObject(item) + "@" + dmg
)
}
for ((id, num) <- distribution.filter(_._2 > 0).toList.sortBy(-_._2)) {
CommandBase.func_152373_a(
sender,
this,
"bdlib.oredistribution.entry",
" *",
wrapColor(id, EnumChatFormatting.YELLOW),
DecFormat.round(num),
DecFormat.short(100f * num / total)
)
}
}
}
}
@@ -0,0 +1,24 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib
import net.minecraft.creativetab.CreativeTabs
import net.minecraft.item.Item
class CreativeTabContainer {
class Tab(name: String, item: => Item) extends CreativeTabs(name) {
override def getTabIconItem = item
}
BdLib.logInfo("Loaded creative tabs for %s", Misc.getActiveModId)
def init() {}
}
@@ -0,0 +1,36 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib
import java.text.DecimalFormat
object DecFormat {
val thousandsFmt = new DecimalFormat("#,##0")
val dec2Fmt = new DecimalFormat("#,##0.00")
val dec1Fmt = new DecimalFormat("#,##0.0")
def round(x: Double) = thousandsFmt.format(x).replace('\u00A0', ' ')
def round(x: Float) = thousandsFmt.format(x).replace('\u00A0', ' ')
def round(x: Int) = thousandsFmt.format(x).replace('\u00A0', ' ')
def dec2(x: Double) = dec2Fmt.format(x).replace('\u00A0', ' ')
def dec2(x: Float) = dec2Fmt.format(x).replace('\u00A0', ' ')
def dec2(x: Int) = dec2Fmt.format(x).replace('\u00A0', ' ')
def short(x: Double) = (if (x > 10) thousandsFmt.format(x)
else if (x > 1) dec1Fmt.format(x)
else dec2Fmt.format(x)).replace('\u00A0', ' ')
def short(x: Float) = (if (x > 10) thousandsFmt.format(x)
else if (x > 1) dec1Fmt.format(x)
else dec2Fmt.format(x)).replace('\u00A0', ' ')
def short(x: Int) = (if (x > 10) thousandsFmt.format(x)
else if (x > 1) dec1Fmt.format(x)
else dec2Fmt.format(x)).replace('\u00A0', ' ')
}
@@ -4,7 +4,7 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib
@@ -12,7 +12,7 @@ package net.bdew.lib
class EventBase[T] extends {
var listeners = Seq.empty[T]
def listen(x: T) = listeners :+= x
def hasListeners = listeners.size > 0
def hasListeners = listeners.nonEmpty
}
class Event0 extends EventBase[() => Unit] {
@@ -28,7 +28,7 @@ class Event2[T, R] extends EventBase[(T, R) => Unit] {
}
object Event {
def apply(t: Unit) = new Event0
def apply() = new Event0
def apply[T] = new Event1[T]
def apply[T, R] = new Event2[T, R]
}
}
+209
View File
@@ -0,0 +1,209 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib
import java.util
import java.util.Locale
import cpw.mods.fml.common.registry.GameRegistry
import cpw.mods.fml.common.versioning.VersionParser
import cpw.mods.fml.common.{Loader, ModAPIManager, ModContainer}
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.tileentity.TileEntity
import net.minecraft.util.{IIcon, StatCollector}
import net.minecraft.world.biome.BiomeGenBase
import net.minecraftforge.common.util.ForgeDirection
import net.minecraftforge.fluids.{Fluid, FluidStack}
import net.minecraftforge.oredict.ShapedOreRecipe
object Misc {
def getActiveModId = Option(
Loader.instance().activeModContainer().getModId
) getOrElse "<UNKNOWN>"
def toLocal(s: String) = StatCollector.translateToLocal(s)
def toLocalF(s: String, params: Any*) =
StatCollector.translateToLocal(s).format(params: _*)
def hasLocal(s: String) = StatCollector.canTranslate(s)
def flattenRecipe(pattern: Seq[String], items: Map[Char, AnyRef]) =
pattern ++ items.flatMap { case (k, v) =>
Seq(new Character(k), v)
}
def wrapTag(n: String, f: (NBTTagCompound) => Any)(t: NBTTagCompound) {
val p = t.getCompoundTag(n)
f(p)
t.setTag(n, p)
}
def addRecipe(
result: ItemStack,
pattern: Seq[String],
items: Map[Char, AnyRef]
) =
GameRegistry.addRecipe(result, flattenRecipe(pattern, items): _*)
def addRecipeOD(
result: ItemStack,
pattern: Seq[String],
items: Map[Char, AnyRef]
) =
GameRegistry.addRecipe(
new ShapedOreRecipe(result, flattenRecipe(pattern, items): _*)
)
def min[T: Ordering](values: T*) = values.min
def max[T: Ordering](values: T*) = values.max
def clamp[T](value: T, min: T, max: T)(implicit o: Ordering[T]): T =
if (o.gt(value, max)) max else if (o.lt(value, min)) min else value
def iterSome[T](list: Seq[T], indexes: Iterable[Int]): Iterable[T] = for (
i <- indexes
) yield list(i)
def iterSomeEnum[T](
list: Seq[T],
indexes: Iterable[Int]
): Iterable[(Int, T)] = for (i <- indexes) yield i -> list(i)
def filterType[T](from: Iterable[_], cls: Class[T]) =
from.filter(cls.isInstance).asInstanceOf[Iterable[T]]
def getBiomeByName(name: String) = BiomeGenBase.getBiomeGenArray
.find(x => x != null && x.biomeName == name)
.orNull
private lazy val modLookup = {
val mods = new util.ArrayList[ModContainer]
val nameLookup = new util.HashMap[String, ModContainer]
nameLookup.putAll(Loader.instance().getIndexedModList)
ModAPIManager.INSTANCE.injectAPIModContainers(mods, nameLookup)
import scala.collection.JavaConverters._
nameLookup.asScala
}
def haveModVersion(modId: String) = {
val spec = VersionParser.parseVersionReference(modId)
modLookup.contains(spec.getLabel) && spec.containsVersion(
modLookup(spec.getLabel).getProcessedVersion
)
}
def getModVersion(modId: String) =
modLookup.get(modId) map (_.getVersion)
def getModVersionString(modId: String): String = {
val cont = modLookup.getOrElse(modId, return "NOT FOUND")
cont.getModId + " " + cont.getVersion
}
// Because writing this every time is awkward
def forgeDirection(i: Int) = ForgeDirection.values()(i)
// Easy replacement for various "if(foo.isInstanceOf[Bar]) foo.asInstanceOf[Bar]" constructs
def asInstanceOpt[T](v: Any, cls: Class[T]) =
if (cls.isInstance(v)) Some(v.asInstanceOf[T]) else None
// Same thing but in a way that's easier to use with map, etc.
def asInstanceOpt[T](cls: Class[T])(v: Any) =
if (cls.isInstance(v)) Some(v.asInstanceOf[T]) else None
def getNeighbourTile[T](
origin: TileEntity,
dir: ForgeDirection,
cls: Class[T]
) =
Option(
origin.getWorldObj.getTileEntity(
origin.xCoord + dir.offsetX,
origin.yCoord + dir.offsetY,
origin.zCoord + dir.offsetZ
)
) flatMap (asInstanceOpt(_, cls))
@inline def applyMutator[T](f: (T) => Unit, init: T): T = {
f(init)
init
}
@inline def applyMutator[T](init: T)(f: (T) => Unit) = {
f(init)
init
}
def nextInSeq[T](seq: Seq[T], elem: T) = {
val pos = seq.indexOf(elem)
if (pos < 0 || pos == seq.size - 1)
seq.head
else
seq(pos + 1)
}
def prevInSeq[T](seq: Seq[T], elem: T) = {
val pos = seq.indexOf(elem)
if (pos <= 0)
seq.last
else
seq(pos - 1)
}
def getFluidIcon(fs: FluidStack): IIcon =
if (fs != null && fs.getFluid != null && fs.getFluid.getIcon != null)
fs.getFluid.getIcon(fs)
else
Client.blockMissingIcon
def getFluidIcon(f: Fluid): IIcon =
if (f != null) getFluidIcon(new FluidStack(f, 1))
else Client.blockMissingIcon
def getFluidColor(fs: FluidStack): Int =
if (fs != null && fs.getFluid != null) fs.getFluid.getColor(fs)
else 0xffffff
def getFluidColor(f: Fluid): Int =
if (f != null) getFluidColor(new FluidStack(f, 1)) else 0xffffff
lazy val lineSeparator = System.getProperty("line.separator")
/** Provides something like java try-with-resources in scala
*/
def withAutoClose[T <: AutoCloseable, R](o: T)(f: T => R): R = {
val res =
try {
f(o)
} catch {
case t1: Throwable =>
if (o != null) {
try {
o.close()
} catch {
case t2: Throwable =>
t1.addSuppressed(t2)
}
}
throw t1
}
if (o != null)
o.close()
res
}
def iconName(domain: String, name: String, path: String*) =
if (path.isEmpty)
"%s:%s".format(domain, name).toLowerCase(Locale.US)
else
"%s:%s/%s".format(domain, name, path.mkString("/")).toLowerCase(Locale.US)
}
@@ -0,0 +1,30 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.async
import scala.concurrent.{Future, Promise}
object Async {
def inOtherThread[T](f: => T) = {
val p = Promise[T]()
val t = new Thread(new Runnable {
override def run(): Unit =
try {
p.success(f)
} catch {
case t: Throwable => p.failure(t)
}
})
t.start()
p.future
}
def inServerThread[T](f: => T) = Future(f)(ServerTickExecutionContext)
}
@@ -0,0 +1,55 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.async
import cpw.mods.fml.common.FMLCommonHandler
import cpw.mods.fml.common.eventhandler.SubscribeEvent
import cpw.mods.fml.common.gameevent.TickEvent.ServerTickEvent
import net.bdew.lib.BdLib
import scala.collection.mutable
import scala.concurrent.ExecutionContext
object ServerTickExecutionContext extends ExecutionContext {
private val queue = mutable.Queue.empty[Runnable]
FMLCommonHandler.instance.bus.register(this)
BdLib.logDebug("Installed ServerTickExecutionContext")
private def getNextBatch = this.synchronized {
if (queue.nonEmpty) {
val res = queue.toList
queue.clear()
res
} else List.empty
}
override def execute(runnable: Runnable): Unit =
this.synchronized {
queue += runnable
}
override def reportFailure(cause: Throwable): Unit =
BdLib.logErrorException("Error in execution context", cause)
def doSingleLoop(): Unit = {
for (r <- getNextBatch) {
try {
r.run()
} catch {
case t: Throwable => reportFailure(t)
}
}
}
@SubscribeEvent
def onTick(ev: ServerTickEvent): Unit = doSingleLoop()
}
@@ -0,0 +1,23 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.block
import net.minecraftforge.common.util.ForgeDirection
case class BlockFace(x: Int, y: Int, z: Int, face: ForgeDirection) {
def origin = BlockRef(x, y, z)
def target = origin.neighbour(face)
def opposite = face.getOpposite
}
object BlockFace {
def apply(bp: BlockRef, face: ForgeDirection) =
new BlockFace(bp.x, bp.y, bp.z, face)
}
@@ -0,0 +1,66 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.block
import net.minecraft.block.Block
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.tileentity.TileEntity
import net.minecraft.world.IBlockAccess
import net.minecraftforge.common.util.ForgeDirection
import scala.reflect.ClassTag
case class BlockRef(x: Int, y: Int, z: Int) {
def isValid(w: IBlockAccess) =
y >= 0 && y < 256 // hardcoded because getHeight is unavailable on servers :(
def block(w: IBlockAccess) =
if (isValid(w)) Option(w.getBlock(x, y, z)) else None
def tile(w: IBlockAccess) =
if (isValid(w)) Option(w.getTileEntity(x, y, z)) else None
def meta(w: IBlockAccess) = if (isValid(w)) w.getBlockMetadata(x, y, z) else 0
def blockIs(w: IBlockAccess, other: Block) = block(w).contains(other)
def neighbour(side: ForgeDirection) =
BlockRef(x + side.offsetX, y + side.offsetY, z + side.offsetZ)
def neighbours =
ForgeDirection.VALID_DIRECTIONS.map(x => x -> neighbour(x)).toMap
override def toString = "(x=%d y=%d z=%d)".format(x, y, z)
def getTile[T: ClassTag](w: IBlockAccess) = tile(w) flatMap { tile =>
val cls = implicitly[ClassTag[T]].runtimeClass
if (cls.isInstance(tile))
Some(tile.asInstanceOf[T])
else None
}
def ==(tx: Int, ty: Int, tz: Int) = x == tx && y == ty && z == tz
def getBlock[T: ClassTag](w: IBlockAccess) = block(w) flatMap { block =>
val cls = implicitly[ClassTag[T]].runtimeClass
if (cls.isInstance(block))
Some(block.asInstanceOf[T])
else None
}
def writeToNBT(tag: NBTTagCompound) {
tag.setInteger("x", x)
tag.setInteger("y", y)
tag.setInteger("z", z)
}
}
object BlockRef {
def fromTile(te: TileEntity) = BlockRef(te.xCoord, te.yCoord, te.zCoord)
def fromNBT(tag: NBTTagCompound) =
BlockRef(tag.getInteger("x"), tag.getInteger("y"), tag.getInteger("z"))
}
@@ -0,0 +1,20 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.block
import net.minecraft.block.Block
import net.minecraft.item.ItemBlock
/** If defined on a block - defines a custom ItemBlock class that will be used
* when registering Supported by BlockManager and Machine
*/
trait HasItemBlock extends Block {
def ItemBlockClass: Class[_ <: ItemBlock]
}
@@ -4,27 +4,38 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.block
import net.minecraft.block.{ITileEntityProvider, Block}
import net.minecraft.world.{IBlockAccess, World}
import net.bdew.lib.BdLib
import net.minecraft.block.{Block, ITileEntityProvider}
import net.minecraft.tileentity.TileEntity
import cpw.mods.fml.common.FMLCommonHandler
import net.minecraft.world.{IBlockAccess, World}
trait HasTE[T] extends Block with ITileEntityProvider {
val TEClass: Class[_ <: TileEntity]
def createNewTileEntity(world: World): TileEntity = TEClass.newInstance()
def createNewTileEntity(world: World, meta: Int): TileEntity =
TEClass.newInstance()
def getTE(w: IBlockAccess, ref: BlockRef): T = getTE(w, ref.x, ref.y, ref.z)
def getTE(w: IBlockAccess, x: Int, y: Int, z: Int): T = {
var t = w.getBlockTileEntity(x, y, z)
var t = w.getTileEntity(x, y, z)
if ((t == null) || !TEClass.isInstance(t)) {
FMLCommonHandler.instance().getFMLLogger.severe("Tile entity for block %s at (%d,%d,%d) is corrupt or missing - recreating".format(this, x, y, z))
BdLib.logError(
"Tile entity for block %s at (%d,%d,%d) is corrupt or missing - recreating",
this,
x,
y,
z
)
w match {
case ww: World =>
t = createNewTileEntity(ww)
ww.setBlockTileEntity(x, y, z, t)
t = createNewTileEntity(ww, w.getBlockMetadata(x, y, z))
ww.setTileEntity(x, y, z, t)
case _ =>
sys.error("Unable to recreate TE")
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.block
import java.util
import net.minecraft.block.Block
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.{ItemBlock, ItemStack}
trait BlockTooltip extends Block with HasItemBlock {
override val ItemBlockClass: Class[_ <: ItemBlock] = classOf[ItemBlockTooltip]
def getTooltip(
stack: ItemStack,
player: EntityPlayer,
advanced: Boolean
): List[String]
}
class ItemBlockTooltip(b: Block) extends ItemBlock(b) {
override def addInformation(
stack: ItemStack,
player: EntityPlayer,
list: util.List[_],
advanced: Boolean
): Unit = {
import scala.collection.JavaConversions._
if (b.isInstanceOf[BlockTooltip])
list
.asInstanceOf[util.List[String]]
.addAll(
b.asInstanceOf[BlockTooltip].getTooltip(stack, player, advanced)
)
}
}
@@ -0,0 +1,181 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.block
import java.util
import net.bdew.lib.nbt.NBT
import net.bdew.lib.tile.TileExtended
import net.minecraft.block.Block
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.MovingObjectPosition
import net.minecraft.world.World
/** Mixin for blocks to keep their data when broken Must have a TileEntity that
* extends TileKeepData
*/
trait BlockKeepData extends Block with HasItemBlock {
this: HasTE[_ <: TileKeepData] =>
override val ItemBlockClass: Class[_ <: ItemBlockKeepData] =
classOf[ItemBlockKeepData]
def getSavedBlock(world: World, x: Int, y: Int, z: Int, metadata: Int) = {
val stack = new ItemStack(
getItemDropped(metadata, world.rand, 0),
1,
damageDropped(metadata)
)
getTE(world, x, y, z).saveToItem(stack)
stack
}
override def getDrops(
world: World,
x: Int,
y: Int,
z: Int,
metadata: Int,
fortune: Int
): util.ArrayList[ItemStack] = {
val drops = new util.ArrayList[ItemStack]()
drops.add(getSavedBlock(world, x, y, z, metadata))
drops
}
override def removedByPlayer(
world: World,
player: EntityPlayer,
x: Int,
y: Int,
z: Int,
willHarvest: Boolean
): Boolean =
if (willHarvest)
true
else
super.removedByPlayer(world, player, x, y, z, willHarvest)
override def harvestBlock(
world: World,
player: EntityPlayer,
x: Int,
y: Int,
z: Int,
meta: Int
): Unit = {
super.harvestBlock(world, player, x, y, z, meta)
world.setBlockToAir(x, y, z)
}
override def getPickBlock(
target: MovingObjectPosition,
world: World,
x: Int,
y: Int,
z: Int,
player: EntityPlayer
): ItemStack = {
getSavedBlock(world, x, y, z, world.getBlockMetadata(x, y, z))
}
/** Override for special actions on placing ItemStack might or might not
* contain actual data Called with the TE created and added to world, after
* onBlockPlacedBy & co
*/
def restoreTileEntity(
world: World,
x: Int,
y: Int,
z: Int,
is: ItemStack,
player: EntityPlayer
) = getTE(world, x, y, z).loadFromItem(is)
}
/** Mixin for tile entities to keep their data when broken Block class has to
* extend BlockKeepData
*/
trait TileKeepData extends TileExtended {
/** Override to modify data that will be stored in an item
* @param t
* Automatically serialized data
* @return
* Modified serialized data
*/
def afterTileBreakSave(t: NBTTagCompound) = t
/** Override to modify data that will be load from an item After the tile
* entity is fully constructed and added to world
* @param t
* Automatically serialized data
* @return
* Modified serialized data
*/
def beforeTileBreakLoad(t: NBTTagCompound) = t
final def saveToItem(is: ItemStack): Unit = {
if (!is.hasTagCompound) is.setTagCompound(new NBTTagCompound)
is.getTagCompound.setTag(
"data",
afterTileBreakSave(NBT.from(persistSave.trigger))
)
}
final def loadFromItem(is: ItemStack): Unit = {
if (is.hasTagCompound && is.getTagCompound.hasKey("data")) {
persistLoad.trigger(
beforeTileBreakLoad(is.getTagCompound.getCompoundTag("data"))
)
}
}
}
/** Custom ItemBlock that handles loading data to the Tile Entity
*/
class ItemBlockKeepData(b: Block) extends ItemBlockTooltip(b) {
override def placeBlockAt(
stack: ItemStack,
player: EntityPlayer,
world: World,
x: Int,
y: Int,
z: Int,
side: Int,
hitX: Float,
hitY: Float,
hitZ: Float,
metadata: Int
): Boolean = {
if (
super.placeBlockAt(
stack,
player,
world,
x,
y,
z,
side,
hitX,
hitY,
hitZ,
metadata
)
) {
if (!world.isRemote && b.isInstanceOf[BlockKeepData])
b.asInstanceOf[BlockKeepData]
.restoreTileEntity(world, x, y, z, stack, player)
true
} else false
}
}
@@ -0,0 +1,34 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.block
import cpw.mods.fml.relauncher.{Side, SideOnly}
import net.bdew.lib.Misc
import net.minecraft.block.Block
import net.minecraft.block.material.Material
import net.minecraft.client.renderer.texture.IIconRegister
import scala.language.implicitConversions
trait NamedBlock extends Block {
def name: String
}
class SimpleBlock(val name: String, material: Material)
extends Block(material)
with NamedBlock {
val modId = Misc.getActiveModId
setBlockName(modId + "." + name)
@SideOnly(Side.CLIENT)
override def registerBlockIcons(reg: IIconRegister) {
blockIcon = reg.registerIcon(Misc.iconName(modId, name))
}
}
@@ -0,0 +1,78 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.config
import cpw.mods.fml.common.ObfuscationReflectionHelper
import cpw.mods.fml.common.registry.GameRegistry
import net.bdew.lib.Misc
import net.bdew.lib.block.{HasItemBlock, HasTE, NamedBlock}
import net.minecraft.block.Block
import net.minecraft.creativetab.CreativeTabs
import net.minecraft.item.{ItemBlock, ItemStack}
import net.minecraft.tileentity.TileEntity
class BlockManager(creativeTab: CreativeTabs) {
def regBlock[T <: NamedBlock](block: T): T = regBlock(block, block.name)
def regSpecial[T <: NamedBlock](
block: T,
addStack: Boolean = false,
skipTileEntityReg: Boolean = false
): T =
regBlock(block, block.name, addStack, skipTileEntityReg)
def regBlock[T <: Block](
block: T,
name: String,
addStack: Boolean = false,
skipTileEntityReg: Boolean = false
): T = {
val itemClass: Class[_ <: ItemBlock] =
if (block.isInstanceOf[HasItemBlock])
block.asInstanceOf[HasItemBlock].ItemBlockClass
else
classOf[ItemBlock]
GameRegistry.registerBlock(block, itemClass, name)
block.setCreativeTab(creativeTab)
if (addStack)
GameRegistry.registerCustomItemStack(name, new ItemStack(block))
if (block.isInstanceOf[HasTE[_]] && !skipTileEntityReg)
GameRegistry.registerTileEntity(
block.asInstanceOf[HasTE[_]].TEClass,
"%s.%s".format(Misc.getActiveModId, name)
)
return block
}
/** Registers a legacy TE name->class mapping. Stolen from
* GameRegistry.registerTileEntityWithAlternatives
*/
def registerLegacyTileEntity(
name: String,
cls: Class[_ <: TileEntity]
): Unit = {
val teMappings: java.util.Map[String, Class[_]] =
ObfuscationReflectionHelper.getPrivateValue(
classOf[TileEntity],
null,
"field_" + "145855_i",
"nameToClassMap"
)
if (!teMappings.containsKey(name))
teMappings.put(name, cls)
}
def load() {}
}
@@ -4,14 +4,14 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.config
import net.minecraftforge.fluids.{FluidRegistry, Fluid}
import net.minecraftforge.fluids.{Fluid, FluidRegistry}
class FluidManager(val ids: IdManager) {
class FluidManager() {
def regFluid[T <: Fluid](fluid: T): T = {
FluidRegistry.registerFluid(fluid)
return fluid
@@ -0,0 +1,36 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.config
import cpw.mods.fml.common.registry.GameRegistry
import net.bdew.lib.items.{NamedItem, SimpleItem}
import net.minecraft.creativetab.CreativeTabs
import net.minecraft.item.{Item, ItemStack}
class ItemManager(creativeTab: CreativeTabs) {
def regSimpleItem(name: String): SimpleItem =
regItem(new SimpleItem(name), name)
def regItem[T <: NamedItem](item: T): T = regItem[T](item, item.name)
def regItem[T <: Item](
item: T,
name: String,
addStack: Boolean = false
): T = {
GameRegistry.registerItem(item, name)
item.setCreativeTab(creativeTab)
if (addStack)
GameRegistry.registerCustomItemStack(name, new ItemStack(item))
return item
}
def load() {}
}
@@ -0,0 +1,59 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.config
import net.bdew.lib.Misc
import net.bdew.lib.gui.{GuiHandler, GuiProvider}
import net.bdew.lib.machine.Machine
import net.bdew.lib.multiblock.MachineCore
import net.bdew.lib.multiblock.block.BlockModule
import net.bdew.lib.recipes.gencfg.ConfigSection
import net.minecraft.creativetab.CreativeTabs
class MachineManager(
val tuning: ConfigSection,
guiHandler: GuiHandler,
creativeTab: CreativeTabs
) {
def registerMachine[R <: Machine[_]](machine: R): R = {
machine.tuning = tuning.getSection(machine.name)
if (machine.tuning.getBoolean("Enabled")) {
machine.enabled = true
machine.regBlock(creativeTab)
if (machine.isInstanceOf[GuiProvider])
guiHandler.register(machine.asInstanceOf[GuiProvider])
}
return machine
}
def load() {}
}
trait MachineManagerMultiblock extends MachineManager {
var controllers = Set.empty[MachineCore]
override def registerMachine[R <: Machine[_]](machine: R): R = {
super.registerMachine(machine)
if (machine.enabled) {
Misc.asInstanceOpt(machine, classOf[MachineCore]) foreach {
controllerMachine =>
controllers += controllerMachine
controllerMachine.getController.machine = controllerMachine
}
}
machine
}
def getMachinesForBlock(b: BlockModule[_]): Map[MachineCore, (Int, Int)] = {
(for (machine <- controllers; max <- machine.modules.get(b.kind)) yield {
machine -> (machine.required.getOrElse(b.kind, 0), max)
}).toMap
}
}
@@ -0,0 +1,182 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.covers
import cpw.mods.fml.relauncher.{Side, SideOnly}
import net.bdew.lib.Misc
import net.bdew.lib.block.{BlockRef, HasTE}
import net.bdew.lib.items.ItemUtils
import net.minecraft.block.Block
import net.minecraft.entity.player.{EntityPlayer, EntityPlayerMP}
import net.minecraft.item.ItemStack
import net.minecraft.util.IIcon
import net.minecraft.world.{IBlockAccess, World}
import net.minecraftforge.common.util.ForgeDirection
trait BlockCoverable[T <: TileCoverable] extends HasTE[T] {
@SideOnly(Side.CLIENT)
override def getRenderType = CoverRenderer.id
private def getCoverItem(
w: IBlockAccess,
x: Int,
y: Int,
z: Int,
side: ForgeDirection
): Option[(ItemCover, ItemStack, TileCoverable)] = {
val te = getTE(w, x, y, z)
for {
coverStack <- Option(te.covers(side).value)
coverItemMaybe <- Option(coverStack.getItem)
coverItem <- Misc.asInstanceOpt(coverItemMaybe, classOf[ItemCover])
} yield (coverItem, coverStack, te)
}
override def onBlockActivated(
world: World,
x: Int,
y: Int,
z: Int,
player: EntityPlayer,
face: Int,
xOffs: Float,
yOffs: Float,
zOffs: Float
): Boolean = {
val te = getTE(world, x, y, z)
val side = Misc.forgeDirection(face)
// Shift+RightClick with empty hand should remove cover
if (player.getCurrentEquippedItem == null && player.isSneaking) {
for {
cover <- Option(te.covers(side).value)
coverItem <- Misc.asInstanceOpt(cover.getItem, classOf[ItemCover])
} {
if (!world.isRemote) {
te.covers(side) := null
te.onCoversChanged()
coverChanged(world, x, y, z, side)
ItemUtils.dropItemToPlayer(world, player, coverItem.onRemove(cover))
}
return true
}
}
// If held item is cover - try to install it
for {
activeStack <- Option(player.getCurrentEquippedItem)
activeItem <- Option(activeStack.getItem)
coverItem <- Misc.asInstanceOpt(activeItem, classOf[ItemCover])
if te.isValidCover(side, activeStack) && coverItem.isValidTile(
te,
activeStack
)
} {
if (!world.isRemote && player.isInstanceOf[EntityPlayerMP]) {
for {
oldCover <- Option(te.covers(side).value)
oldItem <- Misc.asInstanceOpt(oldCover.getItem, classOf[ItemCover])
} {
ItemUtils.throwItemAt(
world,
te.xCoord + side.offsetX,
te.yCoord + side.offsetY,
te.zCoord + side.offsetZ,
oldItem.onRemove(oldCover)
)
}
te.covers(side) := coverItem.onInstall(
te,
side,
activeStack.splitStack(1),
player.asInstanceOf[EntityPlayerMP]
)
if (activeStack.stackSize <= 0)
player.inventory.setInventorySlotContents(
player.inventory.currentItem,
null
)
te.onCoversChanged()
coverChanged(world, x, y, z, side)
}
return true
}
// If has cover - let it handle the click
for ((item, stack, te) <- getCoverItem(world, x, y, z, side)) {
if (item.clickCover(te, side, stack, player)) return true
}
super.onBlockActivated(world, x, y, z, player, face, xOffs, yOffs, zOffs)
}
override def canProvidePower = true
override def isProvidingWeakPower(
w: IBlockAccess,
x: Int,
y: Int,
z: Int,
side: Int
): Int = {
val direction = Misc.forgeDirection(side).getOpposite
for ((item, stack, te) <- getCoverItem(w, x, y, z, direction)) {
if (item.isEmittingSignal(te, direction, stack)) return 15
}
0
}
def coverChanged(
w: World,
x: Int,
y: Int,
z: Int,
side: ForgeDirection
): Unit = {
val pos = BlockRef(x, y, z).neighbour(side)
w.notifyBlockOfNeighborChange(pos.x, pos.y, pos.z, pos.block(w).orNull)
}
def getCoverIcon(
w: IBlockAccess,
x: Int,
y: Int,
z: Int,
side: ForgeDirection
): Option[IIcon] =
for ((item, stack, te) <- getCoverItem(w, x, y, z, side))
yield item.getCoverIcon(te, side, stack)
override def breakBlock(
world: World,
x: Int,
y: Int,
z: Int,
block: Block,
meta: Int
) {
if (!world.isRemote) {
val te = getTE(world, x, y, z)
for {
(dir, covOpt) <- te.covers
cover <- Option(covOpt.value)
item <- Misc.asInstanceOpt(cover.getItem, classOf[ItemCover])
} {
te.covers(dir) := null
ItemUtils.throwItemAt(world, x, y, z, item.onRemove(cover))
coverChanged(world, x, y, z, dir)
}
}
super.breakBlock(world, x, y, z, block, meta)
}
}
@@ -0,0 +1,56 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.covers
import net.bdew.lib.Misc
import net.bdew.lib.render.connected.ConnectedHelper
import net.bdew.lib.render.{BaseBlockRenderHandler, RenderUtils}
import net.minecraft.block.Block
import net.minecraft.client.renderer.RenderBlocks
import net.minecraft.world.IBlockAccess
import net.minecraftforge.common.util.ForgeDirection
object CoverRenderer extends BaseBlockRenderHandler {
override def renderInventoryBlock(
block: Block,
metadata: Int,
modelId: Int,
renderer: RenderBlocks
) =
RenderUtils.renderSimpleBlockItem(block, metadata, renderer)
override def renderWorldBlock(
world: IBlockAccess,
x: Int,
y: Int,
z: Int,
block: Block,
modelId: Int,
renderer: RenderBlocks
) = {
renderer.renderStandardBlock(block, x, y, z)
if (!renderer.hasOverrideBlockTexture)
for {
blockCov <- Misc.asInstanceOpt(block, classOf[BlockCoverable[_]])
face <- ForgeDirection.VALID_DIRECTIONS
icon <- blockCov.getCoverIcon(world, x, y, z, face)
if block.shouldSideBeRendered(
world,
x + face.offsetX,
y + face.offsetY,
z + face.offsetZ,
face.ordinal()
)
} ConnectedHelper
.draw(face, 8)
.doDraw(ConnectedHelper.Vec3F(x, y, z), icon)
true
}
}
@@ -0,0 +1,125 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.covers
import net.minecraft.entity.player.{EntityPlayer, EntityPlayerMP}
import net.minecraft.item.{Item, ItemStack}
import net.minecraft.util.IIcon
import net.minecraftforge.common.util.ForgeDirection
trait ItemCover extends Item {
/** @return
* true if tickCover should be called
*/
def isCoverTicking: Boolean
/** @param te
* Host TileEntity
* @param side
* Side the cover is installed on
* @param cover
* Cover ItemStack
* @return
* Icon to render, MUST be on terrain sprite sheet (0), not item!
*/
def getCoverIcon(
te: TileCoverable,
side: ForgeDirection,
cover: ItemStack
): IIcon
/** Perform tick, called on server only
* @param te
* Host TileEntity
* @param side
* Side the cover is installed on
* @param cover
* Cover ItemStack
*/
def tickCover(
te: TileCoverable,
side: ForgeDirection,
cover: ItemStack
): Unit = {}
/** Checks if this cover can be installed on a specific TE
* @param te
* Potential host TileEntity
* @param cover
* Cover ItemStack
* @return
* true if can be installed
*/
def isValidTile(te: TileCoverable, cover: ItemStack): Boolean
/** Handle click on covered side - called on both client and server
* @param te
* Host TileEntity
* @param side
* Side the cover is installed on
* @param cover
* Cover ItemStack
* @param player
* Player clicking the cover
* @return
* true if click was handled by cover
*/
def clickCover(
te: TileCoverable,
side: ForgeDirection,
cover: ItemStack,
player: EntityPlayer
): Boolean = false
/** Check if cover is emitting RS signal
* @param te
* Host TileEntity
* @param side
* Side the cover is installed on
* @param cover
* Cover ItemStack
* @return
* true if cover is emitting RS signal
*/
def isEmittingSignal(
te: TileCoverable,
side: ForgeDirection,
cover: ItemStack
): Boolean = false
/** Called when cover is installed on a block - called only on server
* @param te
* Host TileEntity
* @param side
* Side the cover is installed on
* @param cover
* Cover ItemStack - do not modify!
* @param player
* Player entity doing the installation
* @return
* cover ItemStack - copy if modified
*/
def onInstall(
te: TileCoverable,
side: ForgeDirection,
cover: ItemStack,
player: EntityPlayerMP
): ItemStack = cover
/** Called when cover is removed from block or block is destroyed - called
* only on server
* @param cover
* Cover ItemStack - do not modify!
* @return
* cover ItemStack - copy if modified
*/
def onRemove(cover: ItemStack): ItemStack = cover
}
@@ -4,37 +4,41 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.covers
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots}
import net.minecraftforge.common.ForgeDirection
import net.bdew.lib.data.DataSlotItemStack
import java.util.Locale
import net.bdew.lib.Misc
import net.bdew.lib.data.DataSlotItemStack
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind}
import net.minecraft.item.ItemStack
import net.minecraftforge.common.util.ForgeDirection
trait TileCoverable extends TileDataSlots {
val covers = (ForgeDirection.VALID_DIRECTIONS map { x =>
x -> DataSlotItemStack("cover_" + x.toString.toLowerCase, this).setUpdate(UpdateKind.SAVE, UpdateKind.WORLD, UpdateKind.RENDER)
x -> DataSlotItemStack("cover_" + x.toString.toLowerCase(Locale.US), this)
.setUpdate(UpdateKind.SAVE, UpdateKind.WORLD, UpdateKind.RENDER)
}).toMap
/**
* Checks if a specific cover can be installed here
*/
/** Checks if a specific cover can be installed here
*/
def isValidCover(side: ForgeDirection, cover: ItemStack): Boolean
/**
* Called when new covers are installed
*/
/** Called when new covers are installed
*/
def onCoversChanged() {}
def tickCovers() =
for {
(dir, coverSlot) <- covers
coverStack <- Option(coverSlot.cval)
coverItem <- Option(coverStack.getItem) flatMap (Misc.asInstanceOpt(_, classOf[ItemCover]))
coverStack <- Option(coverSlot.value)
coverItem <- Option(coverStack.getItem) flatMap (Misc.asInstanceOpt(
_,
classOf[ItemCover]
))
} {
coverItem.tickCover(this, dir, coverStack)
}
@@ -0,0 +1,25 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
case class DataSlotBoolean(
name: String,
parent: DataSlotContainer,
default: Boolean = false
) extends DataSlotVal[Boolean] {
var value = default
def save(t: NBTTagCompound, kind: UpdateKind.Value) =
t.setBoolean(name, value)
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value =
t.getBoolean(name)
}
@@ -0,0 +1,23 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.ForgeDirection
case class DataSlotDirection(name: String, parent: DataSlotContainer)
extends DataSlotVal[ForgeDirection] {
var value = ForgeDirection.UP
def save(t: NBTTagCompound, kind: UpdateKind.Value) =
t.setByte(name, value.ordinal().toByte)
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value =
ForgeDirection.getOrientation(t.getByte(name))
}
@@ -0,0 +1,23 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotNumeric, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
case class DataSlotDouble(
name: String,
parent: DataSlotContainer,
default: Double = 0
) extends DataSlotNumeric[Double](default) {
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setDouble(name, value)
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value =
t.getDouble(name)
}
@@ -0,0 +1,22 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotNumeric, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
case class DataSlotFloat(
name: String,
parent: DataSlotContainer,
default: Float = 0
) extends DataSlotNumeric[Float](default) {
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setFloat(name, value)
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value = t.getFloat(name)
}
@@ -0,0 +1,32 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlotContainer, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.fluids.{Fluid, FluidRegistry}
case class DataSlotFluidOption(name: String, parent: DataSlotContainer)
extends DataSlotOption[Fluid] {
setUpdate(UpdateKind.SAVE, UpdateKind.GUI)
override def save(t: NBTTagCompound, kind: UpdateKind.Value) {
value foreach { x => t.setString(name, x.getName) }
}
override def load(t: NBTTagCompound, kind: UpdateKind.Value): Unit = {
if (t.hasKey(name)) {
val fluidName = t.getString(name)
if (FluidRegistry.isFluidRegistered(fluidName)) {
value = Option(FluidRegistry.getFluid(fluidName))
} else unset()
} else unset()
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data
import java.util.UUID
import com.mojang.authlib.GameProfile
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
import org.apache.commons.lang3.StringUtils
case class DataSlotGameProfile(name: String, parent: DataSlotContainer)
extends DataSlotVal[GameProfile] {
override var value: GameProfile = null
override def load(t: NBTTagCompound, kind: UpdateKind.Value) = {
value = if (t.hasKey(name + "_uid") || t.hasKey(name + "_name")) {
val uId =
if (t.hasKey(name + "_uid")) UUID.fromString(t.getString(name + "_uid"))
else null
val uName =
if (t.hasKey(name + "_name")) t.getString(name + "_name") else null
new GameProfile(uId, uName)
} else null
}
override def save(t: NBTTagCompound, kind: UpdateKind.Value) = {
if (value != null) {
Option(value.getId) foreach (id =>
t.setString(name + "_uid", id.toString)
)
Option(value.getName) filterNot (name =>
StringUtils.isBlank(name)
) foreach (name => t.setString(name + "_name", name))
}
}
}
@@ -0,0 +1,24 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotNumeric, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
case class DataSlotInt(
name: String,
parent: DataSlotContainer,
default: Int = 0
) extends DataSlotNumeric[Int](default) {
def save(t: NBTTagCompound, kind: UpdateKind.Value) =
t.setInteger(name, value)
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value =
t.getInteger(name)
}
@@ -0,0 +1,46 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
import net.bdew.lib.tile.inventory.BaseInventory
import net.minecraft.item.ItemStack
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
case class DataSlotInventory(name: String, parent: DataSlotContainer, size: Int)
extends DataSlot
with BaseInventory {
setUpdate(UpdateKind.SAVE)
override def getSizeInventory = size
override def markDirty() = parent.dataSlotChanged(this)
override def load(t: NBTTagCompound, kind: UpdateKind.Value) {
inv = new Array[ItemStack](getSizeInventory)
import net.bdew.lib.nbt._
for (nbtItem <- t.getList[NBTTagCompound](name)) {
val slot = nbtItem.getByte("Slot")
if (slot >= 0 && slot < inv.length) {
inv(slot) = ItemStack.loadItemStackFromNBT(nbtItem)
}
}
}
override def save(t: NBTTagCompound, kind: UpdateKind.Value) {
val itemList = new NBTTagList
for ((item, i) <- inv.view.zipWithIndex if item != null) {
val itemNbt: NBTTagCompound = new NBTTagCompound
itemNbt.setByte("Slot", i.asInstanceOf[Byte])
item.writeToNBT(itemNbt)
itemList.appendTag(itemNbt)
}
t.setTag(name, itemList)
}
}
@@ -0,0 +1,34 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
case class DataSlotItemStack(name: String, parent: DataSlotContainer)
extends DataSlotVal[ItemStack] {
var value: ItemStack = null
override def update(v: ItemStack) = {
if (!ItemStack.areItemStacksEqual(v, value)) {
value = if (v == null) null else v.copy()
parent.dataSlotChanged(this)
}
}
def save(t: NBTTagCompound, kind: UpdateKind.Value) = {
val tag = new NBTTagCompound()
if (value != null) value.writeToNBT(tag)
t.setTag(name, tag)
}
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value =
ItemStack.loadItemStackFromNBT(t.getCompoundTag(name))
}
@@ -0,0 +1,74 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data
import java.io.{
ByteArrayInputStream,
ByteArrayOutputStream,
DataInputStream,
DataOutputStream
}
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
import scala.collection.mutable
case class DataSlotMovingAverage(
name: String,
parent: DataSlotContainer,
size: Int
) extends DataSlot {
val values = mutable.Queue.empty[Double]
var average: Double = 0
setUpdate(UpdateKind.GUI, UpdateKind.SAVE)
def reset() {
values.clear()
average = 0
}
def update(v: Double) = {
values += v
if (values.length > size)
values.dequeue()
average = values.sum / values.length
parent.dataSlotChanged(this)
}
override def save(t: NBTTagCompound, kind: UpdateKind.Value) {
if (kind == UpdateKind.GUI) {
t.setDouble(name, average)
} else {
val b = new ByteArrayOutputStream()
val o = new DataOutputStream(b)
o.writeByte(values.size)
values.foreach(o.writeDouble)
t.setByteArray(name, b.toByteArray)
o.close()
}
}
override def load(t: NBTTagCompound, kind: UpdateKind.Value) {
if (kind == UpdateKind.GUI) {
average = t.getDouble(name)
} else {
values.clear()
if (t.hasKey(name)) {
val i = new DataInputStream(
new ByteArrayInputStream(t.getByteArray(name))
)
val len = i.readByte()
values ++= (for (x <- 0 until Math.min(len, size)) yield i.readDouble())
i.close()
}
}
}
}
@@ -0,0 +1,46 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data
import net.bdew.lib.data.base.DataSlotVal
abstract class DataSlotOption[T] extends DataSlotVal[Option[T]] {
override var value: Option[T] = None
def set(v: T) {
if (v == null) sys.error("Null should never be used with DataSlotOption")
value = Some(v)
}
def unset() {
value = None
}
override def isSame(v: Option[T]) = {
if (v == null) sys.error("Null should never be used with DataSlotOption")
super.isSame(v)
}
override def :=(that: Option[T]) = {
if (that == null) sys.error("Null should never be used with DataSlotOption")
super.:=(that)
}
override def :!=(that: Option[T]) = {
if (that == null) sys.error("Null should never be used with DataSlotOption")
super.:!=(that)
}
override def :==(that: Option[T]) = {
if (that == null) sys.error("Null should never be used with DataSlotOption")
super.:==(that)
}
override def update(v: Option[T]) = {
if (v == null) sys.error("Null should never be used with DataSlotOption")
super.update(v)
}
}
@@ -0,0 +1,25 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
case class DataSlotString(
name: String,
parent: DataSlotContainer,
default: String = null
) extends DataSlotVal[String] {
var value: String = default
def save(t: NBTTagCompound, kind: UpdateKind.Value) =
if (value != null) t.setString(name, value)
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value =
if (t.hasKey(name)) t.getString(name) else null
}
@@ -0,0 +1,96 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.fluids._
abstract class DataSlotTankBase(sz: Int)
extends FluidTank(sz)
with IFluidTank
with DataSlot {
var oldStack: FluidStack = null
parent.onServerTick(checkUpdate)
updateKind = Set(UpdateKind.GUI, UpdateKind.SAVE)
val sendCapacityOnUpdateKind = Set(UpdateKind.GUI)
def checkUpdate() {
if (!isSame(oldStack, fluid)) {
oldStack = if (fluid == null) null else fluid.copy()
parent.dataSlotChanged(this)
}
}
def isSame(v1: FluidStack, v2: FluidStack): Boolean = {
if (v1 == null && v2 == null) return true
if (v1 == null || v2 == null) return false
return v1.isFluidStackIdentical(v2)
}
def save(t: NBTTagCompound, k: UpdateKind.Value) {
val tag = new NBTTagCompound()
writeToNBT(tag)
if (sendCapacityOnUpdateKind.contains(k))
tag.setInteger("size", getCapacity)
t.setTag(name, tag)
}
def load(t: NBTTagCompound, k: UpdateKind.Value) {
setFluid(null)
val tag = t.getCompoundTag(name)
readFromNBT(tag)
if (sendCapacityOnUpdateKind.contains(k))
setCapacity(tag.getInteger("size"))
}
override def setFluid(fluid: FluidStack) = execWithChangeNotify(
super.setFluid(fluid)
)
override def setCapacity(capacity: Int) = execWithChangeNotify(
super.setCapacity(capacity)
)
override def drain(maxDrain: Int, doDrain: Boolean) =
if (doDrain)
execWithChangeNotifyConditional[FluidStack](
super.drain(maxDrain, true),
_ != null
)
else
super.drain(maxDrain, false)
override def fill(resource: FluidStack, doFill: Boolean) =
if (doFill)
execWithChangeNotifyConditional[Int](super.fill(resource, true), _ > 0)
else
super.fill(resource, false)
}
case class DataSlotTank(name: String, parent: DataSlotContainer, size: Int)
extends DataSlotTankBase(size)
case class DataSlotTankRestricted(
name: String,
parent: DataSlotContainer,
var size: Int,
filterFluid: Fluid
) extends DataSlotTankBase(size) {
def fill(amount: Int, doFill: Boolean) =
super.fill(new FluidStack(filterFluid, amount), doFill)
override def fill(resource: FluidStack, doFill: Boolean): Int = {
if ((resource != null) && (resource.getFluid != filterFluid)) return 0
return super.fill(resource, doFill)
}
}
@@ -4,13 +4,13 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data.base
import net.minecraft.entity.player.EntityPlayerMP
import net.bdew.lib.gui.NoInvContainer
import net.minecraft.entity.player.EntityPlayerMP
import net.minecraft.inventory.ICrafting
trait ContainerDataSlots extends NoInvContainer {
@@ -21,19 +21,24 @@ trait ContainerDataSlots extends NoInvContainer {
super.addCraftingToCrafters(crafter)
if (crafter.isInstanceOf[EntityPlayerMP]) {
val pkt = dataSource.getDataSlotPacket
crafter.asInstanceOf[EntityPlayerMP].playerNetServerHandler.sendPacketToPlayer(pkt)
crafter
.asInstanceOf[EntityPlayerMP]
.playerNetServerHandler
.sendPacket(pkt)
}
}
override def detectAndSendChanges() {
super.detectAndSendChanges()
// only send updates every 10 ticks
if (dataSource.lastChange >= lastSentChange + 10 || (dataSource.lastChange > lastSentChange && lastSentChange + 10 < dataSource.worldObj.getTotalWorldTime)) {
if (
dataSource.lastChange >= lastSentChange + 10 || (dataSource.lastChange > lastSentChange && lastSentChange + 10 < dataSource.getWorldObj.getTotalWorldTime)
) {
lastSentChange = dataSource.lastChange
val pkt = dataSource.getDataSlotPacket
for (player <- players)
player.playerNetServerHandler.sendPacketToPlayer(pkt)
player.playerNetServerHandler.sendPacket(pkt)
}
}
}
@@ -0,0 +1,56 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data.base
import net.minecraft.nbt.NBTTagCompound
/** Base trait for all data slots
*/
trait DataSlot {
/** Tile Entity that owns this slot Accessed in constructor, so should be in
* parameters or a lazy val, otherwise will crash
*/
val parent: DataSlotContainer
/** Unique name Accessed in constructor, so should be in parameters or a lazy
* val, otherwise will crash
*/
val name: String
parent.dataSlots += (name -> this)
// Where should it sync
var updateKind = Set(UpdateKind.GUI)
def save(t: NBTTagCompound, kind: UpdateKind.Value)
def load(t: NBTTagCompound, kind: UpdateKind.Value)
def execWithChangeNotify[T](f: => T): T = {
val v = f
parent.dataSlotChanged(this)
v
}
def execWithChangeNotifyConditional[T](
f: => T,
condition: T => Boolean
): T = {
val v = f
if (condition(v))
parent.dataSlotChanged(this)
v
}
def setUpdate(vals: UpdateKind.Value*): this.type = {
updateKind = vals.toSet
return this
}
}
@@ -0,0 +1,70 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data.base
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.world.World
import scala.collection.mutable
/** Base Trait for objects that can contain Data Slots, this allows implementing
* them on things that aren't TEs
*/
trait DataSlotContainer {
// Can't use getWorldObj - it fails to get remapped and stuff breaks in obfuscated environment
def getWorldObject: World
/** Called when a dataslot value changes
*/
def dataSlotChanged(slot: DataSlot): Unit
/** Register a function to run on every server tick
*/
def onServerTick(f: () => Unit): Unit
/** List of dataslots in this container
*/
val dataSlots = mutable.HashMap.empty[String, DataSlot]
/** The value of getTotalWorldTime when the last change happened
*/
var lastChange = 0L
/** The value of getTotalWorldTime when the last GUI packet was sent happened
*/
var lastGuiPacket = 0L
final val TRACE = false
def doSave(kind: UpdateKind.Value, t: NBTTagCompound) {
if (kind == UpdateKind.GUI)
t.setLong("BDLib_TS", getWorldObject.getTotalWorldTime)
for ((n, s) <- dataSlots if s.updateKind.contains(kind)) {
s.save(t, kind)
if (TRACE) printf("%s: %s S=> %s\n".format(kind, n, t.getTag(n)))
}
}
def doLoad(kind: UpdateKind.Value, t: NBTTagCompound) {
if (kind == UpdateKind.GUI) {
val ts = t.getLong("BDLib_TS")
if (ts > lastGuiPacket) {
lastGuiPacket = ts
} else {
return
}
}
for ((n, s) <- dataSlots if s.updateKind.contains(kind)) {
if (TRACE) printf("%s: %s L<= %s\n".format(kind, n, t.getTag(n)))
s.load(t, kind)
}
}
}
@@ -0,0 +1,27 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data.base
/** Base class for data slots that hold numeric values adds convenience
* operators to modify the value
*/
abstract class DataSlotNumeric[T](default: T)(implicit n: Numeric[T])
extends DataSlotVal[T] {
var value = default
def +=(that: T) = update(n.plus(value, that))
def -=(that: T) = update(n.minus(value, that))
def *=(that: T) = update(n.times(value, that))
/* Special Int versions, using the conversion from numeric */
def +=(that: Int) = update(n.plus(value, n.fromInt(that)))
def -=(that: Int) = update(n.minus(value, n.fromInt(that)))
def *=(that: Int) = update(n.times(value, n.fromInt(that)))
}
@@ -0,0 +1,22 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data.base
/** Base class for data slots that hold values with ordering operators, adds
* more convenience operators TODO: Do i need this? normal operators can be
* used with the implicit conversion
*/
abstract class DataSlotOrdered[T](implicit n: Ordering[T])
extends DataSlotVal[T] {
def :>(that: T) = n.compare(value, that) > 0
def :<(that: T) = n.compare(value, that) < 0
def :>=(that: T) = n.compare(value, that) >= 0
def :<=(that: T) = n.compare(value, that) <= 0
}
@@ -0,0 +1,39 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data.base
import scala.language.implicitConversions
/** Base trait for data slots that hold primitive values Defines some
* convenience operators to access the value and an implicit conversion to the
* value
*/
trait DataSlotVal[T] extends DataSlot {
var value: T
def isSame(v: T) = v == value
def :=(that: T) = update(that)
def :!=(that: T) = value != that
def :==(that: T) = value == that
def update(v: T) {
if (!isSame(v)) {
value = v
parent.dataSlotChanged(this)
}
}
}
object DataSlotVal {
implicit def slot2val[T](slot: DataSlotVal[T]): T = slot.value
}
@@ -0,0 +1,60 @@
/*
* Copyright (c) bdew, 2013 - 2015
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data.base
import net.bdew.lib.tile.TileExtended
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.network.Packet
import net.minecraft.network.play.server.S35PacketUpdateTileEntity
trait TileDataSlots extends TileExtended with DataSlotContainer {
persistSave.listen(doSave(UpdateKind.SAVE, _))
persistLoad.listen(doLoad(UpdateKind.SAVE, _))
sendClientUpdate.listen(doSave(UpdateKind.WORLD, _))
handleClientUpdate.listen { tag =>
doLoad(UpdateKind.WORLD, tag)
if (dataSlots.values.exists(_.updateKind.contains(UpdateKind.RENDER)))
getWorldObj.markBlockRangeForRenderUpdate(
xCoord,
yCoord,
zCoord,
xCoord,
yCoord,
zCoord
)
}
override def getWorldObject = getWorldObj
override def onServerTick(f: () => Unit) = serverTick.listen(f)
override def dataSlotChanged(slot: DataSlot) = {
if (getWorldObj != null) {
if (slot.updateKind.contains(UpdateKind.GUI))
lastChange = getWorldObj.getTotalWorldTime
if (!getWorldObj.isRemote && slot.updateKind.contains(UpdateKind.WORLD))
getWorldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
if (slot.updateKind.contains(UpdateKind.SAVE))
getWorldObj.markTileEntityChunkModified(xCoord, yCoord, zCoord, this)
}
}
def getDataSlotPacket: Packet = {
val tag = new NBTTagCompound()
doSave(UpdateKind.GUI, tag)
return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, ACT_GUI, tag)
}
override protected def extDataPacket(id: Int, data: NBTTagCompound) {
if (id == ACT_GUI)
doLoad(UpdateKind.GUI, data)
super.extDataPacket(id, data)
}
}
@@ -4,7 +4,7 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data.base
@@ -14,4 +14,4 @@ object UpdateKind extends Enumeration {
val GUI = Value("GUI")
val SAVE = Value("SAVE")
val RENDER = Value("RENDER")
}
}
@@ -4,29 +4,41 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
import net.minecraft.inventory.IInventory
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.bdew.lib.items.ItemUtils
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.inventory.IInventory
import net.minecraft.item.ItemStack
abstract class BaseContainer(te: IInventory) extends NoInvContainer {
override def transferStackInSlot(player: EntityPlayer, slot: Int): ItemStack = {
override def transferStackInSlot(
player: EntityPlayer,
slot: Int
): ItemStack = {
var stack = getSlot(slot).getStack
if (getSlot(slot).inventory == player.inventory) {
stack = ItemUtils.addStackToSlots(stack, te, 0 until te.getSizeInventory, true)
stack =
ItemUtils.addStackToSlots(stack, te, 0 until te.getSizeInventory, true)
} else {
stack = ItemUtils.addStackToSlots(stack, player.inventory, 9 until player.inventory.mainInventory.length, true)
stack = ItemUtils.addStackToSlots(
stack,
player.inventory,
9 until player.inventory.mainInventory.length,
true
)
// Only put in hotbar if the rest is full
if (stack != null)
stack = ItemUtils.addStackToSlots(stack, player.inventory, 0 until 9, true)
stack =
ItemUtils.addStackToSlots(stack, player.inventory, 0 until 9, true)
}
getSlot(slot).putStack(stack)
return null
}
}
override def canInteractWith(player: EntityPlayer) =
te.isUseableByPlayer(player)
}
@@ -4,7 +4,7 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
@@ -4,7 +4,7 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
@@ -16,7 +16,8 @@ case class BaseRect[T: Numeric](x: T, y: T, w: T, h: T) {
def this(p: BasePoint[T], w: T, h: T) = this(p.x, p.y, w, h)
def contains(p: BasePoint[T]) = n.gteq(p.x, x) && n.gteq(p.y, y) && n.lteq(p.x, x2) && n.lteq(p.y, y2)
def contains(p: BasePoint[T]) =
n.gteq(p.x, x) && n.gteq(p.y, y) && n.lt(p.x, x2) && n.lt(p.y, y2)
def origin = BasePoint(x, y)
@@ -4,17 +4,20 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.inventory.GuiContainer
import net.minecraft.inventory.Container
import scala.collection.mutable
import org.lwjgl.opengl.GL11
abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int) extends GuiContainer(cont) {
import scala.collection.mutable
abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int)
extends GuiContainer(cont) {
xSize = xSz
ySize = ySz
@@ -24,7 +27,7 @@ abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int) extends GuiContai
def rect = new Rect(guiLeft, guiTop, xSize, ySize)
def getFontRenderer = fontRenderer
def getFontRenderer = Minecraft.getMinecraft.fontRenderer
def getZLevel = zLevel
override def initGui() {
@@ -52,10 +55,10 @@ abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int) extends GuiContai
widgets.handleTooltip(Point(x, y) - rect.origin, tip)
import collection.JavaConversions._
import scala.collection.JavaConversions._
if (tip.size > 0)
drawHoveringText(tip, x, y, fontRenderer)
if (tip.nonEmpty)
drawHoveringText(tip, x, y, getFontRenderer)
}
protected def drawGuiContainerBackgroundLayer(f: Float, x: Int, y: Int) {
@@ -4,7 +4,7 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
@@ -12,7 +12,8 @@ package net.bdew.lib.gui
import net.minecraft.inventory.{IInventory, Slot}
import org.lwjgl.opengl.GL11
class BaseSlot(inv: IInventory, slot: Int, x: Int, y: Int) extends Slot(inv, slot, x, y) {
class BaseSlot(inv: IInventory, slot: Int, x: Int, y: Int)
extends Slot(inv, slot, x, y) {
override def getBackgroundIconIndex = {
// Workaround for bug in GuiContainer, color isn't reset if previous slot had an item with color.
GL11.glColor4d(1, 1, 1, 1)
@@ -4,13 +4,13 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
import org.lwjgl.opengl.GL11
import net.bdew.lib.Misc
import org.lwjgl.opengl.GL11
case class Color(r: Float, g: Float, b: Float, a: Float = 1) {
def this(c: (Float, Float, Float)) = this(c._1, c._2, c._3)
@@ -28,11 +28,12 @@ case class Color(r: Float, g: Float, b: Float, a: Float = 1) {
}
object Color {
def fromRGB(r: Int, g: Int, b: Int, a: Int = 255) = Color(r / 255F, g / 255F, b / 255F, a / 255F)
def fromRGB(r: Int, g: Int, b: Int, a: Int = 255) =
Color(r / 255f, g / 255f, b / 255f, a / 255f)
def fromInt(v: Int) = Color(
((v >> 16) & 0xFF) / 255F,
((v >> 8) & 0xFF) / 255F,
(v & 0xFF) / 255F
((v >> 16) & 0xff) / 255f,
((v >> 8) & 0xff) / 255f,
(v & 0xff) / 255f
)
final val white = Color(1, 1, 1)
final val black = Color(0, 0, 0)
@@ -43,7 +44,7 @@ object Color {
final val cyan = Color(0, 1, 1)
final val magenta = Color(1, 0, 1)
final val gray = Color(0.5F, 0.5F, 0.5F)
final val lightgray = Color(0.75F, 0.75F, 0.75F)
final val darkgray = Color(0.25F, 0.25F, 0.25F)
final val gray = Color(0.5f, 0.5f, 0.5f)
final val lightGray = Color(0.75f, 0.75f, 0.75f)
final val darkGray = Color(0.25f, 0.25f, 0.25f)
}
@@ -4,7 +4,7 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
@@ -4,13 +4,13 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
import net.minecraft.client.renderer.Tessellator
import net.minecraft.client.gui.FontRenderer
import net.minecraft.client.renderer.Tessellator
trait DrawTarget {
def getZLevel: Float
@@ -19,8 +19,20 @@ trait DrawTarget {
def drawText(text: String, p: Point, color: Color, shadow: Boolean)
def drawTextMultiline(text: String, r: Rect, color: Color)
def drawTextureInterpolate(r: Rect, t: Texture, x1: Float, y1: Float, x2: Float, y2: Float, color: Color = Color.white) =
drawTexture(r.interpolate(x1, y1, x2, y2), Texture.interpolate(t, x1, y1, x2, y2))
def drawTextureInterpolate(
r: Rect,
t: Texture,
x1: Float,
y1: Float,
x2: Float,
y2: Float,
color: Color = Color.white
) =
drawTexture(
r.interpolate(x1, y1, x2, y2),
Texture.interpolate(t, x1, y1, x2, y2),
color
)
}
trait SimpleDrawTarget extends DrawTarget {
@@ -42,5 +54,11 @@ trait SimpleDrawTarget extends DrawTarget {
getFontRenderer.drawString(text, p.x.round, p.y.round, color.asARGB, shadow)
def drawTextMultiline(text: String, r: Rect, color: Color) =
getFontRenderer.drawSplitString(text, r.x.round, r.y.round, r.w.round, color.asARGB)
getFontRenderer.drawSplitString(
text,
r.x.round,
r.y.round,
r.w.round,
color.asARGB
)
}
@@ -0,0 +1,49 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
import cpw.mods.fml.common.network.IGuiHandler
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.world.World
import scala.collection.mutable
class GuiHandler extends IGuiHandler {
val GUIs = mutable.Map.empty[Int, GuiProvider]
def register(p: GuiProvider) = {
if (GUIs.isDefinedAt(p.guiId))
sys.error(
"GUI ID Collision - %d was registered for %s and attempted to register by %s"
.format(p.guiId, GUIs(p.guiId), p)
)
GUIs += (p.guiId -> p)
}
def getServerGuiElement(
ID: Int,
player: EntityPlayer,
world: World,
x: Int,
y: Int,
z: Int
): AnyRef =
GUIs(ID).getContainer(world.getTileEntity(x, y, z), player)
def getClientGuiElement(
ID: Int,
player: EntityPlayer,
world: World,
x: Int,
y: Int,
z: Int
): AnyRef =
GUIs(ID).getGui(world.getTileEntity(x, y, z), player)
}
@@ -4,14 +4,14 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
import net.minecraft.tileentity.TileEntity
import net.minecraft.entity.player.EntityPlayer
import cpw.mods.fml.relauncher.{Side, SideOnly}
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.tileentity.TileEntity
trait GuiProvider {
def guiId: Int
@@ -23,6 +23,13 @@ trait GuiProvider {
def getContainer(te: TEClass, player: EntityPlayer): AnyRef
@SideOnly(Side.CLIENT)
def getGui(te: TileEntity, player: EntityPlayer): AnyRef = getGui(te.asInstanceOf[TEClass], player)
def getContainer(te: TileEntity, player: EntityPlayer): AnyRef = getContainer(te.asInstanceOf[TEClass], player)
def getGui(te: TileEntity, player: EntityPlayer): AnyRef =
if (te != null)
getGui(te.asInstanceOf[TEClass], player)
else null
def getContainer(te: TileEntity, player: EntityPlayer): AnyRef =
if (te != null)
getContainer(te.asInstanceOf[TEClass], player)
else null
}
@@ -0,0 +1,60 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
import net.bdew.lib.Misc
import net.minecraft.entity.player.{
EntityPlayer,
EntityPlayerMP,
InventoryPlayer
}
import net.minecraft.inventory.{Container, Slot}
import net.minecraft.item.ItemStack
abstract class NoInvContainer extends Container {
import scala.collection.JavaConversions._
def players = Misc.filterType(crafters, classOf[EntityPlayerMP])
protected def bindPlayerInventory(
inv: InventoryPlayer,
xOffs: Int,
yOffsInv: Int,
yOffsHotbar: Int
) {
for (i <- 0 until 3; j <- 0 until 9)
addSlotToContainer(
new Slot(inv, j + i * 9 + 9, xOffs + j * 18, yOffsInv + i * 18)
)
for (i <- 0 until 9)
addSlotToContainer(new Slot(inv, i, xOffs + i * 18, yOffsHotbar))
}
override def slotClick(
slotNum: Int,
button: Int,
modifiers: Int,
player: EntityPlayer
): ItemStack = {
if (inventorySlots.isDefinedAt(slotNum)) {
val slot = getSlot(slotNum)
if (slot != null && slot.isInstanceOf[SlotClickable])
return slot
.asInstanceOf[SlotClickable]
.onClick(button, modifiers, player)
}
return super.slotClick(slotNum, button, modifiers, player)
}
override def transferStackInSlot(player: EntityPlayer, slot: Int): ItemStack =
null
}
@@ -4,14 +4,14 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
import net.minecraft.item.ItemStack
import net.minecraft.inventory.Slot
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.inventory.Slot
import net.minecraft.item.ItemStack
trait SlotClickable extends Slot {
def onClick(button: Int, mods: Int, player: EntityPlayer): ItemStack
@@ -4,7 +4,7 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
@@ -12,6 +12,8 @@ package net.bdew.lib.gui
import net.minecraft.inventory.IInventory
import net.minecraft.item.ItemStack
class SlotValidating(inv: IInventory, slot: Int, x: Int, y: Int) extends BaseSlot(inv, slot, x, y) {
override def isItemValid(stack: ItemStack) = inventory.isItemValidForSlot(getSlotIndex, stack)
}
class SlotValidating(inv: IInventory, slot: Int, x: Int, y: Int)
extends BaseSlot(inv, slot, x, y) {
override def isItemValid(stack: ItemStack) =
inventory.isItemValidForSlot(getSlotIndex, stack)
}
@@ -0,0 +1,146 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
import net.bdew.lib.Client
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.texture.TextureMap
import net.minecraft.util.{IIcon, ResourceLocation}
trait Texture {
def u1: Float
def u2: Float
def v1: Float
def v2: Float
def bind(): Unit
}
class InterpolatedTexture(val texture: Texture, rect: Rect) extends Texture {
def bind() = texture.bind()
def u1 = rect.x1 * (texture.u2 - texture.u1) + texture.u1
def u2 = rect.x2 * (texture.u2 - texture.u1) + texture.u1
def v1 = rect.y1 * (texture.v2 - texture.v1) + texture.v1
def v2 = rect.y2 * (texture.v2 - texture.v1) + texture.v1
}
class IconWrapper(val resource: ResourceLocation, aIcon: IIcon)
extends Texture {
val icon = if (aIcon == null) {
if (resource == Texture.ITEMS) Client.itemMissingIcon
else if (resource == Texture.BLOCKS) Client.blockMissingIcon
else sys.error("Attempt to create IconWrapper for null IIcon")
} else aIcon
def u1 = icon.getMinU
def u2 = icon.getMaxU
def v1 = icon.getMinV
def v2 = icon.getMaxV
def bind() = Minecraft.getMinecraft.renderEngine.bindTexture(resource)
}
class Sprite(val resource: ResourceLocation, r: Rect, scale: Int = 256)
extends Texture {
val rect = Rect(r.x / scale, r.y / scale, r.w / scale, r.h / scale)
def u1 = rect.x1
def u2 = rect.x2
def v1 = rect.y1
def v2 = rect.y2
def bind() = Minecraft.getMinecraft.renderEngine.bindTexture(resource)
}
class ScaledResourceLocation(path: String, val scale: Int = 256)
extends ResourceLocation(path) {
def this(domain: String, path: String, scale: Int) =
this(domain + ":" + path, scale)
def this(domain: String, path: String) = this(domain + ":" + path, 256)
}
object Texture {
val ITEMS = TextureMap.locationItemsTexture
val BLOCKS = TextureMap.locationBlocksTexture
// From minecraft Icon
def apply(res: ResourceLocation, i: IIcon) = new IconWrapper(res, i)
// From a ResourceLocation and position, scale optional
def apply(res: ResourceLocation, r: Rect) = new Sprite(res, r)
def apply(res: ResourceLocation, r: Rect, scale: Int) =
new Sprite(res, r, scale)
def apply(res: ResourceLocation, u1: Float, v1: Float, w: Float, h: Float) =
new Sprite(res, Rect(u1, v1, w, h))
def apply(
res: ResourceLocation,
u1: Float,
v1: Float,
w: Float,
h: Float,
scale: Int
) = new Sprite(res, Rect(u1, v1, w, h), scale)
// From a path (with optional domain) and position, no scale
def apply(path: String, r: Rect) = new Sprite(new ResourceLocation(path), r)
def apply(path: String, u1: Float, v1: Float, w: Float, h: Float) =
new Sprite(new ResourceLocation(path), Rect(u1, v1, w, h))
def apply(domain: String, path: String, r: Rect) =
new Sprite(new ResourceLocation(domain, path), r)
def apply(
domain: String,
path: String,
u1: Float,
v1: Float,
w: Float,
h: Float
) = new Sprite(new ResourceLocation(domain, path), Rect(u1, v1, w, h))
// From a path (with optional domain), position and scale
def apply(path: String, r: Rect, scale: Int) =
new Sprite(new ResourceLocation(path), r, scale)
def apply(
path: String,
u1: Float,
v1: Float,
w: Float,
h: Float,
scale: Int
) = new Sprite(new ResourceLocation(path), Rect(u1, v1, w, h), scale)
def apply(domain: String, path: String, r: Rect, scale: Int) =
new Sprite(new ResourceLocation(domain, path), r, scale)
def apply(
domain: String,
path: String,
u1: Float,
v1: Float,
w: Float,
h: Float,
scale: Int
) = new Sprite(new ResourceLocation(domain, path), Rect(u1, v1, w, h), scale)
// From a ScaledResourceLocation and position
def apply(res: ScaledResourceLocation, r: Rect) =
new Sprite(res, r, res.scale)
def apply(
res: ScaledResourceLocation,
u1: Float,
v1: Float,
w: Float,
h: Float
) = new Sprite(res, Rect(u1, v1, w, h), res.scale)
// A fraction of another Texture, parameters should be between 0 and 1
def interpolate(texture: Texture, rect: Rect) =
new InterpolatedTexture(texture, rect)
def interpolate(
texture: Texture,
u1: Float,
v1: Float,
u2: Float,
v2: Float
) = new InterpolatedTexture(texture, Rect(u1, v1, u2 - u1, v2 - v1))
}
@@ -4,16 +4,17 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui
import scala.collection.mutable
import net.bdew.lib.gui.widgets.BaseWidget
import net.minecraft.client.gui.FontRenderer
import org.lwjgl.opengl.GL11
import scala.collection.mutable
trait WidgetContainer extends DrawTarget {
val rect: Rect
val widgets = mutable.MutableList.empty[BaseWidget]
@@ -77,7 +78,9 @@ trait WidgetContainer extends DrawTarget {
def getOffsetFromWindow: Point
}
class WidgetContainerWindow(val parent: BaseScreen, xSz: Int, ySz: Int) extends WidgetContainer with SimpleDrawTarget {
class WidgetContainerWindow(val parent: BaseScreen, xSz: Int, ySz: Int)
extends WidgetContainer
with SimpleDrawTarget {
def getZLevel = parent.getZLevel
def getFontRenderer = parent.getFontRenderer
def getOffsetFromWindow = Point(0, 0)
@@ -0,0 +1,39 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib
package object gui {
type Rect = BaseRect[Float]
type Point = BasePoint[Float]
import scala.language.implicitConversions
implicit def awt2point(p: java.awt.Point): BasePoint[Int] =
BasePoint(p.x, p.y)
implicit def point2awt(p: BasePoint[Int]): java.awt.Point =
new java.awt.Point(p.x, p.y)
implicit def tuple2point[T: Numeric](p: (T, T)): BasePoint[T] =
BasePoint(p._1, p._2)
// Converts different kinds of Point/Rect as long as there's an implicit for the underlying type
implicit def pointConvert[T, R](
a: BasePoint[R]
)(implicit f: R => T, n: Numeric[T]): BasePoint[T] =
BasePoint[T](f(a.x), f(a.y))
implicit def rectConvert[T, R](
a: BaseRect[R]
)(implicit f: R => T, n: Numeric[T]): BaseRect[T] =
BaseRect[T](f(a.x), f(a.y), f(a.w), f(a.h))
def Rect(x: Float, y: Float, w: Float, h: Float) = BaseRect(x, y, w, h)
def Point(x: Float, y: Float) = BasePoint(x, y)
}
@@ -4,13 +4,14 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui.{Point, Rect, WidgetContainer}
import scala.collection.mutable
import net.bdew.lib.gui.{WidgetContainer, Point, Rect}
trait BaseWidget {
val rect: Rect
@@ -0,0 +1,41 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui.{Point, Rect}
import net.minecraft.client.Minecraft
import net.minecraft.client.audio.PositionedSoundRecord
import net.minecraft.client.gui.GuiButton
import net.minecraft.util.ResourceLocation
class WidgetButton(val rect: Rect, text: String, clicked: WidgetButton => Unit)
extends GuiButton(
0,
rect.x.round,
rect.y.round,
rect.w.round,
rect.h.round,
text
)
with Widget {
override def mouseClicked(p: Point, button: Int) {
Minecraft.getMinecraft.getSoundHandler.playSound(
PositionedSoundRecord.func_147674_a(
new ResourceLocation("gui.button.press"),
1.0f
)
)
clicked(this)
}
override def draw(mouse: Point) =
drawButton(Minecraft.getMinecraft, mouse.x.round, mouse.y.round)
}
@@ -0,0 +1,55 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui.{Point, Rect, Texture}
import net.minecraft.client.Minecraft
import net.minecraft.client.audio.PositionedSoundRecord
import net.minecraft.util.ResourceLocation
import scala.collection.mutable
class WidgetButtonIcon(
p: Point,
clicked: WidgetButtonIcon => Unit,
baseTex: Texture,
hoverTex: Texture
) extends Widget {
val rect = new Rect(p, 16, 16)
val iconRect = new Rect(p + (1, 1), 14, 14)
var icon: Texture = null
var hover: String = null
override def draw(mouse: Point) {
if (rect.contains(mouse))
parent.drawTexture(rect, hoverTex)
else
parent.drawTexture(rect, baseTex)
if (icon != null)
parent.drawTexture(iconRect, icon)
}
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) {
if (hover != null && hover > "")
tip += hover
}
override def mouseClicked(p: Point, button: Int) {
Minecraft.getMinecraft.getSoundHandler.playSound(
PositionedSoundRecord.func_147674_a(
new ResourceLocation("gui.button.press"),
1.0f
)
)
clicked(this)
}
}
@@ -4,14 +4,15 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui.{Color, Point, Rect}
class WidgetDynLabel(text: => String, x: Int, y: Int, color: Color) extends Widget {
class WidgetDynLabel(text: => String, x: Int, y: Int, color: Color)
extends Widget {
val rect = new Rect(x, y, 0, 0)
override def draw(mouse: Point) {
parent.drawText(text, rect.origin, color, false)
@@ -4,20 +4,27 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui._
import net.bdew.lib.data.base.DataSlotNumeric
import net.bdew.lib.gui._
class WidgetFillDataslot[T](val rect: Rect, val texture: Texture, dir: Direction.Direction, dslot: DataSlotNumeric[T], maxval: T)(implicit num: Numeric[T]) extends Widget {
class WidgetFillDataSlot[T](
val rect: Rect,
val texture: Texture,
dir: Direction.Direction,
dSlot: DataSlotNumeric[T],
maxVal: T
)(implicit num: Numeric[T])
extends Widget {
import num.mkNumericOps
override def draw(mouse: Point) {
val fill = dslot.cval.toFloat() / maxval.toFloat()
val fill = dSlot.value.toFloat() / maxVal.toFloat()
dir match {
case Direction.UP =>
parent.drawTextureInterpolate(rect, texture, 0, 1 - fill, 1, 1)
@@ -30,5 +37,3 @@ class WidgetFillDataslot[T](val rect: Rect, val texture: Texture, dir: Direction
}
}
}
@@ -0,0 +1,79 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui.widgets
import net.bdew.lib.data.DataSlotTankBase
import net.bdew.lib.gui.{Color, Point, Rect, Texture}
import net.bdew.lib.{DecFormat, Misc}
import org.lwjgl.opengl.GL11
import scala.collection.mutable
class WidgetFluidGauge(
val rect: Rect,
overlay: Texture,
dSlot: DataSlotTankBase
) extends Widget {
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) {
if (dSlot.getFluid != null) {
tip += dSlot.getFluid.getFluid.getLocalizedName(dSlot.getFluid)
tip += "%s/%s mB".format(
DecFormat.round(dSlot.getFluidAmount),
DecFormat.round(dSlot.getCapacity)
)
} else {
tip += Misc.toLocal("bdlib.label.empty")
}
}
override def draw(mouse: Point) {
GL11.glEnable(GL11.GL_BLEND)
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA)
val fStack = dSlot.getFluid
if (fStack != null) {
val color = Color.fromInt(Misc.getFluidColor(fStack))
val icon = Texture(Texture.BLOCKS, Misc.getFluidIcon(fStack))
var fillHeight =
if (dSlot.getCapacity > 0) rect.h * fStack.amount / dSlot.getCapacity
else 0
var yStart: Int = 0
while (fillHeight > 0) {
if (fillHeight > 16) {
parent.drawTexture(
new Rect(rect.x, rect.y2 - 16 - yStart, rect.w, 16),
icon,
color
)
fillHeight -= 16
} else {
parent.drawTextureInterpolate(
new Rect(rect.x, rect.y2 - 16 - yStart, rect.w, 16),
icon,
0,
1 - fillHeight / 16,
1,
1,
color
)
fillHeight = 0
}
yStart = yStart + 16
}
}
GL11.glColor3d(1, 1, 1)
GL11.glDisable(GL11.GL_BLEND)
if (overlay != null)
parent.drawTexture(rect, overlay)
}
}
@@ -4,7 +4,7 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui.widgets
@@ -4,14 +4,14 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui.Rect
abstract class WidgetMultipane(rect: Rect) extends WidgetSubcontainer(rect) {
abstract class WidgetMultiPane(rect: Rect) extends WidgetSubContainer(rect) {
def getActivePane: BaseWidget
def addPane[T <: BaseWidget](w: T): T = {
@@ -4,15 +4,24 @@
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui._
import scala.collection.mutable
import net.bdew.lib.data.DataSlotFloat
import net.bdew.lib.gui._
class WidgetProgressBar(rect: Rect, texture: Texture, dslot: DataSlotFloat) extends WidgetFillDataslot[Float](rect, texture, Direction.RIGHT, dslot, 1) {
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) = tip += "%.0f".format(dslot.cval * 100) + "%"
import scala.collection.mutable
class WidgetProgressBar(rect: Rect, texture: Texture, dSlot: DataSlotFloat)
extends WidgetFillDataSlot[Float](
rect,
texture,
Direction.RIGHT,
dSlot,
1
) {
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) =
tip += "%.0f".format(dSlot.value * 100) + "%"
}
Loaded 100 of 279 files, more files were not shown because too many files have changed in this diff. Show more