diff --git a/.architectury-transformer/debug.log b/.architectury-transformer/debug.log new file mode 100644 index 00000000..9c6c5e2d --- /dev/null +++ b/.architectury-transformer/debug.log @@ -0,0 +1 @@ +[Architectury Transformer DEBUG] Closed File Systems for E:\Save\Minecraft_Workspace\VS-Addon-Template\common\build\libs\vs_addition-1.18.2-common-0.0.1-alpha.jar diff --git a/.checkstyle/checkstyle.xml b/.checkstyle/checkstyle.xml new file mode 100644 index 00000000..472fc16a --- /dev/null +++ b/.checkstyle/checkstyle.xml @@ -0,0 +1,348 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..be020b35 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,157 @@ +# Use the latest 2.1 version of CircleCI pipeline process engine. +# See: https://circleci.com/docs/2.0/configuration-reference +version: 2.1 + +orbs: + discord: antonioned/discord@0.1.0 + +executors: + java_large: + resource_class: large + docker: + - image: cimg/openjdk:17.0 + environment: + ORG_GRADLE_PROJECT_block_external_repositories: "true" + + +commands: + checkout_and_cache: + steps: + - checkout + - run: git submodule sync + - run: git submodule update --init + + - restore_cache: + keys: + - v1-gradle-home-{{ checksum "build.gradle" }}-{{ checksum "gradle.properties" }} + - v1-gradle-home + - restore_cache: + keys: + - v1-{{ checksum "build.gradle" }}-{{ checksum "gradle.properties" }} + save_artifacts: + parameters: + artifact_name: + type: string + default: eureka + version: + type: string + default: ${CIRCLE_SHA1} + steps: + # Rename artifacts to "forge.jar" and "fabric.jar" + - run: mkdir artifacts + - run: find ./forge/build/libs -regextype posix-extended -regex ".*/<< parameters.artifact_name >>(-[^-]+){2}.jar" -exec bash -c 'cp $0 ./artifacts/<< parameters.artifact_name >>-forge-<< parameters.version >>.jar' {} \; + - run: find ./fabric/build/libs -regextype posix-extended -regex ".*/<< parameters.artifact_name >>(-[^-]+){2}.jar" -exec bash -c 'cp $0 ./artifacts/<< parameters.artifact_name >>-fabric-<< parameters.version >>.jar' {} \; + + # Store artifacts + - store_artifacts: + path: artifacts + save_artifacts_and_generate_discord: + parameters: + artifact_name: + type: string + default: eureka + version: + type: string + default: ${CIRCLE_SHA1} + steps: + - save_artifacts: + artifact_name: << parameters.artifact_name >> + version: << parameters.version >> + - run: >- + echo 'export DISCORD_MSG=" + New version, **${CIRCLE_TAG}** | + [Download Forge](https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/${CIRCLE_NODE_INDEX}/artifacts/<< parameters.artifact_name >>-forge-<< parameters.version >>.jar) | + [Download Fabric](https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/${CIRCLE_NODE_INDEX}/artifacts/<< parameters.artifact_name >>-fabric-<< parameters.version >>.jar) + "' >> "$BASH_ENV" + save_gradle_cache: + steps: + - save_cache: + key: v1-gradle-home-{{ checksum "build.gradle" }}-{{ checksum "gradle.properties" }} + paths: + - ~/.gradle + - save_cache: + key: v1-gradle-{{ checksum "build.gradle" }}-{{ checksum "gradle.properties" }} + paths: + - .gradle + +# Define a job to be invoked later in a workflow. +# See: https://circleci.com/docs/2.0/configuration-reference/#jobs +jobs: + gradle_build: + executor: java_large + steps: + # Checkout repo + - checkout_and_cache + # Run build + - run: + name: "Build" + command: "./gradlew build --no-daemon --stacktrace" + - save_artifacts + - save_gradle_cache + + publish_to_maven: + executor: java_large + steps: + # Checkout repo + - checkout_and_cache + # Run build + - run: + name: "Build" + command: "./gradlew build publish --no-daemon --stacktrace" + deploy_to_curse: + executor: java_large + steps: + - checkout_and_cache + - run: echo 'export ORG_GRADLE_PROJECT_CustomReleaseVersion=${CIRCLE_TAG}' >> "$BASH_ENV" + - run: + command: "./gradlew build modrinth curseforge --no-daemon --stacktrace --continue" + notify_playtesters: + executor: java_large + steps: + # Checkout repo + - checkout_and_cache + # Run build + - run: + name: "Build" + command: "./gradlew build --no-daemon --stacktrace" + - save_artifacts_and_generate_discord + - discord/status: + success_message: ${DISCORD_MSG} + success_only: true + webhook: ${EUREKA_118_WEBHOOK} + +# Invoke jobs via workflows +# See: https://circleci.com/docs/2.0/configuration-reference/#workflows +workflows: + build: + jobs: + - gradle_build: + context: + - valkyrien_maven + + - notify_playtesters: + filters: + tags: + only: /^playtest.*/ + branches: + ignore: /.*/ + context: + - discord_webhooks + - valkyrien_maven + - deploy_to_curse: + filters: + tags: + only: /^release.*/ + branches: + ignore: /.*/ + context: + - curse_publishing + - valkyrien_maven + - publish_to_maven: + filters: + branches: + only: + - /.*\/main/ + context: + - valkyrien_maven + - github_maven diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000..f61ff7a1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,49 @@ +name: Bug report +description: Let us know about a bug that occurs without other mods +title: '' +labels: bug +assignees: [] +body: +- type: checkboxes + attributes: + label: This issue occurs when only Valkyrien Skies and addons are installed and no other mods + options: + - label: I have tested this issue and it occurs when no other mods are installed + required: true +- type: dropdown + attributes: + label: Minecraft Version + description: What Minecraft version does this issue occur on? + options: + - 1.16 + - 1.18 + - 1.19 + - 1.20​ + validations: + required: true +- type: dropdown + attributes: + label: Mod Loader + description: What mod loader does this issue occur on? + options: + - Forge + - Fabric + - Quilt + validations: + required: true +- type: textarea + attributes: + label: Issue description + description: Describe what happens, and what you expect to happen instead + validations: + required: true +- type: textarea + attributes: + label: Issue reproduction + description: Describe how to reproduce your issue + validations: + required: true +- type: textarea + attributes: + label: Logs + description: Go to `.minecraft/logs` and drag and drop the `latest.log` and `debug.log` file into this text field diff --git a/.github/ISSUE_TEMPLATE/compatibility_issue.yml b/.github/ISSUE_TEMPLATE/compatibility_issue.yml new file mode 100644 index 00000000..1fa48e82 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/compatibility_issue.yml @@ -0,0 +1,59 @@ +name: Compatibility issue +description: Let us know about a bug that occurs when another mod is installed +title: '<title>' +labels: compat +assignees: [] +body: +- type: markdown + attributes: + value: | + **Note:** do not report issues with the following mods: + - Optifine + - Magma Server (maybe try Arclight?) +- type: input + attributes: + label: Mod Name + description: The name of the mod that causes the compatibility issue + validations: + required: true +- type: checkboxes + attributes: + label: This issue occurs when only Valkyrien Skies, addons, and the mod I have specified are installed and no other mods + options: + - label: I have tested this issue and it occurs with only Valkyrien Skies, addons, and the mod I have specified +- type: dropdown + attributes: + label: Minecraft Version + description: What Minecraft version does this issue occur on? + options: + - 1.16 + - 1.18 + - 1.19 + validations: + required: true +- type: dropdown + attributes: + label: Mod Loader + description: What mod loader does this issue occur on? + options: + - Forge + - Fabric + - Quilt + validations: + required: true +- type: textarea + attributes: + label: Issue description + description: Describe what happens, and what you expect to happen instead + validations: + required: true +- type: textarea + attributes: + label: Issue reproduction + description: Describe how to reproduce your issue + validations: + required: true +- type: textarea + attributes: + label: Logs + description: Go to `.minecraft/logs` and drag and drop the `latest.log` and `debug.log` file into this text field diff --git a/.github/actions/setup-gradle/action.yml b/.github/actions/setup-gradle/action.yml new file mode 100644 index 00000000..1de13c81 --- /dev/null +++ b/.github/actions/setup-gradle/action.yml @@ -0,0 +1,20 @@ +name: "Setup Gradle" +description: "Installs java and restores gradle and build cache" + +runs: + using: "composite" + steps: + - name: Install JDK 17 (Temurin) + uses: actions/setup-java@v2 + with: + java-version: 17 + distribution: 'temurin' + + - name: Cache local .gradle and gradle packages + uses: actions/cache@v3 + with: + path: | + ~/.gradle/caches + **/.gradle + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle', '**/gradle.properties') }} + restore-keys: ${{ runner.os }}-gradle diff --git a/.github/workflows/build-1.18.x.yml b/.github/workflows/build-1.18.x.yml new file mode 100644 index 00000000..46464861 --- /dev/null +++ b/.github/workflows/build-1.18.x.yml @@ -0,0 +1,37 @@ +name: Build +on: + push: + branches: + - '1.18.x/*' + pull_request: + types: [ opened, synchronize, reopened ] +jobs: + validate-gradle: + name: "Validate Gradle wrapper" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: true # Clone with vs-core submodule + - uses: gradle/wrapper-validation-action@v1 + + test-server: + name: Test Server + strategy: + matrix: + serverType: [ 'fabric', 'forge' ] + runs-on: ubuntu-latest + timeout-minutes: 20 # Fail after 20 minutes + steps: + - name: Shallow Clone (--recurse-submodules) + uses: actions/checkout@v2 + with: + submodules: recursive + + - name: Setup Gradle & Caches + uses: "./.github/actions/setup-gradle" + + - name: Test Server + uses: ValkyrienSkies/Minecraft-Architectury-Testing@v1.9 + with: + serverType: ${{ matrix.serverType }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..12c0f22e --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +build/ +*.ipr +run/ +*.iws +out/ +*.iml +.gradle/ +output/ +bin/ +libs/ + +.classpath +.project +.idea/ +classes/ +.metadata +.vscode +.settings +*.launch + +.architectury-transformer +jars/cbcmodernwarfare*.jar \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 00000000..ea3748ad --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# VS Addition + +A little addon for VS2 ~~, Create and ComputerCraft~~. + +Before building, please download `cbcmodernwarfare-forge-1.18.2-0.0.4a.jar` and put it in `forge/jars`. \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 00000000..cbd1b908 --- /dev/null +++ b/build.gradle @@ -0,0 +1,145 @@ +plugins { + // Needed for Forge+Fabric + id "architectury-plugin" version "3.4.146" + id "dev.architectury.loom" version "1.3.355" apply false + // Kotlin + id "org.jetbrains.kotlin.jvm" version "1.9.10" apply false + // Kotlin linter + id "org.jlleitschuh.gradle.ktlint" version "10.3.0" + // Java linter + id "checkstyle" + + id 'com.matthewprenger.cursegradle' version '1.4.0' apply false + id "com.modrinth.minotaur" version "2.4.5" apply false +} + +// Determine the version +String platform = String.valueOf(loader_platform).toLowerCase() + +version = minecraft_version + "-" + platform + "-" + mod_version + +architectury { + minecraft = rootProject.minecraft_version +} + +subprojects { + apply plugin: "dev.architectury.loom" + // Apply checkstyle and ktlint to check the code style of every sub project + apply plugin: "org.jlleitschuh.gradle.ktlint" + apply plugin: "checkstyle" + apply plugin: "org.jetbrains.kotlin.jvm" + + loom { + silentMojangMappingsLicense() + } + + repositories { + maven { // Ritchie's Projectile Library + url = "https://maven.realrobotix.me/master/" + content { + includeGroup("com.rbasamoyai") // THIS IS IMPORTANT + } + } + maven { + name = "ParchmentMC" + url = "https://maven.parchmentmc.org" + } + maven { url = "https://maven.terraformersmc.com/releases/" } // Mod Menu + maven { + name = 'Kotlin for Forge' + url = 'https://thedarkcolour.github.io/KotlinForForge/' + } + maven { + name = 'tterrag maven' + url = 'https://maven.tterrag.com/' + } + maven { url = "https://api.modrinth.com/maven" } // LazyDFU, Suggestion Tweaker + maven { url = "https://maven.shedaniel.me/" } // Cloth Config, REI + maven { url = "https://mvn.devos.one/snapshots/" } // Fabric Create, Porting Lib, Forge Tags, Milk Lib + maven { url = "https://raw.githubusercontent.com/Fuzss/modresources/main/maven/" } // Forge Config API Port + maven { url = "https://maven.tterrag.com/" } // Registrate, Forge Create and Flywheel + maven { url = "https://maven.cafeteria.dev/releases" } // Fake Player API + maven { url = "https://maven.jamieswhiteshirt.com/libs-release" } // Reach Entity Attributes +// maven { url = "https://cursemaven.com" } //it has some issue, what's happened? + } + + dependencies { + minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" + // The following line declares the mojmap mappings, you may use other mappings as well + mappings(loom.layered { + officialMojangMappings() + parchment("org.parchmentmc.data:parchment-1.18.2:2022.09.04@zip") + }) + + implementation("org.joml:joml:1.10.4") { transitive = false } + implementation("org.joml:joml-primitives:1.10.0") { transitive = false } + } + + checkstyle { + // configure to use checkstyle v8.41 + toolVersion "8.41" + // Gradle shouldn't fail builds on checkstyle errors + ignoreFailures = true + // Checkstyle config file is in .checkstyle/checkstyle.xml + configFile = file("${rootDir}/.checkstyle/checkstyle.xml") + } + + // configure checkstyle, but different + // https://docs.gradle.org/current/userguide/checkstyle_plugin.html + tasks.withType(Checkstyle) { + reports { + // Do not output html reports + html.required = false + // Output xml reports + xml.required = true + } + } + + // configure ktlint + ktlint { + ignoreFailures = true + reporters { + // configure to output in checkstyle XML format + reporter "checkstyle" + } + } +} + +allprojects { + apply plugin: "java" + apply plugin: "architectury-plugin" + apply plugin: "maven-publish" + + archivesBaseName = rootProject.archives_base_name + version = rootProject.version + group = rootProject.maven_group + + repositories { + mavenLocal() + maven { + name = 'Kotlin for Forge' + url = 'https://thedarkcolour.github.io/KotlinForForge/' + content { includeGroup "thedarkcolour" } + } + maven { + name = "Valkyrien Skies Internal" + url = project.vs_maven_url ?: 'https://maven.valkyrienskies.org' + if (project.vs_maven_username && project.vs_maven_password) { + credentials { + username = project.vs_maven_username + password = project.vs_maven_password + } + } + } + } + + tasks.withType(JavaCompile) { + options.encoding = "UTF-8" + + options.release = 17 + } + + java { + withSourcesJar() + } +} \ No newline at end of file diff --git a/common/build.gradle b/common/build.gradle new file mode 100644 index 00000000..d8d50e93 --- /dev/null +++ b/common/build.gradle @@ -0,0 +1,93 @@ +architectury { + common(rootProject.enabled_platforms.split(",")) +} + +loom { + accessWidenerPath = file("src/main/resources/vs_addition.accesswidener") +} + +dependencies { + // We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies + // Do NOT use other classes from fabric loader + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + + // Architectury API + modApi "dev.architectury:architectury:${rootProject.architectury_version}" + + //Mixin Extras + compileOnly(annotationProcessor("io.github.llamalad7:mixinextras-common:0.3.5")) + + // Valkyrien Skies 2 + modApi("org.valkyrienskies:valkyrienskies-118-common:${rootProject.vs2_version}") + + // VS Core + compileOnly("org.valkyrienskies.core:api:${rootProject.vs_core_version}") + compileOnly("org.valkyrienskies.core:api-game:${rootProject.vs_core_version}") + compileOnly("org.valkyrienskies.core:util:${rootProject.vs_core_version}") + compileOnly("org.valkyrienskies.core:impl:${rootProject.vs_core_version}") + + api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10" + api "org.jetbrains.kotlin:kotlin-reflect:1.9.10" + + //Common create compats, + //We just use a version from a platform and hope the classes exist on both versions and mixins apply correctly + modCompileOnly("com.simibubi.create:create-fabric-${minecraft_version}:${create_fabric_version}") + { exclude group: 'com.github.AlphaMode', module: 'fakeconfigtoml' } + modCompileOnly("net.fabricmc.fabric-api:fabric-api:${fabric_api_version}") + modCompileOnly("com.jozufozu.flywheel:flywheel-fabric-${minecraft_version}:${flywheel_version_fabric}") + modCompileOnly("io.github.fabricators_of_create:Porting-Lib:${port_lib_version}+${minecraft_version}") + + // CBC + // Change the previous section + modImplementation("com.rbasamoyai:ritchiesprojectilelib:1.0.0-c5d3ea1+1.18.2-common") { transitive = false } + modCompileOnly("maven.modrinth:create-big-cannons:eLFsS1Ui") + + //ComputerCraft + modCompileOnly("maven.modrinth:cc-restitched:1.100.8+1.18.2") + + //Eureka + modCompileOnly("maven.modrinth:eureka:1.18.2-fabric-1.4.0-beta.1") + + //Clockwork + modCompileOnly("maven.modrinth:create-clockwork:8JdnD9wo") + + //Copycat+ + modCompileOnly("maven.modrinth:copycats:g3m9RPx3") +} + +publishing { + publications { + mavenCommon(MavenPublication) { + groupId = "org.valkyrienskies.eureka" + version = project.version + artifactId = rootProject.archives_base_name + "-" + project.name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + if (project.vs_maven_username && project.vs_maven_password) { + println "Publishing to VS Maven" + maven { + url = project.vs_maven_url + credentials { + username = project.vs_maven_username + password = project.vs_maven_password + } + } + } + // Add repositories to publish to here. + if (System.getenv("GITHUB_ACTOR") != null) { + println "Publishing to Github Packages" + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/ValkyrienSkies/Eureka") + credentials { + username = System.getenv("GITHUB_ACTOR") + password = System.getenv("GITHUB_TOKEN") + } + } + } + } +} \ No newline at end of file diff --git a/common/gradle.properties b/common/gradle.properties new file mode 100644 index 00000000..f148e470 --- /dev/null +++ b/common/gradle.properties @@ -0,0 +1,2 @@ +port_lib_version=1.2.677-beta +port_lib_hash=cca931b \ No newline at end of file diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/PeripheralCommon.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/PeripheralCommon.java new file mode 100644 index 00000000..2c5fae76 --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/PeripheralCommon.java @@ -0,0 +1,55 @@ +package io.github.xiewuzhiying.vs_addition.compats.computercraft; + + +import dan200.computercraft.api.peripheral.IPeripheral; +import io.github.xiewuzhiying.vs_addition.VSAdditionMod; +import io.github.xiewuzhiying.vs_addition.compats.computercraft.peripherals.CannonMountPeripheral; +import io.github.xiewuzhiying.vs_addition.compats.computercraft.peripherals.FlapBearingPeripheral; +import io.github.xiewuzhiying.vs_addition.compats.computercraft.peripherals.ShipHelmPeripheral; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.valkyrienskies.clockwork.ClockworkBlocks; +import org.valkyrienskies.clockwork.content.contraptions.flap.FlapBearingBlockEntity; +import org.valkyrienskies.eureka.EurekaBlocks; +import org.valkyrienskies.eureka.blockentity.ShipHelmBlockEntity; +import rbasamoyai.createbigcannons.cannon_control.cannon_mount.CannonMountBlockEntity; +import rbasamoyai.createbigcannons.index.CBCBlocks; + +import javax.annotation.Nullable; + +public class PeripheralCommon { + private boolean c(BlockState arg1, Block arg2) { return arg1.getBlock() == arg2; } + + @Nullable + public IPeripheral getPeripheralCommon(Level level, BlockPos blockPos, Direction direction){ + BlockState s = level.getBlockState(blockPos); + BlockEntity be = level.getBlockEntity(blockPos); + if (VSAdditionMod.getCBC_ACTIVE() && c(s, CBCBlocks.CANNON_MOUNT.get())) { + return new CannonMountPeripheral("cbc_cannon_mount", (CannonMountBlockEntity) be, level, blockPos, direction); + } else if (VSAdditionMod.getCLOCKWORK_ACTIVE() && c(s, ClockworkBlocks.FLAP_BEARING.get())) { + return new FlapBearingPeripheral("clockwork_flap_bearing", (FlapBearingBlockEntity) be, level, blockPos, direction); + } else if (VSAdditionMod.getEUREKA_ACTIVE() && c(s, EurekaBlocks.INSTANCE.getACACIA_SHIP_HELM().get())) { + return new ShipHelmPeripheral("eureka_ship_helm", (ShipHelmBlockEntity) be, level, blockPos, direction); + } else if (VSAdditionMod.getEUREKA_ACTIVE() && c(s, EurekaBlocks.INSTANCE.getCRIMSON_SHIP_HELM().get())) { + return new ShipHelmPeripheral("eureka_ship_helm", (ShipHelmBlockEntity) be, level, blockPos, direction); + } else if (VSAdditionMod.getEUREKA_ACTIVE() && c(s, EurekaBlocks.INSTANCE.getBIRCH_SHIP_HELM().get())) { + return new ShipHelmPeripheral("eureka_ship_helm", (ShipHelmBlockEntity) be, level, blockPos, direction); + } else if (VSAdditionMod.getEUREKA_ACTIVE() && c(s, EurekaBlocks.INSTANCE.getSPRUCE_SHIP_HELM().get())) { + return new ShipHelmPeripheral("eureka_ship_helm", (ShipHelmBlockEntity) be, level, blockPos, direction); + } else if (VSAdditionMod.getEUREKA_ACTIVE() && c(s, EurekaBlocks.INSTANCE.getWARPED_SHIP_HELM().get())) { + return new ShipHelmPeripheral("eureka_ship_helm", (ShipHelmBlockEntity) be, level, blockPos, direction); + } else if (VSAdditionMod.getEUREKA_ACTIVE() && c(s, EurekaBlocks.INSTANCE.getJUNGLE_SHIP_HELM().get())) { + return new ShipHelmPeripheral("eureka_ship_helm", (ShipHelmBlockEntity) be, level, blockPos, direction); + } else if (VSAdditionMod.getEUREKA_ACTIVE() && c(s, EurekaBlocks.INSTANCE.getOAK_SHIP_HELM().get())) { + return new ShipHelmPeripheral("eureka_ship_helm", (ShipHelmBlockEntity) be, level, blockPos, direction); + } else if (VSAdditionMod.getEUREKA_ACTIVE() && c(s, EurekaBlocks.INSTANCE.getDARK_OAK_SHIP_HELM().get())) { + return new ShipHelmPeripheral("eureka_ship_helm", (ShipHelmBlockEntity) be, level, blockPos, direction); + } else { + return null; + } + } +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/VSAdditionCC.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/VSAdditionCC.java new file mode 100644 index 00000000..1a22d506 --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/VSAdditionCC.java @@ -0,0 +1,12 @@ +package io.github.xiewuzhiying.vs_addition.compats.computercraft; + +import dan200.computercraft.shared.computer.core.ServerComputer; +import io.github.xiewuzhiying.vs_addition.compats.computercraft.apis.CryptoAPI; +import net.minecraft.server.level.ServerLevel; + + +public class VSAdditionCC{ + public static void applyCCAPIs(ServerComputer computer, ServerLevel level){ + computer.addAPI(new CryptoAPI()); + } +} \ No newline at end of file diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/apis/CryptoAPI.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/apis/CryptoAPI.java new file mode 100644 index 00000000..b9c90029 --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/apis/CryptoAPI.java @@ -0,0 +1,277 @@ +package io.github.xiewuzhiying.vs_addition.compats.computercraft.apis; + +import dan200.computercraft.api.lua.IArguments; +import dan200.computercraft.api.lua.ILuaAPI; +import dan200.computercraft.api.lua.LuaException; +import dan200.computercraft.api.lua.LuaFunction; + +import javax.crypto.*; +import javax.crypto.spec.GCMParameterSpec; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.security.spec.ECGenParameterSpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.HashMap; +import java.util.Map; + +public class CryptoAPI implements ILuaAPI { + + private final String ALGO = "AES_256/GCM/NoPadding"; + public final int AES_KEY_SIZE = 256; + public final int GCM_IV_LENGTH = 12; + public final int TLEN = 128; + + @Override + public String[] getNames() { + return new String[] {"cpt", "crypto"}; + } + + private Key generateKey(String key_string) throws NoSuchAlgorithmException, NoSuchProviderException { + KeyGenerator kg = KeyGenerator.getInstance("AES"); + SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "SUN"); + sr.setSeed(key_string.getBytes(StandardCharsets.UTF_8)); + kg.init(AES_KEY_SIZE, sr); + return kg.generateKey(); + } + + private String bytesToHexString(byte[] src) { + StringBuilder sb = new StringBuilder(); + if (src == null || src.length == 0) { + return null; + } + for (int j = 0; j < src.length; j++) { + int v = src[j] & 0xFF; + String hv = Integer.toHexString(v); + if (hv.length() < 2) { + sb.append(0); + } + sb.append(hv); + } + return sb.toString().toUpperCase(); + } + + private byte[] hexStringToBytes(String src) { + if (src == null || src.equals("")) { + return null; + } + src = src.toUpperCase(); + int len = src.length() / 2; + char[] hexChars = src.toCharArray(); + byte[] b = new byte[len]; + for (int i = 0; i < len; i++) { + int pos = i * 2; + b[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); + } + return b; + } + + private byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + + @LuaFunction + public final Object SHA512HASH(IArguments raw_data) { + MessageDigest sha512 = null; + try { + sha512 = MessageDigest.getInstance("SHA3-512"); + } catch (NoSuchAlgorithmException ignored) { + + } + try { + sha512.update(raw_data.getString(0).getBytes(StandardCharsets.UTF_8)); + } catch (LuaException ignored) { + + } + byte[] hash = sha512.digest(); + return bytesToHexString(hash); + } + + @LuaFunction + public final Object SHA256HASH(IArguments raw_data) throws LuaException { + MessageDigest sha256 = null; + try { + sha256 = MessageDigest.getInstance("SHA3-256"); + } catch (NoSuchAlgorithmException ignored) { + + } + sha256.update(raw_data.getString(0).getBytes(StandardCharsets.UTF_8)); + byte[] hash = sha256.digest(); + return bytesToHexString(hash); + } + + @LuaFunction + public final Object AESGCMEncrypt(IArguments args) throws LuaException { + Cipher cipher = null; + try { + cipher = Cipher.getInstance(ALGO); + } catch (NoSuchAlgorithmException | NoSuchPaddingException ignored) { + + } + byte[] iv = new byte[GCM_IV_LENGTH]; + SecureRandom sr = new SecureRandom(); + sr.nextBytes(iv); + try { + cipher.init(Cipher.ENCRYPT_MODE, generateKey(args.getString(1)), new GCMParameterSpec(TLEN, iv)); + } catch (InvalidKeyException | InvalidAlgorithmParameterException | NoSuchAlgorithmException | NoSuchProviderException ignored) { + + } + byte[] textBytes = args.getString(0).getBytes(StandardCharsets.UTF_8); + byte[] encryptBytes = new byte[0]; + try { + encryptBytes = cipher.doFinal(textBytes); + } catch (IllegalBlockSizeException | BadPaddingException ignored) { + + } + byte[] msg = new byte[GCM_IV_LENGTH + encryptBytes.length]; + System.arraycopy(iv, 0, msg, 0, GCM_IV_LENGTH); + System.arraycopy(encryptBytes, 0, msg, GCM_IV_LENGTH, encryptBytes.length); + return bytesToHexString(msg); + } + + @LuaFunction + public final Object AESGCMDecrypt(IArguments args) throws LuaException { + byte[] bytes = hexStringToBytes(args.getString(0)); + byte[] iv = new byte[GCM_IV_LENGTH]; + byte[] content = new byte[bytes.length - GCM_IV_LENGTH]; + System.arraycopy(bytes, 0, iv, 0, GCM_IV_LENGTH); + System.arraycopy(bytes, GCM_IV_LENGTH, content, 0, content.length); + Cipher cipher = null; + try { + cipher = Cipher.getInstance(ALGO); + } catch (NoSuchAlgorithmException | NoSuchPaddingException ignored) { + + } + GCMParameterSpec params = new GCMParameterSpec(TLEN, iv); + try { + cipher.init(Cipher.DECRYPT_MODE, generateKey(args.getString(1)), params); + } catch (InvalidKeyException | InvalidAlgorithmParameterException | NoSuchAlgorithmException | NoSuchProviderException ignored) { + + } + byte[] finals = new byte[0]; + try { + finals = cipher.doFinal(content); + } catch (IllegalBlockSizeException | BadPaddingException ignored) { + + } + return new String(finals, StandardCharsets.UTF_8); + } + + @LuaFunction + public final Map<String, String> GenECDHKeypair() { + KeyPairGenerator kpg = null; + try { + kpg = KeyPairGenerator.getInstance("EC"); + } catch (NoSuchAlgorithmException ignored) { + + } + ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1"); + try { + kpg.initialize(ecSpec); + } catch (InvalidAlgorithmParameterException ignored) { + + } + KeyPair kp = kpg.generateKeyPair(); + String pri = bytesToHexString(kp.getPrivate().getEncoded()); + String pub = bytesToHexString(kp.getPublic().getEncoded()); + Map<String, String> map = new HashMap<>(); + map.put("pri", pri); + map.put("pub", pub); + return map; + } + + @LuaFunction + public final Object GetECDHFinalKey(IArguments args) throws LuaException { + X509EncodedKeySpec x509 = new X509EncodedKeySpec(hexStringToBytes(args.getString(0))); + PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(hexStringToBytes(args.getString(1))); + KeyFactory kf = null; + try { + kf = KeyFactory.getInstance("EC"); + } catch (NoSuchAlgorithmException ignored) { + + } + PublicKey pk = null; + try { + pk = kf.generatePublic(x509); + } catch (InvalidKeySpecException ignored) { + + } + PrivateKey priK = null; + try { + priK = kf.generatePrivate(pkcs); + } catch (InvalidKeySpecException ignored) { + + } + KeyAgreement kam = null; + try { + kam = KeyAgreement.getInstance("ECDH"); + } catch (NoSuchAlgorithmException ignored) { + + } + try { + kam.init(priK); + } catch (InvalidKeyException ignored) { + + } + try { + kam.doPhase(pk, true); + } catch (InvalidKeyException ignored) { + + } + byte[] sSecret = kam.generateSecret(); + return bytesToHexString(sSecret); + } + + @LuaFunction + public final String MakeECDSASign(IArguments args) throws LuaException { + String input = args.getString(0); + String pri = args.getString(1); + String result = ""; + byte[] signedBytes; + try { + Signature sign = Signature.getInstance("SHA256withECDSA"); + PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(hexStringToBytes(pri)); + KeyFactory kf = KeyFactory.getInstance("EC"); + PrivateKey key = kf.generatePrivate(pkcs); + sign.initSign(key); + sign.update(input.getBytes()); + signedBytes = sign.sign(); + result = bytesToHexString(signedBytes); + } catch (Exception ignored) { + + } + return result; + } + + @LuaFunction + public final boolean CheckECDSASign(IArguments args) throws LuaException { + String input = args.getString(0); + String pub = args.getString(1); + String data = args.getString(2); + boolean result = false; + try { + Signature signature = Signature.getInstance("SHA256withECDSA"); + X509EncodedKeySpec x509 = new X509EncodedKeySpec(hexStringToBytes(pub)); + KeyFactory kf = KeyFactory.getInstance("EC"); + PublicKey key = kf.generatePublic(x509); + signature.initVerify(key); + signature.update(data.getBytes()); + result = signature.verify(hexStringToBytes(input)); + } catch (Exception ignored) { + } + return result; + } + + @LuaFunction + public final String Salt() { + byte[] b = new byte[0]; + try { + SecureRandom sr = SecureRandom.getInstanceStrong(); + b = new byte[128]; + sr.nextBytes(b); + } catch (NoSuchAlgorithmException ignored) { + } + return bytesToHexString(b); + } +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/apis/DeflateAPI.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/apis/DeflateAPI.java new file mode 100644 index 00000000..ca8fb441 --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/apis/DeflateAPI.java @@ -0,0 +1,40 @@ +//package io.github.xiewuzhiying.vs_addition.compats.computercraft.apis; +// +//import dan200.computercraft.api.lua.ILuaAPI; +//import dan200.computercraft.api.lua.LuaFunction; +// +//import java.io.UnsupportedEncodingException; +//import java.util.zip.DataFormatException; +//import java.util.zip.Deflater; +//import java.util.zip.Inflater; +// +//public class DeflateAPI implements ILuaAPI { +// @Override +// public String[] getNames() { +// return new String[] {"deflate"}; +// } +// +// @LuaFunction +// public final Object compression(String input) throws UnsupportedEncodingException { +// byte[] data = input.getBytes("UTF-8"); +// +// // Compress the bytes +// byte[] output = new byte[100]; +// Deflater compresser = new Deflater(); +// compresser.setInput(data); +// compresser.finish(); +// int compressedDataLength = compresser.deflate(output); +// compresser.end(); +// return output; +// } +// +// @LuaFunction +// public final Object decompression(String input, Double compressedDataLength) throws DataFormatException { +// Inflater decompresser = new Inflater(); +// decompresser.setInput(input.getBytes(), 0, (int) Math.floor(compressedDataLength)); +// byte[] result = new byte[100]; +// int resultLength = decompresser.inflate(result); +// decompresser.end(); +// return result; +// } +//} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/peripherals/CannonMountPeripheral.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/peripherals/CannonMountPeripheral.java new file mode 100644 index 00000000..7a1554eb --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/peripherals/CannonMountPeripheral.java @@ -0,0 +1,127 @@ +package io.github.xiewuzhiying.vs_addition.compats.computercraft.peripherals; + +import dan200.computercraft.api.lua.IArguments; +import dan200.computercraft.api.lua.LuaException; +import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.peripheral.IPeripheral; +import io.github.xiewuzhiying.vs_addition.mixin.createbigcannons.CannonMountBlockEntityAccessor; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import rbasamoyai.createbigcannons.cannon_control.cannon_mount.CannonMountBlockEntity; + +public class CannonMountPeripheral implements IPeripheral { + + private final String type ; + private final CannonMountBlockEntity tileEntity; + + private final Level level; + + private final BlockPos worldPosition; + + private final Direction direction; + + public CannonMountPeripheral(String type, CannonMountBlockEntity tileEntity, Level level, BlockPos blockPos, Direction direction) { + this.type = type; + this.tileEntity = tileEntity; + this.level = level; + this.worldPosition = blockPos; + this.direction = direction; + } + + @NotNull + @Override + public String getType() { + return type; + } + + @Override + public boolean equals(@Nullable IPeripheral iPeripheral) { + return iPeripheral == this; + } + + @Override + public Object getTarget() { + return this.tileEntity; + } + + + @LuaFunction(mainThread = true) + public final void setPitch(double value){ + if(this.isRunning()) + this.tileEntity.setPitch((float) value); + } + + @LuaFunction(mainThread = true) + public final void setYaw(double value){ + if(this.isRunning()) + this.tileEntity.setYaw((float) value); + } + + @LuaFunction(mainThread = true) + public final Object assemble(){ + if(!this.isRunning()) { + ((CannonMountBlockEntityAccessor) this.tileEntity).Assemble(); + return true; + } + return false; + } + + @LuaFunction(mainThread = true) + public final Object disassemble() { + if(this.isRunning()) { + this.tileEntity.disassemble(); + this.tileEntity.sendData(); + return true; + } + return false; + } + + @LuaFunction(mainThread = true) + public final void fire() { + if(this.isRunning()) { + this.tileEntity.getContraption().tryFiringShot(); + } + } + + @LuaFunction + public final boolean isRunning(){ + return this.tileEntity.isRunning(); + } + + @LuaFunction + public final Object getPitchOffset(IArguments partialTicks) throws LuaException { + if(this.isRunning()) { + double value = partialTicks.optDouble(0).orElse(0.0); + return (double) this.tileEntity.getPitchOffset((float) value); + } + return false; + } + + @LuaFunction + public final Object getYawOffset(IArguments partialTicks) throws LuaException { + if(this.isRunning()) { + double value = partialTicks.optDouble(0).orElse(0.0); + return (double) this.tileEntity.getYawOffset((float) value); + } + return false; + } + + @LuaFunction + public final Object getMaxDepress() { + if(this.isRunning()) { + return (double) ((CannonMountBlockEntityAccessor) this.tileEntity).GetMaxDepress(); + } + return false; + } + + @LuaFunction + public final Object getMaxElevate() { + if(this.isRunning()) { + return (double) ((CannonMountBlockEntityAccessor) this.tileEntity).GetMaxElevate(); + } + return false; + } +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/peripherals/FlapBearingPeripheral.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/peripherals/FlapBearingPeripheral.java new file mode 100644 index 00000000..01522f93 --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/peripherals/FlapBearingPeripheral.java @@ -0,0 +1,64 @@ +package io.github.xiewuzhiying.vs_addition.compats.computercraft.peripherals; + +import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.peripheral.IPeripheral; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.valkyrienskies.clockwork.content.contraptions.flap.FlapBearingBlockEntity; + +public class FlapBearingPeripheral implements IPeripheral { + + private final String type ; + private final FlapBearingBlockEntity tileEntity; + + public FlapBearingPeripheral(String type, FlapBearingBlockEntity tileEntity, Level level, BlockPos blockPos, Direction direction) { + this.type = type; + this.tileEntity = tileEntity; + } + + @NotNull + @Override + public String getType() { + return type; + } + + @Override + public boolean equals(@Nullable IPeripheral iPeripheral) { + return iPeripheral == this; + } + + @Override + public Object getTarget() { + return this.tileEntity; + } + + @LuaFunction(mainThread = true) + public final Object setAngle(double angle){ + if(this.tileEntity.isRunning()) { + this.tileEntity.setAngle((float) angle); + return true; + } + return false; + } + + @LuaFunction(mainThread = true) + public final Object assemble(){ + if(!this.tileEntity.isRunning()){ + this.tileEntity.assemble(); + return true; + } + return false; + } + + @LuaFunction(mainThread = true) + public final Object disassemble(){ + if(this.tileEntity.isRunning()){ + this.tileEntity.disassemble(); + return true; + } + return false; + } +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/peripherals/ShipHelmPeripheral.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/peripherals/ShipHelmPeripheral.java new file mode 100644 index 00000000..7bf5b863 --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/compats/computercraft/peripherals/ShipHelmPeripheral.java @@ -0,0 +1,52 @@ +package io.github.xiewuzhiying.vs_addition.compats.computercraft.peripherals; + +import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.peripheral.IPeripheral; +import io.github.xiewuzhiying.vs_addition.mixin.createbigcannons.CannonMountBlockEntityAccessor; +import io.github.xiewuzhiying.vs_addition.mixin.vs_eureka.ShipHelmBlockEntityAccessor; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.valkyrienskies.eureka.blockentity.ShipHelmBlockEntity; +import org.valkyrienskies.eureka.ship.EurekaShipControl; + +public class ShipHelmPeripheral implements IPeripheral { + + private final String type ; + private final ShipHelmBlockEntity tileEntity; + + private final EurekaShipControl shipControl; + + public ShipHelmPeripheral(String type, ShipHelmBlockEntity tileEntity, Level level, BlockPos blockPos, Direction direction) { + this.type = type; + this.tileEntity = tileEntity; + this.shipControl = ((ShipHelmBlockEntityAccessor)(Object) this.tileEntity).GetControl(); + } + + @NotNull + @Override + public String getType() { + return type; + } + + @Override + public boolean equals(@Nullable IPeripheral iPeripheral) { + return iPeripheral == this; + } + + @Override + public Object getTarget() { + return this.tileEntity; + } + + @LuaFunction(mainThread = true) + public final Object disassemble() { + if(this.tileEntity.getAssembled()){ + this.tileEntity.disassemble(); + return true; + } + return false; + } +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/content/wing/CopycatWingBlock.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/content/wing/CopycatWingBlock.java new file mode 100644 index 00000000..f519fb1c --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/content/wing/CopycatWingBlock.java @@ -0,0 +1,222 @@ +//package io.github.xiewuzhiying.vs_addition.content.wing; +// +//import com.copycatsplus.copycats.CCShapes; +//import com.copycatsplus.copycats.Copycats; +//import com.copycatsplus.copycats.content.copycat.base.CTWaterloggedCopycatBlock; +//import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement; +//import com.simibubi.create.content.schematics.requirement.ItemRequirement; +//import com.simibubi.create.foundation.utility.VoxelShaper; +//import net.minecraft.core.BlockPos; +//import net.minecraft.core.Direction; +//import net.minecraft.server.level.ServerLevel; +//import net.minecraft.world.InteractionResult; +//import net.minecraft.world.entity.player.Player; +//import net.minecraft.world.item.ItemStack; +//import net.minecraft.world.item.context.BlockPlaceContext; +//import net.minecraft.world.item.context.UseOnContext; +//import net.minecraft.world.level.BlockAndTintGetter; +//import net.minecraft.world.level.BlockGetter; +//import net.minecraft.world.level.Level; +//import net.minecraft.world.level.block.Block; +//import net.minecraft.world.level.block.Mirror; +//import net.minecraft.world.level.block.Rotation; +//import net.minecraft.world.level.block.entity.BlockEntity; +//import net.minecraft.world.level.block.state.BlockState; +//import net.minecraft.world.level.block.state.StateDefinition; +//import net.minecraft.world.level.block.state.properties.BlockStateProperties; +//import net.minecraft.world.level.block.state.properties.DirectionProperty; +//import net.minecraft.world.level.block.state.properties.IntegerProperty; +//import net.minecraft.world.level.pathfinder.PathComputationType; +//import net.minecraft.world.phys.shapes.CollisionContext; +//import net.minecraft.world.phys.shapes.VoxelShape; +//import org.jetbrains.annotations.NotNull; +//import org.jetbrains.annotations.Nullable; +// +//import java.util.List; +// +//import static net.minecraft.core.Direction.UP; +// +//public class CopycatWingBlock extends CTWaterloggedCopycatBlock implements ISpecialBlockItemRequirement { +// +// +// public static final DirectionProperty FACING = BlockStateProperties.FACING; +// public static final IntegerProperty LAYERS = BlockStateProperties.LAYERS; +// +// private static final VoxelShaper[] SHAPE_BY_LAYER = new VoxelShaper[]{CCShapes.EMPTY, CCShapes.LAYER_2PX, CCShapes.LAYER_4PX, CCShapes.LAYER_6PX, CCShapes.LAYER_8PX, CCShapes.LAYER_10PX, CCShapes.LAYER_12PX, CCShapes.LAYER_14PX, CCShapes.LAYER_16PX}; +// +// public CopycatWingBlock(Properties pProperties) { +// super(pProperties); +// registerDefaultState(defaultBlockState().setValue(FACING, UP)); +// } +// +// @Override +// public boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face, BlockPos fromPos, BlockPos toPos) { +// Direction facing = state.getValue(FACING); +// BlockState toState = reader.getBlockState(toPos); +// +// return !toState.is(this); +// } +// +// @Override +// public BlockState getStateForPlacement(BlockPlaceContext context) { +// BlockState stateForPlacement = super.getStateForPlacement(context); +// assert stateForPlacement != null; +// BlockPos blockPos = context.getClickedPos(); +// BlockState state = context.getLevel().getBlockState(blockPos); +// if (state.is(this)) { +// if (state.getValue(LAYERS) < 8) +// return state.cycle(LAYERS); +// else { +// Copycats.LOGGER.warn("Can't figure out where to place a layer! Please file an issue if you see this."); +// return state; +// } +// } else { +// return stateForPlacement.setValue(FACING, context.getNearestLookingDirection().getOpposite()); +// } +// } +// +// @SuppressWarnings("deprecation") +// @Override +// public boolean canBeReplaced(@NotNull BlockState pState, BlockPlaceContext pUseContext) { +// ItemStack itemstack = pUseContext.getItemInHand(); +// if (!itemstack.is(this.asItem())) return false; +// if (pState.getValue(LAYERS) == 8) return false; +// return pState.getValue(FACING) == pUseContext.getClickedFace(); +// } +// +// @Override +// public InteractionResult onSneakWrenched(BlockState state, UseOnContext context) { +// if (state.getValue(LAYERS) <= 1) +// return super.onSneakWrenched(state, context); +// +// Level world = context.getLevel(); +// BlockPos pos = context.getClickedPos(); +// Player player = context.getPlayer(); +// if (world instanceof ServerLevel serverLevel) { +// if (player != null && !player.isCreative()) { +// // Respect loot tables +// List<ItemStack> drops = Block.getDrops(state.setValue(LAYERS, 1), serverLevel, pos, world.getBlockEntity(pos), player, context.getItemInHand()); +// for (ItemStack drop : drops) { +// player.getInventory().placeItemBackInInventory(drop); +// } +// } +// BlockPos up = pos.relative(Direction.UP); +// // need to call updateShape before setBlock to schedule a tick for water +// world.setBlockAndUpdate(pos, state.setValue(LAYERS, state.getValue(LAYERS) - 1).updateShape(Direction.UP, world.getBlockState(up), world, pos, up)); +// playRemoveSound(world, pos); +// } +// return InteractionResult.SUCCESS; +// } +// +// @Override +// public ItemRequirement getRequiredItems(BlockState state, BlockEntity blockEntity) { +// return new ItemRequirement( +// ItemRequirement.ItemUseType.CONSUME, +// new ItemStack(asItem(), state.getValue(LAYERS)) +// ); +// } +// +// +// public boolean canConnectTexturesToward(BlockAndTintGetter reader, BlockPos fromPos, BlockPos toPos, BlockState state) { +// BlockState toState = reader.getBlockState(toPos); +// if (!toState.is(this)) return false; +// if (!state.is(this)) return false; +// Direction facing = state.getValue(FACING); +// +// if (toPos.equals(fromPos.relative(facing))) return false; +// +// BlockPos diff = fromPos.subtract(toPos); +// int coord = facing.getAxis().choose(diff.getX(), diff.getY(), diff.getZ()); +// +// if (!toState.is(this)) return coord != -facing.getAxisDirection().getStep(); +// +// if (isOccluded(state, toState, facing)) return true; +// if (toState.setValue(WATERLOGGED, false) == state.setValue(WATERLOGGED, false) && coord == 0) return true; +// return false; +// } +// +// @Nullable +// @Override +// public BlockState getConnectiveMaterial(BlockAndTintGetter reader, BlockState otherState, Direction face, BlockPos fromPos, BlockPos toPos) { +// return (canConnectTexturesToward(reader, fromPos, toPos, reader.getBlockState(fromPos)) ? getMaterial(reader, toPos) : null); +// } +// +// private static boolean isOccluded(BlockState state, BlockState other, Direction pDirection) { +// state = state.setValue(WATERLOGGED, false); +// other = other.setValue(WATERLOGGED, false); +// Direction facing = state.getValue(FACING); +// if (facing.getOpposite() == other.getValue(FACING) && pDirection == facing) return true; +// if (other.getValue(FACING) != facing) return false; +// return pDirection.getAxis() != facing.getAxis(); +// } +// +// @SuppressWarnings("deprecation") +// @Override +// public @NotNull BlockState rotate(BlockState state, Rotation rot) { +// return state.setValue(FACING, rot.rotate(state.getValue(FACING))); +// } +// +// @Override +// @SuppressWarnings("deprecation") +// public @NotNull BlockState mirror(BlockState state, Mirror mirrorIn) { +// return state.rotate(mirrorIn.getRotation(state.getValue(FACING))); +// } +// +// @SuppressWarnings("deprecation") +// @Override +// public boolean isPathfindable(@NotNull BlockState pState, @NotNull BlockGetter pLevel, @NotNull BlockPos pPos, @NotNull PathComputationType pType) { +// return switch (pType) { +// case LAND -> pState.getValue(LAYERS) < 5 && pState.getValue(FACING).equals(UP); +// default -> false; +// }; +// } +// +// @Override +// protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> pBuilder) { +// super.createBlockStateDefinition(pBuilder.add(FACING).add(LAYERS)); +// } +// +// @SuppressWarnings("deprecation") +// @Override +// public @NotNull VoxelShape getShape(BlockState pState, @NotNull BlockGetter pLevel, @NotNull BlockPos pPos, @NotNull CollisionContext pContext) { +// return SHAPE_BY_LAYER[pState.getValue(LAYERS)].get(pState.getValue(FACING)); +// } +// +// +// public boolean supportsExternalFaceHiding(BlockState state) { +// return true; +// } +// +// +// public boolean hidesNeighborFace(BlockGetter level, BlockPos pos, BlockState state, BlockState neighborState, Direction dir) { +// Direction facing = state.getValue(FACING); +// int layers = state.getValue(LAYERS); +// if (state.is(this) == neighborState.is(this)) { +// Direction neighborFacing = neighborState.getValue(FACING); +// int neighborLayers = neighborState.getValue(LAYERS); +// if (getMaterial(level, pos).skipRendering(getMaterial(level, pos.relative(dir)), dir.getOpposite())) { +// return neighborFacing == facing && neighborLayers == layers || // cull the sides if two copycats of the same height are next to each other +// // cull if both sides have a square block face +// (neighborFacing == facing.getOpposite() || neighborLayers == 8) && facing == dir.getOpposite() || +// (neighborFacing == facing.getOpposite() || layers == 8) && neighborFacing == dir || +// layers == 8 && neighborLayers == 8; +// } +// } +// return false; +// } +// +// @Override +// public @NotNull VoxelShape getOcclusionShape(BlockState pState, BlockGetter level, BlockPos pos) { +// return SHAPE_BY_LAYER[pState.getValue(LAYERS)].get(pState.getValue(FACING)); +// } +// +// @Override +// public boolean useShapeForLightOcclusion(BlockState state) { +// return true; +// } +// +// @Override +// public float getShadeBrightness(BlockState state, BlockGetter level, BlockPos pos) { +// return state.getValue(LAYERS) == 8 ? 0.2f : 1.0f; +// } +//} \ No newline at end of file diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/content/wing/CopycatWingModel.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/content/wing/CopycatWingModel.java new file mode 100644 index 00000000..d6218f2b --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/content/wing/CopycatWingModel.java @@ -0,0 +1,50 @@ +//package io.github.xiewuzhiying.vs_addition.content.wing; +// +//import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart; +//import com.copycatsplus.copycats.content.copycat.layer.CopycatLayerBlock; +//import net.minecraft.core.Direction; +//import net.minecraft.world.level.block.state.BlockState; +// +//import static com.copycatsplus.copycats.content.copycat.base.model.QuadHelper.CopycatRenderContext; +//import static com.copycatsplus.copycats.content.copycat.base.model.QuadHelper.MutableCullFace.*; +//import static com.copycatsplus.copycats.content.copycat.base.model.QuadHelper.assemblePiece; +// +// +//public class CopycatWingModel implements SimpleCopycatPart { +// +// @Override +// public void emitCopycatQuads(BlockState state, CopycatRenderContext context, BlockState material) { +// int layer = state.getValue(CopycatWingBlock.LAYERS); +// Direction facing = state.getValue(CopycatWingBlock.FACING); +// +// if (facing.getAxis().isVertical()) { +// boolean flipY = facing == Direction.DOWN; +// assemblePiece( +// context, 0, flipY, +// vec3(0, 0, 0), +// aabb(16, layer, 16), +// cull(UP) +// ); +// assemblePiece( +// context, 0, flipY, +// vec3(0, layer, 0), +// aabb(16, layer, 16).move(0, 16 - layer, 0), +// cull(DOWN) +// ); +// } else { +// int rot = (int) facing.toYRot(); +// assemblePiece( +// context, rot, false, +// vec3(0, 0, 0), +// aabb(16, 16, layer), +// cull(SOUTH) +// ); +// assemblePiece( +// context, rot, false, +// vec3(0, 0, layer), +// aabb(16, 16, layer).move(0, 0, 16 - layer), +// cull(NORTH) +// ); +// } +// } +//} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/computercraft/MixinRedstoneAPI.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/computercraft/MixinRedstoneAPI.java new file mode 100644 index 00000000..87150e41 --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/computercraft/MixinRedstoneAPI.java @@ -0,0 +1,31 @@ +package io.github.xiewuzhiying.vs_addition.mixin.computercraft; + +import dan200.computercraft.api.lua.LuaException; +import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.core.apis.IAPIEnvironment; +import dan200.computercraft.core.apis.RedstoneAPI; +import dan200.computercraft.core.computer.ComputerSide; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(RedstoneAPI.class) +public abstract class MixinRedstoneAPI{ + + @Mutable + @Final + @Shadow + private final IAPIEnvironment environment; + + public MixinRedstoneAPI(IAPIEnvironment environment) { + this.environment = environment; + } + + @LuaFunction( { "setAnalogOutput2", "setAnalogueOutput2" } ) + public final void setAnalogOutput2( ComputerSide side, int value ) throws LuaException + { + if( value < 0) throw new LuaException( "Expected number in range >= 0" ); + environment.setOutput( side, value ); + } +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/computercraft/MixinWirelessModemPeripheral.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/computercraft/MixinWirelessModemPeripheral.java new file mode 100644 index 00000000..27c4bcfa --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/computercraft/MixinWirelessModemPeripheral.java @@ -0,0 +1,37 @@ +package io.github.xiewuzhiying.vs_addition.mixin.computercraft; + +import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; +import dan200.computercraft.shared.peripheral.modem.ModemPeripheral; +import dan200.computercraft.shared.peripheral.modem.ModemState; +import dan200.computercraft.shared.peripheral.modem.wireless.WirelessModemPeripheral; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyVariable; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.valkyrienskies.core.api.ships.Ship; +import org.valkyrienskies.mod.common.VSGameUtilsKt; + +@Mixin(WirelessModemPeripheral.class) +public abstract class MixinWirelessModemPeripheral extends ModemPeripheral{ + protected MixinWirelessModemPeripheral(ModemState state) { + super(state); + } + @Inject( + method = "getRange", + at = @At( + value = "INVOKE", + target = "Ldan200/computercraft/shared/peripheral/modem/wireless/WirelessModemPeripheral;getPosition()Lnet/minecraft/world/phys/Vec3;", + shift = At.Shift.AFTER + ) + ) + public void whenPositionOnShip(CallbackInfoReturnable<Double> cir, @Local Level world, @Local LocalRef<Vec3> position){ + final Ship ship = VSGameUtilsKt.getShipManagingPos(world, position.get()); + if (ship != null) { + position.set(VSGameUtilsKt.toWorldCoordinates(ship, position.get())); + } + } +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/copycats/MixinCopycatLayerBlock.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/copycats/MixinCopycatLayerBlock.java new file mode 100644 index 00000000..934a11d1 --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/copycats/MixinCopycatLayerBlock.java @@ -0,0 +1,94 @@ +//package io.github.xiewuzhiying.vs_addition.mixin.copycats; +// +// +//import com.copycatsplus.copycats.content.copycat.base.CTWaterloggedCopycatBlock; +//import com.copycatsplus.copycats.content.copycat.layer.CopycatLayerBlock; +//import com.simibubi.create.AllBlocks; +//import com.simibubi.create.content.schematics.requirement.ISpecialBlockItemRequirement; +//import kotlin.Pair; +//import net.minecraft.core.BlockPos; +//import net.minecraft.world.item.context.BlockPlaceContext; +//import net.minecraft.world.level.BlockGetter; +//import net.minecraft.world.level.Level; +//import net.minecraft.world.level.block.Block; +//import net.minecraft.world.level.block.Blocks; +//import net.minecraft.world.level.block.state.BlockState; +//import net.minecraft.world.phys.AABB; +//import net.minecraft.world.phys.shapes.CollisionContext; +//import net.minecraft.world.phys.shapes.VoxelShape; +//import org.jetbrains.annotations.NotNull; +//import org.spongepowered.asm.mixin.Mixin; +//import org.spongepowered.asm.mixin.Shadow; +//import org.spongepowered.asm.mixin.Unique; +//import org.spongepowered.asm.mixin.injection.At; +//import org.spongepowered.asm.mixin.injection.Inject; +//import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +//import org.valkyrienskies.core.apigame.world.ShipWorldCore; +//import org.valkyrienskies.core.apigame.world.chunks.BlockType; +//import org.valkyrienskies.mod.common.BlockStateInfo; +//import org.valkyrienskies.mod.common.VSGameUtilsKt; +//import org.valkyrienskies.mod.common.util.DimensionIdProvider; +// +//import java.util.List; +// +//@Mixin(CopycatLayerBlock.class) +//public abstract class MixinCopycatLayerBlock extends CTWaterloggedCopycatBlock implements ISpecialBlockItemRequirement { +// @Shadow @NotNull public abstract @NotNull VoxelShape getShape(BlockState pState, @NotNull BlockGetter pLevel, @NotNull BlockPos pPos, @NotNull CollisionContext pContext); +// +// public MixinCopycatLayerBlock(Properties pProperties) { +// super(pProperties); +// } +// +// @Unique +// private static double vs_addition$calculateTotalVolume(final List<AABB> aabbList) { +// double totalVolume = 0.0; +// +// for (final AABB aabb : aabbList) { +// final double width = aabb.maxX - aabb.minX; +// final double height = aabb.maxY - aabb.minY; +// final double depth = aabb.maxZ - aabb.minZ; +// totalVolume += width * height * depth; +// } +// +// return totalVolume; +// } +// +// @Inject( +// method = "canBeReplaced", +// at = @At( +// value = "INVOKE", +// target = "Lnet/minecraft/world/level/block/state/BlockState;getValue(Lnet/minecraft/world/level/block/state/properties/Property;)Ljava/lang/Comparable;", +// shift = At.Shift.BEFORE +// ) +// +// ) +// public void canBeReplaced(BlockState pState, BlockPlaceContext pUseContext, CallbackInfoReturnable<Boolean> cir){ +// final Level pLevel = pUseContext.getLevel(); +// final BlockPos pPos = pUseContext.getClickedPos(); +// +// +// final ShipWorldCore shipObjectWorld = VSGameUtilsKt.getShipObjectWorld(pLevel); +// +// final Double multiplier = vs_addition$calculateTotalVolume(pState.getShape(pLevel, pPos).toAabbs()); +// +// final Double Oldmass; +// +// final Double Newmass; +// +// final Pair<Double, BlockType> State = BlockStateInfo.INSTANCE.get(pLevel.getBlockState(pPos)); +// +// final Pair<Double, BlockType> NewState = BlockStateInfo.INSTANCE.get(pState); +// +// if(getBlockEntity(pLevel, pPos).getMaterial()== AllBlocks.COPYCAT_BASE.getDefaultState()) { +// Oldmass = BlockStateInfo.INSTANCE.get(Blocks.AIR.defaultBlockState()).getFirst(); +// Newmass = BlockStateInfo.INSTANCE.get(Blocks.AIR.defaultBlockState()).getFirst(); +// } +// else { +// Oldmass = BlockStateInfo.INSTANCE.get(getBlockEntity(pLevel, pPos).getMaterial()).getFirst() * multiplier; +// Newmass = BlockStateInfo.INSTANCE.get(getBlockEntity(pLevel, pPos).getMaterial()).getFirst() * multiplier; +// } +// +// shipObjectWorld.onSetBlock(pPos.getX(), pPos.getY(), pPos.getZ(), ((DimensionIdProvider) pLevel).getDimensionId(), State.getSecond(), NewState.getSecond(), Oldmass, NewState.getFirst()); +// } +// +//} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/create/MixinCopycatBlock.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/create/MixinCopycatBlock.java new file mode 100644 index 00000000..81bde22d --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/create/MixinCopycatBlock.java @@ -0,0 +1,78 @@ +package io.github.xiewuzhiying.vs_addition.mixin.create; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.decoration.copycat.CopycatBlock; +import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; +import com.simibubi.create.content.equipment.wrench.IWrenchable; +import com.simibubi.create.foundation.block.IBE; +import java.util.List; +import kotlin.Pair; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.valkyrienskies.core.apigame.world.ShipWorldCore; +import org.valkyrienskies.core.apigame.world.chunks.BlockType; +import org.valkyrienskies.mod.common.BlockStateInfo; +import org.valkyrienskies.mod.common.VSGameUtilsKt; +import org.valkyrienskies.mod.common.util.DimensionIdProvider; + +@Mixin(CopycatBlock.class) +public abstract class MixinCopycatBlock extends Block implements IBE<CopycatBlockEntity>, IWrenchable { + + @Unique + private static double vs_addition$calculateTotalVolume(final List<AABB> aabbList) { + double totalVolume = 0.0; + + for (final AABB aabb : aabbList) { + final double width = aabb.maxX - aabb.minX; + final double height = aabb.maxY - aabb.minY; + final double depth = aabb.maxZ - aabb.minZ; + totalVolume += width * height * depth; + } + + return totalVolume; + } + + public MixinCopycatBlock(final Properties pProperties) { + super(pProperties); + } + + @Inject( + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/level/Level;removeBlockEntity(Lnet/minecraft/core/BlockPos;)V", + shift = Shift.BEFORE + ), + method = "onRemove" + ) + public void onRemove(final BlockState pState, final Level pLevel, final BlockPos pPos, final BlockState pNewState, final boolean pIsMoving, + final CallbackInfo ci) { + + + final ShipWorldCore shipObjectWorld = VSGameUtilsKt.getShipObjectWorld(pLevel); + + final Double multiplier = vs_addition$calculateTotalVolume(pState.getShape(pLevel, pPos).toAabbs()); + + final Double Oldmass; + + final Pair<Double, BlockType> State = BlockStateInfo.INSTANCE.get(pState); + + final Pair<Double, BlockType> NewState = BlockStateInfo.INSTANCE.get(pNewState); + + if(getBlockEntity(pLevel, pPos).getMaterial()== AllBlocks.COPYCAT_BASE.getDefaultState()) + Oldmass = BlockStateInfo.INSTANCE.get(Blocks.AIR.defaultBlockState()).getFirst(); + else + Oldmass = BlockStateInfo.INSTANCE.get(getBlockEntity(pLevel, pPos).getMaterial()).getFirst() * multiplier; + + shipObjectWorld.onSetBlock(pPos.getX(), pPos.getY(), pPos.getZ(), ((DimensionIdProvider) pLevel).getDimensionId(), State.getSecond(), NewState.getSecond(), Oldmass, NewState.getFirst()); + } +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/create/MixinCopycatBlockEntity.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/create/MixinCopycatBlockEntity.java new file mode 100644 index 00000000..a490bbff --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/create/MixinCopycatBlockEntity.java @@ -0,0 +1,91 @@ +package io.github.xiewuzhiying.vs_addition.mixin.create; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity; +import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; +import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; +import java.util.List; +import kotlin.Pair; +import net.minecraft.core.BlockPos; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.AABB; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.valkyrienskies.core.apigame.world.ShipWorldCore; +import org.valkyrienskies.core.apigame.world.chunks.BlockType; +import org.valkyrienskies.mod.common.BlockStateInfo; +import org.valkyrienskies.mod.common.VSGameUtilsKt; +import org.valkyrienskies.mod.common.util.DimensionIdProvider; + +@Mixin(CopycatBlockEntity.class) +public abstract class MixinCopycatBlockEntity extends SmartBlockEntity{ + + @Shadow + private BlockState material; + @Shadow + private ItemStack consumedItem; + + @Unique + private static double vs_addition$calculateTotalVolume(final List<AABB> aabbList) { + double totalVolume = 0.0; + + for (final AABB aabb : aabbList) { + final double width = aabb.maxX - aabb.minX; + final double height = aabb.maxY - aabb.minY; + final double depth = aabb.maxZ - aabb.minZ; + totalVolume += width * height * depth; + } + + return totalVolume; + } + + + public MixinCopycatBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) { + super(type, pos, state); + material = AllBlocks.COPYCAT_BASE.getDefaultState(); + consumedItem = ItemStack.EMPTY; + } + + @Inject( + method = "setMaterial", + at = @At( + value = "INVOKE", + target = "Lcom/simibubi/create/content/decoration/copycat/CopycatBlockEntity;getBlockState()Lnet/minecraft/world/level/block/state/BlockState;", + shift = Shift.AFTER + ) + ) + public void setMaterial(final BlockState blockState, final CallbackInfo ci) { + + final ShipWorldCore shipObjectWorld = VSGameUtilsKt.getShipObjectWorld(level); + + final Double multiplier = vs_addition$calculateTotalVolume(getBlockState().getShape(level, worldPosition).toAabbs()); + + final Pair<Double, BlockType> State = BlockStateInfo.INSTANCE.get(getBlockState()); + + final Double Oldmass; + + final Double Newmass; + + if(material==AllBlocks.COPYCAT_BASE.getDefaultState()) + Oldmass = BlockStateInfo.INSTANCE.get(Blocks.AIR.defaultBlockState()).getFirst(); + else + Oldmass = BlockStateInfo.INSTANCE.get(material).getFirst() * multiplier; + + + if(blockState==AllBlocks.COPYCAT_BASE.getDefaultState()) + Newmass = BlockStateInfo.INSTANCE.get(Blocks.AIR.defaultBlockState()).getFirst(); + else + Newmass = BlockStateInfo.INSTANCE.get(blockState).getFirst() * multiplier; + + shipObjectWorld.onSetBlock(worldPosition.getX(), worldPosition.getY(), worldPosition.getZ(), ((DimensionIdProvider) level).getDimensionId(), State.getSecond(), State.getSecond(), Oldmass, Newmass); + } + +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/create/MixinDisplayLinkBlockItem.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/create/MixinDisplayLinkBlockItem.java new file mode 100644 index 00000000..c5bbdceb --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/create/MixinDisplayLinkBlockItem.java @@ -0,0 +1,105 @@ +package io.github.xiewuzhiying.vs_addition.mixin.create; + +import com.simibubi.create.content.redstone.displayLink.DisplayLinkBlockItem; +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.infrastructure.config.AllConfigs; +import net.minecraft.ChatFormatting; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Vec3i; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.util.Mth; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.valkyrienskies.mod.common.VSGameUtilsKt; + + +@Mixin(DisplayLinkBlockItem.class) +public abstract class MixinDisplayLinkBlockItem extends BlockItem { + + public MixinDisplayLinkBlockItem(Block block, Properties properties) { + super(block, properties); + } + + @Unique + private Level vs_addition$accessedLevel; + + @Override + public InteractionResult useOn(UseOnContext pContext) { + ItemStack stack = pContext.getItemInHand(); + BlockPos pos = pContext.getClickedPos(); + Level level = pContext.getLevel(); + BlockState state = level.getBlockState(pos); + Player player = pContext.getPlayer(); + vs_addition$accessedLevel = level; + + if (player == null) + return InteractionResult.FAIL; + + if (player.isShiftKeyDown() && stack.hasTag()) { + if (level.isClientSide) + return InteractionResult.SUCCESS; + player.displayClientMessage(Lang.translateDirect("display_link.clear"), true); + stack.setTag(null); + return InteractionResult.SUCCESS; + } + + if (!stack.hasTag()) { + if (level.isClientSide) + return InteractionResult.SUCCESS; + CompoundTag stackTag = stack.getOrCreateTag(); + stackTag.put("SelectedPos", NbtUtils.writeBlockPos(pos)); + player.displayClientMessage(Lang.translateDirect("display_link.set"), true); + stack.setTag(stackTag); + return InteractionResult.SUCCESS; + } + + CompoundTag tag = stack.getTag(); + CompoundTag teTag = new CompoundTag(); + + BlockPos selectedPos = NbtUtils.readBlockPos(tag.getCompound("SelectedPos")); + BlockPos placedPos = pos.relative(pContext.getClickedFace(), state.getMaterial() + .isReplaceable() ? 0 : 1); + + if (!selectedPos.closerThan(placedPos, AllConfigs.server().logistics.displayLinkRange.get())) { + player.displayClientMessage(Lang.translateDirect("display_link.too_far") + .withStyle(ChatFormatting.RED), true); + return InteractionResult.FAIL; + } + + teTag.put("TargetOffset", NbtUtils.writeBlockPos(selectedPos.subtract(placedPos))); + tag.put("BlockEntityTag", teTag); + + InteractionResult useOn = super.useOn(pContext); + if (level.isClientSide || useOn == InteractionResult.FAIL) + return useOn; + + ItemStack itemInHand = player.getItemInHand(pContext.getHand()); + if (!itemInHand.isEmpty()) + itemInHand.setTag(null); + player.displayClientMessage(Lang.translateDirect("display_link.success") + .withStyle(ChatFormatting.GREEN), true); + return useOn; + } + + @Redirect( + method = "useOn", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/core/BlockPos;closerThan(Lnet/minecraft/core/Vec3i;D)Z" + ) + ) + public boolean closerThan(BlockPos instance, Vec3i pVector, double pDistance) { + return VSGameUtilsKt.squaredDistanceBetweenInclShips(vs_addition$accessedLevel, instance.getX(), instance.getY(), instance.getZ(), pVector.getX(), pVector.getY(), pVector.getZ()) < Mth.square(pDistance); + } +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/create/MixinTreeFertilizerItem.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/create/MixinTreeFertilizerItem.java new file mode 100644 index 00000000..f988448d --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/create/MixinTreeFertilizerItem.java @@ -0,0 +1,123 @@ +package io.github.xiewuzhiying.vs_addition.mixin.create; + +import com.simibubi.create.content.equipment.TreeFertilizerItem; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.tags.BlockTags; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.item.BoneMealItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.BonemealableBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import org.jetbrains.annotations.NotNull; +import org.joml.Vector3d; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.valkyrienskies.core.api.ships.ServerShip; +import org.valkyrienskies.core.api.world.ServerShipWorld; +import org.valkyrienskies.core.apigame.VSCore; +import org.valkyrienskies.core.util.datastructures.DenseBlockPosSet; +import org.valkyrienskies.eureka.util.ShipAssembler; +import org.valkyrienskies.mod.common.ValkyrienSkiesMod; +import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; +import org.valkyrienskies.core.apigame.ShipTeleportData; +import org.valkyrienskies.core.impl.game.ShipTeleportDataImpl; + +import java.util.Collections; +import java.util.List; + +import static org.valkyrienskies.mod.common.assembly.ShipAssemblyKt.createNewShipWithBlocks; + +@Mixin(TreeFertilizerItem.class) +public abstract class MixinTreeFertilizerItem extends Item { + + public MixinTreeFertilizerItem(Properties properties) { + super(properties); + } + + /** + * @author xiewuzhiying + * @reason try to use ship instead of create new dimension + */ + @Overwrite + public @NotNull InteractionResult useOn(UseOnContext context) { + BlockState state = context.getLevel() + .getBlockState(context.getClickedPos()); + Block block = state.getBlock(); + if (block instanceof BonemealableBlock bonemealableBlock && state.is(BlockTags.SAPLINGS)) { + + if (context.getLevel().isClientSide) { + BoneMealItem.addGrowthParticles(context.getLevel(), context.getClickedPos(), 100); + return InteractionResult.SUCCESS; + } + + BlockPos saplingPos = context.getClickedPos(); + ServerLevel world = (ServerLevel) context.getLevel(); + +// DenseBlockPosSet set = new DenseBlockPosSet(); +// for (BlockPos pos : BlockPos.betweenClosed(-1, 0, -1, 1, 0, 1)) { +// if (context.getLevel() +// .getBlockState(saplingPos.offset(pos)) +// .getBlock() == block) { +// set.add(saplingPos.offset(pos).getX(), saplingPos.offset(pos).getY(), saplingPos.offset(pos).getZ()); +// set.add(saplingPos.offset(pos).getX(), saplingPos.offset(pos).getY() - 1, saplingPos.offset(pos).getZ()); +// } +// } +// +// ServerShip ship = createNewShipWithBlocks(saplingPos, set, world); +// ship.setStatic(true); +// +// Vector3d position = ship.getTransform().getWorldToShip().transformPosition(VectorConversionsMCKt.toJOMLD(saplingPos)); + + bonemealableBlock.performBonemeal(world, world.getRandom(), + saplingPos , + withStage(state, 1)); + +// ShipAssembler.INSTANCE.unfillShip(world, ship, Direction.SOUTH, new BlockPos(position.x, position.y, position.z), saplingPos); +// ValkyrienSkiesMod.vsCore.deleteShips((ServerShipWorld) ship, Collections.singletonList(ship)); + +// for (BlockPos pos : world.ket) { +// BlockPos actualPos = pos.offset(saplingPos).below(10); +// BlockState newState = world.getBlockState(pos); +// +// // Don't replace Bedrock +// if (context.getLevel() +// .getBlockState(actualPos) +// .getDestroySpeed(context.getLevel(), actualPos) == -1) +// continue; +// // Don't replace solid blocks with leaves +// if (!newState.isRedstoneConductor(world, pos) +// && !context.getLevel() +// .getBlockState(actualPos) +// .getCollisionShape(context.getLevel(), actualPos) +// .isEmpty()) +// continue; +// +// context.getLevel() +// .setBlockAndUpdate(actualPos, newState); +// } + + if (context.getPlayer() != null && !context.getPlayer() + .isCreative()) + context.getItemInHand() + .shrink(1); + return InteractionResult.SUCCESS; + + } + + return super.useOn(context); + } + + @Shadow + private BlockState withStage(BlockState original, int stage) { + if (!original.hasProperty(BlockStateProperties.STAGE)) + return original; + return original.setValue(BlockStateProperties.STAGE, 1); + } +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/createbigcannons/CannonMountBlockEntityAccessor.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/createbigcannons/CannonMountBlockEntityAccessor.java new file mode 100644 index 00000000..2883c1de --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/createbigcannons/CannonMountBlockEntityAccessor.java @@ -0,0 +1,18 @@ +package io.github.xiewuzhiying.vs_addition.mixin.createbigcannons; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; +import rbasamoyai.createbigcannons.cannon_control.cannon_mount.CannonMountBlockEntity; + +@Mixin(CannonMountBlockEntity.class) +public interface CannonMountBlockEntityAccessor { + + @Invoker("assemble") + void Assemble(); + + @Invoker("getMaxDepress") + float GetMaxDepress(); + + @Invoker("getMaxElevate") + float GetMaxElevate(); +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/createbigcannons/MixinMountedAutoCannonContraption.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/createbigcannons/MixinMountedAutoCannonContraption.java new file mode 100644 index 00000000..c56555a0 --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/createbigcannons/MixinMountedAutoCannonContraption.java @@ -0,0 +1,82 @@ +package io.github.xiewuzhiying.vs_addition.mixin.createbigcannons; + +import io.github.xiewuzhiying.vs_addition.mixin.minecraft.EntityAccessor; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; +import net.minecraft.world.phys.Vec3; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.valkyrienskies.core.api.ships.ServerShip; +import org.valkyrienskies.mod.common.VSGameUtilsKt; +import org.valkyrienskies.mod.common.util.GameTickForceApplier; +import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; +import rbasamoyai.createbigcannons.cannon_control.contraption.AbstractMountedCannonContraption; +import rbasamoyai.createbigcannons.cannon_control.contraption.ItemCannon; +import rbasamoyai.createbigcannons.cannon_control.contraption.MountedAutocannonContraption; +import rbasamoyai.createbigcannons.cannon_control.contraption.PitchOrientedContraptionEntity; +import rbasamoyai.createbigcannons.munitions.autocannon.AbstractAutocannonProjectile; + +@Mixin(MountedAutocannonContraption.class) +public abstract class MixinMountedAutoCannonContraption extends AbstractMountedCannonContraption implements ItemCannon { + + @Unique + private float vs_addition$speed; + + @Unique + private Vec3 vs_addition$vector; + + @Unique + private ServerShip vs_addition$serverShip; + + @Inject( + method = "fireShot", + at = @At( + value = "INVOKE", + target = "Lrbasamoyai/createbigcannons/munitions/autocannon/AbstractAutocannonProjectile;shoot(DDDFF)V", + shift = At.Shift.BEFORE + ) + ) + public void getShip(ServerLevel level, PitchOrientedContraptionEntity entity, CallbackInfo ci){ + vs_addition$serverShip = (ServerShip) VSGameUtilsKt.getShipObjectManagingPos(entity.level, VectorConversionsMCKt.toJOML(entity.getAnchorVec())); + } + + + @Redirect( + method = "fireShot", + at = @At( + value = "INVOKE", + target = "Lrbasamoyai/createbigcannons/munitions/autocannon/AbstractAutocannonProjectile;shoot(DDDFF)V" + ) + ) + public void shoot(AbstractAutocannonProjectile<?> instance, double x, double y, double z, float velocity, float inaccuracy) { + vs_addition$speed = velocity; + vs_addition$vector = (new Vec3(x, y, z)).normalize().add(((EntityAccessor) instance).getRandom().nextGaussian() * 0.007499999832361937 * (double)inaccuracy, ((EntityAccessor)(Object) instance).getRandom().nextGaussian() * 0.007499999832361937 * (double)inaccuracy, ((EntityAccessor) instance).getRandom().nextGaussian() * 0.007499999832361937 * (double)inaccuracy).scale(velocity).add(VectorConversionsMCKt.toMinecraft(vs_addition$serverShip.getVelocity())); + Vec3 vec3 = vs_addition$vector.add(VectorConversionsMCKt.toMinecraft(vs_addition$serverShip.getVelocity())); + instance.setDeltaMovement(vec3); + double d = vs_addition$vector.horizontalDistance(); + instance.setYRot((float)(Mth.atan2(vs_addition$vector.x, vs_addition$vector.z) * 57.2957763671875)); + instance.setXRot((float)(Mth.atan2(vs_addition$vector.y, d) * 57.2957763671875)); + instance.yRotO = instance.getYRot(); + instance.xRotO = instance.getXRot(); + } + + @Inject( + method = "fireShot", + at = @At( + value = "INVOKE", + target = "Lrbasamoyai/createbigcannons/munitions/autocannon/AbstractAutocannonProjectile;shoot(DDDFF)V", + shift = At.Shift.AFTER + ) + ) + public void recoil(ServerLevel level, PitchOrientedContraptionEntity entity, CallbackInfo ci) { + if (vs_addition$serverShip != null) { + GameTickForceApplier applier = vs_addition$serverShip.getAttachment(GameTickForceApplier.class); + double recoilForce = vs_addition$speed * 1250.0d; + applier.applyInvariantForceToPos(vs_addition$serverShip.getTransform().getShipToWorldRotation().transform(VectorConversionsMCKt.toJOML(vs_addition$vector).negate().normalize()).mul(recoilForce), VectorConversionsMCKt.toJOML(entity.getAnchorVec().add(0.5, 0.5, 0.5)).sub(vs_addition$serverShip.getTransform().getPositionInShip())); + } + } +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/createbigcannons/MixinMountedBigCannonContraption.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/createbigcannons/MixinMountedBigCannonContraption.java new file mode 100644 index 00000000..6978b483 --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/createbigcannons/MixinMountedBigCannonContraption.java @@ -0,0 +1,80 @@ +package io.github.xiewuzhiying.vs_addition.mixin.createbigcannons; + +import io.github.xiewuzhiying.vs_addition.mixin.minecraft.EntityAccessor; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; +import net.minecraft.world.phys.Vec3; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.valkyrienskies.core.api.ships.ServerShip; +import org.valkyrienskies.mod.common.VSGameUtilsKt; +import org.valkyrienskies.mod.common.util.GameTickForceApplier; +import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; +import rbasamoyai.createbigcannons.cannon_control.contraption.AbstractMountedCannonContraption; +import rbasamoyai.createbigcannons.cannon_control.contraption.MountedBigCannonContraption; +import rbasamoyai.createbigcannons.cannon_control.contraption.PitchOrientedContraptionEntity; +import rbasamoyai.createbigcannons.munitions.big_cannon.AbstractBigCannonProjectile; + +@Mixin(MountedBigCannonContraption.class) +public abstract class MixinMountedBigCannonContraption extends AbstractMountedCannonContraption { + + @Unique + private float vs_addition$speed; + + @Unique + private Vec3 vs_addition$vector; + + @Unique + private ServerShip vs_addition$serverShip; + + @Inject( + method = "fireShot", + at = @At( + value = "INVOKE", + target = "Lrbasamoyai/createbigcannons/munitions/big_cannon/AbstractBigCannonProjectile;shoot(DDDFF)V", + shift = At.Shift.BEFORE + ) + ) + public void getShip(ServerLevel level, PitchOrientedContraptionEntity entity, CallbackInfo ci){ + vs_addition$serverShip = (ServerShip) VSGameUtilsKt.getShipObjectManagingPos(entity.level, VectorConversionsMCKt.toJOML(entity.getAnchorVec())); + } + + @Redirect( + method = "fireShot", + at = @At( + value = "INVOKE", + target = "Lrbasamoyai/createbigcannons/munitions/big_cannon/AbstractBigCannonProjectile;shoot(DDDFF)V" + ) + ) + public void shoot(AbstractBigCannonProjectile<?> instance, double x, double y, double z, float velocity, float inaccuracy) { + vs_addition$speed = velocity; + vs_addition$vector = (new Vec3(x, y, z)).normalize().add(((EntityAccessor) instance).getRandom().nextGaussian() * 0.007499999832361937 * (double)inaccuracy, ((EntityAccessor) instance).getRandom().nextGaussian() * 0.007499999832361937 * (double)inaccuracy, ((EntityAccessor)(Object) instance).getRandom().nextGaussian() * 0.007499999832361937 * (double)inaccuracy).scale(velocity); + Vec3 vec3 = vs_addition$vector.add(VectorConversionsMCKt.toMinecraft(vs_addition$serverShip.getVelocity())); + instance.setDeltaMovement(vec3); + double d = vs_addition$vector.horizontalDistance(); + instance.setYRot((float)(Mth.atan2(vs_addition$vector.x, vs_addition$vector.z) * 57.2957763671875)); + instance.setXRot((float)(Mth.atan2(vs_addition$vector.y, d) * 57.2957763671875)); + instance.yRotO = instance.getYRot(); + instance.xRotO = instance.getXRot(); + } + + @Inject( + method = "fireShot", + at = @At( + value = "INVOKE", + target = "Lrbasamoyai/createbigcannons/munitions/big_cannon/AbstractBigCannonProjectile;shoot(DDDFF)V", + shift = At.Shift.AFTER + ) + ) + public void recoil(ServerLevel level, PitchOrientedContraptionEntity entity, CallbackInfo ci) { + if (vs_addition$serverShip != null) { + GameTickForceApplier applier = vs_addition$serverShip.getAttachment(GameTickForceApplier.class); + double recoilForce = vs_addition$speed * 50000.0d; + applier.applyInvariantForceToPos(vs_addition$serverShip.getTransform().getShipToWorldRotation().transform(VectorConversionsMCKt.toJOML(vs_addition$vector).negate().normalize()).mul(recoilForce), VectorConversionsMCKt.toJOML(entity.getAnchorVec().add(0.5, 0.5, 0.5)).sub(vs_addition$serverShip.getTransform().getPositionInShip())); + } + } +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/minecraft/EntityAccessor.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/minecraft/EntityAccessor.java new file mode 100644 index 00000000..eebf3ec0 --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/minecraft/EntityAccessor.java @@ -0,0 +1,14 @@ +package io.github.xiewuzhiying.vs_addition.mixin.minecraft; + + +import net.minecraft.world.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +import java.util.Random; + +@Mixin(Entity.class) +public interface EntityAccessor { + @Accessor("random") + Random getRandom(); +} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/vs_eureka/EurekaShipControlAccessor.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/vs_eureka/EurekaShipControlAccessor.java new file mode 100644 index 00000000..6f030a44 --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/vs_eureka/EurekaShipControlAccessor.java @@ -0,0 +1,13 @@ +//package io.github.xiewuzhiying.vs_addition.mixin.vs_eureka; +// +//import org.spongepowered.asm.mixin.Mixin; +//import org.spongepowered.asm.mixin.gen.Invoker; +//import org.valkyrienskies.eureka.ship.EurekaShipControl; +// +//@Mixin(EurekaShipControl.class) +//public interface EurekaShipControlAccessor { +// @Invoker("<ControlData>") +// public class data aaControlData(){ +// +// } +//} diff --git a/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/vs_eureka/ShipHelmBlockEntityAccessor.java b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/vs_eureka/ShipHelmBlockEntityAccessor.java new file mode 100644 index 00000000..e65cf114 --- /dev/null +++ b/common/src/main/java/io/github/xiewuzhiying/vs_addition/mixin/vs_eureka/ShipHelmBlockEntityAccessor.java @@ -0,0 +1,12 @@ +package io.github.xiewuzhiying.vs_addition.mixin.vs_eureka; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; +import org.valkyrienskies.eureka.blockentity.ShipHelmBlockEntity; +import org.valkyrienskies.eureka.ship.EurekaShipControl; + +@Mixin(ShipHelmBlockEntity.class) +public interface ShipHelmBlockEntityAccessor { + @Invoker("getControl") + EurekaShipControl GetControl(); +} diff --git a/common/src/main/kotlin/io/github/xiewuzhiying/vs_addition/VSAdditionBlockEntityTypes.kt b/common/src/main/kotlin/io/github/xiewuzhiying/vs_addition/VSAdditionBlockEntityTypes.kt new file mode 100644 index 00000000..0884dc10 --- /dev/null +++ b/common/src/main/kotlin/io/github/xiewuzhiying/vs_addition/VSAdditionBlockEntityTypes.kt @@ -0,0 +1,27 @@ +//package io.github.xiewuzhiying.vs_addition +// +//import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity +//import com.tterrag.registrate.builders.BlockEntityBuilder +//import net.minecraft.core.BlockPos +//import net.minecraft.world.level.block.entity.BlockEntityType +//import net.minecraft.world.level.block.state.BlockState +// +//class VSAdditionBlockEntityTypes { +// private val REGISTRATE = VSAdditionMod.getRegistrate() +// +// val COPYCAT = REGISTRATE.blockEntity<CopycatBlockEntity>("copycat", +// BlockEntityBuilder.BlockEntityFactory<CopycatBlockEntity?> { type: BlockEntityType<CopycatBlockEntity?>?, pos: BlockPos?, state: BlockState? -> +// CopycatBlockEntity( +// type, +// pos, +// state +// ) +// }) +// .validBlocks( +// VSAdditionBlocks +// ) +// .register() +// +// +// fun register() {} +//} \ No newline at end of file diff --git a/common/src/main/kotlin/io/github/xiewuzhiying/vs_addition/VSAdditionBlocks.kt b/common/src/main/kotlin/io/github/xiewuzhiying/vs_addition/VSAdditionBlocks.kt new file mode 100644 index 00000000..1dcad74e --- /dev/null +++ b/common/src/main/kotlin/io/github/xiewuzhiying/vs_addition/VSAdditionBlocks.kt @@ -0,0 +1,63 @@ +//package io.github.xiewuzhiying.vs_addition +// +//import com.copycatsplus.copycats.CopycatRegistrate +//import com.copycatsplus.copycats.config.FeatureToggle +//import com.copycatsplus.copycats.content.copycat.base.model.SimpleCopycatPart +//import com.copycatsplus.copycats.datagen.CCLootGen +//import com.simibubi.create.foundation.data.BuilderTransformers +//import com.simibubi.create.foundation.data.CreateRegistrate +//import com.simibubi.create.foundation.data.ModelGen +//import com.tterrag.registrate.builders.BlockBuilder +//import com.tterrag.registrate.providers.DataGenContext +//import com.tterrag.registrate.providers.RegistrateBlockstateProvider +//import com.tterrag.registrate.util.nullness.NonNullFunction +//import dev.architectury.injectables.annotations.ExpectPlatform +//import io.github.xiewuzhiying.vs_addition.content.wing.CopycatWingBlock +//import io.github.xiewuzhiying.vs_addition.content.wing.CopycatWingModel +//import net.minecraft.client.resources.model.BakedModel +//import net.minecraft.world.item.BlockItem +//import net.minecraft.world.level.block.Block +//import net.minecraft.world.level.block.state.BlockBehaviour +// +//@SuppressWarnings("unused") +//class VSAdditionBlocks { +// private val REGISTRATE: CopycatRegistrate = VSAdditionMod.getRegistrate() +// +// +// val COPYCAT_WING = REGISTRATE.block<CopycatWingBlock>("copycat_wing", +// NonNullFunction<BlockBehaviour.Properties, CopycatWingBlock> { pProperties: BlockBehaviour.Properties -> +// CopycatWingBlock( +// pProperties +// ) +// }) +// .transform<Block, CopycatWingBlock, CreateRegistrate, BlockBuilder<CopycatWingBlock, CreateRegistrate>>( +// BuilderTransformers.copycat<CopycatWingBlock, CreateRegistrate>() +// ) +// .transform<Block, CopycatWingBlock, CreateRegistrate, BlockBuilder<CopycatWingBlock, CreateRegistrate>>( +// FeatureToggle.register<Block, CopycatWingBlock, CreateRegistrate, BlockBuilder<CopycatWingBlock, CreateRegistrate>>() +// ) +// .onRegister(CreateRegistrate.blockModel<CopycatWingBlock> { +// NonNullFunction<BakedModel?, BakedModel> { model: BakedModel? -> +// SimpleCopycatPart.create( +// model, +// CopycatWingModel() +// ) +// } +// }) +// .loot(CCLootGen.build<CopycatWingBlock>(CCLootGen.lootForLayers<CopycatWingBlock>())) +// .item() +// .transform<Block, CopycatWingBlock, CreateRegistrate, BlockBuilder<CopycatWingBlock, CreateRegistrate>>( +// ModelGen.customItemModel<BlockItem, BlockBuilder<CopycatWingBlock, CreateRegistrate>>( +// "copycat_base", +// "wing" +// ) +// ) +// .register() +// +// @ExpectPlatform +// fun getWrappedBlockState(c: DataGenContext<Block?, out Block?>?, p: RegistrateBlockstateProvider?, name: String?) { +// throw AssertionError() +// } +// +// fun register() {} +//} \ No newline at end of file diff --git a/common/src/main/kotlin/io/github/xiewuzhiying/vs_addition/VSAdditionCreativeTabs.kt b/common/src/main/kotlin/io/github/xiewuzhiying/vs_addition/VSAdditionCreativeTabs.kt new file mode 100644 index 00000000..4ce532fd --- /dev/null +++ b/common/src/main/kotlin/io/github/xiewuzhiying/vs_addition/VSAdditionCreativeTabs.kt @@ -0,0 +1,39 @@ +//package io.github.xiewuzhiying.vs_addition +// +//import com.copycatsplus.copycats.config.FeatureToggle +//import com.copycatsplus.copycats.mixin_interfaces.CreativeTabExpander +//import com.tterrag.registrate.util.entry.ItemProviderEntry +//import net.minecraft.core.NonNullList +//import net.minecraft.world.item.CreativeModeTab +//import net.minecraft.world.item.ItemStack +//import net.minecraft.world.level.ItemLike +// +// +//object VSAdditionCreativeTabs { +// val MAIN: CreativeModeTab = MainCreativeModeTab() +// var ITEMS: List<ItemProviderEntry<*>>? = null +// +// init { +// ITEMS = java.util.List.of<ItemProviderEntry<*>>( +// VSAdditionBlocks.COPYCAT_WING +// ) +// } +// +// class MainCreativeModeTab : +// CreativeModeTab((TAB_BUILDING_BLOCKS as CreativeTabExpander).`copycats$expandTabCount`(), "vs_addition.main") { +// override fun makeIcon(): ItemStack { +// return VSAdditionBlocks.COPYCAT_WING.asStack() +// } +// +// override fun fillItemList(pItems: NonNullList<ItemStack>) { +// val var2: Iterator<*> = ITEMS!!.iterator() +// while (var2.hasNext()) { +// val item = var2.next() as ItemProviderEntry<*> +// if (FeatureToggle.isEnabled(item.id)) { +// (item.get() as ItemLike).asItem().fillItemCategory(this, pItems) +// } +// } +// } +// } +//} +// diff --git a/common/src/main/kotlin/io/github/xiewuzhiying/vs_addition/VSAdditionMod.kt b/common/src/main/kotlin/io/github/xiewuzhiying/vs_addition/VSAdditionMod.kt new file mode 100644 index 00000000..3e4fa4ec --- /dev/null +++ b/common/src/main/kotlin/io/github/xiewuzhiying/vs_addition/VSAdditionMod.kt @@ -0,0 +1,26 @@ +package io.github.xiewuzhiying.vs_addition + +import dev.architectury.platform.Platform + +object VSAdditionMod { + const val MOD_ID = "vs_addition" + + @JvmStatic var CREATE_ACTIVE = false + @JvmStatic var CC_ACTIVE = false + @JvmStatic var CLOCKWORK_ACTIVE = false + @JvmStatic var CBC_ACTIVE = false + @JvmStatic var EUREKA_ACTIVE = false + + @JvmStatic + fun init() { + CREATE_ACTIVE = Platform.isModLoaded("create") + CC_ACTIVE = Platform.isModLoaded("computercraft") + CLOCKWORK_ACTIVE = Platform.isModLoaded("vs_clockwork") + CBC_ACTIVE = Platform.isModLoaded("createbigcannons") + EUREKA_ACTIVE = Platform.isModLoaded("eureka") + } + + @JvmStatic + fun initClient() { + } +} \ No newline at end of file diff --git a/common/src/main/resources/architectury.common.json b/common/src/main/resources/architectury.common.json new file mode 100644 index 00000000..3ec01b4c --- /dev/null +++ b/common/src/main/resources/architectury.common.json @@ -0,0 +1,3 @@ +{ + "accessWidener": "vs_addition.accesswidener" +} \ No newline at end of file diff --git a/common/src/main/resources/vs_addition-common.mixins.json b/common/src/main/resources/vs_addition-common.mixins.json new file mode 100644 index 00000000..0da063fb --- /dev/null +++ b/common/src/main/resources/vs_addition-common.mixins.json @@ -0,0 +1,22 @@ +{ + "required": true, + "package": "io.github.xiewuzhiying.vs_addition.mixin", + "compatibilityLevel": "JAVA_17", + "mixins": [ + "computercraft.MixinRedstoneAPI", + "computercraft.MixinWirelessModemPeripheral", + "create.MixinCopycatBlock", + "create.MixinCopycatBlockEntity", + "create.MixinDisplayLinkBlockItem", + "create.MixinTreeFertilizerItem", + "createbigcannons.CannonMountBlockEntityAccessor", + "createbigcannons.MixinMountedAutoCannonContraption", + "createbigcannons.MixinMountedBigCannonContraption", + "minecraft.EntityAccessor", + "vs_eureka.ShipHelmBlockEntityAccessor" + ], + "injectors": { + "defaultRequire": 1 + }, + "minVersion": "0.8" +} diff --git a/common/src/main/resources/vs_addition.accesswidener b/common/src/main/resources/vs_addition.accesswidener new file mode 100644 index 00000000..13268c32 --- /dev/null +++ b/common/src/main/resources/vs_addition.accesswidener @@ -0,0 +1 @@ +accessWidener v2 named \ No newline at end of file diff --git a/fabric/build.gradle b/fabric/build.gradle new file mode 100644 index 00000000..591c52d7 --- /dev/null +++ b/fabric/build.gradle @@ -0,0 +1,144 @@ +plugins { + id "com.github.johnrengelman.shadow" version "7.1.2" + id "com.matthewprenger.cursegradle" + id "com.modrinth.minotaur" +} + +apply from: '../gradle-scripts/publish-curseforge.gradle' + +architectury { + platformSetupLoomIde() + fabric() +} + +loom { + accessWidenerPath = project(":common").loom.accessWidenerPath +} + +configurations { + common + shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. + compileClasspath.extendsFrom common + runtimeClasspath.extendsFrom common + developmentFabric.extendsFrom common +} + +dependencies { + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" + modImplementation("net.fabricmc:fabric-language-kotlin:1.10.10+kotlin.1.9.10") + + // Architectury API + include(modApi "dev.architectury:architectury-fabric:${rootProject.architectury_version}") + + //Mixin Extras + compileOnly(annotationProcessor("io.github.llamalad7:mixinextras-common:0.3.5")) + + // Mod menu + modImplementation("com.terraformersmc:modmenu:3.2.3") + modImplementation("me.shedaniel.cloth:cloth-config:${cloth_config_version}") + + // Valkyrien Skies 2 + modApi("org.valkyrienskies:valkyrienskies-118-fabric:${rootProject.vs2_version}") + + common(project(path: ":common", configuration: "namedElements")) { transitive false } + shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } + + // CC Restitched + modImplementation("maven.modrinth:cc-restitched:1.100.8+1.18.2") + + // Create compats + modImplementation("com.simibubi.create:create-fabric-${minecraft_version}:${create_fabric_version}") { + exclude group: 'com.github.AlphaMode', module: 'fakeconfigtoml' + } + modImplementation("com.jozufozu.flywheel:flywheel-fabric-${minecraft_version}:${flywheel_version_fabric}") + modImplementation("com.tterrag.registrate_fabric:Registrate:${registrate_version}") + modImplementation("io.github.fabricators_of_create:Porting-Lib:${port_lib_version}+${minecraft_version}") + modImplementation("me.alphamode:ForgeTags:${forge_tags_version}") + modImplementation("net.minecraftforge:forgeconfigapiport-fabric:${forge_config_api_port_version}") + modImplementation("com.jamieswhiteshirt:reach-entity-attributes:${reach_entity_attributes_version}") + modImplementation("dev.cafeteria:fake-player-api:${fake_player_api_version}") + modImplementation("io.github.tropheusj:milk-lib:${milk_lib_version}") + + // CBC + modCompileOnly("maven.modrinth:create-big-cannons:eLFsS1Ui") + modImplementation("com.rbasamoyai:ritchiesprojectilelib:1.0.0-c5d3ea1+1.18.2-fabric") { transitive = false } + + //Copycat+ + modCompileOnly("maven.modrinth:copycats:g3m9RPx3") +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version, "vs2_version": project.vs2_version.substring(0, project.vs2_version.indexOf('+')) + } +} + +shadowJar { + exclude "architectury.common.json" + + configurations = [project.configurations.shadowCommon] + archiveClassifier.set "dev-shadow" +} + +remapJar { + injectAccessWidener = true + input.set shadowJar.archiveFile + dependsOn shadowJar + archiveClassifier.set null +} + +jar { + archiveClassifier.set "dev" +} + +sourcesJar { + def commonSources = project(":common").sourcesJar + dependsOn commonSources + from commonSources.archiveFile.map { zipTree(it) } +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +publishing { + publications { + mavenCommon(MavenPublication) { + groupId = "org.valkyrienskies.eureka" + version = project.version + artifactId = rootProject.archives_base_name + "-" + project.name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + if (project.vs_maven_username && project.vs_maven_password) { + println "Publishing to VS Maven" + maven { + url = project.vs_maven_url + credentials { + username = project.vs_maven_username + password = project.vs_maven_password + } + } + } + // Add repositories to publish to here. + if (System.getenv("GITHUB_ACTOR") != null) { + println "Publishing to Github Packages" + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/ValkyrienSkies/Eureka") + credentials { + username = System.getenv("GITHUB_ACTOR") + password = System.getenv("GITHUB_TOKEN") + } + } + } + } +} \ No newline at end of file diff --git a/fabric/gradle.properties b/fabric/gradle.properties new file mode 100644 index 00000000..ba0b072a --- /dev/null +++ b/fabric/gradle.properties @@ -0,0 +1,18 @@ +loader_platform=Fabric +create_version=0.5.1-f-build.1333+mc1.18.2 +# https://github.com/Fabricators-of-Create/Create/blob/mc1.18/fabric/dev/gradle.properties +config_api_id=3943250 +forge_config_api_port_version=3.2.4 +fake_player_api_version=0.3.0 +# https://maven.tterrag.com/com/jozufozu/flywheel/Flywheel-Fabric +reach_entity_attributes_version=2.1.1 +registrate_version=MC1.18.2-1.1.11 +forge_tags_version=2.1 +milk_lib_version=0.3.2 +port_lib_version=1.2.1304-beta +# port_lib_hash=cca931b +night_config_core_version=3.6.3 +night_config_toml_version=3.6.3 +jsr305_version=3.0.2 +# https://modrinth.com/mod/no-indium/ +no_indium_version=1.0.2+1.18.2 \ No newline at end of file diff --git a/fabric/src/main/java/io/github/xiewuzhiying/vs_addition/fabric/VSAdditionModFabric.java b/fabric/src/main/java/io/github/xiewuzhiying/vs_addition/fabric/VSAdditionModFabric.java new file mode 100644 index 00000000..d9231373 --- /dev/null +++ b/fabric/src/main/java/io/github/xiewuzhiying/vs_addition/fabric/VSAdditionModFabric.java @@ -0,0 +1,41 @@ +package io.github.xiewuzhiying.vs_addition.fabric; + +import dan200.computercraft.api.ComputerCraftAPI; +import io.github.xiewuzhiying.vs_addition.VSAdditionMod; +import io.github.xiewuzhiying.vs_addition.fabric.compat.computercraft.FabricPeripheralProvider; +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.api.ModInitializer; +import net.fabricmc.loader.api.FabricLoader; +import org.valkyrienskies.mod.fabric.common.ValkyrienSkiesModFabric; + +import static io.github.xiewuzhiying.vs_addition.VSAdditionMod.init; +import static io.github.xiewuzhiying.vs_addition.VSAdditionMod.initClient; + +public class VSAdditionModFabric implements ModInitializer { + private static boolean VS2_ACTIVE = false; + + @Override + public void onInitialize() { + // force VS2 to load before eureka + VS2_ACTIVE = FabricLoader.getInstance().isModLoaded("valkyrienskies"); + + if(VS2_ACTIVE) + new ValkyrienSkiesModFabric().onInitialize(); + + init(); + + if(VSAdditionMod.getCC_ACTIVE()) + ComputerCraftAPI.registerPeripheralProvider(new FabricPeripheralProvider()); + } + + @Environment(EnvType.CLIENT) + public static class Client implements ClientModInitializer { + @Override + public void onInitializeClient() { + + initClient(); + } + } +} diff --git a/fabric/src/main/java/io/github/xiewuzhiying/vs_addition/fabric/ValkyrienPreLaunch.java b/fabric/src/main/java/io/github/xiewuzhiying/vs_addition/fabric/ValkyrienPreLaunch.java new file mode 100644 index 00000000..4c8041e1 --- /dev/null +++ b/fabric/src/main/java/io/github/xiewuzhiying/vs_addition/fabric/ValkyrienPreLaunch.java @@ -0,0 +1,12 @@ +package io.github.xiewuzhiying.vs_addition.fabric; + +import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint; + +/** + * For now, just using this class as an abusive early entrypoint to run the updater + */ +public class ValkyrienPreLaunch implements PreLaunchEntrypoint { + + @Override + public void onPreLaunch() {} +} diff --git a/fabric/src/main/java/io/github/xiewuzhiying/vs_addition/fabric/compat/computercraft/FabricPeripheralProvider.java b/fabric/src/main/java/io/github/xiewuzhiying/vs_addition/fabric/compat/computercraft/FabricPeripheralProvider.java new file mode 100644 index 00000000..dbc9de6b --- /dev/null +++ b/fabric/src/main/java/io/github/xiewuzhiying/vs_addition/fabric/compat/computercraft/FabricPeripheralProvider.java @@ -0,0 +1,20 @@ +package io.github.xiewuzhiying.vs_addition.fabric.compat.computercraft; + +import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.api.peripheral.IPeripheralProvider; +import io.github.xiewuzhiying.vs_addition.compats.computercraft.PeripheralCommon; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +public class FabricPeripheralProvider implements IPeripheralProvider { + + @Nullable + @Override + public IPeripheral getPeripheral(@Nonnull Level level, @Nonnull BlockPos blockPos, @Nonnull Direction direction) { + return (new PeripheralCommon()).getPeripheralCommon(level, blockPos, direction); + } +} diff --git a/fabric/src/main/java/io/github/xiewuzhiying/vs_addition/fabric/mixin/computercraft/TileComputerMixin.java b/fabric/src/main/java/io/github/xiewuzhiying/vs_addition/fabric/mixin/computercraft/TileComputerMixin.java new file mode 100644 index 00000000..0badafe0 --- /dev/null +++ b/fabric/src/main/java/io/github/xiewuzhiying/vs_addition/fabric/mixin/computercraft/TileComputerMixin.java @@ -0,0 +1,29 @@ +package io.github.xiewuzhiying.vs_addition.fabric.mixin.computercraft; + +import dan200.computercraft.shared.computer.blocks.TileComputer; +import dan200.computercraft.shared.computer.core.ServerComputer; +import io.github.xiewuzhiying.vs_addition.compats.computercraft.VSAdditionCC; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(TileComputer.class) +public abstract class TileComputerMixin { + @Inject( + method = "createComputer", + at = @At("RETURN"), + cancellable = true, + remap = false + ) + private void cc_vs$addAPI(int instanceID, int id, CallbackInfoReturnable<ServerComputer> cir) { + ServerComputer computer = cir.getReturnValue(); + Level level = computer.getLevel(); + + VSAdditionCC.applyCCAPIs(computer, (ServerLevel) level); + + cir.setReturnValue(computer); + } +} \ No newline at end of file diff --git a/fabric/src/main/resources/assets/vs_addition/icon.png b/fabric/src/main/resources/assets/vs_addition/icon.png new file mode 100644 index 00000000..72d59786 Binary files /dev/null and b/fabric/src/main/resources/assets/vs_addition/icon.png differ diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json new file mode 100644 index 00000000..0998cef8 --- /dev/null +++ b/fabric/src/main/resources/fabric.mod.json @@ -0,0 +1,42 @@ +{ + "schemaVersion": 1, + "id": "vs_addition", + "version": "${version}", + "name": "VS Addition", + "description": "Some little addition for VS2 and other mods.", + "authors": [ + "xiewuzhying" + ], + "contact": { + "homepage": "https://valkyrienskies.org/", + "sources": "https://github.com/xiewuzhiying/VS-Addition" + }, + "license": "Apache-2.0", + "icon": "assets/vs_addition/icon.png", + "environment": "*", + "entrypoints": { + "main": [ + "io.github.xiewuzhiying.vs_addition.fabric.VSAdditionModFabric" + ], + "preLaunch": [ + "io.github.xiewuzhiying.vs_addition.fabric.ValkyrienPreLaunch" + ] + }, + "mixins": [ + "vs_addition-common.mixins.json", + "vs_addition.mixins.json" + ], + "accessWidener" : "vs_addition-common.accesswidener", + "depends": { + "minecraft": ">=1.18.2", + "fabricloader": ">=0.14.21" + }, + "suggests": { + "valkyrienskies": ">=2.1.1-beta.5", + "create": ">=0.5.1", + "createbigcannons": ">=0.5.2", + "computercraft": "*", + "vs_clockwork": ">=0.1", + "copycats": ">=1.2.5" + } +} \ No newline at end of file diff --git a/fabric/src/main/resources/vs_addition.mixins.json b/fabric/src/main/resources/vs_addition.mixins.json new file mode 100644 index 00000000..7275036a --- /dev/null +++ b/fabric/src/main/resources/vs_addition.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "package": "io.github.xiewuzhiying.vs_addition.fabric.mixin", + "compatibilityLevel": "JAVA_17", + "mixins": [ + "computercraft.TileComputerMixin" + ], + "client": [ + ], + "injectors": { + "defaultRequire": 1 + }, + "minVersion": "0.8" +} diff --git a/forge/build.gradle b/forge/build.gradle new file mode 100644 index 00000000..4486c8ed --- /dev/null +++ b/forge/build.gradle @@ -0,0 +1,171 @@ +buildscript { + repositories { + mavenCentral() + } + dependencies { + // Make sure this version matches the one included in Kotlin for Forge + classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10' + // OPTIONAL Gradle plugin for Kotlin Serialization + classpath 'org.jetbrains.kotlin:kotlin-serialization:1.6.10' + } +} + +plugins { + id "com.github.johnrengelman.shadow" version "7.1.2" + id "com.matthewprenger.cursegradle" + id "com.modrinth.minotaur" +} + +apply from: '../gradle-scripts/publish-curseforge.gradle' + +architectury { + platformSetupLoomIde() + forge() +} + +loom { + accessWidenerPath = project(":common").loom.accessWidenerPath + + forge { + convertAccessWideners = true + mixinConfig "vs_addition.mixins.json" + mixinConfig "vs_addition-common.mixins.json" + extraAccessWideners.add loom.accessWidenerPath.get().asFile.name + } +} + +configurations { + common + shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. + compileClasspath.extendsFrom common + runtimeClasspath.extendsFrom common + developmentForge.extendsFrom common +} + +dependencies { + forge "net.minecraftforge:forge:$forge_version" + + // Architectury API + include(modApi "dev.architectury:architectury-forge:${rootProject.architectury_version}") + + //Mixin Extras + compileOnly(annotationProcessor("io.github.llamalad7:mixinextras-common:0.3.5")) + implementation(include("io.github.llamalad7:mixinextras-forge:0.3.5")) + + // Valkyrien Skies 2 + modApi("org.valkyrienskies:valkyrienskies-118-forge:$vs2_version") { transitive = false } + + // VS Core + implementation("org.valkyrienskies.core:api:$vs_core_version") + implementation("org.valkyrienskies.core:api-game:$vs_core_version") + implementation("org.valkyrienskies.core:util:$vs_core_version") + implementation("org.valkyrienskies.core:impl:$vs_core_version") + + common(project(path: ":common", configuration: "namedElements")) { transitive false } + shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false } + + // Kotlin for Forge + implementation "thedarkcolour:kotlinforforge:$forge_kotlin_version" + + // Create compats + modImplementation("com.simibubi.create:create-${minecraft_version}:${create_version}:slim") { transitive = false } + modImplementation("com.jozufozu.flywheel:flywheel-forge-${minecraft_version}:${flywheel_version}") + modImplementation("com.tterrag.registrate:Registrate:${registrate_version}") + + // CC Tweaked + modCompileOnly("maven.modrinth:cc-tweaked:1.18.2-1.101.3") + + //Framed blocks + modCompileOnly("maven.modrinth:framedblocks:5.11.5") + + //Copycat+ + + modImplementation("maven.modrinth:copycats:1.18.2-1.2.5") + + //CBC + modCompileOnly("maven.modrinth:create-big-cannons:0.5.4") + modImplementation("com.rbasamoyai:ritchiesprojectilelib:1.0.0-c5d3ea1+1.18.2-forge") { transitive = false } + + //CBC Modern Warfare + modCompileOnly files("jars/cbcmodernwarfare-forge-1.18.2-0.0.4a.jar") +} + +processResources { + inputs.property "version", project.version + + filesMatching("META-INF/mods.toml") { + expand "version": project.version, "vs2_version": project.vs2_version.substring(0, project.vs2_version.indexOf('+')) + } +} + +tasks.withType(JavaCompile).configureEach { + // Minecraft 1.18 (1.18-pre2) upwards uses Java 17. + it.options.release = 17 +} + +shadowJar { + exclude "fabric.mod.json" + exclude "architectury.common.json" + + configurations = [project.configurations.shadowCommon] + archiveClassifier.set "dev-shadow" +} + +remapJar { + input.set shadowJar.archiveFile + dependsOn shadowJar + archiveClassifier.set null +} + +jar { + archiveClassifier.set "dev" +} + +sourcesJar { + def commonSources = project(":common").sourcesJar + dependsOn commonSources + from commonSources.archiveFile.map { zipTree(it) } +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +publishing { + publications { + mavenCommon(MavenPublication) { + groupId = "org.valkyrienskies.eureka" + version = project.version + artifactId = rootProject.archives_base_name + "-" + project.name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + if (project.vs_maven_username && project.vs_maven_password) { + println "Publishing to VS Maven" + maven { + url = project.vs_maven_url + credentials { + username = project.vs_maven_username + password = project.vs_maven_password + } + } + } + // Add repositories to publish to here. + if (System.getenv("GITHUB_ACTOR") != null) { + println "Publishing to Github Packages" + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/ValkyrienSkies/Eureka") + credentials { + username = System.getenv("GITHUB_ACTOR") + password = System.getenv("GITHUB_TOKEN") + } + } + } + } +} \ No newline at end of file diff --git a/forge/gradle.properties b/forge/gradle.properties new file mode 100644 index 00000000..73cc3a3b --- /dev/null +++ b/forge/gradle.properties @@ -0,0 +1,6 @@ +loom.platform=forge +loader_platform=Forge +kotlin.stdlib.default.dependency=false +create_version=0.5.1.f-345 +flywheel_version=0.6.10-105 +registrate_version=MC1.18.2-1.1.3 \ No newline at end of file diff --git a/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/compat/computercraft/ForgePeripheralProvider.java b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/compat/computercraft/ForgePeripheralProvider.java new file mode 100644 index 00000000..70925cd7 --- /dev/null +++ b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/compat/computercraft/ForgePeripheralProvider.java @@ -0,0 +1,22 @@ +package io.github.xiewuzhiying.vs_addition.forge.compat.computercraft; + +import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.api.peripheral.IPeripheralProvider; +import io.github.xiewuzhiying.vs_addition.compats.computercraft.PeripheralCommon; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import net.minecraftforge.common.util.LazyOptional; +import org.jetbrains.annotations.NotNull; + +public class ForgePeripheralProvider implements IPeripheralProvider { + @NotNull + @Override + public LazyOptional<IPeripheral> getPeripheral(@NotNull Level level, @NotNull BlockPos blockPos, @NotNull Direction direction) { + IPeripheral peripheral = (new PeripheralCommon()).getPeripheralCommon(level,blockPos,direction); + if(peripheral==null) peripheral = (new PeripheralForge().getPeripheralForge(level,blockPos,direction)); + if(peripheral==null) return LazyOptional.empty(); + IPeripheral finalPeripheral = peripheral; + return LazyOptional.of(() -> finalPeripheral); + } +} diff --git a/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/compat/computercraft/PeripheralForge.java b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/compat/computercraft/PeripheralForge.java new file mode 100644 index 00000000..3b8085bf --- /dev/null +++ b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/compat/computercraft/PeripheralForge.java @@ -0,0 +1,30 @@ +package io.github.xiewuzhiying.vs_addition.forge.compat.computercraft; + +import dan200.computercraft.api.peripheral.IPeripheral; +import io.github.xiewuzhiying.vs_addition.forge.compat.computercraft.peripherals.CompactCannonMountPeripheral; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import riftyboi.cbcmodernwarfare.cannon_control.compact_mount.CompactCannonMountBlockEntity; +import riftyboi.cbcmodernwarfare.index.CBCModernWarfareBlocks; + +import javax.annotation.Nullable; + +public class PeripheralForge { + + private boolean c(BlockState arg1, Block arg2) { return arg1.getBlock() == arg2; } + + @Nullable + public IPeripheral getPeripheralForge(Level level, BlockPos blockPos, Direction direction){ + BlockState s = level.getBlockState(blockPos); + BlockEntity be = level.getBlockEntity(blockPos); + if (c(s, CBCModernWarfareBlocks.COMPACT_MOUNT.get())) { + return new CompactCannonMountPeripheral("cbcmf_compact_cannon_mount", (CompactCannonMountBlockEntity) be, level, blockPos, direction); + } else { + return null; + } + } +} diff --git a/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/compat/computercraft/peripherals/CompactCannonMountPeripheral.java b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/compat/computercraft/peripherals/CompactCannonMountPeripheral.java new file mode 100644 index 00000000..ec07aaf9 --- /dev/null +++ b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/compat/computercraft/peripherals/CompactCannonMountPeripheral.java @@ -0,0 +1,126 @@ +package io.github.xiewuzhiying.vs_addition.forge.compat.computercraft.peripherals; + +import dan200.computercraft.api.lua.IArguments; +import dan200.computercraft.api.lua.LuaException; +import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.peripheral.IPeripheral; +import io.github.xiewuzhiying.vs_addition.forge.mixin.cbcmodernwarfare.CompactCannonMountBlockEntityAccessor; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import riftyboi.cbcmodernwarfare.cannon_control.compact_mount.CompactCannonMountBlockEntity; + +public class CompactCannonMountPeripheral implements IPeripheral { + + private final String type ; + private final CompactCannonMountBlockEntity tileEntity; + + private final Level level; + + private final BlockPos worldPosition; + + private final Direction direction; + + public CompactCannonMountPeripheral(String type, CompactCannonMountBlockEntity tileEntity, Level level, BlockPos blockPos, Direction direction) { + this.type = type; + this.tileEntity = tileEntity; + this.level = level; + this.worldPosition = blockPos; + this.direction = direction; + } + + @NotNull + @Override + public String getType() { + return type; + } + + @Override + public boolean equals(@Nullable IPeripheral iPeripheral) { + return iPeripheral == this; + } + + @Override + public Object getTarget() { + return this.tileEntity; + } + + @LuaFunction(mainThread = true) + public final void setPitch(double value){ + if(this.isRunning()) + this.tileEntity.setPitch((float) value); + } + + @LuaFunction(mainThread = true) + public final void setYaw(double value){ + if(this.isRunning()) + this.tileEntity.setYaw((float) value); + } + + @LuaFunction(mainThread = true) + public final Object assemble(){ + if(!this.isRunning()) { + ((CompactCannonMountBlockEntityAccessor) this.tileEntity).Assemble(); + return true; + } + return false; + } + + @LuaFunction(mainThread = true) + public final Object disassemble() { + if(this.isRunning()) { + this.tileEntity.disassemble(); + this.tileEntity.sendData(); + return true; + } + return false; + } + + @LuaFunction(mainThread = true) + public final void fire() { + if(this.isRunning()) { + this.tileEntity.getContraption().tryFiringShot(); + } + } + + @LuaFunction + public final boolean isRunning(){ + return this.tileEntity.isRunning(); + } + + @LuaFunction + public final Object getPitchOffset(IArguments partialTicks) throws LuaException { + if(this.isRunning()) { + double value = partialTicks.optDouble(0).orElse(0.0); + return (double) this.tileEntity.getPitchOffset((float) value); + } + return false; + } + + @LuaFunction + public final Object getYawOffset(IArguments partialTicks) throws LuaException { + if(this.isRunning()) { + double value = partialTicks.optDouble(0).orElse(0.0); + return (double) this.tileEntity.getYawOffset((float) value); + } + return false; + } + + @LuaFunction + public final Object getMaxDepress() { + if(this.isRunning()) { + return (double) ((CompactCannonMountBlockEntityAccessor) this.tileEntity).GetMaxDepress(); + } + return false; + } + + @LuaFunction + public final Object getMaxElevate() { + if(this.isRunning()) { + return (double) ((CompactCannonMountBlockEntityAccessor) this.tileEntity).GetMaxElevate(); + } + return false; + } +} diff --git a/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/content/redstone/displayLink/target/FramedSignDisplayTarget.java b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/content/redstone/displayLink/target/FramedSignDisplayTarget.java new file mode 100644 index 00000000..26d885b6 --- /dev/null +++ b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/content/redstone/displayLink/target/FramedSignDisplayTarget.java @@ -0,0 +1,40 @@ +package io.github.xiewuzhiying.vs_addition.forge.content.redstone.displayLink.target; + +import com.simibubi.create.content.redstone.displayLink.DisplayLinkContext; +import com.simibubi.create.content.redstone.displayLink.target.DisplayTarget; +import com.simibubi.create.content.redstone.displayLink.target.DisplayTargetStats; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.level.block.entity.BlockEntity; +import xfacthd.framedblocks.common.blockentity.FramedSignBlockEntity; + +import java.util.List; + +public class FramedSignDisplayTarget extends DisplayTarget { + + @Override + public void acceptText(int line, List<MutableComponent> text, DisplayLinkContext context) { + BlockEntity be = context.getTargetBlockEntity(); + if (!(be instanceof FramedSignBlockEntity sign)) + return; + + boolean changed = false; + for (int i = 0; i < text.size() && i + line < 4; i++) { + if (i == 0) + reserve(i + line, sign, context); + if (i > 0 && isReserved(i + line, sign, context)) + break; + + sign.setLine(i + line, text.get(i)); + changed = true; + } + + if (changed) + context.level().sendBlockUpdated(context.getTargetPos(), sign.getBlockState(), sign.getBlockState(), 2); + } + + @Override + public DisplayTargetStats provideStats(DisplayLinkContext context) { + return new DisplayTargetStats(4, 15, this); + } + +} diff --git a/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/mixin/ValkyrienForgeMixinConfigPlugin.java b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/mixin/ValkyrienForgeMixinConfigPlugin.java new file mode 100644 index 00000000..8460ef94 --- /dev/null +++ b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/mixin/ValkyrienForgeMixinConfigPlugin.java @@ -0,0 +1,47 @@ +package io.github.xiewuzhiying.vs_addition.forge.mixin; + +import java.util.List; +import java.util.Set; +import org.objectweb.asm.tree.ClassNode; +import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; +import org.spongepowered.asm.mixin.extensibility.IMixinInfo; + +/** + * For now, just using this class as an abusive early entrypoint to run the updater + */ +public class ValkyrienForgeMixinConfigPlugin implements IMixinConfigPlugin { + + @Override + public void onLoad(final String s) { + } + + @Override + public String getRefMapperConfig() { + return null; + } + + @Override + public boolean shouldApplyMixin(final String s, final String s1) { + return true; + } + + @Override + public void acceptTargets(final Set<String> set, final Set<String> set1) { + + } + + @Override + public List<String> getMixins() { + return null; + } + + @Override + public void preApply(final String s, final ClassNode classNode, final String s1, final IMixinInfo iMixinInfo) { + + } + + @Override + public void postApply(final String s, final ClassNode classNode, final String s1, final IMixinInfo iMixinInfo) { + + } +} diff --git a/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/mixin/cbcmodernwarfare/CompactCannonMountBlockEntityAccessor.java b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/mixin/cbcmodernwarfare/CompactCannonMountBlockEntityAccessor.java new file mode 100644 index 00000000..ddb0a1cf --- /dev/null +++ b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/mixin/cbcmodernwarfare/CompactCannonMountBlockEntityAccessor.java @@ -0,0 +1,18 @@ +package io.github.xiewuzhiying.vs_addition.forge.mixin.cbcmodernwarfare; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; +import riftyboi.cbcmodernwarfare.cannon_control.compact_mount.CompactCannonMountBlockEntity; + +@Mixin(CompactCannonMountBlockEntity.class) +public interface CompactCannonMountBlockEntityAccessor { + + @Invoker("assemble") + void Assemble(); + + @Invoker("getMaxDepress") + float GetMaxDepress(); + + @Invoker("getMaxElevate") + float GetMaxElevate(); +} diff --git a/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/mixin/cbcmodernwarfare/MixinMountedMediumcannonContraption.java b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/mixin/cbcmodernwarfare/MixinMountedMediumcannonContraption.java new file mode 100644 index 00000000..e15baf8b --- /dev/null +++ b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/mixin/cbcmodernwarfare/MixinMountedMediumcannonContraption.java @@ -0,0 +1,81 @@ +//package io.github.xiewuzhiying.vs_addition.forge.mixin.cbcmodernwarfare; +// +//import io.github.xiewuzhiying.vs_addition.mixin.minecraft.EntityAccessor; +//import net.minecraft.server.level.ServerLevel; +//import net.minecraft.util.Mth; +//import net.minecraft.world.phys.Vec3; +//import org.spongepowered.asm.mixin.Mixin; +//import org.spongepowered.asm.mixin.Unique; +//import org.spongepowered.asm.mixin.injection.At; +//import org.spongepowered.asm.mixin.injection.Inject; +//import org.spongepowered.asm.mixin.injection.Redirect; +//import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +//import org.valkyrienskies.core.api.ships.ServerShip; +//import org.valkyrienskies.mod.common.VSGameUtilsKt; +//import org.valkyrienskies.mod.common.util.GameTickForceApplier; +//import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; +//import rbasamoyai.createbigcannons.cannon_control.contraption.AbstractMountedCannonContraption; +//import rbasamoyai.createbigcannons.cannon_control.contraption.ItemCannon; +//import rbasamoyai.createbigcannons.cannon_control.contraption.PitchOrientedContraptionEntity; +//import riftyboi.cbcmodernwarfare.cannon_control.contraption.MountedMediumcannonContraption; +//import riftyboi.cbcmodernwarfare.munitions.medium_cannon.AbstractMediumcannonProjectile; +// +//@Mixin(MountedMediumcannonContraption.class) +//public abstract class MixinMountedMediumcannonContraption extends AbstractMountedCannonContraption implements ItemCannon { +// +// @Unique +// private float vs_addition$speed; +// +// @Unique +// private Vec3 vs_addition$vector; +// +// @Unique +// private ServerShip vs_addition$serverShip; +// +// @Inject( +// method = "fireShot", +// at = @At( +// value = "INVOKE", +// target = "Lriftyboi/cbcmodernwarfare/munitions/medium_cannon/AbstractMediumcannonProjectile;m_6686_(DDDFF)V", +// shift = At.Shift.BEFORE +// ) +// ) +// public void getShip(ServerLevel level, PitchOrientedContraptionEntity entity, CallbackInfo ci){ +// vs_addition$serverShip = (ServerShip) VSGameUtilsKt.getShipObjectManagingPos(entity.level, VectorConversionsMCKt.toJOML(entity.getAnchorVec())); +// } +// +// @Redirect( +// method = "fireShot", +// at = @At( +// value = "INVOKE", +// target = "Lriftyboi/cbcmodernwarfare/munitions/medium_cannon/AbstractMediumcannonProjectile;m_6686_(DDDFF)V" +// ) +// ) +// public void shoot(AbstractMediumcannonProjectile<?> instance, double x, double y, double z, float velocity, float inaccuracy) { +// vs_addition$speed = velocity; +// vs_addition$vector = (new Vec3(x, y, z)).normalize().add(((EntityAccessor) instance).getRandom().nextGaussian() * 0.007499999832361937 * (double)inaccuracy, ((EntityAccessor)(Object) instance).getRandom().nextGaussian() * 0.007499999832361937 * (double)inaccuracy, ((EntityAccessor)(Object) instance).getRandom().nextGaussian() * 0.007499999832361937 * (double)inaccuracy).scale(velocity); +// Vec3 vec3 = vs_addition$vector.add(VectorConversionsMCKt.toMinecraft(vs_addition$serverShip.getVelocity())); +// instance.setDeltaMovement(vec3); +// double d = vs_addition$vector.horizontalDistance(); +// instance.setYRot((float)(Mth.atan2(vs_addition$vector.x, vs_addition$vector.z) * 57.2957763671875)); +// instance.setXRot((float)(Mth.atan2(vs_addition$vector.y, d) * 57.2957763671875)); +// instance.yRotO = instance.getYRot(); +// instance.xRotO = instance.getXRot(); +// } +// +// @Inject( +// method = "fireShot", +// at = @At( +// value = "INVOKE", +// target = "Lriftyboi/cbcmodernwarfare/munitions/medium_cannon/AbstractMediumcannonProjectile;m_6686_(DDDFF)V", +// shift = At.Shift.AFTER +// ) +// ) +// public void recoil(ServerLevel level, PitchOrientedContraptionEntity entity, CallbackInfo ci) { +// if (vs_addition$serverShip != null) { +// GameTickForceApplier applier = vs_addition$serverShip.getAttachment(GameTickForceApplier.class); +// double recoilForce = vs_addition$speed * 50000.0d; +// applier.applyInvariantForceToPos(vs_addition$serverShip.getTransform().getShipToWorldRotation().transform(VectorConversionsMCKt.toJOML(vs_addition$vector).negate().normalize()).mul(recoilForce), VectorConversionsMCKt.toJOML(entity.getAnchorVec().add(0.5, 0.5, 0.5)).sub(vs_addition$serverShip.getTransform().getPositionInShip())); +// } +// } +//} diff --git a/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/mixin/computercraft/TileComputerMixin.java b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/mixin/computercraft/TileComputerMixin.java new file mode 100644 index 00000000..ed98b293 --- /dev/null +++ b/forge/src/main/java/io/github/xiewuzhiying/vs_addition/forge/mixin/computercraft/TileComputerMixin.java @@ -0,0 +1,29 @@ +package io.github.xiewuzhiying.vs_addition.forge.mixin.computercraft; + +import dan200.computercraft.shared.computer.blocks.TileComputer; +import dan200.computercraft.shared.computer.core.ServerComputer; +import io.github.xiewuzhiying.vs_addition.compats.computercraft.VSAdditionCC; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.Level; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(TileComputer.class) +public abstract class TileComputerMixin { + @Inject( + method = "createComputer", + at = @At("RETURN"), + cancellable = true, + remap = false + ) + private void cc_vs$addAPI(int id, CallbackInfoReturnable<ServerComputer> cir) { + ServerComputer computer = cir.getReturnValue(); + Level level = computer.getLevel(); + + VSAdditionCC.applyCCAPIs(computer, (ServerLevel) level); + + cir.setReturnValue(computer); + } +} \ No newline at end of file diff --git a/forge/src/main/kotlin/io/github/xiewuzhiying/vs_addition/forge/VSAdditionModForge.kt b/forge/src/main/kotlin/io/github/xiewuzhiying/vs_addition/forge/VSAdditionModForge.kt new file mode 100644 index 00000000..ea85d443 --- /dev/null +++ b/forge/src/main/kotlin/io/github/xiewuzhiying/vs_addition/forge/VSAdditionModForge.kt @@ -0,0 +1,75 @@ +package io.github.xiewuzhiying.vs_addition.forge + +import com.simibubi.create.content.redstone.displayLink.AllDisplayBehaviours +import dan200.computercraft.api.ComputerCraftAPI +import io.github.xiewuzhiying.vs_addition.VSAdditionMod +import io.github.xiewuzhiying.vs_addition.VSAdditionMod.init +import io.github.xiewuzhiying.vs_addition.VSAdditionMod.initClient +import io.github.xiewuzhiying.vs_addition.forge.compat.computercraft.ForgePeripheralProvider +import io.github.xiewuzhiying.vs_addition.forge.content.redstone.displayLink.target.FramedSignDisplayTarget +import net.minecraft.resources.ResourceLocation +import net.minecraftforge.eventbus.api.IEventBus +import net.minecraftforge.fml.ModList +import net.minecraftforge.fml.common.Mod +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent +import thedarkcolour.kotlinforforge.forge.MOD_BUS +import xfacthd.framedblocks.common.FBContent + + +@Mod(VSAdditionMod.MOD_ID) +class VSAdditionModForge { + + var CREATE_ACTIVE = false + var CC_ACTIVE = false + var FRAMEDBLOCKS_ACTIVE = false + var COPYCATS_ACTIVE = false + var CBC_ACTIVE = false + var CBCMF_ACTIVE = false + + init { + CREATE_ACTIVE = ModList.get().isLoaded("create") + CC_ACTIVE = ModList.get().isLoaded("computercraft") + FRAMEDBLOCKS_ACTIVE = ModList.get().isLoaded("framedblocks") + COPYCATS_ACTIVE = ModList.get().isLoaded("copycats") + CBC_ACTIVE = ModList.get().isLoaded("createbigcannnons") + CBCMF_ACTIVE = ModList.get().isLoaded("cbcmodernwarfare") + + MOD_BUS.addListener { event: FMLClientSetupEvent? -> + clientSetup( + event + ) + } + MOD_BUS.addListener { event: FMLCommonSetupEvent? -> + serverSetup( + event + ) + } + init() + } + + private fun clientSetup(event: FMLClientSetupEvent?) { + initClient() + } + + private fun serverSetup(event: FMLCommonSetupEvent?) { + if(FRAMEDBLOCKS_ACTIVE && CREATE_ACTIVE) + AllDisplayBehaviours.assignBlockEntity( + AllDisplayBehaviours.register( + ResourceLocation( + VSAdditionMod.MOD_ID, + "framed_sign_display_target" + ), FramedSignDisplayTarget() + ), FBContent.blockEntityTypeFramedSign.get() + ) + + if(CC_ACTIVE) + ComputerCraftAPI.registerPeripheralProvider(ForgePeripheralProvider()) + } + + + companion object { + fun getModBus(): IEventBus = MOD_BUS + } + +} diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml new file mode 100644 index 00000000..513ba0d4 --- /dev/null +++ b/forge/src/main/resources/META-INF/mods.toml @@ -0,0 +1,77 @@ +modLoader = "kotlinforforge" +loaderVersion = "[3.12.0,)" +issueTrackerURL = "https://github.com/xiewuzhiying/VS-Addition/issues" +license = "Apache-2.0" + +[[mods]] +modId = "vs_addition" +version = "${version}" +displayName = "VS Addition" +authors = ["xiewuzhiying"] +description = ''' +Some little addition for VS2 and other mods. +''' +logoFile = "icon.png" + +[[dependencies.vs_addition]] +modId = "forge" +mandatory = true +versionRange = "[40.1.69,)" +ordering = "NONE" +side = "BOTH" + +[[dependencies.vs_addition]] +modId = "minecraft" +mandatory = true +versionRange = "[1.18.2,)" +ordering = "NONE" +side = "BOTH" + +[[dependencies.vs_addition]] +modId = "valkyrienskies" +mandatory = false +versionRange = "[2.1.1-beta.5,)" +ordering = "AFTER" +side = "BOTH" + +[[dependencies.vs_addition]] +modId = "create" +mandatory = false +versionRange = "[0.5.1,)" +ordering = "AFTER" +side = "BOTH" + +[[dependencies.vs_addition]] +modId = "createbigcannons" +mandatory = false +versionRange = "[0.5.2,)" +ordering = "AFTER" +side = "BOTH" + +[[dependencies.vs_addition]] +modId = "framedblocks" +mandatory = false +versionRange = "[5,)" +ordering = "AFTER" +side = "BOTH" + +[[dependencies.vs_addition]] +modId = "computercraft" +mandatory = false +versionRange = "*" +ordering = "AFTER" +side = "BOTH" + +[[dependencies.vs_addition]] +modId = "vs_clockwork" +mandatory = false +versionRange = "[0.1,)" +ordering = "AFTER" +side = "BOTH" + +[[dependencies.vs_addition]] +modId = "copycats" +mandatory = false +versionRange = "[1.2.5,)" +ordering = "AFTER" +side = "BOTH" \ No newline at end of file diff --git a/forge/src/main/resources/icon.png b/forge/src/main/resources/icon.png new file mode 100644 index 00000000..72d59786 Binary files /dev/null and b/forge/src/main/resources/icon.png differ diff --git a/forge/src/main/resources/pack.mcmeta b/forge/src/main/resources/pack.mcmeta new file mode 100644 index 00000000..08796647 --- /dev/null +++ b/forge/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "VS Addition", + "pack_format": 8 + } +} diff --git a/forge/src/main/resources/vs_addition.mixins.json b/forge/src/main/resources/vs_addition.mixins.json new file mode 100644 index 00000000..4d54f53b --- /dev/null +++ b/forge/src/main/resources/vs_addition.mixins.json @@ -0,0 +1,14 @@ +{ + "required": true, + "package": "io.github.xiewuzhiying.vs_addition.forge.mixin", + "compatibilityLevel": "JAVA_17", + "plugin": "io.github.xiewuzhiying.vs_addition.forge.mixin.ValkyrienForgeMixinConfigPlugin", + "mixins": [ + "cbcmodernwarfare.CompactCannonMountBlockEntityAccessor", + "computercraft.TileComputerMixin" + ], + "injectors": { + "defaultRequire": 1 + }, + "minVersion": "0.8" +} diff --git a/gradle-scripts/publish-curseforge.gradle b/gradle-scripts/publish-curseforge.gradle new file mode 100644 index 00000000..9d7f444a --- /dev/null +++ b/gradle-scripts/publish-curseforge.gradle @@ -0,0 +1,53 @@ +// Determine release type +def vsReleaseType = 'alpha' +if (project.hasProperty("CustomReleaseVersion")) { + def matches = project.property("CustomReleaseVersion") =~ 'release/(?:\\d+\\.){1,2}\\d+(?:-(alpha|beta).\\d+)?' + + vsReleaseType = matches[0][1] ?: 'release' +} + +def fileDisplayName = "[${project.loader_platform} ${project.minecraft_version}] v${project.version}" + +// upgrade curseforge release type if it's an alpha, +// because alpha can't be installed from the curseforge app +def curseForgeReleaseType = vsReleaseType == 'alpha' ? 'beta' : vsReleaseType + +// Publish to CurseForge +curseforge { + if (project.curse_api_key) { + apiKey = project.curse_api_key + project { + id = project.curse_project_id + releaseType = curseForgeReleaseType + addGameVersion project.minecraft_version + addGameVersion project.loader_platform + + mainArtifact(remapJar.archiveFile.get().asFile) { + relations { + requiredDependency 'valkyrien-skies' + } + displayName = fileDisplayName + } + } + } + options { + forgeGradleIntegration = false + javaVersionAutoDetect = false + } +} + +// Publish to Modrinth +modrinth { + token = project.modrinth_api_key + projectId = project.modrinth_project_id + versionType = vsReleaseType + versionName = fileDisplayName + versionNumber = "${project.minecraft_version}-${project.loader_platform.toLowerCase()}-${project.version}" + uploadFile = remapJar + gameVersions = [project.minecraft_version] + loaders = [project.loader_platform.toLowerCase()] + + dependencies { + required.project 'valkyrien-skies' + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..8d7d1a68 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,32 @@ +org.gradle.jvmargs=-Xmx4096M +# Identity +mod_name=vs_addition +mod_id=vs_addition +mod_version=0.0.1c +enabled_platforms=fabric,forge +archives_base_name=vs_addition +maven_group=io.github.xiewuzhiying +loader_platform=Common +# Dependencies +vs2_version=2.1.1-beta.6+88d9088afa +vs_core_version=1.1.0+e26d9059c0 +minecraft_version=1.18.2 +architectury_version=4.10.86 +fabric_loader_version=0.15.8 +fabric_api_version=0.77.0+1.18.2 +forge_version=1.18.2-40.2.10 +forge_kotlin_version=3.12.0 +kotlin_version=1.9.10 +cloth_config_version=6.4.90 +create_fabric_version=0.5.1-f-build.1333+mc1.18.2 +flywheel_version_fabric=0.6.9-38 +createbigcannons_version=0.5.2-nightly-e815ca4 +# Maven publishing +vs_maven_url= +vs_maven_username= +vs_maven_password= +# For release builds +curse_api_key= +curse_project_id= +modrinth_api_key= +modrinth_project_id= diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000..e708b1c0 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..27313fbc --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 00000000..1b6c7873 --- /dev/null +++ b/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100755 index 00000000..107acd32 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 00000000..fb04e482 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,52 @@ +pluginManagement { + repositories { + /*maven { + val vs_maven_url: String? by settings + val vs_maven_username: String? by settings + val vs_maven_password: String? by settings + + name = "Valkyrien Skies Internal" + url = uri(vs_maven_url ?: "https://maven.valkyrienskies.org") + + if (vs_maven_username != null && vs_maven_password != null) { + credentials { + username = vs_maven_username!! + password = vs_maven_password!! + } + } + }*/ + gradlePluginPortal() + maven("https://maven.fabricmc.net/") { + name = "Fabric" + } + maven("https://repo.spongepowered.org/repository/maven-public/") { + name = "Sponge Snapshots" + } + maven("https://maven.minecraftforge.net") { + name = "Forge" + } + maven("https://maven.architectury.dev/") { + name = "Architectury" + } + } + + resolutionStrategy { + eachPlugin { + // If we request Forge, actually give it the correct artifact. + if (requested.id.id == "net.minecraftforge.gradle") { + useModule("${requested.id}:ForgeGradle:${requested.version}") + } + + if (requested.id.namespace?.startsWith("org.jetbrains.kotlin") == true) { + val kotlin_version: String by settings + useVersion(kotlin_version) + } + } + } +} + +include("common") +include("fabric") +include("forge") + +rootProject.name = "vs_addition"