├── .github └── workflows │ └── build.yml ├── .gitignore ├── LICENSE ├── blockbench ├── computerised_display_source.bbmodel ├── computerized_display_target.bbmodel ├── computerized_redstone_link.bbmodel └── train_network_observer.bbmodel ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── readme.md ├── settings.gradle └── src └── main ├── java └── de │ └── saschat │ └── createcomputing │ ├── Behaviours.java │ ├── CreateComputingMod.java │ ├── Registries.java │ ├── Utils.java │ ├── api │ ├── PeripheralMethod.java │ └── SmartPeripheral.java │ ├── behaviour │ ├── source │ │ └── TextDisplayBehaviour.java │ ├── target │ │ └── TextPassBehaviour.java │ └── tile │ │ └── TrainNetworkObserver.java │ ├── blocks │ ├── ComputerizedDisplaySourceBlock.java │ ├── ComputerizedDisplayTargetBlock.java │ ├── ComputerizedRedstoneLinkBlock.java │ └── TrainNetworkObserverBlock.java │ ├── config │ └── CreateComputingConfigServer.java │ ├── mixin │ └── TrackTargetingClientMixin.java │ ├── peripherals │ ├── ComputerizedDisplaySourcePeripheral.java │ ├── ComputerizedDisplayTargetPeripheral.java │ ├── ComputerizedRedstoneLinkPeripheral.java │ ├── TrainNetworkObserverPeripheral.java │ └── handles │ │ ├── DisplayLinkHandle.java │ │ └── RedstoneHandle.java │ └── tiles │ ├── ComputerizedDisplaySourceTile.java │ ├── ComputerizedDisplayTargetTile.java │ ├── ComputerizedRedstoneLinkTile.java │ ├── TrainNetworkObserverTile.java │ └── renderer │ └── TrainNetworkObserverRenderer.java └── resources ├── META-INF └── mods.toml ├── assets └── createcomputing │ ├── blockstates │ ├── computerized_display_source.json │ ├── computerized_display_target.json │ ├── computerized_redstone_link.json │ └── train_network_observer.json │ ├── lang │ ├── en_gb.json │ └── en_us.json │ ├── models │ ├── block │ │ ├── computerized_display_source.json │ │ ├── computerized_display_target.json │ │ ├── computerized_redstone_link.json │ │ └── train_network_observer.json │ └── item │ │ ├── computerized_display_source.json │ │ ├── computerized_display_target.json │ │ ├── computerized_redstone_link.json │ │ └── train_network_observer.json │ └── textures │ └── block │ ├── brass_casing_slab.png │ └── train_network_observer_side.png ├── createcomputing.mixins.json ├── data └── createcomputing │ ├── loot_tables │ └── blocks │ │ ├── computerized_display_source.json │ │ ├── computerized_display_target.json │ │ ├── computerized_redstone_link.json │ │ └── train_network_observer.json │ └── recipes │ ├── computerized_display_source.json │ ├── computerized_display_target.json │ ├── computerized_redstone_link.json │ └── train_network_observer.json ├── logo.png └── pack.mcmeta /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: "Builder" 2 | on: [ push, pull_request ] 3 | permissions: 4 | contents: read 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v3 11 | - name: Set up JDK 17 12 | uses: actions/setup-java@v3 13 | with: 14 | java-version: '17' 15 | distribution: 'adopt' 16 | - name: Setup Gradle 17 | uses: gradle/gradle-build-action@v2 18 | - name: Fix Gradle Permissions 19 | run: chmod +x gradlew 20 | - name: Execute Gradle build 21 | run: ./gradlew build 22 | - uses: actions/upload-artifact@v3 23 | with: 24 | name: build_output 25 | path: build/libs/* 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific stuff 2 | .idea/ 3 | 4 | *.iml 5 | *.ipr 6 | *.iws 7 | 8 | # IntelliJ 9 | out/ 10 | # mpeltonen/sbt-idea plugin 11 | .idea_modules/ 12 | 13 | # JIRA plugin 14 | atlassian-ide-plugin.xml 15 | 16 | # Compiled class file 17 | *.class 18 | 19 | # Log file 20 | *.log 21 | 22 | # BlueJ files 23 | *.ctxt 24 | 25 | # Package Files # 26 | *.jar 27 | *.war 28 | *.nar 29 | *.ear 30 | *.zip 31 | *.tar.gz 32 | *.rar 33 | 34 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 35 | hs_err_pid* 36 | 37 | *~ 38 | 39 | # temporary files which can be created if a process still has a handle open of a deleted file 40 | .fuse_hidden* 41 | 42 | # KDE directory preferences 43 | .directory 44 | 45 | # Linux trash folder which might appear on any partition or disk 46 | .Trash-* 47 | 48 | # .nfs files are created when an open file is removed but is still being accessed 49 | .nfs* 50 | 51 | # General 52 | .DS_Store 53 | .AppleDouble 54 | .LSOverride 55 | 56 | # Icon must end with two \r 57 | Icon 58 | 59 | # Thumbnails 60 | ._* 61 | 62 | # Files that might appear in the root of a volume 63 | .DocumentRevisions-V100 64 | .fseventsd 65 | .Spotlight-V100 66 | .TemporaryItems 67 | .Trashes 68 | .VolumeIcon.icns 69 | .com.apple.timemachine.donotpresent 70 | 71 | # Directories potentially created on remote AFP share 72 | .AppleDB 73 | .AppleDesktop 74 | Network Trash Folder 75 | Temporary Items 76 | .apdisk 77 | 78 | # Windows thumbnail cache files 79 | Thumbs.db 80 | Thumbs.db:encryptable 81 | ehthumbs.db 82 | ehthumbs_vista.db 83 | 84 | # Dump file 85 | *.stackdump 86 | 87 | # Folder config file 88 | [Dd]esktop.ini 89 | 90 | # Recycle Bin used on file shares 91 | $RECYCLE.BIN/ 92 | 93 | # Windows Installer files 94 | *.cab 95 | *.msi 96 | *.msix 97 | *.msm 98 | *.msp 99 | 100 | # Windows shortcuts 101 | *.lnk 102 | 103 | .gradle 104 | build/ 105 | 106 | # Ignore Gradle GUI config 107 | gradle-app.setting 108 | 109 | # Cache of project 110 | .gradletasknamecache 111 | 112 | **/build/ 113 | 114 | # Common working directory 115 | run/ 116 | 117 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 118 | !gradle-wrapper.jar 119 | 120 | 121 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | EUROPEAN UNION PUBLIC LICENCE v. 1.2 2 | EUPL © the European Union 2007, 2016 3 | 4 | This European Union Public Licence (the ‘EUPL’) applies to the Work (as defined 5 | below) which is provided under the terms of this Licence. Any use of the Work, 6 | other than as authorised under this Licence is prohibited (to the extent such 7 | use is covered by a right of the copyright holder of the Work). 8 | 9 | The Work is provided under the terms of this Licence when the Licensor (as 10 | defined below) has placed the following notice immediately following the 11 | copyright notice for the Work: 12 | 13 | Licensed under the EUPL 14 | 15 | or has expressed by any other means his willingness to license under the EUPL. 16 | 17 | 1. Definitions 18 | 19 | In this Licence, the following terms have the following meaning: 20 | 21 | - ‘The Licence’: this Licence. 22 | 23 | - ‘The Original Work’: the work or software distributed or communicated by the 24 | Licensor under this Licence, available as Source Code and also as Executable 25 | Code as the case may be. 26 | 27 | - ‘Derivative Works’: the works or software that could be created by the 28 | Licensee, based upon the Original Work or modifications thereof. This Licence 29 | does not define the extent of modification or dependence on the Original Work 30 | required in order to classify a work as a Derivative Work; this extent is 31 | determined by copyright law applicable in the country mentioned in Article 15. 32 | 33 | - ‘The Work’: the Original Work or its Derivative Works. 34 | 35 | - ‘The Source Code’: the human-readable form of the Work which is the most 36 | convenient for people to study and modify. 37 | 38 | - ‘The Executable Code’: any code which has generally been compiled and which is 39 | meant to be interpreted by a computer as a program. 40 | 41 | - ‘The Licensor’: the natural or legal person that distributes or communicates 42 | the Work under the Licence. 43 | 44 | - ‘Contributor(s)’: any natural or legal person who modifies the Work under the 45 | Licence, or otherwise contributes to the creation of a Derivative Work. 46 | 47 | - ‘The Licensee’ or ‘You’: any natural or legal person who makes any usage of 48 | the Work under the terms of the Licence. 49 | 50 | - ‘Distribution’ or ‘Communication’: any act of selling, giving, lending, 51 | renting, distributing, communicating, transmitting, or otherwise making 52 | available, online or offline, copies of the Work or providing access to its 53 | essential functionalities at the disposal of any other natural or legal 54 | person. 55 | 56 | 2. Scope of the rights granted by the Licence 57 | 58 | The Licensor hereby grants You a worldwide, royalty-free, non-exclusive, 59 | sublicensable licence to do the following, for the duration of copyright vested 60 | in the Original Work: 61 | 62 | - use the Work in any circumstance and for all usage, 63 | - reproduce the Work, 64 | - modify the Work, and make Derivative Works based upon the Work, 65 | - communicate to the public, including the right to make available or display 66 | the Work or copies thereof to the public and perform publicly, as the case may 67 | be, the Work, 68 | - distribute the Work or copies thereof, 69 | - lend and rent the Work or copies thereof, 70 | - sublicense rights in the Work or copies thereof. 71 | 72 | Those rights can be exercised on any media, supports and formats, whether now 73 | known or later invented, as far as the applicable law permits so. 74 | 75 | In the countries where moral rights apply, the Licensor waives his right to 76 | exercise his moral right to the extent allowed by law in order to make effective 77 | the licence of the economic rights here above listed. 78 | 79 | The Licensor grants to the Licensee royalty-free, non-exclusive usage rights to 80 | any patents held by the Licensor, to the extent necessary to make use of the 81 | rights granted on the Work under this Licence. 82 | 83 | 3. Communication of the Source Code 84 | 85 | The Licensor may provide the Work either in its Source Code form, or as 86 | Executable Code. If the Work is provided as Executable Code, the Licensor 87 | provides in addition a machine-readable copy of the Source Code of the Work 88 | along with each copy of the Work that the Licensor distributes or indicates, in 89 | a notice following the copyright notice attached to the Work, a repository where 90 | the Source Code is easily and freely accessible for as long as the Licensor 91 | continues to distribute or communicate the Work. 92 | 93 | 4. Limitations on copyright 94 | 95 | Nothing in this Licence is intended to deprive the Licensee of the benefits from 96 | any exception or limitation to the exclusive rights of the rights owners in the 97 | Work, of the exhaustion of those rights or of other applicable limitations 98 | thereto. 99 | 100 | 5. Obligations of the Licensee 101 | 102 | The grant of the rights mentioned above is subject to some restrictions and 103 | obligations imposed on the Licensee. Those obligations are the following: 104 | 105 | Attribution right: The Licensee shall keep intact all copyright, patent or 106 | trademarks notices and all notices that refer to the Licence and to the 107 | disclaimer of warranties. The Licensee must include a copy of such notices and a 108 | copy of the Licence with every copy of the Work he/she distributes or 109 | communicates. The Licensee must cause any Derivative Work to carry prominent 110 | notices stating that the Work has been modified and the date of modification. 111 | 112 | Copyleft clause: If the Licensee distributes or communicates copies of the 113 | Original Works or Derivative Works, this Distribution or Communication will be 114 | done under the terms of this Licence or of a later version of this Licence 115 | unless the Original Work is expressly distributed only under this version of the 116 | Licence — for example by communicating ‘EUPL v. 1.2 only’. The Licensee 117 | (becoming Licensor) cannot offer or impose any additional terms or conditions on 118 | the Work or Derivative Work that alter or restrict the terms of the Licence. 119 | 120 | Compatibility clause: If the Licensee Distributes or Communicates Derivative 121 | Works or copies thereof based upon both the Work and another work licensed under 122 | a Compatible Licence, this Distribution or Communication can be done under the 123 | terms of this Compatible Licence. For the sake of this clause, ‘Compatible 124 | Licence’ refers to the licences listed in the appendix attached to this Licence. 125 | Should the Licensee's obligations under the Compatible Licence conflict with 126 | his/her obligations under this Licence, the obligations of the Compatible 127 | Licence shall prevail. 128 | 129 | Provision of Source Code: When distributing or communicating copies of the Work, 130 | the Licensee will provide a machine-readable copy of the Source Code or indicate 131 | a repository where this Source will be easily and freely available for as long 132 | as the Licensee continues to distribute or communicate the Work. 133 | 134 | Legal Protection: This Licence does not grant permission to use the trade names, 135 | trademarks, service marks, or names of the Licensor, except as required for 136 | reasonable and customary use in describing the origin of the Work and 137 | reproducing the content of the copyright notice. 138 | 139 | 6. Chain of Authorship 140 | 141 | The original Licensor warrants that the copyright in the Original Work granted 142 | hereunder is owned by him/her or licensed to him/her and that he/she has the 143 | power and authority to grant the Licence. 144 | 145 | Each Contributor warrants that the copyright in the modifications he/she brings 146 | to the Work are owned by him/her or licensed to him/her and that he/she has the 147 | power and authority to grant the Licence. 148 | 149 | Each time You accept the Licence, the original Licensor and subsequent 150 | Contributors grant You a licence to their contributions to the Work, under the 151 | terms of this Licence. 152 | 153 | 7. Disclaimer of Warranty 154 | 155 | The Work is a work in progress, which is continuously improved by numerous 156 | Contributors. It is not a finished work and may therefore contain defects or 157 | ‘bugs’ inherent to this type of development. 158 | 159 | For the above reason, the Work is provided under the Licence on an ‘as is’ basis 160 | and without warranties of any kind concerning the Work, including without 161 | limitation merchantability, fitness for a particular purpose, absence of defects 162 | or errors, accuracy, non-infringement of intellectual property rights other than 163 | copyright as stated in Article 6 of this Licence. 164 | 165 | This disclaimer of warranty is an essential part of the Licence and a condition 166 | for the grant of any rights to the Work. 167 | 168 | 8. Disclaimer of Liability 169 | 170 | Except in the cases of wilful misconduct or damages directly caused to natural 171 | persons, the Licensor will in no event be liable for any direct or indirect, 172 | material or moral, damages of any kind, arising out of the Licence or of the use 173 | of the Work, including without limitation, damages for loss of goodwill, work 174 | stoppage, computer failure or malfunction, loss of data or any commercial 175 | damage, even if the Licensor has been advised of the possibility of such damage. 176 | However, the Licensor will be liable under statutory product liability laws as 177 | far such laws apply to the Work. 178 | 179 | 9. Additional agreements 180 | 181 | While distributing the Work, You may choose to conclude an additional agreement, 182 | defining obligations or services consistent with this Licence. However, if 183 | accepting obligations, You may act only on your own behalf and on your sole 184 | responsibility, not on behalf of the original Licensor or any other Contributor, 185 | and only if You agree to indemnify, defend, and hold each Contributor harmless 186 | for any liability incurred by, or claims asserted against such Contributor by 187 | the fact You have accepted any warranty or additional liability. 188 | 189 | 10. Acceptance of the Licence 190 | 191 | The provisions of this Licence can be accepted by clicking on an icon ‘I agree’ 192 | placed under the bottom of a window displaying the text of this Licence or by 193 | affirming consent in any other similar way, in accordance with the rules of 194 | applicable law. Clicking on that icon indicates your clear and irrevocable 195 | acceptance of this Licence and all of its terms and conditions. 196 | 197 | Similarly, you irrevocably accept this Licence and all of its terms and 198 | conditions by exercising any rights granted to You by Article 2 of this Licence, 199 | such as the use of the Work, the creation by You of a Derivative Work or the 200 | Distribution or Communication by You of the Work or copies thereof. 201 | 202 | 11. Information to the public 203 | 204 | In case of any Distribution or Communication of the Work by means of electronic 205 | communication by You (for example, by offering to download the Work from a 206 | remote location) the distribution channel or media (for example, a website) must 207 | at least provide to the public the information requested by the applicable law 208 | regarding the Licensor, the Licence and the way it may be accessible, concluded, 209 | stored and reproduced by the Licensee. 210 | 211 | 12. Termination of the Licence 212 | 213 | The Licence and the rights granted hereunder will terminate automatically upon 214 | any breach by the Licensee of the terms of the Licence. 215 | 216 | Such a termination will not terminate the licences of any person who has 217 | received the Work from the Licensee under the Licence, provided such persons 218 | remain in full compliance with the Licence. 219 | 220 | 13. Miscellaneous 221 | 222 | Without prejudice of Article 9 above, the Licence represents the complete 223 | agreement between the Parties as to the Work. 224 | 225 | If any provision of the Licence is invalid or unenforceable under applicable 226 | law, this will not affect the validity or enforceability of the Licence as a 227 | whole. Such provision will be construed or reformed so as necessary to make it 228 | valid and enforceable. 229 | 230 | The European Commission may publish other linguistic versions or new versions of 231 | this Licence or updated versions of the Appendix, so far this is required and 232 | reasonable, without reducing the scope of the rights granted by the Licence. New 233 | versions of the Licence will be published with a unique version number. 234 | 235 | All linguistic versions of this Licence, approved by the European Commission, 236 | have identical value. Parties can take advantage of the linguistic version of 237 | their choice. 238 | 239 | 14. Jurisdiction 240 | 241 | Without prejudice to specific agreement between parties, 242 | 243 | - any litigation resulting from the interpretation of this License, arising 244 | between the European Union institutions, bodies, offices or agencies, as a 245 | Licensor, and any Licensee, will be subject to the jurisdiction of the Court 246 | of Justice of the European Union, as laid down in article 272 of the Treaty on 247 | the Functioning of the European Union, 248 | 249 | - any litigation arising between other parties and resulting from the 250 | interpretation of this License, will be subject to the exclusive jurisdiction 251 | of the competent court where the Licensor resides or conducts its primary 252 | business. 253 | 254 | 15. Applicable Law 255 | 256 | Without prejudice to specific agreement between parties, 257 | 258 | - this Licence shall be governed by the law of the European Union Member State 259 | where the Licensor has his seat, resides or has his registered office, 260 | 261 | - this licence shall be governed by Belgian law if the Licensor has no seat, 262 | residence or registered office inside a European Union Member State. 263 | 264 | Appendix 265 | 266 | ‘Compatible Licences’ according to Article 5 EUPL are: 267 | 268 | - GNU General Public License (GPL) v. 2, v. 3 269 | - GNU Affero General Public License (AGPL) v. 3 270 | - Open Software License (OSL) v. 2.1, v. 3.0 271 | - Eclipse Public License (EPL) v. 1.0 272 | - CeCILL v. 2.0, v. 2.1 273 | - Mozilla Public Licence (MPL) v. 2 274 | - GNU Lesser General Public Licence (LGPL) v. 2.1, v. 3 275 | - Creative Commons Attribution-ShareAlike v. 3.0 Unported (CC BY-SA 3.0) for 276 | works other than software 277 | - European Union Public Licence (EUPL) v. 1.1, v. 1.2 278 | - Québec Free and Open-Source Licence — Reciprocity (LiLiQ-R) or Strong 279 | Reciprocity (LiLiQ-R+). 280 | 281 | The European Commission may update this Appendix to later versions of the above 282 | licences without producing a new version of the EUPL, as long as they provide 283 | the rights granted in Article 2 of this Licence and protect the covered Source 284 | Code from exclusive appropriation. 285 | 286 | All other changes or additions to this Appendix require the production of a new 287 | EUPL version. 288 | -------------------------------------------------------------------------------- /blockbench/computerised_display_source.bbmodel: -------------------------------------------------------------------------------- 1 | {"meta":{"format_version":"4.0","creation_time":1658923346,"model_format":"java_block","box_uv":false},"name":"computerized_display_source","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"resolution":{"width":16,"height":16},"elements":[{"name":"connector","rescale":false,"locked":false,"from":[2,2,-1],"to":[14,14,1],"autouv":0,"color":0,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,10,10],"texture":0},"east":{"uv":[0,0,1,10],"texture":0},"south":{"uv":[0,0,1,12]},"west":{"uv":[0,0,1,10],"texture":0},"up":{"uv":[0,0,12,1],"texture":0},"down":{"uv":[0,0,12,1],"texture":0}},"type":"cube","uuid":"4ed57ebc-1ba0-9b9d-f19d-22c33ce9cba5"},{"name":"bottom","rescale":false,"locked":false,"from":[0,0,0],"to":[16,2,16],"autouv":1,"color":7,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,16,2],"texture":1},"east":{"uv":[0,0,16,2],"texture":1},"south":{"uv":[0,0,16,2],"texture":1},"west":{"uv":[0,0,16,2],"texture":1},"up":{"uv":[0,0,16,16],"texture":2},"down":{"uv":[0,0,16,16],"texture":2}},"type":"cube","uuid":"279d2402-893a-b2ed-effd-99b634ec3f07"},{"name":"top","rescale":false,"locked":false,"from":[0,14,0],"to":[16,16,16],"autouv":1,"color":7,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,16,2],"texture":1},"east":{"uv":[0,0,16,2],"texture":1},"south":{"uv":[0,0,16,2],"texture":1},"west":{"uv":[0,0,16,2],"texture":1},"up":{"uv":[0,0,16,16],"texture":2},"down":{"uv":[0,0,16,16],"texture":2}},"type":"cube","uuid":"fffb332a-6974-b51b-d760-ae6627e709cc"},{"name":"center","rescale":false,"locked":false,"from":[1,2,1],"to":[15,14,15],"autouv":1,"color":7,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,14,12],"texture":3},"east":{"uv":[0,0,14,12],"texture":3},"south":{"uv":[0,0,14,12],"texture":3},"west":{"uv":[0,0,14,12],"texture":3},"up":{"uv":[0,0,14,14]},"down":{"uv":[0,0,14,14]}},"type":"cube","uuid":"105c7144-ca00-47ba-9fe7-6fc1d247af17"}],"outliner":[{"name":"VoxelShapes","origin":[0,0,0],"color":0,"nbt":"{}","armAnimationEnabled":false,"uuid":"0884aead-16c2-c3be-da0d-8878e2d7c5a7","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["4ed57ebc-1ba0-9b9d-f19d-22c33ce9cba5","279d2402-893a-b2ed-effd-99b634ec3f07","fffb332a-6974-b51b-d760-ae6627e709cc","105c7144-ca00-47ba-9fe7-6fc1d247af17"]}],"textures":[{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\filtered_detector_front.png","name":"filtered_detector_front.png","folder":"block","namespace":"create","id":"0","particle":true,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"ebf7d3bc-e161-952d-58d0-cb96b7ef3652","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/filtered_detector_front.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAR9JREFUOE/tUrGKg0AQfaazEwRbQbC2EGs7sRJsQ/BH0t5fXCchOYSDu07srMVCSCcItoIgpLD0mOHWxJxHSJ9pdnZ25u2beSMlSTIBgKIodEBVVfR9zycZ+ffmeZ4kYhIBBEHA93EcF7nDMDBwURQcdxyH/QVAlmUTPcRxDE3TIMvyDNK2LaIoQtM0HDMMg33btq8MyrKc6CFNU3xvt3PxBcDueITv+/wrtUR5qwxM00RVVfgIQ1AhWbuZ8Pb5BcuyUNc1xyiP/EULgkGe53gPwyv9XwDXdZk2DZNafdjCecOisO0Pp8ctCAY0RF3X52JSpOs6kEJEW8zgXwZUKWS71/1WxlUAsThrS/Nni4DlENcSnonNC/FM0W3uCwD4AQtbnxFea/9LAAAAAElFTkSuQmCC"},{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\brass_casing_side.png","name":"brass_casing_side.png","folder":"block","namespace":"create","id":"1","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"72f0a1e4-e4c3-c4f8-a2d8-29716a2602cf","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/brass_casing_side.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAWZJREFUOE+dUsFKw0AQnUnTtEnFWqFYCt7soRQRBEE89OBNEDzofwie/AC/wA/xu4QKtZU2zSbtypsw6Sa0HpzL7s57OzvvzfLr07mNKCVEI/RlrUYSZzvxaczEH29jC3QwOhXS7PO7uN/uHZXOq2X+EGIer2Tl20HLphuiukfkB15ByMyGkEeEzW1eCcC/fgzxw2VPOjBrWSSCGpdUAFuYlFpBvcCmsck7uLs4se4FACAicKkabpHJPCG+OevYpVkLLwpqsuLs7pMs19LwParuRQK0T2Yr6rabpQerOehWqeiuEwZlCa5WELLUkl/nQtIub3g8PBb3VJtr5mxhqHvYKLpyX9ckD/sHUgD61Ad4oFqVqHiVU3gAwNUYhbmh+wJcTEwKoLV9s9cCkKh/QccLj/jxum+r7rqv6p/QnF7GBKQD14Nds1d/gOl/cf3h9+er7R/+U3UZXC6YopYlfrkf/auAlvsFFk/Rq3UFaSMAAAAASUVORK5CYII="},{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\brass_casing.png","name":"brass_casing.png","folder":"block","namespace":"create","id":"2","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"22633162-c1b9-d82d-d439-4bf954c0e5e9","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/brass_casing.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAZFJREFUOE+VUr9Lw0AUfpekKW2wVlARHEQLWqhCwX9DF+0gDuLi4CoOzp0d3ARdXAQX/5eCFapDdZR2MK0maX715F14ySUGwW95ebl3333fd8cuWlu8DD4giiVN1CxcJ8hd/3QYsHarzlfrVWhu18TQ6MOM988uVVP9xI4OQoydCXQ7g4hgs7kI7ZuOWCjrqqhagUHgc1GzwP/nx1u/CVbmy+CFHHSVgRdMwQ85FDQl7nVVEVzDLxdODzbgrWcCwwwadQOuH15goVJMCEIuhv1gGgtAMoTl+XCyvw7PPSshuH18FZIRthfGVvJ6/He0V4P3vptkcHn3lFJAx5IlOYfh2BUEg/53QnB13wVDL8RzJB1ly99k4XB3LSKgDNACEuAwec2mT0S2GyQWZIK5kh7vsdwQjGJ0pQjZClkQGci3QPePlQKldyAHXDE0QAupEDEDWQGeSMB3gYrI2sjy8kPUFTXtn3PxmBBiM+egawrkWsAQCSQ3G6Lcp95BdXnmr9ncNdtiYJoOsLOdRmL23zQAP2aU7p+Dky3/AAAAAElFTkSuQmCC"},{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\brass_casing_inner.png","name":"brass_casing_inner.png","folder":"block","namespace":"create","id":"3","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"2e42e593-58d6-f878-8b13-9c2add168bb7","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/brass_casing_inner.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAT9JREFUOE91Uz1PwzAQPTchkVKpCKQCP6BDJSSQGBmYWDrx/39DJ4oaKaldo3fJs+wL3BKfe7bfV93h9THKXP0QpGsr7b7Po9yuG/4kF3/V9U290jW+KPexv9cLTr2Xrqmkrp14H6Ufg2y6WofQY5/FHl9HBHixa6cDLL5SbJrGHV4eYlOt5Pgz6AU41FRORn+VS4hFj7kJt8gYos79iWDdVjqAInfy517S4H13p5PkjjX4Q48krunzWff19pRcwAFC4+HzEKQfvGw3bcF+QcEKldtGgQm7sPHzeZsQWI/JFwhyh/I5FRFq2gL0pMF8AcS15SgihWNgEBKKy5DlAnNuISJfoI3WStDJIz7lIEYNTe61NvM+cwHxqAfppCDl3KwmQENXeMEiSFYcG6b/QlW4QOUB73ia/huEagPGC38BXLrHrPBkj80AAAAASUVORK5CYII="}],"display":{"thirdperson_righthand":{"rotation":[75,45,0],"translation":[0,2.5,0],"scale":[0.375,0.375,0.375]},"thirdperson_lefthand":{"rotation":[75,45,0],"translation":[0,2.5,0],"scale":[0.375,0.375,0.375]},"firstperson_righthand":{"rotation":[0,45,0],"scale":[0.4,0.4,0.4]},"firstperson_lefthand":{"rotation":[0,225,0],"scale":[0.4,0.4,0.4]},"ground":{"translation":[0,3,0],"scale":[0.25,0.25,0.25]},"gui":{"rotation":[30,225,0],"scale":[0.625,0.625,0.625]},"fixed":{"scale":[0.5,0.5,0.5]}}} -------------------------------------------------------------------------------- /blockbench/computerized_display_target.bbmodel: -------------------------------------------------------------------------------- 1 | {"meta":{"format_version":"4.0","creation_time":1658945022,"model_format":"java_block","box_uv":false},"name":"computerized_display_target","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"resolution":{"width":16,"height":16},"elements":[{"name":"connector","rescale":false,"locked":false,"from":[2,2,-2],"to":[14,14,0],"autouv":0,"color":0,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,10,10],"texture":0},"east":{"uv":[0,0,1,10],"texture":0},"south":{"uv":[0,0,3,3],"texture":0},"west":{"uv":[0,0,1,10],"texture":0},"up":{"uv":[0,0,12,1],"texture":0},"down":{"uv":[0,0,12,1],"texture":0}},"type":"cube","uuid":"591d70b4-cfa6-5772-db8f-5bbacff2721f"},{"name":"hind","rescale":false,"locked":false,"from":[2,2,5],"to":[14,14,10],"autouv":0,"color":4,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,16,16],"texture":1},"east":{"uv":[0,0,5,16],"texture":3},"south":{"uv":[0,0,16,16],"texture":1},"west":{"uv":[0,0,5,16],"texture":3},"up":{"uv":[0,0,5,16],"rotation":90,"texture":3},"down":{"uv":[0,0,5,16],"rotation":90,"texture":3}},"type":"cube","uuid":"a04246c0-4ef2-124b-6fbb-85228ec94d66"},{"name":"front","rescale":false,"locked":false,"from":[0,0,0],"to":[16,16,5],"autouv":0,"color":4,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,16,16],"texture":1},"east":{"uv":[0,0,5,16],"texture":3},"south":{"uv":[0,0,16,16],"texture":1},"west":{"uv":[0,0,5,16],"texture":3},"up":{"uv":[0,0,5,16],"rotation":90,"texture":3},"down":{"uv":[0,0,5,16],"rotation":90,"texture":3}},"type":"cube","uuid":"6364be50-bb8f-6dc7-fe54-efaa226938f2"},{"name":"antenna","rescale":false,"locked":false,"from":[7,13,10],"to":[9,18,12],"autouv":0,"color":6,"origin":[0,0,0],"faces":{"north":{"uv":[1,1,2,4],"texture":4},"east":{"uv":[1,1,2,4],"texture":4},"south":{"uv":[1,1,2,4],"texture":4},"west":{"uv":[1,1,2,4],"texture":4},"up":{"uv":[1,1,2,2],"texture":4},"down":{"uv":[1,9,2,10],"texture":4}},"type":"cube","uuid":"aeb0686d-0571-decb-ff9d-e9d48c6d2ace"},{"name":"dish","rescale":false,"locked":false,"from":[5,17,8],"to":[11,17,14],"autouv":0,"color":4,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,4,0]},"east":{"uv":[0,0,4,0]},"south":{"uv":[0,0,4,0]},"west":{"uv":[0,0,4,0]},"up":{"uv":[4,0,9,5],"texture":4},"down":{"uv":[4,0,9,5],"texture":4}},"type":"cube","uuid":"226392ad-731b-dabd-7292-70432c5c2acc"}],"outliner":["aeb0686d-0571-decb-ff9d-e9d48c6d2ace","226392ad-731b-dabd-7292-70432c5c2acc",{"name":"VoxelShapes","origin":[0,0,0],"color":0,"nbt":"{}","armAnimationEnabled":false,"uuid":"59d725b7-2382-50f1-30d3-4262e657978b","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["6364be50-bb8f-6dc7-fe54-efaa226938f2","591d70b4-cfa6-5772-db8f-5bbacff2721f","a04246c0-4ef2-124b-6fbb-85228ec94d66"]}],"textures":[{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\filtered_detector_front.png","name":"filtered_detector_front.png","folder":"block","namespace":"create","id":"0","particle":true,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"8f41f452-ae3f-f102-d9cb-bc47990ff8d4","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/filtered_detector_front.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAR9JREFUOE/tUrGKg0AQfaazEwRbQbC2EGs7sRJsQ/BH0t5fXCchOYSDu07srMVCSCcItoIgpLD0mOHWxJxHSJ9pdnZ25u2beSMlSTIBgKIodEBVVfR9zycZ+ffmeZ4kYhIBBEHA93EcF7nDMDBwURQcdxyH/QVAlmUTPcRxDE3TIMvyDNK2LaIoQtM0HDMMg33btq8MyrKc6CFNU3xvt3PxBcDueITv+/wrtUR5qwxM00RVVfgIQ1AhWbuZ8Pb5BcuyUNc1xyiP/EULgkGe53gPwyv9XwDXdZk2DZNafdjCecOisO0Pp8ctCAY0RF3X52JSpOs6kEJEW8zgXwZUKWS71/1WxlUAsThrS/Nni4DlENcSnonNC/FM0W3uCwD4AQtbnxFea/9LAAAAAElFTkSuQmCC"},{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\brass_casing.png","name":"brass_casing.png","folder":"block","namespace":"create","id":"1","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"1c3d5596-4a90-ed37-bfb2-502f0d46aad2","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/brass_casing.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAZFJREFUOE+VUr9Lw0AUfpekKW2wVlARHEQLWqhCwX9DF+0gDuLi4CoOzp0d3ARdXAQX/5eCFapDdZR2MK0maX715F14ySUGwW95ebl3333fd8cuWlu8DD4giiVN1CxcJ8hd/3QYsHarzlfrVWhu18TQ6MOM988uVVP9xI4OQoydCXQ7g4hgs7kI7ZuOWCjrqqhagUHgc1GzwP/nx1u/CVbmy+CFHHSVgRdMwQ85FDQl7nVVEVzDLxdODzbgrWcCwwwadQOuH15goVJMCEIuhv1gGgtAMoTl+XCyvw7PPSshuH18FZIRthfGVvJ6/He0V4P3vptkcHn3lFJAx5IlOYfh2BUEg/53QnB13wVDL8RzJB1ly99k4XB3LSKgDNACEuAwec2mT0S2GyQWZIK5kh7vsdwQjGJ0pQjZClkQGci3QPePlQKldyAHXDE0QAupEDEDWQGeSMB3gYrI2sjy8kPUFTXtn3PxmBBiM+egawrkWsAQCSQ3G6Lcp95BdXnmr9ncNdtiYJoOsLOdRmL23zQAP2aU7p+Dky3/AAAAAElFTkSuQmCC"},{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\redstone_bridge.png","name":"redstone_bridge.png","folder":"block","namespace":"create","id":"2","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"d4b89823-24d8-c01e-018c-99ab81937655","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/redstone_bridge.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAxZJREFUWEftl0tPE1EUx8/tY8rwaCmCQkJ91ahh4Svqzg1uNMS4IW5dmfgJXLpwyRfQxK/gzrWuXJrIRuIjNRIkECAUOpRppzO95n/hjHeGW+wE1MRwN/O455z7+59755xWPLp9QVaWtqkvlybTqDcDKo/1qinYYexni3nYv3zzWRgDxl6KyYmS7MYwqc3buYVkAKBmhbyY/g6qORtxu7g9bF9/+N4dwL2rpyUC7zc45b+z4xhHAEcZ+L8zYPpc/8pn2O0nyDCHXojiRalT2f5jpdik6N3zKVXGG9stYx2ruQ31fqW200NWvm3RQlVG+oTothmZmsuVk/lEfaR0bEiVc12MMKno6c1GVLESVsNKVqqbtLbVpOH+HDlNn3KZnY5a91rUZ2Wp5nrh3Lrj0Z2bp+hjxYn0CRFXkU1He0grMIsc6i9QLuuFi1Rdj4q2RV4gFQBGEEjK25Z6rtV9M8DdyyekTqqryKRS5LfbhGuzFUSCIZ3LG1WysimlEgCwgz8WBAyy47XaCgZCjBm4caYg9SCsotdOU9XxFACr0YMBoD07T9XyIBX6LGr6AQ3kMmEGRgo9tLTm0nhlg5ZIklPKmwFuCZJBuUgj+agKHQBQq7VmJBgA7Nl5+lEepLFhm7bdgKy0CAFMPpOXSvR1sR49A1NCSJMKVoTUmtToAMgABgBgj8E+xcoGLQpJNN4hAw+EkHEVvJ/FAYt8b2cLkAE9WKcM8GFkn3SlSg7OdRKAjJVS+w+A1c2GOlAA0IPph3B06NcWwJd9Eh1CDgJy7D/2VL8ur7uREw2AlGgoMD4DcV8cQmzPvp/h/WujEqQMgEUxGIBrLAC44KCoMIDJt5OP8RDqhShehPj7xRVzelFCIVrf2gx7gO7LdnGfQy/FD6fPKYADNaMXT65L1HaMnJ1R16brh/csEe+On+2nxzPvw1rNvp38TD5hynZvxLPpixItcmB3cd3AcX31iDncl4qCnr76FAH4MueGc7ovxzw/YUeg9wBwO8ZE0v983cDHofcAxF8keT7Ibwlep6v/b0mgktr+c4Cfy1bqP07FTPsAAAAASUVORK5CYII="},{"path":"C:\\Coding\\createcomputing\\src\\main\\resources\\assets\\createcomputing\\textures\\block\\brass_casing_slab.png","name":"brass_casing_slab.png","folder":"block","namespace":"createcomputing","id":"3","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"cc0b0ed7-938d-02d4-6996-97124be573f1","relative_path":"../../src/main/resources/assets/createcomputing/textures/block/brass_casing_slab.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAM9JREFUOE9jrAjR/c/F8JsBBNg5WRjef2dk6FhzmREsQARgbArR+K+oIcBgYKzMcPvqY4YrF14x1K25QZoBOgZiDE2zLjDUpRlQZkBxnBbD/RsfSHMBKAy0NbgZpq+4yZAZoc5w9cZX0sIAZsDstbcYonyVGB7c+0maAaBABIVBz4LLDHFBygyv7n0hzQswAyYsvQJ2AckGUOwFqhkAigVQGJAdiGSHAXogkuwCisMA5AIBaV5wvvv2lZHhw4fvpCWkIh/t/+i5tm/LVaJzIwBwAZYRbLZp8gAAAABJRU5ErkJggg=="},{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\redstone_antenna.png","name":"redstone_antenna.png","folder":"block","namespace":"create","id":"4","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"b47e351a-ebe7-2f24-368a-c9bc207ac78d","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/redstone_antenna.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAPRJREFUOE9jZMACHj58+P/Lly9gGW1tbUZsamBiYMlAKan/6589A7Nhmh89esTAx8fHICAgADdES0vr/7Vr11AMBHNyw83+T155Csy+fPny/ydPnjB8/fqVgZubm4GXl5fBxsYGLGdra/v/8OHDmAaEuur9X737Elji6tWr/z98+MDw6dMnsAv+//8PNwBZHYoXnEyV/u87fQ9uMsiQd+/eMTAyMsI1gzSgqwOJgTVhMxlbwOF0AcUG2BrI/j984THe6AIHIhZ1YE3WetL/j156StAAbOrAmsy1xP+fvPaSoAHY1BHUhC8VwmOBkCKCSXmEGwAACf13EThOGKEAAAAASUVORK5CYII="}],"display":{"thirdperson_righthand":{"rotation":[75,-145,0],"translation":[0,2.5,0],"scale":[0.375,0.375,0.375]},"thirdperson_lefthand":{"rotation":[75,45,0],"translation":[0,2.5,0],"scale":[0.375,0.375,0.375]},"firstperson_righthand":{"rotation":[0,45,0],"scale":[0.4,0.4,0.4]},"firstperson_lefthand":{"rotation":[0,225,0],"scale":[0.4,0.4,0.4]},"ground":{"translation":[0,3,0],"scale":[0.25,0.25,0.25]},"gui":{"rotation":[30,225,0],"scale":[0.625,0.625,0.625]},"fixed":{"scale":[0.5,0.5,0.5]}}} -------------------------------------------------------------------------------- /blockbench/computerized_redstone_link.bbmodel: -------------------------------------------------------------------------------- 1 | {"meta":{"format_version":"4.0","model_format":"java_block","box_uv":false},"name":"computerized_redstone_link","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"resolution":{"width":16,"height":16},"elements":[{"name":"box","rescale":false,"locked":false,"from":[1,0,1],"to":[15,2,15],"autouv":0,"color":4,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,14,2],"texture":1},"east":{"uv":[0,0,14,2],"texture":1},"south":{"uv":[0,0,14,2],"texture":1},"west":{"uv":[0,0,14,2],"texture":1},"up":{"uv":[1,1,15,15],"texture":2},"down":{"uv":[1,1,15,15],"texture":2}},"type":"cube","uuid":"6ab9df4b-2d79-ae67-a995-d407e4b7d2c7"},{"name":"stick","rescale":false,"locked":false,"from":[2,2,2],"to":[3,10,3],"autouv":0,"color":5,"origin":[0,0,0],"faces":{"north":{"uv":[1,2,2,10],"texture":3},"east":{"uv":[1,2,2,10],"texture":3},"south":{"uv":[1,2,2,10],"texture":3},"west":{"uv":[1,2,2,10],"texture":3},"up":{"uv":[2,1,3,2],"texture":3},"down":{"uv":[0,0,1,1]}},"type":"cube","uuid":"d08ca785-2762-01f9-742b-8dee066d3e84"},{"name":"dish","rescale":false,"locked":false,"from":[0,9,0],"to":[5,9,5],"autouv":0,"color":5,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,5,0]},"east":{"uv":[0,0,5,0]},"south":{"uv":[0,0,5,0]},"west":{"uv":[0,0,5,0]},"up":{"uv":[4,0,9,5],"texture":3},"down":{"uv":[4,0,9,5],"texture":3}},"type":"cube","uuid":"4c22dbfc-d5b2-89e8-f050-ee0047022709"},{"name":"stick","rescale":false,"locked":false,"from":[8,2,2],"to":[9,10,3],"autouv":0,"color":5,"origin":[0,0,0],"faces":{"north":{"uv":[1,2,2,10],"texture":3},"east":{"uv":[1,2,2,10],"texture":3},"south":{"uv":[1,2,2,10],"texture":3},"west":{"uv":[1,2,2,10],"texture":3},"up":{"uv":[2,1,3,2],"texture":3},"down":{"uv":[0,0,1,1]}},"type":"cube","uuid":"fc51e6f3-164e-1115-fdb5-73e905ba937c"},{"name":"cube","rescale":false,"locked":false,"from":[2,-1,2],"to":[14,0,14],"autouv":0,"color":7,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,12,1],"texture":4},"east":{"uv":[0,0,12,1],"texture":4},"south":{"uv":[0,0,12,1],"texture":4},"west":{"uv":[0,0,12,1],"texture":4},"up":{"uv":[0,0,12,12]},"down":{"uv":[0,0,10,10],"texture":4}},"type":"cube","uuid":"c54fec1f-a187-289c-d9ed-f15e8c0cd0a8"}],"outliner":[{"name":"antenna 1","origin":[0,0,0],"color":0,"nbt":"{}","armAnimationEnabled":false,"uuid":"388bde65-fb8b-a828-9d4c-843c267ea8da","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["fc51e6f3-164e-1115-fdb5-73e905ba937c","c54fec1f-a187-289c-d9ed-f15e8c0cd0a8"]},{"name":"antenna 1","origin":[0,0,0],"color":0,"nbt":"{}","armAnimationEnabled":false,"uuid":"8466190f-aa1e-0ffe-a0a8-ffe184a60eae","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["d08ca785-2762-01f9-742b-8dee066d3e84","4c22dbfc-d5b2-89e8-f050-ee0047022709"]},{"name":"VoxelShapes","origin":[0,0,0],"color":0,"nbt":"{}","armAnimationEnabled":false,"uuid":"45700195-9ab4-e25e-ca62-33988cc74b7d","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":["6ab9df4b-2d79-ae67-a995-d407e4b7d2c7"]}],"textures":[{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\brass_casing_inner.png","name":"brass_casing_inner.png","folder":"block","namespace":"create","id":"0","particle":true,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"5ee7dca0-8235-14e5-d9e7-f667bf2f9d55","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/brass_casing_inner.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAT9JREFUOE91Uz1PwzAQPTchkVKpCKQCP6BDJSSQGBmYWDrx/39DJ4oaKaldo3fJs+wL3BKfe7bfV93h9THKXP0QpGsr7b7Po9yuG/4kF3/V9U290jW+KPexv9cLTr2Xrqmkrp14H6Ufg2y6WofQY5/FHl9HBHixa6cDLL5SbJrGHV4eYlOt5Pgz6AU41FRORn+VS4hFj7kJt8gYos79iWDdVjqAInfy517S4H13p5PkjjX4Q48krunzWff19pRcwAFC4+HzEKQfvGw3bcF+QcEKldtGgQm7sPHzeZsQWI/JFwhyh/I5FRFq2gL0pMF8AcS15SgihWNgEBKKy5DlAnNuISJfoI3WStDJIz7lIEYNTe61NvM+cwHxqAfppCDl3KwmQENXeMEiSFYcG6b/QlW4QOUB73ia/huEagPGC38BXLrHrPBkj80AAAAASUVORK5CYII="},{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\brass_casing_side.png","name":"brass_casing_side.png","folder":"block","namespace":"create","id":"1","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"82c1f331-ef7e-60bc-0d92-b5b64210cd0a","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/brass_casing_side.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAWZJREFUOE+dUsFKw0AQnUnTtEnFWqFYCt7soRQRBEE89OBNEDzofwie/AC/wA/xu4QKtZU2zSbtypsw6Sa0HpzL7s57OzvvzfLr07mNKCVEI/RlrUYSZzvxaczEH29jC3QwOhXS7PO7uN/uHZXOq2X+EGIer2Tl20HLphuiukfkB15ByMyGkEeEzW1eCcC/fgzxw2VPOjBrWSSCGpdUAFuYlFpBvcCmsck7uLs4se4FACAicKkabpHJPCG+OevYpVkLLwpqsuLs7pMs19LwParuRQK0T2Yr6rabpQerOehWqeiuEwZlCa5WELLUkl/nQtIub3g8PBb3VJtr5mxhqHvYKLpyX9ckD/sHUgD61Ad4oFqVqHiVU3gAwNUYhbmh+wJcTEwKoLV9s9cCkKh/QccLj/jxum+r7rqv6p/QnF7GBKQD14Nds1d/gOl/cf3h9+er7R/+U3UZXC6YopYlfrkf/auAlvsFFk/Rq3UFaSMAAAAASUVORK5CYII="},{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\brass_casing.png","name":"brass_casing.png","folder":"block","namespace":"create","id":"2","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"7b89993d-b0bf-324e-b069-b035682425fc","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/brass_casing.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAZFJREFUOE+VUr9Lw0AUfpekKW2wVlARHEQLWqhCwX9DF+0gDuLi4CoOzp0d3ARdXAQX/5eCFapDdZR2MK0maX715F14ySUGwW95ebl3333fd8cuWlu8DD4giiVN1CxcJ8hd/3QYsHarzlfrVWhu18TQ6MOM988uVVP9xI4OQoydCXQ7g4hgs7kI7ZuOWCjrqqhagUHgc1GzwP/nx1u/CVbmy+CFHHSVgRdMwQ85FDQl7nVVEVzDLxdODzbgrWcCwwwadQOuH15goVJMCEIuhv1gGgtAMoTl+XCyvw7PPSshuH18FZIRthfGVvJ6/He0V4P3vptkcHn3lFJAx5IlOYfh2BUEg/53QnB13wVDL8RzJB1ly99k4XB3LSKgDNACEuAwec2mT0S2GyQWZIK5kh7vsdwQjGJ0pQjZClkQGci3QPePlQKldyAHXDE0QAupEDEDWQGeSMB3gYrI2sjy8kPUFTXtn3PxmBBiM+egawrkWsAQCSQ3G6Lcp95BdXnmr9ncNdtiYJoOsLOdRmL23zQAP2aU7p+Dky3/AAAAAElFTkSuQmCC"},{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\redstone_antenna_powered.png","name":"redstone_antenna_powered.png","folder":"block","namespace":"create","id":"3","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"1ecdeba7-eef3-c37d-78bd-aadd28c24765","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/redstone_antenna_powered.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAARxJREFUOE9jZGBgYPjLwPCfmYGBEcQGgYcPH/7/8uULmK2trQ0Xr62t/d/c3Azng+QZQZr/r4hnYIxYyAAyBKT574d3DF9uX2P4IyrFwC4iBjYEpLm+vp6hsbGRAdkQsGnrGRj+B0JdcO3ixf9f7t9i4Hz7kuE/vyDDJwl5BhsbG7C6pKSk//PmzUN1AUgiN9zs/+SVp8ASV69e/f/zzSuGP+/fMLAIijB8Y2aFG4CsDuZdsCYnU6X/+07fg5sMMuTjmzcM/5iZ4ZqxqQOHAYgIddX7v3r3JRSnwWxAprGpo44Btgay/w9feEzQBdjUgTVZ60n/P3rpKUEDsKkDazLXEv9/8tpLggZgU0dQE7bARBYbNQApCxMKLFzyAAsqgBGiwxhuAAAAAElFTkSuQmCC"},{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\filtered_detector_front.png","name":"filtered_detector_front.png","folder":"block","namespace":"create","id":"4","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"7e722d7e-ec58-46ac-43f0-f6b09c2de9d0","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/filtered_detector_front.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAR9JREFUOE/tUrGKg0AQfaazEwRbQbC2EGs7sRJsQ/BH0t5fXCchOYSDu07srMVCSCcItoIgpLD0mOHWxJxHSJ9pdnZ25u2beSMlSTIBgKIodEBVVfR9zycZ+ffmeZ4kYhIBBEHA93EcF7nDMDBwURQcdxyH/QVAlmUTPcRxDE3TIMvyDNK2LaIoQtM0HDMMg33btq8MyrKc6CFNU3xvt3PxBcDueITv+/wrtUR5qwxM00RVVfgIQ1AhWbuZ8Pb5BcuyUNc1xyiP/EULgkGe53gPwyv9XwDXdZk2DZNafdjCecOisO0Pp8ctCAY0RF3X52JSpOs6kEJEW8zgXwZUKWS71/1WxlUAsThrS/Nni4DlENcSnonNC/FM0W3uCwD4AQtbnxFea/9LAAAAAElFTkSuQmCC"}],"display":{"thirdperson_righthand":{"rotation":[75,45,0],"translation":[0,2.5,0],"scale":[0.375,0.375,0.375]},"thirdperson_lefthand":{"rotation":[75,45,0],"translation":[0,2.5,0],"scale":[0.375,0.375,0.375]},"firstperson_righthand":{"rotation":[0,45,0],"scale":[0.4,0.4,0.4]},"firstperson_lefthand":{"rotation":[0,225,0],"scale":[0.4,0.4,0.4]},"ground":{"translation":[0,3,0],"scale":[0.25,0.25,0.25]},"gui":{"rotation":[30,225,0],"scale":[0.625,0.625,0.625]},"fixed":{"scale":[0.5,0.5,0.5]}}} -------------------------------------------------------------------------------- /blockbench/train_network_observer.bbmodel: -------------------------------------------------------------------------------- 1 | {"meta":{"format_version":"4.0","model_format":"java_block","box_uv":false},"name":"train_network_observer","parent":"","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"resolution":{"width":16,"height":16},"elements":[{"name":"bottom","rescale":false,"locked":false,"from":[0,0,0],"to":[16,2,16],"autouv":0,"color":0,"origin":[0,0,0],"faces":{"north":{"uv":[0,14,16,16],"texture":1},"east":{"uv":[0,14,16,16],"texture":1},"south":{"uv":[0,14,16,16],"texture":1},"west":{"uv":[0,14,16,16],"texture":1},"up":{"uv":[0,0,16,16],"texture":0},"down":{"uv":[0,0,16,16]}},"type":"cube","uuid":"e5325358-842d-8037-c92d-68a4257927dc"},{"name":"top","rescale":false,"locked":false,"from":[0,14,0],"to":[16,16,16],"autouv":0,"color":0,"origin":[0,0,0],"faces":{"north":{"uv":[0,14,16,16],"texture":1},"east":{"uv":[0,14,16,16],"texture":1},"south":{"uv":[0,14,16,16],"texture":1},"west":{"uv":[0,14,16,16],"texture":1},"up":{"uv":[0,0,16,16],"texture":0},"down":{"uv":[0,0,16,16],"texture":0}},"type":"cube","uuid":"03a3879f-4767-8ece-e307-156ce45c8b5b"},{"name":"center","rescale":false,"locked":false,"from":[1,2,1],"to":[15,14,15],"autouv":0,"color":7,"origin":[0,0,0],"faces":{"north":{"uv":[1,3,15,14],"texture":1},"east":{"uv":[1,3,15,14],"texture":1},"south":{"uv":[1,3,15,14],"texture":1},"west":{"uv":[1,3,15,14],"texture":1},"up":{"uv":[0,0,14,14]},"down":{"uv":[0,0,14,14]}},"type":"cube","uuid":"32de849b-c7a4-4bac-6de7-8342f17ad83d"},{"name":"pile_ne","rescale":false,"locked":false,"from":[15,2,0],"to":[16,14,1],"autouv":1,"color":1,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,1,12],"texture":0},"east":{"uv":[0,0,1,12],"texture":0},"south":{"uv":[0,0,1,12],"texture":0},"west":{"uv":[0,0,1,12],"texture":0},"up":{"uv":[0,0,1,1]},"down":{"uv":[0,0,1,1]}},"type":"cube","uuid":"bc7581fc-67dd-54b8-bb49-f260dc06433d"},{"name":"pile_sw","rescale":false,"locked":false,"from":[0,2,15],"to":[1,14,16],"autouv":1,"color":1,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,1,12],"texture":0},"east":{"uv":[0,0,1,12],"texture":0},"south":{"uv":[0,0,1,12],"texture":0},"west":{"uv":[0,0,1,12],"texture":0},"up":{"uv":[0,0,1,1]},"down":{"uv":[0,0,1,1]}},"type":"cube","uuid":"29174c00-86b8-085a-e03d-2369107c4c20"},{"name":"pile_nw","rescale":false,"locked":false,"from":[0,2,0],"to":[1,14,1],"autouv":1,"color":1,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,1,12],"texture":0},"east":{"uv":[0,0,1,12],"texture":0},"south":{"uv":[0,0,1,12],"texture":0},"west":{"uv":[0,0,1,12],"texture":0},"up":{"uv":[0,0,1,1]},"down":{"uv":[0,0,1,1]}},"type":"cube","uuid":"b2c01e77-2c7e-a19b-8611-6749343187e2"},{"name":"pile_se","rescale":false,"locked":false,"from":[15,2,15],"to":[16,14,16],"autouv":1,"color":1,"origin":[0,0,0],"faces":{"north":{"uv":[0,0,1,12],"texture":0},"east":{"uv":[0,0,1,12],"texture":0},"south":{"uv":[0,0,1,12],"texture":0},"west":{"uv":[0,0,1,12],"texture":0},"up":{"uv":[0,0,1,1]},"down":{"uv":[0,0,1,1]}},"type":"cube","uuid":"fa777615-5c4e-e660-4581-39868e369c9d"},{"name":"connector","rescale":false,"locked":false,"from":[2,15,2],"to":[14,17,14],"autouv":0,"color":5,"origin":[0,0,0],"faces":{"north":{"uv":[10,0,12,10],"rotation":90,"texture":2},"east":{"uv":[10,0,12,10],"rotation":90,"texture":2},"south":{"uv":[10,0,12,10],"rotation":90,"texture":2},"west":{"uv":[10,0,12,10],"rotation":90,"texture":2},"up":{"uv":[0,0,10,10],"texture":2},"down":{"uv":[0,0,12,12]}},"type":"cube","uuid":"fc9a61fe-0980-8fdd-959a-069ffbd35f91"}],"outliner":[{"name":"VoxelShapes","origin":[0,0,0],"color":0,"nbt":"{}","armAnimationEnabled":false,"uuid":"d76985e8-4876-203a-bfc5-23d9ead3e2b9","export":true,"isOpen":true,"locked":false,"visibility":true,"autouv":0,"children":[]},"fc9a61fe-0980-8fdd-959a-069ffbd35f91","e5325358-842d-8037-c92d-68a4257927dc","03a3879f-4767-8ece-e307-156ce45c8b5b","32de849b-c7a4-4bac-6de7-8342f17ad83d","bc7581fc-67dd-54b8-bb49-f260dc06433d","fa777615-5c4e-e660-4581-39868e369c9d","29174c00-86b8-085a-e03d-2369107c4c20","b2c01e77-2c7e-a19b-8611-6749343187e2"],"textures":[{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\signal_box_top.png","name":"signal_box_top.png","folder":"block","namespace":"create","id":"0","particle":true,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"b4ee22ef-474e-61b3-53e7-94e3081774d1","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/signal_box_top.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAf1JREFUOE99Uz1vE0EQfZv4vu0LFxsbhJUgcIMooAIJRUKBkgYJBYpI1PwDQg0SPfyE1MCP4A+kSUcZAjFxYu5772wvmj0mOYPhNXszOzez8+aNuH+jrZbNZRAssaRPhlQzTIvpnM+1DG3TnW+bEJSAnEGnqS/KtIThVkFs8zf5LcuFlCmiOEeSFRCP7/aV37SRywkGax2keTFXsW64tgnLNLD/5Ru67RaGowji6cZVRcajF2+w9+Gtji8mAmZD6ZNBNuP2k1f4+O4l0nwCsb05UN3AgcJ5MAVSNQa/in22ZeJoFCFOUogHt7rKc0x02qu6N+Lgf2B+4kSiLBXE84fXVMvz4HtVRd87J3BRotNI4iSZosxSxETi9uZ1FfguLgbVFGRRzhHp/B4bJ8tkCaWgY8JYViTaVgP93oW/fqReCadhok/mYDab4fBHiDDOqzEuWTbWOi5WV5pIswnyIj97vW3aEGIKqsygRMfjBElWVkLyVxy0mvZC4dRJZQJJTMejE4Q/s2qMnmOg3wv07BmKGq2BNUEcEQ6OxlULWxvrqtf2tZA+774+4+FfOiAl3nm2g0/vdzAOM4ite+uqf8nH12GEm4PLc1W5GjnrEj8chrjSbeHge1gJibaQlokXiXpkkLj+tCkuTqXeSE0irfOiVaYkvM71NebkRsPEL0QO81m7Q1w7AAAAAElFTkSuQmCC"},{"path":"C:\\Coding\\createcomputing\\src\\main\\resources\\assets\\createcomputing\\textures\\block\\train_network_observer_side.png","name":"train_network_observer_side.png","folder":"block","namespace":"createcomputing","id":"1","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"6ab46808-f9e3-4a95-3526-13a7b93e4f3c","relative_path":"../../src/main/resources/assets/createcomputing/textures/block/train_network_observer_side.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAUBJREFUOE/NU1FLAkEQ/hbx8HYPRM3qIVN7MMOXg8Kol4L+QL87CnoJpIdS7EFLkaLdvc7kYgY2PKLTt5qXndv55tv5ZubE5fFOUi0HUL6HcjGAsZ+I4ghZJgse3vQHnkYziLODSkLgnJdjEm3jzGQKOtwiXkCcnl8k1c0KlF9AoBTetYa2Uerb3dM5nkw5RpiX5ylE2D1JpJT8qjEGzv+tjGUM+UzQPQpxdX3LOVbbTAm+8jnucsRus5X4UsIawwHyx4dNzGevmE9mfJffKCFfKmLr5jGFo5yUBOpF7+7+m2C5FEfQ7rRYu5Ms9jthQmWRdql8KCUx6A/Rb2+npDR6I9QbNWhtYLTlfpHcHwQ8JiW502RuInRSMr+8imDVIvwzArcHD4Mha1/HqBd79RrvDu+Bm/86yQ7j9kb8+d/4Baju1coKWEz4AAAAAElFTkSuQmCC"},{"path":"C:\\Users\\sasch\\Downloads\\Create-mc1.18-dev\\src\\main\\resources\\assets\\create\\textures\\block\\filtered_detector_front.png","name":"filtered_detector_front.png","folder":"block","namespace":"create","id":"2","particle":false,"render_mode":"default","visible":true,"mode":"bitmap","saved":true,"uuid":"ecfdb93e-c8ce-66eb-f0ca-f5d80f1be15a","relative_path":"../../../../Users/sasch/Downloads/Create-mc1.18-dev/src/main/resources/assets/create/textures/block/filtered_detector_front.png","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAR9JREFUOE/tUrGKg0AQfaazEwRbQbC2EGs7sRJsQ/BH0t5fXCchOYSDu07srMVCSCcItoIgpLD0mOHWxJxHSJ9pdnZ25u2beSMlSTIBgKIodEBVVfR9zycZ+ffmeZ4kYhIBBEHA93EcF7nDMDBwURQcdxyH/QVAlmUTPcRxDE3TIMvyDNK2LaIoQtM0HDMMg33btq8MyrKc6CFNU3xvt3PxBcDueITv+/wrtUR5qwxM00RVVfgIQ1AhWbuZ8Pb5BcuyUNc1xyiP/EULgkGe53gPwyv9XwDXdZk2DZNafdjCecOisO0Pp8ctCAY0RF3X52JSpOs6kEJEW8zgXwZUKWS71/1WxlUAsThrS/Nni4DlENcSnonNC/FM0W3uCwD4AQtbnxFea/9LAAAAAElFTkSuQmCC"}],"display":{"thirdperson_righthand":{"rotation":[75,45,0],"translation":[0,2.5,0],"scale":[0.375,0.375,0.375]},"thirdperson_lefthand":{"rotation":[75,45,0],"translation":[0,2.5,0],"scale":[0.375,0.375,0.375]},"firstperson_righthand":{"rotation":[0,45,0],"scale":[0.4,0.4,0.4]},"firstperson_lefthand":{"rotation":[0,225,0],"scale":[0.4,0.4,0.4]},"ground":{"translation":[0,3,0],"scale":[0.25,0.25,0.25]},"gui":{"rotation":[30,225,0],"scale":[0.625,0.625,0.625]},"fixed":{"scale":[0.5,0.5,0.5]}}} -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | // These repositories are only for Gradle plugins, put any other repositories in the repository block further below 4 | maven { url = 'https://repo.spongepowered.org/repository/maven-public/' } 5 | mavenCentral() 6 | } 7 | dependencies { 8 | classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT' 9 | } 10 | } 11 | 12 | plugins { 13 | id 'net.minecraftforge.gradle' version '5.1.+' 14 | } 15 | 16 | apply plugin: 'org.spongepowered.mixin' 17 | 18 | group = 'de.saschat' 19 | version = '1.0.0-pre3' 20 | 21 | java { 22 | archivesBaseName = 'createcomputing' 23 | toolchain.languageVersion = JavaLanguageVersion.of(17) 24 | } 25 | 26 | minecraft { 27 | // The mappings can be changed at any time and must be in the following format. 28 | // Channel: Version: 29 | // official MCVersion Official field/method names from Mojang mapping files 30 | // parchment YYYY.MM.DD-MCVersion Open community-sourced parameter names and javadocs layered on top of official 31 | // 32 | // You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. 33 | // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md 34 | // 35 | // Parchment is an unofficial project maintained by ParchmentMC, separate from MinecraftForge 36 | // Additional setup is needed to use their mappings: https://github.com/ParchmentMC/Parchment/wiki/Getting-Started 37 | // 38 | // Use non-default mappings at your own risk. They may not always work. 39 | // Simply re-run your setup task after changing the mappings to update your workspace. 40 | mappings channel: 'official', version: '1.19.2' 41 | 42 | // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') 43 | 44 | // Default run configurations. 45 | // These can be tweaked, removed, or duplicated as needed. 46 | runs { 47 | client { 48 | workingDirectory project.file('run') 49 | 50 | // Recommended logging data for a userdev environment 51 | // The markers can be added/remove as needed separated by commas. 52 | // "SCAN": For mods scan. 53 | // "REGISTRIES": For firing of registry events. 54 | // "REGISTRYDUMP": For getting the contents of all registries. 55 | property 'forge.logging.markers', 'REGISTRIES' 56 | 57 | 58 | // Recommended logging level for the console 59 | // You can set various levels here. 60 | // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels 61 | property 'forge.logging.console.level', 'debug' 62 | 63 | // Comma-separated list of namespaces to load gametests from. Empty = all namespaces. 64 | property 'forge.enabledGameTestNamespaces', 'createcomputing' 65 | 66 | mods { 67 | createcomputing { 68 | source sourceSets.main 69 | } 70 | } 71 | } 72 | 73 | server { 74 | workingDirectory project.file('run') 75 | 76 | property 'forge.logging.markers', 'REGISTRIES' 77 | 78 | property 'forge.logging.console.level', 'debug' 79 | 80 | property 'forge.enabledGameTestNamespaces', 'createcomputing' 81 | 82 | mods { 83 | createcomputing { 84 | source sourceSets.main 85 | } 86 | } 87 | } 88 | 89 | // This run config launches GameTestServer and runs all registered gametests, then exits. 90 | // By default, the server will crash when no gametests are provided. 91 | // The gametest system is also enabled by default for other run configs under the /test command. 92 | gameTestServer { 93 | workingDirectory project.file('run') 94 | 95 | property 'forge.logging.markers', 'REGISTRIES' 96 | 97 | property 'forge.logging.console.level', 'debug' 98 | 99 | property 'forge.enabledGameTestNamespaces', 'createcomputing' 100 | 101 | mods { 102 | createcomputing { 103 | source sourceSets.main 104 | } 105 | } 106 | } 107 | 108 | data { 109 | workingDirectory project.file('run') 110 | 111 | property 'forge.logging.markers', 'REGISTRIES' 112 | 113 | property 'forge.logging.console.level', 'debug' 114 | 115 | // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. 116 | args '--mod', 'create:computing', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') 117 | 118 | mods { 119 | createcomputing { 120 | source sourceSets.main 121 | } 122 | } 123 | } 124 | } 125 | } 126 | 127 | mixin { 128 | add sourceSets.main, "createcomputing.refmap.json" 129 | 130 | config "createcomputing.mixins.json" 131 | } 132 | 133 | // Include resources generated by data generators. 134 | sourceSets.main.resources { srcDir 'src/generated/resources' } 135 | 136 | repositories { 137 | // Put repositories for dependencies here 138 | // ForgeGradle automatically adds the Forge maven and Maven Central for you 139 | 140 | // If you have mod jar dependencies in ./libs, you can declare them as a repository like so: 141 | // flatDir { 142 | // dir 'libs' 143 | // } 144 | 145 | 146 | maven { 147 | url 'https://www.cursemaven.com' 148 | content { 149 | includeGroup "curse.maven" 150 | } 151 | } 152 | maven { 153 | name = 'tterrag maven' 154 | url = 'https://maven.tterrag.com/' 155 | } 156 | } 157 | 158 | dependencies { 159 | // Specify the version of Minecraft to use. If this is any group other than 'net.minecraft' it is assumed 160 | // that the dep is a ForgeGradle 'patcher' dependency, and its patches will be applied. 161 | // The userdev artifact is a special name and will get all sorts of transformations applied to it. 162 | minecraft 'net.minecraftforge:forge:1.19.2-43.1.1' 163 | 164 | jarJar(group: 'com.tterrag.registrate', name: 'Registrate', version: '[MC1.19-1.1.5,)') { 165 | jarJar.pin(it, project.registrate_version) 166 | } 167 | 168 | implementation fg.deobf("com.simibubi.create:create-${create_minecraft_version}:${create_version}:all") { transitive = false } 169 | implementation fg.deobf("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") 170 | implementation fg.deobf("curse.maven:cc-tweaked-282001:3709268") 171 | implementation fg.deobf("curse.maven:jade-324717:3865918") 172 | implementation fg.deobf("com.tterrag.registrate:Registrate:${registrate_version}") 173 | // Real mod deobf dependency examples - these get remapped to your current mappings 174 | // compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") // Adds JEI API as a compile dependency 175 | // runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}") // Adds the full JEI mod as a runtime dependency 176 | // implementation fg.deobf("com.tterrag.registrate:Registrate:MC${mc_version}-${registrate_version}") // Adds registrate as a dependency 177 | 178 | // Examples using mod jars from ./libs 179 | // implementation fg.deobf("blank:coolmod-${mc_version}:${coolmod_version}") 180 | 181 | // For more info... 182 | // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html 183 | // http://www.gradle.org/docs/current/userguide/dependency_management.html 184 | 185 | annotationProcessor 'org.spongepowered:mixin:0.8.5:processor' 186 | } 187 | 188 | // Example for how to get properties into the manifest for reading at runtime. 189 | jar { 190 | manifest { 191 | attributes([ 192 | "Specification-Title" : "Create: Computing", 193 | "Specification-Vendor" : "Sascha_T", 194 | "Specification-Version" : "1", // We are version 1 of ourselves 195 | "Implementation-Title" : project.name, 196 | "Implementation-Version" : project.jar.archiveVersion, 197 | "Implementation-Vendor" : "Sascha_T", 198 | "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") 199 | ]) 200 | } 201 | } 202 | 203 | jar.finalizedBy('reobfJar') 204 | 205 | tasks.withType(JavaCompile).configureEach { 206 | options.encoding = 'UTF-8' // Use the UTF-8 charset for Java compilation 207 | } 208 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx3G 2 | org.gradle.daemon=false 3 | create_minecraft_version = 1.19.2 4 | flywheel_minecraft_version = 1.19.2 5 | create_version = 0.5.0.d-7 6 | flywheel_version = 0.6.5-4 7 | registrate_version = MC1.19-1.1.5 -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sascha-T/create-computing/4621de59a1910e83705e5c26d41d8b2eb2b63b92/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Create: Computing 2 | Augment your Create gameplay with ComputerCraft peripherals and other shenanigans. 3 | 4 | ### W.I.P. 5 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | gradlePluginPortal() 4 | maven { url = 'https://maven.minecraftforge.net/' } 5 | } 6 | } 7 | 8 | rootProject.name = 'createcomputing' 9 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/Behaviours.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing; 2 | 3 | import com.simibubi.create.content.logistics.block.display.AllDisplayBehaviours; 4 | import de.saschat.createcomputing.behaviour.source.TextDisplayBehaviour; 5 | import de.saschat.createcomputing.behaviour.target.TextPassBehaviour; 6 | import net.minecraft.resources.ResourceLocation; 7 | 8 | public class Behaviours { 9 | public static void register() { 10 | AllDisplayBehaviours.assignTile( 11 | AllDisplayBehaviours.register( 12 | new ResourceLocation(CreateComputingMod.MOD_ID, 13 | "computerized_display_source"), 14 | new TextDisplayBehaviour() 15 | ), 16 | Registries.COMPUTERIZED_DISPLAY_SOURCE_TILE.get() 17 | ); 18 | AllDisplayBehaviours.assignTile( 19 | AllDisplayBehaviours.register( 20 | new ResourceLocation(CreateComputingMod.MOD_ID, 21 | "computerized_display_target"), 22 | new TextPassBehaviour() 23 | ), 24 | Registries.COMPUTERIZED_DISPLAY_TARGET_TILE.get() 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/CreateComputingMod.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing; 2 | 3 | import com.mojang.logging.LogUtils; 4 | import de.saschat.createcomputing.config.CreateComputingConfigServer; 5 | import net.minecraftforge.common.MinecraftForge; 6 | import net.minecraftforge.fml.ModLoadingContext; 7 | import net.minecraftforge.fml.common.Mod; 8 | import net.minecraftforge.fml.config.ModConfig; 9 | import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; 10 | import org.slf4j.Logger; 11 | 12 | @Mod(CreateComputingMod.MOD_ID) 13 | public class CreateComputingMod { 14 | public static final String MOD_ID = "createcomputing"; 15 | 16 | public static final Logger LOGGER = LogUtils.getLogger(); 17 | 18 | public CreateComputingMod() { 19 | ModLoadingContext.get().registerConfig(ModConfig.Type.SERVER, CreateComputingConfigServer.pair.getRight()); 20 | Registries.init(FMLJavaModLoadingContext.get().getModEventBus()); 21 | MinecraftForge.EVENT_BUS.register(this); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/Registries.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing; 2 | 3 | import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBlockItem; 4 | import com.tterrag.registrate.util.nullness.NonNullBiFunction; 5 | import de.saschat.createcomputing.blocks.ComputerizedDisplaySourceBlock; 6 | import de.saschat.createcomputing.blocks.ComputerizedDisplayTargetBlock; 7 | import de.saschat.createcomputing.blocks.ComputerizedRedstoneLinkBlock; 8 | import de.saschat.createcomputing.blocks.TrainNetworkObserverBlock; 9 | import de.saschat.createcomputing.tiles.ComputerizedDisplaySourceTile; 10 | import de.saschat.createcomputing.tiles.ComputerizedDisplayTargetTile; 11 | import de.saschat.createcomputing.tiles.ComputerizedRedstoneLinkTile; 12 | import de.saschat.createcomputing.tiles.TrainNetworkObserverTile; 13 | import de.saschat.createcomputing.tiles.renderer.TrainNetworkObserverRenderer; 14 | import net.minecraft.client.renderer.ItemBlockRenderTypes; 15 | import net.minecraft.client.renderer.RenderType; 16 | import net.minecraft.world.item.BlockItem; 17 | import net.minecraft.world.item.CreativeModeTab; 18 | import net.minecraft.world.item.Item; 19 | import net.minecraft.world.item.ItemStack; 20 | import net.minecraft.world.level.block.Block; 21 | import net.minecraft.world.level.block.entity.BlockEntity; 22 | import net.minecraft.world.level.block.entity.BlockEntityType; 23 | import net.minecraftforge.client.event.EntityRenderersEvent; 24 | import net.minecraftforge.data.event.GatherDataEvent; 25 | import net.minecraftforge.eventbus.api.IEventBus; 26 | import net.minecraftforge.eventbus.api.SubscribeEvent; 27 | import net.minecraftforge.fml.common.Mod; 28 | import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; 29 | import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; 30 | import net.minecraftforge.registries.DeferredRegister; 31 | import net.minecraftforge.registries.ForgeRegistries; 32 | import net.minecraftforge.registries.RegistryObject; 33 | 34 | import java.util.Arrays; 35 | import java.util.function.Supplier; 36 | 37 | public class Registries { 38 | public static DeferredRegister ITEM_REGISTRY = DeferredRegister.create(ForgeRegistries.ITEMS, CreateComputingMod.MOD_ID); 39 | public static DeferredRegister BLOCK_REGISTRY = DeferredRegister.create(ForgeRegistries.BLOCKS, CreateComputingMod.MOD_ID); 40 | public static DeferredRegister> TILE_REGISTRY = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, CreateComputingMod.MOD_ID); 41 | 42 | public static RegistryObject registerBlock(String name, Supplier blockSupplier) { 43 | CreateComputingMod.LOGGER.info("Queuing block: " + name); 44 | return BLOCK_REGISTRY.register(name, blockSupplier); 45 | } 46 | 47 | public static RegistryObject registerBlockItem(String name, RegistryObject block, Item.Properties properties, NonNullBiFunction function) { 48 | CreateComputingMod.LOGGER.info("Queuing block item: " + name); 49 | return ITEM_REGISTRY.register(name, () -> { 50 | return function.apply(block.get(), properties); 51 | }); 52 | } 53 | 54 | public static RegistryObject registerBlockItem(String name, RegistryObject block, Item.Properties properties) { 55 | return registerBlockItem(name, block, properties, BlockItem::new); 56 | } 57 | 58 | public static RegistryObject> registerTile(String name, BlockEntityType.BlockEntitySupplier supplier, Supplier... blocks) { 59 | CreateComputingMod.LOGGER.info("Queuing tile: " + name); 60 | return TILE_REGISTRY.register(name, () -> { 61 | Block[] rBlocks = Arrays.stream(blocks).map(Supplier::get).toList().toArray(new Block[0]); 62 | return BlockEntityType.Builder.of( 63 | supplier, 64 | rBlocks).build(null); 65 | }); 66 | } 67 | 68 | public static CreativeModeTab TAB = new CreativeModeTab("createcomputing.tab") { 69 | @Override 70 | public ItemStack makeIcon() { 71 | return new ItemStack(COMPUTERIZED_DISPLAY_TARGET_ITEM.get()); 72 | } 73 | }; 74 | 75 | // Computerized Display Source 76 | public static RegistryObject COMPUTERIZED_DISPLAY_SOURCE = registerBlock( 77 | "computerized_display_source", 78 | ComputerizedDisplaySourceBlock::new 79 | ); 80 | public static RegistryObject COMPUTERIZED_DISPLAY_SOURCE_ITEM = registerBlockItem( 81 | "computerized_display_source", 82 | COMPUTERIZED_DISPLAY_SOURCE, 83 | new Item.Properties().tab(TAB) 84 | ); 85 | public static RegistryObject> COMPUTERIZED_DISPLAY_SOURCE_TILE = registerTile( 86 | "computerized_display_source", 87 | ComputerizedDisplaySourceTile::new, 88 | COMPUTERIZED_DISPLAY_SOURCE 89 | ); 90 | 91 | 92 | // Computerized Display Target 93 | public static RegistryObject COMPUTERIZED_DISPLAY_TARGET = registerBlock( 94 | "computerized_display_target", 95 | ComputerizedDisplayTargetBlock::new 96 | ); 97 | public static RegistryObject COMPUTERIZED_DISPLAY_TARGET_ITEM = registerBlockItem( 98 | "computerized_display_target", 99 | COMPUTERIZED_DISPLAY_TARGET, 100 | new Item.Properties().tab(TAB) 101 | ); 102 | public static RegistryObject> COMPUTERIZED_DISPLAY_TARGET_TILE = registerTile( 103 | "computerized_display_target", 104 | ComputerizedDisplayTargetTile::new, 105 | COMPUTERIZED_DISPLAY_TARGET 106 | ); 107 | 108 | // Computerized Redstone Link 109 | public static RegistryObject COMPUTERIZED_REDSTONE_LINK = registerBlock( 110 | "computerized_redstone_link", 111 | ComputerizedRedstoneLinkBlock::new 112 | ); 113 | public static RegistryObject COMPUTERIZED_REDSTONE_LINK_ITEM = registerBlockItem( 114 | "computerized_redstone_link", 115 | COMPUTERIZED_REDSTONE_LINK, 116 | new Item.Properties().tab(TAB) 117 | ); 118 | public static RegistryObject> COMPUTERIZED_REDSTONE_LINK_TILE = registerTile( 119 | "computerized_redstone_link", 120 | ComputerizedRedstoneLinkTile::new, 121 | COMPUTERIZED_REDSTONE_LINK 122 | ); 123 | 124 | // Train Network Observer 125 | public static RegistryObject TRAIN_NETWORK_OBSERVER = registerBlock( 126 | "train_network_observer", 127 | TrainNetworkObserverBlock::new 128 | ); 129 | public static RegistryObject TRAIN_NETWORK_OBSERVER_ITEM = registerBlockItem( 130 | "train_network_observer", 131 | TRAIN_NETWORK_OBSERVER, 132 | new Item.Properties().tab(TAB), 133 | TrackTargetingBlockItem.ofType(TrainNetworkObserverTile.NETWORK_OBSERVER) 134 | ); 135 | public static RegistryObject> TRAIN_NETWORK_OBSERVER_TILE = registerTile( 136 | "train_network_observer", 137 | TrainNetworkObserverTile::new, 138 | TRAIN_NETWORK_OBSERVER 139 | ); 140 | 141 | // Events 142 | @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) 143 | public static class RegistryEvents { 144 | @SubscribeEvent 145 | public static void fmlCommon(final FMLCommonSetupEvent blockRegistryEvent) { 146 | CreateComputingMod.LOGGER.info("Registering all Create behaviours."); 147 | Behaviours.register(); 148 | CreateComputingMod.LOGGER.info("Registered all Create behaviour."); 149 | } 150 | 151 | @SubscribeEvent 152 | public static void fmlClient(final FMLClientSetupEvent blockRegistryEvent) { 153 | ItemBlockRenderTypes.setRenderLayer(COMPUTERIZED_DISPLAY_TARGET.get(), RenderType.cutout()); 154 | ItemBlockRenderTypes.setRenderLayer(COMPUTERIZED_REDSTONE_LINK.get(), RenderType.cutout()); 155 | } 156 | 157 | @SubscribeEvent 158 | public static void modRenderer(final EntityRenderersEvent.RegisterRenderers event) { 159 | event.registerBlockEntityRenderer(TRAIN_NETWORK_OBSERVER_TILE.get(), TrainNetworkObserverRenderer::new); 160 | } 161 | public static void modData(final GatherDataEvent event) { 162 | } 163 | } 164 | /*@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE) 165 | public static class ForgeEvents { 166 | @SubscribeEvent 167 | public static void modCommands(final RegisterCommandsEvent event) { 168 | System.out.println("REGISTER COMMANDS"); 169 | event.getDispatcher().register( 170 | Commands.literal("redstone_link").executes(context -> { 171 | Map, Set> coupleSetMap = Create.REDSTONE_LINK_NETWORK_HANDLER.networksIn(context.getSource().getLevel()); 172 | coupleSetMap.forEach((frequencies, iRedstoneLinkables) -> { 173 | System.out.println("Frequency: " + frequencies.get(true).getStack().getItem().getRegistryName().toString() + ", " + frequencies.get(false).getStack().getItem().getRegistryName().toString()); 174 | for (IRedstoneLinkable iRedstoneLinkable : iRedstoneLinkables) { 175 | System.out.println("\tAt " + iRedstoneLinkable.getLocation().toString() + ", listening: " + iRedstoneLinkable.isListening() + ", alive: " + iRedstoneLinkable.isAlive() + ", strength: " + iRedstoneLinkable.getTransmittedStrength()); 176 | } 177 | }); 178 | return 0; 179 | }) 180 | ); 181 | } 182 | }*/ 183 | 184 | 185 | 186 | // Real loading 187 | 188 | public static void init(IEventBus modEventBus) { 189 | CreateComputingMod.LOGGER.info("Registering all registries."); 190 | BLOCK_REGISTRY.register(modEventBus); 191 | ITEM_REGISTRY.register(modEventBus); 192 | TILE_REGISTRY.register(modEventBus); 193 | CreateComputingMod.LOGGER.info("Registered all registries."); 194 | } // For loading. 195 | 196 | 197 | } 198 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/Utils.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing; 2 | 3 | import net.minecraft.core.Direction; 4 | import net.minecraft.nbt.*; 5 | import net.minecraft.resources.ResourceLocation; 6 | import net.minecraft.world.item.Item; 7 | import net.minecraft.world.item.Items; 8 | import net.minecraft.world.phys.shapes.Shapes; 9 | import net.minecraft.world.phys.shapes.VoxelShape; 10 | import net.minecraftforge.registries.ForgeRegistries; 11 | 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | 15 | public class Utils { 16 | public static Item getByName(ResourceLocation loc) { 17 | var itemRegistryObject = ForgeRegistries.ITEMS.getHolder(loc); 18 | if (itemRegistryObject.isEmpty()) 19 | return Items.AIR; 20 | return itemRegistryObject.get().get(); 21 | } 22 | 23 | public interface Receiver { 24 | void receive(T a); 25 | } 26 | public static VoxelShape rotate(Direction from, Direction to, VoxelShape shape) { 27 | VoxelShape[] buffer = new VoxelShape[]{ shape, Shapes.empty() }; 28 | 29 | int times = (to.get2DDataValue() - from.get2DDataValue() + 4) % 4; 30 | for (int i = 0; i < times; i++) { 31 | buffer[0].forAllBoxes((minX, minY, minZ, maxX, maxY, maxZ) -> buffer[1] = Shapes.or(buffer[1], Shapes.create(1-maxZ, minY, minX, 1-minZ, maxY, maxX))); 32 | buffer[0] = buffer[1]; 33 | buffer[1] = Shapes.empty(); 34 | } 35 | return buffer[0]; 36 | } 37 | 38 | public static Object blowNBT(Tag tag) { 39 | 40 | Map ret = new HashMap<>(); 41 | if (tag == null) 42 | return ret; 43 | if (tag instanceof CompoundTag com) { 44 | for (String key : com.getAllKeys()) { 45 | ret.put(key, blowNBT(com.get(key))); 46 | } 47 | return ret; 48 | } 49 | if (tag instanceof CollectionTag lis) { 50 | int idx = 1; 51 | for (Object t : lis) { 52 | ret.put(idx, t instanceof Tag ? blowNBT((Tag) t) : t); 53 | idx++; 54 | } 55 | return ret; 56 | } 57 | if (tag instanceof IntTag t) { 58 | return t.getAsNumber(); 59 | } 60 | if (tag instanceof ByteTag t) { 61 | return t.getAsNumber(); 62 | } 63 | if (tag instanceof ShortTag t) { 64 | return t.getAsNumber(); 65 | } 66 | if (tag instanceof LongTag t) { 67 | return t.getAsNumber(); 68 | } 69 | if (tag instanceof FloatTag t) { 70 | return t.getAsNumber(); 71 | } 72 | if (tag instanceof DoubleTag t) { 73 | return t.getAsNumber(); 74 | } 75 | if (tag instanceof StringTag t) { 76 | return t.getAsString(); 77 | } 78 | System.err.println("Invalid tag type: " + tag.getClass().getName()); 79 | return null; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/api/PeripheralMethod.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.api; 2 | 3 | import dan200.computercraft.api.lua.IArguments; 4 | import dan200.computercraft.api.lua.ILuaContext; 5 | import dan200.computercraft.api.lua.LuaException; 6 | import dan200.computercraft.api.lua.MethodResult; 7 | import dan200.computercraft.api.peripheral.IComputerAccess; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | public interface PeripheralMethod { 11 | MethodResult run(@NotNull IComputerAccess iComputerAccess, @NotNull ILuaContext iLuaContext, @NotNull IArguments iArguments) throws LuaException; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/api/SmartPeripheral.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.api; 2 | 3 | import dan200.computercraft.api.lua.IArguments; 4 | import dan200.computercraft.api.lua.ILuaContext; 5 | import dan200.computercraft.api.lua.LuaException; 6 | import dan200.computercraft.api.lua.MethodResult; 7 | import dan200.computercraft.api.peripheral.IComputerAccess; 8 | import dan200.computercraft.api.peripheral.IDynamicPeripheral; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | import java.util.LinkedList; 12 | import java.util.List; 13 | 14 | public abstract class SmartPeripheral implements IDynamicPeripheral { 15 | List names = new LinkedList<>(); 16 | List methods = new LinkedList<>(); 17 | 18 | public void addMethod(String name, PeripheralMethod method) { 19 | names.add(name); 20 | methods.add(method); 21 | } 22 | 23 | public PeripheralMethod removeMethod(String name) { 24 | int i = names.indexOf(name); 25 | names.remove(i); 26 | return methods.remove(i); 27 | } 28 | 29 | @NotNull 30 | @Override 31 | public String[] getMethodNames() { 32 | return names.toArray(new String[0]); 33 | } 34 | 35 | @NotNull 36 | @Override 37 | public MethodResult callMethod(@NotNull IComputerAccess iComputerAccess, @NotNull ILuaContext iLuaContext, int i, @NotNull IArguments iArguments) throws LuaException { 38 | return methods.get(i).run(iComputerAccess, iLuaContext, iArguments); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/behaviour/source/TextDisplayBehaviour.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.behaviour.source; 2 | 3 | import com.simibubi.create.content.logistics.block.display.DisplayLinkContext; 4 | import com.simibubi.create.content.logistics.block.display.source.DisplaySource; 5 | import com.simibubi.create.content.logistics.block.display.target.DisplayTargetStats; 6 | import de.saschat.createcomputing.tiles.ComputerizedDisplaySourceTile; 7 | import net.minecraft.network.chat.Component; 8 | import net.minecraft.network.chat.MutableComponent; 9 | 10 | import java.util.List; 11 | 12 | public class TextDisplayBehaviour extends DisplaySource { 13 | public static MutableComponent NIL_TEXT = Component.literal(""); 14 | @Override 15 | public List provideText(DisplayLinkContext displayLinkContext, DisplayTargetStats displayTargetStats) { 16 | /* 17 | Maybe some events in the future? 18 | */ 19 | return ((ComputerizedDisplaySourceTile) displayLinkContext.getSourceTE()).getFromPos(displayLinkContext.te().getBlockPos()).toDisplay; 20 | } 21 | 22 | @Override 23 | public int getPassiveRefreshTicks() { 24 | return 20; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/behaviour/target/TextPassBehaviour.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.behaviour.target; 2 | 3 | import com.simibubi.create.content.logistics.block.display.DisplayLinkContext; 4 | import com.simibubi.create.content.logistics.block.display.target.DisplayTarget; 5 | import com.simibubi.create.content.logistics.block.display.target.DisplayTargetStats; 6 | import de.saschat.createcomputing.tiles.ComputerizedDisplayTargetTile; 7 | import net.minecraft.network.chat.MutableComponent; 8 | 9 | import java.util.List; 10 | 11 | public class TextPassBehaviour extends DisplayTarget { 12 | @Override 13 | public void acceptText(int line, List list, DisplayLinkContext displayLinkContext) { 14 | ComputerizedDisplayTargetTile tile = (ComputerizedDisplayTargetTile) displayLinkContext.getTargetTE(); 15 | tile.acceptText(line, list, displayLinkContext); 16 | } 17 | 18 | @Override 19 | public DisplayTargetStats provideStats(DisplayLinkContext displayLinkContext) { 20 | ComputerizedDisplayTargetTile tile = (ComputerizedDisplayTargetTile) displayLinkContext.getTargetTE(); 21 | return new DisplayTargetStats(tile.maxHeight, tile.maxHeight, this); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/behaviour/tile/TrainNetworkObserver.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.behaviour.tile; 2 | 3 | import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SingleTileEdgePoint; 4 | 5 | public class TrainNetworkObserver extends SingleTileEdgePoint { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/blocks/ComputerizedDisplaySourceBlock.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.blocks; 2 | 3 | import de.saschat.createcomputing.Utils; 4 | import de.saschat.createcomputing.tiles.ComputerizedDisplaySourceTile; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.core.Direction; 7 | import net.minecraft.world.item.context.BlockPlaceContext; 8 | import net.minecraft.world.level.BlockGetter; 9 | import net.minecraft.world.level.Level; 10 | import net.minecraft.world.level.LevelReader; 11 | import net.minecraft.world.level.block.Block; 12 | import net.minecraft.world.level.block.EntityBlock; 13 | import net.minecraft.world.level.block.HorizontalDirectionalBlock; 14 | import net.minecraft.world.level.block.entity.BlockEntity; 15 | import net.minecraft.world.level.block.state.BlockBehaviour; 16 | import net.minecraft.world.level.block.state.BlockState; 17 | import net.minecraft.world.level.block.state.StateDefinition; 18 | import net.minecraft.world.level.block.state.properties.DirectionProperty; 19 | import net.minecraft.world.level.material.Material; 20 | import net.minecraft.world.phys.shapes.BooleanOp; 21 | import net.minecraft.world.phys.shapes.CollisionContext; 22 | import net.minecraft.world.phys.shapes.Shapes; 23 | import net.minecraft.world.phys.shapes.VoxelShape; 24 | import org.jetbrains.annotations.Nullable; 25 | 26 | import java.util.stream.Stream; 27 | 28 | public class ComputerizedDisplaySourceBlock extends Block implements EntityBlock { 29 | public static DirectionProperty FACING = HorizontalDirectionalBlock.FACING; 30 | 31 | public ComputerizedDisplaySourceBlock() { 32 | super(BlockBehaviour.Properties.of(Material.WOOD).destroyTime(1)); 33 | registerDefaultState(this.getStateDefinition().any().setValue(FACING, Direction.NORTH)); 34 | } 35 | 36 | @Nullable 37 | @Override 38 | public BlockState getStateForPlacement(BlockPlaceContext p_49820_) { 39 | Direction a = p_49820_.getPlayer().isCrouching() ? p_49820_.getHorizontalDirection() : p_49820_.getHorizontalDirection().getOpposite(); 40 | return this.defaultBlockState().setValue(FACING, a); 41 | } 42 | 43 | @Override 44 | protected void createBlockStateDefinition(StateDefinition.Builder p_49915_) { 45 | p_49915_.add(FACING); 46 | } 47 | 48 | @Nullable 49 | @Override 50 | public BlockEntity newBlockEntity(BlockPos p_153215_, BlockState p_153216_) { 51 | return new ComputerizedDisplaySourceTile(p_153215_, p_153216_); 52 | } 53 | 54 | @Override 55 | public VoxelShape getShape(BlockState p_60555_, BlockGetter p_60556_, BlockPos p_60557_, CollisionContext p_60558_) { 56 | return Utils.rotate(Direction.NORTH, p_60555_.getValue(FACING), Stream.of( 57 | Block.box(2, 2, -1, 14, 14, 1), 58 | Block.box(0, 0, 0, 16, 2, 16), 59 | Block.box(0, 14, 0, 16, 16, 16), 60 | Block.box(1, 2, 1, 15, 14, 15) 61 | ).reduce((v1, v2) -> Shapes.join(v1, v2, BooleanOp.OR)).get()); 62 | } 63 | 64 | @Override 65 | public void onNeighborChange(BlockState state, LevelReader level, BlockPos pos, BlockPos neighbor) { 66 | ((ComputerizedDisplaySourceTile) level.getBlockEntity(pos)).onNeighborChange(state, level, pos, neighbor); 67 | } 68 | 69 | @Override 70 | public void onRemove(BlockState p_60515_, Level p_60516_, BlockPos p_60517_, BlockState p_60518_, boolean p_60519_) { 71 | ((ComputerizedDisplaySourceTile) p_60516_.getBlockEntity(p_60517_)).onBlockBreak(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/blocks/ComputerizedDisplayTargetBlock.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.blocks; 2 | 3 | import de.saschat.createcomputing.Utils; 4 | import de.saschat.createcomputing.tiles.ComputerizedDisplayTargetTile; 5 | import net.minecraft.core.BlockPos; 6 | import net.minecraft.core.Direction; 7 | import net.minecraft.world.item.context.BlockPlaceContext; 8 | import net.minecraft.world.level.BlockGetter; 9 | import net.minecraft.world.level.block.Block; 10 | import net.minecraft.world.level.block.EntityBlock; 11 | import net.minecraft.world.level.block.HorizontalDirectionalBlock; 12 | import net.minecraft.world.level.block.entity.BlockEntity; 13 | import net.minecraft.world.level.block.state.BlockState; 14 | import net.minecraft.world.level.block.state.StateDefinition; 15 | import net.minecraft.world.level.block.state.properties.DirectionProperty; 16 | import net.minecraft.world.level.material.Material; 17 | import net.minecraft.world.phys.shapes.BooleanOp; 18 | import net.minecraft.world.phys.shapes.CollisionContext; 19 | import net.minecraft.world.phys.shapes.Shapes; 20 | import net.minecraft.world.phys.shapes.VoxelShape; 21 | import org.jetbrains.annotations.Nullable; 22 | 23 | import java.util.stream.Stream; 24 | 25 | public class ComputerizedDisplayTargetBlock extends Block implements EntityBlock { 26 | public static DirectionProperty FACING = HorizontalDirectionalBlock.FACING; 27 | 28 | public ComputerizedDisplayTargetBlock() { 29 | super(Properties.of(Material.WOOD).destroyTime(1)); 30 | registerDefaultState(this.getStateDefinition().any().setValue(FACING, Direction.NORTH)); 31 | } 32 | 33 | @Nullable 34 | @Override 35 | public BlockState getStateForPlacement(BlockPlaceContext p_49820_) { 36 | Direction a = p_49820_.getPlayer().isCrouching() ? p_49820_.getHorizontalDirection() : p_49820_.getHorizontalDirection().getOpposite(); 37 | return this.defaultBlockState().setValue(FACING, a); 38 | } 39 | 40 | @Override 41 | protected void createBlockStateDefinition(StateDefinition.Builder p_49915_) { 42 | p_49915_.add(FACING); 43 | } 44 | 45 | 46 | @Nullable 47 | @Override 48 | public BlockEntity newBlockEntity(BlockPos p_153215_, BlockState p_153216_) { 49 | return new ComputerizedDisplayTargetTile(p_153215_, p_153216_); 50 | } 51 | 52 | @Override 53 | public VoxelShape getShape(BlockState p_60555_, BlockGetter p_60556_, BlockPos p_60557_, CollisionContext p_60558_) { 54 | return Utils.rotate(Direction.NORTH, p_60555_.getValue(FACING), Stream.of( 55 | Block.box(0, 0, 0, 16, 16, 5), 56 | Block.box(2, 2, -2, 14, 14, 0), 57 | Block.box(2, 2, 5, 14, 14, 10) 58 | ).reduce((v1, v2) -> Shapes.join(v1, v2, BooleanOp.OR)).get()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/blocks/ComputerizedRedstoneLinkBlock.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.blocks; 2 | 3 | import com.simibubi.create.foundation.block.ITE; 4 | import de.saschat.createcomputing.Registries; 5 | import de.saschat.createcomputing.tiles.ComputerizedRedstoneLinkTile; 6 | import net.minecraft.core.BlockPos; 7 | import net.minecraft.world.level.BlockGetter; 8 | import net.minecraft.world.level.block.Block; 9 | import net.minecraft.world.level.block.entity.BlockEntityType; 10 | import net.minecraft.world.level.block.state.BlockBehaviour; 11 | import net.minecraft.world.level.block.state.BlockState; 12 | import net.minecraft.world.level.material.Material; 13 | import net.minecraft.world.phys.shapes.CollisionContext; 14 | import net.minecraft.world.phys.shapes.VoxelShape; 15 | 16 | public class ComputerizedRedstoneLinkBlock extends Block implements ITE { 17 | public ComputerizedRedstoneLinkBlock() { 18 | super(BlockBehaviour.Properties.of(Material.WOOD).destroyTime(1)); 19 | } 20 | 21 | @Override 22 | public Class getTileEntityClass() { 23 | return ComputerizedRedstoneLinkTile.class; 24 | } 25 | 26 | @Override 27 | public BlockEntityType getTileEntityType() { 28 | return Registries.COMPUTERIZED_REDSTONE_LINK_TILE.get(); 29 | } 30 | 31 | 32 | @Override 33 | public VoxelShape getShape(BlockState p_60555_, BlockGetter p_60556_, BlockPos p_60557_, CollisionContext p_60558_) { 34 | return box( 35 | 1,0,1,15,2,15 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/blocks/TrainNetworkObserverBlock.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.blocks; 2 | 3 | import com.simibubi.create.foundation.block.ITE; 4 | import de.saschat.createcomputing.Registries; 5 | import de.saschat.createcomputing.tiles.TrainNetworkObserverTile; 6 | import net.minecraft.core.BlockPos; 7 | import net.minecraft.world.level.BlockGetter; 8 | import net.minecraft.world.level.Level; 9 | import net.minecraft.world.level.block.Block; 10 | import net.minecraft.world.level.block.entity.BlockEntityType; 11 | import net.minecraft.world.level.block.state.BlockState; 12 | import net.minecraft.world.level.material.Material; 13 | import net.minecraft.world.phys.shapes.BooleanOp; 14 | import net.minecraft.world.phys.shapes.CollisionContext; 15 | import net.minecraft.world.phys.shapes.Shapes; 16 | import net.minecraft.world.phys.shapes.VoxelShape; 17 | 18 | import java.util.stream.Stream; 19 | 20 | public class TrainNetworkObserverBlock extends Block implements ITE { 21 | public TrainNetworkObserverBlock() { 22 | super(Properties.of(Material.WOOD).destroyTime(1)); 23 | } 24 | 25 | @Override 26 | public Class getTileEntityClass() { 27 | return TrainNetworkObserverTile.class; 28 | } 29 | 30 | @Override 31 | public BlockEntityType getTileEntityType() { 32 | return Registries.TRAIN_NETWORK_OBSERVER_TILE.get(); 33 | } 34 | 35 | 36 | @Override 37 | public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean p_60519_) { 38 | if (pState.hasBlockEntity() && (!pState.is(pNewState.getBlock()) || !pNewState.hasBlockEntity())) { 39 | pLevel.removeBlockEntity(pPos); 40 | } 41 | } 42 | 43 | @Override 44 | public VoxelShape getShape(BlockState p_60555_, BlockGetter p_60556_, BlockPos p_60557_, CollisionContext p_60558_) { 45 | return Stream.of( 46 | Block.box(2,15,2,14,17,14), 47 | Block.box(0,0,0,16,2,16), 48 | Block.box(0,14,0,16,16,16), 49 | Block.box(1,2,1,15,14,15), 50 | Block.box(15,2,0,16,14,1), 51 | Block.box(15,2,15,16,14,16), 52 | Block.box(0,2,15,1,14,16), 53 | Block.box(0,2,0,1,14,1) 54 | ).reduce((v1, v2) -> Shapes.join(v1, v2, BooleanOp.OR)).get(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/config/CreateComputingConfigServer.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.config; 2 | 3 | import net.minecraft.resources.ResourceLocation; 4 | import net.minecraftforge.common.ForgeConfigSpec; 5 | import net.minecraftforge.common.ForgeConfigSpec.*; 6 | import org.apache.commons.lang3.tuple.Pair; 7 | 8 | import java.util.List; 9 | 10 | public class CreateComputingConfigServer { 11 | public ConfigValue> BANNED_LINK_ITEMS; 12 | public LongValue MAXIMUM_CONCURRENT_LINKS; 13 | 14 | public CreateComputingConfigServer(ForgeConfigSpec.Builder builder) { 15 | BANNED_LINK_ITEMS = builder.comment("These are the items the computerized redstone link cannot use.").define( 16 | "computerized_redstone_link.banned_link_items", 17 | List.of( 18 | new ResourceLocation("minecraft", "dragon_egg").toString(), 19 | new ResourceLocation("minecraft", "nether_star").toString() 20 | ) 21 | ); 22 | MAXIMUM_CONCURRENT_LINKS = builder.comment("This is the maximum amount of concurrent handles one computerized redstone link is allowed ot have.").defineInRange( 23 | "computerized_redstone_link.maximum_concurrent_links", 24 | 8, 25 | 1, 26 | Long.MAX_VALUE 27 | ); 28 | 29 | } 30 | 31 | public static Pair pair = new ForgeConfigSpec.Builder() 32 | .configure(CreateComputingConfigServer::new); 33 | 34 | public static CreateComputingConfigServer get() { 35 | return pair.getLeft(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/mixin/TrackTargetingClientMixin.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.mixin; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; 5 | import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingClient; 6 | import com.simibubi.create.foundation.render.SuperRenderTypeBuffer; 7 | import de.saschat.createcomputing.tiles.TrainNetworkObserverTile; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | 14 | @Mixin(TrackTargetingClient.class) 15 | public class TrackTargetingClientMixin { 16 | @Shadow(remap = false) private static EdgePointType lastType; 17 | 18 | @Inject(method = "render", at=@At("HEAD"), remap = false) 19 | private static void render(PoseStack ms, SuperRenderTypeBuffer buffer, CallbackInfo ci) { 20 | if(lastType == TrainNetworkObserverTile.NETWORK_OBSERVER) 21 | lastType = EdgePointType.OBSERVER; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/peripherals/ComputerizedDisplaySourcePeripheral.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.peripherals; 2 | 3 | import dan200.computercraft.api.lua.IArguments; 4 | import dan200.computercraft.api.lua.ILuaContext; 5 | import dan200.computercraft.api.lua.LuaException; 6 | import dan200.computercraft.api.lua.MethodResult; 7 | import dan200.computercraft.api.peripheral.IComputerAccess; 8 | import dan200.computercraft.api.peripheral.IDynamicPeripheral; 9 | import dan200.computercraft.api.peripheral.IPeripheral; 10 | import de.saschat.createcomputing.CreateComputingMod; 11 | import de.saschat.createcomputing.peripherals.handles.DisplayLinkHandle; 12 | import de.saschat.createcomputing.tiles.ComputerizedDisplaySourceTile; 13 | import net.minecraft.core.Direction; 14 | import net.minecraft.resources.ResourceLocation; 15 | import org.jetbrains.annotations.NotNull; 16 | import org.jetbrains.annotations.Nullable; 17 | 18 | import java.util.ArrayList; 19 | import java.util.LinkedList; 20 | import java.util.List; 21 | import java.util.stream.Collectors; 22 | 23 | public class ComputerizedDisplaySourcePeripheral implements IDynamicPeripheral { 24 | public ComputerizedDisplaySourceTile source; 25 | public List computers = new LinkedList<>(); 26 | 27 | public ComputerizedDisplaySourcePeripheral(ComputerizedDisplaySourceTile computerizedDisplaySourceTile) { 28 | this.source = computerizedDisplaySourceTile; 29 | } 30 | 31 | @Override 32 | public void attach(@NotNull IComputerAccess computer) { 33 | computers.add(computer); 34 | } 35 | 36 | @Override 37 | public void detach(@NotNull IComputerAccess computer) { 38 | computers.remove(computer); 39 | } 40 | 41 | @NotNull 42 | @Override 43 | public String[] getMethodNames() { 44 | return new String[]{"getLink", "getLinks"}; 45 | } 46 | 47 | @NotNull 48 | @Override 49 | public MethodResult callMethod(@NotNull IComputerAccess iComputerAccess, @NotNull ILuaContext iLuaContext, int i, @NotNull IArguments iArguments) throws LuaException { 50 | switch (i) { 51 | case 0: { 52 | String text = iArguments.getString(0); 53 | Direction direction = Direction.byName(text); 54 | if (direction == null) 55 | throw new LuaException("Specified direction is not real."); 56 | if (!source.display_links.containsKey(direction)) 57 | throw new LuaException("Specified direction does not have an attached link."); 58 | return MethodResult.of( 59 | createHandle(direction) 60 | ); 61 | } 62 | case 1: { 63 | return MethodResult.of(source.display_links.keySet().stream().map(a -> a.toString()).collect(Collectors.toList())); 64 | } 65 | } 66 | return MethodResult.of(); 67 | } 68 | 69 | @NotNull 70 | @Override 71 | public String getType() { 72 | return new ResourceLocation(CreateComputingMod.MOD_ID, "computerized_display_source").toString(); 73 | } 74 | 75 | @Override 76 | public boolean equals(@Nullable IPeripheral iPeripheral) { 77 | return false; 78 | } 79 | 80 | public List handles = new ArrayList<>(); 81 | 82 | public DisplayLinkHandle createHandle(Direction dir) { 83 | DisplayLinkHandle handle = new DisplayLinkHandle( 84 | this, 85 | dir 86 | ); 87 | handles.add(handle); 88 | return handle; 89 | } 90 | 91 | public void closeHandle(Direction direction) { 92 | for (DisplayLinkHandle handle : handles) { 93 | if (handle.direction == direction) { 94 | handle.open = false; 95 | handles.remove(handle); 96 | } 97 | } 98 | } 99 | 100 | public boolean closeHandle(DisplayLinkHandle toDelete) { 101 | for (DisplayLinkHandle handle : handles) { 102 | if (handle.id == toDelete.id) { 103 | handle.open = false; 104 | handles.remove(handle); 105 | return true; 106 | } 107 | } 108 | return false; 109 | } 110 | 111 | public void addLink(Direction dir) { 112 | computers.forEach(a -> a.queueEvent("display_link_added", dir.toString())); 113 | } 114 | 115 | public void delLink(Direction dir) { 116 | closeHandle(dir); 117 | computers.forEach(a -> a.queueEvent("display_link_removed", dir.toString())); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/peripherals/ComputerizedDisplayTargetPeripheral.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.peripherals; 2 | 3 | import com.google.gson.Gson; 4 | import com.simibubi.create.content.logistics.block.display.DisplayLinkContext; 5 | import dan200.computercraft.api.lua.IArguments; 6 | import dan200.computercraft.api.lua.ILuaContext; 7 | import dan200.computercraft.api.lua.LuaException; 8 | import dan200.computercraft.api.lua.MethodResult; 9 | import dan200.computercraft.api.peripheral.IComputerAccess; 10 | import dan200.computercraft.api.peripheral.IDynamicPeripheral; 11 | import dan200.computercraft.api.peripheral.IPeripheral; 12 | import de.saschat.createcomputing.CreateComputingMod; 13 | import de.saschat.createcomputing.tiles.ComputerizedDisplayTargetTile; 14 | import net.minecraft.network.chat.Component; 15 | import net.minecraft.network.chat.MutableComponent; 16 | import net.minecraft.resources.ResourceLocation; 17 | import org.jetbrains.annotations.NotNull; 18 | import org.jetbrains.annotations.Nullable; 19 | 20 | import java.util.HashMap; 21 | import java.util.LinkedList; 22 | import java.util.List; 23 | import java.util.Map; 24 | 25 | public class ComputerizedDisplayTargetPeripheral implements IDynamicPeripheral { 26 | ComputerizedDisplayTargetTile parent; 27 | 28 | public ComputerizedDisplayTargetPeripheral(ComputerizedDisplayTargetTile computerizedDisplayTargetTile) { 29 | this.parent = computerizedDisplayTargetTile; 30 | } 31 | 32 | public List computers = new LinkedList<>(); 33 | 34 | @Override 35 | public void attach(@NotNull IComputerAccess computer) { 36 | computers.add(computer); 37 | } 38 | 39 | @Override 40 | public void detach(@NotNull IComputerAccess computer) { 41 | computers.remove(computer); 42 | } 43 | 44 | @NotNull 45 | @Override 46 | public String[] getMethodNames() { 47 | return new String[]{"setWidth", "getWidth", "setHeight", "getHeight"}; 48 | } 49 | 50 | @NotNull 51 | @Override 52 | public MethodResult callMethod(@NotNull IComputerAccess iComputerAccess, @NotNull ILuaContext iLuaContext, int i, @NotNull IArguments iArguments) throws LuaException { 53 | switch (i) { 54 | case 0: { 55 | int width = iArguments.getInt(0); 56 | parent.maxWidth = width; 57 | } 58 | case 1: { 59 | return MethodResult.of(parent.maxWidth); 60 | } 61 | case 2: { 62 | int height = iArguments.getInt(0); 63 | parent.maxHeight = height; 64 | } 65 | case 3: { 66 | return MethodResult.of(parent.maxHeight); 67 | } 68 | } 69 | return MethodResult.of(); 70 | } 71 | 72 | 73 | @NotNull 74 | @Override 75 | public String getType() { 76 | return new ResourceLocation(CreateComputingMod.MOD_ID, "computerized_display_target").toString(); 77 | } 78 | 79 | @Override 80 | public boolean equals(@Nullable IPeripheral iPeripheral) { 81 | return false; 82 | } 83 | 84 | public Gson gson = new Gson(); 85 | 86 | public void acceptText(int line, List list, DisplayLinkContext displayLinkContext) { 87 | Map map = new HashMap<>(); 88 | for (int i = 0; i < list.size(); i++) { 89 | map.put((double) i, gson.fromJson(Component.Serializer.toJson(list.get(i)), Map.class)); // this code is terrific 90 | } 91 | computers.forEach(a -> { 92 | a.queueEvent("display_link_data", 93 | displayLinkContext.te().activeSource.id.toString(), 94 | displayLinkContext.getSourcePos().getX(), 95 | displayLinkContext.getSourcePos().getY(), 96 | displayLinkContext.getSourcePos().getZ(), 97 | line, 98 | map 99 | ); 100 | }); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/peripherals/ComputerizedRedstoneLinkPeripheral.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.peripherals; 2 | 3 | import dan200.computercraft.api.lua.LuaException; 4 | import dan200.computercraft.api.lua.MethodResult; 5 | import dan200.computercraft.api.peripheral.IPeripheral; 6 | import de.saschat.createcomputing.CreateComputingMod; 7 | import de.saschat.createcomputing.Utils; 8 | import de.saschat.createcomputing.api.SmartPeripheral; 9 | import de.saschat.createcomputing.config.CreateComputingConfigServer; 10 | import de.saschat.createcomputing.peripherals.handles.RedstoneHandle; 11 | import de.saschat.createcomputing.tiles.ComputerizedRedstoneLinkTile; 12 | import net.minecraft.resources.ResourceLocation; 13 | import net.minecraft.world.item.Item; 14 | import org.jetbrains.annotations.NotNull; 15 | import org.jetbrains.annotations.Nullable; 16 | 17 | import java.util.HashMap; 18 | import java.util.Map; 19 | import java.util.UUID; 20 | 21 | public class ComputerizedRedstoneLinkPeripheral extends SmartPeripheral { 22 | public ComputerizedRedstoneLinkTile parent; 23 | public HashMap handles = new HashMap<>(); 24 | 25 | public void removeHandle(UUID hd) { 26 | handles.values().forEach(a -> { 27 | if (a.handle.equals(hd)) { 28 | a.close(); 29 | handles.remove(hd, a); 30 | } 31 | }); 32 | } 33 | 34 | public void killHandles(UUID hd) { 35 | handles.values().forEach(a -> { 36 | if (a.handle.equals(hd)) { 37 | a.close(); 38 | handles.remove(a.handle, a); 39 | } 40 | }); 41 | } 42 | 43 | public ComputerizedRedstoneLinkPeripheral(ComputerizedRedstoneLinkTile tile) { 44 | this.parent = tile; 45 | 46 | addMethod("clearHandles", (iComputerAccess, iLuaContext, iArguments) -> { 47 | parent.tasks.add(() -> { 48 | handles.clear(); 49 | parent.pairs.forEach((b,a) -> { 50 | parent.remove(a); 51 | }); 52 | }); 53 | return MethodResult.of(); 54 | }); 55 | addMethod("getMaxHandles", (iComputerAccess, iLuaContext, iArguments) -> { 56 | return MethodResult.of(CreateComputingConfigServer.get().MAXIMUM_CONCURRENT_LINKS.get()); 57 | }); 58 | addMethod("closeHandle", (iComputerAccess, iLuaContext, iArguments) -> { 59 | return MethodResult.of(); 60 | }); 61 | addMethod("getHandles", (iComputerAccess, iLuaContext, iArguments) -> { 62 | Map hdl = new HashMap<>(); 63 | for (Map.Entry uuidRedstoneHandleEntry : handles.entrySet()) { 64 | hdl.put(uuidRedstoneHandleEntry.getKey().toString(), uuidRedstoneHandleEntry.getValue()); 65 | } 66 | return MethodResult.of(hdl); 67 | }); 68 | addMethod("openHandle", (iComputerAccess, iLuaContext, iArguments) -> { 69 | String _item1 = iArguments.getString(0); 70 | String _item2 = iArguments.getString(1); 71 | Item item1 = Utils.getByName(new ResourceLocation(_item1)); 72 | Item item2 = Utils.getByName(new ResourceLocation(_item2)); 73 | if (item1 == null) 74 | throw new LuaException(_item1 + " is not a valid item id!"); 75 | if (item2 == null) 76 | throw new LuaException(_item2 + " is not a valid item id!"); 77 | if (!ComputerizedRedstoneLinkTile.checkItem(item1)) 78 | throw new LuaException(_item1 + " is banned from the Computerized Redstone Link! This can be changed in the config."); 79 | if (!ComputerizedRedstoneLinkTile.checkItem(item2)) 80 | throw new LuaException(_item2 + " is banned from the Computerized Redstone Link! This can be changed in the config."); 81 | ComputerizedRedstoneLinkTile.LinkPair pair = new ComputerizedRedstoneLinkTile.LinkPair(parent, new Item[]{item1, item2}); 82 | pair.setFrequency(pair.items); 83 | UUID data = parent.add(pair); 84 | if(data == null) 85 | throw new LuaException("You have exceeded the maximum amount of frequencies for this peripheral. The maximum can be changed in the config."); 86 | RedstoneHandle redstoneHandle = new RedstoneHandle(this, data); 87 | handles.put(redstoneHandle.handle, redstoneHandle); 88 | return MethodResult.of(redstoneHandle); 89 | }); 90 | } 91 | 92 | @NotNull 93 | @Override 94 | public String getType() { 95 | return new ResourceLocation(CreateComputingMod.MOD_ID, "computerized_redstone_link").toString(); 96 | } 97 | 98 | @Override 99 | public boolean equals(@Nullable IPeripheral iPeripheral) { 100 | return false; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/peripherals/TrainNetworkObserverPeripheral.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.peripherals; 2 | 3 | import com.google.gson.Gson; 4 | import com.simibubi.create.AllItems; 5 | import com.simibubi.create.Create; 6 | import com.simibubi.create.content.logistics.item.filter.AttributeFilterContainer; 7 | import com.simibubi.create.content.logistics.item.filter.FilterItem; 8 | import com.simibubi.create.content.logistics.trains.BezierConnection; 9 | import com.simibubi.create.content.logistics.trains.GraphLocation; 10 | import com.simibubi.create.content.logistics.trains.TrackNodeLocation; 11 | import com.simibubi.create.content.logistics.trains.entity.Carriage; 12 | import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity; 13 | import com.simibubi.create.content.logistics.trains.entity.Train; 14 | import com.simibubi.create.content.logistics.trains.management.display.GlobalTrainDisplayData; 15 | import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; 16 | import com.simibubi.create.content.logistics.trains.management.edgePoint.observer.TrackObserver; 17 | import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalBoundary; 18 | import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalTileEntity; 19 | import com.simibubi.create.content.logistics.trains.management.edgePoint.station.GlobalStation; 20 | import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleEntry; 21 | import com.simibubi.create.content.logistics.trains.management.schedule.condition.ScheduleWaitCondition; 22 | import dan200.computercraft.api.lua.MethodResult; 23 | import dan200.computercraft.api.peripheral.IPeripheral; 24 | import de.saschat.createcomputing.CreateComputingMod; 25 | import de.saschat.createcomputing.Utils; 26 | import de.saschat.createcomputing.api.SmartPeripheral; 27 | import de.saschat.createcomputing.tiles.TrainNetworkObserverTile; 28 | import net.minecraft.core.BlockPos; 29 | import net.minecraft.nbt.CompoundTag; 30 | import net.minecraft.nbt.ListTag; 31 | import net.minecraft.nbt.Tag; 32 | import net.minecraft.network.chat.Component; 33 | import net.minecraft.resources.ResourceLocation; 34 | import net.minecraft.world.item.ItemStack; 35 | import net.minecraft.world.level.Level; 36 | import net.minecraftforge.items.ItemStackHandler; 37 | import net.minecraftforge.registries.ForgeRegistries; 38 | import org.jetbrains.annotations.NotNull; 39 | import org.jetbrains.annotations.Nullable; 40 | 41 | import java.util.*; 42 | import java.util.stream.Collectors; 43 | 44 | public class TrainNetworkObserverPeripheral extends SmartPeripheral { 45 | TrainNetworkObserverTile parent; 46 | 47 | public List getTrains() { 48 | List trainList = new LinkedList<>(); 49 | GraphLocation graphLocation = parent.getGraphLocation(); 50 | for (Train train : Create.RAILWAYS.trains.values()) { 51 | if (train.graph.id.equals(graphLocation.graph.id)) 52 | trainList.add(train); 53 | } 54 | return trainList; 55 | } 56 | 57 | public Collection getStations() { 58 | return parent.getGraphLocation().graph.getPoints(EdgePointType.STATION); 59 | } 60 | 61 | private Collection getSignals() { 62 | return parent.getGraphLocation().graph.getPoints(EdgePointType.SIGNAL); 63 | } 64 | 65 | private Collection getObservers() { 66 | return parent.getGraphLocation().graph.getPoints(EdgePointType.OBSERVER); 67 | } 68 | 69 | public TrainNetworkObserverPeripheral(TrainNetworkObserverTile tile) { 70 | this.parent = tile; 71 | // TRAINS 72 | addMethod("getTrains", (iComputerAccess, iLuaContext, iArguments) -> { 73 | List trainList = getTrains(); 74 | return MethodResult.of(trainList.stream().map(a -> a.id.toString()).collect(Collectors.toList())); 75 | }); 76 | addMethod("getTrainName", (iComputerAccess, iLuaContext, iArguments) -> { 77 | String b = iArguments.getString(0); 78 | Optional first = getTrains().stream().filter(a -> a.id.toString().equals(b)).findFirst(); 79 | if (first.isEmpty()) 80 | return MethodResult.of(null); 81 | Train train = first.get(); 82 | return MethodResult.of(new Gson().fromJson(Component.Serializer.toJson(train.name), Map.class)); 83 | }); 84 | addMethod("getTrainSchedule", (iComputerAccess, iLuaContext, iArguments) -> { 85 | String b = iArguments.getString(0); 86 | Optional first = getTrains().stream().filter(a -> a.id.toString().equals(b)).findFirst(); 87 | if (first.isEmpty()) 88 | return MethodResult.of(null); 89 | Train train = first.get(); 90 | Map map = new HashMap<>(); 91 | if (train.runtime.getSchedule() == null) 92 | return MethodResult.of(null); 93 | int bidx = 1; 94 | for (ScheduleEntry entry : train.runtime.getSchedule().entries) { 95 | Map data = new HashMap<>(); 96 | data.put("type", entry.instruction.getId().toString()); 97 | data.put("data", blowNBT(entry.instruction.getData())); 98 | int sidx = 1; 99 | for (List conditionLayer : entry.conditions) { 100 | Map conditionL = new HashMap<>(); 101 | int idx = 1; 102 | for (ScheduleWaitCondition cond : conditionLayer) { 103 | Map condition = new HashMap<>(); 104 | 105 | condition.put("type", cond.getId().toString()); 106 | condition.put("data", blowNBT(cond.getData())); 107 | 108 | conditionL.put(idx, condition); 109 | idx++; 110 | } 111 | data.put(sidx, conditionL); 112 | sidx++; 113 | } 114 | map.put(bidx, data); 115 | bidx++; 116 | } 117 | return MethodResult.of(map); 118 | }); 119 | addMethod("getTrainWorldPosition", (iComputerAccess, iLuaContext, iArguments) -> { 120 | String b = iArguments.getString(0); 121 | Optional first = getTrains().stream().filter(a -> a.id.toString().equals(b)).findFirst(); 122 | if (first.isEmpty()) 123 | return MethodResult.of(null); 124 | Train train = first.get(); 125 | 126 | Optional carr = Optional.empty(); 127 | Carriage.DimensionalCarriageEntity a2 = train.carriages.get(0).getDimensionalIfPresent(Level.NETHER); 128 | if (a2 != null) 129 | carr = Optional.of(a2); 130 | Carriage.DimensionalCarriageEntity a1 = train.carriages.get(0).getDimensionalIfPresent(Level.OVERWORLD); 131 | if (a1 != null) 132 | carr = Optional.of(a1); 133 | 134 | if (carr.isEmpty()) 135 | return MethodResult.of(null); 136 | Carriage.DimensionalCarriageEntity car = carr.get(); 137 | CarriageContraptionEntity ent = car.entity.get(); 138 | return MethodResult.of(ent.getX(), ent.getY(), ent.getZ(), ent.getLevel().dimension().registry().toString()); 139 | }); 140 | addMethod("getTrainSpeed", (iComputerAccess, iLuaContext, iArguments) -> { 141 | String b = iArguments.getString(0); 142 | Optional first = getTrains().stream().filter(a -> a.id.toString().equals(b)).findFirst(); 143 | if (first.isEmpty()) 144 | return MethodResult.of(null); 145 | Train train = first.get(); 146 | return MethodResult.of(train.speed); 147 | }); 148 | addMethod("getTrainStopped", (iComputerAccess, iLuaContext, iArguments) -> { 149 | String b = iArguments.getString(0); 150 | Optional first = getTrains().stream().filter(a -> a.toString().equals(b)).findFirst(); 151 | if (first.isEmpty()) 152 | return MethodResult.of(null); 153 | Train train = first.get(); 154 | GlobalStation currentStation = train.getCurrentStation(); 155 | if (currentStation != null) 156 | return MethodResult.of(currentStation.getId().toString(), currentStation.name); 157 | return MethodResult.of(null); 158 | }); 159 | // STOPS 160 | addMethod("getStops", ((iComputerAccess, iLuaContext, iArguments) -> { 161 | Collection stations = getStations(); 162 | return MethodResult.of(stations.stream().map(a -> a.id.toString()).collect(Collectors.toList())); 163 | })); 164 | addMethod("getStopName", (iComputerAccess, iLuaContext, iArguments) -> { 165 | String b = iArguments.getString(0); 166 | Optional first = getStations().stream().filter(a -> a.id.toString().equals(b)).findFirst(); 167 | if (first.isEmpty()) 168 | return MethodResult.of(null); 169 | GlobalStation station = first.get(); 170 | return MethodResult.of(station.name); 171 | }); 172 | addMethod("getStopWorldPosition", (iComputerAccess, iLuaContext, iArguments) -> { 173 | String b = iArguments.getString(0); 174 | Optional first = getStations().stream().filter(a -> a.id.toString().equals(b)).findFirst(); 175 | if (first.isEmpty()) 176 | return MethodResult.of(null); 177 | GlobalStation station = first.get(); 178 | return MethodResult.of(station.tilePos.getX(), station.tilePos.getY(), station.tilePos.getZ()); 179 | }); 180 | addMethod("getStopExpectedTrain", (iComputerAccess, iLuaContext, iArguments) -> { 181 | String b = iArguments.getString(0); 182 | Optional first = getStations().stream().filter(a -> a.id.toString().equals(b)).findFirst(); 183 | if (first.isEmpty()) 184 | return MethodResult.of(null); 185 | GlobalStation station = first.get(); 186 | List prepare = GlobalTrainDisplayData.prepare(station.name, 200); 187 | Map> data = new HashMap(); 188 | int idx = 1; 189 | for (GlobalTrainDisplayData.TrainDeparturePrediction dep : prepare) { 190 | Map subData = new HashMap<>(); 191 | subData.put("destination", dep.destination); // obvious lol 192 | subData.put("ticks", dep.ticks); 193 | subData.put("scheduleName", new Gson().fromJson(Component.Serializer.toJson(dep.scheduleTitle), Map.class)); 194 | subData.put("train", dep.train.id.toString()); 195 | data.put(idx, subData); 196 | idx++; 197 | } 198 | return MethodResult.of(data); 199 | }); 200 | // SIGNALS 201 | addMethod("getSignals", ((iComputerAccess, iLuaContext, iArguments) -> { 202 | Collection stations = getSignals(); 203 | return MethodResult.of(stations.stream().map(a -> a.id.toString()).collect(Collectors.toList())); 204 | })); 205 | addMethod("getSignalWorldPositions", (iComputerAccess, iLuaContext, iArguments) -> { 206 | String b = iArguments.getString(0); 207 | Optional first = getSignals().stream().filter(a -> a.id.toString().equals(b)).findFirst(); 208 | if (first.isEmpty()) 209 | return MethodResult.of(null); 210 | SignalBoundary signal = first.get(); 211 | Map> returned = new HashMap<>(); 212 | int idx = 1; 213 | // fix shitcode and implications 214 | for (Map.Entry map : signal.blockEntities.get(true).entrySet()) { 215 | Map pos = new HashMap<>(); 216 | pos.put(1, map.getKey().getX()); 217 | pos.put(2, map.getKey().getY()); 218 | pos.put(3, map.getKey().getZ()); 219 | returned.put(idx, pos); 220 | idx++; 221 | } 222 | for (Map.Entry map : signal.blockEntities.get(false).entrySet()) { 223 | Map pos = new HashMap<>(); 224 | pos.put(1, map.getKey().getX()); 225 | pos.put(2, map.getKey().getY()); 226 | pos.put(3, map.getKey().getZ()); 227 | returned.put(idx, pos); 228 | idx++; 229 | } 230 | return MethodResult.of(returned); 231 | }); 232 | addMethod("getSignalState", (iComputerAccess, iLuaContext, iArguments) -> { 233 | String b = iArguments.getString(0); 234 | boolean toPos = iArguments.getBoolean(1); 235 | Optional first = getSignals().stream().filter(a -> a.id.toString().equals(b)).findFirst(); 236 | if (first.isEmpty()) 237 | return MethodResult.of(null); 238 | SignalBoundary signal = first.get(); 239 | SignalTileEntity.SignalState stateFor = signal.cachedStates.get(toPos); 240 | return switch (stateFor) { 241 | case RED -> MethodResult.of(0); 242 | case YELLOW -> MethodResult.of(1); 243 | case GREEN -> MethodResult.of(2); 244 | case INVALID -> MethodResult.of(-1); 245 | }; 246 | }); 247 | // OBSERVERS 248 | addMethod("getObservers", ((iComputerAccess, iLuaContext, iArguments) -> { 249 | Collection stations = getObservers(); 250 | return MethodResult.of(stations.stream().map(a -> a.id.toString()).collect(Collectors.toList())); 251 | })); 252 | addMethod("getObserverWorldPosition", (iComputerAccess, iLuaContext, iArguments) -> { 253 | String b = iArguments.getString(0); 254 | Optional first = getObservers().stream().filter(a -> a.id.toString().equals(b)).findFirst(); 255 | if (first.isEmpty()) 256 | return MethodResult.of(null); 257 | TrackObserver obs = first.get(); 258 | return MethodResult.of(obs.tilePos.getX(), obs.tilePos.getY(), obs.tilePos.getZ()); 259 | }); 260 | addMethod("getObserverFilter", ((iComputerAccess, iLuaContext, iArguments) -> { 261 | String b = iArguments.getString(0); 262 | Optional first = getObservers().stream().filter(a -> a.id.toString().equals(b)).findFirst(); 263 | if (first.isEmpty()) 264 | return MethodResult.of(null); 265 | TrackObserver obs = first.get(); 266 | return MethodResult.of(blowFilter(obs.getFilter())); 267 | })); 268 | // GRAPH 269 | addMethod("getGraph", ((iComputerAccess, iLuaContext, iArguments) -> { 270 | Set nodes = parent.getGraphLocation().graph.getNodes(); 271 | List map = new LinkedList<>(); 272 | int index = 0; 273 | for (TrackNodeLocation location : nodes) { 274 | Map map2 = new HashMap<>(); 275 | map2.put("x", (Number) location.getX()); 276 | map2.put("y", (Number) location.getY()); 277 | map2.put("z", (Number) location.getZ()); 278 | map2.put("dimension", location.dimension.location().toString()); 279 | map2.put("bezier", false); 280 | if (location instanceof TrackNodeLocation.DiscoveredLocation disc) { 281 | BezierConnection turn = disc.getTurn(); 282 | if (turn != null) { 283 | map2.put("bezier", true); 284 | map2.put("girder", turn.hasGirder); 285 | map2.put("primary", turn.hasGirder); 286 | map2.put("positions", List.of( 287 | List.of(turn.tePositions.get(true).getX(), turn.tePositions.get(true).getY(), turn.tePositions.get(true).getZ()), 288 | List.of(turn.tePositions.get(false).getX(), turn.tePositions.get(false).getY(), turn.tePositions.get(false).getZ()) 289 | )); 290 | map2.put("starts", List.of( 291 | List.of(turn.starts.get(true).x, turn.starts.get(true).y, turn.starts.get(true).z), 292 | List.of(turn.starts.get(false).x, turn.starts.get(false).y, turn.starts.get(false).z) 293 | )); 294 | map2.put("axes", List.of( 295 | List.of(turn.axes.get(true).x, turn.axes.get(true).y, turn.axes.get(true).z), 296 | List.of(turn.axes.get(false).x, turn.axes.get(false).y, turn.axes.get(false).z) 297 | )); 298 | map2.put("normals", List.of( 299 | List.of(turn.normals.get(true).x, turn.normals.get(true).y, turn.normals.get(true).z), 300 | List.of(turn.normals.get(false).x, turn.normals.get(false).y, turn.normals.get(false).z) 301 | )); 302 | } 303 | } 304 | map.add(map2); 305 | } 306 | return MethodResult.of(map); 307 | })); 308 | } 309 | 310 | private static Map blowFilter(ItemStack filter) { 311 | Map ret = new HashMap<>(); 312 | if (filter.is(AllItems.FILTER.get())) { 313 | ItemStackHandler filterItems = FilterItem.getFilterItems(filter); 314 | ret.put("type", "filter"); 315 | ret.put("whitelist", !filter.getTag().getBoolean("Blacklist")); 316 | ret.put("respectnbt", !filter.getTag().getBoolean("RespectNBT")); 317 | for (int i = 1; i < filterItems.getSlots() + 1; i++) { 318 | ret.put(i - 1, blowFilter(filterItems.getStackInSlot(i))); 319 | } 320 | return ret; 321 | } 322 | if (filter.is(AllItems.ATTRIBUTE_FILTER.get())) { 323 | ret.put("type", "attribute"); 324 | AttributeFilterContainer.WhitelistMode whitelistMode = AttributeFilterContainer.WhitelistMode.values()[filter.getTag().getInt("WhitelistMode")]; 325 | ret.put("allowmode", whitelistMode.toString()); 326 | ListTag tag = filter.getTag().getList("MatchedAttributes", Tag.TAG_COMPOUND); 327 | int idx = 1; 328 | for (Tag inb : tag) { 329 | CompoundTag tg = (CompoundTag) inb; 330 | ret.put(idx, blowNBT(tg)); 331 | idx++; 332 | } 333 | return ret; 334 | } 335 | ret.put("type", "item"); 336 | ret.put("count", filter.getCount()); 337 | ret.put("id", ForgeRegistries.ITEMS.getKey(filter.getItem()).toString()); 338 | ret.put("nbt", blowNBT(filter.getTag())); 339 | return ret; 340 | } 341 | 342 | public static final boolean DEBUG_NBT = false; 343 | private static Object blowNBT(Tag tag) { 344 | Object b = Utils.blowNBT(tag); 345 | if(DEBUG_NBT) { 346 | System.out.println("======================"); 347 | System.out.println("in: " + tag.getClass().getName()); 348 | System.out.println("out: " + b.getClass().getName()); 349 | } 350 | return b; 351 | } 352 | 353 | @NotNull 354 | @Override 355 | public String getType() { 356 | return new ResourceLocation(CreateComputingMod.MOD_ID, "train_network_observer").toString(); 357 | } 358 | 359 | @Override 360 | public boolean equals(@Nullable IPeripheral iPeripheral) { 361 | return false; 362 | } 363 | } 364 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/peripherals/handles/DisplayLinkHandle.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.peripherals.handles; 2 | 3 | import com.google.gson.Gson; 4 | import com.simibubi.create.content.logistics.block.display.DisplayLinkTileEntity; 5 | import com.simibubi.create.content.logistics.block.display.target.DisplayTarget; 6 | import com.simibubi.create.content.logistics.trains.management.display.FlapDisplayTileEntity; 7 | import dan200.computercraft.api.lua.IArguments; 8 | import dan200.computercraft.api.lua.LuaException; 9 | import dan200.computercraft.api.lua.LuaFunction; 10 | import de.saschat.createcomputing.behaviour.source.TextDisplayBehaviour; 11 | import de.saschat.createcomputing.peripherals.ComputerizedDisplaySourcePeripheral; 12 | import de.saschat.createcomputing.tiles.ComputerizedDisplaySourceTile; 13 | import net.minecraft.core.Direction; 14 | import net.minecraft.network.chat.Component; 15 | import net.minecraft.network.chat.MutableComponent; 16 | 17 | import java.util.*; 18 | 19 | public class DisplayLinkHandle { 20 | public UUID id = UUID.randomUUID(); 21 | public boolean open = true; 22 | public Direction direction; 23 | private ComputerizedDisplaySourcePeripheral parent; 24 | 25 | public DisplayLinkHandle(ComputerizedDisplaySourcePeripheral parent, Direction direction) { 26 | this.parent = parent; 27 | this.direction = direction; 28 | } 29 | 30 | public void checkOpen() throws LuaException { 31 | if (!open) 32 | throw new LuaException("Trying to use closed handle."); 33 | } 34 | 35 | public ComputerizedDisplaySourceTile.DisplayData getData() throws LuaException { 36 | if (!parent.source.display_links.containsKey(direction)) { 37 | close(); 38 | checkOpen(); 39 | } 40 | return parent.source.display_links.get(direction); 41 | } 42 | 43 | public void setData(ComputerizedDisplaySourceTile.DisplayData data) throws LuaException { 44 | if (!parent.source.display_links.containsKey(direction)) { 45 | close(); 46 | checkOpen(); 47 | } 48 | parent.source.display_links.put(direction, data); 49 | } 50 | 51 | @LuaFunction 52 | public final void close() throws LuaException { 53 | this.open = false; 54 | if (!this.parent.closeHandle(this)) { 55 | throw new RuntimeException("Failed to close handle."); 56 | } 57 | } 58 | 59 | public DisplayTarget getTarget() throws LuaException { 60 | ComputerizedDisplaySourceTile.DisplayData data = getData(); 61 | return data.tileEntity.activeTarget; 62 | } 63 | 64 | @LuaFunction 65 | public final Object[] getTargetType(IArguments arg) throws LuaException { 66 | checkOpen(); 67 | ComputerizedDisplaySourceTile.DisplayData data = getData(); 68 | 69 | DisplayLinkTileEntity te = data.tileEntity; 70 | 71 | if(getTarget() != null) 72 | return new Object[]{getTarget().id.toString()}; 73 | return new Object[]{null}; 74 | } 75 | 76 | @LuaFunction 77 | public final void setText(IArguments arg) throws LuaException { 78 | checkOpen(); 79 | 80 | Gson gson = new Gson(); 81 | Map table = (Map) arg.getTable(0); 82 | List components = new ArrayList<>(); 83 | for (Map.Entry entry : table.entrySet()) { 84 | if (!(entry.getKey() instanceof Double)) { 85 | throw new LuaException("Invalid table index."); 86 | } 87 | if (!((entry.getValue()) instanceof Map)) 88 | throw new LuaException("Table value should be a component (table)."); 89 | try { 90 | for (int i = components.size(); i < entry.getKey() - 1; i++) { 91 | components.add(TextDisplayBehaviour.NIL_TEXT); 92 | } 93 | components.add( 94 | entry.getKey().intValue() - 1, 95 | Component.Serializer.fromJson(gson.toJson(entry.getValue())) 96 | ); 97 | } catch (Exception ex) { 98 | throw new LuaException(ex.getMessage()); 99 | } 100 | } 101 | 102 | ComputerizedDisplaySourceTile.DisplayData data = getData(); 103 | data.toDisplay = components; 104 | setData(data); 105 | } 106 | 107 | 108 | @LuaFunction 109 | public final Object[] getText() throws LuaException { 110 | checkOpen(); 111 | ComputerizedDisplaySourceTile.DisplayData data = getData(); 112 | 113 | Gson gson = new Gson(); 114 | Map result = new HashMap<>(); 115 | int i = 0; 116 | for (MutableComponent cmp : data.toDisplay) { 117 | if (!cmp.equals(TextDisplayBehaviour.NIL_TEXT)) 118 | result.put((double) i, gson.fromJson(Component.Serializer.toJson(cmp), Map.class)); 119 | i++; 120 | } 121 | 122 | return new Object[]{result}; 123 | } 124 | 125 | @LuaFunction(mainThread = true) 126 | public final Object[] getWidth() throws LuaException { 127 | ComputerizedDisplaySourceTile.DisplayData data = getData(); 128 | if (getTarget() != null) { 129 | switch (getTarget().id.toString()) { 130 | // @todo more target sizes 131 | case "create:display_board_target": { 132 | FlapDisplayTileEntity d = (FlapDisplayTileEntity) data.tileEntity.getLevel().getBlockEntity(data.tileEntity.getTargetPosition()); 133 | d = d.getController(); 134 | return new Object[]{d.getMaxCharCount()}; 135 | } 136 | } 137 | } 138 | return new Object[]{-1}; 139 | } 140 | 141 | @LuaFunction(mainThread = true) 142 | public final Object[] getHeight() throws LuaException { 143 | ComputerizedDisplaySourceTile.DisplayData data = getData(); 144 | if (getTarget() != null) { 145 | switch (getTarget().id.toString()) { 146 | // @todo more target sizes 147 | case "create:display_board_target": { 148 | FlapDisplayTileEntity d = (FlapDisplayTileEntity) data.tileEntity.getLevel().getBlockEntity(data.tileEntity.getTargetPosition()); 149 | d = d.getController(); 150 | return new Object[]{d.getLines().size()}; 151 | } 152 | } 153 | } 154 | 155 | return new Object[]{-1}; 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/peripherals/handles/RedstoneHandle.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.peripherals.handles; 2 | 3 | import dan200.computercraft.api.lua.IArguments; 4 | import dan200.computercraft.api.lua.LuaException; 5 | import dan200.computercraft.api.lua.LuaFunction; 6 | import de.saschat.createcomputing.peripherals.ComputerizedRedstoneLinkPeripheral; 7 | import de.saschat.createcomputing.tiles.ComputerizedRedstoneLinkTile; 8 | import net.minecraft.resources.ResourceLocation; 9 | import net.minecraft.world.item.Item; 10 | import net.minecraftforge.registries.ForgeRegistries; 11 | 12 | import java.util.Arrays; 13 | import java.util.UUID; 14 | import java.util.stream.Collectors; 15 | 16 | import static de.saschat.createcomputing.Utils.getByName; 17 | 18 | public class RedstoneHandle { 19 | public ComputerizedRedstoneLinkPeripheral parent; 20 | public UUID handle; 21 | public boolean open = true; 22 | public RedstoneHandle(ComputerizedRedstoneLinkPeripheral parent, UUID pair) { 23 | this.handle = pair; 24 | this.parent = parent; 25 | } 26 | 27 | public void isOpen() throws LuaException { 28 | if(!open) 29 | throw new LuaException("This handle has already been closed."); 30 | } 31 | 32 | 33 | public ComputerizedRedstoneLinkTile.LinkPair getHandle() throws LuaException { 34 | isOpen(); 35 | ComputerizedRedstoneLinkTile.LinkPair linkPair = parent.parent.pairs.get(handle); 36 | if(linkPair == null) 37 | throw new LuaException("Pair has already been deleted."); 38 | return linkPair; 39 | } 40 | 41 | @LuaFunction(mainThread = true) 42 | public final void setSignal(IArguments arguments) throws LuaException { 43 | isOpen(); 44 | int value = arguments.getInt(0); 45 | System.out.println("sx: " + value); 46 | getHandle().provideSignal(value); 47 | } 48 | @LuaFunction(mainThread = true) 49 | public final int getSignal(IArguments arguments) throws LuaException { 50 | isOpen(); 51 | return getHandle().retrieveSignal(); 52 | } 53 | @LuaFunction 54 | public final String getId() throws LuaException { 55 | return this.handle.toString(); 56 | } 57 | @LuaFunction(mainThread = true) 58 | public final void setItems(IArguments arguments) throws LuaException { 59 | isOpen(); 60 | String _item1 = arguments.getString(0); 61 | String _item2 = arguments.getString(1); 62 | Item item1 = getByName(new ResourceLocation(_item1)); 63 | Item item2 = getByName(new ResourceLocation(_item2)); 64 | if (item1 == null) 65 | throw new LuaException(_item1 + " is not a valid item id!"); 66 | if (item2 == null) 67 | throw new LuaException(_item2 + " is not a valid item id!"); 68 | if (!ComputerizedRedstoneLinkTile.checkItem(item1)) 69 | throw new LuaException(_item1 + " is banned from the Computerized Redstone Link! This can be changed in the config."); 70 | if (!ComputerizedRedstoneLinkTile.checkItem(item2)) 71 | throw new LuaException(_item2 + " is banned from the Computerized Redstone Link! This can be changed in the config."); 72 | getHandle().setFrequency(new Item[] {item1, item2}); 73 | } 74 | @LuaFunction(mainThread = true) 75 | public final String[] getItems(IArguments arguments) throws LuaException { 76 | return Arrays.stream(getHandle().items).map(a -> ForgeRegistries.ITEMS.getKey(a).toString()).collect(Collectors.toList()).toArray(new String[0]); 77 | } 78 | @LuaFunction 79 | public final void close() { 80 | this.open = false; 81 | parent.removeHandle(handle); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/tiles/ComputerizedDisplaySourceTile.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.tiles; 2 | 3 | import com.simibubi.create.AllBlocks; 4 | import com.simibubi.create.content.logistics.block.display.DisplayLinkTileEntity; 5 | import dan200.computercraft.shared.Capabilities; 6 | import de.saschat.createcomputing.Registries; 7 | import de.saschat.createcomputing.blocks.ComputerizedDisplaySourceBlock; 8 | import de.saschat.createcomputing.peripherals.ComputerizedDisplaySourcePeripheral; 9 | import net.minecraft.core.BlockPos; 10 | import net.minecraft.core.Direction; 11 | import net.minecraft.network.chat.Component; 12 | import net.minecraft.network.chat.MutableComponent; 13 | import net.minecraft.world.level.LevelReader; 14 | import net.minecraft.world.level.block.entity.BlockEntity; 15 | import net.minecraft.world.level.block.entity.BlockEntityType; 16 | import net.minecraft.world.level.block.state.BlockState; 17 | import net.minecraftforge.common.capabilities.Capability; 18 | import net.minecraftforge.common.util.LazyOptional; 19 | import org.jetbrains.annotations.NotNull; 20 | import org.jetbrains.annotations.Nullable; 21 | 22 | import java.util.ArrayList; 23 | import java.util.HashMap; 24 | import java.util.List; 25 | import java.util.Map; 26 | 27 | public class ComputerizedDisplaySourceTile extends BlockEntity { 28 | public LazyOptional peripheral = LazyOptional.empty(); 29 | public Map display_links = new HashMap(); 30 | 31 | public DisplayData getFromPos(BlockPos pos) { 32 | // @todo: optimize lol 33 | for(Direction d: Direction.values()) { 34 | if(getBlockPos().relative(d).equals(pos)) { 35 | return display_links.get(d); 36 | } 37 | } 38 | onNeighborChange(null, getLevel(), getBlockPos(), null); 39 | return getFromPos(pos); 40 | } 41 | 42 | public static class DisplayData { 43 | public DisplayLinkTileEntity tileEntity; 44 | public List toDisplay = new ArrayList<>(); 45 | public DisplayData(DisplayLinkTileEntity te) { 46 | this.tileEntity = te; 47 | } 48 | } 49 | 50 | 51 | public String text; 52 | 53 | public ComputerizedDisplaySourceTile(BlockPos p_155229_, BlockState p_155230_) { 54 | super(Registries.COMPUTERIZED_DISPLAY_SOURCE_TILE.get(), p_155229_, p_155230_); 55 | } 56 | 57 | @NotNull 58 | @Override 59 | public LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction side) { 60 | if (cap == Capabilities.CAPABILITY_PERIPHERAL && side == getBlockState().getValue(ComputerizedDisplaySourceBlock.FACING)) { 61 | if (peripheral == null || !peripheral.isPresent()) { 62 | peripheral = LazyOptional.of(() -> new ComputerizedDisplaySourcePeripheral(this)); 63 | } 64 | return peripheral.cast(); 65 | } 66 | return super.getCapability(cap, side); 67 | } 68 | 69 | public void onNeighborChange(BlockState state, LevelReader level, BlockPos pos, BlockPos neighbor) { 70 | for (Direction dir : Direction.values()) { 71 | BlockPos location = pos.relative(dir); 72 | BlockState blockState = level.getBlockState(location); 73 | if (blockState.is(AllBlocks.DISPLAY_LINK.get())) { 74 | display_links.put(dir, new DisplayData((DisplayLinkTileEntity) level.getBlockEntity(location))); 75 | addLink(dir); 76 | } else { 77 | if (display_links.containsKey(dir)) { 78 | display_links.remove(dir); 79 | delLink(dir); 80 | } 81 | } 82 | } 83 | } 84 | 85 | public void onBlockBreak() { 86 | if (peripheral.isPresent()) { 87 | for (Direction dir: Direction.values()) { 88 | if(display_links.containsKey(dir)) 89 | peripheral.resolve().get().delLink(dir); 90 | else 91 | peripheral.resolve().get().closeHandle(dir); 92 | } 93 | } 94 | } 95 | 96 | public void addLink(Direction dir) { 97 | if (peripheral.isPresent()) 98 | peripheral.resolve().get().addLink(dir); 99 | } 100 | 101 | public void delLink(Direction dir) { 102 | if (peripheral.isPresent()) 103 | peripheral.resolve().get().delLink(dir); 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/tiles/ComputerizedDisplayTargetTile.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.tiles; 2 | 3 | import com.simibubi.create.content.logistics.block.display.DisplayLinkContext; 4 | import dan200.computercraft.shared.Capabilities; 5 | import de.saschat.createcomputing.Registries; 6 | import de.saschat.createcomputing.blocks.ComputerizedDisplaySourceBlock; 7 | import de.saschat.createcomputing.peripherals.ComputerizedDisplaySourcePeripheral; 8 | import de.saschat.createcomputing.peripherals.ComputerizedDisplayTargetPeripheral; 9 | import net.minecraft.core.BlockPos; 10 | import net.minecraft.core.Direction; 11 | import net.minecraft.network.chat.MutableComponent; 12 | import net.minecraft.world.level.block.entity.BlockEntity; 13 | import net.minecraft.world.level.block.state.BlockState; 14 | import net.minecraftforge.common.capabilities.Capability; 15 | import net.minecraftforge.common.util.LazyOptional; 16 | import org.jetbrains.annotations.NotNull; 17 | import org.jetbrains.annotations.Nullable; 18 | 19 | import java.util.List; 20 | 21 | public class ComputerizedDisplayTargetTile extends BlockEntity { 22 | public int maxHeight = 4; 23 | public int maxWidth = 15; 24 | public LazyOptional peripheral = LazyOptional.empty(); 25 | public ComputerizedDisplayTargetTile(BlockPos p_153215_, BlockState p_153216_) { 26 | super(Registries.COMPUTERIZED_DISPLAY_TARGET_TILE.get(), p_153215_, p_153216_); 27 | } 28 | 29 | public void acceptText(int line, List list, DisplayLinkContext displayLinkContext) { 30 | if(peripheral.isPresent()) 31 | peripheral.resolve().get().acceptText(line, list, displayLinkContext); 32 | } 33 | @NotNull 34 | @Override 35 | public LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction side) { 36 | if (cap == Capabilities.CAPABILITY_PERIPHERAL && side == getBlockState().getValue(ComputerizedDisplaySourceBlock.FACING)) { 37 | if (peripheral == null || !peripheral.isPresent()) { 38 | peripheral = LazyOptional.of(() -> new ComputerizedDisplayTargetPeripheral(this)); 39 | } 40 | return peripheral.cast(); 41 | } 42 | return super.getCapability(cap, side); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/tiles/ComputerizedRedstoneLinkTile.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.tiles; 2 | 3 | import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkFrequencySlot; 4 | import com.simibubi.create.foundation.tileEntity.SmartTileEntity; 5 | import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; 6 | import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform; 7 | import com.simibubi.create.foundation.tileEntity.behaviour.linked.LinkBehaviour; 8 | import dan200.computercraft.shared.Capabilities; 9 | import de.saschat.createcomputing.Registries; 10 | import de.saschat.createcomputing.Utils; 11 | import de.saschat.createcomputing.config.CreateComputingConfigServer; 12 | import de.saschat.createcomputing.peripherals.ComputerizedRedstoneLinkPeripheral; 13 | import net.minecraft.core.BlockPos; 14 | import net.minecraft.core.Direction; 15 | import net.minecraft.nbt.CompoundTag; 16 | import net.minecraft.resources.ResourceLocation; 17 | import net.minecraft.world.item.Item; 18 | import net.minecraft.world.item.ItemStack; 19 | import net.minecraft.world.level.block.state.BlockState; 20 | import net.minecraftforge.common.capabilities.Capability; 21 | import net.minecraftforge.common.util.LazyOptional; 22 | import net.minecraftforge.registries.ForgeRegistries; 23 | import org.apache.commons.lang3.tuple.Pair; 24 | import org.jetbrains.annotations.NotNull; 25 | import org.jetbrains.annotations.Nullable; 26 | 27 | import java.util.*; 28 | import java.util.concurrent.ArrayBlockingQueue; 29 | import java.util.concurrent.ConcurrentHashMap; 30 | 31 | public class ComputerizedRedstoneLinkTile extends SmartTileEntity { 32 | public ConcurrentHashMap pairs = new ConcurrentHashMap<>(); 33 | public List deferred = new LinkedList<>(); 34 | public Queue tasks = new ArrayBlockingQueue<>(32); 35 | 36 | public LazyOptional PERIPHERAL = LazyOptional.of( 37 | () -> new ComputerizedRedstoneLinkPeripheral(this) 38 | ); 39 | 40 | public ComputerizedRedstoneLinkTile(BlockPos p_155229_, BlockState p_155230_) { 41 | super(Registries.COMPUTERIZED_REDSTONE_LINK_TILE.get(), p_155229_, p_155230_); 42 | } 43 | 44 | 45 | int i = 0; 46 | 47 | @Override 48 | public void tick() { 49 | super.tick(); 50 | if (!getLevel().isClientSide()) { 51 | Runnable a; 52 | while ((a = tasks.poll()) != null) { 53 | a.run(); 54 | } 55 | } 56 | pairs.values().forEach(linkPair -> linkPair.transmit.tick()); 57 | pairs.values().forEach(linkPair -> linkPair.receive.tick()); 58 | } 59 | 60 | public UUID add(LinkPair pair) { 61 | if (pairs.size() >= CreateComputingConfigServer.get().MAXIMUM_CONCURRENT_LINKS.get()) 62 | return null; 63 | UUID uuid = UUID.randomUUID(); 64 | pair.index = uuid; 65 | tasks.add(() -> { 66 | pair.transmit.initialize(); 67 | pair.receive.initialize(); 68 | }); 69 | pairs.put(uuid, pair); 70 | return uuid; 71 | } 72 | 73 | public void addDeferred(LinkPair pair) { 74 | deferred.add(pair); 75 | } 76 | 77 | public void remove(LinkPair pair) { 78 | if (PERIPHERAL.isPresent()) 79 | PERIPHERAL.resolve().get().killHandles(pair.index); 80 | pairs.remove(pair.index, pair); 81 | pair.sendSignal = 0; 82 | pair.transmit.notifySignalChange(); 83 | pair.transmit.remove(); 84 | pair.receive.remove(); 85 | } 86 | 87 | 88 | /* 89 | @Override 90 | protected void write(CompoundTag tag, boolean clientPacket) { 91 | super.write(tag, clientPacket); 92 | System.out.println("WRITING... " + clientPacket); 93 | ListTag behaviours = new ListTag(); 94 | for (LinkPair value : pairs.values()) { 95 | behaviours.add(value.toTag()); 96 | } 97 | tag.put("transceivers", behaviours); 98 | System.out.println(Utils.blowNBT(tag)); 99 | } 100 | 101 | @Override 102 | protected void read(CompoundTag tag, boolean clientPacket) { 103 | super.read(tag, clientPacket); 104 | System.out.println("READING... " + clientPacket); 105 | System.out.println(Utils.blowNBT(tag)); 106 | ListTag transceivers = tag.getList("transceivers", Tag.TAG_COMPOUND); 107 | for (Tag transceiver : transceivers) { 108 | LinkPair behaviour = LinkPair.fromTag(this, (CompoundTag) transceiver); 109 | addDeferred(behaviour); 110 | PERIPHERAL.resolve().get().handles.put(behaviour.index, new RedstoneHandle( 111 | PERIPHERAL.resolve().get(), 112 | behaviour.index 113 | )); 114 | } 115 | 116 | } 117 | */ 118 | @Override 119 | public void addBehavioursDeferred(List behaviours) { 120 | super.addBehavioursDeferred(behaviours); 121 | for (LinkPair linkPair : deferred) { 122 | pairs.put(linkPair.index, linkPair); 123 | linkPair.registered = true; 124 | linkPair.setFrequency(linkPair.items); 125 | } 126 | } 127 | 128 | public static boolean checkItem(Item stack) { 129 | for (String loc : CreateComputingConfigServer.get().BANNED_LINK_ITEMS.get()) { 130 | if (loc.equals(ForgeRegistries.ITEMS.getKey(stack).toString())) 131 | return false; 132 | } 133 | return true; 134 | } 135 | 136 | @Override 137 | public void addBehaviours(List list) { 138 | } 139 | 140 | private static boolean firstRun = true; 141 | 142 | @NotNull 143 | @Override 144 | public LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction side) { 145 | if (side == Direction.DOWN && cap == Capabilities.CAPABILITY_PERIPHERAL) { 146 | return PERIPHERAL.cast(); 147 | } 148 | return super.getCapability(cap, side); 149 | } 150 | 151 | public static class LinkPair { 152 | private final LinkBehaviour transmit; 153 | private final LinkBehaviour receive; 154 | public UUID index; 155 | 156 | public boolean registered = false; 157 | 158 | public int sendSignal = 0; 159 | public int recvSignal = 0; 160 | ComputerizedRedstoneLinkTile parent; 161 | 162 | public Item[] items; 163 | 164 | public List> listeners = new ArrayList<>(); 165 | 166 | public LinkPair(ComputerizedRedstoneLinkTile parent, Item[] items) { 167 | this.parent = parent; 168 | Pair slots = 169 | ValueBoxTransform.Dual.makeSlots(RedstoneLinkFrequencySlot::new); 170 | transmit = LinkBehaviour.transmitter(parent, slots, this::getSignal); 171 | receive = LinkBehaviour.receiver(parent, slots, this::setSignal); 172 | this.items = items; 173 | parent.setChanged(); 174 | } 175 | 176 | /*public CompoundTag toTag() { 177 | CompoundTag us = new CompoundTag(); 178 | us.putUUID("index", index); 179 | us.putByte("send", (byte) sendSignal); 180 | us.putByte("receive", (byte) recvSignal); 181 | us.putString("frequency.0", items[0].getRegistryName().toString()); 182 | us.putString("frequency.1", items[1].getRegistryName().toString()); 183 | return us; 184 | }*/ 185 | 186 | public static LinkPair fromTag(ComputerizedRedstoneLinkTile parent, CompoundTag tag) { 187 | Item[] items = new Item[]{ 188 | Utils.getByName(new ResourceLocation(tag.getString("frequency.0"))), 189 | Utils.getByName(new ResourceLocation(tag.getString("frequency.1"))), 190 | }; 191 | LinkPair pair = new LinkPair(parent, items); 192 | pair.index = tag.getUUID("index"); 193 | pair.setSignal(tag.getByte("send")); 194 | pair.recvSignal = tag.getByte("receive"); 195 | return pair; 196 | } 197 | 198 | public void setFrequency(Item[] items) { 199 | parent.tasks.add(() -> { 200 | transmit.setFrequency(true, new ItemStack(items[0])); 201 | transmit.setFrequency(false, new ItemStack(items[1])); 202 | receive.setFrequency(true, new ItemStack(items[0])); 203 | receive.setFrequency(false, new ItemStack(items[1])); 204 | this.items = items; 205 | }); 206 | dirty(); 207 | } 208 | 209 | public void provideSignal(int strength) { 210 | sendSignal = strength; 211 | dirty(); 212 | } 213 | 214 | public int retrieveSignal() { 215 | return recvSignal; 216 | } 217 | 218 | private void dirty() { 219 | if (parent.getLevel().isClientSide()) 220 | return; 221 | parent.tasks.add(this::_dirty); 222 | parent.setChanged(); 223 | } 224 | 225 | private void _dirty() { 226 | transmit.notifySignalChange(); 227 | receive.notifySignalChange(); 228 | } 229 | 230 | private void setSignal(int i) { 231 | recvSignal = i; 232 | listeners.forEach(a -> a.receive(i)); 233 | } 234 | 235 | private int getSignal() { 236 | return sendSignal; 237 | } 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/tiles/TrainNetworkObserverTile.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.tiles; 2 | 3 | import com.simibubi.create.AllBlocks; 4 | import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE; 5 | import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform; 6 | import com.simibubi.create.content.logistics.trains.GraphLocation; 7 | import com.simibubi.create.content.logistics.trains.TrackGraphHelper; 8 | import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; 9 | import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour; 10 | import com.simibubi.create.foundation.tileEntity.SmartTileEntity; 11 | import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; 12 | import dan200.computercraft.shared.Capabilities; 13 | import de.saschat.createcomputing.CreateComputingMod; 14 | import de.saschat.createcomputing.Registries; 15 | import de.saschat.createcomputing.behaviour.tile.TrainNetworkObserver; 16 | import de.saschat.createcomputing.peripherals.TrainNetworkObserverPeripheral; 17 | import net.minecraft.core.BlockPos; 18 | import net.minecraft.core.Direction; 19 | import net.minecraft.resources.ResourceLocation; 20 | import net.minecraft.world.level.block.state.BlockState; 21 | import net.minecraft.world.phys.Vec3; 22 | import net.minecraftforge.common.capabilities.Capability; 23 | import net.minecraftforge.common.util.LazyOptional; 24 | import org.jetbrains.annotations.NotNull; 25 | import org.jetbrains.annotations.Nullable; 26 | 27 | import java.util.List; 28 | 29 | public class TrainNetworkObserverTile extends SmartTileEntity implements ITransformableTE { 30 | public TrackTargetingBehaviour edgePoint; 31 | public static final EdgePointType NETWORK_OBSERVER = EdgePointType.register(new ResourceLocation( 32 | CreateComputingMod.MOD_ID, 33 | "network_observer" 34 | ), TrainNetworkObserver::new); 35 | 36 | public GraphLocation getGraphLocation() { 37 | GraphLocation l = null; 38 | if (edgePoint.getTargetBezier() != null) { 39 | l = TrackGraphHelper.getBezierGraphLocationAt(getLevel(), edgePoint.getGlobalPosition(), Direction.AxisDirection.POSITIVE, edgePoint.getTargetBezier()); 40 | } else { 41 | List trackAxes = AllBlocks.TRACK.get().getTrackAxes(level, edgePoint.getGlobalPosition(), edgePoint.getTrackBlockState()); 42 | if(trackAxes.size() != 1) { 43 | getLevel().destroyBlock(getBlockPos(), true); 44 | return null; 45 | } 46 | l = TrackGraphHelper.getGraphLocationAt(level, edgePoint.getGlobalPosition(), Direction.AxisDirection.POSITIVE, trackAxes.get(0)); 47 | } 48 | return l; 49 | } 50 | 51 | public LazyOptional peripheral = LazyOptional.empty(); 52 | 53 | @NotNull 54 | @Override 55 | public LazyOptional getCapability(@NotNull Capability cap, @Nullable Direction side) { 56 | if(cap == Capabilities.CAPABILITY_PERIPHERAL && side == Direction.UP) { 57 | if(!peripheral.isPresent()) 58 | peripheral = LazyOptional.of(() -> new TrainNetworkObserverPeripheral(this)); 59 | return peripheral.cast(); 60 | } 61 | return super.getCapability(cap, side); 62 | } 63 | 64 | public TrainNetworkObserverTile(BlockPos p_155229_, BlockState p_155230_) { 65 | super(Registries.TRAIN_NETWORK_OBSERVER_TILE.get(), p_155229_, p_155230_); 66 | } 67 | 68 | @Override 69 | public void tick() { 70 | super.tick(); 71 | } 72 | 73 | @Override 74 | public void addBehaviours(List behaviours) { 75 | behaviours.add(edgePoint = new TrackTargetingBehaviour<>(this, NETWORK_OBSERVER)); 76 | } 77 | 78 | @Override 79 | public void transform(StructureTransform structureTransform) { 80 | edgePoint.transform(structureTransform); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/de/saschat/createcomputing/tiles/renderer/TrainNetworkObserverRenderer.java: -------------------------------------------------------------------------------- 1 | package de.saschat.createcomputing.tiles.renderer; 2 | 3 | import com.mojang.blaze3d.vertex.PoseStack; 4 | import com.simibubi.create.content.logistics.trains.ITrackBlock; 5 | import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour; 6 | import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour.RenderedTrackOverlayType; 7 | import com.simibubi.create.foundation.tileEntity.renderer.SmartTileEntityRenderer; 8 | import de.saschat.createcomputing.behaviour.tile.TrainNetworkObserver; 9 | import de.saschat.createcomputing.tiles.TrainNetworkObserverTile; 10 | import net.minecraft.client.renderer.MultiBufferSource; 11 | import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; 12 | import net.minecraft.core.BlockPos; 13 | import net.minecraft.world.level.Level; 14 | import net.minecraft.world.level.block.Block; 15 | import net.minecraft.world.level.block.state.BlockState; 16 | 17 | public class TrainNetworkObserverRenderer extends SmartTileEntityRenderer { 18 | 19 | public TrainNetworkObserverRenderer(BlockEntityRendererProvider.Context context) { 20 | super(context); 21 | } 22 | 23 | @Override 24 | protected void renderSafe(TrainNetworkObserverTile te, float partialTicks, PoseStack ms, MultiBufferSource buffer, 25 | int light, int overlay) { 26 | super.renderSafe(te, partialTicks, ms, buffer, light, overlay); 27 | BlockPos pos = te.getBlockPos(); 28 | 29 | TrackTargetingBehaviour target = te.edgePoint; 30 | BlockPos targetPosition = target.getGlobalPosition(); 31 | Level level = te.getLevel(); 32 | BlockState trackState = level.getBlockState(targetPosition); 33 | Block block = trackState.getBlock(); 34 | 35 | if (!(block instanceof ITrackBlock)) 36 | return; 37 | 38 | ms.pushPose(); 39 | ms.translate(-pos.getX(), -pos.getY(), -pos.getZ()); 40 | RenderedTrackOverlayType type = RenderedTrackOverlayType.OBSERVER; 41 | TrackTargetingBehaviour.render(level, targetPosition, target.getTargetDirection(), target.getTargetBezier(), ms, 42 | buffer, light, overlay, type, 1); 43 | ms.popPose(); 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/mods.toml: -------------------------------------------------------------------------------- 1 | # This is an example mods.toml file. It contains the data relating to the loading mods. 2 | # There are several mandatory fields (#mandatory), and many more that are optional (#optional). 3 | # The overall format is standard TOML format, v0.5.0. 4 | # Note that there are a couple of TOML lists in this file. 5 | # Find more information on toml format here: https://github.com/toml-lang/toml 6 | # The name of the mod loader type to load - for regular FML @Mod mods it should be javafml 7 | modLoader = "javafml" #mandatory 8 | # A version range to match for said mod loader - for regular FML @Mod it will be the forge version 9 | loaderVersion = "[40,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. 10 | # The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. 11 | # Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. 12 | license = "EUPL 1.2" 13 | # A URL to refer people to when problems occur with this mod 14 | #issueTrackerURL="http://my.issue.tracker/" #optional 15 | # A list of mods - how many allowed here is determined by the individual mod loader 16 | [[mods]] #mandatory 17 | # The modid of the mod 18 | modId = "createcomputing" #mandatory 19 | # The version number of the mod - there's a few well known ${} variables useable here or just hardcode it 20 | # ${file.jarVersion} will substitute the value of the Implementation-Version as read from the mod's JAR file metadata 21 | # see the associated build.gradle script for how to populate this completely automatically during a build 22 | version = "${file.jarVersion}" #mandatory 23 | # A display name for the mod 24 | displayName = "Create: Computing" #mandatory 25 | # A URL to query for updates for this mod. See the JSON update specification 26 | #updateJSONURL="http://myurl.me/" #optional 27 | # A URL for the "homepage" for this mod, displayed in the mod UI 28 | displayURL="https://github.com/Sascha-T/create-computing" #optional 29 | # A file name (in the root of the mod JAR) containing a logo for display 30 | logoFile="logo.png" #optional 31 | # A text field displayed in the mod UI 32 | #credits="Thanks for this example mod goes to Java" #optional 33 | # A text field displayed in the mod UI 34 | authors = "Sascha_T" #optional 35 | # The description text for the mod (multi line!) (#mandatory) 36 | description = ''' 37 | An integration mod between Create and Computer Craft. 38 | Adds multiple features that open up more possibilities between the two mods, such as Computerised Display Sources and Targets. 39 | ''' 40 | # A dependency - use the . to indicate dependency for a specific modid. Dependencies are optional. 41 | [[dependencies.createcomputing]] #optional 42 | # the modid of the dependency 43 | modId = "forge" #mandatory 44 | # Does this dependency have to exist - if not, ordering below must be specified 45 | mandatory = true #mandatory 46 | # The version range of the dependency 47 | versionRange = "[41,)" #mandatory 48 | # An ordering relationship for the dependency - BEFORE or AFTER required if the relationship is not mandatory 49 | ordering = "NONE" 50 | # Side this dependency is applied on - BOTH, CLIENT or SERVER 51 | side = "BOTH" 52 | # Here's another dependency 53 | [[dependencies.createcomputing]] 54 | modId = "minecraft" 55 | mandatory = true 56 | # This version range declares a minimum of the current minecraft version up to but not including the next major version 57 | versionRange = "[1.19.2]" 58 | ordering = "NONE" 59 | side = "BOTH" 60 | [[dependencies.createcomputing]] 61 | modId = "create" 62 | mandatory = true 63 | versionRange = "[0.5.0c,)" 64 | [[dependencies.createcomputing]] 65 | modId = "computercraft" 66 | mandatory = true 67 | versionRange = "[1.100.0,)" 68 | -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/blockstates/computerized_display_source.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "facing=north": { 4 | "model": "createcomputing:block/computerized_display_source" 5 | }, 6 | "facing=east": { 7 | "model": "createcomputing:block/computerized_display_source", "y": 90 8 | }, 9 | "facing=south": { 10 | "model": "createcomputing:block/computerized_display_source", "y": 180 11 | }, 12 | "facing=west": { 13 | "model": "createcomputing:block/computerized_display_source", "y": 270 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/blockstates/computerized_display_target.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "facing=north": { 4 | "model": "createcomputing:block/computerized_display_target" 5 | }, 6 | "facing=east": { 7 | "model": "createcomputing:block/computerized_display_target", "y": 90 8 | }, 9 | "facing=south": { 10 | "model": "createcomputing:block/computerized_display_target", "y": 180 11 | }, 12 | "facing=west": { 13 | "model": "createcomputing:block/computerized_display_target", "y": 270 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/blockstates/computerized_redstone_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "": { 4 | "model": "createcomputing:block/computerized_redstone_link" 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/blockstates/train_network_observer.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "": { 4 | "model": "createcomputing:block/train_network_observer" 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/lang/en_gb.json: -------------------------------------------------------------------------------- 1 | { 2 | "itemGroup.createcomputing.tab": "Create: Computing", 3 | "createcomputing.display_source.computerized_display_source": "Computer Text", 4 | "block.createcomputing.computerized_display_source": "Computerized Display Source", 5 | "block.createcomputing.computerized_display_target": "Computerized Display Target", 6 | "block.createcomputing.computerized_redstone_link": "Computerized Redstone Link", 7 | "block.createcomputing.train_network_observer": "Train Network Observer" 8 | } 9 | -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "itemGroup.createcomputing.tab": "Create: Computing", 3 | "createcomputing.display_source.computerized_display_source": "Computer Text", 4 | "block.createcomputing.computerized_display_source": "Computerised Display Source", 5 | "block.createcomputing.computerized_display_target": "Computerised Display Target", 6 | "block.createcomputing.computerized_redstone_link": "Computerised Redstone Link", 7 | "block.createcomputing.train_network_observer": "Train Network Observer" 8 | } 9 | -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/models/block/computerized_display_source.json: -------------------------------------------------------------------------------- 1 | { 2 | "credit": "Made with Blockbench", 3 | "textures": { 4 | "0": "create:block/filtered_detector_front", 5 | "1": "create:block/brass_casing_side", 6 | "2": "create:block/brass_casing", 7 | "3": "create:block/brass_casing_inner", 8 | "particle": "create:block/filtered_detector_front" 9 | }, 10 | "elements": [ 11 | { 12 | "name": "connector", 13 | "from": [2, 2, -1], 14 | "to": [14, 14, 1], 15 | "faces": { 16 | "north": {"uv": [0, 0, 10, 10], "texture": "#0"}, 17 | "east": {"uv": [0, 0, 1, 10], "texture": "#0"}, 18 | "south": {"uv": [0, 0, 1, 12], "texture": "#missing"}, 19 | "west": {"uv": [0, 0, 1, 10], "texture": "#0"}, 20 | "up": {"uv": [0, 0, 12, 1], "texture": "#0"}, 21 | "down": {"uv": [0, 0, 12, 1], "texture": "#0"} 22 | } 23 | }, 24 | { 25 | "name": "bottom", 26 | "from": [0, 0, 0], 27 | "to": [16, 2, 16], 28 | "faces": { 29 | "north": {"uv": [0, 0, 16, 2], "texture": "#1"}, 30 | "east": {"uv": [0, 0, 16, 2], "texture": "#1"}, 31 | "south": {"uv": [0, 0, 16, 2], "texture": "#1"}, 32 | "west": {"uv": [0, 0, 16, 2], "texture": "#1"}, 33 | "up": {"uv": [0, 0, 16, 16], "texture": "#2"}, 34 | "down": {"uv": [0, 0, 16, 16], "texture": "#2"} 35 | } 36 | }, 37 | { 38 | "name": "top", 39 | "from": [0, 14, 0], 40 | "to": [16, 16, 16], 41 | "faces": { 42 | "north": {"uv": [0, 0, 16, 2], "texture": "#1"}, 43 | "east": {"uv": [0, 0, 16, 2], "texture": "#1"}, 44 | "south": {"uv": [0, 0, 16, 2], "texture": "#1"}, 45 | "west": {"uv": [0, 0, 16, 2], "texture": "#1"}, 46 | "up": {"uv": [0, 0, 16, 16], "texture": "#2"}, 47 | "down": {"uv": [0, 0, 16, 16], "texture": "#2"} 48 | } 49 | }, 50 | { 51 | "name": "center", 52 | "from": [1, 2, 1], 53 | "to": [15, 14, 15], 54 | "faces": { 55 | "north": {"uv": [0, 0, 14, 12], "texture": "#3"}, 56 | "east": {"uv": [0, 0, 14, 12], "texture": "#3"}, 57 | "south": {"uv": [0, 0, 14, 12], "texture": "#3"}, 58 | "west": {"uv": [0, 0, 14, 12], "texture": "#3"}, 59 | "up": {"uv": [0, 0, 14, 14], "texture": "#missing"}, 60 | "down": {"uv": [0, 0, 14, 14], "texture": "#missing"} 61 | } 62 | } 63 | ], 64 | "display": { 65 | "thirdperson_righthand": { 66 | "rotation": [75, 45, 0], 67 | "translation": [0, 2.5, 0], 68 | "scale": [0.375, 0.375, 0.375] 69 | }, 70 | "thirdperson_lefthand": { 71 | "rotation": [75, 45, 0], 72 | "translation": [0, 2.5, 0], 73 | "scale": [0.375, 0.375, 0.375] 74 | }, 75 | "firstperson_righthand": { 76 | "rotation": [0, 45, 0], 77 | "scale": [0.4, 0.4, 0.4] 78 | }, 79 | "firstperson_lefthand": { 80 | "rotation": [0, 225, 0], 81 | "scale": [0.4, 0.4, 0.4] 82 | }, 83 | "ground": { 84 | "translation": [0, 3, 0], 85 | "scale": [0.25, 0.25, 0.25] 86 | }, 87 | "gui": { 88 | "rotation": [30, 225, 0], 89 | "scale": [0.625, 0.625, 0.625] 90 | }, 91 | "fixed": { 92 | "scale": [0.5, 0.5, 0.5] 93 | } 94 | }, 95 | "groups": [ 96 | { 97 | "name": "VoxelShapes", 98 | "origin": [0, 0, 0], 99 | "color": 0, 100 | "nbt": "{}", 101 | "armAnimationEnabled": false, 102 | "children": [0, 1, 2, 3] 103 | } 104 | ] 105 | } -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/models/block/computerized_display_target.json: -------------------------------------------------------------------------------- 1 | { 2 | "credit": "Made with Blockbench", 3 | "textures": { 4 | "0": "create:block/filtered_detector_front", 5 | "1": "create:block/brass_casing", 6 | "3": "createcomputing:block/brass_casing_slab", 7 | "4": "create:block/redstone_antenna", 8 | "particle": "create:block/filtered_detector_front" 9 | }, 10 | "elements": [ 11 | { 12 | "name": "antenna", 13 | "from": [7, 13, 10], 14 | "to": [9, 18, 12], 15 | "faces": { 16 | "north": {"uv": [1, 1, 2, 4], "texture": "#4"}, 17 | "east": {"uv": [1, 1, 2, 4], "texture": "#4"}, 18 | "south": {"uv": [1, 1, 2, 4], "texture": "#4"}, 19 | "west": {"uv": [1, 1, 2, 4], "texture": "#4"}, 20 | "up": {"uv": [1, 1, 2, 2], "texture": "#4"}, 21 | "down": {"uv": [1, 9, 2, 10], "texture": "#4"} 22 | } 23 | }, 24 | { 25 | "name": "dish", 26 | "from": [5, 17, 8], 27 | "to": [11, 17, 14], 28 | "faces": { 29 | "north": {"uv": [0, 0, 4, 0], "texture": "#missing"}, 30 | "east": {"uv": [0, 0, 4, 0], "texture": "#missing"}, 31 | "south": {"uv": [0, 0, 4, 0], "texture": "#missing"}, 32 | "west": {"uv": [0, 0, 4, 0], "texture": "#missing"}, 33 | "up": {"uv": [4, 0, 9, 5], "texture": "#4"}, 34 | "down": {"uv": [4, 0, 9, 5], "texture": "#4"} 35 | } 36 | }, 37 | { 38 | "name": "front", 39 | "from": [0, 0, 0], 40 | "to": [16, 16, 5], 41 | "faces": { 42 | "north": {"uv": [0, 0, 16, 16], "texture": "#1"}, 43 | "east": {"uv": [0, 0, 5, 16], "texture": "#3"}, 44 | "south": {"uv": [0, 0, 16, 16], "texture": "#1"}, 45 | "west": {"uv": [0, 0, 5, 16], "texture": "#3"}, 46 | "up": {"uv": [0, 0, 5, 16], "rotation": 90, "texture": "#3"}, 47 | "down": {"uv": [0, 0, 5, 16], "rotation": 90, "texture": "#3"} 48 | } 49 | }, 50 | { 51 | "name": "connector", 52 | "from": [2, 2, -2], 53 | "to": [14, 14, 0], 54 | "faces": { 55 | "north": {"uv": [0, 0, 10, 10], "texture": "#0"}, 56 | "east": {"uv": [0, 0, 1, 10], "texture": "#0"}, 57 | "south": {"uv": [0, 0, 3, 3], "texture": "#0"}, 58 | "west": {"uv": [0, 0, 1, 10], "texture": "#0"}, 59 | "up": {"uv": [0, 0, 12, 1], "texture": "#0"}, 60 | "down": {"uv": [0, 0, 12, 1], "texture": "#0"} 61 | } 62 | }, 63 | { 64 | "name": "hind", 65 | "from": [2, 2, 5], 66 | "to": [14, 14, 10], 67 | "faces": { 68 | "north": {"uv": [0, 0, 16, 16], "texture": "#1"}, 69 | "east": {"uv": [0, 0, 5, 16], "texture": "#3"}, 70 | "south": {"uv": [0, 0, 16, 16], "texture": "#1"}, 71 | "west": {"uv": [0, 0, 5, 16], "texture": "#3"}, 72 | "up": {"uv": [0, 0, 5, 16], "rotation": 90, "texture": "#3"}, 73 | "down": {"uv": [0, 0, 5, 16], "rotation": 90, "texture": "#3"} 74 | } 75 | } 76 | ], 77 | "display": { 78 | "thirdperson_righthand": { 79 | "rotation": [75, -145, 0], 80 | "translation": [0, 2.5, 0], 81 | "scale": [0.375, 0.375, 0.375] 82 | }, 83 | "thirdperson_lefthand": { 84 | "rotation": [75, 45, 0], 85 | "translation": [0, 2.5, 0], 86 | "scale": [0.375, 0.375, 0.375] 87 | }, 88 | "firstperson_righthand": { 89 | "rotation": [0, 45, 0], 90 | "scale": [0.4, 0.4, 0.4] 91 | }, 92 | "firstperson_lefthand": { 93 | "rotation": [0, 225, 0], 94 | "scale": [0.4, 0.4, 0.4] 95 | }, 96 | "ground": { 97 | "translation": [0, 3, 0], 98 | "scale": [0.25, 0.25, 0.25] 99 | }, 100 | "gui": { 101 | "rotation": [30, 225, 0], 102 | "scale": [0.625, 0.625, 0.625] 103 | }, 104 | "fixed": { 105 | "scale": [0.5, 0.5, 0.5] 106 | } 107 | }, 108 | "groups": [ 109 | 0, 110 | 1, 111 | { 112 | "name": "VoxelShapes", 113 | "origin": [0, 0, 0], 114 | "color": 0, 115 | "nbt": "{}", 116 | "armAnimationEnabled": false, 117 | "children": [2, 3, 4] 118 | } 119 | ] 120 | } -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/models/block/computerized_redstone_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "credit": "Made with Blockbench", 3 | "textures": { 4 | "1": "create:block/brass_casing_side", 5 | "2": "create:block/brass_casing", 6 | "3": "create:block/redstone_antenna_powered", 7 | "4": "create:block/filtered_detector_front", 8 | "particle": "create:block/brass_casing_inner" 9 | }, 10 | "elements": [ 11 | { 12 | "name": "stick", 13 | "from": [8, 2, 2], 14 | "to": [9, 10, 3], 15 | "faces": { 16 | "north": {"uv": [1, 2, 2, 10], "texture": "#3"}, 17 | "east": {"uv": [1, 2, 2, 10], "texture": "#3"}, 18 | "south": {"uv": [1, 2, 2, 10], "texture": "#3"}, 19 | "west": {"uv": [1, 2, 2, 10], "texture": "#3"}, 20 | "up": {"uv": [2, 1, 3, 2], "texture": "#3"}, 21 | "down": {"uv": [0, 0, 1, 1], "texture": "#missing"} 22 | } 23 | }, 24 | { 25 | "from": [2, -1, 2], 26 | "to": [14, 0, 14], 27 | "faces": { 28 | "north": {"uv": [0, 0, 12, 1], "texture": "#4"}, 29 | "east": {"uv": [0, 0, 12, 1], "texture": "#4"}, 30 | "south": {"uv": [0, 0, 12, 1], "texture": "#4"}, 31 | "west": {"uv": [0, 0, 12, 1], "texture": "#4"}, 32 | "up": {"uv": [0, 0, 12, 12], "texture": "#missing"}, 33 | "down": {"uv": [0, 0, 10, 10], "texture": "#4"} 34 | } 35 | }, 36 | { 37 | "name": "stick", 38 | "from": [2, 2, 2], 39 | "to": [3, 10, 3], 40 | "faces": { 41 | "north": {"uv": [1, 2, 2, 10], "texture": "#3"}, 42 | "east": {"uv": [1, 2, 2, 10], "texture": "#3"}, 43 | "south": {"uv": [1, 2, 2, 10], "texture": "#3"}, 44 | "west": {"uv": [1, 2, 2, 10], "texture": "#3"}, 45 | "up": {"uv": [2, 1, 3, 2], "texture": "#3"}, 46 | "down": {"uv": [0, 0, 1, 1], "texture": "#missing"} 47 | } 48 | }, 49 | { 50 | "name": "dish", 51 | "from": [0, 9, 0], 52 | "to": [5, 9, 5], 53 | "faces": { 54 | "north": {"uv": [0, 0, 5, 0], "texture": "#missing"}, 55 | "east": {"uv": [0, 0, 5, 0], "texture": "#missing"}, 56 | "south": {"uv": [0, 0, 5, 0], "texture": "#missing"}, 57 | "west": {"uv": [0, 0, 5, 0], "texture": "#missing"}, 58 | "up": {"uv": [4, 0, 9, 5], "texture": "#3"}, 59 | "down": {"uv": [4, 0, 9, 5], "texture": "#3"} 60 | } 61 | }, 62 | { 63 | "name": "box", 64 | "from": [1, 0, 1], 65 | "to": [15, 2, 15], 66 | "faces": { 67 | "north": {"uv": [0, 0, 14, 2], "texture": "#1"}, 68 | "east": {"uv": [0, 0, 14, 2], "texture": "#1"}, 69 | "south": {"uv": [0, 0, 14, 2], "texture": "#1"}, 70 | "west": {"uv": [0, 0, 14, 2], "texture": "#1"}, 71 | "up": {"uv": [1, 1, 15, 15], "texture": "#2"}, 72 | "down": {"uv": [1, 1, 15, 15], "texture": "#2"} 73 | } 74 | } 75 | ], 76 | "display": { 77 | "thirdperson_righthand": { 78 | "rotation": [75, 45, 0], 79 | "translation": [0, 2.5, 0], 80 | "scale": [0.375, 0.375, 0.375] 81 | }, 82 | "thirdperson_lefthand": { 83 | "rotation": [75, 45, 0], 84 | "translation": [0, 2.5, 0], 85 | "scale": [0.375, 0.375, 0.375] 86 | }, 87 | "firstperson_righthand": { 88 | "rotation": [0, 45, 0], 89 | "scale": [0.4, 0.4, 0.4] 90 | }, 91 | "firstperson_lefthand": { 92 | "rotation": [0, 225, 0], 93 | "scale": [0.4, 0.4, 0.4] 94 | }, 95 | "ground": { 96 | "translation": [0, 3, 0], 97 | "scale": [0.25, 0.25, 0.25] 98 | }, 99 | "gui": { 100 | "rotation": [30, 225, 0], 101 | "scale": [0.625, 0.625, 0.625] 102 | }, 103 | "fixed": { 104 | "scale": [0.5, 0.5, 0.5] 105 | } 106 | }, 107 | "groups": [ 108 | { 109 | "name": "antenna 1", 110 | "origin": [0, 0, 0], 111 | "color": 0, 112 | "nbt": "{}", 113 | "armAnimationEnabled": false, 114 | "children": [0, 1] 115 | }, 116 | { 117 | "name": "antenna 1", 118 | "origin": [0, 0, 0], 119 | "color": 0, 120 | "nbt": "{}", 121 | "armAnimationEnabled": false, 122 | "children": [2, 3] 123 | }, 124 | { 125 | "name": "VoxelShapes", 126 | "origin": [0, 0, 0], 127 | "color": 0, 128 | "nbt": "{}", 129 | "armAnimationEnabled": false, 130 | "children": [4] 131 | } 132 | ] 133 | } -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/models/block/train_network_observer.json: -------------------------------------------------------------------------------- 1 | { 2 | "credit": "Made with Blockbench", 3 | "textures": { 4 | "0": "create:block/signal_box_top", 5 | "1": "createcomputing:block/train_network_observer_side", 6 | "2": "create:block/filtered_detector_front", 7 | "particle": "create:block/signal_box_top" 8 | }, 9 | "elements": [ 10 | { 11 | "name": "connector", 12 | "from": [2, 15, 2], 13 | "to": [14, 17, 14], 14 | "faces": { 15 | "north": {"uv": [10, 0, 12, 10], "rotation": 90, "texture": "#2"}, 16 | "east": {"uv": [10, 0, 12, 10], "rotation": 90, "texture": "#2"}, 17 | "south": {"uv": [10, 0, 12, 10], "rotation": 90, "texture": "#2"}, 18 | "west": {"uv": [10, 0, 12, 10], "rotation": 90, "texture": "#2"}, 19 | "up": {"uv": [0, 0, 10, 10], "texture": "#2"}, 20 | "down": {"uv": [0, 0, 12, 12], "texture": "#missing"} 21 | } 22 | }, 23 | { 24 | "name": "bottom", 25 | "from": [0, 0, 0], 26 | "to": [16, 2, 16], 27 | "faces": { 28 | "north": {"uv": [0, 14, 16, 16], "texture": "#1"}, 29 | "east": {"uv": [0, 14, 16, 16], "texture": "#1"}, 30 | "south": {"uv": [0, 14, 16, 16], "texture": "#1"}, 31 | "west": {"uv": [0, 14, 16, 16], "texture": "#1"}, 32 | "up": {"uv": [0, 0, 16, 16], "texture": "#0"}, 33 | "down": {"uv": [0, 0, 16, 16], "texture": "#missing"} 34 | } 35 | }, 36 | { 37 | "name": "top", 38 | "from": [0, 14, 0], 39 | "to": [16, 16, 16], 40 | "faces": { 41 | "north": {"uv": [0, 14, 16, 16], "texture": "#1"}, 42 | "east": {"uv": [0, 14, 16, 16], "texture": "#1"}, 43 | "south": {"uv": [0, 14, 16, 16], "texture": "#1"}, 44 | "west": {"uv": [0, 14, 16, 16], "texture": "#1"}, 45 | "up": {"uv": [0, 0, 16, 16], "texture": "#0"}, 46 | "down": {"uv": [0, 0, 16, 16], "texture": "#0"} 47 | } 48 | }, 49 | { 50 | "name": "center", 51 | "from": [1, 2, 1], 52 | "to": [15, 14, 15], 53 | "faces": { 54 | "north": {"uv": [1, 3, 15, 14], "texture": "#1"}, 55 | "east": {"uv": [1, 3, 15, 14], "texture": "#1"}, 56 | "south": {"uv": [1, 3, 15, 14], "texture": "#1"}, 57 | "west": {"uv": [1, 3, 15, 14], "texture": "#1"}, 58 | "up": {"uv": [0, 0, 14, 14], "texture": "#missing"}, 59 | "down": {"uv": [0, 0, 14, 14], "texture": "#missing"} 60 | } 61 | }, 62 | { 63 | "name": "pile_ne", 64 | "from": [15, 2, 0], 65 | "to": [16, 14, 1], 66 | "faces": { 67 | "north": {"uv": [0, 0, 1, 12], "texture": "#0"}, 68 | "east": {"uv": [0, 0, 1, 12], "texture": "#0"}, 69 | "south": {"uv": [0, 0, 1, 12], "texture": "#0"}, 70 | "west": {"uv": [0, 0, 1, 12], "texture": "#0"}, 71 | "up": {"uv": [0, 0, 1, 1], "texture": "#missing"}, 72 | "down": {"uv": [0, 0, 1, 1], "texture": "#missing"} 73 | } 74 | }, 75 | { 76 | "name": "pile_se", 77 | "from": [15, 2, 15], 78 | "to": [16, 14, 16], 79 | "faces": { 80 | "north": {"uv": [0, 0, 1, 12], "texture": "#0"}, 81 | "east": {"uv": [0, 0, 1, 12], "texture": "#0"}, 82 | "south": {"uv": [0, 0, 1, 12], "texture": "#0"}, 83 | "west": {"uv": [0, 0, 1, 12], "texture": "#0"}, 84 | "up": {"uv": [0, 0, 1, 1], "texture": "#missing"}, 85 | "down": {"uv": [0, 0, 1, 1], "texture": "#missing"} 86 | } 87 | }, 88 | { 89 | "name": "pile_sw", 90 | "from": [0, 2, 15], 91 | "to": [1, 14, 16], 92 | "faces": { 93 | "north": {"uv": [0, 0, 1, 12], "texture": "#0"}, 94 | "east": {"uv": [0, 0, 1, 12], "texture": "#0"}, 95 | "south": {"uv": [0, 0, 1, 12], "texture": "#0"}, 96 | "west": {"uv": [0, 0, 1, 12], "texture": "#0"}, 97 | "up": {"uv": [0, 0, 1, 1], "texture": "#missing"}, 98 | "down": {"uv": [0, 0, 1, 1], "texture": "#missing"} 99 | } 100 | }, 101 | { 102 | "name": "pile_nw", 103 | "from": [0, 2, 0], 104 | "to": [1, 14, 1], 105 | "faces": { 106 | "north": {"uv": [0, 0, 1, 12], "texture": "#0"}, 107 | "east": {"uv": [0, 0, 1, 12], "texture": "#0"}, 108 | "south": {"uv": [0, 0, 1, 12], "texture": "#0"}, 109 | "west": {"uv": [0, 0, 1, 12], "texture": "#0"}, 110 | "up": {"uv": [0, 0, 1, 1], "texture": "#missing"}, 111 | "down": {"uv": [0, 0, 1, 1], "texture": "#missing"} 112 | } 113 | } 114 | ], 115 | "display": { 116 | "thirdperson_righthand": { 117 | "rotation": [75, 45, 0], 118 | "translation": [0, 2.5, 0], 119 | "scale": [0.375, 0.375, 0.375] 120 | }, 121 | "thirdperson_lefthand": { 122 | "rotation": [75, 45, 0], 123 | "translation": [0, 2.5, 0], 124 | "scale": [0.375, 0.375, 0.375] 125 | }, 126 | "firstperson_righthand": { 127 | "rotation": [0, 45, 0], 128 | "scale": [0.4, 0.4, 0.4] 129 | }, 130 | "firstperson_lefthand": { 131 | "rotation": [0, 225, 0], 132 | "scale": [0.4, 0.4, 0.4] 133 | }, 134 | "ground": { 135 | "translation": [0, 3, 0], 136 | "scale": [0.25, 0.25, 0.25] 137 | }, 138 | "gui": { 139 | "rotation": [30, 225, 0], 140 | "scale": [0.625, 0.625, 0.625] 141 | }, 142 | "fixed": { 143 | "scale": [0.5, 0.5, 0.5] 144 | } 145 | }, 146 | "groups": [ 147 | { 148 | "name": "VoxelShapes", 149 | "origin": [0, 0, 0], 150 | "color": 0, 151 | "nbt": "{}", 152 | "armAnimationEnabled": false, 153 | "children": [] 154 | }, 155 | 0, 156 | 1, 157 | 2, 158 | 3, 159 | 4, 160 | 5, 161 | 6, 162 | 7 163 | ] 164 | } -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/models/item/computerized_display_source.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "createcomputing:block/computerized_display_source" 3 | } 4 | -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/models/item/computerized_display_target.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "createcomputing:block/computerized_display_target" 3 | } 4 | -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/models/item/computerized_redstone_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "createcomputing:block/computerized_redstone_link" 3 | } 4 | -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/models/item/train_network_observer.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "createcomputing:block/train_network_observer" 3 | } 4 | -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/textures/block/brass_casing_slab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sascha-T/create-computing/4621de59a1910e83705e5c26d41d8b2eb2b63b92/src/main/resources/assets/createcomputing/textures/block/brass_casing_slab.png -------------------------------------------------------------------------------- /src/main/resources/assets/createcomputing/textures/block/train_network_observer_side.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sascha-T/create-computing/4621de59a1910e83705e5c26d41d8b2eb2b63b92/src/main/resources/assets/createcomputing/textures/block/train_network_observer_side.png -------------------------------------------------------------------------------- /src/main/resources/createcomputing.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "package": "de.saschat.createcomputing.mixin", 5 | "compatibilityLevel": "JAVA_8", 6 | "refmap": "createcomputing.refmap.json", 7 | "client": [ 8 | "TrackTargetingClientMixin" 9 | ], 10 | "injectors": { 11 | "defaultRequire": 1 12 | }, 13 | "mixins": [] 14 | } 15 | -------------------------------------------------------------------------------- /src/main/resources/data/createcomputing/loot_tables/blocks/computerized_display_source.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:block", 3 | "pools": [ 4 | { 5 | "bonus_rolls": 0.0, 6 | "conditions": [ 7 | { 8 | "condition": "minecraft:survives_explosion" 9 | } 10 | ], 11 | "entries": [ 12 | { 13 | "type": "minecraft:item", 14 | "name": "createcomputing:computerized_display_source" 15 | } 16 | ], 17 | "rolls": 1.0 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/data/createcomputing/loot_tables/blocks/computerized_display_target.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:block", 3 | "pools": [ 4 | { 5 | "bonus_rolls": 0.0, 6 | "conditions": [ 7 | { 8 | "condition": "minecraft:survives_explosion" 9 | } 10 | ], 11 | "entries": [ 12 | { 13 | "type": "minecraft:item", 14 | "name": "createcomputing:computerized_display_target" 15 | } 16 | ], 17 | "rolls": 1.0 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/data/createcomputing/loot_tables/blocks/computerized_redstone_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:block", 3 | "pools": [ 4 | { 5 | "bonus_rolls": 0.0, 6 | "conditions": [ 7 | { 8 | "condition": "minecraft:survives_explosion" 9 | } 10 | ], 11 | "entries": [ 12 | { 13 | "type": "minecraft:item", 14 | "name": "createcomputing:computerized_redstone_link" 15 | } 16 | ], 17 | "rolls": 1.0 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/data/createcomputing/loot_tables/blocks/train_network_observer.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:block", 3 | "pools": [ 4 | { 5 | "bonus_rolls": 0.0, 6 | "conditions": [ 7 | { 8 | "condition": "minecraft:survives_explosion" 9 | } 10 | ], 11 | "entries": [ 12 | { 13 | "type": "minecraft:item", 14 | "name": "createcomputing:train_network_observer" 15 | } 16 | ], 17 | "rolls": 1.0 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/data/createcomputing/recipes/computerized_display_source.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | " T ", 5 | " BM", 6 | " E " 7 | ], 8 | "key": { 9 | "T": { 10 | "item": "minecraft:redstone_torch" 11 | }, 12 | "B": { 13 | "item": "create:brass_casing" 14 | }, 15 | "E": { 16 | "item": "create:electron_tube" 17 | }, 18 | "M": { 19 | "tag": "computercraft:wired_modem" 20 | } 21 | }, 22 | "result": { 23 | "item": "createcomputing:computerized_display_source" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/resources/data/createcomputing/recipes/computerized_display_target.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "GTG", 5 | " BM", 6 | " E " 7 | ], 8 | "key": { 9 | "G": { 10 | "item": "create:golden_sheet" 11 | }, 12 | "T": { 13 | "item": "minecraft:redstone_torch" 14 | }, 15 | "B": { 16 | "item": "create:brass_casing" 17 | }, 18 | "E": { 19 | "item": "create:electron_tube" 20 | }, 21 | "M": { 22 | "item": "computercraft:wired_modem" 23 | } 24 | }, 25 | "result": { 26 | "item": "createcomputing:computerized_display_target" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/resources/data/createcomputing/recipes/computerized_redstone_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | "GTG", 5 | "LBL", 6 | " E " 7 | ], 8 | "key": { 9 | "B": { 10 | "item": "create:brass_casing" 11 | }, 12 | "L": { 13 | "item": "create:redstone_link" 14 | }, 15 | "E": { 16 | "item": "create:electron_tube" 17 | }, 18 | "G": { 19 | "item": "create:golden_sheet" 20 | }, 21 | "T": { 22 | "item": "minecraft:redstone_torch" 23 | } 24 | }, 25 | "result": { 26 | "item": "createcomputing:computerized_redstone_link" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/resources/data/createcomputing/recipes/train_network_observer.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "minecraft:crafting_shaped", 3 | "pattern": [ 4 | " Y ", 5 | " RM", 6 | " E " 7 | ], 8 | "key": { 9 | "Y": { 10 | "item": "minecraft:ender_eye" 11 | }, 12 | "R": { 13 | "item": "create:railway_casing" 14 | }, 15 | "E": { 16 | "item": "create:electron_tube" 17 | }, 18 | "M": { 19 | "tag": "computercraft:wired_modem" 20 | } 21 | }, 22 | "result": { 23 | "item": "createcomputing:train_network_observer" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/resources/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sascha-T/create-computing/4621de59a1910e83705e5c26d41d8b2eb2b63b92/src/main/resources/logo.png -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "description": "createcomputing resources", 4 | "pack_format": 8, 5 | "forge:resource_pack_format": 8, 6 | "forge:data_pack_format": 9 7 | } 8 | } 9 | --------------------------------------------------------------------------------