├── .editorconfig ├── .gitattributes ├── .gitignore ├── .travis.yml ├── LICENSE ├── ReadMe.md ├── build.gradle ├── gradle.properties ├── gradle ├── scripts │ ├── artifacts.gradle │ ├── dependencies.gradle │ ├── documentation.gradle │ ├── jsonGen.gradle │ └── upload.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── api └── java │ └── org │ └── squiddev │ └── cctweaks │ └── api │ ├── CCTweaksAPI.java │ ├── CoreNotFoundException.java │ ├── ICCTweaksAPI.java │ ├── IComputerItemFactory.java │ ├── IDataCard.java │ ├── IWorldPosition.java │ ├── UnorderedPair.java │ ├── block │ ├── BasicRotationHandler.java │ ├── IRotationHandler.java │ ├── IRotationRegistry.java │ └── PropertyRotationHandler.java │ ├── computer │ ├── ICustomRomItem.java │ └── IExtendedServerComputer.java │ ├── network │ ├── INetworkAccess.java │ ├── INetworkCompatiblePeripheral.java │ ├── INetworkController.java │ ├── INetworkHelpers.java │ ├── INetworkNode.java │ ├── INetworkNodeProvider.java │ ├── INetworkRegistry.java │ ├── INetworkedPeripheral.java │ ├── IWorldNetworkNode.java │ ├── IWorldNetworkNodeHost.java │ └── NetworkAPI.java │ ├── package-info.java │ ├── peripheral │ ├── IPeripheralHelpers.java │ ├── IPeripheralHidden.java │ ├── IPeripheralHost.java │ ├── IPeripheralProxy.java │ └── IPeripheralTargeted.java │ └── turtle │ ├── AbstractTurtleInteraction.java │ ├── IExtendedTurtleUpgrade.java │ ├── ITurtleFuelProvider.java │ ├── ITurtleFuelRegistry.java │ ├── ITurtleInteraction.java │ └── ITurtleRegistry.java ├── main ├── java │ └── org │ │ └── squiddev │ │ └── cctweaks │ │ ├── CCTweaks.java │ │ ├── GuiHandler.java │ │ ├── blocks │ │ ├── BlockBase.java │ │ ├── IMultiBlock.java │ │ ├── TileBase.java │ │ ├── TileLazyNBT.java │ │ ├── debug │ │ │ ├── BlockDebug.java │ │ │ ├── TileDebugNetworkedPeripheral.java │ │ │ ├── TileDebugNode.java │ │ │ └── TileDebugPeripheral.java │ │ └── network │ │ │ ├── BlockNetworked.java │ │ │ ├── TileNetworked.java │ │ │ ├── TileNetworkedModem.java │ │ │ └── TileNetworkedWirelessBridge.java │ │ ├── client │ │ ├── CustomModelLoader.java │ │ ├── gui │ │ │ ├── GuiAnyComputer.java │ │ │ ├── GuiConfigCCTweaks.java │ │ │ └── GuiConfigFactory.java │ │ └── render │ │ │ ├── RenderNetworkOverlay.java │ │ │ └── RenderSquidOverlay.java │ │ ├── command │ │ ├── CommandCCTweaks.java │ │ ├── ComputerSelector.java │ │ ├── ContainerAnyComputer.java │ │ └── SubCommandGive.java │ │ ├── core │ │ ├── API.java │ │ ├── Config.java │ │ ├── McEvents.java │ │ ├── asm │ │ │ ├── ASMTransformer.java │ │ │ ├── CopyRom.java │ │ │ ├── DisableTurtleCommand.java │ │ │ ├── SetCustomRom.java │ │ │ ├── SetSuspendable.java │ │ │ └── TweaksLoadingPlugin.java │ │ ├── block │ │ │ ├── RotationRegistry.java │ │ │ └── VanillaRotationHandlers.java │ │ ├── collections │ │ │ ├── MapChanges.java │ │ │ └── MapsX.java │ │ ├── command │ │ │ ├── ChatHelpers.java │ │ │ ├── CommandContext.java │ │ │ ├── CommandDelegate.java │ │ │ ├── CommandRoot.java │ │ │ ├── ISubCommand.java │ │ │ ├── SubCommandBase.java │ │ │ ├── SubCommandHelp.java │ │ │ ├── TextTable.java │ │ │ └── UserLevel.java │ │ ├── network │ │ │ ├── AbstractNode.java │ │ │ ├── AbstractWorldNode.java │ │ │ ├── NetworkAccessDelegate.java │ │ │ ├── NetworkHelpers.java │ │ │ ├── NetworkRegistry.java │ │ │ ├── bridge │ │ │ │ ├── NetworkBinding.java │ │ │ │ ├── NetworkBindingPeripheral.java │ │ │ │ ├── NetworkBindingWithModem.java │ │ │ │ └── NetworkBindings.java │ │ │ ├── cable │ │ │ │ ├── BasicCable.java │ │ │ │ ├── CableWithInternalSidedParts.java │ │ │ │ └── SingleModemCable.java │ │ │ ├── controller │ │ │ │ ├── ControllerValidator.java │ │ │ │ ├── NetworkController.java │ │ │ │ ├── NodeScanner.java │ │ │ │ └── Point.java │ │ │ └── modem │ │ │ │ ├── BasicModem.java │ │ │ │ ├── BasicModemPeripheral.java │ │ │ │ ├── ControllableModemPeripheral.java │ │ │ │ ├── DirectionalPeripheralModem.java │ │ │ │ ├── DynamicPeripheralCollection.java │ │ │ │ ├── MultiPeripheralModem.java │ │ │ │ ├── PeripheralAccess.java │ │ │ │ ├── PeripheralCollection.java │ │ │ │ └── SinglePeripheralModem.java │ │ ├── packet │ │ │ └── AbstractPacketHandler.java │ │ ├── patch │ │ │ ├── BlockCable_Patch.java │ │ │ ├── ComputerItemFactory_Patch.java │ │ │ ├── GuiContainer_Extension.java │ │ │ ├── ItemCable_Patch.java │ │ │ ├── ItemComputerBase_Patch.java │ │ │ ├── ItemPocketComputer_Patch.java │ │ │ ├── PeripheralAPI_Patch.java │ │ │ ├── PocketServerComputer_Patch.java │ │ │ ├── ServerComputerRegistry_Patch.java │ │ │ ├── ServerComputer_Patch.java │ │ │ ├── Terminal_Patch.java │ │ │ ├── TileCable_Ignore.java │ │ │ ├── TileCable_Patch.java │ │ │ ├── TileComputerBase_Patch.java │ │ │ ├── TurtleBrain_Patch.java │ │ │ ├── TurtleItemFactory_Patch.java │ │ │ ├── TurtlePlaceCommand_Patch.java │ │ │ ├── TurtleRefuelCommand_Rewrite.java │ │ │ ├── iface │ │ │ │ ├── IExtendedComputerTile.java │ │ │ │ └── IExtendedServerComputer.java │ │ │ └── targeted │ │ │ │ ├── ComputerPeripheral_Patch.java │ │ │ │ ├── DiskDrivePeripheral_Patch.java │ │ │ │ └── PrinterPeripheral_Patch.java │ │ ├── peripheral │ │ │ ├── PeripheralHelpers.java │ │ │ ├── PeripheralHostProvider.java │ │ │ └── PeripheralProxy.java │ │ ├── pocket │ │ │ └── ItemPocketRenderer.java │ │ ├── registry │ │ │ ├── IClientModule.java │ │ │ ├── IModule.java │ │ │ ├── Module.java │ │ │ └── Registry.java │ │ ├── rom │ │ │ └── CraftingSetRom.java │ │ ├── turtle │ │ │ ├── DefaultTurtleProviders.java │ │ │ ├── LuaDirection.java │ │ │ ├── TurtleFuelRegistry.java │ │ │ ├── TurtleHooks.java │ │ │ └── TurtleRegistry.java │ │ ├── utils │ │ │ ├── BlockNotifyFlags.java │ │ │ ├── ComputerAccessor.java │ │ │ ├── DebugLogger.java │ │ │ ├── EntityPosition.java │ │ │ ├── FakeNetHandler.java │ │ │ ├── Helpers.java │ │ │ ├── InventoryUtils.java │ │ │ └── WorldPosition.java │ │ └── visualiser │ │ │ ├── NetworkChange.java │ │ │ ├── NetworkNode.java │ │ │ ├── NetworkPlayerWatcher.java │ │ │ ├── NetworkState.java │ │ │ └── VisualisationPacket.java │ │ ├── integration │ │ ├── APIIntegration.java │ │ ├── ForgeIntegration.java │ │ ├── IndustrialCraftIntegration.java │ │ ├── ModIntegration.java │ │ ├── RedstoneFluxIntegration.java │ │ ├── TeslaIntegration.java │ │ ├── jei │ │ │ ├── BasicRecipeHandler.java │ │ │ ├── IValidRecipeWrapper.java │ │ │ ├── JeiCCTweaks.java │ │ │ ├── JeiDescription.java │ │ │ ├── PocketUpgradeWrapper.java │ │ │ ├── TurtleUpgradeWrapper.java │ │ │ └── UpgradeCategory.java │ │ └── multipart │ │ │ ├── ItemCustomPart.java │ │ │ ├── MultipartConverter.java │ │ │ ├── MultipartHelpers.java │ │ │ ├── MultipartIntegration.java │ │ │ ├── PartBase.java │ │ │ ├── PartLazyNBT.java │ │ │ ├── PartSided.java │ │ │ └── network │ │ │ ├── PartCable.java │ │ │ ├── PartModem.java │ │ │ └── PartWirelessBridge.java │ │ ├── items │ │ ├── CraftingComputerUpgrade.java │ │ ├── ItemBase.java │ │ ├── ItemComputerAction.java │ │ ├── ItemComputerUpgrade.java │ │ ├── ItemDataCard.java │ │ ├── ItemDebugger.java │ │ ├── ItemMultiBlock.java │ │ └── ItemToolHost.java │ │ ├── pocket │ │ └── PocketWirelessBridge.java │ │ └── turtle │ │ ├── ToolHostPlayer.java │ │ ├── ToolManipulatorPeripheral.java │ │ ├── TurtlePosition.java │ │ ├── TurtleUpgradeBase.java │ │ ├── TurtleUpgradeToolHost.java │ │ ├── TurtleUpgradeToolManipulator.java │ │ └── TurtleUpgradeWirelessBridge.java └── resources │ ├── META-INF │ └── CCTweaks_at.cfg │ ├── assets │ └── cctweaks │ │ ├── blockstates │ │ ├── cable.json │ │ ├── debugBlock.json │ │ ├── modem.json │ │ ├── networkedBlock.json │ │ └── wirelessBridgeSmall.json │ │ ├── docs │ │ └── en_US │ │ │ ├── item │ │ │ ├── computerUpgrade.txt │ │ │ ├── dataCard.txt │ │ │ ├── debugger.txt │ │ │ ├── toolHost.advanced.txt │ │ │ └── toolHost.txt │ │ │ └── tile │ │ │ ├── debugBlock.txt │ │ │ ├── networkedBlock.wiredModem.txt │ │ │ └── networkedBlock.wirelessBridge.txt │ │ ├── lang │ │ └── en_US.lang │ │ ├── models │ │ ├── block │ │ │ ├── wireless_bridge_small.json │ │ │ ├── wireless_bridge_turtle_left.json │ │ │ └── wireless_bridge_turtle_right.json │ │ ├── generate.json │ │ ├── item │ │ │ └── wireless_bridge_small.json │ │ └── templates │ │ │ ├── block.json │ │ │ ├── item.json │ │ │ └── itemblock.json │ │ └── textures │ │ ├── blocks │ │ ├── debug_networked_peripheral.png │ │ ├── debug_node.png │ │ ├── debug_peripheral.png │ │ ├── debug_template.png │ │ ├── wireless_bridge.png │ │ └── wireless_bridge_small.png │ │ ├── gui │ │ └── jei_upgrade.png │ │ └── items │ │ ├── computer_upgrade.png │ │ ├── data_card.png │ │ ├── debugger.png │ │ ├── tool_host.png │ │ └── tool_host_advanced.png │ ├── mcmod.info │ └── pack.mcmeta └── test ├── java └── org │ └── squiddev │ └── cctweaks │ └── core │ ├── network │ ├── NetworkTest.java │ ├── PacketTest.java │ └── mock │ │ ├── BasicNetwork.java │ │ ├── BoundNetworkNode.java │ │ ├── CountingNetworkNode.java │ │ ├── KeyedNetworkNode.java │ │ └── NodeTile.java │ └── peripheral │ ├── BasePeripheral.java │ └── PeripheralHelpersTest.java └── resources └── org └── squiddev └── cctweaks └── core ├── network └── data.json └── patcher ├── binaryEvent.lua └── binaryFS.lua /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = tab 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | 14 | [*.properties] 15 | insert_final_newline = false 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | .shelf 3 | 4 | # Mobile Tools for Java (J2ME) 5 | .mtj.tmp/ 6 | 7 | # Package Files # 8 | *.jar 9 | *.war 10 | *.ear 11 | 12 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 13 | hs_err_pid* 14 | 15 | # ========================= 16 | # Operating System Files 17 | # ========================= 18 | 19 | # OSX 20 | # ========================= 21 | 22 | .DS_Store 23 | .AppleDouble 24 | .LSOverride 25 | 26 | # Icon must ends with two \r. 27 | Icon 28 | 29 | 30 | # Thumbnails 31 | ._* 32 | 33 | # Files that might appear on external disk 34 | .Spotlight-V100 35 | .Trashes 36 | 37 | # Windows 38 | # ========================= 39 | 40 | # Windows image file caches 41 | Thumbs.db 42 | ehthumbs.db 43 | 44 | # Folder config file 45 | Desktop.ini 46 | 47 | # Recycle Bin used on file shares 48 | $RECYCLE.BIN/ 49 | 50 | # Windows Installer files 51 | *.cab 52 | *.msi 53 | *.msm 54 | *.msp 55 | 56 | # ========================= 57 | # Forge Files 58 | # ========================= 59 | /run-*/ 60 | /build-*/ 61 | /bin/ 62 | /lib/ # Include libs manually 63 | 64 | # Gradle 65 | # ========================= 66 | /.gradle 67 | /build/ 68 | /run/ 69 | !gradle/wrapper/gradle-wrapper.jar 70 | 71 | # Idea 72 | # ========================= 73 | *.iml 74 | *.ipr 75 | *.iws 76 | .idea 77 | 78 | # Eclipse 79 | # ========================= 80 | /eclipse/ 81 | /.classpath 82 | /.project 83 | /.settings/ 84 | /debug/ 85 | *.lock 86 | /.metadata/ 87 | out 88 | logs/ 89 | /classes/ 90 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | sudo: false 3 | notifications: 4 | email: false 5 | cache: 6 | directories: 7 | - $HOME/.gradle 8 | - $HOME/.m2 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015-2017 SquidDev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # CCTweaks [![Build Status](https://travis-ci.org/SquidDev-CC/CCTweaks.svg?branch=minecraft-1.10.2)](https://travis-ci.org/SquidDev-CC/CCTweaks) 2 | Miscellaneous changes for ComputerCraft 3 | 4 | ## Important! 5 | CCTweaks is a core mod and makes modifications to the internals of ComputerCraft. Whilst the mod is thoroughly tested there may be issues. If you encounter any bugs report them *here* and **not** on the ComputerCraft issue tracker. This will ensure a faster response time and will ensure you do not frustrate DanTwoHundred. 6 | 7 | Thanks :smile:! 8 | 9 | ## Features 10 | 11 | ### Programming ([More up-to-date list here](https://github.com/SquidDev-CC/CCTweaks-Lua)) 12 | - Custom computer timeout 13 | - Whitelist globals (such as debug) 14 | - TCP socket API (`socket`) 15 | - Compression API (`data`) 16 | - [Cobalt](https://github.com/SquidDev/Cobalt) VM (reentrant fork of LuaJ) 17 | - Custom termination handler 18 | - Several bugs fixed (any object error messages, string pattern matching, number format strings) 19 | - Run multiple computers at once 20 | - API for adding custom APIs 21 | 22 | ### Turtles 23 | - Blacklist turtle verbs - no more `turtle.inspect` if you don't like it. 24 | - Turtle refuel using RF/EU/Tesla and Forge Energy 25 | - Turtle tool host - use any tool with turtles 26 | 27 | ### Networking 28 | - Networking API: add custom network components 29 | - Multidimensional modems (connect wired networks together) 30 | - Full block modems (connect to peripherals on 6 sides) 31 | - Multipart support 32 | - Beautiful network visualiser 33 | 34 | ### More 35 | - Computer upgrades - convert normal computers to advanced! 36 | - Debug Wand - add the debug API to any computer 37 | - Packet optimisations, reducing network traffic 38 | - Powerful server management commands, allowing monitoring, profiling and controlling computers. 39 | 40 | ## Contributing 41 | ### Code and dependencies: 42 | You'll need Git installed. If you are using Windows, replace `./gradlew` with `gradlew.bat` 43 | - `git clone https://github.com/SquidDev-CC/CCTweaks` 44 | - `./gradlew build` This should download all dependencies. You can test with `./gradlew runClient` 45 | - To get the deobfuscated sources run `./gradlew setupDecompWorkspace` 46 | 47 | Because of how the CCTweaks works, you may experience issues using the built in IDE tasks to run this project. 48 | 49 | ## Including in your own project 50 | CCTweaks is available on Maven. To include it in your project you will need the following code: 51 | 52 | ```groovy 53 | repositories { 54 | // Holds the main CCTweaks code 55 | maven { 56 | name = "squiddev" 57 | url = "https://dl.bintray.com/squiddev/maven" 58 | } 59 | } 60 | 61 | dependencies { 62 | compile "org.squiddev:CCTweaks:${mc_version}-${cctweaks_version}:dev" 63 | } 64 | ``` 65 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | jcenter() 5 | maven { 6 | name = "forge" 7 | url = "http://files.minecraftforge.net/maven" 8 | } 9 | } 10 | dependencies { 11 | classpath 'net.minecraftforge.gradle:ForgeGradle:2.2-SNAPSHOT' 12 | } 13 | } 14 | 15 | plugins { 16 | id 'com.matthewprenger.cursegradle' version '1.0.5' 17 | id "com.jfrog.bintray" version "1.4" 18 | } 19 | buildDir = "build-${mc_version}" 20 | apply plugin: 'net.minecraftforge.gradle.forge' 21 | 22 | group = "org.squiddev" 23 | archivesBaseName = "CCTweaks" 24 | version = mc_version + "-" + mod_version 25 | 26 | apply from: 'gradle/scripts/dependencies.gradle' 27 | apply from: 'gradle/scripts/artifacts.gradle' 28 | apply from: 'gradle/scripts/upload.gradle' 29 | apply from: 'gradle/scripts/documentation.gradle' 30 | apply from: 'gradle/scripts/jsonGen.gradle' 31 | 32 | minecraft { 33 | version = project.mc_version + "-" + project.forge_version 34 | runDir = "run-${project.mc_version}" 35 | mappings = "snapshot_20160518" 36 | 37 | replace '${mod_version}', project.mod_version 38 | replace '${mc_version}', project.mc_version 39 | replace '${cc_version}', project.cc_version 40 | } 41 | 42 | runClient.outputs.upToDateWhen { false } 43 | runServer.outputs.upToDateWhen { false } 44 | 45 | jar { 46 | manifest { 47 | attributes( 48 | 'FMLCorePlugin': 'org.squiddev.cctweaks.core.asm.TweaksLoadingPlugin', 49 | 'FMLCorePluginContainsFMLMod': 'true', 50 | 'FMLAT': 'CCTweaks_at.cfg', 51 | ) 52 | } 53 | 54 | // Package all the org.squiddev dependencies into one file 55 | from(configurations.shade.collect { it.isDirectory() ? it : zipTree(it) }) 56 | 57 | exclude("assets/**/docs") 58 | } 59 | 60 | sourceSets { 61 | main { 62 | java { 63 | srcDirs += 'src/api/java' 64 | } 65 | } 66 | } 67 | 68 | processResources { 69 | // this will ensure that this task is redone when the versions change. 70 | inputs.property "mod_version", project.mod_version 71 | inputs.property "mc_version", project.mc_version 72 | 73 | // replace stuff in mcmod.info, nothing else 74 | from(sourceSets.main.resources.srcDirs) { 75 | include 'mcmod.info' 76 | 77 | // Replace mod_version and mc_version 78 | expand 'mod_version': mod_version, 'mc_version': mc_version 79 | } 80 | 81 | // copy everything else, thats not the mcmod.info 82 | from(sourceSets.main.resources.srcDirs) { 83 | exclude 'mcmod.info' 84 | } 85 | } 86 | 87 | test { 88 | testLogging { 89 | events "passed", "skipped", "failed", "standardOut", "standardError" 90 | } 91 | } 92 | 93 | gradle.projectsEvaluated { 94 | tasks.withType(JavaCompile) { 95 | options.compilerArgs << "-Xlint" 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Mod stuff 2 | mc_version=1.10.2 3 | forge_version=12.18.2.2123 4 | mod_version=1.5.0-pr2 5 | 6 | # Various libraries 7 | cc_minor_version=build12 8 | cc_version=1.80pr0 9 | org.gradle.jvmargs=-Dfile.encoding=UTF-8 10 | # -Xmx3G 11 | -------------------------------------------------------------------------------- /gradle/scripts/artifacts.gradle: -------------------------------------------------------------------------------- 1 | task sourcesJar(type: Jar, dependsOn: classes) { 2 | from sourceSets.api.allSource 3 | classifier = "sources" 4 | } 5 | 6 | // Build the Javadocs for the API 7 | task javadocAPI(type: Javadoc) { 8 | source = sourceSets.api.java 9 | classpath = sourceSets.api.compileClasspath 10 | } 11 | 12 | // Package Javadocs into a Jar 13 | task javadocJar(type: Jar, dependsOn: javadocAPI) { 14 | from javadocAPI.destinationDir 15 | classifier = "javadoc" 16 | } 17 | 18 | // API dist Jar 19 | task apiJar(type: Jar) { 20 | from sourceSets.api.output 21 | classifier = 'api' 22 | } 23 | 24 | // Build a non-obfuscated jar 25 | task devJar(type: Jar) { 26 | manifest { 27 | attributes( 28 | 'FMLCorePlugin': 'org.squiddev.cctweaks.core.asm.TweaksLoadingPlugin', 29 | 'FMLCorePluginContainsFMLMod': 'true' 30 | ) 31 | } 32 | 33 | from sourceSets.main.output 34 | 35 | // Package all the org.squiddev dependencies into one file 36 | from configurations.shade.collect { it.isDirectory() ? it : zipTree(it) } 37 | 38 | classifier = 'dev' 39 | 40 | exclude("assets/**/docs") 41 | } 42 | 43 | // Sign the main jar 44 | task signJar(type: SignJar, dependsOn: reobfJar) { 45 | onlyIf { 46 | project.hasProperty('keyStore') 47 | } 48 | 49 | if(project.hasProperty('keyStore')) { 50 | keyStore = project.keyStore 51 | alias = project.keyStoreAlias 52 | storePass = project.keyStorePass 53 | keyPass = project.keyStoreKeyPass 54 | } 55 | 56 | inputFile = jar.archivePath 57 | outputFile = jar.archivePath 58 | } 59 | 60 | build.dependsOn signJar 61 | -------------------------------------------------------------------------------- /gradle/scripts/dependencies.gradle: -------------------------------------------------------------------------------- 1 | repositories { 2 | mavenCentral() 3 | jcenter() 4 | 5 | maven { 6 | name = "squiddev" 7 | url = "https://dl.bintray.com/squiddev/maven" 8 | } 9 | 10 | maven { 11 | name "IC2" 12 | url "http://maven.ic2.player.to" 13 | } 14 | 15 | maven { 16 | name "OpenMods" 17 | url "http://repo.openmods.info/artifactory/openmods" 18 | } 19 | 20 | maven { url "http://maven.amadornes.com/" } 21 | maven { url "http://dvs1.progwml6.com/files/maven" } 22 | 23 | maven { url = "https://cc.crzd.me/maven/" } // ComputerCraft 24 | 25 | ivy { 26 | name = "CoFHLib" 27 | artifactPattern "http://addons-origin.cursecdn.com/files/2235/558/[module]-[revision](.[ext])" 28 | } 29 | 30 | maven { url 'http://maven.epoxide.xyz' } // Tesla 31 | } 32 | 33 | configurations { 34 | shade 35 | compile.extendsFrom shade 36 | } 37 | 38 | dependencies { 39 | 40 | compile "dan200.computercraft:ComputerCraft:${project.cc_version}-${project.cc_minor_version}" 41 | deobfCompile "MCMultiPart:MCMultiPart:1.3.0:universal" 42 | deobfCompile "mezz.jei:jei_${project.mc_version}:3.14.3.403" 43 | 44 | // For 1.7.10 but including anyway 45 | provided "CoFHLib:CoFHLib:[1.7.10]1.0.1-159-dev" 46 | provided "net.industrial-craft:industrialcraft-2:2.3.249-ex18:api" 47 | provided "net.darkhax.tesla:Tesla:${mc_version}-1.2.1.50:deobf" 48 | 49 | shade("org.squiddev:cctweaks-lua:1.5.0-pr2") { 50 | // Different versions 51 | exclude group: 'com.google.guava' 52 | exclude group: 'org.ow2.asm' 53 | exclude group: 'io.netty' 54 | } 55 | 56 | shade('org.squiddev:Patcher:1.2.4') { exclude group: 'org.ow2.asm' } 57 | provided('org.squiddev:ConfigGen:1.2.5') { exclude group: 'net.minecraftforge' } 58 | 59 | testCompile group: "junit", name: "junit", version: "4.12" 60 | } 61 | -------------------------------------------------------------------------------- /gradle/scripts/upload.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'maven-publish' 2 | 3 | bintray { 4 | user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER') 5 | key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY') 6 | publications = ['mavenJava'] 7 | publish = true 8 | pkg { 9 | repo = 'maven' 10 | name = 'CCTweaks' 11 | licenses = ['MIT'] 12 | vcsUrl = 'https://github.com/SquidDev-CC/CCTweaks' 13 | version { 14 | name = project.version 15 | desc = 'Random additions to ComputerCraft' 16 | released = new Date() 17 | vcsTag = 'v' + project.version 18 | } 19 | } 20 | } 21 | 22 | publishing { 23 | publications { 24 | mavenJava(MavenPublication) { 25 | artifact jar 26 | artifact devJar 27 | 28 | artifact apiJar 29 | artifact sourcesJar 30 | artifact javadocJar 31 | } 32 | } 33 | } 34 | 35 | curseforge { 36 | apiKey = project.hasProperty('curseForgeApiKey') ? project.curseForgeApiKey : '' 37 | 38 | project { 39 | id = '232180' 40 | releaseType = 'release' 41 | changelog = '' 42 | addArtifact devJar 43 | 44 | relations { 45 | requiredLibrary 'computercraft' 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquidDev-CC/CCTweaks/17a716d61d40715ac854436fea097e828f12df40/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Aug 18 08:20:46 BST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'CCTweaks' 2 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/CCTweaksAPI.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api; 2 | 3 | /** 4 | * Main entry point for CCTweaks API 5 | */ 6 | public final class CCTweaksAPI { 7 | private static final ICCTweaksAPI API; 8 | 9 | /** 10 | * Get the main API entry point 11 | * 12 | * @return Main API entry point 13 | */ 14 | public static ICCTweaksAPI instance() { 15 | return API; 16 | } 17 | 18 | static { 19 | ICCTweaksAPI api; 20 | String name = "org.squiddev.cctweaks.core.API"; 21 | try { 22 | Class registryClass = Class.forName(name); 23 | api = (ICCTweaksAPI) registryClass.newInstance(); 24 | } catch (ClassNotFoundException e) { 25 | throw new CoreNotFoundException("Cannot load CCTweaks API as " + name + " cannot be found", e); 26 | } catch (InstantiationException e) { 27 | throw new CoreNotFoundException("Cannot load CCTweaks API as " + name + " cannot be created", e); 28 | } catch (IllegalAccessException e) { 29 | throw new CoreNotFoundException("Cannot load CCTweaks API as " + name + " cannot be accessed", e); 30 | } 31 | API = api; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/CoreNotFoundException.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api; 2 | 3 | /** 4 | * Thrown when we cannot load an API 5 | */ 6 | public class CoreNotFoundException extends RuntimeException { 7 | private static final long serialVersionUID = -3257530593207305353L; 8 | 9 | public CoreNotFoundException(String message, Throwable cause) { 10 | super(message, cause); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/ICCTweaksAPI.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api; 2 | 3 | import org.squiddev.cctweaks.api.block.IRotationRegistry; 4 | import org.squiddev.cctweaks.api.lua.ILuaEnvironment; 5 | import org.squiddev.cctweaks.api.network.INetworkHelpers; 6 | import org.squiddev.cctweaks.api.network.INetworkRegistry; 7 | import org.squiddev.cctweaks.api.peripheral.IPeripheralHelpers; 8 | import org.squiddev.cctweaks.api.turtle.ITurtleFuelRegistry; 9 | import org.squiddev.cctweaks.api.turtle.ITurtleRegistry; 10 | 11 | /** 12 | * A provider for the API interface 13 | */ 14 | public interface ICCTweaksAPI { 15 | INetworkRegistry networkRegistry(); 16 | 17 | INetworkHelpers networkHelpers(); 18 | 19 | ITurtleFuelRegistry fuelRegistry(); 20 | 21 | ITurtleRegistry turtleRegistry(); 22 | 23 | IPeripheralHelpers peripheralHelpers(); 24 | 25 | ILuaEnvironment luaEnvironment(); 26 | 27 | IRotationRegistry rotationRegistry(); 28 | } 29 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/IComputerItemFactory.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api; 2 | 3 | import dan200.computercraft.shared.computer.core.ComputerFamily; 4 | import net.minecraft.item.ItemStack; 5 | 6 | import javax.annotation.Nonnull; 7 | import javax.annotation.Nullable; 8 | import java.util.Set; 9 | 10 | /** 11 | * Implemented on {@link net.minecraft.item.Item}s to allow building stacks with specific attributes. 12 | */ 13 | public interface IComputerItemFactory { 14 | /** 15 | * Create a computer with a given ID 16 | * 17 | * @param id The id of the computer to create. 18 | * @param label Optional label for the computer 19 | * @param family The family of the computer to create. Will be once of the items in {@link #getSupportedFamilies()}. 20 | * @return The built item stack. 21 | */ 22 | @Nonnull 23 | ItemStack createComputer(int id, @Nullable String label, @Nonnull ComputerFamily family); 24 | 25 | @Nonnull 26 | Set getSupportedFamilies(); 27 | 28 | @Nonnull 29 | ComputerFamily getDefaultFamily(); 30 | } 31 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/IDataCard.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraft.nbt.NBTTagCompound; 6 | import net.minecraft.util.text.ITextComponent; 7 | import net.minecraft.util.text.TextComponentTranslation; 8 | 9 | import javax.annotation.Nonnull; 10 | import javax.annotation.Nullable; 11 | 12 | /** 13 | * A card that can be used to store/retrieve data 14 | */ 15 | public interface IDataCard { 16 | /** 17 | * Variable to return if no data is stored 18 | */ 19 | String EMPTY = "cctweaks.data.empty"; 20 | 21 | /** 22 | * Set the current data for this stack 23 | * 24 | * @param stack The stack to set the data for 25 | * @param type The type of data this card stores. {@link #getType} 26 | * @param data The data that this card stores {@link #getData} 27 | */ 28 | void setSettings(@Nonnull ItemStack stack, @Nonnull String type, @Nullable NBTTagCompound data); 29 | 30 | /** 31 | * Get the type this card stores. 32 | * 33 | * This will be translated using gui.tooltip.${name} and then ${name}. 34 | * 35 | * @param stack The stack to read the data from 36 | * @return The type this card contains or {@link #EMPTY} if nothing is stored 37 | */ 38 | @Nonnull 39 | String getType(@Nonnull ItemStack stack); 40 | 41 | /** 42 | * Get the data this card stores 43 | * 44 | * A string called "tooltip" will be displayed 45 | * A string called "details" will be displayed if F3+H is on 46 | * 47 | * @param stack The stack to read the data from 48 | * @return The data that is stored on this card 49 | */ 50 | @Nullable 51 | NBTTagCompound getData(@Nonnull ItemStack stack); 52 | 53 | /** 54 | * Notify the player of a card event 55 | * 56 | * @param player The player to notify 57 | * @param message The message to notify the player with 58 | */ 59 | void notifyPlayer(@Nonnull EntityPlayer player, @Nonnull Messages message); 60 | 61 | enum Messages { 62 | /** 63 | * Settings are loaded from the card 64 | */ 65 | Loaded, 66 | 67 | /** 68 | * Settings are stored on the card 69 | */ 70 | Stored, 71 | 72 | /** 73 | * Settings are cleared from the card 74 | */ 75 | Cleared; 76 | 77 | /** 78 | * Get the chat message for this data 79 | * 80 | * @return The chat message 81 | */ 82 | @Nonnull 83 | public ITextComponent getChatMessage() { 84 | return new TextComponentTranslation("chat.cctweaks.data.messages." + this.toString()); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/IWorldPosition.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api; 2 | 3 | import net.minecraft.util.math.BlockPos; 4 | import net.minecraft.world.IBlockAccess; 5 | 6 | import javax.annotation.Nonnull; 7 | 8 | /** 9 | * Helper interface for blocks that provide a position 10 | */ 11 | public interface IWorldPosition { 12 | /** 13 | * Get the world the block lies in 14 | * 15 | * @return The block's world 16 | */ 17 | IBlockAccess getBlockAccess(); 18 | 19 | /** 20 | * Get the position of the block 21 | * 22 | * @return The position of the block 23 | */ 24 | @Nonnull 25 | BlockPos getPosition(); 26 | } 27 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/UnorderedPair.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api; 2 | 3 | import javax.annotation.Nonnull; 4 | import javax.annotation.Nullable; 5 | 6 | /** 7 | * An unordered pair of objects with the same type. 8 | */ 9 | public class UnorderedPair { 10 | @Nonnull 11 | public final T x; 12 | 13 | @Nonnull 14 | public final T y; 15 | 16 | public UnorderedPair(@Nonnull T x, @Nonnull T y) { 17 | this.x = x; 18 | this.y = y; 19 | } 20 | 21 | /** 22 | * Gets the other object in the pair. 23 | * 24 | * @param obj The object that you don't want from this pair. 25 | * @return If obj is {@link #x}, returns {@link #y}. Else if obj is {@link #y}, returns {@link #x}. Else returns null. 26 | */ 27 | public T other(@Nonnull T obj) { 28 | if (obj.equals(x)) { 29 | return y; 30 | } else if (obj.equals(y)) { 31 | return x; 32 | } else { 33 | return null; 34 | } 35 | } 36 | 37 | /** 38 | * Determines if an object is one of this pair's elements. 39 | * 40 | * @param z An object to test against. 41 | * @return If {@link #x} or {@link #y} {@link #equals(Object)} the passed object. 42 | */ 43 | public boolean contains(@Nullable Object z) { 44 | return x.equals(z) || y.equals(z); 45 | } 46 | 47 | /** 48 | * Determine equality even if the other object has a different order. 49 | */ 50 | @Override 51 | public boolean equals(Object other) { 52 | if (other == this) { 53 | return true; 54 | } 55 | if (other instanceof UnorderedPair) { 56 | UnorderedPair pair = (UnorderedPair) other; 57 | if (x.equals(pair.x) && y.equals(pair.y)) { 58 | return true; 59 | } else if (y.equals(pair.x) && x.equals(pair.y)) { 60 | return true; 61 | } 62 | } 63 | return false; 64 | } 65 | 66 | /** 67 | * Symmetric hashcode. 68 | */ 69 | @Override 70 | public int hashCode() { 71 | return x.hashCode() ^ y.hashCode(); 72 | } 73 | 74 | @Override 75 | @Nonnull 76 | public String toString() { 77 | return String.format("<%s, %s>", x, y); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/block/BasicRotationHandler.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.block; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.block.state.IBlockState; 5 | import net.minecraft.util.EnumActionResult; 6 | import net.minecraft.util.EnumFacing; 7 | import net.minecraft.util.math.BlockPos; 8 | import net.minecraft.world.World; 9 | 10 | import javax.annotation.Nonnull; 11 | 12 | /** 13 | * A rotation handler which just changes the block state (after checking it can be placed on a side). 14 | */ 15 | public abstract class BasicRotationHandler implements IRotationHandler { 16 | private final boolean checkPlace; 17 | 18 | public BasicRotationHandler(boolean checkPlace) { 19 | this.checkPlace = checkPlace; 20 | } 21 | 22 | public BasicRotationHandler() { 23 | this.checkPlace = false; 24 | } 25 | 26 | @Nonnull 27 | protected abstract IBlockState setDirection(@Nonnull IBlockState state, @Nonnull EnumFacing facing, @Nonnull EnumFacing rotatorFacing); 28 | 29 | @Nonnull 30 | @Override 31 | public EnumActionResult rotate(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull IBlockState state, @Nonnull EnumFacing facing, @Nonnull EnumFacing rotatorFacing) { 32 | Block block = state.getBlock(); 33 | if (checkPlace && !block.canPlaceBlockOnSide(world, pos, facing)) { 34 | return EnumActionResult.FAIL; 35 | } 36 | 37 | world.setBlockState(pos, setDirection(state, facing, rotatorFacing)); 38 | return EnumActionResult.SUCCESS; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/block/IRotationHandler.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.block; 2 | 3 | import net.minecraft.block.state.IBlockState; 4 | import net.minecraft.util.EnumActionResult; 5 | import net.minecraft.util.EnumFacing; 6 | import net.minecraft.util.math.BlockPos; 7 | import net.minecraft.world.World; 8 | 9 | import javax.annotation.Nonnull; 10 | 11 | /** 12 | * A handler which attempts to rotate blocks 13 | */ 14 | public interface IRotationHandler { 15 | /** 16 | * Attempt to rotate the block in a set direction 17 | * 18 | * @param world The world the block is in 19 | * @param pos The position the block is in 20 | * @param state The current block state 21 | * @param facing The new direction to face 22 | * @param rotatorFacing The direction the rotator is facing. Will be {@link EnumFacing#NORTH} if unknown. 23 | * @return Whether rotating the block was successful 24 | */ 25 | @Nonnull 26 | EnumActionResult rotate(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull IBlockState state, @Nonnull EnumFacing facing, @Nonnull EnumFacing rotatorFacing); 27 | } 28 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/block/IRotationRegistry.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.block; 2 | 3 | import net.minecraft.block.Block; 4 | 5 | import javax.annotation.Nonnull; 6 | 7 | /** 8 | * A registry for registering rotation handlers. 9 | */ 10 | public interface IRotationRegistry extends IRotationHandler { 11 | /** 12 | * Register a generic rotation handler 13 | * 14 | * @param handler The handler to register 15 | */ 16 | void register(@Nonnull IRotationHandler handler); 17 | 18 | /** 19 | * Register a rotation handler for a specific block class 20 | * 21 | * @param targetClass The class to target. This will not target subclasses. 22 | * @param handler The handler to register. 23 | */ 24 | void register(@Nonnull Class targetClass, @Nonnull IRotationHandler handler); 25 | 26 | /** 27 | * Register a rotation handler for a specific block 28 | * 29 | * @param block The block to target. 30 | * @param handler The handler to register. 31 | */ 32 | void register(@Nonnull Block block, @Nonnull IRotationHandler handler); 33 | } 34 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/block/PropertyRotationHandler.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.block; 2 | 3 | import net.minecraft.block.properties.PropertyEnum; 4 | import net.minecraft.block.state.IBlockState; 5 | import net.minecraft.util.EnumActionResult; 6 | import net.minecraft.util.EnumFacing; 7 | import net.minecraft.util.math.BlockPos; 8 | import net.minecraft.world.World; 9 | 10 | import javax.annotation.Nonnull; 11 | 12 | /** 13 | * A rotation handler which just sets a property (after checking it can be placed on a side). 14 | */ 15 | public class PropertyRotationHandler extends BasicRotationHandler { 16 | private final PropertyEnum property; 17 | 18 | public PropertyRotationHandler(PropertyEnum property) { 19 | super(); 20 | this.property = property; 21 | } 22 | 23 | public PropertyRotationHandler(PropertyEnum property, boolean checkPlace) { 24 | super(checkPlace); 25 | this.property = property; 26 | } 27 | 28 | @Nonnull 29 | @Override 30 | protected IBlockState setDirection(@Nonnull IBlockState state, @Nonnull EnumFacing facing, @Nonnull EnumFacing rotatorFacing) { 31 | return state.withProperty(property, facing); 32 | } 33 | 34 | @Nonnull 35 | @Override 36 | public EnumActionResult rotate(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull IBlockState state, @Nonnull EnumFacing facing, @Nonnull EnumFacing rotatorFacing) { 37 | if (!property.getAllowedValues().contains(facing)) return EnumActionResult.FAIL; 38 | 39 | return super.rotate(world, pos, state, facing, rotatorFacing); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/computer/ICustomRomItem.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.computer; 2 | 3 | import net.minecraft.item.ItemStack; 4 | 5 | import javax.annotation.Nonnull; 6 | 7 | /** 8 | * A computer item which can be crafted with a disk in order to set a custom ROM. 9 | * 10 | * The id used is an that of a disk (and so refers to a folder in the /computercraft/disks directory). 11 | * 12 | * This will generate several recipes - you should avoid registering similar recipes in order to avoid conflicts. 13 | * - Crafting with a disk in order to set the ROM 14 | * - Crafting without a disk in order to remove the ROM 15 | * 16 | * When creating a computer, you should use {@link IExtendedServerComputer#setCustomRom(int)} in order to set the ROM 17 | * id. 18 | */ 19 | public interface ICustomRomItem { 20 | /** 21 | * Return whether this item has a custom ROM. 22 | * 23 | * @param stack The stack to check. 24 | * @return Whether this stack has a custom ROM. 25 | */ 26 | boolean hasCustomRom(@Nonnull ItemStack stack); 27 | 28 | /** 29 | * Get the custom ROM id. 30 | * 31 | * This should only be called if {@link #hasCustomRom(ItemStack)} is true. 32 | * 33 | * @param stack The stack to get the ROM from. 34 | * @return The custom ROM id. 35 | */ 36 | int getCustomRom(@Nonnull ItemStack stack); 37 | 38 | /** 39 | * Remove the custom ROM from this stack. 40 | * 41 | * @param stack The stack to clear. 42 | */ 43 | void clearCustomRom(@Nonnull ItemStack stack); 44 | 45 | /** 46 | * Set the custom ROM for this stack. 47 | * 48 | * @param stack The stack to set. 49 | * @param id The custom ROM id to set it to. 50 | */ 51 | void setCustomRom(@Nonnull ItemStack stack, int id); 52 | } 53 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/computer/IExtendedServerComputer.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.computer; 2 | 3 | import dan200.computercraft.shared.computer.core.IComputer; 4 | import dan200.computercraft.shared.computer.core.ServerComputer; 5 | 6 | /** 7 | * Various extension methods to {@link ServerComputer}. 8 | * 9 | * You should not implement this interface yourself. Instead, cast {@link ServerComputer} to this and use the resulting 10 | * object. 11 | */ 12 | public interface IExtendedServerComputer extends IComputer { 13 | /** 14 | * Set the custom ROM file to be the specified disk 15 | * 16 | * @param diskId The disk to use as a custom ROM. 17 | * @see ICustomRomItem 18 | */ 19 | void setCustomRom(int diskId); 20 | 21 | /** 22 | * Determine whether a computer is mostly on or not 23 | * 24 | * @return Whether this computer is on, starting up or about has a shutdown queued but is not shutdown. 25 | */ 26 | boolean isMostlyOn(); 27 | } 28 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/network/INetworkAccess.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.network; 2 | 3 | import dan200.computercraft.api.network.Packet; 4 | import dan200.computercraft.api.peripheral.IPeripheral; 5 | 6 | import javax.annotation.Nonnull; 7 | import java.util.Map; 8 | 9 | /** 10 | * Access object for a computer network 11 | */ 12 | public interface INetworkAccess { 13 | /** 14 | * Gets all peripherals on the network mapped by their names. 15 | * 16 | * @return The map of these peripherals. 17 | */ 18 | @Nonnull 19 | Map getPeripheralsOnNetwork(); 20 | 21 | /** 22 | * Invalidates the network. 23 | * Forces peripherals to be recalculated. 24 | */ 25 | void invalidateNetwork(); 26 | 27 | /** 28 | * Broadcasts a packet on the network. 29 | * Some networks may not be capable of packet transmission. 30 | * Such as the artificial network represented by computers' sides. 31 | * 32 | * @param packet The packet to transmit. 33 | * @return Whether the network was able to transmit the packet. 34 | */ 35 | boolean transmitPacket(@Nonnull Packet packet); 36 | } 37 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/network/INetworkCompatiblePeripheral.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.network; 2 | 3 | import dan200.computercraft.api.peripheral.IPeripheral; 4 | 5 | /** 6 | * A marker interface that allows turtle/pocket peripherals 7 | * to be exposed to the network. 8 | */ 9 | public interface INetworkCompatiblePeripheral extends IPeripheral { 10 | } 11 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/network/INetworkNodeProvider.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.network; 2 | 3 | import net.minecraft.tileentity.TileEntity; 4 | 5 | import javax.annotation.Nonnull; 6 | import javax.annotation.Nullable; 7 | 8 | /** 9 | * Provide a custom way to get a node. 10 | * 11 | * This can be used for blocks that do not implement {@link INetworkNode}. They should be registered 12 | * with {@link INetworkRegistry#addNodeProvider(INetworkNodeProvider)}. 13 | */ 14 | public interface INetworkNodeProvider { 15 | /** 16 | * Get the network node for the specific TileEntity 17 | * 18 | * @param tile The entity to get the node for 19 | * @return The node or {@code null} if it cannot be converted 20 | */ 21 | @Nullable 22 | IWorldNetworkNode getNode(@Nonnull TileEntity tile); 23 | 24 | /** 25 | * Checks if this TileEntity is a network node 26 | * 27 | * @param tile The entity to check 28 | * @return True if this can be converted into a node 29 | */ 30 | boolean isNode(@Nonnull TileEntity tile); 31 | } 32 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/network/INetworkRegistry.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.network; 2 | 3 | import net.minecraft.tileentity.TileEntity; 4 | import net.minecraft.util.math.BlockPos; 5 | import net.minecraft.world.IBlockAccess; 6 | import org.squiddev.cctweaks.api.IWorldPosition; 7 | 8 | import javax.annotation.Nonnull; 9 | import javax.annotation.Nullable; 10 | 11 | /** 12 | * Handles registration of node providers 13 | */ 14 | public interface INetworkRegistry { 15 | /** 16 | * Add a custom node provider. 17 | * 18 | * This should occur during the init stages of a mod 19 | * 20 | * @param provider The provider to register 21 | */ 22 | void addNodeProvider(@Nonnull INetworkNodeProvider provider); 23 | 24 | /** 25 | * Check if this block is a node 26 | * 27 | * @param world The world to check in 28 | * @param position Position of the block 29 | * @return If this block is a node 30 | */ 31 | boolean isNode(@Nonnull IBlockAccess world, @Nonnull BlockPos position); 32 | 33 | /** 34 | * Check if this tile is a node 35 | * 36 | * @param tile The tile to check 37 | * @return If this block is a node 38 | */ 39 | boolean isNode(@Nullable TileEntity tile); 40 | 41 | /** 42 | * Check if block tile is a node 43 | * 44 | * @param position The position to check 45 | * @return If this block is a node 46 | */ 47 | boolean isNode(@Nonnull IWorldPosition position); 48 | 49 | /** 50 | * Get the node for this position 51 | * 52 | * @param world The world to check in 53 | * @param position Position of the block 54 | * @return The node, or null if there is none 55 | */ 56 | @Nullable 57 | IWorldNetworkNode getNode(@Nonnull IBlockAccess world, @Nonnull BlockPos position); 58 | 59 | /** 60 | * Get the node from this tile entity 61 | * 62 | * @param tile The tile to check 63 | * @return The node, or null if there is none 64 | */ 65 | @Nullable 66 | IWorldNetworkNode getNode(@Nullable TileEntity tile); 67 | 68 | /** 69 | * Get the node for this position 70 | * 71 | * @param position The position to check 72 | * @return The node, or null if there is none 73 | */ 74 | @Nullable 75 | IWorldNetworkNode getNode(@Nonnull IWorldPosition position); 76 | } 77 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/network/INetworkedPeripheral.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.network; 2 | 3 | import dan200.computercraft.api.network.Packet; 4 | import dan200.computercraft.api.peripheral.IPeripheral; 5 | 6 | import javax.annotation.Nonnull; 7 | import java.util.Map; 8 | 9 | public interface INetworkedPeripheral extends INetworkCompatiblePeripheral { 10 | /** 11 | * Called when this peripheral is attached to a network access. 12 | * 13 | * @param network Access to the network being attached to. 14 | * @param name The name of this peripheral on that network. 15 | */ 16 | void attachToNetwork(@Nonnull INetworkAccess network, @Nonnull String name); 17 | 18 | /** 19 | * Called when this peripheral is detached from a network access. 20 | * 21 | * @param network Access to the network being detached from. 22 | * @param name The name of this peripheral on that network. 23 | */ 24 | void detachFromNetwork(@Nonnull INetworkAccess network, @Nonnull String name); 25 | 26 | /** 27 | * Called when the peripheral map on the network changes 28 | * 29 | * This is also called when attaching or detaching from a network with peripherals 30 | * 31 | * @param network The network that was invalidated. 32 | * @param oldPeripherals Peripherals removed from the network 33 | * @param newPeripherals Peripherals added to the network 34 | */ 35 | void networkInvalidated(@Nonnull INetworkAccess network, @Nonnull Map oldPeripherals, @Nonnull Map newPeripherals); 36 | 37 | /** 38 | * Called when the network receives a packet. 39 | * 40 | * @param network The network this packet was sent on. 41 | * @param packet The packet received. 42 | * @param distanceTravelled The distance that packet travelled. 43 | */ 44 | void receivePacket(@Nonnull INetworkAccess network, @Nonnull Packet packet, double distanceTravelled); 45 | } 46 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/network/IWorldNetworkNode.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.network; 2 | 3 | import net.minecraft.util.EnumFacing; 4 | import org.squiddev.cctweaks.api.IWorldPosition; 5 | 6 | import javax.annotation.Nonnull; 7 | 8 | /** 9 | * Represents an INetworkNode with a position in the world. 10 | */ 11 | public interface IWorldNetworkNode extends INetworkNode { 12 | /** 13 | * Get the position the node exists in in the world 14 | * 15 | * @return The node's position 16 | */ 17 | @Nonnull 18 | IWorldPosition getPosition(); 19 | 20 | /** 21 | * Get if the node can connect in this direction. 22 | * 23 | * This does not specify whether a connection exists, but if it can exist. 24 | * 25 | * @param direction The direction to check 26 | * @return If the node can connect 27 | */ 28 | boolean canConnect(@Nonnull EnumFacing direction); 29 | } 30 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/network/IWorldNetworkNodeHost.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.network; 2 | 3 | import javax.annotation.Nonnull; 4 | 5 | /** 6 | * An object that hosts a {@link IWorldNetworkNode}. 7 | * 8 | * Instead of implementing {@link IWorldNetworkNode} and delegating methods to it, 9 | * you can implement this interface instead. This is supported for TileEntities, multiparts 10 | * and on {@link dan200.computercraft.api.turtle.ITurtleUpgrade} 11 | */ 12 | public interface IWorldNetworkNodeHost { 13 | /** 14 | * Get this host's node. This should NEVER be null. 15 | * 16 | * @return The node this object holds 17 | */ 18 | @Nonnull 19 | IWorldNetworkNode getNode(); 20 | } 21 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/network/NetworkAPI.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.network; 2 | 3 | import org.squiddev.cctweaks.api.CCTweaksAPI; 4 | 5 | /** 6 | * Holds the main network API code 7 | */ 8 | public final class NetworkAPI { 9 | /** 10 | * Get the main registry instance 11 | * 12 | * @return The network registry 13 | */ 14 | public static INetworkRegistry registry() { 15 | return REGISTRY; 16 | } 17 | 18 | /** 19 | * Get the network helper instance 20 | * 21 | * @return The network helper instance 22 | */ 23 | public static INetworkHelpers helpers() { 24 | return HELPERS; 25 | } 26 | 27 | private static final INetworkRegistry REGISTRY = CCTweaksAPI.instance().networkRegistry(); 28 | private static final INetworkHelpers HELPERS = CCTweaksAPI.instance().networkHelpers(); 29 | } 30 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/package-info.java: -------------------------------------------------------------------------------- 1 | @API(apiVersion = "${mod_version}", owner = "CCTweaks", provides = "CCTweaks|API") 2 | package org.squiddev.cctweaks.api; 3 | 4 | import net.minecraftforge.fml.common.API; 5 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/peripheral/IPeripheralHelpers.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.peripheral; 2 | 3 | import dan200.computercraft.api.peripheral.IPeripheral; 4 | 5 | import javax.annotation.Nonnull; 6 | 7 | /** 8 | * Useful helpers for peripherals 9 | */ 10 | public interface IPeripheralHelpers { 11 | /** 12 | * Get the base peripheral by following a chain of {@link IPeripheralProxy}s. 13 | * 14 | * @param peripheral The peripheral 15 | * @return The base peripheral 16 | */ 17 | @Nonnull 18 | IPeripheral getBasePeripheral(@Nonnull IPeripheral peripheral); 19 | 20 | /** 21 | * Gets the target peripheral for this peripheral. 22 | * 23 | * If it does not implement {@link IPeripheralTargeted} then it will attempt to find 24 | * the parent peripheral using {@link IPeripheralProxy} and start the search again. 25 | * 26 | * @param peripheral The peripheral to find 27 | * @return The target or the last peripheral we found 28 | */ 29 | @Nonnull 30 | Object getTarget(@Nonnull IPeripheral peripheral); 31 | } 32 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/peripheral/IPeripheralHidden.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.peripheral; 2 | 3 | import dan200.computercraft.api.peripheral.IPeripheral; 4 | 5 | import javax.annotation.Nullable; 6 | 7 | /** 8 | * A peripheral that cannot be accessed on a network, only 9 | * by a computer or turtle. 10 | * 11 | * You may want to implement this on network nodes, 12 | * so users do not attempt to connect to them using modems. 13 | */ 14 | public interface IPeripheralHidden extends IPeripheral { 15 | /** 16 | * Get the network only peripheral 17 | * 18 | * @return The peripheral to use on the network or {@code null} if none needed. 19 | */ 20 | @Nullable 21 | IPeripheral getNetworkPeripheral(); 22 | } 23 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/peripheral/IPeripheralHost.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.peripheral; 2 | 3 | import dan200.computercraft.api.peripheral.IPeripheral; 4 | import net.minecraft.util.EnumFacing; 5 | 6 | import javax.annotation.Nonnull; 7 | import javax.annotation.Nullable; 8 | 9 | /** 10 | * An object that hosts a {@link IPeripheral}. 11 | * 12 | * Instead of implementing {@link IPeripheral} and delegating methods to it, 13 | * you can implement this interface instead. This is supported for TileEntities 14 | * and multiparts. 15 | */ 16 | public interface IPeripheralHost { 17 | /** 18 | * Get this host's peripheral 19 | * 20 | * @param side The side to get the peripheral from 21 | * @return The peripheral this object holds 22 | */ 23 | @Nullable 24 | IPeripheral getPeripheral(@Nonnull EnumFacing side); 25 | } 26 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/peripheral/IPeripheralProxy.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.peripheral; 2 | 3 | import dan200.computercraft.api.peripheral.IPeripheral; 4 | 5 | import javax.annotation.Nullable; 6 | 7 | /** 8 | * Used to denote a peripheral that delegates to another peripheral. 9 | * 10 | * This does not automatically delegate, use {@link IPeripheralHost} for that, 11 | * this is simply a method of getting the base peripheral if additional 12 | * processing needs to occur on that instead. 13 | * 14 | * You should always implement {@link IPeripheral}. 15 | * You should implement {@link org.squiddev.cctweaks.api.network.INetworkedPeripheral} 16 | * if you wish to delegate network events. 17 | * 18 | * You can get the base peripheral using {@link IPeripheralHelpers#getBasePeripheral(IPeripheral)}. 19 | */ 20 | public interface IPeripheralProxy extends IPeripheral { 21 | /** 22 | * Get the base peripheral for this peripheral 23 | * 24 | * @return The peripheral this delegates to 25 | */ 26 | @Nullable 27 | IPeripheral getBasePeripheral(); 28 | } 29 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/peripheral/IPeripheralTargeted.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.peripheral; 2 | 3 | import dan200.computercraft.api.peripheral.IPeripheral; 4 | 5 | import javax.annotation.Nullable; 6 | 7 | /** 8 | * Used to denote a peripheral that targets a TileEntity or other object in game 9 | * 10 | * You can get the target of a peripheral using {@link IPeripheralHelpers#getTarget(IPeripheral)}. 11 | */ 12 | public interface IPeripheralTargeted extends IPeripheral { 13 | /** 14 | * Get the object this peripheral targets. This is generally a TileEntity 15 | * 16 | * @return The target 17 | */ 18 | @Nullable 19 | Object getTarget(); 20 | } 21 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/turtle/AbstractTurtleInteraction.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.turtle; 2 | 3 | import dan200.computercraft.api.lua.LuaException; 4 | import dan200.computercraft.api.peripheral.IComputerAccess; 5 | import dan200.computercraft.api.turtle.ITurtleAccess; 6 | import dan200.computercraft.api.turtle.TurtleCommandResult; 7 | import net.minecraft.item.Item; 8 | import net.minecraft.item.ItemStack; 9 | import net.minecraft.util.EnumFacing; 10 | import net.minecraft.util.math.RayTraceResult; 11 | import net.minecraftforge.common.util.FakePlayer; 12 | 13 | import javax.annotation.Nonnull; 14 | 15 | /** 16 | * Abstract implementation of {@link ITurtleInteraction} with no methods implemented. 17 | * It is probably a good idea to override at least one of them. 18 | * 19 | * @see ITurtleRegistry#registerInteraction(ITurtleInteraction) 20 | * @see ITurtleRegistry#registerInteraction(Item, ITurtleInteraction) 21 | */ 22 | public abstract class AbstractTurtleInteraction implements ITurtleInteraction { 23 | @Override 24 | public TurtleCommandResult swing(@Nonnull ITurtleAccess turtle, @Nonnull IComputerAccess computer, @Nonnull FakePlayer player, @Nonnull ItemStack stack, @Nonnull EnumFacing direction, RayTraceResult hit) throws LuaException { 25 | return null; 26 | } 27 | 28 | @Override 29 | public boolean canSwing(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull ItemStack stack, @Nonnull EnumFacing direction, RayTraceResult hit) { 30 | return false; 31 | } 32 | 33 | @Override 34 | public TurtleCommandResult use(@Nonnull ITurtleAccess turtle, @Nonnull IComputerAccess computer, @Nonnull FakePlayer player, @Nonnull ItemStack stack, @Nonnull EnumFacing direction, RayTraceResult hit) throws LuaException { 35 | return null; 36 | } 37 | 38 | @Override 39 | public boolean canUse(@Nonnull ITurtleAccess turtle, @Nonnull FakePlayer player, @Nonnull ItemStack stack, @Nonnull EnumFacing direction, RayTraceResult hit) { 40 | return false; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/turtle/IExtendedTurtleUpgrade.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.turtle; 2 | 3 | import dan200.computercraft.api.turtle.ITurtleAccess; 4 | import dan200.computercraft.api.turtle.ITurtleUpgrade; 5 | import dan200.computercraft.api.turtle.TurtleSide; 6 | 7 | import javax.annotation.Nonnull; 8 | import javax.annotation.Nullable; 9 | 10 | /** 11 | * Extended functionality for turtle upgrades. 12 | */ 13 | public interface IExtendedTurtleUpgrade extends ITurtleUpgrade { 14 | /** 15 | * Fired when an upgrade has changed on the turtle 16 | * 17 | * @param turtle The turtle the upgrade has changed on 18 | * @param side The side this upgrade is attached to. The opposite side is the one which has changed. 19 | * @param oldUpgrade The old upgrade. May be {@code null}. 20 | * @param newUpgrade The new upgrade. May be {@code null}. 21 | */ 22 | void upgradeChanged(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, @Nullable ITurtleUpgrade oldUpgrade, @Nullable ITurtleUpgrade newUpgrade); 23 | } 24 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/turtle/ITurtleFuelProvider.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.turtle; 2 | 3 | import dan200.computercraft.api.turtle.ITurtleAccess; 4 | import net.minecraft.item.ItemStack; 5 | 6 | import javax.annotation.Nonnull; 7 | 8 | /** 9 | * Provides a method of refueling turtles to be registered 10 | * with {@link ITurtleFuelRegistry#addFuelProvider(ITurtleFuelProvider)} 11 | */ 12 | public interface ITurtleFuelProvider { 13 | /** 14 | * Check if the turtle can refuel from this item 15 | * 16 | * @param turtle The turtle to refuel 17 | * @param stack The fuel to refuel with 18 | * @return If a refuel can occur 19 | */ 20 | boolean canRefuel(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack); 21 | 22 | /** 23 | * Refuels the turtle. 24 | * This should consume the stack but not add fuel to the turtle. 25 | * 26 | * @param turtle The turtle to refuel 27 | * @param stack The fuel to refuel with 28 | * @param limit The maximum number of items to consume 29 | * @return The fuel added to the turtle 30 | */ 31 | int refuel(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, int limit); 32 | } 33 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/turtle/ITurtleFuelRegistry.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.turtle; 2 | 3 | import dan200.computercraft.api.turtle.ITurtleAccess; 4 | import net.minecraft.item.ItemStack; 5 | 6 | import javax.annotation.Nonnull; 7 | import javax.annotation.Nullable; 8 | 9 | /** 10 | * Register custom fuel providers 11 | */ 12 | public interface ITurtleFuelRegistry { 13 | /** 14 | * Add a fuel provider. 15 | * 16 | * Ideally this should be done in the init stages of a mod, though it doesn't matter too much. 17 | * 18 | * @param provider The fuel provider to register with 19 | */ 20 | void addFuelProvider(@Nonnull ITurtleFuelProvider provider); 21 | 22 | /** 23 | * Get a provider for this fuel 24 | * 25 | * @param turtle The turtle we will refuel 26 | * @param stack The fuel to refuel with 27 | * @return The provider, or {@code null} if none found. 28 | * @see ITurtleFuelProvider#canRefuel(ITurtleAccess, ItemStack) 29 | */ 30 | @Nullable 31 | ITurtleFuelProvider getProvider(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack); 32 | } 33 | -------------------------------------------------------------------------------- /src/api/java/org/squiddev/cctweaks/api/turtle/ITurtleRegistry.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.api.turtle; 2 | 3 | import net.minecraft.item.Item; 4 | 5 | import javax.annotation.Nonnull; 6 | 7 | /** 8 | * Registry for various turtle features 9 | */ 10 | public interface ITurtleRegistry { 11 | /** 12 | * Register an interaction 13 | * 14 | * @param interaction The interaction to use 15 | */ 16 | void registerInteraction(@Nonnull ITurtleInteraction interaction); 17 | 18 | /** 19 | * Register an interaction for a specific item 20 | * 21 | * @param item The item to use 22 | * @param interaction The interaction to use 23 | */ 24 | void registerInteraction(@Nonnull Item item, @Nonnull ITurtleInteraction interaction); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/GuiHandler.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks; 2 | 3 | import dan200.computercraft.ComputerCraft; 4 | import dan200.computercraft.shared.computer.core.ClientComputer; 5 | import dan200.computercraft.shared.computer.core.ComputerFamily; 6 | import dan200.computercraft.shared.computer.core.ServerComputer; 7 | import net.minecraft.entity.player.EntityPlayer; 8 | import net.minecraft.world.World; 9 | import net.minecraftforge.fml.common.network.IGuiHandler; 10 | import org.squiddev.cctweaks.client.gui.GuiAnyComputer; 11 | import org.squiddev.cctweaks.command.ContainerAnyComputer; 12 | import org.squiddev.cctweaks.core.utils.Helpers; 13 | 14 | public class GuiHandler implements IGuiHandler { 15 | private static final ComputerFamily[] FAMILIES = ComputerFamily.values(); 16 | private static final int GUI_COMPUTER = 101; 17 | 18 | @Override 19 | public Object getServerGuiElement(int id, EntityPlayer player, World world, int arg1, int arg2, int arg3) { 20 | switch (id) { 21 | case GUI_COMPUTER: { 22 | ServerComputer computer = ComputerCraft.serverComputerRegistry.get(arg1); 23 | return computer == null ? null : new ContainerAnyComputer(computer); 24 | } 25 | default: 26 | return null; 27 | } 28 | } 29 | 30 | @Override 31 | public Object getClientGuiElement(int id, EntityPlayer player, World world, int arg1, int arg2, int arg3) { 32 | switch (id) { 33 | case GUI_COMPUTER: { 34 | ClientComputer computer = ComputerCraft.clientComputerRegistry.get(arg1); 35 | ComputerFamily family; 36 | if (arg2 >= 0 && arg2 <= FAMILIES.length) { 37 | family = FAMILIES[arg2]; 38 | } else { 39 | family = computer.isColour() ? ComputerFamily.Advanced : ComputerFamily.Normal; 40 | } 41 | return computer == null ? null : new GuiAnyComputer(computer, family); 42 | } 43 | default: 44 | return null; 45 | } 46 | } 47 | 48 | public static void openComputer(EntityPlayer player, ServerComputer computer) { 49 | player.openGui( 50 | CCTweaks.instance, GUI_COMPUTER, player.getEntityWorld(), 51 | computer.getInstanceID(), Helpers.guessFamily(computer).ordinal(), 0 52 | ); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/blocks/IMultiBlock.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.blocks; 2 | 3 | /** 4 | * Interface to be implemented by {@link BlockBase} for blocks that represent more than one object 5 | */ 6 | public interface IMultiBlock { 7 | /** 8 | * Get the unlocalised name for this damage value 9 | * 10 | * @param meta Metadata value 11 | * @return The metadata value 12 | */ 13 | String getUnlocalizedName(int meta); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/blocks/TileLazyNBT.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.blocks; 2 | 3 | import net.minecraft.nbt.NBTBase; 4 | import net.minecraft.nbt.NBTTagCompound; 5 | import org.squiddev.cctweaks.core.McEvents; 6 | 7 | import javax.annotation.Nonnull; 8 | 9 | /** 10 | * A tile entity that lazy loads NBT. 11 | * 12 | * We need this as some things need to happen once the world 13 | * has been loaded (such as peripherals). 14 | */ 15 | public abstract class TileLazyNBT extends TileBase { 16 | private NBTTagCompound lazyTag; 17 | 18 | /** 19 | * Lazy load the NBT tag 20 | * 21 | * @param tag The NBT tag to load 22 | */ 23 | public abstract void readLazyNBT(NBTTagCompound tag); 24 | 25 | /** 26 | * The fields that the tag stores. 27 | * 28 | * Used in the rare case that we are saving without having had an update tick 29 | * 30 | * @return The list of fields to keep 31 | */ 32 | public abstract Iterable getFields(); 33 | 34 | @Override 35 | public void create() { 36 | super.create(); 37 | McEvents.schedule(new Runnable() { 38 | @Override 39 | public void run() { 40 | if (lazyTag != null) { 41 | readLazyNBT(lazyTag); 42 | lazyTag = null; 43 | } 44 | } 45 | }); 46 | } 47 | 48 | @Override 49 | public void readFromNBT(NBTTagCompound tag) { 50 | super.readFromNBT(tag); 51 | if (worldObj == null) { 52 | lazyTag = tag; 53 | } else { 54 | readLazyNBT(tag); 55 | } 56 | } 57 | 58 | @Nonnull 59 | @Override 60 | public NBTTagCompound writeToNBT(NBTTagCompound tag) { 61 | tag = super.writeToNBT(tag); 62 | if (lazyTag != null) { 63 | for (String field : getFields()) { 64 | NBTBase fieldTag = lazyTag.getTag(field); 65 | if (fieldTag != null) tag.setTag(field, fieldTag); 66 | } 67 | } 68 | return tag; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/blocks/debug/TileDebugNode.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.blocks.debug; 2 | 3 | import dan200.computercraft.api.network.Packet; 4 | import dan200.computercraft.api.peripheral.IPeripheral; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.squiddev.cctweaks.api.IWorldPosition; 7 | import org.squiddev.cctweaks.blocks.network.TileNetworked; 8 | import org.squiddev.cctweaks.core.network.AbstractWorldNode; 9 | import org.squiddev.cctweaks.core.utils.DebugLogger; 10 | 11 | import javax.annotation.Nonnull; 12 | import java.util.Map; 13 | 14 | /** 15 | * A network node that logs events to the console 16 | */ 17 | public class TileDebugNode extends TileNetworked { 18 | protected final AbstractWorldNode node = new AbstractWorldNode() { 19 | @Nonnull 20 | @Override 21 | public IWorldPosition getPosition() { 22 | return TileDebugNode.this; 23 | } 24 | 25 | @Override 26 | public void receivePacket(@Nonnull Packet packet, double distanceTravelled) { 27 | DebugLogger.debug("Received packet from " + distanceTravelled + " blocks away"); 28 | } 29 | 30 | @Override 31 | public void networkInvalidated(@Nonnull Map oldPeripherals, @Nonnull Map newPeripherals) { 32 | DebugLogger.debug( 33 | "Node invalidated at %s, %s, %s\n - Removed: %s\n - Added: %s", 34 | pos.getX(), pos.getY(), pos.getZ(), 35 | StringUtils.join(oldPeripherals.keySet(), ", "), 36 | StringUtils.join(newPeripherals.keySet(), ", ") 37 | ); 38 | } 39 | }; 40 | 41 | @Nonnull 42 | @Override 43 | public AbstractWorldNode getNode() { 44 | return node; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/blocks/network/TileNetworked.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.blocks.network; 2 | 3 | import org.squiddev.cctweaks.api.network.IWorldNetworkNodeHost; 4 | import org.squiddev.cctweaks.blocks.TileBase; 5 | import org.squiddev.cctweaks.core.network.AbstractWorldNode; 6 | import org.squiddev.cctweaks.core.network.NetworkHelpers; 7 | 8 | import javax.annotation.Nonnull; 9 | 10 | /** 11 | * Abstract world node host 12 | */ 13 | public abstract class TileNetworked extends TileBase implements IWorldNetworkNodeHost { 14 | @Nonnull 15 | @Override 16 | public abstract AbstractWorldNode getNode(); 17 | 18 | @Override 19 | public void create() { 20 | super.create(); 21 | NetworkHelpers.scheduleConnect(getNode(), this); 22 | } 23 | 24 | @Override 25 | public void destroy() { 26 | super.destroy(); 27 | getNode().destroy(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/client/CustomModelLoader.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.client; 2 | 3 | import net.minecraft.client.renderer.block.model.IBakedModel; 4 | import net.minecraft.client.renderer.block.model.ModelResourceLocation; 5 | import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 6 | import net.minecraft.util.ResourceLocation; 7 | import net.minecraftforge.client.event.ModelBakeEvent; 8 | import net.minecraftforge.client.event.TextureStitchEvent; 9 | import net.minecraftforge.client.model.ModelLoader; 10 | import net.minecraftforge.client.model.ModelLoaderRegistry; 11 | import net.minecraftforge.common.MinecraftForge; 12 | import net.minecraftforge.common.model.TRSRTransformation; 13 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 14 | import net.minecraftforge.fml.relauncher.Side; 15 | import net.minecraftforge.fml.relauncher.SideOnly; 16 | import org.squiddev.cctweaks.CCTweaks; 17 | import org.squiddev.cctweaks.core.registry.IClientModule; 18 | import org.squiddev.cctweaks.core.registry.Module; 19 | 20 | /** 21 | * Loader for models that aren't associated with a block 22 | * 23 | * Mostly for 24 | */ 25 | public class CustomModelLoader extends Module implements IClientModule { 26 | @SubscribeEvent 27 | @SideOnly(Side.CLIENT) 28 | public void onModelBakeEvent(ModelBakeEvent event) { 29 | loadModel(event, "wireless_bridge_turtle_left"); 30 | loadModel(event, "wireless_bridge_turtle_right"); 31 | } 32 | 33 | @SubscribeEvent 34 | @SideOnly(Side.CLIENT) 35 | public void onTextureStitchEvent(TextureStitchEvent.Pre event) { 36 | // I didn't think I had to do this. Odd. 37 | event.getMap().registerSprite(new ResourceLocation(CCTweaks.ID, "blocks/wireless_bridge_small")); 38 | } 39 | 40 | @SideOnly(Side.CLIENT) 41 | private void loadModel(ModelBakeEvent event, String name) { 42 | IBakedModel model; 43 | try { 44 | model = ModelLoaderRegistry 45 | .getModel(new ResourceLocation(CCTweaks.ID, "block/" + name)) 46 | .bake(TRSRTransformation.identity(), DefaultVertexFormats.BLOCK, ModelLoader.defaultTextureGetter()); 47 | } catch (Exception e) { 48 | model = event.getModelManager().getMissingModel(); 49 | } 50 | 51 | event.getModelRegistry().putObject(new ModelResourceLocation(new ResourceLocation(CCTweaks.ID, name), "inventory"), model); 52 | } 53 | 54 | @Override 55 | @SideOnly(Side.CLIENT) 56 | public void clientPreInit() { 57 | MinecraftForge.EVENT_BUS.register(this); 58 | } 59 | 60 | @Override 61 | @SideOnly(Side.CLIENT) 62 | public void clientInit() { 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/client/gui/GuiAnyComputer.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.client.gui; 2 | 3 | import dan200.computercraft.client.gui.GuiComputer; 4 | import dan200.computercraft.shared.computer.core.ComputerFamily; 5 | import dan200.computercraft.shared.computer.core.IComputer; 6 | import net.minecraftforge.fml.relauncher.Side; 7 | import net.minecraftforge.fml.relauncher.SideOnly; 8 | import org.squiddev.cctweaks.command.ContainerAnyComputer; 9 | 10 | @SideOnly(Side.CLIENT) 11 | public class GuiAnyComputer extends GuiComputer { 12 | public GuiAnyComputer(IComputer computer, ComputerFamily family) { 13 | super( 14 | new ContainerAnyComputer(computer), family, computer, 15 | computer.getTerminal().getWidth(), computer.getTerminal().getHeight() 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/client/gui/GuiConfigCCTweaks.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.client.gui; 2 | 3 | import net.minecraft.client.gui.GuiScreen; 4 | import net.minecraftforge.common.config.ConfigElement; 5 | import net.minecraftforge.fml.client.config.GuiConfig; 6 | import net.minecraftforge.fml.client.config.IConfigElement; 7 | import org.squiddev.cctweaks.CCTweaks; 8 | import org.squiddev.cctweaks.core.Config; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class GuiConfigCCTweaks extends GuiConfig { 14 | 15 | public GuiConfigCCTweaks(GuiScreen screen) { 16 | super(screen, getConfigElements(), CCTweaks.ID, false, false, CCTweaks.NAME); 17 | } 18 | 19 | @SuppressWarnings("rawtypes") 20 | private static List getConfigElements() { 21 | ArrayList elements = new ArrayList(); 22 | for (String category : Config.configuration.getCategoryNames()) { 23 | if (!category.contains(".")) elements.add(new ConfigElement(Config.configuration.getCategory(category))); 24 | } 25 | return elements; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/client/gui/GuiConfigFactory.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.client.gui; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.client.gui.GuiScreen; 5 | import net.minecraftforge.fml.client.IModGuiFactory; 6 | 7 | import java.util.Set; 8 | 9 | public class GuiConfigFactory implements IModGuiFactory { 10 | @Override 11 | public void initialize(Minecraft minecraft) { 12 | } 13 | 14 | @Override 15 | public Class mainConfigGuiClass() { 16 | return GuiConfigCCTweaks.class; 17 | } 18 | 19 | @Override 20 | public Set runtimeGuiCategories() { 21 | return null; 22 | } 23 | 24 | @Override 25 | @SuppressWarnings("deprecation") 26 | public RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement runtimeOptionCategoryElement) { 27 | return null; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/command/ContainerAnyComputer.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.command; 2 | 3 | import dan200.computercraft.ComputerCraft; 4 | import dan200.computercraft.shared.computer.blocks.TileComputerBase; 5 | import dan200.computercraft.shared.computer.core.IComputer; 6 | import dan200.computercraft.shared.computer.core.IContainerComputer; 7 | import dan200.computercraft.shared.computer.core.ServerComputer; 8 | import net.minecraft.entity.player.EntityPlayer; 9 | import net.minecraft.inventory.Container; 10 | import org.squiddev.cctweaks.core.utils.Helpers; 11 | 12 | import javax.annotation.Nonnull; 13 | import javax.annotation.Nullable; 14 | 15 | public class ContainerAnyComputer extends Container implements IContainerComputer { 16 | private final IComputer computer; 17 | 18 | public ContainerAnyComputer(IComputer computer) { 19 | this.computer = computer; 20 | } 21 | 22 | @Override 23 | public boolean canInteractWith(@Nonnull EntityPlayer player) { 24 | if (computer instanceof ServerComputer) { 25 | ServerComputer computer = (ServerComputer) this.computer; 26 | 27 | // Ensure the computer is still loaded 28 | if (!ComputerCraft.serverComputerRegistry.contains(computer.getInstanceID())) { 29 | return false; 30 | } 31 | 32 | TileComputerBase tileBase = Helpers.getTile(computer); 33 | if (tileBase != null && !tileBase.isUsable(player, true)) { 34 | return false; 35 | } 36 | } 37 | 38 | return true; 39 | } 40 | 41 | @Nullable 42 | @Override 43 | public IComputer getComputer() { 44 | return computer; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/API.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core; 2 | 3 | import org.squiddev.cctweaks.api.ICCTweaksAPI; 4 | import org.squiddev.cctweaks.api.block.IRotationRegistry; 5 | import org.squiddev.cctweaks.api.lua.ILuaEnvironment; 6 | import org.squiddev.cctweaks.api.network.INetworkHelpers; 7 | import org.squiddev.cctweaks.api.network.INetworkRegistry; 8 | import org.squiddev.cctweaks.api.peripheral.IPeripheralHelpers; 9 | import org.squiddev.cctweaks.api.turtle.ITurtleFuelRegistry; 10 | import org.squiddev.cctweaks.api.turtle.ITurtleRegistry; 11 | import org.squiddev.cctweaks.core.block.RotationRegistry; 12 | import org.squiddev.cctweaks.core.network.NetworkHelpers; 13 | import org.squiddev.cctweaks.core.network.NetworkRegistry; 14 | import org.squiddev.cctweaks.core.peripheral.PeripheralHelpers; 15 | import org.squiddev.cctweaks.core.turtle.TurtleFuelRegistry; 16 | import org.squiddev.cctweaks.core.turtle.TurtleRegistry; 17 | import org.squiddev.cctweaks.lua.lib.LuaEnvironment; 18 | 19 | /** 20 | * The implementation for {@link org.squiddev.cctweaks.api.CCTweaksAPI} 21 | */ 22 | public final class API implements ICCTweaksAPI { 23 | private final INetworkRegistry networkRegistry = new NetworkRegistry(); 24 | private final INetworkHelpers networkHelpers = new NetworkHelpers(); 25 | 26 | private final ITurtleFuelRegistry fuelRegistry = new TurtleFuelRegistry(); 27 | private final IPeripheralHelpers peripheralHelpers = new PeripheralHelpers(); 28 | private final IRotationRegistry rotationRegistry = new RotationRegistry(); 29 | 30 | @Override 31 | public INetworkRegistry networkRegistry() { 32 | return networkRegistry; 33 | } 34 | 35 | @Override 36 | public INetworkHelpers networkHelpers() { 37 | return networkHelpers; 38 | } 39 | 40 | @Override 41 | public ITurtleFuelRegistry fuelRegistry() { 42 | return fuelRegistry; 43 | } 44 | 45 | @Override 46 | public ITurtleRegistry turtleRegistry() { 47 | return TurtleRegistry.instance; 48 | } 49 | 50 | @Override 51 | public IPeripheralHelpers peripheralHelpers() { 52 | return peripheralHelpers; 53 | } 54 | 55 | @Override 56 | public ILuaEnvironment luaEnvironment() { 57 | return LuaEnvironment.instance; 58 | } 59 | 60 | @Override 61 | public IRotationRegistry rotationRegistry() { 62 | return rotationRegistry; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/asm/SetCustomRom.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.asm; 2 | 3 | import org.objectweb.asm.ClassVisitor; 4 | import org.objectweb.asm.Label; 5 | import org.objectweb.asm.MethodVisitor; 6 | import org.objectweb.asm.tree.InsnList; 7 | import org.objectweb.asm.tree.MethodInsnNode; 8 | import org.objectweb.asm.tree.VarInsnNode; 9 | import org.squiddev.patcher.transformer.IPatcher; 10 | import org.squiddev.patcher.visitors.FindingVisitor; 11 | 12 | import static org.objectweb.asm.Opcodes.*; 13 | 14 | /** 15 | * Sets {@link org.squiddev.cctweaks.core.patch.ServerComputer_Patch#setCustomRom(int)} for computers 16 | */ 17 | public class SetCustomRom implements IPatcher { 18 | @Override 19 | public boolean matches(String className) { 20 | return className.equals("dan200.computercraft.shared.computer.blocks.TileComputerBase"); 21 | } 22 | 23 | @Override 24 | public ClassVisitor patch(String className, ClassVisitor delegate) throws Exception { 25 | return new FindingVisitor( 26 | delegate, 27 | new MethodInsnNode(INVOKEVIRTUAL, "dan200/computercraft/shared/computer/blocks/TileComputerBase", "createComputer", "(II)Ldan200/computercraft/shared/computer/core/ServerComputer;", false), 28 | new VarInsnNode(ASTORE, 2) 29 | ) { 30 | @Override 31 | public void handle(InsnList nodes, MethodVisitor visitor) { 32 | nodes.accept(visitor); 33 | 34 | Label finish = new Label(); 35 | 36 | visitor.visitVarInsn(ALOAD, 0); 37 | visitor.visitFieldInsn(GETFIELD, "dan200/computercraft/shared/computer/blocks/TileComputerBase", "hasDisk", "Z"); 38 | visitor.visitJumpInsn(IFEQ, finish); 39 | 40 | visitor.visitVarInsn(ALOAD, 2); 41 | visitor.visitVarInsn(ALOAD, 0); 42 | visitor.visitFieldInsn(GETFIELD, "dan200/computercraft/shared/computer/blocks/TileComputerBase", "diskId", "I"); 43 | visitor.visitMethodInsn(INVOKEVIRTUAL, "dan200/computercraft/shared/computer/core/ServerComputer", "setCustomRom", "(I)V", false); 44 | 45 | visitor.visitLabel(finish); 46 | } 47 | }.onMethod("createServerComputer").once().mustFind(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/asm/SetSuspendable.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.asm; 2 | 3 | import org.objectweb.asm.ClassVisitor; 4 | import org.objectweb.asm.MethodVisitor; 5 | import org.objectweb.asm.tree.InsnList; 6 | import org.objectweb.asm.tree.MethodInsnNode; 7 | import org.objectweb.asm.tree.VarInsnNode; 8 | import org.squiddev.patcher.transformer.IPatcher; 9 | import org.squiddev.patcher.visitors.FindingVisitor; 10 | 11 | import static org.objectweb.asm.Opcodes.*; 12 | 13 | /** 14 | * Sets {@link org.squiddev.cctweaks.core.patch.ServerComputer_Patch#setSuspendable()} for computers 15 | */ 16 | public class SetSuspendable implements IPatcher { 17 | @Override 18 | public boolean matches(String className) { 19 | return className.equals("dan200.computercraft.shared.computer.blocks.TileComputerBase"); 20 | } 21 | 22 | @Override 23 | public ClassVisitor patch(String className, ClassVisitor delegate) throws Exception { 24 | return new FindingVisitor( 25 | delegate, 26 | new MethodInsnNode(INVOKEVIRTUAL, "dan200/computercraft/shared/computer/blocks/TileComputerBase", "createComputer", "(II)Ldan200/computercraft/shared/computer/core/ServerComputer;", false), 27 | new VarInsnNode(ASTORE, 2) 28 | ) { 29 | @Override 30 | public void handle(InsnList nodes, MethodVisitor visitor) { 31 | nodes.accept(visitor); 32 | 33 | visitor.visitVarInsn(ALOAD, 2); 34 | visitor.visitMethodInsn(INVOKEVIRTUAL, "dan200/computercraft/shared/computer/core/ServerComputer", "setSuspendable", "()V", false); 35 | } 36 | }.onMethod("createServerComputer").once().mustFind(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/collections/MapChanges.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.collections; 2 | 3 | import java.util.Map; 4 | 5 | import static java.util.Collections.unmodifiableMap; 6 | 7 | /** 8 | * Represents keys and values removed/added from pairs 9 | */ 10 | public final class MapChanges { 11 | private final Map removed; 12 | private final Map added; 13 | 14 | public MapChanges(Map removed, Map added) { 15 | this.removed = unmodifiableMap(removed); 16 | this.added = unmodifiableMap(added); 17 | } 18 | 19 | public Map removed() { 20 | return removed; 21 | } 22 | 23 | public Map added() { 24 | return added; 25 | } 26 | 27 | public void apply(Map map) { 28 | for (K entry : removed().keySet()) { 29 | map.remove(entry); 30 | } 31 | map.putAll(added); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/collections/MapsX.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.collections; 2 | 3 | import com.google.common.base.Equivalence; 4 | 5 | import java.util.Map; 6 | import java.util.Set; 7 | 8 | import static com.google.common.collect.Maps.newHashMap; 9 | 10 | /** 11 | * Even more map collection classes 12 | */ 13 | public final class MapsX { 14 | private MapsX() { 15 | } 16 | 17 | public static void removeAll(Map original, Set keys) { 18 | for (K key : keys) { 19 | original.remove(key); 20 | } 21 | } 22 | 23 | public static void removeAll(Map original, Map toRemove) { 24 | for (K key : toRemove.keySet()) { 25 | original.remove(key); 26 | } 27 | } 28 | 29 | public static void putAll(Map original, Map toPut) { 30 | original.putAll(toPut); 31 | } 32 | 33 | public static MapChanges changes( 34 | Map left, 35 | Map right 36 | ) { 37 | return changes(left, right, Equivalence.equals()); 38 | } 39 | 40 | public static MapChanges changes( 41 | Map left, 42 | Map right, 43 | Equivalence valueEquivalence 44 | ) { 45 | Map removed = newHashMap(); 46 | Map added = newHashMap(right); 47 | 48 | for (Map.Entry entry : left.entrySet()) { 49 | K leftKey = entry.getKey(); 50 | V leftValue = entry.getValue(); 51 | if (right.containsKey(leftKey)) { 52 | V rightValue = added.get(leftKey); 53 | if (valueEquivalence.equivalent(leftValue, rightValue)) { 54 | added.remove(leftKey); 55 | } else { 56 | removed.put(leftKey, leftValue); 57 | } 58 | } else { 59 | removed.put(leftKey, leftValue); 60 | } 61 | } 62 | 63 | return new MapChanges(removed, added); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/command/CommandContext.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.command; 2 | 3 | import com.google.common.collect.Lists; 4 | import net.minecraft.command.ICommandSender; 5 | import net.minecraft.server.MinecraftServer; 6 | 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | /** 11 | * Represents the way a command was invoked, including the command sender, the current server and 12 | * the "path" to this command. 13 | */ 14 | public final class CommandContext { 15 | private final MinecraftServer server; 16 | private final ICommandSender sender; 17 | private final List path; 18 | 19 | public CommandContext(MinecraftServer server, ICommandSender sender, ISubCommand initial) { 20 | this.server = server; 21 | this.sender = sender; 22 | this.path = Collections.singletonList(initial); 23 | } 24 | 25 | private CommandContext(MinecraftServer server, ICommandSender sender, List path) { 26 | this.server = server; 27 | this.sender = sender; 28 | this.path = path; 29 | } 30 | 31 | public CommandContext enter(ISubCommand child) { 32 | List newPath = Lists.newArrayListWithExpectedSize(path.size() + 1); 33 | newPath.addAll(path); 34 | newPath.add(child); 35 | return new CommandContext(server, sender, newPath); 36 | } 37 | 38 | public CommandContext parent() { 39 | if (path.size() == 1) throw new IllegalStateException("No parent command"); 40 | return new CommandContext(server, sender, path.subList(0, path.size() - 1)); 41 | } 42 | 43 | public String getFullPath() { 44 | StringBuilder out = new StringBuilder(); 45 | boolean first = true; 46 | for (ISubCommand command : path) { 47 | if (first) { 48 | first = false; 49 | } else { 50 | out.append(' '); 51 | } 52 | 53 | out.append(command.getName()); 54 | } 55 | 56 | return out.toString(); 57 | } 58 | 59 | public String getFullUsage() { 60 | return "/" + getFullPath() + " " + path.get(path.size() - 1).getUsage(this); 61 | } 62 | 63 | public List getPath() { 64 | return Collections.unmodifiableList(path); 65 | } 66 | 67 | public String getRootCommand() { 68 | return path.get(0).getName(); 69 | } 70 | 71 | public MinecraftServer getServer() { 72 | return server; 73 | } 74 | 75 | public ICommandSender getSender() { 76 | return sender; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/command/CommandDelegate.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.command; 2 | 3 | import net.minecraft.command.CommandBase; 4 | import net.minecraft.command.CommandException; 5 | import net.minecraft.command.ICommandSender; 6 | import net.minecraft.server.MinecraftServer; 7 | import net.minecraft.util.math.BlockPos; 8 | import org.squiddev.cctweaks.core.utils.DebugLogger; 9 | 10 | import javax.annotation.Nonnull; 11 | import javax.annotation.Nullable; 12 | import java.util.Arrays; 13 | import java.util.Collections; 14 | import java.util.List; 15 | 16 | /** 17 | * {@link net.minecraft.command.ICommand} which delegates to a {@link ISubCommand}. 18 | */ 19 | public class CommandDelegate extends CommandBase { 20 | private final ISubCommand command; 21 | 22 | public CommandDelegate(ISubCommand command) { 23 | this.command = command; 24 | } 25 | 26 | @Nonnull 27 | @Override 28 | public String getCommandName() { 29 | return command.getName(); 30 | } 31 | 32 | @Nonnull 33 | @Override 34 | public String getCommandUsage(@Nonnull ICommandSender sender) { 35 | return "/" + command.getName() + " " + command.getUsage(new CommandContext(sender.getServer(), sender, command)); 36 | } 37 | 38 | @Nonnull 39 | @Override 40 | public List getCommandAliases() { 41 | return Collections.emptyList(); 42 | } 43 | 44 | @Override 45 | public void execute(@Nonnull MinecraftServer server, @Nonnull ICommandSender sender, @Nonnull String[] args) throws CommandException { 46 | try { 47 | command.execute(new CommandContext(server, sender, command), Arrays.asList(args)); 48 | } catch (CommandException e) { 49 | throw e; 50 | } catch (Throwable e) { 51 | DebugLogger.debug("Unhandled exception in command", e); 52 | throw new CommandException("Unhandled exception: " + e.toString()); 53 | } 54 | } 55 | 56 | @Nonnull 57 | @Override 58 | public List getTabCompletionOptions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos pos) { 59 | return command.getCompletion(new CommandContext(server, sender, command), Arrays.asList(args)); 60 | } 61 | 62 | @Override 63 | public boolean checkPermission(MinecraftServer server, ICommandSender sender) { 64 | return command.userLevel().canExecute(new CommandContext(server, sender, command)); 65 | } 66 | 67 | 68 | @Override 69 | public int getRequiredPermissionLevel() { 70 | return command.userLevel().toLevel(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/command/ISubCommand.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.command; 2 | 3 | import net.minecraft.command.CommandException; 4 | 5 | import javax.annotation.Nonnull; 6 | import java.util.List; 7 | 8 | /** 9 | * A slightly different implementation of {@link net.minecraft.command.ICommand} which is delegated to. 10 | */ 11 | public interface ISubCommand { 12 | /** 13 | * Get the name of this command 14 | * 15 | * @return The name of this command 16 | */ 17 | @Nonnull 18 | String getName(); 19 | 20 | /** 21 | * Get the usage of this command 22 | * 23 | * @return The usage of this command 24 | * @param context The context this command is executed in 25 | */ 26 | @Nonnull 27 | String getUsage(CommandContext context); 28 | 29 | /** 30 | * Get a short description of this command, including its usage. 31 | * 32 | * @return The command's synopsis 33 | */ 34 | @Nonnull 35 | String getSynopsis(); 36 | 37 | /** 38 | * Get the lengthy description of this command. This synopsis is prepended to this. 39 | * 40 | * @return The command's description 41 | */ 42 | @Nonnull 43 | String getDescription(); 44 | 45 | /** 46 | * Determine the level this command requires. 47 | * 48 | * @return The user level the player must have in order to execute it. 49 | */ 50 | UserLevel userLevel(); 51 | 52 | /** 53 | * Execute this command 54 | * 55 | * @param context The current command context. 56 | * @param arguments The arguments passed @throws CommandException When an error occurs 57 | */ 58 | void execute(@Nonnull CommandContext context, @Nonnull List arguments) throws CommandException; 59 | 60 | /** 61 | * Get a list of possible completions 62 | * 63 | * @param context The current command context. 64 | * @param arguments The arguments passed. You should complete the last one. 65 | * @return List of possible completions 66 | */ 67 | @Nonnull 68 | List getCompletion(@Nonnull CommandContext context, @Nonnull List arguments); 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/command/SubCommandBase.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.command; 2 | 3 | import javax.annotation.Nonnull; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | public abstract class SubCommandBase implements ISubCommand { 8 | private final String name; 9 | private final String usage; 10 | private final String synopsis; 11 | private final String description; 12 | private final UserLevel level; 13 | 14 | public SubCommandBase(String name, String usage, String synopsis, UserLevel level, String description) { 15 | this.name = name; 16 | this.usage = usage; 17 | this.synopsis = synopsis; 18 | this.description = description; 19 | this.level = level; 20 | } 21 | 22 | public SubCommandBase(String name, String synopsis, UserLevel level, String description) { 23 | this(name, "", synopsis, level, description); 24 | } 25 | 26 | @Nonnull 27 | @Override 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | @Nonnull 33 | @Override 34 | public String getUsage(CommandContext context) { 35 | return usage; 36 | } 37 | 38 | @Nonnull 39 | @Override 40 | public String getSynopsis() { 41 | return synopsis; 42 | } 43 | 44 | @Nonnull 45 | @Override 46 | public String getDescription() { 47 | return description; 48 | } 49 | 50 | @Override 51 | public UserLevel userLevel() { 52 | return level; 53 | } 54 | 55 | @Nonnull 56 | @Override 57 | public List getCompletion(@Nonnull CommandContext context, @Nonnull List arguments) { 58 | return Collections.emptyList(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/command/UserLevel.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.command; 2 | 3 | import net.minecraft.command.ICommandSender; 4 | import net.minecraft.entity.player.EntityPlayerMP; 5 | import net.minecraft.server.MinecraftServer; 6 | 7 | /** 8 | * The level a user must be at in order to execute a command. 9 | */ 10 | public enum UserLevel { 11 | /** 12 | * Only can be used by the owner of the server: namely the server console or the player in SSP. 13 | */ 14 | OWNER, 15 | 16 | /** 17 | * Can only be used by ops. 18 | */ 19 | OP, 20 | 21 | /** 22 | * Can be used by any op, or the player in SSP. 23 | */ 24 | OWNER_OP, 25 | 26 | /** 27 | * Can be used by anyone. 28 | */ 29 | ANYONE; 30 | 31 | public int toLevel() { 32 | switch (this) { 33 | case OWNER: 34 | return 4; 35 | case OP: 36 | case OWNER_OP: 37 | return 2; 38 | case ANYONE: 39 | default: 40 | return 0; 41 | } 42 | } 43 | 44 | public boolean canExecute(CommandContext context) { 45 | if (this == ANYONE) return true; 46 | 47 | // We *always* allow level 0 stuff, even if the 48 | MinecraftServer server = context.getServer(); 49 | ICommandSender sender = context.getSender(); 50 | 51 | if (server.isSinglePlayer() && sender instanceof EntityPlayerMP && 52 | ((EntityPlayerMP) sender).getGameProfile().getName().equalsIgnoreCase(server.getServerOwner())) { 53 | if (this == OWNER || this == OWNER_OP) return true; 54 | } 55 | 56 | return sender.canCommandSenderUseCommand(toLevel(), context.getRootCommand()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/network/AbstractNode.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network; 2 | 3 | import com.google.common.base.Preconditions; 4 | import dan200.computercraft.api.network.Packet; 5 | import dan200.computercraft.api.peripheral.IPeripheral; 6 | import org.squiddev.cctweaks.api.network.INetworkController; 7 | import org.squiddev.cctweaks.api.network.INetworkNode; 8 | 9 | import javax.annotation.Nonnull; 10 | import java.util.Collections; 11 | import java.util.Map; 12 | 13 | /** 14 | * A base node class 15 | */ 16 | public abstract class AbstractNode implements INetworkNode { 17 | /** 18 | * The network this modem is attached to. 19 | */ 20 | private INetworkController networkController; 21 | 22 | @Nonnull 23 | @Override 24 | public Map getConnectedPeripherals() { 25 | return Collections.emptyMap(); 26 | } 27 | 28 | @Override 29 | public void receivePacket(@Nonnull Packet packet, double distanceTravelled) { 30 | } 31 | 32 | @Override 33 | public void networkInvalidated(@Nonnull Map oldPeripherals, @Nonnull Map newPeripherals) { 34 | } 35 | 36 | @Override 37 | public void detachFromNetwork() { 38 | if (networkController == null) { 39 | throw new IllegalStateException("Not connected to network"); 40 | } 41 | 42 | networkController = null; 43 | } 44 | 45 | @Override 46 | public void attachToNetwork(@Nonnull INetworkController networkController) { 47 | Preconditions.checkNotNull(networkController, "networkController cannot be null"); 48 | if (this.networkController != null) { 49 | throw new IllegalStateException("Already connected"); 50 | } 51 | 52 | this.networkController = networkController; 53 | } 54 | 55 | @Override 56 | public INetworkController getAttachedNetwork() { 57 | return networkController; 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | String name = getClass().getName(); 63 | return name.substring(name.lastIndexOf('.') + 1) + "@" + Integer.toHexString(this.hashCode()); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/network/AbstractWorldNode.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network; 2 | 3 | import net.minecraft.util.EnumFacing; 4 | import net.minecraft.util.math.BlockPos; 5 | import org.squiddev.cctweaks.api.IWorldPosition; 6 | import org.squiddev.cctweaks.api.network.INetworkController; 7 | import org.squiddev.cctweaks.api.network.INetworkNode; 8 | import org.squiddev.cctweaks.api.network.IWorldNetworkNode; 9 | import org.squiddev.cctweaks.api.network.NetworkAPI; 10 | 11 | import javax.annotation.Nonnull; 12 | import java.util.Set; 13 | 14 | /** 15 | * Basic world network node class with additional methods 16 | */ 17 | public abstract class AbstractWorldNode extends AbstractNode implements IWorldNetworkNode { 18 | @Override 19 | public boolean canConnect(@Nonnull EnumFacing direction) { 20 | return true; 21 | } 22 | 23 | /** 24 | * Get the adjacent nodes. 25 | * 26 | * This is primarily used when choosing a network to connect to. 27 | * Use {@link org.squiddev.cctweaks.core.network.cable.BasicCable} if you need 28 | * more advanced handling. 29 | * 30 | * This set can be modified in place. 31 | */ 32 | public Set getConnectedNodes() { 33 | return NetworkAPI.helpers().getAdjacentNodes(this); 34 | } 35 | 36 | /** 37 | * Attempt to connect to {@link #getConnectedNodes()} using {@link NetworkHelpers#joinOrCreateNetwork(INetworkNode, Set)} 38 | */ 39 | public void connect() { 40 | NetworkAPI.helpers().joinOrCreateNetwork(this, getConnectedNodes()); 41 | } 42 | 43 | /** 44 | * Remove this node from the network 45 | */ 46 | public void destroy() { 47 | INetworkController controller = getAttachedNetwork(); 48 | if (controller != null) controller.removeNode(this); 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | IWorldPosition position = getPosition(); 54 | BlockPos pos = position.getPosition(); 55 | return super.toString() + String.format(" (%s, %s, %s)", pos.getX(), pos.getY(), pos.getZ()); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/network/NetworkAccessDelegate.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network; 2 | 3 | import dan200.computercraft.api.network.Packet; 4 | import dan200.computercraft.api.peripheral.IPeripheral; 5 | import org.squiddev.cctweaks.api.network.INetworkAccess; 6 | 7 | import javax.annotation.Nonnull; 8 | import java.util.HashMap; 9 | import java.util.HashSet; 10 | import java.util.Map; 11 | import java.util.Set; 12 | 13 | /** 14 | * A {@link INetworkAccess} implementation that delegates to other networks 15 | */ 16 | public class NetworkAccessDelegate implements INetworkAccess { 17 | private final Set networks = new HashSet(); 18 | 19 | @Nonnull 20 | @Override 21 | public Map getPeripheralsOnNetwork() { 22 | // We can't cache this at all as we can't receive network changed events 23 | Map peripherals = new HashMap(); 24 | for (INetworkAccess network : networks) { 25 | peripherals.putAll(network.getPeripheralsOnNetwork()); 26 | } 27 | return peripherals; 28 | } 29 | 30 | @Override 31 | public void invalidateNetwork() { 32 | for (INetworkAccess network : networks) { 33 | network.invalidateNetwork(); 34 | } 35 | } 36 | 37 | @Override 38 | public boolean transmitPacket(@Nonnull Packet packet) { 39 | // To consider, should we always fail if one fails, or succeed if one succeeds? 40 | 41 | boolean success = false; 42 | for (INetworkAccess network : networks) { 43 | success |= network.transmitPacket(packet); 44 | } 45 | return success; 46 | } 47 | 48 | public void add(INetworkAccess network) { 49 | networks.add(network); 50 | } 51 | 52 | public void remove(INetworkAccess network) { 53 | networks.remove(network); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/network/bridge/NetworkBindingPeripheral.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network.bridge; 2 | 3 | import dan200.computercraft.api.lua.ILuaContext; 4 | import dan200.computercraft.api.lua.LuaException; 5 | import dan200.computercraft.api.peripheral.IComputerAccess; 6 | import dan200.computercraft.api.peripheral.IPeripheral; 7 | 8 | import javax.annotation.Nonnull; 9 | 10 | /** 11 | * org.squiddev.cctweaks.core.network.bridge (CC-Tweaks 12 | */ 13 | public class NetworkBindingPeripheral implements IPeripheral { 14 | private final NetworkBindingWithModem binding; 15 | 16 | public NetworkBindingPeripheral(NetworkBindingWithModem binding) { 17 | this.binding = binding; 18 | } 19 | 20 | @Nonnull 21 | @Override 22 | public String getType() { 23 | return "network_binding"; 24 | } 25 | 26 | @Nonnull 27 | @Override 28 | public String[] getMethodNames() { 29 | return new String[]{"getOpenRemote", "openRemote", "closeRemote"}; 30 | } 31 | 32 | @Override 33 | public Object[] callMethod(@Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments) throws LuaException, InterruptedException { 34 | switch (method) { 35 | case 0: { 36 | Integer id = binding.getId(); 37 | if (id == null) { 38 | return new Object[]{false}; 39 | } else { 40 | return new Object[]{id}; 41 | } 42 | } 43 | 44 | case 1: { 45 | if (arguments.length == 0 || !(arguments[0] instanceof Number)) { 46 | throw new LuaException("Expected number"); 47 | } 48 | 49 | if (binding.getId() != null) throw new LuaException("Already open"); 50 | 51 | binding.setId(((Number) arguments[0]).intValue()); 52 | binding.markDirty(); 53 | return null; 54 | } 55 | 56 | case 2: { 57 | if (binding.getId() == null) throw new LuaException("Not opened"); 58 | binding.removeId(); 59 | binding.markDirty(); 60 | return null; 61 | } 62 | } 63 | 64 | return null; 65 | } 66 | 67 | @Override 68 | public void attach(@Nonnull IComputerAccess iComputerAccess) { 69 | 70 | } 71 | 72 | @Override 73 | public void detach(@Nonnull IComputerAccess iComputerAccess) { 74 | 75 | } 76 | 77 | @Override 78 | public boolean equals(IPeripheral peripheral) { 79 | return equals((Object) peripheral); 80 | } 81 | 82 | @Override 83 | public boolean equals(Object o) { 84 | if (this == o) return true; 85 | if (!(o instanceof NetworkBindingPeripheral)) return false; 86 | 87 | NetworkBindingPeripheral that = (NetworkBindingPeripheral) o; 88 | 89 | return binding.equals(that.binding); 90 | 91 | } 92 | 93 | @Override 94 | public int hashCode() { 95 | return binding.hashCode(); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/network/cable/BasicCable.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network.cable; 2 | 3 | import com.google.common.collect.Sets; 4 | import net.minecraft.util.EnumFacing; 5 | import org.squiddev.cctweaks.api.UnorderedPair; 6 | import org.squiddev.cctweaks.api.network.INetworkHelpers; 7 | import org.squiddev.cctweaks.api.network.INetworkNode; 8 | import org.squiddev.cctweaks.api.network.NetworkAPI; 9 | import org.squiddev.cctweaks.core.network.AbstractWorldNode; 10 | 11 | import java.util.Collections; 12 | import java.util.Set; 13 | 14 | /** 15 | * A world node that caches where it can connect to and 16 | * handles adding and removing connections 17 | */ 18 | public abstract class BasicCable extends AbstractWorldNode { 19 | private int connMap; 20 | private Set connections = Collections.emptySet(); 21 | 22 | protected boolean updateConnectionMap() { 23 | int map = 0; 24 | 25 | INetworkHelpers helpers = NetworkAPI.helpers(); 26 | for (EnumFacing dir : EnumFacing.VALUES) { 27 | if (canConnect(dir) && helpers.canConnect(getPosition(), dir)) { 28 | map |= 1 << dir.ordinal(); 29 | } 30 | } 31 | 32 | if (connMap != map) { 33 | connMap = map; 34 | return true; 35 | } else { 36 | return false; 37 | } 38 | } 39 | 40 | /** 41 | * Update the connection map. 42 | * 43 | * On a server, this will also connect/disconnect networks 44 | * 45 | * @return If the connections changed 46 | */ 47 | public boolean updateConnections() { 48 | if (getAttachedNetwork() != null) { 49 | Set attachedNodes = connections; 50 | Set newNodes = connections = getConnectedNodes(); 51 | 52 | for (INetworkNode newNode : Sets.difference(newNodes, attachedNodes)) { 53 | getAttachedNetwork().formConnection(this, newNode); 54 | } 55 | 56 | for (INetworkNode removedNode : Sets.difference(attachedNodes, newNodes)) { 57 | UnorderedPair connection = new UnorderedPair(this, removedNode); 58 | 59 | // The network can/will change whilst the loop is iterating. 60 | if (getAttachedNetwork().getNodeConnections().contains(connection)) { 61 | getAttachedNetwork().breakConnection(connection); 62 | } 63 | } 64 | } 65 | 66 | return updateConnectionMap(); 67 | } 68 | 69 | @Override 70 | public void connect() { 71 | super.connect(); 72 | updateConnections(); 73 | } 74 | 75 | public boolean doesConnect(EnumFacing dir) { 76 | int flag = 1 << dir.ordinal(); 77 | return (connMap & flag) == flag; 78 | } 79 | 80 | @Override 81 | public String toString() { 82 | return "Cable: " + super.toString(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/network/cable/CableWithInternalSidedParts.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network.cable; 2 | 3 | import net.minecraft.util.EnumFacing; 4 | 5 | public abstract class CableWithInternalSidedParts extends BasicCable { 6 | private int internalConnMap; 7 | 8 | public abstract boolean canConnectInternally(EnumFacing direction); 9 | 10 | private boolean doesConnectInternally(EnumFacing direction) { 11 | int flag = 1 << direction.ordinal(); 12 | return (internalConnMap & flag) == flag; 13 | } 14 | 15 | public boolean doesConnectVisually(EnumFacing direction) { 16 | return doesConnect(direction) || doesConnectInternally(direction); 17 | } 18 | 19 | protected boolean updateInternalConnectionMap() { 20 | int map = 0; 21 | for (EnumFacing dir : EnumFacing.VALUES) { 22 | if (canConnectInternally(dir)) { 23 | map |= 1 << dir.ordinal(); 24 | } 25 | } 26 | 27 | if (map != internalConnMap) { 28 | internalConnMap = map; 29 | return true; 30 | } else { 31 | return false; 32 | } 33 | } 34 | 35 | @Override 36 | public boolean updateConnections() { 37 | return updateInternalConnectionMap() | super.updateConnections(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/network/cable/SingleModemCable.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network.cable; 2 | 3 | import net.minecraft.util.EnumFacing; 4 | import org.squiddev.cctweaks.api.network.INetworkNode; 5 | import org.squiddev.cctweaks.core.network.modem.DirectionalPeripheralModem; 6 | 7 | import java.util.Set; 8 | 9 | public abstract class SingleModemCable extends CableWithInternalSidedParts { 10 | public abstract DirectionalPeripheralModem getModem(); 11 | 12 | @Override 13 | public boolean canConnectInternally(EnumFacing dir) { 14 | return getModem().getDirection() == dir; 15 | } 16 | 17 | @Override 18 | public void connect() { 19 | super.connect(); 20 | getAttachedNetwork().formConnection(this, getModem()); 21 | } 22 | 23 | @Override 24 | public Set getConnectedNodes() { 25 | Set nodes = super.getConnectedNodes(); 26 | nodes.add(getModem()); 27 | return nodes; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/network/controller/NodeScanner.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network.controller; 2 | 3 | import org.squiddev.cctweaks.api.network.INetworkController; 4 | import org.squiddev.cctweaks.api.network.INetworkNode; 5 | 6 | import java.util.*; 7 | 8 | /** 9 | * Scans a list of points, putting each group of connected nodes in an individual network. 10 | */ 11 | public class NodeScanner { 12 | /** 13 | * Scan a network and create a series of sub networks, based off connections 14 | * 15 | * @param controller The parent controller 16 | * @param points The points to start scanning at 17 | * @return The created networks 18 | */ 19 | public static Collection> scanNetwork(INetworkController controller, Point... points) { 20 | return scanNetwork(controller, Arrays.asList(points)); 21 | } 22 | 23 | /** 24 | * Scan a network and create a series of sub networks, based off connections 25 | * 26 | * @param controller The parent controller 27 | * @param points The points to start scanning at 28 | * @return The created networks. Will return an empty list if no changes are needed. 29 | */ 30 | public static Collection> scanNetwork(INetworkController controller, Collection points) { 31 | if (points.size() <= 1) { 32 | return Collections.emptyList(); 33 | } 34 | 35 | int nodes = controller.getNodesOnNetwork().size(); 36 | 37 | HashSet seen = new HashSet(nodes); 38 | HashSet remainingPoints = new HashSet(points); 39 | List> networks = new ArrayList>(); 40 | 41 | boolean first = true; 42 | for (Point point : points) { 43 | if (!seen.add(point)) continue; 44 | 45 | remainingPoints.remove(point); 46 | 47 | HashMap network = new HashMap(nodes); 48 | networks.add(network); 49 | 50 | Queue queue = new LinkedList(); 51 | queue.add(point); 52 | 53 | while ((point = queue.poll()) != null) { 54 | network.put(point.node, point); 55 | 56 | for (Point.Connection connection : point.connections) { 57 | Point other = connection.other(point); 58 | if (seen.add(other)) { 59 | // If we've only got one network and we don't need to visit any 60 | // other nodes then we are fine to abort. 61 | if (first && remainingPoints.remove(other) && remainingPoints.isEmpty()) { 62 | return Collections.emptyList(); 63 | } 64 | 65 | queue.add(other); 66 | } 67 | } 68 | } 69 | 70 | first = false; 71 | } 72 | 73 | return networks; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/network/modem/ControllableModemPeripheral.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network.modem; 2 | 3 | import dan200.computercraft.api.lua.ILuaContext; 4 | import dan200.computercraft.api.lua.LuaException; 5 | import dan200.computercraft.api.peripheral.IComputerAccess; 6 | 7 | import javax.annotation.Nonnull; 8 | 9 | /** 10 | * A modem peripheral that can be enabled/disabled 11 | */ 12 | public class ControllableModemPeripheral extends BasicModemPeripheral { 13 | private final int methodLength; 14 | 15 | public ControllableModemPeripheral(T modem) { 16 | super(modem); 17 | methodLength = super.getMethodNames().length; 18 | } 19 | 20 | @Nonnull 21 | @Override 22 | public String[] getMethodNames() { 23 | String[] methods = super.getMethodNames(); 24 | String[] newMethods = new String[methods.length + 2]; 25 | System.arraycopy(methods, 0, newMethods, 0, methods.length); 26 | 27 | int l = methods.length; 28 | newMethods[l] = "enableRemote"; 29 | newMethods[l + 1] = "disableRemote"; 30 | 31 | return newMethods; 32 | } 33 | 34 | @Override 35 | public Object[] callMethod(@Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments) throws LuaException, InterruptedException { 36 | switch (method - methodLength) { 37 | case 0: { // enableRemote 38 | if (!modem.isPeripheralEnabled()) { 39 | modem.setPeripheralEnabled(true); 40 | modem.updateEnabled(); 41 | modem.refreshState(); 42 | 43 | if (modem.isPeripheralEnabled()) changed = true; 44 | } 45 | 46 | return new Object[]{modem.isPeripheralEnabled()}; 47 | } 48 | case 1: { // disableRemote 49 | if (modem.isPeripheralEnabled()) { 50 | modem.setPeripheralEnabled(false); 51 | modem.refreshState(); 52 | 53 | if (!modem.isPeripheralEnabled()) changed = true; 54 | } 55 | 56 | return new Object[]{modem.isPeripheralEnabled()}; 57 | } 58 | default: 59 | return super.callMethod(computer, context, method, arguments); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/network/modem/DirectionalPeripheralModem.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network.modem; 2 | 3 | import dan200.computercraft.api.peripheral.IPeripheral; 4 | import dan200.computercraft.shared.util.PeripheralUtil; 5 | import net.minecraft.util.EnumFacing; 6 | import net.minecraft.world.World; 7 | import org.squiddev.cctweaks.api.IWorldPosition; 8 | import org.squiddev.cctweaks.api.peripheral.IPeripheralHidden; 9 | import org.squiddev.cctweaks.core.utils.Helpers; 10 | 11 | /** 12 | * A modem that finds a peripheral in the side it is updating 13 | */ 14 | public abstract class DirectionalPeripheralModem extends SinglePeripheralModem { 15 | @Override 16 | public IPeripheral getPeripheral() { 17 | EnumFacing dir = getDirection(); 18 | 19 | IWorldPosition position = getPosition(); 20 | IPeripheral peripheral = PeripheralUtil.getPeripheral((World) position.getBlockAccess(), position.getPosition().offset(dir), dir.getOpposite()); 21 | 22 | if (peripheral instanceof IPeripheralHidden) { 23 | peripheral = ((IPeripheralHidden) peripheral).getNetworkPeripheral(); 24 | } 25 | 26 | if (peripheral == null) { 27 | id = -1; 28 | peripheral = null; 29 | } else if (id <= -1) { 30 | id = Helpers.nextId((World) position.getBlockAccess(), peripheral); 31 | } 32 | 33 | return peripheral; 34 | } 35 | 36 | public abstract EnumFacing getDirection(); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/network/modem/DynamicPeripheralCollection.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network.modem; 2 | 3 | import dan200.computercraft.api.peripheral.IPeripheral; 4 | import net.minecraft.world.World; 5 | import org.squiddev.cctweaks.core.utils.Helpers; 6 | 7 | import java.util.*; 8 | 9 | /** 10 | * A collection of peripherals that handles id assignment 11 | */ 12 | public abstract class DynamicPeripheralCollection { 13 | private final Map ids = new HashMap(); 14 | 15 | public Map getConnectedPeripherals() { 16 | Map peripherals = getPeripherals(); 17 | Map ids = this.ids; 18 | 19 | if (peripherals == null) { 20 | boolean changed = false; 21 | Iterator items = ids.values().iterator(); 22 | while (items.hasNext()) { 23 | if (items.next() >= 0) { 24 | items.remove(); 25 | changed = true; 26 | } 27 | } 28 | 29 | if (changed) changed(); 30 | 31 | return Collections.emptyMap(); 32 | } 33 | 34 | Map peripheralMap = new HashMap(peripherals.size()); 35 | 36 | boolean changed = false; 37 | Set items = new HashSet(ids.keySet()); 38 | 39 | for (Map.Entry item : peripherals.entrySet()) { 40 | if (item.getValue() != null) { 41 | T key = item.getKey(); 42 | IPeripheral peripheral = item.getValue(); 43 | 44 | int id; 45 | if (items.remove(key)) { 46 | id = ids.get(key); 47 | } else { 48 | id = Helpers.nextId(getWorld(), peripheral); 49 | ids.put(key, id); 50 | changed = true; 51 | } 52 | 53 | peripheralMap.put(peripheral.getType() + "_" + id, peripheral); 54 | } 55 | } 56 | 57 | if (changed) changed(); 58 | 59 | return peripheralMap; 60 | } 61 | 62 | public Collection ids() { 63 | return ids.values(); 64 | } 65 | 66 | /** 67 | * Get the list of peripherals 68 | * 69 | * @return The list of peripherals. 70 | */ 71 | protected abstract Map getPeripherals(); 72 | 73 | /** 74 | * Get the current world 75 | * 76 | * @return The current world 77 | */ 78 | protected abstract World getWorld(); 79 | 80 | /** 81 | * Callback for when the id list changes 82 | */ 83 | protected void changed() { 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/network/modem/MultiPeripheralModem.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network.modem; 2 | 3 | import dan200.computercraft.api.peripheral.IPeripheral; 4 | import dan200.computercraft.shared.util.PeripheralUtil; 5 | import net.minecraft.util.EnumFacing; 6 | import net.minecraft.world.World; 7 | import org.squiddev.cctweaks.api.IWorldPosition; 8 | import org.squiddev.cctweaks.api.peripheral.IPeripheralHidden; 9 | 10 | import javax.annotation.Nonnull; 11 | import java.util.Arrays; 12 | import java.util.Collections; 13 | import java.util.Map; 14 | import java.util.Set; 15 | 16 | /** 17 | * A peripheral that checks all 6 sides to connect to 18 | */ 19 | public abstract class MultiPeripheralModem extends BasicModem { 20 | public final PeripheralCollection peripherals = new PeripheralCollection(6) { 21 | @Override 22 | protected IPeripheral[] getPeripherals() { 23 | IWorldPosition position = getPosition(); 24 | 25 | IPeripheral[] peripherals = new IPeripheral[6]; 26 | 27 | World world = (World) position.getBlockAccess(); 28 | net.minecraft.util.math.BlockPos blockPos = position.getPosition(); 29 | 30 | for (EnumFacing facing : EnumFacing.VALUES) { 31 | IPeripheral peripheral = peripherals[facing.ordinal()] = PeripheralUtil.getPeripheral( 32 | world, 33 | blockPos.offset(facing), 34 | facing.getOpposite() 35 | ); 36 | 37 | if ((peripheral instanceof BasicModemPeripheral && ((BasicModemPeripheral) peripheral).modem instanceof MultiPeripheralModem)) { 38 | peripherals[facing.ordinal()] = null; 39 | } else if (peripheral instanceof IPeripheralHidden) { 40 | peripherals[facing.ordinal()] = ((IPeripheralHidden) peripheral).getNetworkPeripheral(); 41 | } 42 | } 43 | 44 | return peripherals; 45 | } 46 | 47 | @Override 48 | protected World getWorld() { 49 | return (World) getPosition().getBlockAccess(); 50 | } 51 | }; 52 | 53 | @Nonnull 54 | @Override 55 | public Map getConnectedPeripherals() { 56 | if (!isPeripheralEnabled()) return Collections.emptyMap(); 57 | return peripherals.getConnectedPeripherals(); 58 | } 59 | 60 | public Set getPeripheralNames() { 61 | return getConnectedPeripherals().keySet(); 62 | } 63 | 64 | /** 65 | * Checks if the peripheral attachment has changed 66 | * 67 | * Simply compares IDs 68 | * 69 | * @return If peripherals have changed 70 | */ 71 | public boolean hasChanged() { 72 | int[] ids = Arrays.copyOf(peripherals.ids, 6); 73 | 74 | return updateEnabled() || !Arrays.equals(ids, peripherals.ids); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/network/modem/PeripheralCollection.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network.modem; 2 | 3 | import dan200.computercraft.api.peripheral.IPeripheral; 4 | import net.minecraft.world.World; 5 | import org.squiddev.cctweaks.core.utils.Helpers; 6 | 7 | import java.util.Arrays; 8 | import java.util.Collections; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * A collection of peripherals that handles id assignment 14 | */ 15 | public abstract class PeripheralCollection { 16 | public final int[] ids; 17 | protected final int size; 18 | 19 | public PeripheralCollection(int size) { 20 | this.size = size; 21 | 22 | ids = new int[size]; 23 | Arrays.fill(ids, -1); 24 | } 25 | 26 | public Map getConnectedPeripherals() { 27 | IPeripheral[] peripherals = getPeripherals(); 28 | int[] ids = this.ids; 29 | int size = this.size; 30 | 31 | if (peripherals == null) { 32 | boolean changed = false; 33 | for (int i = 0; i < size; i++) { 34 | if (ids[i] != -1) { 35 | ids[i] = -1; 36 | changed = true; 37 | } 38 | } 39 | 40 | if (changed) changed(); 41 | 42 | return Collections.emptyMap(); 43 | } else if (peripherals.length != size) { 44 | throw new IllegalStateException("Peripherals size is incorrect: " + peripherals.length + " != " + size); 45 | } 46 | 47 | Map peripheralMap = new HashMap(size); 48 | 49 | boolean changed = false; 50 | for (int i = 0; i < size; i++) { 51 | IPeripheral peripheral = peripherals[i]; 52 | if (peripheral == null) { 53 | if (ids[i] >= 0) changed = true; 54 | ids[i] = -1; 55 | } else { 56 | if (ids[i] <= -1) { 57 | ids[i] = Helpers.nextId(getWorld(), peripheral); 58 | changed = true; 59 | } 60 | peripheralMap.put(peripheral.getType() + "_" + ids[i], peripheral); 61 | } 62 | } 63 | 64 | if (changed) changed(); 65 | 66 | return peripheralMap; 67 | } 68 | 69 | /** 70 | * Get the list of peripherals 71 | * 72 | * @return The list of peripherals. This must have a constant size 73 | */ 74 | protected abstract IPeripheral[] getPeripherals(); 75 | 76 | /** 77 | * Get the current world 78 | * 79 | * @return The current world 80 | */ 81 | protected abstract World getWorld(); 82 | 83 | /** 84 | * Callback for when the id list changes 85 | */ 86 | protected void changed() { 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/network/modem/SinglePeripheralModem.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network.modem; 2 | 3 | import dan200.computercraft.api.peripheral.IPeripheral; 4 | 5 | import javax.annotation.Nonnull; 6 | import java.util.Collections; 7 | import java.util.Map; 8 | 9 | /** 10 | * A modem that only has one peripheral 11 | */ 12 | public abstract class SinglePeripheralModem extends BasicModem { 13 | public int id = -1; 14 | 15 | @Nonnull 16 | @Override 17 | public Map getConnectedPeripherals() { 18 | if (!isPeripheralEnabled()) return Collections.emptyMap(); 19 | 20 | IPeripheral peripheral = getPeripheral(); 21 | 22 | if (peripheral == null) return Collections.emptyMap(); 23 | return Collections.singletonMap(peripheral.getType() + "_" + id, peripheral); 24 | } 25 | 26 | public String getPeripheralName() { 27 | if (!isPeripheralEnabled()) return null; 28 | 29 | IPeripheral peripheral = getPeripheral(); 30 | if (peripheral == null) return null; 31 | return peripheral.getType() + "_" + id; 32 | } 33 | 34 | public abstract IPeripheral getPeripheral(); 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/packet/AbstractPacketHandler.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.packet; 2 | 3 | import net.minecraftforge.fml.common.network.simpleimpl.IMessage; 4 | import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; 5 | import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; 6 | import net.minecraftforge.fml.relauncher.Side; 7 | import org.squiddev.cctweaks.CCTweaks; 8 | import org.squiddev.cctweaks.core.registry.Module; 9 | 10 | public class AbstractPacketHandler extends Module implements IMessageHandler { 11 | private final int id; 12 | private final Side side; 13 | private final Class type; 14 | 15 | public AbstractPacketHandler(int id, Class type) { 16 | this(id, Side.CLIENT, type); 17 | } 18 | 19 | public AbstractPacketHandler(int id, Side side, Class type) { 20 | this.id = id; 21 | this.side = side; 22 | this.type = type; 23 | } 24 | 25 | @Override 26 | public void preInit() { 27 | super.preInit(); 28 | CCTweaks.network.registerMessage(this, type, id, side); 29 | } 30 | 31 | @Override 32 | public IMessage onMessage(T message, MessageContext ctx) { 33 | return message.handle(ctx); 34 | } 35 | 36 | public interface IPacket extends IMessage { 37 | IMessage handle(MessageContext ctx); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/patch/BlockCable_Patch.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.patch; 2 | 3 | import dan200.computercraft.shared.peripheral.common.BlockCable; 4 | import net.minecraft.block.state.IBlockState; 5 | import net.minecraft.tileentity.TileEntity; 6 | import net.minecraft.util.EnumFacing; 7 | import net.minecraft.util.math.BlockPos; 8 | import net.minecraft.world.IBlockAccess; 9 | import net.minecraft.world.World; 10 | import org.squiddev.cctweaks.api.network.NetworkAPI; 11 | import org.squiddev.patcher.visitors.MergeVisitor; 12 | 13 | import javax.annotation.Nonnull; 14 | 15 | /** 16 | * Patches {@link dan200.computercraft.shared.peripheral.common.BlockCable#isCable(IBlockAccess, BlockPos)} 17 | */ 18 | @SuppressWarnings("unused") 19 | public final class BlockCable_Patch extends BlockCable { 20 | public static boolean isCable(IBlockAccess world, BlockPos position) { 21 | return NetworkAPI.registry().isNode(world, position); 22 | } 23 | 24 | @SuppressWarnings("unchecked") 25 | private boolean doesConnect(IBlockState state, IBlockAccess world, BlockPos pos, EnumFacing dir) { 26 | if (state.getValue(Properties.CABLE)) { 27 | if (state.getValue(Properties.MODEM).getFacing() == dir) { 28 | return true; 29 | } else { 30 | return NetworkAPI.helpers().canConnect(world, pos, dir); 31 | } 32 | } else { 33 | return false; 34 | } 35 | } 36 | 37 | @Nonnull 38 | @Override 39 | @MergeVisitor.Stub 40 | public TileEntity createNewTileEntity(@Nonnull World worldIn, int meta) { 41 | return null; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/patch/ComputerItemFactory_Patch.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.patch; 2 | 3 | import dan200.computercraft.shared.computer.blocks.IComputerTile; 4 | import dan200.computercraft.shared.computer.items.ComputerItemFactory; 5 | import net.minecraft.item.ItemStack; 6 | import net.minecraft.nbt.NBTTagCompound; 7 | import org.squiddev.patcher.visitors.MergeVisitor; 8 | 9 | /** 10 | * Copy across rom_id from the computer tile to the item 11 | */ 12 | @MergeVisitor.Rename( 13 | from = "org/squiddev/cctweaks/core/patch/TileComputerBase_Patch", 14 | to = "dan200/computercraft/shared/computer/blocks/TileComputerBase" 15 | ) 16 | public class ComputerItemFactory_Patch extends ComputerItemFactory { 17 | public static ItemStack create(IComputerTile tile) { 18 | ItemStack stack = native_create(tile); 19 | if (stack != null && tile instanceof TileComputerBase_Patch) { 20 | TileComputerBase_Patch compTile = (TileComputerBase_Patch) tile; 21 | if (compTile.hasDisk()) { 22 | NBTTagCompound tag = stack.getTagCompound(); 23 | if (tag == null) stack.setTagCompound(tag = new NBTTagCompound()); 24 | 25 | tag.setInteger("rom_id", compTile.getDiskId()); 26 | } 27 | } 28 | 29 | return stack; 30 | } 31 | 32 | @MergeVisitor.Rename(from = "create") 33 | @MergeVisitor.Stub 34 | public static ItemStack native_create(IComputerTile tile) { 35 | return ComputerItemFactory.create(tile); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/patch/GuiContainer_Extension.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.patch; 2 | 3 | import net.minecraft.client.gui.inventory.GuiContainer; 4 | import net.minecraft.inventory.Container; 5 | import org.lwjgl.input.Keyboard; 6 | import org.squiddev.patcher.visitors.MergeVisitor; 7 | 8 | import java.io.IOException; 9 | 10 | public abstract class GuiContainer_Extension extends GuiContainer { 11 | @MergeVisitor.Stub 12 | public GuiContainer_Extension(Container inventorySlotsIn) { 13 | super(inventorySlotsIn); 14 | } 15 | 16 | @Override 17 | public void handleInput() throws IOException { 18 | // JEI incorrectly sets the repeat events filter, so we force it here. 19 | boolean previous = Keyboard.areRepeatEventsEnabled(); 20 | if (!previous) Keyboard.enableRepeatEvents(true); 21 | 22 | super.handleInput(); 23 | 24 | if (!previous) Keyboard.enableRepeatEvents(false); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/patch/ServerComputerRegistry_Patch.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.patch; 2 | 3 | import dan200.computercraft.shared.computer.core.ComputerRegistry; 4 | import dan200.computercraft.shared.computer.core.ServerComputer; 5 | import org.squiddev.patcher.visitors.MergeVisitor; 6 | 7 | /** 8 | * Make the server computer registry thread safe 9 | */ 10 | @MergeVisitor.Rename( 11 | from = {"org/squiddev/cctweaks/core/patch/ServerComputer_Patch"}, 12 | to = {"dan200/computercraft/shared/computer/core/ServerComputer"} 13 | ) 14 | public class ServerComputerRegistry_Patch extends ComputerRegistry { 15 | public synchronized void update() { 16 | native_update(); 17 | } 18 | 19 | public synchronized void add(int instanceID, ServerComputer computer) { 20 | super.add(instanceID, computer); 21 | 22 | // We force sending the state of the computer 23 | ((ServerComputer_Patch) computer).broadcastState(true); 24 | } 25 | 26 | public synchronized void remove(int instanceID) { 27 | native_remove(instanceID); 28 | } 29 | 30 | @MergeVisitor.Stub 31 | @MergeVisitor.Rename(from = "update") 32 | private void native_update() { 33 | } 34 | 35 | @MergeVisitor.Stub 36 | @MergeVisitor.Rename(from = "remove") 37 | private void native_remove(int instanceID) { 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/patch/Terminal_Patch.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.patch; 2 | 3 | import dan200.computercraft.core.terminal.Terminal; 4 | import dan200.computercraft.core.terminal.TextBuffer; 5 | import dan200.computercraft.shared.util.Palette; 6 | import net.minecraft.nbt.NBTTagCompound; 7 | import org.squiddev.patcher.visitors.MergeVisitor; 8 | 9 | public class Terminal_Patch extends Terminal { 10 | @MergeVisitor.Stub 11 | private int m_cursorX; 12 | @MergeVisitor.Stub 13 | private int m_cursorY; 14 | @MergeVisitor.Stub 15 | private boolean m_cursorBlink; 16 | @MergeVisitor.Stub 17 | private int m_cursorColour; 18 | @MergeVisitor.Stub 19 | private int m_cursorBackgroundColour; 20 | @MergeVisitor.Stub 21 | private TextBuffer[] m_text; 22 | @MergeVisitor.Stub 23 | private TextBuffer[] m_textColour; 24 | @MergeVisitor.Stub 25 | private TextBuffer[] m_backgroundColour; 26 | @MergeVisitor.Stub 27 | private int m_height; 28 | @MergeVisitor.Stub 29 | private final Palette m_palette = null; 30 | 31 | @MergeVisitor.Stub 32 | public Terminal_Patch() { 33 | super(-1, -1); 34 | } 35 | 36 | public void writeToNBT(NBTTagCompound nbttagcompound, boolean lines) { 37 | nbttagcompound.setInteger("term_cursorX", m_cursorX); 38 | nbttagcompound.setInteger("term_cursorY", m_cursorY); 39 | nbttagcompound.setBoolean("term_cursorBlink", m_cursorBlink); 40 | nbttagcompound.setInteger("term_textColour", m_cursorColour); 41 | nbttagcompound.setInteger("term_bgColour", m_cursorBackgroundColour); 42 | 43 | if (lines) { 44 | for (int i = 0; i < m_height; ++i) { 45 | nbttagcompound.setString("term_text_" + i, m_text[i].toString()); 46 | nbttagcompound.setString("term_textColour_" + i, m_textColour[i].toString()); 47 | nbttagcompound.setString("term_textBgColour_" + i, m_backgroundColour[i].toString()); 48 | } 49 | } 50 | 51 | if (m_palette != null) { 52 | // TODO: Move to if(lines) when we update to the next commit (see dan200/ComputerCraft#259) 53 | m_palette.writeToNBT(nbttagcompound); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/patch/TileCable_Ignore.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.patch; 2 | 3 | import dan200.computercraft.shared.peripheral.modem.TileCable; 4 | 5 | /** 6 | * Hack because interfaces 7 | */ 8 | public class TileCable_Ignore extends TileCable { 9 | @Override 10 | public void update() { 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/patch/TurtleBrain_Patch.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.patch; 2 | 3 | import dan200.computercraft.api.turtle.ITurtleUpgrade; 4 | import dan200.computercraft.api.turtle.TurtleSide; 5 | import dan200.computercraft.shared.turtle.blocks.TileTurtle; 6 | import dan200.computercraft.shared.turtle.core.TurtleBrain; 7 | import net.minecraft.nbt.NBTTagCompound; 8 | import org.squiddev.cctweaks.api.turtle.IExtendedTurtleUpgrade; 9 | import org.squiddev.patcher.visitors.MergeVisitor; 10 | 11 | import javax.annotation.Nonnull; 12 | import java.util.Map; 13 | 14 | /** 15 | * Adds upgrade changed handler 16 | */ 17 | public class TurtleBrain_Patch extends TurtleBrain { 18 | @MergeVisitor.Stub 19 | private Map m_upgrades; 20 | @MergeVisitor.Stub 21 | private Map m_upgradeNBTData; 22 | @MergeVisitor.Stub 23 | private TileTurtle m_owner; 24 | 25 | @MergeVisitor.Stub 26 | public TurtleBrain_Patch(TileTurtle turtle) { 27 | super(turtle); 28 | } 29 | 30 | @Override 31 | public void setUpgrade(@Nonnull TurtleSide side, ITurtleUpgrade upgrade) { 32 | ITurtleUpgrade oldUpgrade = m_upgrades.get(side); 33 | if (oldUpgrade == upgrade) { 34 | return; 35 | } else if (oldUpgrade != null) { 36 | m_upgrades.remove(side); 37 | } 38 | 39 | if (m_upgradeNBTData.containsKey(side)) { 40 | m_upgradeNBTData.remove(side); 41 | } 42 | 43 | if (upgrade != null) m_upgrades.put(side, upgrade); 44 | 45 | if (m_owner.getWorld() != null) { 46 | updatePeripherals(m_owner.createServerComputer()); 47 | m_owner.updateBlock(); 48 | 49 | if (!m_owner.getWorld().isRemote) { 50 | TurtleSide otherSide = side == TurtleSide.Left ? TurtleSide.Right : TurtleSide.Left; 51 | ITurtleUpgrade other = getUpgrade(otherSide); 52 | if (other != null && other instanceof IExtendedTurtleUpgrade) { 53 | ((IExtendedTurtleUpgrade) other).upgradeChanged(this, otherSide, oldUpgrade, upgrade); 54 | } 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/patch/TurtleItemFactory_Patch.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.patch; 2 | 3 | import dan200.computercraft.shared.turtle.blocks.ITurtleTile; 4 | import dan200.computercraft.shared.turtle.items.TurtleItemFactory; 5 | import net.minecraft.item.ItemStack; 6 | import net.minecraft.nbt.NBTTagCompound; 7 | import org.squiddev.patcher.visitors.MergeVisitor; 8 | 9 | /** 10 | * Copy across rom_id from the computer tile to the item 11 | */ 12 | @MergeVisitor.Rename( 13 | from = "org/squiddev/cctweaks/core/patch/TileComputerBase_Patch", 14 | to = "dan200/computercraft/shared/computer/blocks/TileComputerBase" 15 | ) 16 | public class TurtleItemFactory_Patch extends TurtleItemFactory { 17 | public static ItemStack create(ITurtleTile turtle) { 18 | ItemStack stack = native_create(turtle); 19 | if (stack != null && turtle instanceof TileComputerBase_Patch) { 20 | TileComputerBase_Patch compTile = (TileComputerBase_Patch) turtle; 21 | if (compTile.hasDisk()) { 22 | NBTTagCompound tag = stack.getTagCompound(); 23 | if (tag == null) stack.setTagCompound(tag = new NBTTagCompound()); 24 | 25 | tag.setInteger("rom_id", compTile.getDiskId()); 26 | } 27 | } 28 | 29 | return stack; 30 | } 31 | 32 | @MergeVisitor.Rename(from = "create") 33 | @MergeVisitor.Stub 34 | public static ItemStack native_create(ITurtleTile turtle) { 35 | return TurtleItemFactory.create(turtle); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/patch/TurtleRefuelCommand_Rewrite.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.patch; 2 | 3 | import dan200.computercraft.api.turtle.ITurtleAccess; 4 | import dan200.computercraft.api.turtle.ITurtleCommand; 5 | import dan200.computercraft.api.turtle.TurtleAnimation; 6 | import dan200.computercraft.api.turtle.TurtleCommandResult; 7 | import net.minecraft.item.ItemStack; 8 | import org.squiddev.cctweaks.api.CCTweaksAPI; 9 | import org.squiddev.cctweaks.api.turtle.ITurtleFuelProvider; 10 | import org.squiddev.cctweaks.api.turtle.ITurtleFuelRegistry; 11 | 12 | import javax.annotation.Nonnull; 13 | 14 | /** 15 | * Complete rewrite of {@link dan200.computercraft.shared.turtle.core.TurtleRefuelCommand} 16 | * Uses the turtle refuel registry instead {@link ITurtleFuelRegistry}. 17 | */ 18 | @SuppressWarnings("unused") 19 | public class TurtleRefuelCommand_Rewrite implements ITurtleCommand { 20 | private int m_limit = 0; 21 | 22 | public TurtleRefuelCommand_Rewrite(int limit) { 23 | m_limit = limit; 24 | } 25 | 26 | @Nonnull 27 | @Override 28 | public TurtleCommandResult execute(@Nonnull ITurtleAccess turtle) { 29 | ItemStack stack = turtle.getInventory().getStackInSlot(turtle.getSelectedSlot()); 30 | if (stack == null) { 31 | return TurtleCommandResult.failure("No items to combust"); 32 | } 33 | 34 | ITurtleFuelProvider source = CCTweaksAPI.instance().fuelRegistry().getProvider(turtle, stack); 35 | if (source != null) { 36 | if (m_limit == 0) { 37 | return TurtleCommandResult.success(); 38 | } else { 39 | turtle.addFuel(source.refuel(turtle, stack, m_limit)); 40 | turtle.playAnimation(TurtleAnimation.Wait); 41 | return TurtleCommandResult.success(); 42 | } 43 | } 44 | 45 | return TurtleCommandResult.failure("Items not combustible"); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/patch/iface/IExtendedComputerTile.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.patch.iface; 2 | 3 | import dan200.computercraft.shared.computer.blocks.IComputerTile; 4 | 5 | public interface IExtendedComputerTile extends IComputerTile { 6 | /** 7 | * Get the custom rom for this tile 8 | * 9 | * @return The custom ROM, or {@code -1} if none exists 10 | */ 11 | int getCustomRom(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/patch/iface/IExtendedServerComputer.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.patch.iface; 2 | 3 | import dan200.computercraft.shared.network.ComputerCraftPacket; 4 | import net.minecraft.nbt.NBTTagCompound; 5 | import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; 6 | 7 | public interface IExtendedServerComputer { 8 | ComputerCraftPacket createStatePacket(); 9 | 10 | void writeDescription(NBTTagCompound tag, boolean withTerminal); 11 | 12 | FMLProxyPacket encode(ComputerCraftPacket packet); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/patch/targeted/ComputerPeripheral_Patch.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.patch.targeted; 2 | 3 | import dan200.computercraft.shared.computer.blocks.ComputerPeripheral; 4 | import dan200.computercraft.shared.computer.core.ServerComputer; 5 | import net.minecraft.util.math.BlockPos; 6 | import net.minecraft.world.World; 7 | import org.squiddev.cctweaks.api.peripheral.IPeripheralTargeted; 8 | import org.squiddev.patcher.visitors.MergeVisitor; 9 | 10 | public class ComputerPeripheral_Patch extends ComputerPeripheral implements IPeripheralTargeted { 11 | @MergeVisitor.Stub 12 | private ServerComputer m_computer; 13 | 14 | @MergeVisitor.Stub 15 | public ComputerPeripheral_Patch(String type, ServerComputer computer) { 16 | super(type, computer); 17 | } 18 | 19 | @Override 20 | public Object getTarget() { 21 | if (m_computer == null) return null; 22 | 23 | World world = m_computer.getWorld(); 24 | BlockPos pos = m_computer.getPosition(); 25 | 26 | if (world == null || pos == null) return null; 27 | 28 | return world.getTileEntity(pos); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/patch/targeted/DiskDrivePeripheral_Patch.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.patch.targeted; 2 | 3 | import dan200.computercraft.shared.peripheral.diskdrive.DiskDrivePeripheral; 4 | import dan200.computercraft.shared.peripheral.diskdrive.TileDiskDrive; 5 | import org.squiddev.cctweaks.api.peripheral.IPeripheralTargeted; 6 | import org.squiddev.patcher.visitors.MergeVisitor; 7 | 8 | public class DiskDrivePeripheral_Patch extends DiskDrivePeripheral implements IPeripheralTargeted { 9 | @MergeVisitor.Stub 10 | private final TileDiskDrive m_diskDrive; 11 | 12 | @MergeVisitor.Stub 13 | public DiskDrivePeripheral_Patch(TileDiskDrive diskDrive) { 14 | super(diskDrive); 15 | m_diskDrive = null; 16 | } 17 | 18 | @Override 19 | public Object getTarget() { 20 | return m_diskDrive; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/patch/targeted/PrinterPeripheral_Patch.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.patch.targeted; 2 | 3 | import dan200.computercraft.shared.peripheral.printer.PrinterPeripheral; 4 | import dan200.computercraft.shared.peripheral.printer.TilePrinter; 5 | import org.squiddev.cctweaks.api.peripheral.IPeripheralTargeted; 6 | import org.squiddev.patcher.visitors.MergeVisitor; 7 | 8 | public class PrinterPeripheral_Patch extends PrinterPeripheral implements IPeripheralTargeted { 9 | @MergeVisitor.Stub 10 | private final TilePrinter m_printer; 11 | 12 | @MergeVisitor.Stub 13 | public PrinterPeripheral_Patch(TilePrinter printer) { 14 | super(printer); 15 | m_printer = null; 16 | } 17 | 18 | @Override 19 | public Object getTarget() { 20 | return m_printer; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/peripheral/PeripheralHelpers.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.peripheral; 2 | 3 | import dan200.computercraft.api.peripheral.IPeripheral; 4 | import org.squiddev.cctweaks.api.peripheral.IPeripheralHelpers; 5 | import org.squiddev.cctweaks.api.peripheral.IPeripheralProxy; 6 | import org.squiddev.cctweaks.api.peripheral.IPeripheralTargeted; 7 | 8 | import javax.annotation.Nonnull; 9 | 10 | public class PeripheralHelpers implements IPeripheralHelpers { 11 | @Nonnull 12 | @Override 13 | public IPeripheral getBasePeripheral(@Nonnull IPeripheral peripheral) { 14 | IPeripheral previous = null; 15 | 16 | while (peripheral != null) { 17 | previous = peripheral; 18 | peripheral = peripheral instanceof IPeripheralProxy ? 19 | ((IPeripheralProxy) peripheral).getBasePeripheral() : 20 | null; 21 | } 22 | 23 | return previous; 24 | } 25 | 26 | @Nonnull 27 | @Override 28 | public Object getTarget(@Nonnull IPeripheral peripheral) { 29 | IPeripheral previous = null; 30 | 31 | while (peripheral != null) { 32 | previous = peripheral; 33 | 34 | if (peripheral instanceof IPeripheralTargeted) { 35 | Object result = ((IPeripheralTargeted) peripheral).getTarget(); 36 | if (result != null) return result; 37 | } 38 | 39 | peripheral = peripheral instanceof IPeripheralProxy ? 40 | ((IPeripheralProxy) peripheral).getBasePeripheral() : 41 | null; 42 | } 43 | 44 | return previous; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/peripheral/PeripheralHostProvider.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.peripheral; 2 | 3 | import dan200.computercraft.api.ComputerCraftAPI; 4 | import dan200.computercraft.api.peripheral.IPeripheral; 5 | import dan200.computercraft.api.peripheral.IPeripheralProvider; 6 | import net.minecraft.tileentity.TileEntity; 7 | import net.minecraft.util.EnumFacing; 8 | import net.minecraft.util.math.BlockPos; 9 | import net.minecraft.world.World; 10 | import org.squiddev.cctweaks.api.peripheral.IPeripheralHost; 11 | import org.squiddev.cctweaks.core.registry.Module; 12 | 13 | import javax.annotation.Nonnull; 14 | 15 | /** 16 | * Adds support for {@link org.squiddev.cctweaks.api.peripheral.IPeripheralHost} 17 | */ 18 | public class PeripheralHostProvider extends Module implements IPeripheralProvider { 19 | @Override 20 | public void init() { 21 | ComputerCraftAPI.registerPeripheralProvider(this); 22 | } 23 | 24 | @Override 25 | public IPeripheral getPeripheral(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing side) { 26 | TileEntity tile = world.getTileEntity(pos); 27 | if (tile != null && tile instanceof IPeripheralHost) { 28 | return ((IPeripheralHost) tile).getPeripheral(side); 29 | } 30 | return null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/peripheral/PeripheralProxy.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.peripheral; 2 | 3 | import dan200.computercraft.api.lua.ILuaContext; 4 | import dan200.computercraft.api.lua.LuaException; 5 | import dan200.computercraft.api.peripheral.IComputerAccess; 6 | import dan200.computercraft.api.peripheral.IPeripheral; 7 | import org.squiddev.cctweaks.api.CCTweaksAPI; 8 | import org.squiddev.cctweaks.api.peripheral.IPeripheralHelpers; 9 | import org.squiddev.cctweaks.api.peripheral.IPeripheralProxy; 10 | 11 | import javax.annotation.Nonnull; 12 | import java.util.HashSet; 13 | import java.util.Set; 14 | 15 | /** 16 | * An simple peripheral proxy instance. 17 | */ 18 | public abstract class PeripheralProxy implements IPeripheral, IPeripheralProxy { 19 | private IPeripheral instance; 20 | private final Set mounts = new HashSet(); 21 | 22 | private String defaultType = null; 23 | 24 | public PeripheralProxy() { 25 | } 26 | 27 | public PeripheralProxy(String defaultType) { 28 | this.defaultType = defaultType; 29 | } 30 | 31 | @Nonnull 32 | protected abstract IPeripheral createPeripheral(); 33 | 34 | @Nonnull 35 | @Override 36 | public IPeripheral getBasePeripheral() { 37 | IPeripheral instance = this.instance; 38 | if (instance == null) { 39 | this.instance = instance = createPeripheral(); 40 | for (IComputerAccess mount : mounts) { 41 | instance.attach(mount); 42 | } 43 | } 44 | 45 | return instance; 46 | } 47 | 48 | @Nonnull 49 | @Override 50 | public String getType() { 51 | return instance == null && defaultType != null ? defaultType : getBasePeripheral().getType(); 52 | } 53 | 54 | @Nonnull 55 | @Override 56 | public String[] getMethodNames() { 57 | return getBasePeripheral().getMethodNames(); 58 | } 59 | 60 | @Override 61 | public Object[] callMethod(@Nonnull IComputerAccess access, @Nonnull ILuaContext context, int i, @Nonnull Object[] objects) throws LuaException, InterruptedException { 62 | return getBasePeripheral().callMethod(access, context, i, objects); 63 | } 64 | 65 | @Override 66 | public void attach(@Nonnull IComputerAccess access) { 67 | if (instance == null) { 68 | // We want to be as lazy as possible with loading 69 | mounts.add(access); 70 | } else { 71 | getBasePeripheral().attach(access); 72 | } 73 | } 74 | 75 | @Override 76 | public void detach(@Nonnull IComputerAccess access) { 77 | mounts.remove(access); 78 | if (instance != null) { 79 | getBasePeripheral().detach(access); 80 | } 81 | } 82 | 83 | @Override 84 | public boolean equals(IPeripheral other) { 85 | IPeripheralHelpers helpers = CCTweaksAPI.instance().peripheralHelpers(); 86 | return helpers.getBasePeripheral(this).equals(helpers.getBasePeripheral(other)); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/registry/IClientModule.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.registry; 2 | 3 | import net.minecraftforge.fml.relauncher.Side; 4 | import net.minecraftforge.fml.relauncher.SideOnly; 5 | 6 | /** 7 | * A module that adds custom client functionality 8 | */ 9 | public interface IClientModule extends IModule { 10 | /** 11 | * Register custom handlers on the client 12 | */ 13 | @SideOnly(Side.CLIENT) 14 | void clientPreInit(); 15 | 16 | /** 17 | * Register custom handlers on the client 18 | */ 19 | @SideOnly(Side.CLIENT) 20 | void clientInit(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/registry/IModule.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.registry; 2 | 3 | import net.minecraftforge.fml.common.Mod; 4 | 5 | /** 6 | * An item that can be registered 7 | */ 8 | public interface IModule { 9 | /** 10 | * Can this module be loaded 11 | * 12 | * @return If this module should be loaded 13 | */ 14 | boolean canLoad(); 15 | 16 | /** 17 | * @see Mod.EventHandler 18 | */ 19 | void preInit(); 20 | 21 | /** 22 | * @see Mod.EventHandler 23 | */ 24 | void init(); 25 | 26 | /** 27 | * @see Mod.EventHandler 28 | */ 29 | void postInit(); 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/registry/Module.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.registry; 2 | 3 | /** 4 | * Default implementation of {@link IModule} 5 | */ 6 | public abstract class Module implements IModule { 7 | @Override 8 | public boolean canLoad() { 9 | return true; 10 | } 11 | 12 | @Override 13 | public void preInit() { 14 | } 15 | 16 | @Override 17 | public void init() { 18 | } 19 | 20 | @Override 21 | public void postInit() { 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/turtle/TurtleFuelRegistry.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.turtle; 2 | 3 | import com.google.common.base.Preconditions; 4 | import dan200.computercraft.api.turtle.ITurtleAccess; 5 | import net.minecraft.item.ItemStack; 6 | import org.squiddev.cctweaks.api.turtle.ITurtleFuelProvider; 7 | import org.squiddev.cctweaks.api.turtle.ITurtleFuelRegistry; 8 | 9 | import javax.annotation.Nonnull; 10 | import java.util.HashSet; 11 | import java.util.Set; 12 | 13 | /** 14 | * Registry for turtle fuels 15 | */ 16 | public final class TurtleFuelRegistry implements ITurtleFuelRegistry { 17 | private final Set providers = new HashSet(); 18 | 19 | @Override 20 | public void addFuelProvider(@Nonnull ITurtleFuelProvider provider) { 21 | Preconditions.checkNotNull(provider, "provider cannot be null"); 22 | providers.add(provider); 23 | } 24 | 25 | @Override 26 | public ITurtleFuelProvider getProvider(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack) { 27 | Preconditions.checkNotNull(turtle, "turtle cannot be null"); 28 | Preconditions.checkNotNull(stack, "stack cannot be null"); 29 | for (ITurtleFuelProvider source : providers) { 30 | if (source.canRefuel(turtle, stack)) { 31 | return source; 32 | } 33 | } 34 | 35 | return null; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/turtle/TurtleHooks.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.turtle; 2 | 3 | import dan200.computercraft.ComputerCraft; 4 | import dan200.computercraft.api.permissions.ITurtlePermissionProvider; 5 | import dan200.computercraft.api.turtle.ITurtleAccess; 6 | import net.minecraft.block.state.IBlockState; 7 | import net.minecraft.init.Blocks; 8 | import net.minecraft.util.EnumActionResult; 9 | import net.minecraft.util.EnumFacing; 10 | import net.minecraft.util.math.BlockPos; 11 | import net.minecraft.world.World; 12 | import net.minecraftforge.fml.relauncher.ReflectionHelper; 13 | import org.squiddev.cctweaks.api.CCTweaksAPI; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * Various hooks for turtle patches 19 | */ 20 | public class TurtleHooks { 21 | private static List permissionProviders; 22 | 23 | public static boolean rotate(ITurtleAccess turtle, BlockPos pos, EnumFacing side, Object[] args, String[] error) { 24 | if (args == null || args.length < 2) return false; 25 | if (!(args[1] instanceof String)) { 26 | if (error != null) error[0] = "Expected string"; 27 | return false; 28 | } 29 | 30 | EnumFacing argDir = LuaDirection.getDirection((String) args[1]); 31 | if (argDir == null) { 32 | if (error != null) error[0] = "Unknown direction"; 33 | return false; 34 | } 35 | 36 | EnumFacing direction = LuaDirection.orient(argDir, turtle.getDirection()); 37 | 38 | World world = turtle.getWorld(); 39 | BlockPos offsetPos = pos.offset(side); 40 | IBlockState state = world.getBlockState(offsetPos); 41 | if (state.getBlock() == Blocks.AIR) { 42 | state = world.getBlockState(pos); 43 | } else { 44 | pos = offsetPos; 45 | } 46 | 47 | EnumActionResult result = CCTweaksAPI.instance().rotationRegistry().rotate(world, pos, state, direction, turtle.getDirection()); 48 | 49 | if (error != null) { 50 | switch (result) { 51 | case FAIL: 52 | error[0] = "Could not rotate"; 53 | break; 54 | case PASS: 55 | error[0] = "Do not know how to rotate"; 56 | break; 57 | } 58 | } 59 | 60 | return result == EnumActionResult.SUCCESS; 61 | } 62 | 63 | private static List getPermissionProviders() { 64 | if (permissionProviders == null) { 65 | permissionProviders = ReflectionHelper.getPrivateValue(ComputerCraft.class, null, "permissionProviders"); 66 | } 67 | 68 | return permissionProviders; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/utils/BlockNotifyFlags.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.utils; 2 | 3 | /** 4 | * Provides constants for the types of block notifications possible in 5 | * World.setBlock() 6 | * 7 | * @author bspkrs 8 | */ 9 | public class BlockNotifyFlags { 10 | 11 | public static final int NONE = 0; 12 | 13 | /** 14 | * Cause a block update 15 | */ 16 | public static final int BLOCK_UPDATE = 1; 17 | 18 | /** 19 | * Send the change to clients 20 | */ 21 | public static final int SEND_TO_CLIENTS = 2; 22 | 23 | public static final int ALL = BLOCK_UPDATE | SEND_TO_CLIENTS; 24 | 25 | /** 26 | * Prevents the block from being re-rendered, if this is a client world 27 | */ 28 | public static final int NO_RENDER = 4; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/utils/EntityPosition.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.utils; 2 | 3 | import net.minecraft.entity.Entity; 4 | import net.minecraft.entity.EntityLivingBase; 5 | import net.minecraft.util.math.BlockPos; 6 | import net.minecraft.world.IBlockAccess; 7 | import org.squiddev.cctweaks.api.IWorldPosition; 8 | 9 | import javax.annotation.Nonnull; 10 | 11 | public class EntityPosition implements IWorldPosition { 12 | public Entity entity; 13 | 14 | public EntityPosition(Entity entity) { 15 | this.entity = entity; 16 | } 17 | 18 | @Nonnull 19 | @Override 20 | public IBlockAccess getBlockAccess() { 21 | return entity.worldObj; 22 | } 23 | 24 | @Nonnull 25 | @Override 26 | public BlockPos getPosition() { 27 | int y; 28 | if (entity instanceof EntityLivingBase) { 29 | EntityLivingBase entityLiving = (EntityLivingBase) entity; 30 | y = (int) (entityLiving.posY + entityLiving.getEyeHeight()); 31 | } else { 32 | y = (int) entity.posY; 33 | } 34 | 35 | return new BlockPos(entity.posX, y, entity.posZ); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/utils/WorldPosition.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.utils; 2 | 3 | import net.minecraft.tileentity.TileEntity; 4 | import net.minecraft.util.math.BlockPos; 5 | import net.minecraft.world.IBlockAccess; 6 | import org.squiddev.cctweaks.api.IWorldPosition; 7 | 8 | import javax.annotation.Nonnull; 9 | 10 | /** 11 | * Base implementation of {@link IWorldPosition} 12 | */ 13 | public class WorldPosition implements IWorldPosition { 14 | private final IBlockAccess world; 15 | private final BlockPos pos; 16 | 17 | public WorldPosition(TileEntity tile) { 18 | this(tile.getWorld(), tile.getPos()); 19 | } 20 | 21 | public WorldPosition(IBlockAccess world, BlockPos pos) { 22 | this.world = world; 23 | this.pos = pos; 24 | } 25 | 26 | @Nonnull 27 | @Override 28 | public IBlockAccess getBlockAccess() { 29 | return world; 30 | } 31 | 32 | @Nonnull 33 | @Override 34 | public BlockPos getPosition() { 35 | return pos; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object o) { 40 | if (this == o) return true; 41 | if (!(o instanceof IWorldPosition)) return false; 42 | 43 | IWorldPosition that = (IWorldPosition) o; 44 | 45 | return pos.equals(that.getPosition()) && world.equals(that.getBlockAccess()); 46 | } 47 | 48 | @Override 49 | public int hashCode() { 50 | return world.hashCode() * 31 + pos.hashCode(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/visualiser/NetworkNode.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.visualiser; 2 | 3 | import net.minecraft.util.math.BlockPos; 4 | import org.squiddev.cctweaks.api.network.INetworkNode; 5 | 6 | /** 7 | * A node in a visualised network 8 | */ 9 | public class NetworkNode { 10 | public final int id; 11 | public final INetworkNode node; 12 | public String name; 13 | public BlockPos position; 14 | 15 | public NetworkNode(int id, String name, BlockPos position) { 16 | this(id, name, position, null); 17 | } 18 | 19 | public NetworkNode(int id, String name, BlockPos position, INetworkNode node) { 20 | this.id = id; 21 | this.name = name; 22 | this.position = position; 23 | this.node = node; 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return "Node{#" + id + " name=" + name + " position=" + position + "}"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/visualiser/NetworkPlayerWatcher.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.visualiser; 2 | 3 | import net.minecraft.entity.player.EntityPlayerMP; 4 | import net.minecraft.util.math.BlockPos; 5 | import net.minecraftforge.common.MinecraftForge; 6 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 7 | import net.minecraftforge.fml.common.gameevent.PlayerEvent; 8 | import org.squiddev.cctweaks.api.network.INetworkController; 9 | import org.squiddev.cctweaks.api.network.INetworkNode; 10 | import org.squiddev.cctweaks.api.network.NetworkAPI; 11 | import org.squiddev.cctweaks.core.packet.AbstractPacketHandler; 12 | 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * Static class for watching network changes 18 | */ 19 | public class NetworkPlayerWatcher extends AbstractPacketHandler { 20 | public NetworkPlayerWatcher() { 21 | super(0, VisualisationPacket.class); 22 | } 23 | 24 | private static final Map watchers = new HashMap(); 25 | 26 | public static void reset() { 27 | watchers.clear(); 28 | } 29 | 30 | public static void update(EntityPlayerMP player, BlockPos pos) { 31 | INetworkNode node = pos == null ? null : NetworkAPI.registry().getNode(player.worldObj, pos); 32 | NetworkState state = watchers.get(player); 33 | 34 | INetworkController controller = node == null ? null : node.getAttachedNetwork(); 35 | if (state == null && (controller == null || controller.getNodesOnNetwork().isEmpty())) { 36 | return; 37 | } 38 | 39 | if (controller == null) controller = state.controller(); 40 | 41 | if (state == null) { 42 | state = new NetworkState(player); 43 | watchers.put(player, state); 44 | } 45 | 46 | VisualisationPacket.send(state, controller); 47 | 48 | if (controller.getNodesOnNetwork().isEmpty()) { 49 | watchers.remove(player); 50 | } 51 | } 52 | 53 | @Override 54 | public void preInit() { 55 | super.preInit(); 56 | MinecraftForge.EVENT_BUS.register(this); 57 | } 58 | 59 | @SubscribeEvent 60 | public void handlePlayerLogout(PlayerEvent.PlayerLoggedOutEvent ev) { 61 | if (ev.player instanceof EntityPlayerMP) { 62 | watchers.remove(ev.player); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/core/visualiser/VisualisationPacket.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.visualiser; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import net.minecraftforge.fml.common.network.simpleimpl.IMessage; 5 | import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; 6 | import org.squiddev.cctweaks.CCTweaks; 7 | import org.squiddev.cctweaks.api.network.INetworkController; 8 | import org.squiddev.cctweaks.client.render.RenderNetworkOverlay; 9 | import org.squiddev.cctweaks.core.packet.AbstractPacketHandler; 10 | import org.squiddev.cctweaks.core.utils.DebugLogger; 11 | 12 | /** 13 | * Handles transmitting/receiving the network 14 | */ 15 | public class VisualisationPacket implements AbstractPacketHandler.IPacket { 16 | private NetworkChange change; 17 | 18 | public VisualisationPacket() { 19 | } 20 | 21 | public VisualisationPacket(NetworkChange change) { 22 | this.change = change; 23 | } 24 | 25 | public static void send(NetworkState state, INetworkController controller) { 26 | NetworkChange change = state.calculateChange(controller); 27 | if (change != null && !change.isEmpty()) { 28 | CCTweaks.network.sendTo(new VisualisationPacket(change), state.player); 29 | } 30 | } 31 | 32 | @Override 33 | public void fromBytes(ByteBuf buf) { 34 | byte version = buf.readByte(); 35 | if (version == 1) { 36 | change = NetworkChange.read(buf); 37 | } else { 38 | DebugLogger.error("Unexpected version " + version + " for network visualiser"); 39 | } 40 | } 41 | 42 | @Override 43 | public void toBytes(ByteBuf buf) { 44 | buf.writeByte(1); 45 | change.write(buf); 46 | } 47 | 48 | @Override 49 | public IMessage handle(MessageContext cxt) { 50 | if (change != null) { 51 | RenderNetworkOverlay.apply(change); 52 | } 53 | return null; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/APIIntegration.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration; 2 | 3 | import net.minecraftforge.fml.common.ModAPIManager; 4 | import org.squiddev.cctweaks.core.registry.Module; 5 | 6 | /** 7 | * A module that is loaded when an API is on the class path 8 | */ 9 | public abstract class APIIntegration extends Module { 10 | public final String apiName; 11 | 12 | public APIIntegration(String modName) { 13 | this.apiName = modName; 14 | } 15 | 16 | @Override 17 | public boolean canLoad() { 18 | return ModAPIManager.INSTANCE.hasAPI(apiName); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/ForgeIntegration.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration; 2 | 3 | import dan200.computercraft.api.turtle.ITurtleAccess; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraftforge.energy.CapabilityEnergy; 6 | import net.minecraftforge.energy.IEnergyStorage; 7 | import org.squiddev.cctweaks.api.CCTweaksAPI; 8 | import org.squiddev.cctweaks.api.turtle.ITurtleFuelProvider; 9 | import org.squiddev.cctweaks.core.Config; 10 | import org.squiddev.cctweaks.core.registry.Module; 11 | 12 | import javax.annotation.Nonnull; 13 | 14 | /** 15 | * Forge energy provider for turtles 16 | */ 17 | public class ForgeIntegration extends Module { 18 | @Override 19 | public void init() { 20 | CCTweaksAPI.instance().fuelRegistry().addFuelProvider(new ITurtleFuelProvider() { 21 | @Override 22 | public boolean canRefuel(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack) { 23 | return Config.Turtle.fluxRefuelAmount > 0 && stack.hasCapability(CapabilityEnergy.ENERGY, null); 24 | } 25 | 26 | @Override 27 | public int refuel(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, int limit) { 28 | int fluxAmount = Config.Turtle.fluxRefuelAmount; 29 | 30 | // Avoid over refueling 31 | int maxRefuel = turtle.getFuelLimit() - turtle.getFuelLevel(); 32 | int fluxLimit = (limit >= 64 ? maxRefuel : limit) * fluxAmount; 33 | 34 | IEnergyStorage producer = stack.getCapability(CapabilityEnergy.ENERGY, null); 35 | 36 | int change = 1; 37 | int progress = 0; 38 | while (progress < fluxLimit && change > 0) { 39 | change = producer.extractEnergy(fluxLimit - progress, false); 40 | progress += change; 41 | } 42 | return progress / fluxAmount; 43 | } 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/IndustrialCraftIntegration.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration; 2 | 3 | import dan200.computercraft.api.turtle.ITurtleAccess; 4 | import ic2.api.item.ElectricItem; 5 | import ic2.api.item.IElectricItem; 6 | import net.minecraft.item.ItemStack; 7 | import org.squiddev.cctweaks.api.CCTweaksAPI; 8 | import org.squiddev.cctweaks.api.turtle.ITurtleFuelProvider; 9 | import org.squiddev.cctweaks.core.Config; 10 | 11 | import javax.annotation.Nonnull; 12 | 13 | /** 14 | * Refuel for IC2 energy sources 15 | */ 16 | public class IndustrialCraftIntegration extends APIIntegration { 17 | public IndustrialCraftIntegration() { 18 | super("IC2API"); 19 | } 20 | 21 | @Override 22 | public void init() { 23 | CCTweaksAPI.instance().fuelRegistry().addFuelProvider(new ITurtleFuelProvider() { 24 | @Override 25 | public boolean canRefuel(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack) { 26 | return Config.Turtle.euRefuelAmount > 0 && stack.getItem() instanceof IElectricItem; 27 | } 28 | 29 | @Override 30 | public int refuel(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, int limit) { 31 | int euAmount = Config.Turtle.euRefuelAmount; 32 | 33 | // Avoid over refueling 34 | int maxRefuel = turtle.getFuelLimit() - turtle.getFuelLevel(); 35 | int euLimit = (limit >= 64 ? maxRefuel : limit) * euAmount; 36 | 37 | return (int) (ElectricItem.manager.discharge(stack, euLimit, Integer.MAX_VALUE, true, true, false) / euAmount); 38 | } 39 | }); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/ModIntegration.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration; 2 | 3 | import net.minecraftforge.fml.common.Loader; 4 | import org.squiddev.cctweaks.core.registry.Module; 5 | 6 | /** 7 | * A module that is loaded when a mod is installed 8 | */ 9 | public abstract class ModIntegration extends Module { 10 | public final String modName; 11 | 12 | public ModIntegration(String modName) { 13 | this.modName = modName; 14 | } 15 | 16 | @Override 17 | public boolean canLoad() { 18 | return Loader.isModLoaded(modName); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/RedstoneFluxIntegration.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration; 2 | 3 | import cofh.api.energy.IEnergyContainerItem; 4 | import dan200.computercraft.api.turtle.ITurtleAccess; 5 | import net.minecraft.item.ItemStack; 6 | import org.squiddev.cctweaks.api.CCTweaksAPI; 7 | import org.squiddev.cctweaks.api.turtle.ITurtleFuelProvider; 8 | import org.squiddev.cctweaks.core.Config; 9 | 10 | import javax.annotation.Nonnull; 11 | 12 | /** 13 | * Registers Redstone Flux as a fuel 14 | */ 15 | public class RedstoneFluxIntegration extends APIIntegration { 16 | public RedstoneFluxIntegration() { 17 | super("CoFHAPI|energy"); 18 | } 19 | 20 | @Override 21 | public void init() { 22 | CCTweaksAPI.instance().fuelRegistry().addFuelProvider(new ITurtleFuelProvider() { 23 | @Override 24 | public boolean canRefuel(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack) { 25 | return Config.Turtle.fluxRefuelAmount > 0 && stack.getItem() instanceof IEnergyContainerItem; 26 | } 27 | 28 | @Override 29 | public int refuel(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, int limit) { 30 | int fluxAmount = Config.Turtle.fluxRefuelAmount; 31 | 32 | // Avoid over refueling 33 | int maxRefuel = turtle.getFuelLimit() - turtle.getFuelLevel(); 34 | int fluxLimit = (limit >= 64 ? maxRefuel : limit) * fluxAmount; 35 | 36 | IEnergyContainerItem container = (IEnergyContainerItem) stack.getItem(); 37 | 38 | // Don't want to pull to much 39 | fluxLimit = Math.min(container.getMaxEnergyStored(stack), fluxLimit); 40 | 41 | int change = 1; 42 | int progress = 0; 43 | while (progress < fluxLimit && change > 0) { 44 | change = container.extractEnergy(stack, fluxLimit - progress, false); 45 | progress += change; 46 | } 47 | return progress / fluxAmount; 48 | } 49 | }); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/TeslaIntegration.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration; 2 | 3 | import dan200.computercraft.api.turtle.ITurtleAccess; 4 | import net.darkhax.tesla.api.ITeslaProducer; 5 | import net.darkhax.tesla.capability.TeslaCapabilities; 6 | import net.darkhax.tesla.lib.Constants; 7 | import net.minecraft.item.ItemStack; 8 | import org.squiddev.cctweaks.api.CCTweaksAPI; 9 | import org.squiddev.cctweaks.api.turtle.ITurtleFuelProvider; 10 | import org.squiddev.cctweaks.core.Config; 11 | 12 | import javax.annotation.Nonnull; 13 | 14 | /** 15 | * Tesla energy provider for turtles 16 | */ 17 | public class TeslaIntegration extends APIIntegration { 18 | public TeslaIntegration() { 19 | super(Constants.MOD_ID); 20 | } 21 | 22 | @Override 23 | public void init() { 24 | CCTweaksAPI.instance().fuelRegistry().addFuelProvider(new ITurtleFuelProvider() { 25 | @Override 26 | public boolean canRefuel(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack) { 27 | return Config.Turtle.fluxRefuelAmount > 0 && stack.hasCapability(TeslaCapabilities.CAPABILITY_PRODUCER, null); 28 | } 29 | 30 | @Override 31 | public int refuel(@Nonnull ITurtleAccess turtle, @Nonnull ItemStack stack, int limit) { 32 | int fluxAmount = Config.Turtle.fluxRefuelAmount; 33 | 34 | // Avoid over refueling 35 | int maxRefuel = turtle.getFuelLimit() - turtle.getFuelLevel(); 36 | int fluxLimit = (limit >= 64 ? maxRefuel : limit) * fluxAmount; 37 | 38 | ITeslaProducer producer = stack.getCapability(TeslaCapabilities.CAPABILITY_PRODUCER, null); 39 | 40 | long change = 1; 41 | long progress = 0; 42 | while (progress < fluxLimit && change > 0) { 43 | change = producer.takePower(fluxLimit - progress, false); 44 | progress += change; 45 | } 46 | return (int) (progress / fluxAmount); 47 | } 48 | }); 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/jei/BasicRecipeHandler.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration.jei; 2 | 3 | import mezz.jei.api.recipe.IRecipeCategory; 4 | import mezz.jei.api.recipe.IRecipeHandler; 5 | import mezz.jei.api.recipe.IRecipeWrapper; 6 | 7 | import javax.annotation.Nonnull; 8 | 9 | public class BasicRecipeHandler implements IRecipeHandler { 10 | private final String id; 11 | private final Class klass; 12 | 13 | public BasicRecipeHandler(IRecipeCategory category, Class klass) { 14 | this.id = category.getUid(); 15 | this.klass = klass; 16 | } 17 | 18 | @Nonnull 19 | @Override 20 | public Class getRecipeClass() { 21 | return klass; 22 | } 23 | 24 | @Nonnull 25 | @Override 26 | @SuppressWarnings("deprecation") 27 | public String getRecipeCategoryUid() { 28 | return id; 29 | } 30 | 31 | @Nonnull 32 | @Override 33 | public String getRecipeCategoryUid(@Nonnull T recipe) { 34 | return id; 35 | } 36 | 37 | @Nonnull 38 | @Override 39 | public IRecipeWrapper getRecipeWrapper(@Nonnull T recipe) { 40 | return recipe; 41 | } 42 | 43 | @Override 44 | public boolean isRecipeValid(@Nonnull T recipe) { 45 | return recipe.isValid(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/jei/IValidRecipeWrapper.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration.jei; 2 | 3 | import mezz.jei.api.recipe.IRecipeWrapper; 4 | 5 | public interface IValidRecipeWrapper extends IRecipeWrapper { 6 | boolean isValid(); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/jei/JeiDescription.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration.jei; 2 | 3 | import mezz.jei.api.IModRegistry; 4 | import net.minecraft.item.ItemStack; 5 | import org.squiddev.cctweaks.blocks.BlockBase; 6 | import org.squiddev.cctweaks.items.ItemBase; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public final class JeiDescription { 12 | private JeiDescription() { 13 | } 14 | 15 | public static void registerDescription(IModRegistry registry, ItemStack stack) { 16 | registry.addDescription(stack, stack.getUnlocalizedName() + ".information"); 17 | } 18 | 19 | public static void registerDescription(IModRegistry registry, ItemBase stack, int meta) { 20 | if (stack.canLoad()) registerDescription(registry, new ItemStack(stack, meta)); 21 | } 22 | 23 | public static void registerDescription(IModRegistry registry, ItemBase item) { 24 | if (item.canLoad()) { 25 | List stacks = new ArrayList(); 26 | item.getSubItems(null, null, stacks); 27 | 28 | if (stacks.size() == 0) { 29 | registerDescription(registry, new ItemStack(item)); 30 | } else { 31 | for (ItemStack stack : stacks) { 32 | registerDescription(registry, stack); 33 | } 34 | } 35 | } 36 | } 37 | 38 | public static void registerDescription(IModRegistry registry, BlockBase block) { 39 | if (block.canLoad()) { 40 | List stacks = new ArrayList(); 41 | block.getSubBlocks(null, null, stacks); 42 | 43 | if (stacks.size() == 0) { 44 | registerDescription(registry, new ItemStack(block)); 45 | } else { 46 | for (ItemStack stack : stacks) { 47 | registerDescription(registry, stack); 48 | } 49 | } 50 | } 51 | } 52 | 53 | public static void registerGenericDescription(IModRegistry registry, ItemBase stack) { 54 | if (stack.canLoad()) registerGenericDescription(registry, new ItemStack(stack)); 55 | } 56 | 57 | public static void registerGenericDescription(IModRegistry registry, BlockBase block) { 58 | if (block.canLoad()) { 59 | List stacks = new ArrayList(); 60 | block.getSubBlocks(null, null, stacks); 61 | 62 | if (stacks.size() == 0) { 63 | registerGenericDescription(registry, new ItemStack(block)); 64 | } else { 65 | for (ItemStack stack : stacks) { 66 | registerGenericDescription(registry, stack); 67 | } 68 | } 69 | } 70 | } 71 | 72 | public static void registerGenericDescription(IModRegistry registry, ItemStack stack) { 73 | registry.addDescription(stack, stack.getItem().getUnlocalizedName() + ".information"); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/jei/PocketUpgradeWrapper.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration.jei; 2 | 3 | import dan200.computercraft.api.pocket.IPocketUpgrade; 4 | import dan200.computercraft.shared.computer.core.ComputerFamily; 5 | import dan200.computercraft.shared.pocket.items.PocketComputerItemFactory; 6 | import mezz.jei.api.ingredients.IIngredients; 7 | import mezz.jei.api.recipe.BlankRecipeWrapper; 8 | import net.minecraft.item.ItemStack; 9 | 10 | import javax.annotation.Nonnull; 11 | import java.util.Arrays; 12 | 13 | public class PocketUpgradeWrapper extends BlankRecipeWrapper implements IValidRecipeWrapper { 14 | public static final ComputerFamily[] FAMILIES = new ComputerFamily[]{ 15 | ComputerFamily.Normal, ComputerFamily.Advanced, 16 | }; 17 | 18 | private final ItemStack inputStack; 19 | private final ItemStack upgradeStack; 20 | private final ItemStack outputStack; 21 | 22 | public PocketUpgradeWrapper(ItemStack inputStack, ItemStack upgradeStack, ItemStack outputStack) { 23 | this.inputStack = inputStack; 24 | this.upgradeStack = upgradeStack; 25 | this.outputStack = outputStack; 26 | } 27 | 28 | public PocketUpgradeWrapper(IPocketUpgrade upgrade, ComputerFamily family) { 29 | inputStack = PocketComputerItemFactory.create(-1, null, -1, family, null); 30 | upgradeStack = upgrade.getCraftingItem(); 31 | outputStack = PocketComputerItemFactory.create(-1, null, -1, family, upgrade); 32 | } 33 | 34 | @Override 35 | public boolean isValid() { 36 | return upgradeStack != null; 37 | } 38 | 39 | @Override 40 | public void getIngredients(@Nonnull IIngredients ingredients) { 41 | ingredients.setInputs(ItemStack.class, Arrays.asList(upgradeStack, inputStack)); 42 | ingredients.setOutput(ItemStack.class, outputStack); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/jei/TurtleUpgradeWrapper.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration.jei; 2 | 3 | import dan200.computercraft.api.turtle.ITurtleUpgrade; 4 | import dan200.computercraft.shared.computer.core.ComputerFamily; 5 | import dan200.computercraft.shared.turtle.items.TurtleItemFactory; 6 | import mezz.jei.api.ingredients.IIngredients; 7 | import mezz.jei.api.recipe.BlankRecipeWrapper; 8 | import net.minecraft.item.ItemStack; 9 | 10 | import javax.annotation.Nonnull; 11 | import java.util.Arrays; 12 | 13 | public class TurtleUpgradeWrapper extends BlankRecipeWrapper implements IValidRecipeWrapper { 14 | public static final ComputerFamily[] FAMILIES = new ComputerFamily[]{ 15 | ComputerFamily.Normal, ComputerFamily.Advanced, 16 | }; 17 | 18 | private final ItemStack inputStack; 19 | private final ItemStack upgradeStack; 20 | private final ItemStack outputStack; 21 | 22 | public TurtleUpgradeWrapper(ITurtleUpgrade upgrade, ComputerFamily family) { 23 | this.inputStack = TurtleItemFactory.create(-1, null, -1, family, null, null, 0, null); 24 | this.upgradeStack = upgrade.getCraftingItem(); 25 | this.outputStack = TurtleItemFactory.create(-1, null, -1, family, null, upgrade, 0, null); 26 | } 27 | 28 | @Override 29 | public boolean isValid() { 30 | return upgradeStack != null; 31 | } 32 | 33 | @Override 34 | public void getIngredients(@Nonnull IIngredients ingredients) { 35 | ingredients.setInputs(ItemStack.class, Arrays.asList(upgradeStack, inputStack)); 36 | ingredients.setOutput(ItemStack.class, outputStack); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/jei/UpgradeCategory.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration.jei; 2 | 3 | import mezz.jei.api.IGuiHelper; 4 | import mezz.jei.api.gui.IDrawable; 5 | import mezz.jei.api.gui.IGuiItemStackGroup; 6 | import mezz.jei.api.gui.IRecipeLayout; 7 | import mezz.jei.api.ingredients.IIngredients; 8 | import mezz.jei.api.recipe.BlankRecipeCategory; 9 | import mezz.jei.api.recipe.IRecipeWrapper; 10 | import net.minecraft.util.ResourceLocation; 11 | import org.squiddev.cctweaks.CCTweaks; 12 | import org.squiddev.cctweaks.core.utils.Helpers; 13 | 14 | import javax.annotation.Nonnull; 15 | 16 | public class UpgradeCategory extends BlankRecipeCategory { 17 | private final String id; 18 | private final IDrawable background; 19 | 20 | public UpgradeCategory(String id, IGuiHelper helper) { 21 | this.id = id; 22 | ResourceLocation location = new ResourceLocation(CCTweaks.ID, "textures/gui/jei_upgrade.png"); 23 | background = helper.createDrawable(location, 0, 0, 160, 50); 24 | } 25 | 26 | @Nonnull 27 | @Override 28 | public String getUid() { 29 | return CCTweaks.ID + ":" + id; 30 | } 31 | 32 | @Nonnull 33 | @Override 34 | public String getTitle() { 35 | return Helpers.translateToLocal("gui.jei.cctweaks." + id); 36 | } 37 | 38 | @Nonnull 39 | @Override 40 | public IDrawable getBackground() { 41 | return background; 42 | } 43 | 44 | @Override 45 | public void setRecipe(@Nonnull IRecipeLayout recipeLayout, @Nonnull IRecipeWrapper recipeWrapper, @Nonnull IIngredients ingredients) { 46 | IGuiItemStackGroup guiItemStacks = recipeLayout.getItemStacks(); 47 | 48 | guiItemStacks.init(0, true, 18, 16); 49 | guiItemStacks.init(1, true, 67, 16); 50 | guiItemStacks.init(2, false, 125, 16); 51 | 52 | guiItemStacks.set(ingredients); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/multipart/ItemCustomPart.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration.multipart; 2 | 3 | import mcmultipart.item.ItemMultiPart; 4 | import mcmultipart.multipart.IMultipart; 5 | import net.minecraft.entity.player.EntityPlayer; 6 | import net.minecraft.item.ItemStack; 7 | import net.minecraft.util.EnumFacing; 8 | import net.minecraft.util.math.BlockPos; 9 | import net.minecraft.util.math.Vec3d; 10 | import net.minecraft.world.World; 11 | import org.squiddev.cctweaks.CCTweaks; 12 | import org.squiddev.cctweaks.integration.multipart.network.PartWirelessBridge; 13 | 14 | import javax.annotation.Nonnull; 15 | 16 | public class ItemCustomPart extends ItemMultiPart { 17 | public ItemCustomPart() { 18 | setCreativeTab(CCTweaks.getCreativeTab()); 19 | } 20 | 21 | @Nonnull 22 | @Override 23 | public String getUnlocalizedName(ItemStack stack) { 24 | switch (stack.getItemDamage()) { 25 | case 0: 26 | return "tile." + CCTweaks.ID + ".networkedBlock.wirelessBridge"; 27 | } 28 | return super.getUnlocalizedName(stack); 29 | } 30 | 31 | @Override 32 | public IMultipart createPart(World world, BlockPos pos, EnumFacing side, Vec3d vec3, ItemStack stack, EntityPlayer player) { 33 | switch (stack.getItemDamage()) { 34 | case 0: 35 | return new PartWirelessBridge(side); 36 | } 37 | return null; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/multipart/MultipartHelpers.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration.multipart; 2 | 3 | import com.google.common.base.Predicate; 4 | import mcmultipart.microblock.IMicroblock; 5 | import mcmultipart.multipart.IMultipart; 6 | import mcmultipart.multipart.ISlottedPart; 7 | import mcmultipart.multipart.OcclusionHelper; 8 | import mcmultipart.multipart.PartSlot; 9 | import net.minecraft.util.EnumFacing; 10 | import net.minecraft.util.math.AxisAlignedBB; 11 | import org.squiddev.cctweaks.api.network.INetworkNode; 12 | import org.squiddev.cctweaks.api.network.IWorldNetworkNode; 13 | import org.squiddev.cctweaks.api.network.IWorldNetworkNodeHost; 14 | 15 | import javax.annotation.Nullable; 16 | 17 | import static mcmultipart.multipart.OcclusionHelper.boxes; 18 | 19 | /** 20 | * Various helpers for multiparts 21 | */ 22 | public class MultipartHelpers { 23 | public static boolean extendIn(final IMultipart multipart, AxisAlignedBB bound, EnumFacing side) { 24 | ISlottedPart part = multipart.getContainer().getPartInSlot(PartSlot.getFaceSlot(side)); 25 | 26 | if (part instanceof IMicroblock.IFaceMicroblock) { 27 | if (!((IMicroblock.IFaceMicroblock) part).isFaceHollow()) { 28 | return false; 29 | } 30 | } 31 | 32 | return OcclusionHelper.occlusionTest(boxes(bound), new Predicate() { 33 | @Override 34 | public boolean apply(@Nullable IMultipart input) { 35 | return input != multipart; 36 | } 37 | }, multipart.getContainer().getParts()); 38 | } 39 | 40 | public static INetworkNode getNode(IMultipart part) { 41 | if (part instanceof INetworkNode) { 42 | return (INetworkNode) part; 43 | } else if (part instanceof IWorldNetworkNodeHost) { 44 | return ((IWorldNetworkNodeHost) part).getNode(); 45 | } else { 46 | return null; 47 | } 48 | } 49 | 50 | public static IWorldNetworkNode getWorldNode(IMultipart part) { 51 | if (part instanceof IWorldNetworkNode) { 52 | return (IWorldNetworkNode) part; 53 | } else if (part instanceof IWorldNetworkNodeHost) { 54 | return ((IWorldNetworkNodeHost) part).getNode(); 55 | } else { 56 | return null; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/multipart/PartBase.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration.multipart; 2 | 3 | import mcmultipart.client.multipart.AdvancedParticleManager; 4 | import mcmultipart.multipart.Multipart; 5 | import mcmultipart.multipart.MultipartRegistry; 6 | import mcmultipart.raytrace.PartMOP; 7 | import net.minecraft.block.Block; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.entity.Entity; 10 | import net.minecraft.entity.player.EntityPlayer; 11 | import net.minecraft.item.ItemStack; 12 | import net.minecraft.tileentity.TileEntity; 13 | import net.minecraft.util.math.AxisAlignedBB; 14 | import net.minecraft.util.math.BlockPos; 15 | import net.minecraft.world.IBlockAccess; 16 | import net.minecraftforge.fml.relauncher.Side; 17 | import net.minecraftforge.fml.relauncher.SideOnly; 18 | import org.squiddev.cctweaks.api.IWorldPosition; 19 | 20 | import javax.annotation.Nonnull; 21 | import java.util.Collections; 22 | import java.util.List; 23 | 24 | public abstract class PartBase extends Multipart implements IWorldPosition { 25 | public abstract Block getBlock(); 26 | 27 | public ItemStack getStack() { 28 | return new ItemStack(getBlock()); 29 | } 30 | 31 | @Override 32 | public abstract void addSelectionBoxes(List list); 33 | 34 | @Override 35 | public abstract void addCollisionBoxes(AxisAlignedBB mask, List list, Entity collidingEntity); 36 | 37 | @Override 38 | public ItemStack getPickBlock(EntityPlayer player, PartMOP hit) { 39 | return getStack(); 40 | } 41 | 42 | @Override 43 | public List getDrops() { 44 | return Collections.singletonList(getStack()); 45 | } 46 | 47 | @Override 48 | @SideOnly(Side.CLIENT) 49 | public boolean addDestroyEffects(AdvancedParticleManager particleManager) { 50 | particleManager.addBlockDestroyEffects( 51 | getPos(), 52 | Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes().getTexture( 53 | getExtendedState(MultipartRegistry.getDefaultState(this).getBaseState(), getBlockAccess(), getPos()) 54 | ) 55 | ); 56 | return true; 57 | } 58 | 59 | @Override 60 | @SideOnly(Side.CLIENT) 61 | public boolean addHitEffects(PartMOP hit, AdvancedParticleManager particleManager) { 62 | return true; 63 | } 64 | 65 | @Nonnull 66 | @Override 67 | public final IBlockAccess getBlockAccess() { 68 | return getWorld(); 69 | } 70 | 71 | @Nonnull 72 | @Override 73 | public final BlockPos getPosition() { 74 | return getPos(); 75 | } 76 | 77 | @Override 78 | public void onConverted(TileEntity tile) { 79 | super.onConverted(tile); 80 | onAdded(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/multipart/PartLazyNBT.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration.multipart; 2 | 3 | import net.minecraft.nbt.NBTBase; 4 | import net.minecraft.nbt.NBTTagCompound; 5 | import org.squiddev.cctweaks.core.McEvents; 6 | 7 | /** 8 | * Multipart equivalent of {@link org.squiddev.cctweaks.blocks.TileLazyNBT} 9 | */ 10 | public abstract class PartLazyNBT extends PartBase { 11 | private NBTTagCompound lazyTag; 12 | 13 | /** 14 | * Lazy load the NBT tag 15 | * 16 | * @param tag The NBT tag to load 17 | */ 18 | public abstract void readLazyNBT(NBTTagCompound tag); 19 | 20 | /** 21 | * The fields that the tag stores. 22 | * 23 | * Used in the rare case that we are saving without having had an update tick 24 | * 25 | * @return The list of fields to keep 26 | */ 27 | public abstract Iterable getFields(); 28 | 29 | @Override 30 | public void onLoaded() { 31 | super.onLoaded(); 32 | if (!getWorld().isRemote) { 33 | McEvents.schedule(new Runnable() { 34 | @Override 35 | public void run() { 36 | if (lazyTag != null) { 37 | readLazyNBT(lazyTag); 38 | lazyTag = null; 39 | } 40 | } 41 | }); 42 | } 43 | } 44 | 45 | @Override 46 | public void readFromNBT(NBTTagCompound tag) { 47 | super.readFromNBT(tag); 48 | if (getWorld() == null) { 49 | lazyTag = tag; 50 | } else { 51 | readLazyNBT(tag); 52 | } 53 | } 54 | 55 | @Override 56 | public NBTTagCompound writeToNBT(NBTTagCompound tag) { 57 | super.writeToNBT(tag); 58 | if (lazyTag != null) { 59 | for (String field : getFields()) { 60 | NBTBase fieldTag = lazyTag.getTag(field); 61 | if (fieldTag != null) tag.setTag(field, fieldTag); 62 | } 63 | } 64 | return tag; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/integration/multipart/PartSided.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.integration.multipart; 2 | 3 | import mcmultipart.MCMultiPartMod; 4 | import mcmultipart.multipart.ISlottedPart; 5 | import mcmultipart.multipart.PartSlot; 6 | import net.minecraft.block.properties.PropertyDirection; 7 | import net.minecraft.block.state.BlockStateContainer; 8 | import net.minecraft.block.state.IBlockState; 9 | import net.minecraft.nbt.NBTTagCompound; 10 | import net.minecraft.network.PacketBuffer; 11 | import net.minecraft.util.EnumFacing; 12 | 13 | import java.util.EnumSet; 14 | 15 | public abstract class PartSided extends PartLazyNBT implements ISlottedPart { 16 | public static final PropertyDirection SIDE = PropertyDirection.create("side"); 17 | 18 | private EnumFacing side; 19 | private EnumSet slot; 20 | 21 | public PartSided() { 22 | this(EnumFacing.NORTH); 23 | } 24 | 25 | public PartSided(EnumFacing facing) { 26 | setSide(facing); 27 | } 28 | 29 | @Override 30 | public EnumFacing[] getValidRotations() { 31 | return EnumFacing.VALUES; 32 | } 33 | 34 | public void setSide(EnumFacing direction) { 35 | side = direction; 36 | slot = EnumSet.of(PartSlot.getFaceSlot(direction)); 37 | } 38 | 39 | public final EnumFacing getSide() { 40 | return side; 41 | } 42 | 43 | @Override 44 | public boolean rotatePart(EnumFacing axis) { 45 | setSide(side.rotateAround(axis.getAxis())); 46 | return true; 47 | } 48 | 49 | @Override 50 | public EnumSet getSlotMask() { 51 | return slot; 52 | } 53 | 54 | @Override 55 | public NBTTagCompound writeToNBT(NBTTagCompound tag) { 56 | super.writeToNBT(tag); 57 | tag.setByte("side", (byte) side.ordinal()); 58 | return tag; 59 | } 60 | 61 | @Override 62 | public void readFromNBT(NBTTagCompound tag) { 63 | super.readFromNBT(tag); 64 | setSide(EnumFacing.getFront(tag.getByte("side"))); 65 | } 66 | 67 | @Override 68 | public void writeUpdatePacket(PacketBuffer buf) { 69 | super.writeUpdatePacket(buf); 70 | buf.writeByte(side.ordinal()); 71 | } 72 | 73 | @Override 74 | public void readUpdatePacket(PacketBuffer buf) { 75 | super.readUpdatePacket(buf); 76 | setSide(EnumFacing.getFront(buf.readByte())); 77 | } 78 | 79 | @Override 80 | public BlockStateContainer createBlockState() { 81 | return new BlockStateContainer(MCMultiPartMod.multipart, SIDE); 82 | } 83 | 84 | @Override 85 | @SuppressWarnings("deprecation") 86 | public IBlockState getActualState(IBlockState state) { 87 | return super.getActualState(state) 88 | .withProperty(SIDE, side); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/items/ItemBase.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.items; 2 | 3 | import net.minecraft.item.Item; 4 | import net.minecraft.item.ItemStack; 5 | import net.minecraft.nbt.NBTTagCompound; 6 | import net.minecraft.util.ResourceLocation; 7 | import net.minecraftforge.fml.common.registry.GameRegistry; 8 | import net.minecraftforge.fml.relauncher.Side; 9 | import net.minecraftforge.fml.relauncher.SideOnly; 10 | import org.squiddev.cctweaks.CCTweaks; 11 | import org.squiddev.cctweaks.core.registry.IClientModule; 12 | import org.squiddev.cctweaks.core.utils.Helpers; 13 | 14 | public abstract class ItemBase extends Item implements IClientModule { 15 | protected final String name; 16 | 17 | public ItemBase(String itemName, int stackSize) { 18 | name = itemName; 19 | 20 | setUnlocalizedName(CCTweaks.ID + "." + name); 21 | 22 | setCreativeTab(CCTweaks.getCreativeTab()); 23 | setMaxStackSize(stackSize); 24 | } 25 | 26 | public ItemBase(String itemName) { 27 | this(itemName, 64); 28 | } 29 | 30 | public static NBTTagCompound getTag(ItemStack stack) { 31 | NBTTagCompound tag = stack.getTagCompound(); 32 | if (tag == null) stack.setTagCompound(tag = new NBTTagCompound()); 33 | return tag; 34 | } 35 | 36 | @Override 37 | public boolean canLoad() { 38 | return true; 39 | } 40 | 41 | @Override 42 | public void preInit() { 43 | GameRegistry.register(this, new ResourceLocation(CCTweaks.ID, name)); 44 | } 45 | 46 | @Override 47 | public void init() { 48 | } 49 | 50 | @Override 51 | public void postInit() { 52 | } 53 | 54 | @Override 55 | @SideOnly(Side.CLIENT) 56 | public void clientPreInit() { 57 | Helpers.setupModel(this, 0, name); 58 | } 59 | 60 | @Override 61 | @SideOnly(Side.CLIENT) 62 | public void clientInit() { 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/items/ItemComputerAction.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.items; 2 | 3 | import dan200.computercraft.shared.computer.blocks.TileComputerBase; 4 | import dan200.computercraft.shared.turtle.blocks.TileTurtle; 5 | import net.minecraft.entity.player.EntityPlayer; 6 | import net.minecraft.item.ItemStack; 7 | import net.minecraft.tileentity.TileEntity; 8 | import net.minecraft.util.EnumActionResult; 9 | import net.minecraft.util.EnumFacing; 10 | import net.minecraft.util.EnumHand; 11 | import net.minecraft.util.math.BlockPos; 12 | import net.minecraft.world.World; 13 | 14 | import javax.annotation.Nonnull; 15 | 16 | /** 17 | * Handles actions on computers 18 | */ 19 | public abstract class ItemComputerAction extends ItemBase { 20 | public ItemComputerAction(String itemName) { 21 | super(itemName); 22 | } 23 | 24 | @Nonnull 25 | @Override 26 | public EnumActionResult onItemUse(ItemStack stack, EntityPlayer player, World world, BlockPos position, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) { 27 | if (!player.isSneaking()) { 28 | return EnumActionResult.PASS; 29 | } 30 | 31 | TileEntity tile = world.getTileEntity(position); 32 | if (tile == null) return EnumActionResult.PASS; 33 | 34 | if (world.isRemote) return EnumActionResult.SUCCESS; 35 | 36 | boolean result; 37 | if (tile instanceof TileComputerBase) { 38 | // Allow custom Turtle Actions 39 | if (tile instanceof TileTurtle) { 40 | result = useTurtle(stack, player, (TileTurtle) tile, side); 41 | } else { 42 | result = useComputer(stack, player, (TileComputerBase) tile, side); 43 | } 44 | } else { 45 | result = useGeneric(stack, player, tile, side); 46 | } 47 | 48 | if (result) { 49 | if (!player.capabilities.isCreativeMode) { 50 | stack.stackSize -= 1; 51 | } 52 | } 53 | 54 | return result ? EnumActionResult.SUCCESS : EnumActionResult.FAIL; 55 | } 56 | 57 | protected abstract boolean useComputer(ItemStack stack, EntityPlayer player, TileComputerBase computerTile, EnumFacing side); 58 | 59 | protected boolean useTurtle(ItemStack stack, EntityPlayer player, TileTurtle computerTile, EnumFacing side) { 60 | return useComputer(stack, player, computerTile, side); 61 | } 62 | 63 | /** 64 | * Custom action on other tile types 65 | */ 66 | protected boolean useGeneric(ItemStack stack, EntityPlayer player, TileEntity tile, EnumFacing side) { 67 | return false; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/items/ItemMultiBlock.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.items; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.item.ItemBlock; 5 | import net.minecraft.item.ItemStack; 6 | import org.squiddev.cctweaks.blocks.IMultiBlock; 7 | 8 | import javax.annotation.Nonnull; 9 | 10 | /** 11 | * An item to place instances of {@link IMultiBlock} 12 | */ 13 | public class ItemMultiBlock extends ItemBlock { 14 | public ItemMultiBlock(Block block) { 15 | super(block); 16 | if (!(block instanceof IMultiBlock)) throw new RuntimeException(block + " must be instance of IMultiBlock"); 17 | 18 | setMaxStackSize(64); 19 | setMaxDamage(0); 20 | setHasSubtypes(true); 21 | } 22 | 23 | @Override 24 | public int getMetadata(int meta) { 25 | return meta; 26 | } 27 | 28 | @Nonnull 29 | @Override 30 | public String getUnlocalizedName(ItemStack stack) { 31 | return ((IMultiBlock) block).getUnlocalizedName(stack.getItemDamage()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/items/ItemToolHost.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.items; 2 | 3 | import dan200.computercraft.ComputerCraft; 4 | import net.minecraft.creativetab.CreativeTabs; 5 | import net.minecraft.init.Blocks; 6 | import net.minecraft.init.Items; 7 | import net.minecraft.item.Item; 8 | import net.minecraft.item.ItemStack; 9 | import net.minecraftforge.fml.common.registry.GameRegistry; 10 | import net.minecraftforge.fml.relauncher.Side; 11 | import net.minecraftforge.fml.relauncher.SideOnly; 12 | import org.squiddev.cctweaks.core.Config; 13 | import org.squiddev.cctweaks.core.utils.Helpers; 14 | import org.squiddev.cctweaks.turtle.TurtleUpgradeToolHost; 15 | import org.squiddev.cctweaks.turtle.TurtleUpgradeToolManipulator; 16 | 17 | import javax.annotation.Nonnull; 18 | import java.util.List; 19 | 20 | /** 21 | * Simply a holder item for the turtle tool host 22 | */ 23 | public class ItemToolHost extends ItemBase { 24 | public ItemToolHost() { 25 | super("toolHost"); 26 | setHasSubtypes(true); 27 | } 28 | 29 | @Override 30 | @SuppressWarnings({"unchecked", "rawtypes"}) 31 | public void getSubItems(@Nonnull Item item, CreativeTabs tab, List list) { 32 | list.add(new ItemStack(this, 1, 0)); 33 | list.add(new ItemStack(this, 1, 1)); 34 | } 35 | 36 | @Nonnull 37 | @Override 38 | public String getUnlocalizedName(ItemStack stack) { 39 | switch (stack.getItemDamage()) { 40 | case 0: 41 | default: 42 | return getUnlocalizedName(); 43 | case 1: 44 | return getUnlocalizedName() + ".advanced"; 45 | } 46 | } 47 | 48 | @Override 49 | public int getMetadata(int metadata) { 50 | return metadata; 51 | } 52 | 53 | @Override 54 | public void init() { 55 | super.init(); 56 | 57 | if (Config.Turtle.ToolHost.enabled) { 58 | if (Config.Turtle.ToolHost.crafting) { 59 | GameRegistry.addRecipe(new ItemStack(this, 1, 0), 60 | "GDG", 61 | "DOD", 62 | "GDG", 63 | 64 | 'G', Items.GOLD_INGOT, 65 | 'D', Items.DIAMOND, 66 | 'O', Blocks.OBSIDIAN 67 | ); 68 | } 69 | 70 | ComputerCraft.registerTurtleUpgrade(new TurtleUpgradeToolHost()); 71 | 72 | if (Config.Turtle.ToolHost.advanced) { 73 | GameRegistry.addRecipe(new ItemStack(this, 1, 1), 74 | "GDG", 75 | "DOD", 76 | "GDG", 77 | 78 | 'G', Items.GOLD_INGOT, 79 | 'D', Items.DIAMOND, 80 | 'O', new ItemStack(this, 1, 0) 81 | ); 82 | 83 | ComputerCraft.registerTurtleUpgrade(new TurtleUpgradeToolManipulator()); 84 | } 85 | } 86 | } 87 | 88 | @Override 89 | @SideOnly(Side.CLIENT) 90 | public void clientPreInit() { 91 | Helpers.setupModel(this, 0, name); 92 | Helpers.setupModel(this, 1, "toolHostAdvanced"); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/turtle/TurtlePosition.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.turtle; 2 | 3 | import dan200.computercraft.api.turtle.ITurtleAccess; 4 | import net.minecraft.util.math.BlockPos; 5 | import net.minecraft.world.IBlockAccess; 6 | import org.squiddev.cctweaks.api.IWorldPosition; 7 | 8 | import javax.annotation.Nonnull; 9 | 10 | /** 11 | * Represents a dynamic position of the turtle 12 | */ 13 | public class TurtlePosition implements IWorldPosition { 14 | public final ITurtleAccess turtle; 15 | 16 | public TurtlePosition(ITurtleAccess turtle) { 17 | this.turtle = turtle; 18 | } 19 | 20 | @Nonnull 21 | @Override 22 | public IBlockAccess getBlockAccess() { 23 | return turtle.getWorld(); 24 | } 25 | 26 | @Nonnull 27 | @Override 28 | public BlockPos getPosition() { 29 | return turtle.getPosition(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/org/squiddev/cctweaks/turtle/TurtleUpgradeToolManipulator.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.turtle; 2 | 3 | import dan200.computercraft.api.peripheral.IPeripheral; 4 | import dan200.computercraft.api.turtle.ITurtleAccess; 5 | import dan200.computercraft.api.turtle.ITurtleUpgrade; 6 | import dan200.computercraft.api.turtle.TurtleSide; 7 | import dan200.computercraft.api.turtle.TurtleUpgradeType; 8 | import net.minecraft.item.ItemStack; 9 | import org.squiddev.cctweaks.CCTweaks; 10 | import org.squiddev.cctweaks.api.turtle.IExtendedTurtleUpgrade; 11 | import org.squiddev.cctweaks.core.Config; 12 | import org.squiddev.cctweaks.core.registry.Registry; 13 | 14 | import javax.annotation.Nonnull; 15 | 16 | public class TurtleUpgradeToolManipulator extends TurtleUpgradeToolHost implements IExtendedTurtleUpgrade { 17 | public TurtleUpgradeToolManipulator() { 18 | super("toolManipulator", Config.Turtle.ToolHost.advancedUpgradeId); 19 | } 20 | 21 | @Override 22 | protected ItemStack getStack() { 23 | return new ItemStack(Registry.itemToolHost, 1, 1); 24 | } 25 | 26 | @Override 27 | public IPeripheral createPeripheral(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side) { 28 | return new ToolManipulatorPeripheral(turtle, getPlayer(turtle), side); 29 | } 30 | 31 | @Nonnull 32 | @Override 33 | public String getUnlocalisedAdjective() { 34 | return "turtle." + CCTweaks.ID + ".toolHost.advanced.adjective"; 35 | } 36 | 37 | @Nonnull 38 | @Override 39 | public TurtleUpgradeType getType() { 40 | return TurtleUpgradeType.Both; 41 | } 42 | 43 | @Override 44 | public void upgradeChanged(@Nonnull ITurtleAccess turtle, @Nonnull TurtleSide side, ITurtleUpgrade oldUpgrade, ITurtleUpgrade newUpgrade) { 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/CCTweaks_at.cfg: -------------------------------------------------------------------------------- 1 | # Turtle Tool Host 2 | public net.minecraft.server.management.PlayerInteractionManager field_73094_o # durabilityRemainingOnBlock 3 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/blockstates/cable.json: -------------------------------------------------------------------------------- 1 | { 2 | "forge_marker": 1, 3 | "defaults": { 4 | "model": "computercraft:cable_core" 5 | }, 6 | "variants": { 7 | "up": { 8 | "true": { 9 | "submodel": { 10 | "up": { "model": "computercraft:cable_arm", "x": 90 } 11 | } 12 | }, 13 | "false": { 14 | } 15 | }, 16 | "down": { 17 | "true": { 18 | "submodel": { 19 | "down": { "model": "computercraft:cable_arm", "x": 270 } 20 | } 21 | }, 22 | "false": { 23 | } 24 | }, 25 | "north": { 26 | "true": { 27 | "submodel": { 28 | "north": { "model": "computercraft:cable_arm", "y": 180 } 29 | } 30 | }, 31 | "false": { 32 | } 33 | }, 34 | "south": { 35 | "true": { 36 | "submodel": { 37 | "south": { "model": "computercraft:cable_arm" } 38 | } 39 | }, 40 | "false": { 41 | } 42 | }, 43 | "west": { 44 | "true": { 45 | "submodel": { 46 | "west": { "model": "computercraft:cable_arm", "y": 90 } 47 | } 48 | }, 49 | "false": { 50 | } 51 | }, 52 | "east": { 53 | "true": { 54 | "submodel": { 55 | "east": { "model": "computercraft:cable_arm", "y": 270 } 56 | } 57 | }, 58 | "false": { 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/blockstates/debugBlock.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "type=peripheral": { "model": "cctweaks:debug_peripheral" }, 4 | "type=networked_peripheral": { "model": "cctweaks:debug_networked_peripheral" }, 5 | "type=node": { "model": "cctweaks:debug_node" } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/blockstates/modem.json: -------------------------------------------------------------------------------- 1 | { 2 | "forge_marker": 1, 3 | "variants": { 4 | "side": { 5 | "up": { "x": 270 }, 6 | "down": { "x": 90 }, 7 | "north": { }, 8 | "south": { "y": 180 }, 9 | "west": { "y": 270 }, 10 | "east": { "y": 90 } 11 | }, 12 | "modem": { 13 | "off": { "model": "computercraft:wired_modem_off" }, 14 | "on": { "model": "computercraft:wired_modem_on" }, 15 | "off_peripheral": { "model": "computercraft:wired_modem_off_peripheral" }, 16 | "on_peripheral": { "model": "computercraft:wired_modem_on_peripheral" } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/blockstates/networkedBlock.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "modem_on=false,peripheral_on=false,type=modem": { "model": "cctweaks:modem" }, 4 | "modem_on=true,peripheral_on=false,type=modem": { "model": "cctweaks:modem_m" }, 5 | "modem_on=false,peripheral_on=true,type=modem": { "model": "cctweaks:modem_p" }, 6 | "modem_on=true,peripheral_on=true,type=modem": { "model": "cctweaks:modem_mp" }, 7 | "modem_on=true,peripheral_on=true,type=wireless_bridge": { "model": "cctweaks:wireless_bridge" }, 8 | "modem_on=true,peripheral_on=false,type=wireless_bridge": { "model": "cctweaks:wireless_bridge" }, 9 | "modem_on=false,peripheral_on=true,type=wireless_bridge": { "model": "cctweaks:wireless_bridge" }, 10 | "modem_on=false,peripheral_on=false,type=wireless_bridge": { "model": "cctweaks:wireless_bridge" } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/blockstates/wirelessBridgeSmall.json: -------------------------------------------------------------------------------- 1 | { 2 | "forge_marker": 1, 3 | "defaults": { 4 | "model": "cctweaks:wireless_bridge_small" 5 | }, 6 | "variants": { 7 | "side": { 8 | "up": { "x": 270 }, 9 | "down": { "x": 90 }, 10 | "north": { }, 11 | "south": { "y": 180 }, 12 | "west": { "y": 270 }, 13 | "east": { "y": 90 } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/docs/en_US/item/computerUpgrade.txt: -------------------------------------------------------------------------------- 1 | Do you want to show your neighbours how much better you are than 2 | them? Well you're in luck, because nothing shows rich better 3 | than a gold-plated computer. 4 | 5 | Simply shift right-click any computer or turtle to 6 | upgrade it to an advanced computer. Or you can craft it 7 | with any device to get the advanced variant. 8 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/docs/en_US/item/dataCard.txt: -------------------------------------------------------------------------------- 1 | Well, there isn't much to say for this little guy. 2 | He stores data, and isn't he good at it? 3 | 4 | Shift right-click a device to store data, right-click 5 | to load data. You can always shift right-click any other block 6 | to wipe his mind, but you wouldn't do that would you? 7 | 8 | Its primary use is binding two ${**}Wireless Bridges${**} 9 | together. 10 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/docs/en_US/item/debugger.txt: -------------------------------------------------------------------------------- 1 | Tired of testing broken scripts? Need some help? The all new 2 | ${**}Debug Wand${**} will help you on the way. 3 | 4 | Shift right-clicking a computer will add a whole host of debugging 5 | tools. On other objects, it just prints a ton of information to chat. 6 | 7 | Hovering over a network node will show a visualisation of 8 | the entire network. If you find this gets out of date, shift-right 9 | click in empty space to refresh it. 10 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/docs/en_US/item/toolHost.advanced.txt: -------------------------------------------------------------------------------- 1 | Further study shows that the ${**}Tool Host${**} 2 | can be extended to support right clicking. 3 | 4 | Wrapping the upgrade as a peripheral allows you to 5 | left and right click with it. 6 | 7 | You can control duration and if the turtle is sneaking 8 | by passing additional arguments. 9 | 10 | Additional methods are added to see if a tool can be used 11 | on a particular block or entity. 12 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/docs/en_US/item/toolHost.txt: -------------------------------------------------------------------------------- 1 | Turtle's, however cute they look, are pretty stupid. 2 | They only seem to understand diamond tools, when any fool 3 | knows that gold is better. 4 | 5 | So get your ${**}Turtle Tool Host${**} today, and enjoy 6 | the benefits of enchantments, gold tools and wooden hoes. 7 | 8 | ${*}We are not responsible for damage turtles may cause to your item.${*} 9 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/docs/en_US/tile/debugBlock.txt: -------------------------------------------------------------------------------- 1 | The ${**}Debug Block${**} and friends are testing 2 | blocks to help check everything works. 3 | 4 | Move along now, nothing more to see. 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/docs/en_US/tile/networkedBlock.wiredModem.txt: -------------------------------------------------------------------------------- 1 | Normal modems are a bit of a pest, so simply 2 | wack down this full block modem and tremble in the 3 | power of all six sides! 4 | 5 | It can connect to any block, be it transparent or not, 6 | and removes the need for additional cables: 7 | modems connect to each other. 8 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/docs/en_US/tile/networkedBlock.wirelessBridge.txt: -------------------------------------------------------------------------------- 1 | Now you're talking! The ${**}Wireless Bridge${**} allows you 2 | to bind multiple wired networks together across infinite distances, 3 | even spanning worlds. 4 | 5 | Firstly place your bridge on a cable, then you'll need to get a 6 | ${**}Data Card${**} to bind two bridges together, but make sure 7 | they're both chunk-loaded. 8 | 9 | You can also bind these similarly to wireless modems. Use the 10 | ${dark_gray}openRemote${none} and ${dark_gray}closeRemote${none} methods 11 | to do so. 12 | 13 | These devices also work on turtles (and sometimes pocket computers), 14 | though you must use the ${dark_gray}bindFromCard${none} method. 15 | 16 | It is a matter of some debate how these work, some say it is ${*}quantum${*}, 17 | others say ${*}magic${*}. It works 18 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/models/block/wireless_bridge_small.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "block/block", 3 | "textures": { 4 | "particle": "cctweaks:blocks/wireless_bridge_small", 5 | "all": "cctweaks:blocks/wireless_bridge_small" 6 | }, 7 | "elements": [ 8 | { 9 | "from": [ 2, 2, 0 ], 10 | "to": [ 14, 14, 2 ], 11 | "faces": { 12 | "down": { "uv": [ 2, 14, 14, 16 ], "texture": "#all" }, 13 | "up": { "uv": [ 2, 0, 14, 2 ], "texture": "#all" }, 14 | "north": { "uv": [ 2, 2, 14, 14 ], "texture": "#all" }, 15 | "south": { "uv": [ 2, 2, 14, 14 ], "texture": "#all" }, 16 | "west": { "uv": [ 0, 2, 2, 14 ], "texture": "#all" }, 17 | "east": { "uv": [ 14, 2, 16, 14 ], "texture": "#all" } 18 | } 19 | } 20 | ], 21 | "display": { 22 | "gui": { 23 | "rotation": [ 24 | 30, 25 | 45, 26 | 0 27 | ], 28 | "translation": [ 29 | 3.2, 30 | -2, 31 | 0 32 | ], 33 | "scale": [ 34 | 0.75, 35 | 0.75, 36 | 0.75 37 | ] 38 | }, 39 | "ground": { 40 | "rotation": [ 41 | 0, 42 | 0, 43 | 0 44 | ], 45 | "translation": [ 46 | 0, 47 | 3, 48 | 0 49 | ], 50 | "scale": [ 51 | 0.25, 52 | 0.25, 53 | 0.25 54 | ] 55 | }, 56 | "fixed": { 57 | "rotation": [ 58 | 0, 59 | 0, 60 | 0 61 | ], 62 | "translation": [ 63 | 0, 64 | 0, 65 | 0 66 | ], 67 | "scale": [ 68 | 0.5, 69 | 0.5, 70 | 0.5 71 | ] 72 | }, 73 | "thirdperson_righthand": { 74 | "rotation": [ 75 | 75, 76 | 180, 77 | 0 78 | ], 79 | "translation": [ 80 | 0, 81 | 2.5, 82 | 0 83 | ], 84 | "scale": [ 85 | 0.375, 86 | 0.375, 87 | 0.375 88 | ] 89 | }, 90 | "firstperson_righthand": { 91 | "rotation": [ 92 | 0, 93 | 45, 94 | 0 95 | ], 96 | "translation": [ 97 | 0, 98 | 0, 99 | 0 100 | ], 101 | "scale": [ 102 | 0.40, 103 | 0.40, 104 | 0.40 105 | ] 106 | }, 107 | "firstperson_lefthand": { 108 | "rotation": [ 109 | 0, 110 | 45, 111 | 0 112 | ], 113 | "translation": [ 114 | 0, 115 | 0, 116 | 0 117 | ], 118 | "scale": [ 119 | 0.40, 120 | 0.40, 121 | 0.40 122 | ] 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/models/block/wireless_bridge_turtle_left.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "computercraft:block/turtle_upgrade_base_left", 3 | "textures": { 4 | "texture": "cctweaks:blocks/wireless_bridge_small" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/models/block/wireless_bridge_turtle_right.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "computercraft:block/turtle_upgrade_base_right", 3 | "textures": { 4 | "texture": "cctweaks:blocks/wireless_bridge_small" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/models/generate.json: -------------------------------------------------------------------------------- 1 | { 2 | "templates": { 3 | "item": { "item": "templates/item.json" }, 4 | "block": { "block": "templates/block.json" }, 5 | "both": { 6 | "item": "templates/itemblock.json", 7 | "block": "templates/block.json" 8 | } 9 | }, 10 | "simple": { 11 | "item": { 12 | "computer_upgrade": "cctweaks:items/computer_upgrade", 13 | "data_card": "cctweaks:items/data_card", 14 | "debugger": "cctweaks:items/debugger", 15 | "tool_host": "cctweaks:items/tool_host", 16 | "tool_host_advanced": "cctweaks:items/tool_host_advanced" 17 | }, 18 | "both": { 19 | "debug_networked_peripheral": "cctweaks:blocks/debug_networked_peripheral", 20 | "debug_node": "cctweaks:blocks/debug_node", 21 | "debug_peripheral": "cctweaks:blocks/debug_peripheral", 22 | "modem": "computercraft:blocks/wired_modem_face", 23 | "wireless_bridge": "cctweaks:blocks/wireless_bridge" 24 | }, 25 | "block": { 26 | "modem_m": "computercraft:blocks/wired_modem_face_on", 27 | "modem_mp": "computercraft:blocks/wired_modem_face_peripheral_on", 28 | "modem_p": "computercraft:blocks/wired_modem_face_peripheral" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/models/item/wireless_bridge_small.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "cctweaks:block/wireless_bridge_small" 3 | } 4 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/models/templates/block.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "block/cube_all", 3 | "textures": { 4 | "all": "${texture}" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/models/templates/item.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "${texture}" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/models/templates/itemblock.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "cctweaks:block/${name}" 3 | } 4 | -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/textures/blocks/debug_networked_peripheral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquidDev-CC/CCTweaks/17a716d61d40715ac854436fea097e828f12df40/src/main/resources/assets/cctweaks/textures/blocks/debug_networked_peripheral.png -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/textures/blocks/debug_node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquidDev-CC/CCTweaks/17a716d61d40715ac854436fea097e828f12df40/src/main/resources/assets/cctweaks/textures/blocks/debug_node.png -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/textures/blocks/debug_peripheral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquidDev-CC/CCTweaks/17a716d61d40715ac854436fea097e828f12df40/src/main/resources/assets/cctweaks/textures/blocks/debug_peripheral.png -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/textures/blocks/debug_template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquidDev-CC/CCTweaks/17a716d61d40715ac854436fea097e828f12df40/src/main/resources/assets/cctweaks/textures/blocks/debug_template.png -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/textures/blocks/wireless_bridge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquidDev-CC/CCTweaks/17a716d61d40715ac854436fea097e828f12df40/src/main/resources/assets/cctweaks/textures/blocks/wireless_bridge.png -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/textures/blocks/wireless_bridge_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquidDev-CC/CCTweaks/17a716d61d40715ac854436fea097e828f12df40/src/main/resources/assets/cctweaks/textures/blocks/wireless_bridge_small.png -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/textures/gui/jei_upgrade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquidDev-CC/CCTweaks/17a716d61d40715ac854436fea097e828f12df40/src/main/resources/assets/cctweaks/textures/gui/jei_upgrade.png -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/textures/items/computer_upgrade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquidDev-CC/CCTweaks/17a716d61d40715ac854436fea097e828f12df40/src/main/resources/assets/cctweaks/textures/items/computer_upgrade.png -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/textures/items/data_card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquidDev-CC/CCTweaks/17a716d61d40715ac854436fea097e828f12df40/src/main/resources/assets/cctweaks/textures/items/data_card.png -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/textures/items/debugger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquidDev-CC/CCTweaks/17a716d61d40715ac854436fea097e828f12df40/src/main/resources/assets/cctweaks/textures/items/debugger.png -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/textures/items/tool_host.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquidDev-CC/CCTweaks/17a716d61d40715ac854436fea097e828f12df40/src/main/resources/assets/cctweaks/textures/items/tool_host.png -------------------------------------------------------------------------------- /src/main/resources/assets/cctweaks/textures/items/tool_host_advanced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SquidDev-CC/CCTweaks/17a716d61d40715ac854436fea097e828f12df40/src/main/resources/assets/cctweaks/textures/items/tool_host_advanced.png -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "modid": "cctweaks", 4 | "name": "CCTweaks", 5 | "description": "Random tweaks to Computer Craft", 6 | "version": "${mod_version}", 7 | "mcversion": "${mc_version}", 8 | "url": "https://github.com/SquidDev-CC/CCTweaks", 9 | "credits": "Dan200, Forge team, Luaj.org", 10 | "authorList": [ 11 | "SquidDev", 12 | "ElvishJerricco" 13 | ], 14 | "dependencies": [ 15 | "ComputerCraft" 16 | ] 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack":{ 3 | "pack_format":1, 4 | "description":"CCTweaks" 5 | } 6 | } -------------------------------------------------------------------------------- /src/test/java/org/squiddev/cctweaks/core/network/mock/BoundNetworkNode.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network.mock; 2 | 3 | import org.squiddev.cctweaks.api.IWorldPosition; 4 | import org.squiddev.cctweaks.core.Config; 5 | import org.squiddev.cctweaks.core.network.bridge.NetworkBinding; 6 | 7 | import java.util.UUID; 8 | 9 | public class BoundNetworkNode extends KeyedNetworkNode { 10 | public static final UUID id = UUID.randomUUID(); 11 | 12 | public final NetworkBinding binding = new NetworkBinding(position); 13 | 14 | public BoundNetworkNode(IWorldPosition position, String character) { 15 | super(position, character); 16 | binding.setUuid(id); 17 | } 18 | 19 | @Override 20 | public void connect() { 21 | super.connect(); 22 | binding.connect(); 23 | getAttachedNetwork().formConnection(this, binding); 24 | } 25 | 26 | static { 27 | Config.Network.WirelessBridge.enabled = true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/org/squiddev/cctweaks/core/network/mock/KeyedNetworkNode.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network.mock; 2 | 3 | import org.squiddev.cctweaks.api.IWorldPosition; 4 | 5 | public class KeyedNetworkNode extends CountingNetworkNode { 6 | public final String key; 7 | 8 | public KeyedNetworkNode(IWorldPosition position, String key) { 9 | super(position); 10 | this.key = key; 11 | } 12 | 13 | public KeyedNetworkNode(IWorldPosition position, String key, boolean[] canVisit) { 14 | super(position, canVisit); 15 | this.key = key; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return key + ": " + super.toString(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/org/squiddev/cctweaks/core/network/mock/NodeTile.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.network.mock; 2 | 3 | import net.minecraft.util.math.BlockPos; 4 | import net.minecraft.world.IBlockAccess; 5 | import org.squiddev.cctweaks.api.network.IWorldNetworkNode; 6 | import org.squiddev.cctweaks.api.network.IWorldNetworkNodeHost; 7 | import org.squiddev.cctweaks.blocks.TileBase; 8 | 9 | import javax.annotation.Nonnull; 10 | 11 | public class NodeTile extends TileBase implements IWorldNetworkNodeHost { 12 | public CountingNetworkNode node; 13 | public final IBlockAccess world; 14 | 15 | public NodeTile(IBlockAccess world, int x, int z) { 16 | this.world = world; 17 | this.pos = new BlockPos(x, 0, z); 18 | } 19 | 20 | @Nonnull 21 | @Override 22 | public IWorldNetworkNode getNode() { 23 | return node; 24 | } 25 | 26 | @Nonnull 27 | @Override 28 | public IBlockAccess getBlockAccess() { 29 | return world; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return String.format("Tile<%s>(%s)", pos, node); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/org/squiddev/cctweaks/core/peripheral/BasePeripheral.java: -------------------------------------------------------------------------------- 1 | package org.squiddev.cctweaks.core.peripheral; 2 | 3 | import dan200.computercraft.api.lua.ILuaContext; 4 | import dan200.computercraft.api.lua.LuaException; 5 | import dan200.computercraft.api.peripheral.IComputerAccess; 6 | import dan200.computercraft.api.peripheral.IPeripheral; 7 | 8 | /** 9 | * A basic peripheral that does nothing 10 | */ 11 | public class BasePeripheral implements IPeripheral { 12 | @Override 13 | public String getType() { 14 | return null; 15 | } 16 | 17 | @Override 18 | public String[] getMethodNames() { 19 | return null; 20 | } 21 | 22 | @Override 23 | public Object[] callMethod(IComputerAccess computer, ILuaContext context, int index, Object[] args) throws LuaException, InterruptedException { 24 | return null; 25 | } 26 | 27 | @Override 28 | public void attach(IComputerAccess computer) { 29 | } 30 | 31 | @Override 32 | public void detach(IComputerAccess computer) { 33 | } 34 | 35 | @Override 36 | public boolean equals(IPeripheral peripheral) { 37 | return peripheral == this; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/resources/org/squiddev/cctweaks/core/network/data.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Visits once from multiple sides", 4 | "map": [ 5 | "+----+", 6 | "| |", 7 | "+----+" 8 | ], 9 | "counts": { 10 | "-": 1 11 | } 12 | }, 13 | { 14 | "name": "Obeys canVisitFrom", 15 | "map": [ 16 | "+---+ ", 17 | "| ", 31 | "+---+ " 32 | ], 33 | "counts": { 34 | "-": 1, 35 | ">": 0 36 | } 37 | }, 38 | { 39 | "name": "Still visits blocked nodes", 40 | "map": [ 41 | "+---+ ", 42 | "| |>", 43 | "+---++" 44 | ], 45 | "counts": { 46 | "-": 1, 47 | ">": 1 48 | }, 49 | "distance": { 50 | ">": 8 51 | } 52 | }, 53 | { 54 | "name": "Bindings", 55 | "map": [ 56 | "----B", 57 | " ", 58 | "X---B" 59 | ], 60 | "counts": { 61 | "-": 1, 62 | "B": 1 63 | }, 64 | "distance": { 65 | "X": 10 66 | } 67 | }, 68 | { 69 | "name": "Shortest", 70 | "map": [ 71 | "B ", 72 | "| ", 73 | "+X--B" 74 | ], 75 | "counts": { 76 | "-": 1, 77 | "B": 1 78 | }, 79 | "distance": { 80 | "X": 3 81 | } 82 | } 83 | ] 84 | -------------------------------------------------------------------------------- /src/test/resources/org/squiddev/cctweaks/core/patcher/binaryEvent.lua: -------------------------------------------------------------------------------- 1 | local str = '\255\244\255\233' 2 | os.queueEvent('foobar', str) 3 | local _, msg = os.pullEvent('foobar') 4 | assert.assertEquals(str, msg) 5 | -------------------------------------------------------------------------------- /src/test/resources/org/squiddev/cctweaks/core/patcher/binaryFS.lua: -------------------------------------------------------------------------------- 1 | -- Check basic FS works 2 | 3 | local str = '\255\244\255\233' 4 | -- Write file 5 | local handle = fs.open('foo', 'w') 6 | handle.write(str) 7 | handle.close() 8 | -- Read file 9 | handle = fs.open('foo', 'r') 10 | local msg = handle.readAll() 11 | handle.close() 12 | -- Check 13 | assert.assertEquals(str, msg) 14 | --------------------------------------------------------------------------------