diff --git a/.github/workflows/gradle-multi-ref.yml b/.github/workflows/gradle-multi-ref.yml index 2d42c78..142ddf0 100644 --- a/.github/workflows/gradle-multi-ref.yml +++ b/.github/workflows/gradle-multi-ref.yml @@ -18,7 +18,7 @@ on: - changelog.md - LICENSE - README.md - workflow_dispatch: {} + workflow_dispatch: { } jobs: build: @@ -28,25 +28,25 @@ jobs: strategy: matrix: - branch: [master, port-1.19.2] + branch: [ master, port-1.19.2 ] steps: - - uses: actions/checkout@v4 - with: - ref: ${{ matrix.branch }} - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'temurin' + - uses: actions/checkout@v4 + with: + ref: ${{ matrix.branch }} + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' - # Configure Gradle for optimal use in GiHub Actions, including caching of downloaded dependencies. - # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md - - name: Setup Gradle - uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 + # Configure Gradle for optimal use in GiHub Actions, including caching of downloaded dependencies. + # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md + - name: Setup Gradle + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 - - name: Build with Gradle Wrapper - run: ./gradlew build + - name: Build with Gradle Wrapper + run: ./gradlew build # NOTE: The Gradle Wrapper is the default and recommended way to run Gradle (https://docs.gradle.org/current/userguide/gradle_wrapper.html). # If your project does not have the Gradle Wrapper configured, you can use the following configuration to run Gradle with a specified version. @@ -66,19 +66,19 @@ jobs: strategy: matrix: - branch: [master, port-1.19.2] + branch: [ master, port-1.19.2 ] steps: - - uses: actions/checkout@v4 - with: - ref: ${{ matrix.branch }} - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'temurin' + - uses: actions/checkout@v4 + with: + ref: ${{ matrix.branch }} + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' - # Generates and submits a dependency graph, enabling Dependabot Alerts for all project dependencies. - # See: https://github.com/gradle/actions/blob/main/dependency-submission/README.md - - name: Generate and submit dependency graph - uses: gradle/actions/dependency-submission@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 + # Generates and submits a dependency graph, enabling Dependabot Alerts for all project dependencies. + # See: https://github.com/gradle/actions/blob/main/dependency-submission/README.md + - name: Generate and submit dependency graph + uses: gradle/actions/dependency-submission@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 1103d57..548f310 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -47,20 +47,20 @@ jobs: version: 1.19.2 steps: - - uses: actions/checkout@v4 - with: - ref: ${{ matrix.branch }} - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'temurin' - server-id: github # Value of the distributionManagement/repository/id field of the pom.xml - settings-path: ${{ github.workspace }} # location for the settings.xml file - - name: Setup Gradle - uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 - - name: Build with Gradle - run: ./gradlew build + - uses: actions/checkout@v4 + with: + ref: ${{ matrix.branch }} + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + server-id: github # Value of the distributionManagement/repository/id field of the pom.xml + settings-path: ${{ github.workspace }} # location for the settings.xml file + - name: Setup Gradle + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 + - name: Build with Gradle + run: ./gradlew build publish-ghp: runs-on: ubuntu-latest diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index ce71737..c78ad87 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -26,7 +26,7 @@ on: - changelog.md - LICENSE - README.md - workflow_dispatch: {} + workflow_dispatch: { } jobs: build: @@ -35,20 +35,20 @@ jobs: contents: read steps: - - uses: actions/checkout@v4 - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'temurin' + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' - # Configure Gradle for optimal use in GiHub Actions, including caching of downloaded dependencies. - # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md - - name: Setup Gradle - uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 + # Configure Gradle for optimal use in GiHub Actions, including caching of downloaded dependencies. + # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md + - name: Setup Gradle + uses: gradle/actions/setup-gradle@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 - - name: Build with Gradle Wrapper - run: ./gradlew build + - name: Build with Gradle Wrapper + run: ./gradlew build # NOTE: The Gradle Wrapper is the default and recommended way to run Gradle (https://docs.gradle.org/current/userguide/gradle_wrapper.html). # If your project does not have the Gradle Wrapper configured, you can use the following configuration to run Gradle with a specified version. @@ -67,14 +67,14 @@ jobs: contents: write steps: - - uses: actions/checkout@v4 - - name: Set up JDK 17 - uses: actions/setup-java@v4 - with: - java-version: '17' - distribution: 'temurin' + - uses: actions/checkout@v4 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' - # Generates and submits a dependency graph, enabling Dependabot Alerts for all project dependencies. - # See: https://github.com/gradle/actions/blob/main/dependency-submission/README.md - - name: Generate and submit dependency graph - uses: gradle/actions/dependency-submission@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 + # Generates and submits a dependency graph, enabling Dependabot Alerts for all project dependencies. + # See: https://github.com/gradle/actions/blob/main/dependency-submission/README.md + - name: Generate and submit dependency graph + uses: gradle/actions/dependency-submission@417ae3ccd767c252f5661f1ace9f835f9654f2b5 # v3.1.0 diff --git a/README.md b/README.md index b6f7d23..e4d1294 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,24 @@ -# Create Train Perspective Fixer +# Create: Train Perspective -[![Java CI with Gradle](https://github.com/der-fruhling-entertainment/create-train-perspective/actions/workflows/gradle.yml/badge.svg)](https://github.com/der-fruhling/create-train-perspective/actions/workflows/gradle.yml) [![Modrinth](https://img.shields.io/badge/dynamic/json?labelColor=black&color=grey&label=&query=title&url=https://api.modrinth.com/v2/project/create-train-perspective&style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAJPUExURQAAABvZahWnUha1WAYzGQlHIxvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZav///9ScwmYAAADDdFJOUwAAAAAAAA8zW3uOYwIBK3rB6Pn+ml18KiGL5HEDquOIH07R/UzKz2zu+uLHIibtafWkVCMNBRqg7/RQuT8EQbvT+5ETDBSU/NAgCSdZlcQKii7mtxJY5fF/7D1SRkB+EcWh4UilOOtPMdTCR1PqN969vmGDCw7G4DSSsAcGHrSPr3bds5CEwDKoXumcZdwcG4KmjayX32A79pjOqRjIFoXynVYVgPi6qxDnL78p2obVJFquNbGZCPdyvHPZ1yhuh8s+iRzcsrEAAAABYktHRMQUDBvhAAAAB3RJTUUH5wQXDwgZWDUtiQAAAqRJREFUOMttU/k7lFEU/k4L4hsxtNAnhRgiJZOiSfbI2oJpmRFCi2kV0aaNVLTIEpVISmnf97r/WO+534yZnqfzw73vOe+559xz7rmKIoVYvLx95vj6qUSqVBW3sGrwnxsQaAwSwcDz5i9g0wxPfmFIqJCyiEgLE4vDl7iD8PGlETotIqOQahlAdJTLA5sWY5JsbNzysHiihEBWViRqRDOlgyFmJVtMq5JWJ5vhvyZlLevrEmUILKl8PihtvYWcYt6QLmNwFjjEb4SSkZnlZLO5yJzcPBg35bODwZfPZxYwWbC5sKjYzwBUkssxSg1wKNsCtHUb89vTy3GwopBxDmcJ9YdDJYB1B9t2WmUtcbtkqt18Mxsp9irsezS2VEu+uka/mqUWSrFd2VsnhLEetoZ9TFv3HwCexdUdjBWi0aH4YTuEvtoPM3/EO1nnuTpEjD2qHIM54DhR0wmA5hZySzIntyknsbZyi8IB0tp07tRpBDKfgeWsdDjHDlFGRIjnl3O0t573gcMFUBeVS1gvlxB1dOZxv0pIu9IF01UDZRdjr1SuZQhxvbvnRrmsMePmrdsrGPRaKP8OLtmn9KM7A4N3xb8yNExUb5RlZt2btpZbXajzPoYkBaDKrtADp3HkYdloo56ndgx37UcHxSP0tIWBGH9cg1nx6TJFTNhS7eCfcA1PJ+GgDbLDs2GuX3V05Ohj0xYSBGumyq/yfApw4EWTRxPJqxQvIF6+ks9Gr0d4nN+8Nbhoi+NdJEwVSc6hVNvHOUvg+5qeDxoP3GQz6x8/qXLuZ6Op7SPy+gNTnydSELabk1Z8Mbs/hlr4dbobfUgxJMS3UdXza9H33jqnA3/OH41FCZ7/l7HW8vOXiWc9GvPf06D953/T2O/EP8HBNtcH0Zm/lqFNUgTAex4AAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDQtMjNUMTU6MDg6MjQrMDA6MDAE5dOaAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA0LTIzVDE1OjA4OjI0KzAwOjAwdbhrJgAAACh0RVh0ZGF0ZTp0aW1lc3RhbXAAMjAyMy0wNC0yM1QxNTowODoyNSswMDowMITaQU0AAAAASUVORK5CYII=)](https://modrinth.com/mod/create-train-perspective) -![Versions](https://img.shields.io/badge/dynamic/json?label=Available%20for&color=4bab62&query=version&url=https://api.blueish.dev/api/minecraft/version?id=create-train-perspective) -![Download Counter](https://img.shields.io/badge/dynamic/json?labelColor=black&color=grey&label=&suffix=%20downloads&query=downloads&url=https://api.modrinth.com/v2/project/create-train-perspective&style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAJPUExURQAAABvZahWnUha1WAYzGQlHIxvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZav///9ScwmYAAADDdFJOUwAAAAAAAA8zW3uOYwIBK3rB6Pn+ml18KiGL5HEDquOIH07R/UzKz2zu+uLHIibtafWkVCMNBRqg7/RQuT8EQbvT+5ETDBSU/NAgCSdZlcQKii7mtxJY5fF/7D1SRkB+EcWh4UilOOtPMdTCR1PqN969vmGDCw7G4DSSsAcGHrSPr3bds5CEwDKoXumcZdwcG4KmjayX32A79pjOqRjIFoXynVYVgPi6qxDnL78p2obVJFquNbGZCPdyvHPZ1yhuh8s+iRzcsrEAAAABYktHRMQUDBvhAAAAB3RJTUUH5wQXDwgZWDUtiQAAAqRJREFUOMttU/k7lFEU/k4L4hsxtNAnhRgiJZOiSfbI2oJpmRFCi2kV0aaNVLTIEpVISmnf97r/WO+534yZnqfzw73vOe+559xz7rmKIoVYvLx95vj6qUSqVBW3sGrwnxsQaAwSwcDz5i9g0wxPfmFIqJCyiEgLE4vDl7iD8PGlETotIqOQahlAdJTLA5sWY5JsbNzysHiihEBWViRqRDOlgyFmJVtMq5JWJ5vhvyZlLevrEmUILKl8PihtvYWcYt6QLmNwFjjEb4SSkZnlZLO5yJzcPBg35bODwZfPZxYwWbC5sKjYzwBUkssxSg1wKNsCtHUb89vTy3GwopBxDmcJ9YdDJYB1B9t2WmUtcbtkqt18Mxsp9irsezS2VEu+uka/mqUWSrFd2VsnhLEetoZ9TFv3HwCexdUdjBWi0aH4YTuEvtoPM3/EO1nnuTpEjD2qHIM54DhR0wmA5hZySzIntyknsbZyi8IB0tp07tRpBDKfgeWsdDjHDlFGRIjnl3O0t573gcMFUBeVS1gvlxB1dOZxv0pIu9IF01UDZRdjr1SuZQhxvbvnRrmsMePmrdsrGPRaKP8OLtmn9KM7A4N3xb8yNExUb5RlZt2btpZbXajzPoYkBaDKrtADp3HkYdloo56ndgx37UcHxSP0tIWBGH9cg1nx6TJFTNhS7eCfcA1PJ+GgDbLDs2GuX3V05Ohj0xYSBGumyq/yfApw4EWTRxPJqxQvIF6+ks9Gr0d4nN+8Nbhoi+NdJEwVSc6hVNvHOUvg+5qeDxoP3GQz6x8/qXLuZ6Op7SPy+gNTnydSELabk1Z8Mbs/hlr4dbobfUgxJMS3UdXza9H33jqnA3/OH41FCZ7/l7HW8vOXiWc9GvPf06D953/T2O/EP8HBNtcH0Zm/lqFNUgTAex4AAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDQtMjNUMTU6MDg6MjQrMDA6MDAE5dOaAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA0LTIzVDE1OjA4OjI0KzAwOjAwdbhrJgAAACh0RVh0ZGF0ZTp0aW1lc3RhbXAAMjAyMy0wNC0yM1QxNTowODoyNSswMDowMITaQU0AAAAASUVORK5CYII=) +[![Versions](https://img.shields.io/badge/1.19.2%2C%201.20.1-grey?style=flat&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAIGNIUk0AAHomAACAhAAA%2BgAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAJPUExURQAAABvZahWnUha1WAYzGQlHIxvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZav%2F%2F%2F9ScwmYAAADDdFJOUwAAAAAAAA8zW3uOYwIBK3rB6Pn%2Bml18KiGL5HEDquOIH07R%2FUzKz2zu%2BuLHIibtafWkVCMNBRqg7%2FRQuT8EQbvT%2B5ETDBSU%2FNAgCSdZlcQKii7mtxJY5fF%2F7D1SRkB%2BEcWh4UilOOtPMdTCR1PqN969vmGDCw7G4DSSsAcGHrSPr3bds5CEwDKoXumcZdwcG4KmjayX32A79pjOqRjIFoXynVYVgPi6qxDnL78p2obVJFquNbGZCPdyvHPZ1yhuh8s%2BiRzcsrEAAAABYktHRMQUDBvhAAAAB3RJTUUH5wQXDwgZWDUtiQAAAqRJREFUOMttU%2Fk7lFEU%2Fk4L4hsxtNAnhRgiJZOiSfbI2oJpmRFCi2kV0aaNVLTIEpVISmnf97r%2FWO%2B534yZnqfzw73vOe%2B559xz7rmKIoVYvLx95vj6qUSqVBW3sGrwnxsQaAwSwcDz5i9g0wxPfmFIqJCyiEgLE4vDl7iD8PGlETotIqOQahlAdJTLA5sWY5JsbNzysHiihEBWViRqRDOlgyFmJVtMq5JWJ5vhvyZlLevrEmUILKl8PihtvYWcYt6QLmNwFjjEb4SSkZnlZLO5yJzcPBg35bODwZfPZxYwWbC5sKjYzwBUkssxSg1wKNsCtHUb89vTy3GwopBxDmcJ9YdDJYB1B9t2WmUtcbtkqt18Mxsp9irsezS2VEu%2Buka%2FmqUWSrFd2VsnhLEetoZ9TFv3HwCexdUdjBWi0aH4YTuEvtoPM3%2FEO1nnuTpEjD2qHIM54DhR0wmA5hZySzIntyknsbZyi8IB0tp07tRpBDKfgeWsdDjHDlFGRIjnl3O0t573gcMFUBeVS1gvlxB1dOZxv0pIu9IF01UDZRdjr1SuZQhxvbvnRrmsMePmrdsrGPRaKP8OLtmn9KM7A4N3xb8yNExUb5RlZt2btpZbXajzPoYkBaDKrtADp3HkYdloo56ndgx37UcHxSP0tIWBGH9cg1nx6TJFTNhS7eCfcA1PJ%2BGgDbLDs2GuX3V05Ohj0xYSBGumyq%2FyfApw4EWTRxPJqxQvIF6%2Bks9Gr0d4nN%2B8Nbhoi%2BNdJEwVSc6hVNvHOUvg%2B5qeDxoP3GQz6x8%2FqXLuZ6Op7SPy%2BgNTnydSELabk1Z8Mbs%2Fhlr4dbobfUgxJMS3UdXza9H33jqnA3%2FOH41FCZ7%2Fl7HW8vOXiWc9GvPf06D953%2FT2O%2FEP8HBNtcH0Zm%2FlqFNUgTAex4AAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDQtMjNUMTU6MDg6MjQrMDA6MDAE5dOaAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA0LTIzVDE1OjA4OjI0KzAwOjAwdbhrJgAAACh0RVh0ZGF0ZTp0aW1lc3RhbXAAMjAyMy0wNC0yM1QxNTowODoyNSswMDowMITaQU0AAAAASUVORK5CYII%3D&labelColor=black)](https://modrinth.com/mod/create-train-perspective) +[![Download Counter](https://img.shields.io/badge/dynamic/json?labelColor=black&color=grey&label=&suffix=%20downloads&query=downloads&url=https://api.modrinth.com/v2/project/create-train-perspective&style=flat&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAJPUExURQAAABvZahWnUha1WAYzGQlHIxvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZahvZav///9ScwmYAAADDdFJOUwAAAAAAAA8zW3uOYwIBK3rB6Pn+ml18KiGL5HEDquOIH07R/UzKz2zu+uLHIibtafWkVCMNBRqg7/RQuT8EQbvT+5ETDBSU/NAgCSdZlcQKii7mtxJY5fF/7D1SRkB+EcWh4UilOOtPMdTCR1PqN969vmGDCw7G4DSSsAcGHrSPr3bds5CEwDKoXumcZdwcG4KmjayX32A79pjOqRjIFoXynVYVgPi6qxDnL78p2obVJFquNbGZCPdyvHPZ1yhuh8s+iRzcsrEAAAABYktHRMQUDBvhAAAAB3RJTUUH5wQXDwgZWDUtiQAAAqRJREFUOMttU/k7lFEU/k4L4hsxtNAnhRgiJZOiSfbI2oJpmRFCi2kV0aaNVLTIEpVISmnf97r/WO+534yZnqfzw73vOe+559xz7rmKIoVYvLx95vj6qUSqVBW3sGrwnxsQaAwSwcDz5i9g0wxPfmFIqJCyiEgLE4vDl7iD8PGlETotIqOQahlAdJTLA5sWY5JsbNzysHiihEBWViRqRDOlgyFmJVtMq5JWJ5vhvyZlLevrEmUILKl8PihtvYWcYt6QLmNwFjjEb4SSkZnlZLO5yJzcPBg35bODwZfPZxYwWbC5sKjYzwBUkssxSg1wKNsCtHUb89vTy3GwopBxDmcJ9YdDJYB1B9t2WmUtcbtkqt18Mxsp9irsezS2VEu+uka/mqUWSrFd2VsnhLEetoZ9TFv3HwCexdUdjBWi0aH4YTuEvtoPM3/EO1nnuTpEjD2qHIM54DhR0wmA5hZySzIntyknsbZyi8IB0tp07tRpBDKfgeWsdDjHDlFGRIjnl3O0t573gcMFUBeVS1gvlxB1dOZxv0pIu9IF01UDZRdjr1SuZQhxvbvnRrmsMePmrdsrGPRaKP8OLtmn9KM7A4N3xb8yNExUb5RlZt2btpZbXajzPoYkBaDKrtADp3HkYdloo56ndgx37UcHxSP0tIWBGH9cg1nx6TJFTNhS7eCfcA1PJ+GgDbLDs2GuX3V05Ohj0xYSBGumyq/yfApw4EWTRxPJqxQvIF6+ks9Gr0d4nN+8Nbhoi+NdJEwVSc6hVNvHOUvg+5qeDxoP3GQz6x8/qXLuZ6Op7SPy+gNTnydSELabk1Z8Mbs/hlr4dbobfUgxJMS3UdXza9H33jqnA3/OH41FCZ7/l7HW8vOXiWc9GvPf06D953/T2O/EP8HBNtcH0Zm/lqFNUgTAex4AAAAldEVYdGRhdGU6Y3JlYXRlADIwMjMtMDQtMjNUMTU6MDg6MjQrMDA6MDAE5dOaAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIzLTA0LTIzVDE1OjA4OjI0KzAwOjAwdbhrJgAAACh0RVh0ZGF0ZTp0aW1lc3RhbXAAMjAyMy0wNC0yM1QxNTowODoyNSswMDowMITaQU0AAAAASUVORK5CYII=)](https://modrinth.com/mod/create-train-perspective) +[![GitHub](https://img.shields.io/badge/github-der--fruhling%2Fcreate--train--perspective-0a0047)](https://github.com/der-fruhling/create-train-perspective) +[![Support Discord](https://img.shields.io/badge/support_discord-~yes~-375fe5)](https://discord.gg/XJWVax7mbg) _More immersion!_ ## What is this? -With the normal behavior, the player's camera stays in the same direction when the train turns, giving the appearance that the player themselves are turning. This mod turns the player's camera with the train they're riding to provide more immersion. +With the normal Create behavior, the player's camera stays in the same direction when the train turns, giving the +appearance that the player themselves are turning. This mod turns the player's camera with the train they're riding to +provide more immersion. This mod also applies "lean" and "roll" to the player when the train is on a slope. -**Notice:** This mod may cause motion sickness. Just like real trains, but blockier. - -## How do I build it? +The mod should also work while standing on the train, though this functionality is a bit experimental at the moment (and +horribly unsafe). If you have any issues (with the +mod), [remember to report them!](https://github.com/der-fruhling-entertainment/create-train-perspective/issues) -### macOS/Linux and Windows (Powershell) -```shell -./gradlew runClient # run the client -./gradlew build # build the jar -``` +**Notice:** This mod may cause motion sickness. Just like real trains, but blockier. -### Windows (Command Prompt) -```batch -gradlew.bat runClient -gradlew.bat build -``` +This is a client-side only mod. It does nothing on the server and will probably crash if you try to use it on one +anyways, so don't do that!! diff --git a/changelog.md b/changelog.md index 0edd69a..c983388 100644 --- a/changelog.md +++ b/changelog.md @@ -1,10 +1,10 @@ A minor update to fix some larger issues. Changelog: -- **Fixed:** Crash when using Figura. -- **Fixed:** Jittery rotations when in third-person and probably also when viewing other players on trains. -- **Fixed:** Some jittering issues when using this mod with others. -- **Improved:** Standing while on a train is now tolerable. + +- **Fixed:** Player camera turns when an unrelated player is on a train. +- **Added:** Ability for non-player entities to be affected by this mod. +- **Technical:** Cleaned up the code a bit. [View full change log.](https://github.com/der-fruhling/create-train-perspective/compare/v0.4.0...v0.4.1) diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Camera3D.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Camera3D.java index 7675707..6aed625 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Camera3D.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Camera3D.java @@ -2,5 +2,6 @@ public interface Camera3D { float getZRot(); + float getExtraYRot(); } diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Conditional.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Conditional.java index 58c296a..7fead56 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Conditional.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Conditional.java @@ -3,23 +3,26 @@ import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.player.RemotePlayer; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; public class Conditional { - private Conditional() {} - + private Conditional() { + } + public static boolean shouldApplyPerspectiveTo(Entity player) { - if(ModConfig.INSTANCE.enabled) { - return (ModConfig.INSTANCE.applyToOthers && player instanceof RemotePlayer) - || player instanceof LocalPlayer; + if (ModConfig.INSTANCE.enabled) { + return (ModConfig.INSTANCE.applyToNonPlayerEntities && !ModConfig.INSTANCE.blockedEntities.contains(EntityType.getKey(player.getType()))) || + (ModConfig.INSTANCE.applyToOthers && player instanceof RemotePlayer) + || player instanceof LocalPlayer; } else { return false; } } - + public static boolean shouldApplyLeaning() { return ModConfig.INSTANCE.leanEnabled; } - + public static boolean shouldApplyRolling() { return ModConfig.INSTANCE.rollEnabled; } diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/CreateTrainPerspectiveMod.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/CreateTrainPerspectiveMod.java index 5db612a..25c81f9 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/CreateTrainPerspectiveMod.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/CreateTrainPerspectiveMod.java @@ -2,11 +2,9 @@ import com.simibubi.create.content.trains.entity.CarriageContraptionEntity; import dev.architectury.event.events.client.ClientTickEvent; -import dev.architectury.event.events.common.TickEvent; -import net.minecraft.client.Minecraft; import net.minecraft.world.entity.Entity; -import java.util.*; +import java.util.Objects; public class CreateTrainPerspectiveMod { public static final String MODID = "create_train_perspective"; @@ -20,11 +18,11 @@ public CreateTrainPerspectiveMod() { } public void onEntityMountEvent(boolean isMounting, Entity entityMounting, Entity entityBeingMounted) { - if( - Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(entityMounting) instanceof Perspective persp && - entityBeingMounted instanceof CarriageContraptionEntity contraption + if ( + entityMounting instanceof Perspective persp && + entityBeingMounted instanceof CarriageContraptionEntity contraption ) { - if(isMounting) { + if (isMounting) { onEntityMount(persp, contraption); } else { onEntityDismount(persp); @@ -33,8 +31,8 @@ public void onEntityMountEvent(boolean isMounting, Entity entityMounting, Entity } public void onEntityMount(Perspective persp, CarriageContraptionEntity contraption) { - if(persp.getRotationState() == null) { - var state = new RotationState(contraption, false, true); + if (persp.getRotationState() == null) { + var state = new RotationState(contraption, false); persp.setRotationState(state); var carriage = state.getContraption(); assert carriage != null; @@ -46,20 +44,19 @@ public void onEntityMount(Perspective persp, CarriageContraptionEntity contrapti } private void onEntityDismount(Perspective persp) { - if(persp.getRotationState() != null) { - persp.setRotationState(null); - persp.disable(); + if (persp.getRotationState() != null) { + persp.getRotationState().onDismount(); } } public void tickStandingEntity(final CarriageContraptionEntity contraption, final Entity entity) { - if(entity.getVehicle() != null) return; + if (entity.getVehicle() != null) return; + if (!(entity instanceof Perspective persp)) return; - var persp = (Perspective) Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(entity); var state = persp.getRotationState(); if (state == null || !Objects.equals(state.getContraption(), contraption)) { - state = new RotationState(contraption, true, false); + state = new RotationState(contraption, true); persp.setRotationState(state); var carriage = state.getContraption(); assert carriage != null; @@ -71,34 +68,32 @@ public void tickStandingEntity(final CarriageContraptionEntity contraption, fina private void tickPerspectiveState(Entity player, Perspective persp, RotationState state) { var carriage = state.getContraption(); - if(carriage == null) return; + if (carriage == null) return; persp.setLean(carriage.pitch); persp.setYaw(carriage.yaw); player.setYRot(player.getYRot() + state.getYawDelta()); player.setYBodyRot(player.getYRot()); - if(state.isStanding() && !state.isMounted()) { + if (state.isStanding() && !state.isSeated()) { state.tick(); - if(state.getTicksSinceLastUpdate() > 5) { + if (state.getTicksSinceLastUpdate() > 5) { state.setShouldTickState(false); } } } - public void tickEntity(final Entity entity) { - if(Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(entity) instanceof Perspective persp - && persp.getRotationState() != null - && Conditional.shouldApplyPerspectiveTo(entity)) { + public void tickEntity(Entity entity, Perspective persp) { + if (persp.getRotationState() != null) { var state = persp.getRotationState(); assert state != null; - if(state.shouldTickState()) { + if (state.shouldTickState()) { tickPerspectiveState(entity, persp, state); } else { persp.diminish(); - if(persp.isDiminished()) { + if (persp.isDiminished()) { persp.setRotationState(null); persp.disable(); } diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/MixinUtil.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/MixinUtil.java index efb1980..dbf07f0 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/MixinUtil.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/MixinUtil.java @@ -7,27 +7,24 @@ import net.minecraft.world.phys.Vec3; public class MixinUtil { - private MixinUtil() {} + private MixinUtil() { + } public static Camera3D asCamera3D(Camera camera) { return (Camera3D) camera; } - private static float invCos(float x) { - return Mth.cos(x + Mth.PI); - } - public static float applyDirectionXRotChange(Perspective persp, float xRot, float yRot, float f) { return xRot - persp.getLean(f) - * ModConfig.INSTANCE.leanMagnitude - * Mth.sin((persp.getYaw(f) - yRot) * Mth.DEG_TO_RAD); + * ModConfig.INSTANCE.leanMagnitude + * Mth.sin((persp.getYaw(f) - yRot) * Mth.DEG_TO_RAD); } public static float getExtraYRot(Perspective persp, float xRot, float yRot, float f) { - return persp.getLean(f) * (xRot / 90.0f) * invCos((persp.getYaw(f) - yRot) * Mth.DEG_TO_RAD); + return persp.getLean(f) * (xRot / 90.0f) * -Mth.cos((persp.getYaw(f) - yRot) * Mth.DEG_TO_RAD); } - public static Vector3d applyStandingCameraRotation(Player player, double x, double y, double z, Perspective persp, float f) { + public static Vector3d applyStandingCameraTranslation(Player player, double x, double y, double z, Perspective persp, float f) { var lean = persp.getLean(f) * Mth.DEG_TO_RAD; var yaw = persp.getYaw(f) * Mth.DEG_TO_RAD; var height = player.getEyeHeight(); @@ -39,8 +36,8 @@ public static Vector3d applyStandingCameraRotation(Player player, double x, doub return new Vector3d(newX, newY, newZ); } - public static Vec3 applyStandingCameraRotation(Player player, Vec3 v, Perspective persp, float f) { - var vec = applyStandingCameraRotation(player, v.x, v.y, v.z, persp, f); + public static Vec3 applyStandingCameraTranslation(Player player, Vec3 v, Perspective persp, float f) { + var vec = applyStandingCameraTranslation(player, v.x, v.y, v.z, persp, f); return new Vec3(vec.x, vec.y, vec.z); } } diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/ModConfig.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/ModConfig.java index b944260..ad7dfe6 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/ModConfig.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/ModConfig.java @@ -7,26 +7,20 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; import java.io.IOException; import java.nio.file.*; +import java.util.ArrayList; +import java.util.List; public class ModConfig { - private ModConfig() {} - - public boolean enabled = true; - public boolean leanEnabled = true; - public float leanMagnitude = 1.0f; - public boolean rollEnabled = true; - public float rollMagnitude = 1.0f; - public boolean applyToOthers = true; - public boolean dbgShowStandingTransforms = false; - private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); private static final WatchService WATCH_SERVICE; private static final Path PATH = Minecraft.getInstance().gameDirectory.toPath() - .resolve("config") - .resolve("create-train-perspective.json"); + .resolve("config") + .resolve("create-train-perspective.json"); + public static ModConfig INSTANCE = loadConfig(); static { try { @@ -37,12 +31,25 @@ private ModConfig() {} } } + public boolean enabled = true; + public boolean leanEnabled = true; + public float leanMagnitude = 1.0f; + public boolean rollEnabled = true; + public float rollMagnitude = 1.0f; + public boolean applyToOthers = true; + public boolean applyToNonPlayerEntities = true; + public List blockedEntities = new ArrayList<>(); + public boolean dbgShowStandingTransforms = false; + + private ModConfig() { + } + public static void tick() { var key = WATCH_SERVICE.poll(); - if(key != null) { - for(var event : key.pollEvents()) { - if(event.context().toString().equals(PATH.getFileName().toString())) { + if (key != null) { + for (var event : key.pollEvents()) { + if (event.context().toString().equals(PATH.getFileName().toString())) { INSTANCE = loadConfig(); key.reset(); } @@ -50,10 +57,8 @@ public static void tick() { } } - public static ModConfig INSTANCE = loadConfig(); - private static ModConfig loadConfig() { - if(Files.exists(PATH)) { + if (Files.exists(PATH)) { try { var configJson = Files.readString(PATH); return GSON.fromJson(configJson, ModConfig.class); @@ -67,19 +72,11 @@ private static ModConfig loadConfig() { } } - private void save() { - try(var file = Files.newBufferedWriter(PATH)) { - GSON.toJson(this, file); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - public static Screen createConfigScreen(Screen parent) { var builder = ConfigBuilder.create() - .setParentScreen(parent) - .setTitle(Component.translatable("title.create_train_perspective.config")) - .setSavingRunnable(INSTANCE::save); + .setParentScreen(parent) + .setTitle(Component.translatable("title.create_train_perspective.config")) + .setSavingRunnable(INSTANCE::save); var general = builder.getOrCreateCategory(Component.translatable( "category.create_train_perspective.general" @@ -88,35 +85,35 @@ public static Screen createConfigScreen(Screen parent) { var entryBuilder = builder.entryBuilder(); general.addEntry(entryBuilder - .startBooleanToggle( - Component.translatable("option.create_train_perspective.enabled"), - INSTANCE.enabled) - .setTooltip(Component.translatable("option.create_train_perspective.enabled.tooltip")) - .setSaveConsumer(value -> INSTANCE.enabled = value) - .setDefaultValue(true) - .build()); + .startBooleanToggle( + Component.translatable("option.create_train_perspective.enabled"), + INSTANCE.enabled) + .setTooltip(Component.translatable("option.create_train_perspective.enabled.tooltip")) + .setSaveConsumer(value -> INSTANCE.enabled = value) + .setDefaultValue(true) + .build()); var leaning = entryBuilder.startSubCategory(Component.translatable( "category.create_train_perspective.leaning" )); leaning.add(entryBuilder - .startBooleanToggle( - Component.translatable("option.create_train_perspective.leaning.enabled"), - INSTANCE.leanEnabled) - .setTooltip(Component.translatable("option.create_train_perspective.leaning.enabled.tooltip")) - .setSaveConsumer(value -> INSTANCE.leanEnabled = value) - .setDefaultValue(true) - .build()); + .startBooleanToggle( + Component.translatable("option.create_train_perspective.leaning.enabled"), + INSTANCE.leanEnabled) + .setTooltip(Component.translatable("option.create_train_perspective.leaning.enabled.tooltip")) + .setSaveConsumer(value -> INSTANCE.leanEnabled = value) + .setDefaultValue(true) + .build()); leaning.add(entryBuilder - .startBooleanToggle( - Component.translatable("option.create_train_perspective.leaning.roll_enabled"), - INSTANCE.rollEnabled) - .setTooltip(Component.translatable("option.create_train_perspective.leaning.roll_enabled.tooltip")) - .setSaveConsumer(value -> INSTANCE.rollEnabled = value) - .setDefaultValue(true) - .build()); + .startBooleanToggle( + Component.translatable("option.create_train_perspective.leaning.roll_enabled"), + INSTANCE.rollEnabled) + .setTooltip(Component.translatable("option.create_train_perspective.leaning.roll_enabled.tooltip")) + .setSaveConsumer(value -> INSTANCE.rollEnabled = value) + .setDefaultValue(true) + .build()); general.addEntry(leaning.build()); @@ -125,13 +122,13 @@ public static Screen createConfigScreen(Screen parent) { )); multiplayer.add(entryBuilder - .startBooleanToggle( - Component.translatable("option.create_train_perspective.multiplayer.apply_to_others"), - INSTANCE.applyToOthers) - .setTooltip(Component.translatable("option.create_train_perspective.multiplayer.apply_to_others.tooltip")) - .setSaveConsumer(value -> INSTANCE.applyToOthers = value) - .setDefaultValue(true) - .build()); + .startBooleanToggle( + Component.translatable("option.create_train_perspective.multiplayer.apply_to_others"), + INSTANCE.applyToOthers) + .setTooltip(Component.translatable("option.create_train_perspective.multiplayer.apply_to_others.tooltip")) + .setSaveConsumer(value -> INSTANCE.applyToOthers = value) + .setDefaultValue(true) + .build()); general.addEntry(multiplayer.build()); @@ -140,22 +137,40 @@ public static Screen createConfigScreen(Screen parent) { )); advanced.add(entryBuilder - .startFloatField( - Component.translatable("option.create_train_perspective.advanced.lean_magnitude"), - INSTANCE.leanMagnitude) - .setTooltip(Component.translatable("option.create_train_perspective.advanced.lean_magnitude.tooltip")) - .setSaveConsumer(value -> INSTANCE.leanMagnitude = value) - .setDefaultValue(1.0f) - .build()); + .startFloatField( + Component.translatable("option.create_train_perspective.advanced.lean_magnitude"), + INSTANCE.leanMagnitude) + .setTooltip(Component.translatable("option.create_train_perspective.advanced.lean_magnitude.tooltip")) + .setSaveConsumer(value -> INSTANCE.leanMagnitude = value) + .setDefaultValue(1.0f) + .build()); + + advanced.add(entryBuilder + .startFloatField( + Component.translatable("option.create_train_perspective.advanced.roll_magnitude"), + INSTANCE.rollMagnitude) + .setTooltip(Component.translatable("option.create_train_perspective.advanced.roll_magnitude.tooltip")) + .setSaveConsumer(value -> INSTANCE.rollMagnitude = value) + .setDefaultValue(1.0f) + .build()); advanced.add(entryBuilder - .startFloatField( - Component.translatable("option.create_train_perspective.advanced.roll_magnitude"), - INSTANCE.rollMagnitude) - .setTooltip(Component.translatable("option.create_train_perspective.advanced.roll_magnitude.tooltip")) - .setSaveConsumer(value -> INSTANCE.rollMagnitude = value) - .setDefaultValue(1.0f) - .build()); + .startBooleanToggle( + Component.translatable("option.create_train_perspective.advanced.apply_to_entities"), + INSTANCE.applyToNonPlayerEntities) + .setTooltip(Component.translatable("option.create_train_perspective.advanced.apply_to_entities.tooltip")) + .setSaveConsumer(value -> INSTANCE.applyToNonPlayerEntities = value) + .setDefaultValue(true) + .build()); + + advanced.add(entryBuilder + .startStrList( + Component.translatable("option.create_train_perspective.advanced.blocked_entities"), + INSTANCE.blockedEntities.stream().map(ResourceLocation::toString).toList()) + .setTooltip(Component.translatable("option.create_train_perspective.advanced.blocked_entities.tooltip")) + .setSaveConsumer(value -> INSTANCE.blockedEntities = value.stream().map(ResourceLocation::new).toList()) + .setDefaultValue(new ArrayList<>()) + .build()); var debug = entryBuilder.startSubCategory(Component.translatable("category.create_train_perspective.debug")); @@ -177,4 +192,12 @@ public static Screen createConfigScreen(Screen parent) { return builder.build(); } + + private void save() { + try (var file = Files.newBufferedWriter(PATH)) { + GSON.toJson(this, file); + } catch (IOException e) { + throw new RuntimeException(e); + } + } } diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Perspective.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Perspective.java index 005ffcb..5042d74 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Perspective.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/Perspective.java @@ -5,13 +5,22 @@ public interface Perspective { void enable(float initialLean, float initialYaw); + void disable(); + boolean isEnabled(); + void setLean(float lean); + void setYaw(float yaw); + float getLean(float f); + float getYaw(float f); - @Nullable RotationState getRotationState(); + + @Nullable + RotationState getRotationState(); + void setRotationState(@Nullable RotationState state); default void diminish() { diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/RotationState.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/RotationState.java index 523e1b0..cf117eb 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/RotationState.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/RotationState.java @@ -3,22 +3,19 @@ import com.simibubi.create.content.trains.entity.CarriageContraptionEntity; import org.jetbrains.annotations.Nullable; -public class RotationState implements RotationStateKeeper { +public class RotationState { private CarriageContraptionEntity contraption; + private boolean isStandingState; private float lastRecordedYaw; - private final boolean isStandingState; - private boolean isMounted; private boolean shouldTickState = true; private int ticksSinceLastUpdate = 0; - public RotationState(CarriageContraptionEntity contraption, boolean isStandingState, boolean isMounted) { + public RotationState(CarriageContraptionEntity contraption, boolean isStandingState) { this.contraption = contraption; lastRecordedYaw = contraption.yaw; this.isStandingState = isStandingState; - this.isMounted = isMounted; } - @Override public float getYawDelta() { while (contraption.yaw - lastRecordedYaw < -180.0f) { lastRecordedYaw -= 360.0f; @@ -33,58 +30,47 @@ public float getYawDelta() { return rotation; } - @Override public @Nullable CarriageContraptionEntity getContraption() { return contraption; } - @Override public void setCarriageEntity(@Nullable CarriageContraptionEntity contraption) { this.contraption = contraption; } - @Override public boolean isStanding() { return isStandingState; } - @Override - public boolean isMounted() { - return isMounted; + public boolean isSeated() { + return !isStandingState; } - @Override public boolean shouldTickState() { return shouldTickState; } - @Override public void onMounted() { - this.isMounted = true; + this.isStandingState = false; this.shouldTickState = true; } - @Override public void onDismount() { - this.isMounted = false; + this.isStandingState = true; } - @Override public void setShouldTickState(boolean shouldTickState) { this.shouldTickState = shouldTickState; } - @Override public int getTicksSinceLastUpdate() { return ticksSinceLastUpdate; } - @Override public void update() { ticksSinceLastUpdate = 0; } - @Override public void tick() { ticksSinceLastUpdate += 1; } diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/RotationStateKeeper.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/RotationStateKeeper.java deleted file mode 100644 index 655ab77..0000000 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/RotationStateKeeper.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.derfruhling.minecraft.create.trainperspective; - -import com.simibubi.create.content.trains.entity.CarriageContraptionEntity; -import org.jetbrains.annotations.Nullable; - -public interface RotationStateKeeper { - @Nullable CarriageContraptionEntity getContraption(); - void setCarriageEntity(@Nullable CarriageContraptionEntity entity); - boolean isStanding(); - boolean isMounted(); - boolean shouldTickState(); - void onMounted(); - void onDismount(); - void setShouldTickState(boolean value); - int getTicksSinceLastUpdate(); - void update(); - void tick(); - float getYawDelta(); -} \ No newline at end of file diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/AbstractContraptionEntityMixin.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/AbstractContraptionEntityMixin.java index d9c21eb..10ffc52 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/AbstractContraptionEntityMixin.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/AbstractContraptionEntityMixin.java @@ -23,10 +23,10 @@ private void onRegisterColliding( Entity entity, CallbackInfo ci ) { - if(!entity.level.isClientSide) return; - if((Object) this instanceof CarriageContraptionEntity carriage - && Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(entity) instanceof Perspective - && Conditional.shouldApplyPerspectiveTo(entity)) { + if (!entity.level.isClientSide) return; + if ((Object) this instanceof CarriageContraptionEntity carriage + && entity instanceof Perspective + && Conditional.shouldApplyPerspectiveTo(entity)) { CreateTrainPerspectiveMod.INSTANCE.tickStandingEntity(carriage, entity); } } diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/CameraMixin.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/CameraMixin.java index 57be6d9..4ca33d4 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/CameraMixin.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/CameraMixin.java @@ -1,13 +1,11 @@ package net.derfruhling.minecraft.create.trainperspective.mixin; -import com.llamalad7.mixinextras.sugar.Local; import com.mojang.math.Quaternion; import com.mojang.math.Vector3f; import net.derfruhling.minecraft.create.trainperspective.*; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Camera; -import net.minecraft.client.Minecraft; import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.network.chat.Component; import net.minecraft.util.Mth; @@ -23,15 +21,19 @@ @Implements({@Interface(iface = Camera3D.class, prefix = "c3d$")}) @Environment(EnvType.CLIENT) public abstract class CameraMixin { - @Shadow private Entity entity; - @Unique private float ctp$zRot; - @Unique private float ctp$extraYRot; - - @Shadow protected abstract void setRotation(float f, float g); - + @Shadow + private Entity entity; + @Unique + private float ctp$zRot; + @Unique + private float ctp$extraYRot; @Shadow @Final private Quaternion rotation; - @Shadow protected abstract void setPosition(double d, double e, double f); + @Shadow + protected abstract void setRotation(float f, float g); + + @Shadow + protected abstract void setPosition(double d, double e, double f); @Inject(method = "setRotation", at = @At(value = "INVOKE", target = "Lcom/mojang/math/Quaternion;mul(Lcom/mojang/math/Quaternion;)V", shift = At.Shift.AFTER, ordinal = 1)) private void applyRoll(float y, float x, CallbackInfo ci) { @@ -57,17 +59,15 @@ public void modifyRotations(Camera instance, boolean isThirdPerson, boolean bl2, float f) { - if(entity instanceof AbstractClientPlayer player + if (entity instanceof Perspective persp && Conditional.shouldApplyPerspectiveTo(entity) && Conditional.shouldApplyLeaning() && !isThirdPerson) { - var persp = (Perspective) Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(player); - - if(Conditional.shouldApplyRolling()) { + if (Conditional.shouldApplyRolling()) { ctp$zRot = persp.getLean(f) - * ModConfig.INSTANCE.rollMagnitude - * Mth.cos((persp.getYaw(f) - y) * Mth.DEG_TO_RAD) - * Mth.sin((x * Mth.DEG_TO_RAD + Mth.PI) / 2.0f); + * ModConfig.INSTANCE.rollMagnitude + * Mth.cos((persp.getYaw(f) - y) * Mth.DEG_TO_RAD) + * Mth.sin((x * Mth.DEG_TO_RAD + Mth.PI) / 2.0f); } ctp$extraYRot = MixinUtil.getExtraYRot(persp, x, y, f); @@ -92,16 +92,16 @@ public void modifyPosition(Camera instance, boolean isThirdPerson, boolean bl2, float f) { - if(entity instanceof AbstractClientPlayer player + if (entity instanceof AbstractClientPlayer clientPlayer && Conditional.shouldApplyPerspectiveTo(entity) && Conditional.shouldApplyLeaning() - && player.getVehicle() == null + && clientPlayer.getVehicle() == null && !isThirdPerson) { - var persp = (Perspective) Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(player); - var newV = MixinUtil.applyStandingCameraRotation(player, x, y, z, persp, f); + var persp = (Perspective) clientPlayer; + var newV = MixinUtil.applyStandingCameraTranslation(clientPlayer, x, y, z, persp, f); if (ModConfig.INSTANCE.dbgShowStandingTransforms) { - player.displayClientMessage(Component.literal("%f, %f, %f".formatted(x - newV.x, y - newV.y, z - newV.z)), true); + clientPlayer.displayClientMessage(Component.literal("%f, %f, %f".formatted(x - newV.x, y - newV.y, z - newV.z)), true); } setPosition(newV.x, newV.y, newV.z); diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/ClientLevelMixin.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/ClientLevelMixin.java index 179e78c..2e28eb2 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/ClientLevelMixin.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/ClientLevelMixin.java @@ -1,7 +1,9 @@ package net.derfruhling.minecraft.create.trainperspective.mixin; +import com.simibubi.create.content.trains.entity.CarriageContraptionEntity; import net.derfruhling.minecraft.create.trainperspective.Conditional; import net.derfruhling.minecraft.create.trainperspective.CreateTrainPerspectiveMod; +import net.derfruhling.minecraft.create.trainperspective.Perspective; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.world.entity.Entity; import org.spongepowered.asm.mixin.Mixin; @@ -13,15 +15,15 @@ public class ClientLevelMixin { @Inject(method = "tickNonPassenger", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;tick()V", shift = At.Shift.AFTER)) public void onTickNonPassenger(Entity entity, CallbackInfo ci) { - if(Conditional.shouldApplyPerspectiveTo(entity)) { - CreateTrainPerspectiveMod.INSTANCE.tickEntity(entity); + if (Conditional.shouldApplyPerspectiveTo(entity)) { + CreateTrainPerspectiveMod.INSTANCE.tickEntity(entity, (Perspective) entity); } } @Inject(method = "tickPassenger", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;rideTick()V", shift = At.Shift.AFTER)) public void onTickPassenger(Entity vehicle, Entity rider, CallbackInfo ci) { - if(Conditional.shouldApplyPerspectiveTo(rider)) { - CreateTrainPerspectiveMod.INSTANCE.tickEntity(rider); + if (Conditional.shouldApplyPerspectiveTo(rider) && vehicle instanceof CarriageContraptionEntity) { + CreateTrainPerspectiveMod.INSTANCE.tickEntity(rider, (Perspective) rider); } } } diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/CreateRaycastHelperMixin.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/CreateRaycastHelperMixin.java index ec55acf..dccd291 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/CreateRaycastHelperMixin.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/CreateRaycastHelperMixin.java @@ -5,7 +5,6 @@ import net.derfruhling.minecraft.create.trainperspective.Conditional; import net.derfruhling.minecraft.create.trainperspective.MixinUtil; import net.derfruhling.minecraft.create.trainperspective.Perspective; -import net.minecraft.client.Minecraft; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; @@ -16,12 +15,8 @@ public class CreateRaycastHelperMixin { @ModifyReturnValue(method = "getTraceOrigin", at = @At("RETURN")) private static Vec3 applyLeaning(Vec3 original, Player player) { - if(player.isLocalPlayer()) { - var renderer = Minecraft.getInstance() - .getEntityRenderDispatcher() - .getRenderer(player); - var persp = (Perspective) renderer; - return MixinUtil.applyStandingCameraRotation(player, original, persp, 1.0f); + if (Conditional.shouldApplyPerspectiveTo(player) && player instanceof Perspective persp) { + return MixinUtil.applyStandingCameraTranslation(player, original, persp, 1.0f); } else { return original; } @@ -29,16 +24,16 @@ private static Vec3 applyLeaning(Vec3 original, Player player) { @ModifyVariable(method = "getTraceTarget", at = @At("STORE"), index = 4) private static float modifyPitch(float pitch, Player player) { - if(Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(player) instanceof Perspective persp - && Conditional.shouldApplyPerspectiveTo(player)) { + if (player instanceof Perspective persp + && Conditional.shouldApplyPerspectiveTo(player)) { return MixinUtil.applyDirectionXRotChange(persp, pitch, player.getYRot(), 1.0f); } else return pitch; } @ModifyVariable(method = "getTraceTarget", at = @At("STORE"), index = 5) private static float modifyYaw(float yaw, Player player) { - if(Minecraft.getInstance().getEntityRenderDispatcher().getRenderer(player) instanceof Perspective persp - && Conditional.shouldApplyPerspectiveTo(player)) { + if (player instanceof Perspective persp + && Conditional.shouldApplyPerspectiveTo(player)) { return yaw + MixinUtil.getExtraYRot(persp, player.getXRot(), yaw, 1.0f); } else return yaw; } diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/EntityMixin.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/EntityMixin.java index 6339ba0..c692966 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/EntityMixin.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/EntityMixin.java @@ -1,41 +1,50 @@ package net.derfruhling.minecraft.create.trainperspective.mixin; import com.llamalad7.mixinextras.sugar.Local; -import net.derfruhling.minecraft.create.trainperspective.Conditional; -import net.derfruhling.minecraft.create.trainperspective.CreateTrainPerspectiveMod; -import net.derfruhling.minecraft.create.trainperspective.MixinUtil; -import net.derfruhling.minecraft.create.trainperspective.Perspective; +import net.derfruhling.minecraft.create.trainperspective.*; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.Minecraft; +import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.*; +import org.spongepowered.asm.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.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(Entity.class) +@Implements({@Interface(iface = Perspective.class, prefix = "ctp$")}) @Environment(EnvType.CLIENT) public abstract class EntityMixin { - @Shadow @Nullable private Entity vehicle; - @Shadow private Level level; + @Shadow + @Nullable + private Entity vehicle; + @Shadow + private Level level; + + @Unique + private boolean ctp$perspectiveActive = false; + @Unique + private float ctp$lean = 0.0f, ctp$yaw = 0.0f, ctp$oldLean = 0.0f, ctp$oldYaw = 0.0f; + @Unique + private @Nullable RotationState ctp$currentState = null; @Inject(method = "startRiding(Lnet/minecraft/world/entity/Entity;Z)Z", at = @At(value = "RETURN", ordinal = 3)) public void onMount(Entity entity, boolean bl, CallbackInfoReturnable cir) { - var self = (Entity)(Object)this; - if(Conditional.shouldApplyPerspectiveTo(self)) { + var self = (Entity) (Object) this; + if (Conditional.shouldApplyPerspectiveTo(self)) { CreateTrainPerspectiveMod.INSTANCE.onEntityMountEvent(true, self, entity); } } @Inject(method = "removeVehicle", at = @At("HEAD")) public void onDismount(CallbackInfo ci) { - if(vehicle != null) { - var self = (Entity)(Object)this; - if(Conditional.shouldApplyPerspectiveTo(self)) { + if (vehicle != null) { + var self = (Entity) (Object) this; + if (Conditional.shouldApplyPerspectiveTo(self)) { CreateTrainPerspectiveMod.INSTANCE.onEntityMountEvent(false, self, vehicle); } } @@ -45,9 +54,9 @@ public void onDismount(CallbackInfo ci) { @ModifyVariable(method = "calculateViewVector", at = @At(value = "LOAD"), index = 1, argsOnly = true) public float modifyPitch(float pitch, @Local(argsOnly = true, index = 2) float yaw) { if (this.level.isClientSide) { - if (Minecraft.getInstance().getEntityRenderDispatcher().getRenderer((Entity)(Object)this) instanceof Perspective persp - && persp.isEnabled() - && Conditional.shouldApplyPerspectiveTo((Entity)(Object)this)) { + if (((Entity) (Object) this) instanceof Perspective persp + && persp.isEnabled() + && Conditional.shouldApplyPerspectiveTo((Entity) (Object) this)) { return MixinUtil.applyDirectionXRotChange(persp, pitch, yaw, 1.0f); } else return pitch; } else return pitch; @@ -57,11 +66,69 @@ public float modifyPitch(float pitch, @Local(argsOnly = true, index = 2) float y @ModifyVariable(method = "calculateViewVector", at = @At(value = "LOAD"), index = 2, argsOnly = true) public float modifyYaw(float yaw, @Local(argsOnly = true, index = 1) float pitch) { if (this.level.isClientSide) { - if (Minecraft.getInstance().getEntityRenderDispatcher().getRenderer((Entity)(Object)this) instanceof Perspective persp - && persp.isEnabled() - && Conditional.shouldApplyPerspectiveTo((Entity)(Object)this)) { + if (((Entity) (Object) this) instanceof Perspective persp + && persp.isEnabled() + && Conditional.shouldApplyPerspectiveTo((Entity) (Object) this)) { return yaw + MixinUtil.getExtraYRot(persp, pitch, yaw, 1.0f); } else return yaw; } else return yaw; } + + public void ctp$enable(float initialLean, float initialYaw) { + ctp$perspectiveActive = true; + ctp$lean = initialLean; + ctp$yaw = initialYaw; + ctp$oldLean = initialLean; + ctp$oldYaw = initialYaw; + } + + public void ctp$disable() { + ctp$perspectiveActive = false; + ctp$lean = 0.0f; + ctp$yaw = 0.0f; + ctp$oldLean = 0.0f; + ctp$oldYaw = 0.0f; + } + + public boolean ctp$isEnabled() { + return ctp$perspectiveActive; + } + + public void ctp$setLean(float lean) { + ctp$oldLean = ctp$lean; + ctp$lean = lean; + } + + public void ctp$setYaw(float yaw) { + // some configurations flip between 0 and 360 constantly + // adjust accordingly + ctp$oldYaw = ctp$yaw; + ctp$yaw = yaw; + + while (ctp$yaw - ctp$oldYaw < -180.0f) { + ctp$oldYaw -= 360.0f; + } + + while (ctp$yaw - ctp$oldYaw >= 180.0f) { + ctp$oldYaw += 360.0f; + } + } + + public float ctp$getLean(float f) { + if (f == 1.0f) return ctp$lean; + return Mth.lerp(f, ctp$oldLean, ctp$lean); + } + + public float ctp$getYaw(float f) { + if (f == 1.0f) return ctp$yaw; + return Mth.lerp(f, ctp$oldYaw, ctp$yaw); + } + + public @Nullable RotationState ctp$getRotationState() { + return ctp$currentState; + } + + public void ctp$setRotationState(@Nullable RotationState state) { + ctp$currentState = state; + } } diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/LivingEntityRendererMixin.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/LivingEntityRendererMixin.java new file mode 100644 index 0000000..11c97a3 --- /dev/null +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/LivingEntityRendererMixin.java @@ -0,0 +1,38 @@ +package net.derfruhling.minecraft.create.trainperspective.mixin; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Vector3f; +import net.derfruhling.minecraft.create.trainperspective.Conditional; +import net.derfruhling.minecraft.create.trainperspective.Perspective; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.renderer.entity.LivingEntityRenderer; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.LivingEntity; +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.CallbackInfo; + +@Mixin(LivingEntityRenderer.class) +@Environment(EnvType.CLIENT) +public class LivingEntityRendererMixin { + @Inject(method = "setupRotations", at = @At("HEAD")) + protected void setupRotations(LivingEntity livingEntity, PoseStack poseStack, float f, float g, float h, CallbackInfo ci) { + if (Conditional.shouldApplyPerspectiveTo(livingEntity)) { + Perspective persp = (Perspective) livingEntity; + float height = 0; + + if (livingEntity.getVehicle() != null) { + height = livingEntity.getEyeHeight(); + } + + var lean = persp.getLean(h); + var yaw = persp.getYaw(h); + poseStack.translate(0, height, 0); + poseStack.mulPose(Vector3f.ZP.rotationDegrees(Mth.cos(Mth.DEG_TO_RAD * yaw) * lean)); + poseStack.mulPose(Vector3f.XP.rotationDegrees(Mth.sin(Mth.DEG_TO_RAD * yaw) * -lean)); + poseStack.translate(0, -height, 0); + } + } +} diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/LocalPlayerMixin.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/LocalPlayerMixin.java index 3573919..4209e9d 100644 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/LocalPlayerMixin.java +++ b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/LocalPlayerMixin.java @@ -10,14 +10,15 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; -// If anything else tries to @Overwrite getViewYRot, use their changes. @Mixin(value = LocalPlayer.class) public class LocalPlayerMixin { - @Shadow @Final protected Minecraft minecraft; + @Shadow + @Final + protected Minecraft minecraft; @WrapOperation(method = "getViewYRot", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;isPassenger()Z")) - public boolean isPassenger(LocalPlayer instance, Operation original) { - var perspective = (Perspective) minecraft.getEntityRenderDispatcher().getRenderer(instance); - return original.call(instance) || perspective.isEnabled(); + public boolean isPassenger(LocalPlayer localPlayer, Operation original) { + var perspective = (Perspective) localPlayer; + return original.call(localPlayer) || perspective.isEnabled(); } } diff --git a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/PlayerRendererMixin.java b/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/PlayerRendererMixin.java deleted file mode 100644 index 0cd01a3..0000000 --- a/common/src/main/java/net/derfruhling/minecraft/create/trainperspective/mixin/PlayerRendererMixin.java +++ /dev/null @@ -1,110 +0,0 @@ -package net.derfruhling.minecraft.create.trainperspective.mixin; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Vector3f; -import net.derfruhling.minecraft.create.trainperspective.Conditional; -import net.derfruhling.minecraft.create.trainperspective.CreateTrainPerspectiveMod; -import net.derfruhling.minecraft.create.trainperspective.Perspective; -import net.derfruhling.minecraft.create.trainperspective.RotationState; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.player.AbstractClientPlayer; -import net.minecraft.client.renderer.entity.player.PlayerRenderer; -import net.minecraft.util.Mth; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Implements; -import org.spongepowered.asm.mixin.Interface; -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.callback.CallbackInfo; - -@Mixin(PlayerRenderer.class) -@Implements({@Interface(iface = Perspective.class, prefix = "ctp$")}) -@Environment(EnvType.CLIENT) -public class PlayerRendererMixin { - @Unique private boolean ctp$perspectiveActive = false; - @Unique private float ctp$lean = 0.0f, ctp$yaw = 0.0f, ctp$oldLean = 0.0f, ctp$oldYaw = 0.0f; - @Unique private @Nullable RotationState ctp$currentState = null; - - public void ctp$enable(float initialLean, float initialYaw) { - ctp$perspectiveActive = true; - ctp$lean = initialLean; - ctp$yaw = initialYaw; - ctp$oldLean = initialLean; - ctp$oldYaw = initialYaw; - } - - public void ctp$disable() { - ctp$perspectiveActive = false; - ctp$lean = 0.0f; - ctp$yaw = 0.0f; - ctp$oldLean = 0.0f; - ctp$oldYaw = 0.0f; - } - - public boolean ctp$isEnabled() { - return ctp$perspectiveActive; - } - - public void ctp$setLean(float lean) { - ctp$oldLean = ctp$lean; - ctp$lean = lean; - } - - public void ctp$setYaw(float yaw) { - // some configurations flip between 0 and 360 constantly - // adjust accordingly - ctp$oldYaw = ctp$yaw; - ctp$yaw = yaw; - - while (ctp$yaw - ctp$oldYaw < -180.0f) { - ctp$oldYaw -= 360.0f; - } - - while (ctp$yaw - ctp$oldYaw >= 180.0f) { - ctp$oldYaw += 360.0f; - } - } - - public float ctp$getLean(float f) { - if(f == 1.0f) return ctp$lean; - return Mth.lerp(f, ctp$oldLean, ctp$lean); - } - - public float ctp$getYaw(float f) { - if(f == 1.0f) return ctp$yaw; - return Mth.lerp(f, ctp$oldYaw, ctp$yaw); - } - - public @Nullable RotationState ctp$getRotationState() { - return ctp$currentState; - } - - public void ctp$setRotationState(@Nullable RotationState state) { - ctp$currentState = state; - } - - @Inject( - method = "setupRotations(Lnet/minecraft/client/player/AbstractClientPlayer;Lcom/mojang/blaze3d/vertex/PoseStack;FFF)V", - at = @At( - value = "HEAD" - ) - ) - protected void setupRotations(AbstractClientPlayer p_117802_, PoseStack p_117803_, float p_117804_, float p_117805_, float f, CallbackInfo ci) { - if(ctp$perspectiveActive && Conditional.shouldApplyPerspectiveTo(p_117802_)) { - float height = 0; - - if(p_117802_.getVehicle() != null) { - height = p_117802_.getEyeHeight(); - } - - var lean = ctp$getLean(f); - p_117803_.translate(0, height, 0); - p_117803_.mulPose(Vector3f.ZP.rotationDegrees(Mth.cos(Mth.DEG_TO_RAD * ctp$yaw) * lean)); - p_117803_.mulPose(Vector3f.XP.rotationDegrees(Mth.sin(Mth.DEG_TO_RAD * ctp$yaw) * -lean)); - p_117803_.translate(0, -height, 0); - } - } -} diff --git a/common/src/main/resources/assets/minecraft/lang/en_us.json b/common/src/main/resources/assets/minecraft/lang/en_us.json index 32f4868..b494b15 100644 --- a/common/src/main/resources/assets/minecraft/lang/en_us.json +++ b/common/src/main/resources/assets/minecraft/lang/en_us.json @@ -1,25 +1,27 @@ { - "title.create_train_perspective.config": "Create: Train Perspective", - - "category.create_train_perspective.general": "General", - "category.create_train_perspective.leaning": "Leaning", - "category.create_train_perspective.multiplayer": "Multiplayer", - "category.create_train_perspective.advanced": "Advanced", - "category.create_train_perspective.debug": "Debug Features", - "category.create_train_perspective.debug.description": "These are debugging features used for development. You probably don't want to touch these unless you're working on the mod itself.", - - "option.create_train_perspective.enabled": "Enabled", - "option.create_train_perspective.enabled.tooltip": "Enables the mod. If False, the mod is disabled.", - "option.create_train_perspective.leaning.enabled": "Enable Leaning", - "option.create_train_perspective.leaning.enabled.tooltip": "If True, players will lean forwards and backwards.", - "option.create_train_perspective.leaning.roll_enabled": "Enable Rolling", - "option.create_train_perspective.leaning.roll_enabled.tooltip": "If True, players will roll when looking to the side on a slope.", - "option.create_train_perspective.multiplayer.apply_to_others": "Apply mod to others", - "option.create_train_perspective.multiplayer.apply_to_others.tooltip": "Applies the mod to other players as well.", - "option.create_train_perspective.advanced.lean_magnitude": "Leaning Magnitude", - "option.create_train_perspective.advanced.lean_magnitude.tooltip": "The magnitude to which the player will lean. Higher = more intense.", - "option.create_train_perspective.advanced.roll_magnitude": "Rolling Magnitude", - "option.create_train_perspective.advanced.roll_magnitude.tooltip": "The magnitude to which the player will roll. Higher = more intense.", - "option.create_train_perspective.debug.standing_transforms": "Show Standing Translations", - "option.create_train_perspective.debug.standing_transforms.tooltip": "Shows translations used to transform the player while standing on a train. (X, Y, Z)" + "title.create_train_perspective.config": "Create: Train Perspective", + "category.create_train_perspective.general": "General", + "category.create_train_perspective.leaning": "Leaning", + "category.create_train_perspective.multiplayer": "Multiplayer", + "category.create_train_perspective.advanced": "Advanced", + "category.create_train_perspective.debug": "Debug Features", + "category.create_train_perspective.debug.description": "These are debugging features used for development. You probably don't want to touch these unless you're working on the mod itself.", + "option.create_train_perspective.enabled": "Enabled", + "option.create_train_perspective.enabled.tooltip": "Enables the mod. If False, the mod is disabled.", + "option.create_train_perspective.leaning.enabled": "Enable Leaning", + "option.create_train_perspective.leaning.enabled.tooltip": "If True, players will lean forwards and backwards.", + "option.create_train_perspective.leaning.roll_enabled": "Enable Rolling", + "option.create_train_perspective.leaning.roll_enabled.tooltip": "If True, players will roll when looking to the side on a slope.", + "option.create_train_perspective.multiplayer.apply_to_others": "Apply mod to others", + "option.create_train_perspective.multiplayer.apply_to_others.tooltip": "Applies the mod to other players as well.", + "option.create_train_perspective.advanced.lean_magnitude": "Leaning Magnitude", + "option.create_train_perspective.advanced.lean_magnitude.tooltip": "The magnitude to which the player will lean. Higher = more intense.", + "option.create_train_perspective.advanced.roll_magnitude": "Rolling Magnitude", + "option.create_train_perspective.advanced.roll_magnitude.tooltip": "The magnitude to which the player will roll. Higher = more intense.", + "option.create_train_perspective.advanced.apply_to_entities": "Apply mod to non-player entities", + "option.create_train_perspective.advanced.apply_to_entities.tooltip": "Applies the mod to non-player entities as well (may be broken with some entities)", + "option.create_train_perspective.advanced.blocked_entities": "Blocked entities", + "option.create_train_perspective.advanced.blocked_entities.tooltip": "Entities with an ID in this list will not be considered for this mod's functionality", + "option.create_train_perspective.debug.standing_transforms": "Show Standing Translations", + "option.create_train_perspective.debug.standing_transforms.tooltip": "Shows translations used to transform the player while standing on a train. (X, Y, Z)" } \ No newline at end of file diff --git a/common/src/main/resources/create_train_perspective.mixins.json b/common/src/main/resources/create_train_perspective.mixins.json index fabbc8d..c7ce58e 100644 --- a/common/src/main/resources/create_train_perspective.mixins.json +++ b/common/src/main/resources/create_train_perspective.mixins.json @@ -4,14 +4,14 @@ "package": "net.derfruhling.minecraft.create.trainperspective.mixin", "compatibilityLevel": "JAVA_8", "client": [ - "CameraMixin", "AbstractContraptionEntityMixin", + "CameraMixin", "ClientLevelMixin", + "CreateRaycastHelperMixin", "EntityMixin", "GameRendererMixin", - "LocalPlayerMixin", - "PlayerRendererMixin", - "CreateRaycastHelperMixin" + "LivingEntityRendererMixin", + "LocalPlayerMixin" ], "overwrites": { "requireAnnotations": true, diff --git a/fabric/gradle.properties b/fabric/gradle.properties index a6facf4..6a83fa7 100644 --- a/fabric/gradle.properties +++ b/fabric/gradle.properties @@ -1,4 +1,3 @@ loom.platform=fabric - create_version=0.5.1-f-build.1416+mc1.19.2 flywheel_version=0.6.10-2 diff --git a/fabric/src/main/java/net/derfruhling/minecraft/create/trainperspective/fabric/ConfigIntegration.java b/fabric/src/main/java/net/derfruhling/minecraft/create/trainperspective/fabric/ConfigIntegration.java index 2867710..49658b1 100644 --- a/fabric/src/main/java/net/derfruhling/minecraft/create/trainperspective/fabric/ConfigIntegration.java +++ b/fabric/src/main/java/net/derfruhling/minecraft/create/trainperspective/fabric/ConfigIntegration.java @@ -3,7 +3,6 @@ import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; import net.derfruhling.minecraft.create.trainperspective.ModConfig; -import net.minecraft.client.gui.screens.Screen; public class ConfigIntegration implements ModMenuApi { @Override diff --git a/fabric/src/main/java/net/derfruhling/minecraft/create/trainperspective/fabric/ModFabricEntrypoint.java b/fabric/src/main/java/net/derfruhling/minecraft/create/trainperspective/fabric/ModFabricEntrypoint.java index c4189b4..5b9095c 100644 --- a/fabric/src/main/java/net/derfruhling/minecraft/create/trainperspective/fabric/ModFabricEntrypoint.java +++ b/fabric/src/main/java/net/derfruhling/minecraft/create/trainperspective/fabric/ModFabricEntrypoint.java @@ -8,13 +8,13 @@ public class ModFabricEntrypoint implements ClientModInitializer { public CreateTrainPerspectiveMod common; + public static ModFabricEntrypoint getInstance() { + return INSTANCE; + } + @Override public void onInitializeClient() { common = new CreateTrainPerspectiveMod(); INSTANCE = this; } - - public static ModFabricEntrypoint getInstance() { - return INSTANCE; - } } diff --git a/forge/build.gradle b/forge/build.gradle index a9af771..2fa8751 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -101,6 +101,7 @@ modrinth { gameVersions = [minecraft_version] loaders = ["forge", "neoforge"] changelog = rootProject.file("changelog.md").getText() + syncBodyFrom = rootProject.file("README.md").text dependencies { required.project 'create' diff --git a/forge/src/main/java/net/derfruhling/minecraft/create/trainperspective/forge/ModForgeEntrypoint.java b/forge/src/main/java/net/derfruhling/minecraft/create/trainperspective/forge/ModForgeEntrypoint.java index e01c253..10ed3d2 100644 --- a/forge/src/main/java/net/derfruhling/minecraft/create/trainperspective/forge/ModForgeEntrypoint.java +++ b/forge/src/main/java/net/derfruhling/minecraft/create/trainperspective/forge/ModForgeEntrypoint.java @@ -17,7 +17,7 @@ public class ModForgeEntrypoint { public ModForgeEntrypoint() { MinecraftForge.EVENT_BUS.addListener(this::onClientSetupEvent); ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, () -> - new ConfigScreenHandler.ConfigScreenFactory((minecraft, screen) -> ModConfig.createConfigScreen(screen))); + new ConfigScreenHandler.ConfigScreenFactory((minecraft, screen) -> ModConfig.createConfigScreen(screen))); } private void onClientSetupEvent(FMLClientSetupEvent event) { diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml index a75ad98..30d6835 100644 --- a/forge/src/main/resources/META-INF/mods.toml +++ b/forge/src/main/resources/META-INF/mods.toml @@ -4,42 +4,42 @@ # Note that there are a couple of TOML lists in this file. # Find more information on toml format here: https://github.com/toml-lang/toml # The name of the mod loader type to load - for regular FML @Mod mods it should be javafml -modLoader="javafml" #mandatory +modLoader = "javafml" #mandatory # A version range to match for said mod loader - for regular FML @Mod it will be the forge version loaderVersion="[43,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. # The license for you mod. This is mandatory metadata and allows for easier comprehension of your redistributive properties. # Review your options at https://choosealicense.com/. All rights reserved is the default copyright stance, and is thus the default here. -license="MIT" +license = "MIT" # A URL to refer people to when problems occur with this mod -issueTrackerURL="https://github.com/der-fruhling-entertainment/create-train-perspective/issues" #optional +issueTrackerURL = "https://github.com/der-fruhling-entertainment/create-train-perspective/issues" #optional # A list of mods - how many allowed here is determined by the individual mod loader [[mods]] #mandatory # The modid of the mod -modId="${mod_id}" #mandatory +modId = "${mod_id}" #mandatory # The version number of the mod -version="${mod_version}" #mandatory +version = "${mod_version}" #mandatory # A display name for the mod -displayName="Create: Train Perspective" #mandatory +displayName = "Create: Train Perspective" #mandatory # A URL to query for updates for this mod. See the JSON update specification https://docs.minecraftforge.net/en/latest/misc/updatechecker/ -updateJSONURL="https://api.modrinth.com/updates/create-train-perspective/forge_updates.json" #optional +updateJSONURL = "https://api.modrinth.com/updates/create-train-perspective/forge_updates.json" #optional # A URL for the "homepage" for this mod, displayed in the mod UI -displayURL="https://modrinth.com/mod/create-train-perspective-fixer" #optional +displayURL = "https://modrinth.com/mod/create-train-perspective-fixer" #optional # A file name (in the root of the mod JAR) containing a logo for display -logoFile="create_train_perspective.png" #optional +logoFile = "create_train_perspective.png" #optional # A text field displayed in the mod UI #credits="Thanks for this example mod goes to Java" #optional # A text field displayed in the mod UI -authors="der_frühling" #optional +authors = "der_frühling" #optional # Display Test controls the display for your mod in the server connection screen # MATCH_VERSION means that your mod will cause a red X if the versions on client and server differ. This is the default behaviour and should be what you choose if you have server and client elements to your mod. # IGNORE_SERVER_VERSION means that your mod will not cause a red X if it's present on the server but not on the client. This is what you should use if you're a server only mod. # IGNORE_ALL_VERSION means that your mod will not cause a red X if it's present on the client or the server. This is a special case and should only be used if your mod has no server component. # NONE means that no display test is set on your mod. You need to do this yourself, see IExtensionPoint.DisplayTest for more information. You can define any scheme you wish with this value. # IMPORTANT NOTE: this is NOT an instruction as to which environments (CLIENT or DEDICATED SERVER) your mod loads on. Your mod should load (and maybe do nothing!) whereever it finds itself. -displayTest="IGNORE_ALL_VERSION" # MATCH_VERSION is the default if nothing is specified (#optional) +displayTest = "IGNORE_ALL_VERSION" # MATCH_VERSION is the default if nothing is specified (#optional) # The description text for the mod (multi line!) (#mandatory) -description=''' +description = ''' Moves your camera (and body!) with the Create Mod train you're riding to increase immersion! ''' @@ -83,8 +83,8 @@ Moves your camera (and body!) with the Create Mod train you're riding to increas ordering="NONE" side="BOTH" [[dependencies."${mod_id}"]] - modId="cloth_config" - mandatory=true - versionRange="[8.0.0,)" - ordering="NONE" - side="BOTH" +modId = "cloth_config" +mandatory = true +versionRange = "[8.0.0,)" +ordering = "NONE" +side = "BOTH" diff --git a/forge/src/main/resources/pack.mcmeta b/forge/src/main/resources/pack.mcmeta index 67de63c..55530c7 100644 --- a/forge/src/main/resources/pack.mcmeta +++ b/forge/src/main/resources/pack.mcmeta @@ -1,7 +1,7 @@ { - "pack": { - "description": "Create: Train Perspective Fixer resources", - "pack_format": 15, - "forge:server_data_pack_format": 12 - } + "pack": { + "description": "Create: Train Perspective Fixer resources", + "pack_format": 15, + "forge:server_data_pack_format": 12 + } } diff --git a/gradle.properties b/gradle.properties index 457e348..c49a57c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,22 +1,19 @@ org.gradle.jvmargs=-Xmx3G -# org.gradle.daemon=false - -enabled_platforms=fabric,forge -# ,quilt - +# minecraft & architectury versions minecraft_version=1.19.2 architectury_version=6.6.92 - +enabled_platforms=fabric,forge +# forge forge_version=1.19.2-43.3.0 - +# fabric fabric_loader_version=0.15.7 fabric_api_version=0.77.0+1.19.2 - +# public info mod_id=create_train_perspective -mod_version=0.4.1 +mod_version=0.5.0 maven_group=net.derfruhling.minecraft archives_base_name=create-train-perspective - +# mod dependency versions create_minecraft_version = 1.19.2 flywheel_minecraft_version = 1.19.2 create_version = 0.5.1.f-46 @@ -24,7 +21,7 @@ flywheel_version = 0.6.10-20 registrate_version = MC1.19-1.1.5 cloth_config_version=8.3.115 mod_menu_version=4.1.2 - +# modrinth project info modrinth_project_id=create-train-perspective modrinth_version_type=beta modrinth_game_versions=1.19.2