merge upstream 26.2
This commit is contained in:
264 files changed
+4863
-3914
No files matched your search
@@ -7,22 +7,21 @@ on: [pull_request]
|
||||
|
||||
jobs:
|
||||
Build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
distribution: microsoft
|
||||
java-version: 25
|
||||
cache: 'gradle'
|
||||
- name: Grant execute permission to gradlew
|
||||
run: chmod +x gradlew
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: "Compiled artifacts for Pull Request #${{github.event.number}}"
|
||||
path: build/libs
|
||||
@@ -11,18 +11,18 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
distribution: microsoft
|
||||
java-version: 25
|
||||
cache: 'gradle'
|
||||
- name: Grant execute permission to gradlew
|
||||
run: chmod +x gradlew
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Compiled artifacts for ${{ github.sha }}
|
||||
path: build/libs
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
extra-branch-curse-version: ${{ steps.properties.outputs.release-extra-curse-version }}
|
||||
steps:
|
||||
- name: Checkout the sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Determine release type
|
||||
id: type
|
||||
run: |
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
if ! ${{ steps.properties.outputs.release-extra-branch }}; then
|
||||
echo "matrix-to-exclude=Snapshots" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- uses: actions/github-script@v6
|
||||
- uses: actions/github-script@v7
|
||||
env:
|
||||
READ_VERSION: ${{ steps.properties.outputs.mod_version }}
|
||||
with:
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
})).data;
|
||||
console.log('Previous release was: ' + releases[1].name);
|
||||
for (let release of releases.slice(1)) {
|
||||
if (release.name.includes(READ_VERSION))
|
||||
if (release.name.includes(' ' + READ_VERSION + ' '))
|
||||
core.setFailed('Version number is the same as a previous release!')
|
||||
}
|
||||
Build-And-Publish:
|
||||
@@ -78,14 +78,14 @@ jobs:
|
||||
echo "curse-versions=${{ needs.Get-Properties.outputs.curse-versions }}" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
- name: Checkout the sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ steps.getbranchinfo.outputs.branchname }}
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v3
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
distribution: microsoft
|
||||
java-version: 25
|
||||
cache: 'gradle'
|
||||
- name: Grant execute permission to gradlew
|
||||
run: chmod +x gradlew
|
||||
@@ -97,7 +97,7 @@ jobs:
|
||||
output="$(find build/libs/ ! -name "*-dev.jar" ! -name "*-sources.jar" -type f -printf "%f\n")"
|
||||
echo "jarname=$output" >> $GITHUB_OUTPUT
|
||||
- name: Save build artifacts in the action
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Artifacts for ${{ matrix.branch }}
|
||||
path: build/libs
|
||||
@@ -111,7 +111,7 @@ jobs:
|
||||
asset_name: ${{ steps.findjar.outputs.jarname }}
|
||||
asset_content_type: application/java-archive
|
||||
- name: Upload to Curseforge
|
||||
uses: itsmeow/curseforge-upload@v3
|
||||
uses: itsmeow/curseforge-upload@v3.1.2
|
||||
with:
|
||||
token: ${{ secrets.CF_API_TOKEN }}
|
||||
project_id: 349239
|
||||
@@ -125,7 +125,7 @@ jobs:
|
||||
- name: Ask Gradle to publish
|
||||
run: ./gradlew publish
|
||||
- name: Save publish folder in action's artifacts # Remove when automated
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Maven publishing artifacts for ${{ matrix.branch }}
|
||||
path: publish/carpet/fabric-carpet/
|
||||
@@ -149,7 +149,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the sources
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: master
|
||||
- name: Merge docs
|
||||
@@ -166,15 +166,15 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Carpet sources
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: 21
|
||||
distribution: microsoft
|
||||
java-version: 25
|
||||
cache: 'gradle'
|
||||
- name: Checkout wiki
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: ${{github.repository}}.wiki
|
||||
path: wiki
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
<img src="./src/main/resources/assets/carpet/icon.png" align="right" width="128px"/>
|
||||
|
||||
# Fabric Carpet
|
||||
|
||||
[](https://github.com/gnembon/fabric-carpet/actions/workflows/devbuild.yml)
|
||||
[](https://www.curseforge.com/minecraft/mc-mods/carpet)
|
||||
[](https://modrinth.com/mod/carpet)
|
||||
[](https://github.com/gnembon/fabric-carpet/releases)
|
||||
[](https://github.com/gnembon/fabric-carpet/graphs/contributors)
|
||||
[](https://discord.gg/gn99m4QRY4)
|
||||
|
||||
English version of this [docs](https://github.com/gnembon/fabric-carpet/blob/master/README.md)
|
||||
|
||||
Cause all carpets are made of fabric?
|
||||
|
||||
Esto es la [Fabric](https://fabricmc.net/) version del Carpet Mod, para Minecraft 1.14.X, 1.15.X, 1.16.X y siguientes.
|
||||
|
||||
Carpet Mod es un mod para Minecraft Vanilla que permite tener un control total de lo que importa desde la perspectiva tecnica del juego.
|
||||
|
||||
* Prueba tus granjas durante varias horas en tan solo unos minutos con el comando [`/tick warp`](https://github.com/gnembon/fabric-carpet/wiki/Commands#usage-tick-warp-ticks-cmd), tan rapido como tu computadora pueda
|
||||
* ...da un informe detallado de los items producido usando el comando [`/hopperCounters`](https://github.com/gnembon/fabric-carpet/wiki/Current-Available-Settings#hoppercounters)
|
||||
* Ve la mobcap del server, TPS, etc. con actualizaciones en vivo con [`/log`](https://github.com/gnembon/fabric-carpet/wiki/Commands#log)
|
||||
* Permite a los pistones mover entidades (por ejemplo. cofres) con [`/movableBlockEntities`](https://github.com/gnembon/fabric-carpet/wiki/Current-Available-Settings#movableblockentities)
|
||||
* [Arregla](https://github.com/gnembon/fabric-carpet/wiki/Current-Available-Settings#leadfix) [muchas](https://github.com/gnembon/fabric-carpet/wiki/Current-Available-Settings#portalsuffocationfix) [cosas](https://github.com/gnembon/fabric-carpet/wiki/Current-Available-Settings#unloadedentityfix)
|
||||
|
||||
# ecosistema carpet
|
||||
|
||||
Para funcionalidades del ecosistema de carpet este el lugar correcto. Ve las descargas disponibles en [pagina de descargas](https://github.com/gnembon/fabric-carpet/releases)
|
||||
|
||||
|
||||
<img src="https://raw.githubusercontent.com/gnembon/carpet-extra/master/src/main/resources/assets/carpet-extra/icon.png" align="right" width="128px"/>
|
||||
|
||||
## carpet-extra
|
||||
|
||||
Mira [carpet-extra](https://github.com/gnembon/carpet-extra/) mod para mas locas y divertidas funcionalidades, incluyendo mesas de crafteo automaticas, dispensers que ponen bloques, hasta trasquilado de pollos!
|
||||
|
||||
## mesa de crafteo automatica
|
||||
|
||||
Debido a problemas de compatibildias con vanilla y otros mods, descarga [mesa de crafteo automatica](https://github.com/gnembon/carpet-autoCraftingTable/releases) por Skyrising como un addon separado para carpet
|
||||
|
||||
## scarpet app store
|
||||
|
||||
Si quieres buscar o contribuir a las app store de scarpet mira las aplicaciones disponibles, ve [aqui](https://github.com/gnembon/scarpet), es gratis!
|
||||
|
||||
## quick-carpet
|
||||
|
||||
Tienes problemas con las snapshots recientes recientes o alguien necesita la version base de carpet?, pero necesita algunas funcionalidades bases de carpet?, checkea la version minima de [quick-carpet](https://github.com/gnembon/quick-carpet/releases). Va a funcionar bien, no vas a poder agregar extensiones o usar apps de scarpet en este por cierto.
|
||||
|
||||
## Otras extensiones hechas por la comunidad para carpet
|
||||
|
||||
Aqui hay una [lista de otras extensiones de carpet](https://github.com/gnembon/fabric-carpet/wiki/List-of-Carpet-extensions) creadas por la comunidad.
|
||||
|
||||
Cualquiera puede crear sus propias opciones de carpeta o extender el lenguaje scarpet con una nueva API, creando una extension de carpet usando esto [extension de carpet plantilla](https://github.com/gnembon/fabric-carpet-extension-example-mod).
|
||||
|
||||
# Como? Que?
|
||||
|
||||
Mira las instrucciones para los mods de carpeta https://fabricmc.net/use/ y pon [carpet...jar](https://github.com/gnembon/fabric-carpet/releases) en la carpeta `mods` junto a los otros mods compatibles.
|
||||
|
||||
Mira la [demostracion de mods](https://www.youtube.com/watch?v=Lt-ooRGpLz4) en youtube para la explicación de cada uno de las opciones y comandos, y checkea la lista de todas las opciones disponibles en la wiki por una lista actualizada de cada opcion.
|
||||
|
||||
# Carpet Mod Settings
|
||||
Mira la lista [Lista de todas las configuraciones disponibles][settings] en la wiki
|
||||
|
||||
[settings]: https://github.com/gnembon/fabric-carpet/wiki/Current-Available-Settings
|
||||
|
||||
Para versiones anteriores de Minecraft: 1.13 checkea [gnembon/carpetmod](https://github.com/gnembon/carpetmod) y para 1.12 checkea [gnembon/carpetmod112](https://github.com/gnembon/carpetmod112).
|
||||
@@ -9,6 +9,8 @@
|
||||
[](https://github.com/gnembon/fabric-carpet/graphs/contributors)
|
||||
[](https://discord.gg/gn99m4QRY4)
|
||||
|
||||
Version en español de esta [documentacion](https://github.com/gnembon/fabric-carpet/blob/master/README-ES.md)
|
||||
|
||||
Cause all carpets are made of fabric?
|
||||
This is the [Fabric](https://fabricmc.net/) version of Carpet Mod, for Minecraft 1.14.X, 1.15.X, 1.16.X and above.
|
||||
|
||||
|
||||
+16
-20
@@ -1,14 +1,13 @@
|
||||
plugins {
|
||||
id 'fabric-loom' version '1.6-SNAPSHOT'
|
||||
id 'io.github.juuxel.loom-quiltflower' version '1.7.3'
|
||||
id 'net.fabricmc.fabric-loom' version "${loom_version}"
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
base {
|
||||
archivesName = project.archives_base_name
|
||||
}
|
||||
|
||||
archivesBaseName = project.archives_base_name
|
||||
version = project.minecraft_version+'-'+project.mod_version+'+v'+new Date().format('yyMMdd')
|
||||
version = project.mod_version+'+v'+new Date().format('yyMMdd')
|
||||
group = project.maven_group
|
||||
|
||||
loom {
|
||||
@@ -19,25 +18,19 @@ loom {
|
||||
dependencies {
|
||||
// To change the versions see the gradle.properties file
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings loom.officialMojangMappings()
|
||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||
implementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||
|
||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||
//modImplementation "net.fabricmc:fabric:${project.fabric_version}"
|
||||
//modCompileOnly fabricApi.module("fabric-rendering-v1", project.fabric_version)
|
||||
|
||||
// PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs.
|
||||
// You may need to force-disable transitiveness on them.
|
||||
compileOnly "com.google.code.findbugs:jsr305:${project.jsr305_version}"
|
||||
|
||||
modImplementation 'me.lucko:fabric-permissions-api:0.3.1'
|
||||
implementation 'me.lucko:fabric-permissions-api:0.7.0'
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version+'+v'+new Date().format('yyMMdd')
|
||||
|
||||
inputs.property "version", project.version
|
||||
print("\nBuilding version: " + project.version + "\n")
|
||||
filesMatching("fabric.mod.json") {
|
||||
expand "version": project.mod_version+'+v'+new Date().format('yyMMdd')
|
||||
expand "version": project.version
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +43,7 @@ tasks.withType(JavaCompile).configureEach {
|
||||
it.options.encoding = "UTF-8"
|
||||
|
||||
// Minecraft 1.20.5 upwards uses Java 21.
|
||||
it.options.release = 21
|
||||
it.options.release = 25
|
||||
}
|
||||
|
||||
java {
|
||||
@@ -58,11 +51,14 @@ java {
|
||||
// if it is present.
|
||||
// If you remove this line, sources will not be generated.
|
||||
withSourcesJar()
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_25
|
||||
targetCompatibility = JavaVersion.VERSION_25
|
||||
}
|
||||
|
||||
jar {
|
||||
from("LICENSE") {
|
||||
rename { "${it}_${project.archivesBaseName}"}
|
||||
rename { "${it}_${project.archives_base_name}"}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +75,7 @@ publishing {
|
||||
repositories {
|
||||
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
|
||||
maven {
|
||||
url "$projectDir/publish"
|
||||
url = "$projectDir/publish"
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
-19
@@ -2869,7 +2869,7 @@ On top of that, scarpet provides the following list of noises sampled directly f
|
||||
|
||||
`'barrier_noise'`, `'fluid_level_floodedness_noise'`, `'fluid_level_spread_noise'`, `'lava_noise'`,
|
||||
`'temperature'`, `'vegetation'`, `'continents'`, `'erosion'`, `'depth'`, `'ridges'`,
|
||||
`'initial_density_without_jaggedness'`, `'final_density'`, `'vein_toggle'`, `'vein_ridged'` and `'vein_gap'`
|
||||
`'preliminary_surface_level'`, `'final_density'`, `'vein_toggle'`, `'vein_ridged'` and `'vein_gap'`
|
||||
|
||||
<pre>
|
||||
// requesting single value
|
||||
@@ -2954,7 +2954,7 @@ It returns a `map` with a report indicating how many chunks were affected, and h
|
||||
|
||||
Adds a chunk ticket at a position, which makes the game to keep the designated area centered around
|
||||
`pos` with radius of `radius` loaded for a predefined amount of ticks, defined by `type`. Allowed types
|
||||
are `portal`: 300 ticks, `teleport`: 5 ticks, and `unknown`: 1 tick. Radius can be from 1 to 32 ticks.
|
||||
are `portal`: 300 ticks, `teleport`: 40 ticks, and `unknown`: 1 tick. Radius can be from 1 to 32 ticks.
|
||||
|
||||
This function is tentative - will likely change when chunk ticket API is properly fleshed out.
|
||||
|
||||
@@ -3433,7 +3433,7 @@ Entity that `e` rides.
|
||||
|
||||
### `query(e, 'unmountable')`
|
||||
|
||||
Boolean, true if the entity cannot be mounted.
|
||||
Boolean, true if the entity cannot be unmounted.
|
||||
|
||||
### `(deprecated) query(e, 'tags')`
|
||||
|
||||
@@ -3956,7 +3956,7 @@ Mounts the entity to the `other`.
|
||||
|
||||
### `modify(e, 'unmountable', boolean)`
|
||||
|
||||
Denies or allows an entity to be mounted.
|
||||
Denies or allows an entity to be unmounted.
|
||||
|
||||
### `modify(e, 'drop_passengers')`
|
||||
|
||||
@@ -4301,8 +4301,8 @@ Recipe type can take one of the following options:
|
||||
* `'smithing'` - smithing table (1.16+)
|
||||
|
||||
The return value is a list of available recipes (even if there is only one recipe available). Each recipe contains of
|
||||
an item triple of the crafting result, list of ingredients, each containing a list of possible variants of the
|
||||
ingredients in this slot, as item triples, or `null` if its a shaped recipe and a given slot in the patterns is left
|
||||
an item triple of the crafting results as a list of item stacks, list of ingredients, each containing a list of possible variants of the
|
||||
ingredients in this slot, as item ids, or `null` if it is a shaped recipe and a given slot in the patterns is left
|
||||
empty, and recipe specification as another list. Possible recipe specs is:
|
||||
* `['shaped', width, height]` - shaped crafting. `width` and `height` can be 1, 2 or 3.
|
||||
* `['shapeless']` - shapeless crafting
|
||||
@@ -4311,10 +4311,6 @@ Recipe type can take one of the following options:
|
||||
* `['special']` - special crafting recipe, typically not present in the crafting menu
|
||||
* `['custom']` - other recipe types
|
||||
|
||||
Note that ingredients are specified as tripes, with count and nbt information. Currently all recipes require always one
|
||||
of the ingredients, and for some recipes, even if the nbt data for the ingredient is specified (e.g. `dispenser`), it
|
||||
can accept items of any tags.
|
||||
|
||||
Also note that some recipes leave some products in the crafting window, and these can be determined using
|
||||
`crafting_remaining_item()` function
|
||||
|
||||
@@ -4328,7 +4324,7 @@ Also note that some recipes leave some products in the crafting window, and thes
|
||||
### `crafting_remaining_item(item)`
|
||||
|
||||
returns `null` if the item has no remaining item in the crafting window when used as a crafting ingredient, or an
|
||||
item name that serves as a replacement after crafting is done. Currently it can only be buckets and glass bottles.
|
||||
item tuple that serves as a replacement after crafting is done. Currently, it can only be buckets and glass bottles.
|
||||
|
||||
### `inventory_size(inventory)`
|
||||
|
||||
@@ -5016,11 +5012,11 @@ Triggered when a player sends a disconnect package or is forcefully disconnected
|
||||
### `__on_player_message(player, message)`
|
||||
Triggered when a player sends a chat message.
|
||||
|
||||
This event can be cancelled by returning `'cancel'`, which prevents the message from being sent.
|
||||
|
||||
### `__on_player_command(player, command)`
|
||||
Triggered when a player runs a command. Command value is returned without the / in front.
|
||||
|
||||
This event can be cancelled by returning `'cancel'`, which prevents the message from being sent.
|
||||
|
||||
### `__on_statistic(player, category, event, value)`
|
||||
Triggered when a player statistic changes. Doesn't notify on periodic an rhythmic events, i.e.
|
||||
`time_since_death`, `time_since_rest`, and `played_one_minute` since these are triggered every tick. Event
|
||||
@@ -5347,7 +5343,7 @@ clients will actually be able to receive (they may have more available via resou
|
||||
Renders a cloud of particles `name` centered around `pos` position, by default `count` 10 of them, default `speed`
|
||||
of 0, and to all players nearby, but these options can be changed via optional arguments. Follow vanilla `/particle`
|
||||
command on details on those options. Valid particle names are
|
||||
for example `'angry_villager', 'item diamond', 'block stone', 'dust 0.8 0.1 0.1 4'`.
|
||||
for example `'angry_villager', 'item diamond', 'block stone', 'dust{"scale": 4, "color": [0.8, 0.1, 0.1]}'`.
|
||||
|
||||
Used with no arguments, return the list of available particle names. Note that some of the names do not correspond to a valid
|
||||
particle that can be fed to `particle(...)` function due to a fact that some particles need more configuration
|
||||
@@ -5735,11 +5731,21 @@ Runs a vanilla command from the string result of the `expr` and returns a triple
|
||||
intercepted list of output messages, and error message if the command resulted in a failure.
|
||||
Successful commands return `null` as their error.
|
||||
|
||||
The command return `null` if the command was not run immediately, but was scheduled for later execution
|
||||
due to being requested while command was executed. This happens most commonly
|
||||
when running `run` from a `/script run/invoke` command since that always results in piling up command to run while `script` is being executed.
|
||||
|
||||
The mitigation for this is to use `run` in a separate scheduled function, or use `run` in a `tick` event, or literally in
|
||||
any other way than directly from a `/script` command, which will ensure that the command runs immediately.
|
||||
|
||||
<pre>
|
||||
run('fill 1 1 1 10 10 10 air') -> [0, ["Successfully filled 123 blocks"], null]
|
||||
run('give @s stone 4') -> [0, ["Gave 4 [Stone] to gnembon"], null]
|
||||
run('seed') -> [0, ["Seed: [4031384495743822299]"], null]
|
||||
run('sed') -> [0, [], "sed<--[HERE]"] // wrong command
|
||||
run('fill 1 1 1 10 10 10 air') -> [123, ["Successfully filled 123 blocks"], null]
|
||||
run('give @s stone 4') -> [1, ["Gave 4 [Stone] to gnembon"], null]
|
||||
run('seed') -> [-170661413, [Seed: [4031384495743822299]], null]
|
||||
run('sed') -> [-1, [], "sed<--[HERE]"] // wrong command
|
||||
|
||||
/script run run('setblock 0 0 0 stone') -> null
|
||||
/script run schedule(0, _() -> print(run('setblock 0 0 0 stone'))) -> [1, [Changed the block at 0, 0, 0], null]
|
||||
</pre>
|
||||
|
||||
### `save()`
|
||||
@@ -6093,7 +6099,8 @@ system calls. In all circumstances, these are only provided as read-only.
|
||||
* `game_major_target` - major release target. For 1.12.2, that would be 12
|
||||
* `game_minor_release` - minor release target. For 1.12.2, that would be 2
|
||||
* `game_protocol` - protocol version number
|
||||
* `game_pack_version` - datapack version number
|
||||
* `game_pack_version` - datapack version number as a version string
|
||||
* `game_pack_minor_version` - datapack format minor version number
|
||||
* `game_data_version` - data version of the game. Returns an integer, so it can be compared.
|
||||
* `game_stable` - indicating if its a production release or a snapshot
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ clients will actually be able to receive (they may have more available via resou
|
||||
Renders a cloud of particles `name` centered around `pos` position, by default `count` 10 of them, default `speed`
|
||||
of 0, and to all players nearby, but these options can be changed via optional arguments. Follow vanilla `/particle`
|
||||
command on details on those options. Valid particle names are
|
||||
for example `'angry_villager', 'item diamond', 'block stone', 'dust 0.8 0.1 0.1 4'`.
|
||||
for example `'angry_villager', 'item diamond', 'block stone', 'dust{"scale": 4, "color": [0.8, 0.1, 0.1]}'`.
|
||||
|
||||
Used with no arguments, return the list of available particle names. Note that some of the names do not correspond to a valid
|
||||
particle that can be fed to `particle(...)` function due to a fact that some particles need more configuration
|
||||
@@ -410,11 +410,21 @@ Runs a vanilla command from the string result of the `expr` and returns a triple
|
||||
intercepted list of output messages, and error message if the command resulted in a failure.
|
||||
Successful commands return `null` as their error.
|
||||
|
||||
The command return `null` if the command was not run immediately, but was scheduled for later execution
|
||||
due to being requested while command was executed. This happens most commonly
|
||||
when running `run` from a `/script run/invoke` command since that always results in piling up command to run while `script` is being executed.
|
||||
|
||||
The mitigation for this is to use `run` in a separate scheduled function, or use `run` in a `tick` event, or literally in
|
||||
any other way than directly from a `/script` command, which will ensure that the command runs immediately.
|
||||
|
||||
<pre>
|
||||
run('fill 1 1 1 10 10 10 air') -> [0, ["Successfully filled 123 blocks"], null]
|
||||
run('give @s stone 4') -> [0, ["Gave 4 [Stone] to gnembon"], null]
|
||||
run('seed') -> [0, ["Seed: [4031384495743822299]"], null]
|
||||
run('sed') -> [0, [], "sed<--[HERE]"] // wrong command
|
||||
run('fill 1 1 1 10 10 10 air') -> [123, ["Successfully filled 123 blocks"], null]
|
||||
run('give @s stone 4') -> [1, ["Gave 4 [Stone] to gnembon"], null]
|
||||
run('seed') -> [-170661413, [Seed: [4031384495743822299]], null]
|
||||
run('sed') -> [-1, [], "sed<--[HERE]"] // wrong command
|
||||
|
||||
/script run run('setblock 0 0 0 stone') -> null
|
||||
/script run schedule(0, _() -> print(run('setblock 0 0 0 stone'))) -> [1, [Changed the block at 0, 0, 0], null]
|
||||
</pre>
|
||||
|
||||
### `save()`
|
||||
@@ -768,7 +778,8 @@ system calls. In all circumstances, these are only provided as read-only.
|
||||
* `game_major_target` - major release target. For 1.12.2, that would be 12
|
||||
* `game_minor_release` - minor release target. For 1.12.2, that would be 2
|
||||
* `game_protocol` - protocol version number
|
||||
* `game_pack_version` - datapack version number
|
||||
* `game_pack_version` - datapack version number as a version string
|
||||
* `game_pack_minor_version` - datapack format minor version number
|
||||
* `game_data_version` - data version of the game. Returns an integer, so it can be compared.
|
||||
* `game_stable` - indicating if its a production release or a snapshot
|
||||
|
||||
|
||||
@@ -540,7 +540,7 @@ On top of that, scarpet provides the following list of noises sampled directly f
|
||||
|
||||
`'barrier_noise'`, `'fluid_level_floodedness_noise'`, `'fluid_level_spread_noise'`, `'lava_noise'`,
|
||||
`'temperature'`, `'vegetation'`, `'continents'`, `'erosion'`, `'depth'`, `'ridges'`,
|
||||
`'initial_density_without_jaggedness'`, `'final_density'`, `'vein_toggle'`, `'vein_ridged'` and `'vein_gap'`
|
||||
`'preliminary_surface_level'`, `'final_density'`, `'vein_toggle'`, `'vein_ridged'` and `'vein_gap'`
|
||||
|
||||
<pre>
|
||||
// requesting single value
|
||||
@@ -625,7 +625,7 @@ It returns a `map` with a report indicating how many chunks were affected, and h
|
||||
|
||||
Adds a chunk ticket at a position, which makes the game to keep the designated area centered around
|
||||
`pos` with radius of `radius` loaded for a predefined amount of ticks, defined by `type`. Allowed types
|
||||
are `portal`: 300 ticks, `teleport`: 5 ticks, and `unknown`: 1 tick. Radius can be from 1 to 32 ticks.
|
||||
are `portal`: 300 ticks, `teleport`: 40 ticks, and `unknown`: 1 tick. Radius can be from 1 to 32 ticks.
|
||||
|
||||
This function is tentative - will likely change when chunk ticket API is properly fleshed out.
|
||||
|
||||
|
||||
@@ -204,7 +204,7 @@ Entity that `e` rides.
|
||||
|
||||
### `query(e, 'unmountable')`
|
||||
|
||||
Boolean, true if the entity cannot be mounted.
|
||||
Boolean, true if the entity cannot be unmounted.
|
||||
|
||||
### `(deprecated) query(e, 'tags')`
|
||||
|
||||
@@ -727,7 +727,7 @@ Mounts the entity to the `other`.
|
||||
|
||||
### `modify(e, 'unmountable', boolean)`
|
||||
|
||||
Denies or allows an entity to be mounted.
|
||||
Denies or allows an entity to be unmounted.
|
||||
|
||||
### `modify(e, 'drop_passengers')`
|
||||
|
||||
|
||||
@@ -318,11 +318,11 @@ Triggered when a player sends a disconnect package or is forcefully disconnected
|
||||
### `__on_player_message(player, message)`
|
||||
Triggered when a player sends a chat message.
|
||||
|
||||
This event can be cancelled by returning `'cancel'`, which prevents the message from being sent.
|
||||
|
||||
### `__on_player_command(player, command)`
|
||||
Triggered when a player runs a command. Command value is returned without the / in front.
|
||||
|
||||
This event can be cancelled by returning `'cancel'`, which prevents the message from being sent.
|
||||
|
||||
### `__on_statistic(player, category, event, value)`
|
||||
Triggered when a player statistic changes. Doesn't notify on periodic an rhythmic events, i.e.
|
||||
`time_since_death`, `time_since_rest`, and `played_one_minute` since these are triggered every tick. Event
|
||||
|
||||
@@ -70,8 +70,8 @@ Recipe type can take one of the following options:
|
||||
* `'smithing'` - smithing table (1.16+)
|
||||
|
||||
The return value is a list of available recipes (even if there is only one recipe available). Each recipe contains of
|
||||
an item triple of the crafting result, list of ingredients, each containing a list of possible variants of the
|
||||
ingredients in this slot, as item triples, or `null` if its a shaped recipe and a given slot in the patterns is left
|
||||
an item triple of the crafting results as a list of item stacks, list of ingredients, each containing a list of possible variants of the
|
||||
ingredients in this slot, as item ids, or `null` if it is a shaped recipe and a given slot in the patterns is left
|
||||
empty, and recipe specification as another list. Possible recipe specs is:
|
||||
* `['shaped', width, height]` - shaped crafting. `width` and `height` can be 1, 2 or 3.
|
||||
* `['shapeless']` - shapeless crafting
|
||||
@@ -80,10 +80,6 @@ Recipe type can take one of the following options:
|
||||
* `['special']` - special crafting recipe, typically not present in the crafting menu
|
||||
* `['custom']` - other recipe types
|
||||
|
||||
Note that ingredients are specified as tripes, with count and nbt information. Currently all recipes require always one
|
||||
of the ingredients, and for some recipes, even if the nbt data for the ingredient is specified (e.g. `dispenser`), it
|
||||
can accept items of any tags.
|
||||
|
||||
Also note that some recipes leave some products in the crafting window, and these can be determined using
|
||||
`crafting_remaining_item()` function
|
||||
|
||||
@@ -97,7 +93,7 @@ Also note that some recipes leave some products in the crafting window, and thes
|
||||
### `crafting_remaining_item(item)`
|
||||
|
||||
returns `null` if the item has no remaining item in the crafting window when used as a crafting ingredient, or an
|
||||
item name that serves as a replacement after crafting is done. Currently it can only be buckets and glass bottles.
|
||||
item tuple that serves as a replacement after crafting is done. Currently, it can only be buckets and glass bottles.
|
||||
|
||||
### `inventory_size(inventory)`
|
||||
|
||||
|
||||
+11
-8
@@ -1,15 +1,18 @@
|
||||
# Done to increase the memory available to gradle.
|
||||
org.gradle.jvmargs=-Xmx1G
|
||||
org.gradle.parallel=true
|
||||
|
||||
# IntelliJ IDEA is not yet fully compatible with configuration cache, see: https://github.com/FabricMC/fabric-loom/issues/1349
|
||||
org.gradle.configuration-cache=false
|
||||
|
||||
# Fabric Properties
|
||||
# check https://fabricmc.net/develop/
|
||||
minecraft_version=1.21.1
|
||||
loader_version=0.15.11
|
||||
jsr305_version=3.0.2
|
||||
fabric_version=0.99.2+1.21
|
||||
minecraft_version=26.2
|
||||
loader_version=0.19.3
|
||||
loom_version=1.15-SNAPSHOT
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.4.147
|
||||
mod_version = 26.2
|
||||
maven_group = carpet
|
||||
archives_base_name = fabric-carpet
|
||||
|
||||
@@ -17,12 +20,12 @@ org.gradle.jvmargs=-Xmx1G
|
||||
# The Curseforge versions "names" or ids for the main branch (comma separated: 1.16.4,1.16.5)
|
||||
# This is needed because CF uses too vague names for prereleases and release candidates
|
||||
# Can also be the version ID directly coming from https://minecraft.curseforge.com/api/game/versions?token=[API_TOKEN]
|
||||
release-curse-versions = Minecraft 1.21.1:1.21.1
|
||||
release-curse-versions = Minecraft 26:26.2
|
||||
# Whether or not to build another branch on release
|
||||
release-extra-branch = false
|
||||
# The name of the second branch to release
|
||||
release-extra-branch-name = 1.20.4
|
||||
release-extra-branch-name = 1.21.10
|
||||
# The "name" or id of the Curseforge version for the secondary branch
|
||||
# This is needed because CF uses too vague names for snapshots
|
||||
# Can also be the version ID directly coming from https://minecraft.curseforge.com/api/game/versions?token=[API_TOKEN]
|
||||
release-extra-curse-version = Minecraft 1.20:1.20.4-Snapshot
|
||||
release-extra-curse-version = Minecraft 1.21:1.21.10-Snapshot
|
||||
Vendored
BIN
Binary file not shown.
+2
-1
@@ -1,6 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright © 2015 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.
|
||||
@@ -15,6 +15,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
@@ -55,7 +57,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -83,10 +85,8 @@ done
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
# 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"'
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
@@ -114,7 +114,6 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -133,18 +132,21 @@ 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.
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
@@ -152,7 +154,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
@@ -169,7 +171,6 @@ fi
|
||||
# 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" )
|
||||
|
||||
@@ -197,16 +198,19 @@ if "$cygwin" || "$msys" ; then
|
||||
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.
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
|
||||
Vendored
+13
-12
@@ -13,6 +13,8 @@
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@@ -43,11 +45,11 @@ set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -57,22 +59,21 @@ 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.
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
: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 %*
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
before_install:
|
||||
- sdk install java 21.0.2-open
|
||||
- sdk use java 21.0.2-open
|
||||
- sdk install java 25.0.1-ms
|
||||
- sdk use java 25.0.1-ms
|
||||
@@ -70,12 +70,6 @@ public interface CarpetExtension
|
||||
registerCommands(dispatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Implement {@link #extensionSettingsManager()} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
default carpet.settings.SettingsManager customSettingsManager() {return null;}
|
||||
|
||||
/**
|
||||
* Provide your own custom settings manager managed in the same way as base /carpet
|
||||
* command, but separated to its own command as defined in SettingsManager.
|
||||
@@ -84,13 +78,7 @@ public interface CarpetExtension
|
||||
*
|
||||
*/
|
||||
default SettingsManager extensionSettingsManager() {
|
||||
// Warn extensions overriding the other (deprecated) method, go ahead and override this if you want to provide a custom SettingsManager
|
||||
SettingsManager deprecatedManager = customSettingsManager();
|
||||
if (deprecatedManager != null) {
|
||||
// Extension is providing a manager via the old method (and also hasn't overriden this)
|
||||
CarpetServer.warnOutdatedManager(this);
|
||||
}
|
||||
return customSettingsManager();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,6 +40,8 @@ import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.commands.PerfCommand;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class CarpetServer // static for now - easier to handle all around the code, its one anyways
|
||||
{
|
||||
public static MinecraftServer minecraft_server;
|
||||
@@ -160,7 +162,7 @@ public class CarpetServer // static for now - easier to handle all around the co
|
||||
LoggerRegistry.playerDisconnected(player);
|
||||
extensions.forEach(e -> e.onPlayerLoggedOut(player));
|
||||
// first case client, second case server
|
||||
CarpetScriptServer runningScriptServer = (player.getServer() == null) ? scriptServer : Vanilla.MinecraftServer_getScriptServer(player.getServer());
|
||||
CarpetScriptServer runningScriptServer = (player.level().getServer() == null) ? scriptServer : Vanilla.MinecraftServer_getScriptServer(player.level().getServer());
|
||||
if (runningScriptServer != null && !runningScriptServer.stopAll) {
|
||||
runningScriptServer.onPlayerLoggedOut(player, reason);
|
||||
}
|
||||
@@ -172,7 +174,7 @@ public class CarpetServer // static for now - easier to handle all around the co
|
||||
scriptServer = null;
|
||||
}
|
||||
|
||||
public static void onServerClosed(MinecraftServer server)
|
||||
public static void onServerClosed(@Nullable MinecraftServer server)
|
||||
{
|
||||
// this for whatever reason gets called multiple times even when joining on SP
|
||||
// so we allow to pass multiple times gating it only on existing server ref
|
||||
@@ -180,7 +182,7 @@ public class CarpetServer // static for now - easier to handle all around the co
|
||||
{
|
||||
if (scriptServer != null) scriptServer.onClose();
|
||||
// this is a mess, will cleanip onlly when global reference is gone
|
||||
if (!Vanilla.MinecraftServer_getScriptServer(server).stopAll) {
|
||||
if (server != null && !Vanilla.MinecraftServer_getScriptServer(server).stopAll) {
|
||||
Vanilla.MinecraftServer_getScriptServer(server).onClose();
|
||||
}
|
||||
|
||||
@@ -224,14 +226,5 @@ public class CarpetServer // static for now - easier to handle all around the co
|
||||
scriptServer.reload(server);
|
||||
extensions.forEach(e -> e.onReload(server));
|
||||
}
|
||||
|
||||
private static final Set<CarpetExtension> warnedOutdatedManagerProviders = new HashSet<>();
|
||||
static void warnOutdatedManager(CarpetExtension ext)
|
||||
{
|
||||
if (warnedOutdatedManagerProviders.add(ext))
|
||||
CarpetSettings.LOG.warn("""
|
||||
%s is providing a SettingsManager from an outdated method in CarpetExtension!
|
||||
This behaviour will not work in later Carpet versions and the manager won't be registered!""".formatted(ext.getClass().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,12 +12,16 @@ import carpet.utils.Messenger;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.SemanticVersion;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.Commands;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.ServerInterface;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.permissions.LevelBasedPermissionSet;
|
||||
import net.minecraft.server.permissions.PermissionCheck;
|
||||
import net.minecraft.server.permissions.PermissionSet;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
@@ -56,7 +60,7 @@ public class CarpetSettings
|
||||
public static final Logger LOG = LoggerFactory.getLogger("carpet");
|
||||
public static final ThreadLocal<Boolean> skipGenerationChecks = ThreadLocal.withInitial(() -> false);
|
||||
public static final ThreadLocal<Boolean> impendingFillSkipUpdates = ThreadLocal.withInitial(() -> false);
|
||||
public static int runPermissionLevel = 2;
|
||||
public static PermissionSet runPermissionLevel = LevelBasedPermissionSet.GAMEMASTER;
|
||||
public static Block structureBlockIgnoredBlock = Blocks.STRUCTURE_VOID;
|
||||
private static class LanguageValidator extends Validator<String> {
|
||||
@Override public String validate(CommandSourceStack source, CarpetRule<String> currentRule, String newValue, String string) {
|
||||
@@ -73,7 +77,7 @@ public class CarpetSettings
|
||||
@Rule(
|
||||
desc = "Sets the language for Carpet",
|
||||
category = FEATURE,
|
||||
options = {"en_us", "fr_fr", "pt_br", "zh_cn", "zh_tw"},
|
||||
options = {"en_us", "fr_fr", "es_ar","pt_br", "zh_cn", "zh_tw"},
|
||||
strict = true, // the current system doesn't handle fallbacks and other, not defined languages would make unreadable mess. Change later
|
||||
validate = LanguageValidator.class
|
||||
)
|
||||
@@ -129,7 +133,7 @@ public class CarpetSettings
|
||||
|
||||
private static class CarpetPermissionLevel extends Validator<String> {
|
||||
@Override public String validate(CommandSourceStack source, CarpetRule<String> currentRule, String newValue, String string) {
|
||||
if (source == null || source.hasPermission(4))
|
||||
if (source == null || Commands.LEVEL_OWNERS.check(source.permissions()))
|
||||
return newValue;
|
||||
return null;
|
||||
}
|
||||
@@ -152,9 +156,6 @@ public class CarpetSettings
|
||||
@Rule(desc = "Gbhs sgnf sadsgras fhskdpri!!!", category = EXPERIMENTAL)
|
||||
public static boolean superSecretSetting = false;
|
||||
|
||||
@Rule(desc = "Dropping entire stacks works also from on the crafting UI result slot", category = {RuleCategory.BUGFIX, SURVIVAL})
|
||||
public static boolean ctrlQCraftingFix = false;
|
||||
|
||||
@Rule(desc = "Parrots don't get of your shoulders until you receive proper damage", category = {SURVIVAL, FEATURE})
|
||||
public static boolean persistentParrots = false;
|
||||
|
||||
@@ -423,10 +424,32 @@ public class CarpetSettings
|
||||
@Rule(
|
||||
desc = "Required permission level for /perf command",
|
||||
options = {"2", "4"},
|
||||
category = CREATIVE
|
||||
category = CREATIVE,
|
||||
validate = PermissionValidator.class
|
||||
)
|
||||
public static int perfPermissionLevel = 4;
|
||||
|
||||
public static class PermissionValidator extends Validator<Integer> {
|
||||
@Override
|
||||
public Integer validate(CommandSourceStack source, CarpetRule<Integer> currentRule, Integer newValue, String string) {
|
||||
if (newValue == 2) {
|
||||
perfPermissionCheck = Commands.LEVEL_GAMEMASTERS;
|
||||
|
||||
} else if (newValue == 4) {
|
||||
perfPermissionCheck = Commands.LEVEL_OWNERS;
|
||||
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "You must have the permission level you are trying to set";
|
||||
}
|
||||
}
|
||||
public static PermissionCheck perfPermissionCheck = Commands.LEVEL_OWNERS;
|
||||
|
||||
|
||||
@Rule(desc = "Enables /log command to monitor events via chat and overlays", category = COMMAND)
|
||||
public static String commandLog = "true";
|
||||
|
||||
@@ -476,17 +499,21 @@ public class CarpetSettings
|
||||
|
||||
private static class ModulePermissionLevel extends Validator<String> {
|
||||
@Override public String validate(CommandSourceStack source, CarpetRule<String> currentRule, String newValue, String string) {
|
||||
int permissionLevel = switch (newValue) {
|
||||
case "false" -> 0;
|
||||
case "true", "ops" -> 2;
|
||||
case "0", "1", "2", "3", "4" -> Integer.parseInt(newValue);
|
||||
PermissionCheck permissionLevel = switch (newValue) {
|
||||
case "0", "false" -> Commands.LEVEL_ALL;
|
||||
case "1" -> Commands.LEVEL_MODERATORS;
|
||||
case "2", "true", "ops" -> Commands.LEVEL_GAMEMASTERS;
|
||||
case "3" -> Commands.LEVEL_ADMINS;
|
||||
case "4" -> Commands.LEVEL_OWNERS;
|
||||
default -> throw new IllegalArgumentException(); // already checked by previous validator
|
||||
};
|
||||
if (source != null && !source.hasPermission(permissionLevel))
|
||||
if (source != null && !permissionLevel.check(source.permissions()))
|
||||
return null;
|
||||
CarpetSettings.runPermissionLevel = permissionLevel;
|
||||
if (source != null)
|
||||
CarpetSettings.runPermissionLevel = LevelBasedPermissionSet.GAMEMASTER;
|
||||
if (source != null) {
|
||||
CommandHelper.notifyPlayersCommandsChanged(source.getServer());
|
||||
CarpetSettings.runPermissionLevel =source.permissions();
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
@Override
|
||||
@@ -708,7 +735,7 @@ public class CarpetSettings
|
||||
|
||||
if (server.isDedicatedServer())
|
||||
{
|
||||
int vd = (newValue >= 2)?newValue:((ServerInterface) server).getProperties().viewDistance;
|
||||
int vd = (newValue >= 2)?newValue:((ServerInterface) server).getProperties().viewDistance.get();
|
||||
if (vd != server.getPlayerList().getViewDistance())
|
||||
server.getPlayerList().setViewDistance(vd);
|
||||
return newValue;
|
||||
@@ -749,7 +776,7 @@ public class CarpetSettings
|
||||
|
||||
if (server.isDedicatedServer())
|
||||
{
|
||||
int vd = (newValue >= 2)?newValue:((DedicatedServer) server).getProperties().simulationDistance;
|
||||
int vd = (newValue >= 2)?newValue:((DedicatedServer) server).getProperties().simulationDistance.get();
|
||||
if (vd != server.getPlayerList().getSimulationDistance())
|
||||
server.getPlayerList().setSimulationDistance(vd);
|
||||
return newValue;
|
||||
@@ -908,7 +935,7 @@ public class CarpetSettings
|
||||
@Override
|
||||
public String validate(CommandSourceStack source, CarpetRule<String> currentRule, String newValue, String string) {
|
||||
if (source == null) return newValue; // closing or sync
|
||||
Optional<Block> ignoredBlock = source.registryAccess().registryOrThrow(Registries.BLOCK).getOptional(ResourceLocation.tryParse(newValue));
|
||||
Optional<Block> ignoredBlock = source.registryAccess().lookupOrThrow(Registries.BLOCK).getOptional(Identifier.tryParse(newValue));
|
||||
if (!ignoredBlock.isPresent()) {
|
||||
Messenger.m(source, "r Unknown block '" + newValue + "'.");
|
||||
return null;
|
||||
@@ -981,48 +1008,6 @@ public class CarpetSettings
|
||||
)
|
||||
public static int sculkSensorRange = 8;
|
||||
|
||||
/**
|
||||
* Listener, we need to update world borders to change whether
|
||||
* they are currently moving in real time or in game time.
|
||||
*/
|
||||
private static class WorldBorderValidator extends Validator<Boolean>
|
||||
{
|
||||
@Override
|
||||
public Boolean validate(CommandSourceStack source, CarpetRule<Boolean> changingRule, Boolean newValue, String userInput)
|
||||
{
|
||||
if (changingRule.value() ^ newValue)
|
||||
{
|
||||
// Needed for the update
|
||||
tickSyncedWorldBorders = newValue;
|
||||
MinecraftServer server = CarpetServer.minecraft_server;
|
||||
if (server == null)
|
||||
{
|
||||
return newValue;
|
||||
}
|
||||
for (ServerLevel level : server.getAllLevels())
|
||||
{
|
||||
WorldBorder worldBorder = level.getWorldBorder();
|
||||
if (worldBorder.getStatus() != BorderStatus.STATIONARY)
|
||||
{
|
||||
double from = worldBorder.getSize();
|
||||
double to = worldBorder.getLerpTarget();
|
||||
long time = worldBorder.getLerpRemainingTime();
|
||||
worldBorder.lerpSizeBetween(from, to, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
|
||||
@Rule(
|
||||
desc = "Makes world borders move based on in game time instead of real time",
|
||||
extra = "This has the effect that when the tick rate changes the world border speed also changes proportional to it",
|
||||
category = FEATURE,
|
||||
validate = WorldBorderValidator.class
|
||||
)
|
||||
public static boolean tickSyncedWorldBorders = false;
|
||||
|
||||
public enum FungusGrowthMode {
|
||||
FALSE, RANDOM, ALL;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import carpet.script.Expression;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
@@ -304,7 +305,7 @@ public class SettingsManager {
|
||||
/**
|
||||
* Calling this method is not supported.
|
||||
*/
|
||||
public void inspectClientsideCommand(CommandSourceStack source, String string)
|
||||
public void inspectClientsideCommand(String string)
|
||||
{
|
||||
if (string.startsWith("/" + identifier + " "))
|
||||
{
|
||||
@@ -316,9 +317,9 @@ public class SettingsManager {
|
||||
if (rules.containsKey(rule) && rules.get(rule).canBeToggledClientSide())
|
||||
{
|
||||
try {
|
||||
rules.get(rule).set(source, strOption);
|
||||
rules.get(rule).set(null, strOption);
|
||||
} catch (InvalidRuleValueException e) {
|
||||
e.notifySource(rule, source);
|
||||
//e.notifySource(rule, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -331,7 +332,7 @@ public class SettingsManager {
|
||||
{
|
||||
if (RuleHelper.getBooleanValue(rule) || (rule.type() == String.class && !rule.value().equals("false")))
|
||||
{
|
||||
CarpetServer.scriptServer.addScriptHost(source, rule.scarpetApp, s -> CommandHelper.canUseCommand(s, rule.value()), false, false, true, null);
|
||||
CarpetServer.scriptServer.addScriptHost(source, rule.scarpetApp, s -> CommandHelper.canUseCommand(s, rule.value()), false, false, true, null, Expression.LoadOverride.DEFAULT);
|
||||
} else {
|
||||
CarpetServer.scriptServer.removeScriptHost(source, rule.scarpetApp, false, true);
|
||||
}
|
||||
@@ -694,16 +695,16 @@ public class SettingsManager {
|
||||
{
|
||||
if (locked()) return 0;
|
||||
if (!rules.containsKey(rule.name())) return 0;
|
||||
ConfigReadResult conf = readSettingsFromConf(getFile());
|
||||
conf.ruleMap().put(rule.name(), stringValue);
|
||||
writeSettingsToConf(conf); // this may feels weird, but if conf
|
||||
// is locked, it will never reach this point.
|
||||
try {
|
||||
rule.set(source, stringValue);
|
||||
Messenger.m(source ,"gi "+String.format(tr(TranslationKeys.DEFAULT_SET), RuleHelper.translatedName(rule), stringValue));
|
||||
} catch (InvalidRuleValueException e) {
|
||||
e.notifySource(rule.name(), source);
|
||||
return 0;
|
||||
}
|
||||
ConfigReadResult conf = readSettingsFromConf(getFile());
|
||||
conf.ruleMap().put(rule.name(), stringValue);
|
||||
writeSettingsToConf(conf);
|
||||
return 1;
|
||||
}
|
||||
// removes overrides of the default values in the file
|
||||
|
||||
@@ -241,7 +241,7 @@ public class DrawCommand
|
||||
}
|
||||
if (CarpetSettings.fillUpdates)
|
||||
{
|
||||
list.forEach(blockpos1 -> world.blockUpdated(blockpos1, world.getBlockState(blockpos1).getBlock()));
|
||||
list.forEach(blockpos1 -> world.updateNeighborsAt(blockpos1, world.getBlockState(blockpos1).getBlock()));
|
||||
}
|
||||
Messenger.m(ctx.getSource(), "gi Filled " + affected + " blocks");
|
||||
return affected;
|
||||
@@ -291,7 +291,7 @@ public class DrawCommand
|
||||
|
||||
if (CarpetSettings.fillUpdates)
|
||||
{
|
||||
list.forEach(p -> world.blockUpdated(p, world.getBlockState(p).getBlock()));
|
||||
list.forEach(p -> world.updateNeighborsAt(p, world.getBlockState(p).getBlock()));
|
||||
}
|
||||
|
||||
Messenger.m(source, "gi Filled " + affected + " blocks");
|
||||
@@ -390,7 +390,7 @@ public class DrawCommand
|
||||
|
||||
for (BlockPos blockpos1 : list) {
|
||||
Block blokc = world.getBlockState(blockpos1).getBlock();
|
||||
world.blockUpdated(blockpos1, blokc);
|
||||
world.updateNeighborsAt(blockpos1, blokc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,7 +441,7 @@ public class DrawCommand
|
||||
|
||||
for (BlockPos blockpos1 : list) {
|
||||
Block blokc = world.getBlockState(blockpos1).getBlock();
|
||||
world.blockUpdated(blockpos1, blokc);
|
||||
world.updateNeighborsAt(blockpos1, blokc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ public class InfoCommand
|
||||
|
||||
private static int infoBlock(CommandSourceStack source, BlockPos pos, String grep)
|
||||
{
|
||||
if (!source.hasPermission(Commands.LEVEL_GAMEMASTERS)) {
|
||||
if (!Commands.LEVEL_GAMEMASTERS.check(source.permissions())) {
|
||||
//check id pos is loaded
|
||||
if (!source.getLevel().hasChunkAt(pos)) {
|
||||
Messenger.m(source, "r Chunk is not loaded");
|
||||
|
||||
@@ -15,6 +15,8 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.entity.EntitySpawnRequest;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
|
||||
@@ -39,11 +41,11 @@ public class PerimeterInfoCommand
|
||||
BlockPosArgument.getSpawnablePos(c, "center position"),
|
||||
null)).
|
||||
then(argument("mob", resource(commandBuildContext, Registries.ENTITY_TYPE)).
|
||||
suggests(SuggestionProviders.SUMMONABLE_ENTITIES).
|
||||
suggests(SuggestionProviders.cast(SuggestionProviders.SUMMONABLE_ENTITIES)).
|
||||
executes( (c) -> perimeterDiagnose(
|
||||
c.getSource(),
|
||||
BlockPosArgument.getSpawnablePos(c, "center position"),
|
||||
getSummonableEntityType(c, "mob").key().location().toString()
|
||||
getSummonableEntityType(c, "mob").key().identifier().toString()
|
||||
))));
|
||||
dispatcher.register(command);
|
||||
}
|
||||
@@ -55,8 +57,8 @@ public class PerimeterInfoCommand
|
||||
if (mobId != null)
|
||||
{
|
||||
nbttagcompound.putString("id", mobId);
|
||||
Entity baseEntity = EntityType.loadEntityRecursive(nbttagcompound, source.getLevel(), (entity_1x) -> {
|
||||
entity_1x.moveTo(new BlockPos(pos.getX(), source.getLevel().getMinBuildHeight()-10, pos.getZ()), entity_1x.getYRot(), entity_1x. getXRot());
|
||||
Entity baseEntity = EntityType.loadEntityRecursive(nbttagcompound, source.getLevel(), new EntitySpawnRequest(EntitySpawnReason.COMMAND, true), (entity_1x) -> {
|
||||
entity_1x.snapTo(new BlockPos(pos.getX(), source.getLevel().getMinY()-10, pos.getZ()), entity_1x.getYRot(), entity_1x. getXRot());
|
||||
return !source.getLevel().addWithUUID(entity_1x) ? null : entity_1x;
|
||||
});
|
||||
if (!(baseEntity instanceof Mob))
|
||||
|
||||
@@ -20,6 +20,7 @@ import me.lucko.fabric.api.permissions.v0.Permissions;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.commands.CommandBuildContext;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.Commands;
|
||||
import net.minecraft.commands.arguments.DimensionArgument;
|
||||
import net.minecraft.commands.arguments.GameModeArgument;
|
||||
import net.minecraft.commands.arguments.coordinates.RotationArgument;
|
||||
@@ -30,6 +31,8 @@ import net.minecraft.core.UUIDUtil;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.players.NameAndId;
|
||||
import net.minecraft.server.players.OldUsersConverter;
|
||||
import net.minecraft.server.players.PlayerList;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.GameType;
|
||||
@@ -37,19 +40,18 @@ import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec2;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static net.minecraft.commands.Commands.argument;
|
||||
import static net.minecraft.commands.Commands.literal;
|
||||
import static net.minecraft.commands.SharedSuggestionProvider.suggest;
|
||||
|
||||
public class PlayerCommand {
|
||||
public class PlayerCommand
|
||||
{
|
||||
// TODO: allow any order like execute
|
||||
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext) {
|
||||
public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext)
|
||||
{
|
||||
LiteralArgumentBuilder<CommandSourceStack> command = literal("player")
|
||||
.requires((player) -> Permissions.check(player, "carpet.command.player", CommandHelper.canUseCommand(player, CarpetSettings.commandPlayer)))
|
||||
.then(argument("player", StringArgumentType.word())
|
||||
@@ -98,15 +100,16 @@ public class PlayerCommand {
|
||||
.then(literal("left").executes(manipulation(ap -> ap.setStrafing(1))))
|
||||
.then(literal("right").executes(manipulation(ap -> ap.setStrafing(-1))))
|
||||
).then(literal("spawn").executes(PlayerCommand::spawn)
|
||||
.then(literal("in").requires((player) -> Permissions.check(player, "carpet.command.player.gamemode", player.hasPermission(2)))
|
||||
.then(literal("in").requires((player) -> Permissions.check(player, "carpet.command.player.gamemode", Commands.LEVEL_GAMEMASTERS.check(player.permissions())))
|
||||
.then(argument("gamemode", GameModeArgument.gameMode())
|
||||
.executes(PlayerCommand::spawn)))
|
||||
.then(literal("at").then(argument("position", Vec3Argument.vec3()).executes(PlayerCommand::spawn)
|
||||
.then(literal("facing").then(argument("direction", RotationArgument.rotation()).executes(PlayerCommand::spawn)
|
||||
.then(literal("in")
|
||||
.requires((player) -> Permissions.check(player,"carpet.command.player.dimension",player.hasPermission(4)))
|
||||
.then(argument("dimension", DimensionArgument.dimension()).executes(PlayerCommand::spawn)
|
||||
.then(literal("in").requires((player) -> player.hasPermission(2))
|
||||
.then(argument("dimension", DimensionArgument.dimension())
|
||||
.requires((player) -> Permissions.check(player,"carpet.command.player.dimension",Commands.LEVEL_GAMEMASTERS.check(player.permissions())))
|
||||
.executes(PlayerCommand::spawn)
|
||||
.then(literal("in")
|
||||
.then(argument("gamemode", GameModeArgument.gameMode())
|
||||
.executes(PlayerCommand::spawn)
|
||||
)))
|
||||
@@ -117,7 +120,8 @@ public class PlayerCommand {
|
||||
dispatcher.register(command);
|
||||
}
|
||||
|
||||
private static LiteralArgumentBuilder<CommandSourceStack> makeActionCommand(String actionName, ActionType type) {
|
||||
private static LiteralArgumentBuilder<CommandSourceStack> makeActionCommand(String actionName, ActionType type)
|
||||
{
|
||||
return literal(actionName)
|
||||
.executes(manipulation(ap -> ap.start(type, Action.once())))
|
||||
.then(literal("once").executes(manipulation(ap -> ap.start(type, Action.once()))))
|
||||
@@ -126,7 +130,8 @@ public class PlayerCommand {
|
||||
.executes(c -> manipulate(c, ap -> ap.start(type, Action.interval(IntegerArgumentType.getInteger(c, "ticks")))))));
|
||||
}
|
||||
|
||||
private static LiteralArgumentBuilder<CommandSourceStack> makeDropCommand(String actionName, boolean dropAll) {
|
||||
private static LiteralArgumentBuilder<CommandSourceStack> makeDropCommand(String actionName, boolean dropAll)
|
||||
{
|
||||
return literal(actionName)
|
||||
.then(literal("all").executes(manipulation(ap -> ap.drop(-2, dropAll))))
|
||||
.then(literal("mainhand").executes(manipulation(ap -> ap.drop(-1, dropAll))))
|
||||
@@ -135,32 +140,39 @@ public class PlayerCommand {
|
||||
executes(c -> manipulate(c, ap -> ap.drop(IntegerArgumentType.getInteger(c, "slot"), dropAll))));
|
||||
}
|
||||
|
||||
private static Collection<String> getPlayerSuggestions(CommandSourceStack source) {
|
||||
Set<String> players = new LinkedHashSet<>(List.of("Steve.bot", "Alex.bot"));
|
||||
private static Collection<String> getPlayerSuggestions(CommandSourceStack source)
|
||||
{
|
||||
Set<String> players = new LinkedHashSet<>(List.of("Steve", "Alex"));
|
||||
players.addAll(source.getOnlinePlayerNames());
|
||||
return players;
|
||||
}
|
||||
|
||||
private static ServerPlayer getPlayer(CommandContext<CommandSourceStack> context) {
|
||||
private static ServerPlayer getPlayer(CommandContext<CommandSourceStack> context)
|
||||
{
|
||||
String playerName = StringArgumentType.getString(context, "player");
|
||||
MinecraftServer server = context.getSource().getServer();
|
||||
return server.getPlayerList().getPlayerByName(playerName);
|
||||
}
|
||||
|
||||
private static boolean cantManipulate(CommandContext<CommandSourceStack> context) {
|
||||
private static boolean cantManipulate(CommandContext<CommandSourceStack> context)
|
||||
{
|
||||
Player player = getPlayer(context);
|
||||
CommandSourceStack source = context.getSource();
|
||||
if (player == null) {
|
||||
if (player == null)
|
||||
{
|
||||
Messenger.m(source, "r Can only manipulate existing players");
|
||||
return true;
|
||||
}
|
||||
Player sender = source.getPlayer();
|
||||
if (sender == null) {
|
||||
if (sender == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!source.getServer().getPlayerList().isOp(sender.getGameProfile())) {
|
||||
if (sender != player && !(player instanceof EntityPlayerMPFake)) {
|
||||
if (!source.getServer().getPlayerList().isOp(sender.nameAndId()))
|
||||
{
|
||||
if (sender != player && !(player instanceof EntityPlayerMPFake))
|
||||
{
|
||||
Messenger.m(source, "r Non OP players can't control other real players");
|
||||
return true;
|
||||
}
|
||||
@@ -168,7 +180,8 @@ public class PlayerCommand {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean cantReMove(CommandContext<CommandSourceStack> context) {
|
||||
private static boolean cantReMove(CommandContext<CommandSourceStack> context)
|
||||
{
|
||||
if (cantManipulate(context)) return true;
|
||||
Player player = getPlayer(context);
|
||||
if (player instanceof EntityPlayerMPFake) return false;
|
||||
@@ -176,63 +189,95 @@ public class PlayerCommand {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean cantSpawn(CommandContext<CommandSourceStack> context) {
|
||||
private static boolean cantSpawn(CommandContext<CommandSourceStack> context)
|
||||
{
|
||||
String playerName = StringArgumentType.getString(context, "player");
|
||||
MinecraftServer server = context.getSource().getServer();
|
||||
PlayerList manager = server.getPlayerList();
|
||||
|
||||
if (manager.getPlayerByName(playerName) != null) {
|
||||
if (EntityPlayerMPFake.isSpawningPlayer(playerName))
|
||||
{
|
||||
Messenger.m(context.getSource(), "r Player ", "rb " + playerName, "r is currently logging on");
|
||||
return true;
|
||||
}
|
||||
if (manager.getPlayerByName(playerName) != null)
|
||||
{
|
||||
Messenger.m(context.getSource(), "r Player ", "rb " + playerName, "r is already logged on");
|
||||
return true;
|
||||
}
|
||||
var sender = context.getSource().getPlayer();
|
||||
if(!playerName.endsWith(".bot") && sender != null && !Permissions.check(sender,"carpet.command.player.name",sender.hasPermissions(4))){
|
||||
if(!playerName.endsWith(".bot") && sender != null && !Permissions.check(sender,"carpet.command.player.name",Commands.LEVEL_GAMEMASTERS.check(sender.permissions()))){
|
||||
Messenger.m(sender,"r You can't spawn a player whose name isn't ends with `.bot` suffix.");
|
||||
Messenger.m(sender,"r Try this: /player "+playerName+".bot spawn ...");
|
||||
return true;
|
||||
}
|
||||
|
||||
GameProfile profile = server.getProfileCache().get(playerName).orElse(null);
|
||||
if (profile == null) {
|
||||
if (!CarpetSettings.allowSpawningOfflinePlayers) {
|
||||
UUID uuid = OldUsersConverter.convertMobOwnerIfNecessary(server, playerName);
|
||||
if (uuid == null)
|
||||
{
|
||||
if (!CarpetSettings.allowSpawningOfflinePlayers)
|
||||
{
|
||||
Messenger.m(context.getSource(), "r Player "+playerName+" is either banned by Mojang, or auth servers are down. " +
|
||||
"Banned players can only be summoned in Singleplayer and in servers in off-line mode.");
|
||||
return true;
|
||||
} else {
|
||||
profile = new GameProfile(UUIDUtil.createOfflinePlayerUUID(playerName), playerName);
|
||||
uuid = UUIDUtil.createOfflinePlayerUUID(playerName);
|
||||
}
|
||||
}
|
||||
if (manager.getBans().isBanned(profile)) {
|
||||
//GameProfile profile = new GameProfile(uuid, playerName);
|
||||
NameAndId profile = server.services().nameToIdCache().get(uuid).orElse(null);
|
||||
if (profile == null)
|
||||
{
|
||||
if (!CarpetSettings.allowSpawningOfflinePlayers)
|
||||
{
|
||||
Messenger.m(context.getSource(), "r Player "+playerName+" is either banned by Mojang, or auth servers are down. " +
|
||||
"Banned players can only be summoned in Singleplayer and in servers in off-line mode.");
|
||||
return true;
|
||||
} else {
|
||||
profile = new NameAndId(UUIDUtil.createOfflinePlayerUUID(playerName), playerName);
|
||||
}
|
||||
}
|
||||
if (manager.getBans().isBanned(profile))
|
||||
{
|
||||
Messenger.m(context.getSource(), "r Player ", "rb " + playerName, "r is banned on this server");
|
||||
return true;
|
||||
}
|
||||
if (manager.isUsingWhitelist() && manager.isWhiteListed(profile) && !context.getSource().hasPermission(2)) {
|
||||
if (manager.isUsingWhitelist() && manager.isWhiteListed(profile) && !Commands.LEVEL_GAMEMASTERS.check(context.getSource().permissions()))
|
||||
{
|
||||
Messenger.m(context.getSource(), "r Whitelisted players can only be spawned by operators");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int kill(CommandContext<CommandSourceStack> context) {
|
||||
private static int kill(CommandContext<CommandSourceStack> context)
|
||||
{
|
||||
if (cantReMove(context)) return 0;
|
||||
getPlayer(context).kill();
|
||||
ServerPlayer player = getPlayer(context);
|
||||
player.kill(player.level());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface SupplierWithCSE<T> {
|
||||
interface SupplierWithCSE<T>
|
||||
{
|
||||
T get() throws CommandSyntaxException;
|
||||
}
|
||||
|
||||
private static <T> T getArgOrDefault(SupplierWithCSE<T> getter, T defaultValue) throws CommandSyntaxException {
|
||||
try {
|
||||
private static <T> T getArgOrDefault(SupplierWithCSE<T> getter, T defaultValue) throws CommandSyntaxException
|
||||
{
|
||||
try
|
||||
{
|
||||
return getter.get();
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
private static int spawn(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
|
||||
private static int spawn(CommandContext<CommandSourceStack> context) throws CommandSyntaxException
|
||||
{
|
||||
if (cantSpawn(context)) return 0;
|
||||
|
||||
CommandSourceStack source = context.getSource();
|
||||
@@ -250,29 +295,33 @@ public class PlayerCommand {
|
||||
);
|
||||
GameType mode = GameType.CREATIVE;
|
||||
boolean flying = false;
|
||||
if (source.getEntity() instanceof ServerPlayer sender) {
|
||||
if (source.getEntity() instanceof ServerPlayer sender)
|
||||
{
|
||||
mode = sender.gameMode.getGameModeForPlayer();
|
||||
flying = sender.getAbilities().flying;
|
||||
}
|
||||
try {
|
||||
mode = GameModeArgument.getGameMode(context, "gamemode");
|
||||
} catch (IllegalArgumentException notPresent) {
|
||||
}
|
||||
} catch (IllegalArgumentException notPresent) {}
|
||||
|
||||
if (mode == GameType.SPECTATOR) {
|
||||
if (mode == GameType.SPECTATOR)
|
||||
{
|
||||
// Force override flying to true for spectator players, or they will fell out of the world.
|
||||
flying = true;
|
||||
} else if (mode.isSurvival()) {
|
||||
} else if (mode.isSurvival())
|
||||
{
|
||||
// Force override flying to false for survival-like players, or they will fly too
|
||||
flying = false;
|
||||
}
|
||||
String playerName = StringArgumentType.getString(context, "player");
|
||||
if (playerName.length() > maxNameLength(source.getServer())) {
|
||||
if (playerName.length() > maxNameLength(source.getServer()))
|
||||
{
|
||||
Messenger.m(source, "rb Player name: " + playerName + " is too long");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!Level.isInSpawnableBounds(BlockPos.containing(pos))) {
|
||||
if (!Level.isInSpawnableBounds(BlockPos.containing(pos)))
|
||||
{
|
||||
Messenger.m(source, "rb Player " + playerName + " cannot be placed outside of the world");
|
||||
return 0;
|
||||
}
|
||||
@@ -281,40 +330,44 @@ public class PlayerCommand {
|
||||
Messenger.m(source, "rb Player " + playerName + " doesn't exist and cannot spawn in online mode. " +
|
||||
"Turn the server offline or the allowSpawningOfflinePlayers on to spawn non-existing players");
|
||||
return 0;
|
||||
}
|
||||
;
|
||||
};
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int maxNameLength(MinecraftServer server) {
|
||||
private static int maxNameLength(MinecraftServer server)
|
||||
{
|
||||
return server.getPort() >= 0 ? SharedConstants.MAX_PLAYER_NAME_LENGTH : 40;
|
||||
}
|
||||
|
||||
private static int manipulate(CommandContext<CommandSourceStack> context, Consumer<EntityPlayerActionPack> action) {
|
||||
private static int manipulate(CommandContext<CommandSourceStack> context, Consumer<EntityPlayerActionPack> action)
|
||||
{
|
||||
if (cantManipulate(context)) return 0;
|
||||
ServerPlayer player = getPlayer(context);
|
||||
action.accept(((ServerPlayerInterface) player).getActionPack());
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static Command<CommandSourceStack> manipulation(Consumer<EntityPlayerActionPack> action) {
|
||||
private static Command<CommandSourceStack> manipulation(Consumer<EntityPlayerActionPack> action)
|
||||
{
|
||||
return c -> manipulate(c, action);
|
||||
}
|
||||
|
||||
private static int shadow(CommandContext<CommandSourceStack> context) {
|
||||
private static int shadow(CommandContext<CommandSourceStack> context)
|
||||
{
|
||||
if (cantManipulate(context)) return 0;
|
||||
|
||||
ServerPlayer player = getPlayer(context);
|
||||
if (player instanceof EntityPlayerMPFake) {
|
||||
if (player instanceof EntityPlayerMPFake)
|
||||
{
|
||||
Messenger.m(context.getSource(), "r Cannot shadow fake players");
|
||||
return 0;
|
||||
}
|
||||
if (player.getServer().isSingleplayerOwner(player.getGameProfile())) {
|
||||
if (player.level().getServer().isSingleplayerOwner(player.nameAndId())) {
|
||||
Messenger.m(context.getSource(), "r Cannot shadow single-player server owner");
|
||||
return 0;
|
||||
}
|
||||
|
||||
EntityPlayerMPFake.createShadow(player.server, player);
|
||||
EntityPlayerMPFake.createShadow(player.level().getServer(), player);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
|
||||
import net.minecraft.world.entity.ai.memory.MemorySlot;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface BrainInterface {
|
||||
Map<MemoryModuleType<?>, MemorySlot<?>> getMemoriesCM();
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.level.Ticket;
|
||||
import net.minecraft.util.SortedArraySet;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
|
||||
public interface ChunkTicketManagerInterface
|
||||
{
|
||||
void changeSpawnChunks(ChunkPos pos, int distance);
|
||||
|
||||
Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> getTicketsByPosition();
|
||||
|
||||
void replaceHolder(ChunkHolder oldHolder, ChunkHolder newHolder);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.commands.CommandResultCallback;
|
||||
import net.minecraft.commands.CommandSigningContext;
|
||||
import net.minecraft.commands.arguments.EntityAnchorArgument;
|
||||
import net.minecraft.util.TaskChainer;
|
||||
|
||||
public interface CommandSourceStackInterface {
|
||||
void setupPrivates(boolean bl, CommandResultCallback commandResultCallback, EntityAnchorArgument.Anchor anchor, CommandSigningContext commandSigningContext, TaskChainer taskChainer);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
|
||||
public interface DefaultRedstoneWireEvaluatorInferface
|
||||
{
|
||||
int calculateTargetStrengthCM(final Level level, final BlockPos pos);
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import carpet.script.EntityEventsGroup;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
|
||||
public interface EntityInterface
|
||||
{
|
||||
@@ -19,4 +22,5 @@ public interface EntityInterface
|
||||
int getPublicNetherPortalCooldown();
|
||||
void setPublicNetherPortalCooldown(int what);
|
||||
|
||||
Stream<Entity> cm$getIndirectPassengersStream();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package carpet.fakes;
|
||||
|
||||
public interface FoodDataInterface
|
||||
{
|
||||
float getCMExhaustionLevel();
|
||||
|
||||
void setExhaustion(float aFloat);
|
||||
}
|
||||
@@ -10,5 +10,5 @@ public interface IngredientInterface
|
||||
* Gets all the stacks of the ingredients for a given item recipe. Also used for {@link carpet.helpers.HopperCounter#guessColor}
|
||||
* to guess the colour of an item to display it prettily
|
||||
*/
|
||||
List<Collection<ItemStack>> getRecipeStacks();
|
||||
//List<Collection<ItemStack>> getRecipeStacks();
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.world.level.redstone.CollectingNeighborUpdater;
|
||||
import net.minecraft.world.level.redstone.NeighborUpdater;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -21,5 +22,5 @@ public interface LevelInterface
|
||||
|
||||
List<Entity> getOtherEntitiesLimited(@Nullable Entity except, AABB box, Predicate<? super Entity> predicate, int limit);
|
||||
|
||||
NeighborUpdater getNeighborUpdater();
|
||||
CollectingNeighborUpdater getNeighborUpdater();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.client.renderer.blockentity.state.BlockEntityRenderState;
|
||||
|
||||
public interface PistonHeadRenderStateInterface {
|
||||
public BlockEntityRenderState getMovedBERenderState();
|
||||
public void setMovedBERenderState(BlockEntityRenderState state);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
|
||||
public interface RecipeManagerInterface
|
||||
{
|
||||
/**
|
||||
* Gets all the recipes for a given item. Also used for {@link carpet.helpers.HopperCounter#guessColor} to guess the
|
||||
* colour of an item to display it prettily
|
||||
*/
|
||||
List<Recipe<?>> getAllMatching(final RecipeType<?> type, final ResourceLocation itemId, final RegistryAccess registryAccess);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.entity.LevelEntityGetter;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
|
||||
public interface ServerWorldInterface {
|
||||
ServerLevelData getWorldPropertiesCM();
|
||||
LevelEntityGetter<Entity> getEntityLookupCMPublic();
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package carpet.fakes;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.minecraft.server.level.Ticket;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface TicketsFetcherInterface
|
||||
{
|
||||
Long2ObjectOpenHashMap<List<Ticket>> getTicketsByPosition();
|
||||
}
|
||||
@@ -6,5 +6,5 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public interface WorldChunkInterface
|
||||
{
|
||||
BlockState setBlockStateWithBlockEntity(BlockPos blockPos, BlockState newBlockState, BlockEntity newBlockEntity, boolean boolean1);
|
||||
BlockState setBlockStateWithBlockEntity(BlockPos blockPos, BlockState newBlockState, BlockEntity newBlockEntity, int flags);
|
||||
}
|
||||
@@ -100,7 +100,7 @@ public class BlockRotator
|
||||
}
|
||||
}
|
||||
// Send block update to the block that just have been rotated.
|
||||
world.neighborChanged(blockpos, block, source.pos());
|
||||
world.neighborChanged(blockpos, block, null);
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import carpet.script.utils.Tracer;
|
||||
import net.minecraft.commands.arguments.EntityAnchorArgument;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetHeldSlotPacket;
|
||||
import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
@@ -19,11 +19,11 @@ import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.animal.horse.AbstractHorse;
|
||||
import net.minecraft.world.entity.animal.equine.AbstractHorse;
|
||||
import net.minecraft.world.entity.decoration.ItemFrame;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.entity.vehicle.Boat;
|
||||
import net.minecraft.world.entity.vehicle.Minecart;
|
||||
import net.minecraft.world.entity.vehicle.boat.Boat;
|
||||
import net.minecraft.world.entity.vehicle.minecart.Minecart;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
@@ -201,7 +201,7 @@ public class EntityPlayerActionPack
|
||||
if (closest instanceof AbstractHorse && onlyRideables)
|
||||
((AbstractHorse) closest).mobInteract(player, InteractionHand.MAIN_HAND);
|
||||
else
|
||||
player.startRiding(closest,true);
|
||||
player.startRiding(closest,true, true);
|
||||
return this;
|
||||
}
|
||||
public EntityPlayerActionPack dismount()
|
||||
@@ -274,15 +274,15 @@ public class EntityPlayerActionPack
|
||||
else // one slot
|
||||
{
|
||||
if (selectedSlot == -1)
|
||||
selectedSlot = inv.selected;
|
||||
selectedSlot = inv.getSelectedSlot();
|
||||
dropItemFromSlot(selectedSlot, dropAll);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSlot(int slot)
|
||||
{
|
||||
player.getInventory().selected = slot-1;
|
||||
player.connection.send(new ClientboundSetCarriedItemPacket(slot-1));
|
||||
player.getInventory().setSelectedSlot(slot-1);
|
||||
player.connection.send(new ClientboundSetHeldSlotPacket(slot-1));
|
||||
}
|
||||
|
||||
public enum ActionType
|
||||
@@ -310,16 +310,16 @@ public class EntityPlayerActionPack
|
||||
case BLOCK:
|
||||
{
|
||||
player.resetLastActionTime();
|
||||
ServerLevel world = player.serverLevel();
|
||||
ServerLevel world = player.level();
|
||||
BlockHitResult blockHit = (BlockHitResult) hit;
|
||||
BlockPos pos = blockHit.getBlockPos();
|
||||
Direction side = blockHit.getDirection();
|
||||
if (pos.getY() < player.level().getMaxBuildHeight() - (side == Direction.UP ? 1 : 0) && world.mayInteract(player, pos))
|
||||
if (pos.getY() < player.level().getMaxY() - (side == Direction.UP ? 1 : 0) && world.mayInteract(player, pos))
|
||||
{
|
||||
InteractionResult result = player.gameMode.useItemOn(player, world, player.getItemInHand(hand), hand, blockHit);
|
||||
if (result.consumesAction())
|
||||
if (result instanceof InteractionResult.Success success)
|
||||
{
|
||||
if (result.shouldSwing()) player.swing(hand);
|
||||
if (success.swingSource() == InteractionResult.SwingSource.SERVER) player.swing(hand);
|
||||
ap.itemUseCooldown = 3;
|
||||
return true;
|
||||
}
|
||||
@@ -334,13 +334,13 @@ public class EntityPlayerActionPack
|
||||
boolean handWasEmpty = player.getItemInHand(hand).isEmpty();
|
||||
boolean itemFrameEmpty = (entity instanceof ItemFrame) && ((ItemFrame) entity).getItem().isEmpty();
|
||||
Vec3 relativeHitPos = entityHit.getLocation().subtract(entity.getX(), entity.getY(), entity.getZ());
|
||||
if (entity.interactAt(player, relativeHitPos, hand).consumesAction())
|
||||
if (entity.interact(player, hand, relativeHitPos).consumesAction())
|
||||
{
|
||||
ap.itemUseCooldown = 3;
|
||||
return true;
|
||||
}
|
||||
// fix for SS itemframe always returns CONSUME even if no action is performed
|
||||
if (player.interactOn(entity, hand).consumesAction() && !(handWasEmpty && itemFrameEmpty))
|
||||
if (player.interactOn(entity, hand, relativeHitPos).consumesAction() && !(handWasEmpty && itemFrameEmpty))
|
||||
{
|
||||
ap.itemUseCooldown = 3;
|
||||
return true;
|
||||
@@ -402,7 +402,7 @@ public class EntityPlayerActionPack
|
||||
boolean blockBroken = false;
|
||||
if (player.gameMode.getGameModeForPlayer().isCreative())
|
||||
{
|
||||
player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, side, player.level().getMaxBuildHeight(), -1);
|
||||
player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, side, player.level().getMaxY(), -1);
|
||||
ap.blockHitDelay = 5;
|
||||
blockBroken = true;
|
||||
}
|
||||
@@ -410,9 +410,9 @@ public class EntityPlayerActionPack
|
||||
{
|
||||
if (ap.currentBlock != null)
|
||||
{
|
||||
player.gameMode.handleBlockBreakAction(ap.currentBlock, ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, side, player.level().getMaxBuildHeight(), -1);
|
||||
player.gameMode.handleBlockBreakAction(ap.currentBlock, ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, side, player.level().getMaxY(), -1);
|
||||
}
|
||||
player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, side, player.level().getMaxBuildHeight(), -1);
|
||||
player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, side, player.level().getMaxY(), -1);
|
||||
boolean notAir = !state.isAir();
|
||||
if (notAir && ap.curBlockDamageMP == 0)
|
||||
{
|
||||
@@ -435,7 +435,7 @@ public class EntityPlayerActionPack
|
||||
ap.curBlockDamageMP += state.getDestroyProgress(player, player.level(), pos);
|
||||
if (ap.curBlockDamageMP >= 1)
|
||||
{
|
||||
player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.STOP_DESTROY_BLOCK, side, player.level().getMaxBuildHeight(), -1);
|
||||
player.gameMode.handleBlockBreakAction(pos, ServerboundPlayerActionPacket.Action.STOP_DESTROY_BLOCK, side, player.level().getMaxY(), -1);
|
||||
ap.currentBlock = null;
|
||||
ap.blockHitDelay = 5;
|
||||
blockBroken = true;
|
||||
@@ -457,7 +457,7 @@ public class EntityPlayerActionPack
|
||||
EntityPlayerActionPack ap = ((ServerPlayerInterface) player).getActionPack();
|
||||
if (ap.currentBlock == null) return;
|
||||
player.level().destroyBlockProgress(-1, ap.currentBlock, -1);
|
||||
player.gameMode.handleBlockBreakAction(ap.currentBlock, ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, Direction.DOWN, player.level().getMaxBuildHeight(), -1);
|
||||
player.gameMode.handleBlockBreakAction(ap.currentBlock, ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK, Direction.DOWN, player.level().getMaxY(), -1);
|
||||
ap.currentBlock = null;
|
||||
}
|
||||
},
|
||||
@@ -468,7 +468,8 @@ public class EntityPlayerActionPack
|
||||
{
|
||||
if (action.limit == 1)
|
||||
{
|
||||
if (player.onGround()) player.jumpFromGround(); // onGround
|
||||
if (player.onGround()) player.jumpFromGround();
|
||||
else if (!player.onClimbable()) player.tryToStartFallFlying();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -58,7 +58,7 @@ public interface FertilizableCoral extends BonemealableBlock {
|
||||
|
||||
MapColor color = blockUnder.getMapColor(worldIn, pos);
|
||||
BlockState properBlock = blockUnder;
|
||||
HolderSet.Named<Block> coralBlocks = worldIn.registryAccess().registryOrThrow(Registries.BLOCK).getTag(BlockTags.CORAL_BLOCKS).orElseThrow();
|
||||
HolderSet.Named<Block> coralBlocks = worldIn.registryAccess().lookupOrThrow(Registries.BLOCK).get(BlockTags.CORAL_BLOCKS).orElseThrow();
|
||||
for (Holder<Block> block: coralBlocks)
|
||||
{
|
||||
properBlock = block.value().defaultBlockState();
|
||||
@@ -75,10 +75,10 @@ public interface FertilizableCoral extends BonemealableBlock {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (worldIn.random.nextInt(10) == 0)
|
||||
if (worldIn.getRandom().nextInt(10) == 0)
|
||||
{
|
||||
BlockPos randomPos = pos.offset(worldIn.random.nextInt(16) - 8, worldIn.random.nextInt(8), worldIn.random.nextInt(16) - 8);
|
||||
if (coralBlocks.contains(worldIn.getBlockState(randomPos).getBlockHolder()))
|
||||
BlockPos randomPos = pos.offset(worldIn.getRandom().nextInt(16) - 8, worldIn.getRandom().nextInt(8), worldIn.getRandom().nextInt(16) - 8);
|
||||
if (worldIn.getBlockState(randomPos).is(BlockTags.CORAL_BLOCKS))
|
||||
{
|
||||
worldIn.setBlock(randomPos, Blocks.WET_SPONGE.defaultBlockState(), Block.UPDATE_ALL);
|
||||
}
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
package carpet.helpers;
|
||||
|
||||
import carpet.CarpetServer;
|
||||
import carpet.fakes.IngredientInterface;
|
||||
import carpet.fakes.RecipeManagerInterface;
|
||||
import carpet.script.utils.RecipeHelper;
|
||||
import carpet.utils.Messenger;
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongLinkedOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.network.chat.TextColor;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.DyeColor;
|
||||
@@ -24,7 +25,7 @@ import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.AbstractBannerBlock;
|
||||
import net.minecraft.world.level.block.BeaconBeamBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
@@ -32,12 +33,12 @@ import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.material.MapColor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
@@ -100,9 +101,11 @@ public class HopperCounter
|
||||
{
|
||||
startTick = -1;
|
||||
this.color = color;
|
||||
String hexColor = Integer.toHexString(color.getTextColor());
|
||||
String hexColor = Integer.toHexString(color.getTextColor() & 0xFFFFFF); // don't get alpha
|
||||
if (hexColor.length() < 6)
|
||||
{
|
||||
hexColor = "0".repeat(6 - hexColor.length()) + hexColor;
|
||||
}
|
||||
this.coloredName = '#' + hexColor + ' ' + color.getName();
|
||||
}
|
||||
|
||||
@@ -136,6 +139,7 @@ public class HopperCounter
|
||||
|
||||
/**
|
||||
* Resets all counters, clearing their items.
|
||||
*
|
||||
* @param fresh Whether or not to start the clocks going immediately or later.
|
||||
*/
|
||||
public static void resetAll(MinecraftServer server, boolean fresh)
|
||||
@@ -143,7 +147,10 @@ public class HopperCounter
|
||||
for (HopperCounter counter : COUNTERS.values())
|
||||
{
|
||||
counter.reset(server);
|
||||
if (fresh) counter.startTick = -1;
|
||||
if (fresh)
|
||||
{
|
||||
counter.startTick = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +166,10 @@ public class HopperCounter
|
||||
List<Component> temp = counter.format(server, realtime, false);
|
||||
if (temp.size() > 1)
|
||||
{
|
||||
if (!text.isEmpty()) text.add(Messenger.s(""));
|
||||
if (!text.isEmpty())
|
||||
{
|
||||
text.add(Messenger.s(""));
|
||||
}
|
||||
text.addAll(temp);
|
||||
}
|
||||
}
|
||||
@@ -215,7 +225,7 @@ public class HopperCounter
|
||||
Item item = e.getKey();
|
||||
MutableComponent itemName = Component.translatable(item.getDescriptionId());
|
||||
Style itemStyle = itemName.getStyle();
|
||||
TextColor color = guessColor(item, server.registryAccess());
|
||||
TextColor color = guessColor(item, server.overworld());
|
||||
itemName.setStyle((color != null) ? itemStyle.withColor(color) : itemStyle.withItalic(true));
|
||||
long count = e.getLongValue();
|
||||
return Messenger.c("g - ", itemName,
|
||||
@@ -232,13 +242,25 @@ public class HopperCounter
|
||||
*/
|
||||
public static int appropriateColor(int color)
|
||||
{
|
||||
if (color == 0) return MapColor.SNOW.col;
|
||||
if (color == 0)
|
||||
{
|
||||
return MapColor.SNOW.col;
|
||||
}
|
||||
int r = (color >> 16 & 255);
|
||||
int g = (color >> 8 & 255);
|
||||
int b = (color & 255);
|
||||
if (r < 70) r = 70;
|
||||
if (g < 70) g = 70;
|
||||
if (b < 70) b = 70;
|
||||
if (r < 70)
|
||||
{
|
||||
r = 70;
|
||||
}
|
||||
if (g < 70)
|
||||
{
|
||||
g = 70;
|
||||
}
|
||||
if (b < 70)
|
||||
{
|
||||
b = 70;
|
||||
}
|
||||
return (r << 16) + (g << 8) + b;
|
||||
}
|
||||
|
||||
@@ -247,19 +269,19 @@ public class HopperCounter
|
||||
* {@link Block#defaultMapColor()} method as these items have those same colours.
|
||||
*/
|
||||
private static final Map<Item, Block> DEFAULTS = Map.ofEntries(
|
||||
entry(Items.DANDELION, Blocks.YELLOW_WOOL),
|
||||
entry(Items.POPPY, Blocks.RED_WOOL),
|
||||
entry(Items.BLUE_ORCHID, Blocks.LIGHT_BLUE_WOOL),
|
||||
entry(Items.ALLIUM, Blocks.MAGENTA_WOOL),
|
||||
entry(Items.DANDELION, Blocks.WOOL.yellow()),
|
||||
entry(Items.POPPY, Blocks.WOOL.red()),
|
||||
entry(Items.BLUE_ORCHID, Blocks.WOOL.lightBlue()),
|
||||
entry(Items.ALLIUM, Blocks.WOOL.magenta()),
|
||||
entry(Items.AZURE_BLUET, Blocks.SNOW_BLOCK),
|
||||
entry(Items.RED_TULIP, Blocks.RED_WOOL),
|
||||
entry(Items.ORANGE_TULIP, Blocks.ORANGE_WOOL),
|
||||
entry(Items.RED_TULIP, Blocks.WOOL.red()),
|
||||
entry(Items.ORANGE_TULIP, Blocks.WOOL.orange()),
|
||||
entry(Items.WHITE_TULIP, Blocks.SNOW_BLOCK),
|
||||
entry(Items.PINK_TULIP, Blocks.PINK_WOOL),
|
||||
entry(Items.PINK_TULIP, Blocks.WOOL.pink()),
|
||||
entry(Items.OXEYE_DAISY, Blocks.SNOW_BLOCK),
|
||||
entry(Items.CORNFLOWER, Blocks.BLUE_WOOL),
|
||||
entry(Items.WITHER_ROSE, Blocks.BLACK_WOOL),
|
||||
entry(Items.LILY_OF_THE_VALLEY, Blocks.WHITE_WOOL),
|
||||
entry(Items.CORNFLOWER, Blocks.WOOL.blue()),
|
||||
entry(Items.WITHER_ROSE, Blocks.WOOL.black()),
|
||||
entry(Items.LILY_OF_THE_VALLEY, Blocks.WOOL.white()),
|
||||
entry(Items.BROWN_MUSHROOM, Blocks.BROWN_MUSHROOM_BLOCK),
|
||||
entry(Items.RED_MUSHROOM, Blocks.RED_MUSHROOM_BLOCK),
|
||||
entry(Items.STICK, Blocks.OAK_PLANKS),
|
||||
@@ -267,51 +289,51 @@ public class HopperCounter
|
||||
entry(Items.IRON_INGOT, Blocks.IRON_BLOCK),
|
||||
entry(Items.DIAMOND, Blocks.DIAMOND_BLOCK),
|
||||
entry(Items.NETHERITE_INGOT, Blocks.NETHERITE_BLOCK),
|
||||
entry(Items.SUNFLOWER, Blocks.YELLOW_WOOL),
|
||||
entry(Items.LILAC, Blocks.MAGENTA_WOOL),
|
||||
entry(Items.ROSE_BUSH, Blocks.RED_WOOL),
|
||||
entry(Items.PEONY, Blocks.PINK_WOOL),
|
||||
entry(Items.CARROT, Blocks.ORANGE_WOOL),
|
||||
entry(Items.APPLE,Blocks.RED_WOOL),
|
||||
entry(Items.SUNFLOWER, Blocks.WOOL.yellow()),
|
||||
entry(Items.LILAC, Blocks.WOOL.magenta()),
|
||||
entry(Items.ROSE_BUSH, Blocks.WOOL.red()),
|
||||
entry(Items.PEONY, Blocks.WOOL.pink()),
|
||||
entry(Items.CARROT, Blocks.WOOL.orange()),
|
||||
entry(Items.APPLE, Blocks.WOOL.red()),
|
||||
entry(Items.WHEAT, Blocks.HAY_BLOCK),
|
||||
entry(Items.PORKCHOP, Blocks.PINK_WOOL),
|
||||
entry(Items.RABBIT,Blocks.PINK_WOOL),
|
||||
entry(Items.CHICKEN,Blocks.WHITE_TERRACOTTA),
|
||||
entry(Items.PORKCHOP, Blocks.WOOL.pink()),
|
||||
entry(Items.RABBIT, Blocks.WOOL.pink()),
|
||||
entry(Items.CHICKEN, Blocks.DYED_TERRACOTTA.white()),
|
||||
entry(Items.BEEF, Blocks.NETHERRACK),
|
||||
entry(Items.ENCHANTED_GOLDEN_APPLE, Blocks.GOLD_BLOCK),
|
||||
entry(Items.COD,Blocks.WHITE_TERRACOTTA),
|
||||
entry(Items.COD, Blocks.DYED_TERRACOTTA.white()),
|
||||
entry(Items.SALMON, Blocks.ACACIA_PLANKS),
|
||||
entry(Items.ROTTEN_FLESH,Blocks.BROWN_WOOL),
|
||||
entry(Items.PUFFERFISH,Blocks.YELLOW_TERRACOTTA),
|
||||
entry(Items.TROPICAL_FISH,Blocks.ORANGE_WOOL),
|
||||
entry(Items.POTATO,Blocks.WHITE_TERRACOTTA),
|
||||
entry(Items.MUTTON, Blocks.RED_WOOL),
|
||||
entry(Items.ROTTEN_FLESH, Blocks.WOOL.brown()),
|
||||
entry(Items.PUFFERFISH, Blocks.DYED_TERRACOTTA.orange()),
|
||||
entry(Items.TROPICAL_FISH, Blocks.WOOL.orange()),
|
||||
entry(Items.POTATO, Blocks.DYED_TERRACOTTA.white()),
|
||||
entry(Items.MUTTON, Blocks.WOOL.red()),
|
||||
entry(Items.BEETROOT, Blocks.NETHERRACK),
|
||||
entry(Items.MELON_SLICE, Blocks.MELON),
|
||||
entry(Items.POISONOUS_POTATO, Blocks.SLIME_BLOCK),
|
||||
entry(Items.SPIDER_EYE, Blocks.NETHERRACK),
|
||||
entry(Items.GUNPOWDER,Blocks.GRAY_WOOL),
|
||||
entry(Items.TURTLE_SCUTE,Blocks.LIME_WOOL),
|
||||
entry(Items.GUNPOWDER, Blocks.WOOL.gray()),
|
||||
entry(Items.TURTLE_SCUTE, Blocks.WOOL.lime()),
|
||||
entry(Items.ARMADILLO_SCUTE, Blocks.ANCIENT_DEBRIS),
|
||||
entry(Items.FEATHER,Blocks.WHITE_WOOL),
|
||||
entry(Items.FLINT,Blocks.BLACK_WOOL),
|
||||
entry(Items.FEATHER, Blocks.WOOL.white()),
|
||||
entry(Items.FLINT, Blocks.WOOL.black()),
|
||||
entry(Items.LEATHER, Blocks.SPRUCE_PLANKS),
|
||||
entry(Items.GLOWSTONE_DUST, Blocks.GLOWSTONE),
|
||||
entry(Items.PAPER,Blocks.WHITE_WOOL),
|
||||
entry(Items.PAPER, Blocks.WOOL.white()),
|
||||
entry(Items.BRICK, Blocks.BRICKS),
|
||||
entry(Items.INK_SAC,Blocks.BLACK_WOOL),
|
||||
entry(Items.INK_SAC, Blocks.WOOL.black()),
|
||||
entry(Items.SNOWBALL, Blocks.SNOW_BLOCK),
|
||||
entry(Items.WATER_BUCKET, Blocks.WATER),
|
||||
entry(Items.LAVA_BUCKET, Blocks.LAVA),
|
||||
entry(Items.MILK_BUCKET,Blocks.WHITE_WOOL),
|
||||
entry(Items.MILK_BUCKET, Blocks.WOOL.white()),
|
||||
entry(Items.CLAY_BALL, Blocks.CLAY),
|
||||
entry(Items.COCOA_BEANS, Blocks.COCOA),
|
||||
entry(Items.BONE, Blocks.BONE_BLOCK),
|
||||
entry(Items.COD_BUCKET,Blocks.BROWN_TERRACOTTA),
|
||||
entry(Items.PUFFERFISH_BUCKET,Blocks.YELLOW_TERRACOTTA),
|
||||
entry(Items.SALMON_BUCKET,Blocks.PINK_TERRACOTTA),
|
||||
entry(Items.TROPICAL_FISH_BUCKET,Blocks.ORANGE_TERRACOTTA),
|
||||
entry(Items.SUGAR,Blocks.WHITE_WOOL),
|
||||
entry(Items.COD_BUCKET, Blocks.DYED_TERRACOTTA.brown()),
|
||||
entry(Items.PUFFERFISH_BUCKET, Blocks.DYED_TERRACOTTA.yellow()),
|
||||
entry(Items.SALMON_BUCKET, Blocks.DYED_TERRACOTTA.pink()),
|
||||
entry(Items.TROPICAL_FISH_BUCKET, Blocks.DYED_TERRACOTTA.orange()),
|
||||
entry(Items.SUGAR, Blocks.WOOL.white()),
|
||||
entry(Items.BLAZE_POWDER, Blocks.GOLD_BLOCK),
|
||||
entry(Items.ENDER_PEARL, Blocks.WARPED_PLANKS),
|
||||
entry(Items.NETHER_STAR, Blocks.DIAMOND_BLOCK),
|
||||
@@ -324,13 +346,13 @@ public class HopperCounter
|
||||
entry(Items.HEART_OF_THE_SEA, Blocks.CONDUIT),
|
||||
entry(Items.HONEYCOMB, Blocks.HONEYCOMB_BLOCK),
|
||||
entry(Items.NAME_TAG, Blocks.BONE_BLOCK),
|
||||
entry(Items.TOTEM_OF_UNDYING,Blocks.YELLOW_TERRACOTTA),
|
||||
entry(Items.TOTEM_OF_UNDYING, Blocks.DYED_TERRACOTTA.yellow()),
|
||||
entry(Items.TRIDENT, Blocks.PRISMARINE),
|
||||
entry(Items.GHAST_TEAR,Blocks.WHITE_WOOL),
|
||||
entry(Items.GHAST_TEAR, Blocks.WOOL.white()),
|
||||
entry(Items.PHANTOM_MEMBRANE, Blocks.BONE_BLOCK),
|
||||
entry(Items.EGG, Blocks.BONE_BLOCK),
|
||||
//entry(Items.,Blocks.),
|
||||
entry(Items.COPPER_INGOT,Blocks.COPPER_BLOCK),
|
||||
entry(Items.COPPER_INGOT, Blocks.COPPER_BLOCK.weathering().unaffected()),
|
||||
entry(Items.AMETHYST_SHARD, Blocks.AMETHYST_BLOCK));
|
||||
|
||||
/**
|
||||
@@ -338,24 +360,36 @@ public class HopperCounter
|
||||
*/
|
||||
public static TextColor fromItem(Item item, RegistryAccess registryAccess)
|
||||
{
|
||||
if (DEFAULTS.containsKey(item)) return TextColor.fromRgb(appropriateColor(DEFAULTS.get(item).defaultMapColor().col));
|
||||
if (item instanceof DyeItem dye) return TextColor.fromRgb(appropriateColor(dye.getDyeColor().getMapColor().col));
|
||||
if (DEFAULTS.containsKey(item))
|
||||
{
|
||||
return TextColor.fromRgb(appropriateColor(DEFAULTS.get(item).defaultMapColor().col));
|
||||
}
|
||||
if (item instanceof DyeItem dye)
|
||||
{
|
||||
return TextColor.fromRgb(appropriateColor(Optional.ofNullable(dye.getDefaultInstance().get(DataComponents.DYE)).orElse(DyeColor.WHITE).getMapColor().col));
|
||||
}
|
||||
Block block = null;
|
||||
final Registry<Item> itemRegistry = registryAccess.registryOrThrow(Registries.ITEM);
|
||||
final Registry<Block> blockRegistry = registryAccess.registryOrThrow(Registries.BLOCK);
|
||||
ResourceLocation id = itemRegistry.getKey(item);
|
||||
final Registry<Item> itemRegistry = registryAccess.lookupOrThrow(Registries.ITEM);
|
||||
final Registry<Block> blockRegistry = registryAccess.lookupOrThrow(Registries.BLOCK);
|
||||
Identifier id = itemRegistry.getKey(item);
|
||||
if (item instanceof BlockItem blockItem)
|
||||
{
|
||||
block = blockItem.getBlock();
|
||||
}
|
||||
else if (blockRegistry.getOptional(id).isPresent())
|
||||
{
|
||||
block = blockRegistry.get(id);
|
||||
block = blockRegistry.getValue(id);
|
||||
}
|
||||
if (block != null)
|
||||
{
|
||||
if (block instanceof AbstractBannerBlock) return TextColor.fromRgb(appropriateColor(((AbstractBannerBlock) block).getColor().getMapColor().col));
|
||||
if (block instanceof BeaconBeamBlock) return TextColor.fromRgb(appropriateColor( ((BeaconBeamBlock) block).getColor().getMapColor().col));
|
||||
if (block instanceof AbstractBannerBlock)
|
||||
{
|
||||
return TextColor.fromRgb(appropriateColor(((AbstractBannerBlock) block).getColor().getMapColor().col));
|
||||
}
|
||||
if (block instanceof BeaconBeamBlock)
|
||||
{
|
||||
return TextColor.fromRgb(appropriateColor(((BeaconBeamBlock) block).getColor().getMapColor().col));
|
||||
}
|
||||
return TextColor.fromRgb(appropriateColor(block.defaultMapColor().col));
|
||||
}
|
||||
return null;
|
||||
@@ -365,38 +399,45 @@ public class HopperCounter
|
||||
* Guesses the item's colour from the item itself. It first calls {@link HopperCounter#fromItem} to see if it has a
|
||||
* valid colour there, if not just makes a guess, and if that fails just returns null
|
||||
*/
|
||||
public static TextColor guessColor(Item item, RegistryAccess registryAccess)
|
||||
public static TextColor guessColor(Item item, Level level)
|
||||
{
|
||||
RegistryAccess registryAccess = level.registryAccess();
|
||||
TextColor direct = fromItem(item, registryAccess);
|
||||
if (direct != null) return direct;
|
||||
if (CarpetServer.minecraft_server == null) return WHITE;
|
||||
if (direct != null)
|
||||
{
|
||||
return direct;
|
||||
}
|
||||
if (CarpetServer.minecraft_server == null)
|
||||
{
|
||||
return WHITE;
|
||||
}
|
||||
|
||||
ResourceLocation id = registryAccess.registryOrThrow(Registries.ITEM).getKey(item);
|
||||
for (RecipeType<?> type: registryAccess.registryOrThrow(Registries.RECIPE_TYPE))
|
||||
Identifier id = registryAccess.lookupOrThrow(Registries.ITEM).getKey(item);
|
||||
if (id == null)
|
||||
{
|
||||
for (Recipe<?> r: ((RecipeManagerInterface) CarpetServer.minecraft_server.getRecipeManager()).getAllMatching(type, id, registryAccess))
|
||||
return null;
|
||||
}
|
||||
|
||||
for (Recipe<?> r : RecipeHelper.getRecipesForOutput(CarpetServer.minecraft_server.getRecipeManager(), id, level))
|
||||
{
|
||||
for (Ingredient ingredient: r.getIngredients())
|
||||
for (Ingredient ingredient : r.placementInfo().ingredients())
|
||||
{
|
||||
for (Collection<ItemStack> stacks : ((IngredientInterface) (Object) ingredient).getRecipeStacks())
|
||||
Optional<Holder<Item>> match = ingredient.items().filter(stack -> fromItem(stack.value(), registryAccess) != null).findFirst();
|
||||
if (match.isPresent())
|
||||
{
|
||||
for (ItemStack iStak : stacks)
|
||||
{
|
||||
TextColor cand = fromItem(iStak.getItem(), registryAccess);
|
||||
if (cand != null)
|
||||
return cand;
|
||||
}
|
||||
}
|
||||
return fromItem(match.get().value(), registryAccess);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hopper counter for the given color
|
||||
*/
|
||||
public static HopperCounter getCounter(DyeColor color) {
|
||||
public static HopperCounter getCounter(DyeColor color)
|
||||
{
|
||||
return COUNTERS.get(color);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,80 +1,39 @@
|
||||
package carpet.helpers;
|
||||
//Author: masa
|
||||
|
||||
import java.math.RoundingMode;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.entity.item.PrimedTnt;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
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.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.storage.loot.LootParams;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import carpet.logging.logHelpers.ExplosionLogHelper;
|
||||
import carpet.mixins.ExplosionAccessor;
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.utils.Messenger;
|
||||
import it.unimi.dsi.fastutil.objects.Object2DoubleOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import static carpet.script.CarpetEventServer.Event.EXPLOSION_OUTCOME;
|
||||
|
||||
public class OptimizedExplosion
|
||||
{
|
||||
private static List<Entity> entitylist;
|
||||
private static Vec3 vec3dmem;
|
||||
private static long tickmem;
|
||||
// For disabling the explosion particles and sound
|
||||
public static int explosionSound = 0;
|
||||
|
||||
// masa's optimizations
|
||||
private static Object2DoubleOpenHashMap<Pair<Vec3, AABB>> densityCache = new Object2DoubleOpenHashMap<>();
|
||||
private static MutablePair<Vec3, AABB> pairMutable = new MutablePair<>();
|
||||
private static Object2ObjectOpenHashMap<BlockPos, BlockState> stateCache = new Object2ObjectOpenHashMap<>();
|
||||
private static Object2ObjectOpenHashMap<BlockPos, FluidState> fluidCache = new Object2ObjectOpenHashMap<>();
|
||||
private static BlockPos.MutableBlockPos posMutable = new BlockPos.MutableBlockPos(0, 0, 0);
|
||||
private static ObjectOpenHashSet<BlockPos> affectedBlockPositionsSet = new ObjectOpenHashSet<>();
|
||||
private static boolean firstRay;
|
||||
private static boolean rayCalcDone;
|
||||
private static ArrayList<Float> chances = new ArrayList<>();
|
||||
private static BlockPos blastChanceLocation;
|
||||
|
||||
// Creating entity list for scarpet event
|
||||
private static List<Entity> entityList = new ArrayList<>();
|
||||
|
||||
public static void doExplosionA(Explosion e, ExplosionLogHelper eLogger) {
|
||||
public static List<BlockPos> doExplosionA(Explosion e, ExplosionLogHelper eLogger) {
|
||||
ExplosionAccessor eAccess = (ExplosionAccessor) e;
|
||||
|
||||
entityList.clear();
|
||||
boolean eventNeeded = EXPLOSION_OUTCOME.isNeeded() && !eAccess.getLevel().isClientSide();
|
||||
blastCalc(e);
|
||||
List<BlockPos> toBlow;
|
||||
|
||||
if (!CarpetSettings.explosionNoBlockDamage && eAccess.getDamageSource() != null) {
|
||||
rayCalcDone = false;
|
||||
@@ -88,291 +47,14 @@ public class OptimizedExplosion
|
||||
stateCache.clear();
|
||||
fluidCache.clear();
|
||||
|
||||
e.getToBlow().addAll(affectedBlockPositionsSet);
|
||||
toBlow = new ArrayList<>(affectedBlockPositionsSet);
|
||||
affectedBlockPositionsSet.clear();
|
||||
} else {
|
||||
toBlow = Collections.emptyList();
|
||||
}
|
||||
|
||||
float f3 = eAccess.getRadius() * 2.0F;
|
||||
int k1 = Mth.floor(eAccess.getX() - (double) f3 - 1.0D);
|
||||
int l1 = Mth.floor(eAccess.getX() + (double) f3 + 1.0D);
|
||||
int i2 = Mth.floor(eAccess.getY() - (double) f3 - 1.0D);
|
||||
int i1 = Mth.floor(eAccess.getY() + (double) f3 + 1.0D);
|
||||
int j2 = Mth.floor(eAccess.getZ() - (double) f3 - 1.0D);
|
||||
int j1 = Mth.floor(eAccess.getZ() + (double) f3 + 1.0D);
|
||||
Vec3 vec3d = new Vec3(eAccess.getX(), eAccess.getY(), eAccess.getZ());
|
||||
|
||||
if (vec3dmem == null || !vec3dmem.equals(vec3d) || tickmem != eAccess.getLevel().getGameTime()) {
|
||||
vec3dmem = vec3d;
|
||||
tickmem = eAccess.getLevel().getGameTime();
|
||||
entitylist = eAccess.getLevel().getEntities(null, new AABB(k1, i2, j2, l1, i1, j1));
|
||||
explosionSound = 0;
|
||||
}
|
||||
|
||||
explosionSound++;
|
||||
|
||||
Entity explodingEntity = eAccess.getSource();
|
||||
for (int k2 = 0; k2 < entitylist.size(); ++k2) {
|
||||
Entity entity = entitylist.get(k2);
|
||||
|
||||
|
||||
if (entity == explodingEntity) {
|
||||
// entitylist.remove(k2);
|
||||
removeFast(entitylist, k2);
|
||||
k2--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entity instanceof PrimedTnt && explodingEntity != null &&
|
||||
entity.getX() == explodingEntity.getX() &&
|
||||
entity.getY() == explodingEntity.getY() &&
|
||||
entity.getZ() == explodingEntity.getZ()) {
|
||||
if (eLogger != null) {
|
||||
eLogger.onEntityImpacted(entity, new Vec3(0,-0.9923437498509884d, 0));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entity.ignoreExplosion(e)) {
|
||||
double d12 = Math.sqrt(entity.distanceToSqr(eAccess.getX(), eAccess.getY(), eAccess.getZ())) / (double) f3;
|
||||
|
||||
if (d12 <= 1.0D) {
|
||||
double d5 = entity.getX() - eAccess.getX();
|
||||
// Change in 1.16 snapshots to fix a bug with TNT jumping
|
||||
double d7 = (entity instanceof PrimedTnt ? entity.getY() : entity.getEyeY()) - eAccess.getY();
|
||||
double d9 = entity.getZ() - eAccess.getZ();
|
||||
double d13 = (double) Math.sqrt(d5 * d5 + d7 * d7 + d9 * d9);
|
||||
|
||||
if (d13 != 0.0D) {
|
||||
d5 = d5 / d13;
|
||||
d7 = d7 / d13;
|
||||
d9 = d9 / d13;
|
||||
double density;
|
||||
|
||||
pairMutable.setLeft(vec3d);
|
||||
pairMutable.setRight(entity.getBoundingBox());
|
||||
density = densityCache.getOrDefault(pairMutable, Double.MAX_VALUE);
|
||||
|
||||
if (density == Double.MAX_VALUE)
|
||||
{
|
||||
Pair<Vec3, AABB> pair = Pair.of(vec3d, entity.getBoundingBox());
|
||||
density = Explosion.getSeenPercent(vec3d, entity);
|
||||
densityCache.put(pair, density);
|
||||
}
|
||||
|
||||
// If it is needed, it saves the entity
|
||||
if (eventNeeded) {
|
||||
entityList.add(entity);
|
||||
}
|
||||
|
||||
double d10 = (1.0D - d12) * density;
|
||||
if (eAccess.getDamageSource() != null)
|
||||
{
|
||||
entity.hurt(eAccess.getDamageSource(),
|
||||
(float) ((int) ((d10 * d10 + d10) / 2.0D * 7.0D * (double) f3 + 1.0D)));
|
||||
}
|
||||
double d11 = d10;
|
||||
|
||||
if (entity instanceof LivingEntity lev) {
|
||||
d11 = d10 * Mth.clamp(1.0 - lev.getAttributeValue(Attributes.EXPLOSION_KNOCKBACK_RESISTANCE), 0.0, 1.0);
|
||||
}
|
||||
|
||||
if (eLogger != null) {
|
||||
eLogger.onEntityImpacted(entity, new Vec3(d5 * d11, d7 * d11, d9 * d11));
|
||||
}
|
||||
|
||||
entity.setDeltaMovement(entity.getDeltaMovement().add(d5 * d11, d7 * d11, d9 * d11));
|
||||
|
||||
if (entity instanceof Player player) {
|
||||
|
||||
if (!player.isSpectator()
|
||||
&& (!player.isCreative() || !player.getAbilities().flying)) { //getAbilities
|
||||
e.getHitPlayers().put(player, new Vec3(d5 * d10, d7 * d10, d9 * d10));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
densityCache.clear();
|
||||
}
|
||||
|
||||
public static void doExplosionB(Explosion e, boolean spawnParticles)
|
||||
{
|
||||
ExplosionAccessor eAccess = (ExplosionAccessor) e;
|
||||
Level world = eAccess.getLevel();
|
||||
double posX = eAccess.getX();
|
||||
double posY = eAccess.getY();
|
||||
double posZ = eAccess.getZ();
|
||||
|
||||
// If it is needed, calls scarpet event
|
||||
if (EXPLOSION_OUTCOME.isNeeded() && !world.isClientSide()) {
|
||||
EXPLOSION_OUTCOME.onExplosion((ServerLevel) world, eAccess.getSource(), e::getIndirectSourceEntity, eAccess.getX(), eAccess.getY(), eAccess.getZ(), eAccess.getRadius(), eAccess.isFire(), e.getToBlow(), entityList, eAccess.getBlockInteraction());
|
||||
}
|
||||
|
||||
boolean damagesTerrain = eAccess.getBlockInteraction() != Explosion.BlockInteraction.KEEP;
|
||||
|
||||
// explosionSound incremented till disabling the explosion particles and sound
|
||||
if (explosionSound < 100 || explosionSound % 100 == 0)
|
||||
{
|
||||
world.playSound(null, posX, posY, posZ, SoundEvents.GENERIC_EXPLODE.value(), SoundSource.BLOCKS, 4.0F,
|
||||
(1.0F + (world.random.nextFloat() - world.random.nextFloat()) * 0.2F) * 0.7F);
|
||||
|
||||
if (spawnParticles)
|
||||
{
|
||||
if (eAccess.getRadius() >= 2.0F && damagesTerrain)
|
||||
{
|
||||
world.addParticle(ParticleTypes.EXPLOSION_EMITTER, posX, posY, posZ, 1.0D, 0.0D, 0.0D);
|
||||
}
|
||||
else
|
||||
{
|
||||
world.addParticle(ParticleTypes.EXPLOSION, posX, posY, posZ, 1.0D, 0.0D, 0.0D);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (damagesTerrain)
|
||||
{
|
||||
ObjectArrayList<Pair<ItemStack, BlockPos>> objectArrayList = new ObjectArrayList<>();
|
||||
Util.shuffle((ObjectArrayList<BlockPos>) e.getToBlow(), world.random);
|
||||
|
||||
boolean dropFromExplosions = CarpetSettings.xpFromExplosions || e.getIndirectSourceEntity() instanceof Player;
|
||||
|
||||
for (BlockPos blockpos : e.getToBlow())
|
||||
{
|
||||
BlockState state = world.getBlockState(blockpos);
|
||||
Block block = state.getBlock();
|
||||
|
||||
if (!state.isAir())
|
||||
{
|
||||
if (block.dropFromExplosion(e) && world instanceof ServerLevel serverLevel)
|
||||
{
|
||||
BlockEntity blockEntity = state.hasBlockEntity() ? world.getBlockEntity(blockpos) : null; //hasBlockEntity()
|
||||
|
||||
LootParams.Builder lootBuilder = (new LootParams.Builder((ServerLevel)eAccess.getLevel()))
|
||||
.withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockpos))
|
||||
.withParameter(LootContextParams.TOOL, ItemStack.EMPTY)
|
||||
.withOptionalParameter(LootContextParams.BLOCK_ENTITY, blockEntity)
|
||||
.withOptionalParameter(LootContextParams.THIS_ENTITY, eAccess.getSource());
|
||||
|
||||
if (eAccess.getBlockInteraction() == Explosion.BlockInteraction.DESTROY_WITH_DECAY)
|
||||
lootBuilder.withParameter(LootContextParams.EXPLOSION_RADIUS, eAccess.getRadius());
|
||||
|
||||
state.spawnAfterBreak(serverLevel, blockpos, ItemStack.EMPTY, dropFromExplosions);
|
||||
|
||||
state.getDrops(lootBuilder).forEach((itemStackx) -> {
|
||||
method_24023(objectArrayList, itemStackx, blockpos.immutable());
|
||||
});
|
||||
}
|
||||
|
||||
world.setBlock(blockpos, Blocks.AIR.defaultBlockState(), 3);
|
||||
block.wasExploded(world, blockpos, e);
|
||||
}
|
||||
}
|
||||
objectArrayList.forEach(p -> Block.popResource(world, p.getRight(), p.getLeft()));
|
||||
|
||||
}
|
||||
|
||||
if (eAccess.isFire())
|
||||
{
|
||||
for (BlockPos blockpos1 : e.getToBlow())
|
||||
{
|
||||
// Use the same Chunk reference because the positions are in the same xz-column
|
||||
ChunkAccess chunk = world.getChunk(blockpos1.getX() >> 4, blockpos1.getZ() >> 4);
|
||||
|
||||
BlockPos down = blockpos1.below(1);
|
||||
if (eAccess.getRandom().nextInt(3) == 0 &&
|
||||
chunk.getBlockState(blockpos1).isAir() &&
|
||||
chunk.getBlockState(down).isSolidRender(world, down)
|
||||
)
|
||||
{
|
||||
world.setBlockAndUpdate(blockpos1, Blocks.FIRE.defaultBlockState());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copied from Explosion, need to move the code to the explosion code anyways and use shadows for
|
||||
// simplicity, its not jarmodding anyways
|
||||
private static void method_24023(ObjectArrayList<Pair<ItemStack, BlockPos>> objectArrayList, ItemStack itemStack, BlockPos blockPos) {
|
||||
int i = objectArrayList.size();
|
||||
|
||||
for(int j = 0; j < i; ++j) {
|
||||
Pair<ItemStack, BlockPos> pair = objectArrayList.get(j);
|
||||
ItemStack itemStack2 = pair.getLeft();
|
||||
if (ItemEntity.areMergable(itemStack2, itemStack)) {
|
||||
ItemStack itemStack3 = ItemEntity.merge(itemStack2, itemStack, 16);
|
||||
objectArrayList.set(j, Pair.of(itemStack3, pair.getRight()));
|
||||
if (itemStack.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
objectArrayList.add(Pair.of(itemStack, blockPos));
|
||||
}
|
||||
|
||||
private static void removeFast(List<Entity> lst, int index) {
|
||||
if (index < lst.size() - 1)
|
||||
lst.set(index, lst.get(lst.size() - 1));
|
||||
lst.remove(lst.size() - 1);
|
||||
}
|
||||
|
||||
private static void rayCalcs(Explosion e) {
|
||||
ExplosionAccessor eAccess = (ExplosionAccessor) e;
|
||||
boolean first = true;
|
||||
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
for (int k = 0; k < 16; ++k) {
|
||||
for (int l = 0; l < 16; ++l) {
|
||||
if (j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15) {
|
||||
double d0 = (double) ((float) j / 15.0F * 2.0F - 1.0F);
|
||||
double d1 = (double) ((float) k / 15.0F * 2.0F - 1.0F);
|
||||
double d2 = (double) ((float) l / 15.0F * 2.0F - 1.0F);
|
||||
double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
|
||||
d0 = d0 / d3;
|
||||
d1 = d1 / d3;
|
||||
d2 = d2 / d3;
|
||||
float rand = eAccess.getLevel().random.nextFloat();
|
||||
if (CarpetSettings.tntRandomRange >= 0) {
|
||||
rand = (float) CarpetSettings.tntRandomRange;
|
||||
}
|
||||
float f = eAccess.getRadius() * (0.7F + rand * 0.6F);
|
||||
double d4 = eAccess.getX();
|
||||
double d6 = eAccess.getY();
|
||||
double d8 = eAccess.getZ();
|
||||
|
||||
for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
|
||||
BlockPos blockpos = BlockPos.containing(d4, d6, d8);
|
||||
BlockState state = eAccess.getLevel().getBlockState(blockpos);
|
||||
FluidState fluidState = eAccess.getLevel().getFluidState(blockpos);
|
||||
|
||||
if (!state.isAir()) {
|
||||
float f2 = Math.max(state.getBlock().getExplosionResistance(), fluidState.getExplosionResistance());
|
||||
if (eAccess.getSource() != null)
|
||||
f2 = eAccess.getSource().getBlockExplosionResistance(e, eAccess.getLevel(), blockpos, state, fluidState, f2);
|
||||
f -= (f2 + 0.3F) * 0.3F;
|
||||
}
|
||||
|
||||
if (f > 0.0F && (eAccess.getSource() == null ||
|
||||
eAccess.getSource().shouldBlockExplode(e, eAccess.getLevel(), blockpos, state, f)))
|
||||
{
|
||||
affectedBlockPositionsSet.add(blockpos);
|
||||
}
|
||||
else if (first) {
|
||||
return;
|
||||
}
|
||||
|
||||
first = false;
|
||||
|
||||
d4 += d0 * 0.30000001192092896D;
|
||||
d6 += d1 * 0.30000001192092896D;
|
||||
d8 += d2 * 0.30000001192092896D;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return toBlow;
|
||||
}
|
||||
|
||||
private static void getAffectedPositionsOnPlaneX(Explosion e, int x, int yStart, int yEnd, int zStart, int zEnd)
|
||||
@@ -451,12 +133,13 @@ public class OptimizedExplosion
|
||||
double xInc = (xRel / len) * 0.3;
|
||||
double yInc = (yRel / len) * 0.3;
|
||||
double zInc = (zRel / len) * 0.3;
|
||||
float rand = eAccess.getLevel().random.nextFloat();
|
||||
float rand = eAccess.getLevel().getRandom().nextFloat();
|
||||
float sizeRand = (CarpetSettings.tntRandomRange >= 0 ? (float) CarpetSettings.tntRandomRange : rand);
|
||||
float size = eAccess.getRadius() * (0.7F + sizeRand * 0.6F);
|
||||
double posX = eAccess.getX();
|
||||
double posY = eAccess.getY();
|
||||
double posZ = eAccess.getZ();
|
||||
Vec3 vec3 = eAccess.getCenter();
|
||||
double posX = vec3.x;
|
||||
double posY = vec3.y;
|
||||
double posZ = vec3.z;
|
||||
|
||||
for (float f1 = 0.3F; size > 0.0F; size -= 0.22500001F)
|
||||
{
|
||||
@@ -508,112 +191,4 @@ public class OptimizedExplosion
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void setBlastChanceLocation(BlockPos p){
|
||||
blastChanceLocation = p;
|
||||
}
|
||||
|
||||
private static void blastCalc(Explosion e){
|
||||
ExplosionAccessor eAccess = (ExplosionAccessor) e;
|
||||
if(blastChanceLocation == null || blastChanceLocation.distToLowCornerSqr(eAccess.getX(), eAccess.getY(), eAccess.getZ()) > 200) return;
|
||||
chances.clear();
|
||||
for (int j = 0; j < 16; ++j) {
|
||||
for (int k = 0; k < 16; ++k) {
|
||||
for (int l = 0; l < 16; ++l) {
|
||||
if (j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15) {
|
||||
double d0 = (double) ((float) j / 15.0F * 2.0F - 1.0F);
|
||||
double d1 = (double) ((float) k / 15.0F * 2.0F - 1.0F);
|
||||
double d2 = (double) ((float) l / 15.0F * 2.0F - 1.0F);
|
||||
double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
|
||||
d0 = d0 / d3;
|
||||
d1 = d1 / d3;
|
||||
d2 = d2 / d3;
|
||||
float f = eAccess.getRadius() * (0.7F + 0.6F);
|
||||
double d4 = eAccess.getX();
|
||||
double d6 = eAccess.getY();
|
||||
double d8 = eAccess.getZ();
|
||||
boolean found = false;
|
||||
|
||||
for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
|
||||
BlockPos blockpos = BlockPos.containing(d4, d6, d8);
|
||||
BlockState state = eAccess.getLevel().getBlockState(blockpos);
|
||||
FluidState fluidState = eAccess.getLevel().getFluidState(blockpos);
|
||||
|
||||
if (!state.isAir()) {
|
||||
float f2 = Math.max(state.getBlock().getExplosionResistance(), fluidState.getExplosionResistance());
|
||||
if (eAccess.getSource() != null)
|
||||
f2 = eAccess.getSource().getBlockExplosionResistance(e, eAccess.getLevel(), blockpos, state, fluidState, f2);
|
||||
f -= (f2 + 0.3F) * 0.3F;
|
||||
}
|
||||
|
||||
if (f > 0.0F && (eAccess.getSource() == null ||
|
||||
eAccess.getSource().shouldBlockExplode(e, eAccess.getLevel(), blockpos, state, f))) {
|
||||
if(!found && blockpos.equals(blastChanceLocation)){
|
||||
chances.add(f);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
d4 += d0 * 0.30000001192092896D;
|
||||
d6 += d1 * 0.30000001192092896D;
|
||||
d8 += d2 * 0.30000001192092896D;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//showTNTblastChance(e);
|
||||
}
|
||||
|
||||
private static void showTNTblastChance(Explosion e){
|
||||
ExplosionAccessor eAccess = (ExplosionAccessor) e;
|
||||
double randMax = 0.6F * eAccess.getRadius();
|
||||
double total = 0;
|
||||
boolean fullyBlownUp = false;
|
||||
boolean first = true;
|
||||
int rays = 0;
|
||||
for(float f3 : chances){
|
||||
rays++;
|
||||
double calc = f3 - randMax;
|
||||
if(calc > 0) fullyBlownUp = true;
|
||||
double chancePerRay = (Math.abs(calc) / randMax);
|
||||
if(!fullyBlownUp){
|
||||
if(first){
|
||||
first = false;
|
||||
total = chancePerRay;
|
||||
}else {
|
||||
total = total * chancePerRay;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(fullyBlownUp) total = 0;
|
||||
double chance = 1 - total;
|
||||
NumberFormat nf = NumberFormat.getNumberInstance();
|
||||
nf.setRoundingMode (RoundingMode.DOWN);
|
||||
nf.setMaximumFractionDigits(2);
|
||||
for(Player player : eAccess.getLevel().players()){
|
||||
Messenger.m(player,"w Pop: ",
|
||||
"c " + nf.format(chance) + " ",
|
||||
"^w Chance for the block to be destroyed by the blast: " + chance,
|
||||
"?" + chance,
|
||||
"w Remain: ",
|
||||
String.format("c %.2f ", total),
|
||||
"^w Chance the block survives the blast: " + total,
|
||||
"?" + total,
|
||||
"w Rays: ",
|
||||
String.format("c %d ", rays),
|
||||
"^w TNT blast rays going through the block",
|
||||
"?" + rays,
|
||||
"w Size: ",
|
||||
String.format("c %.1f ", eAccess.getRadius()),
|
||||
"^w TNT blast size",
|
||||
"?" + eAccess.getRadius(),
|
||||
"w @: ",
|
||||
String.format("c [%.1f %.1f %.1f] ", eAccess.getX(), eAccess.getY(), eAccess.getZ()),
|
||||
"^w TNT blast location X:" + eAccess.getX() + " Y:" + eAccess.getY() + " Z:" + eAccess.getZ(),
|
||||
"?" + eAccess.getX() + " " + eAccess.getY() + " " + eAccess.getZ()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,18 @@
|
||||
package carpet.helpers;
|
||||
|
||||
import carpet.script.utils.ParticleParser;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.core.particles.ParticleType;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class ParticleDisplay
|
||||
{
|
||||
public static void drawParticleLine(ServerPlayer player, Vec3 from, Vec3 to, String main, String accent, int count, double spread)
|
||||
public static void drawParticleLine(ServerPlayer player, Vec3 from, Vec3 to, ParticleOptions mainParticle, ParticleOptions accentParticle, int count, double spread)
|
||||
{
|
||||
ParticleOptions accentParticle = ParticleParser.getEffect(accent, player.server.registryAccess());
|
||||
ParticleOptions mainParticle = ParticleParser.getEffect(main, player.server.registryAccess());
|
||||
|
||||
if (accentParticle != null) player.serverLevel().sendParticles(
|
||||
if (accentParticle != null) player.level().sendParticles(
|
||||
player,
|
||||
accentParticle,
|
||||
true,
|
||||
true, true,
|
||||
to.x, to.y, to.z, count,
|
||||
spread, spread, spread, 0.0);
|
||||
|
||||
@@ -28,12 +22,12 @@ public class ParticleDisplay
|
||||
Vec3 incvec = to.subtract(from).normalize();// multiply(50/sqrt(lineLengthSq));
|
||||
for (Vec3 delta = new Vec3(0.0,0.0,0.0);
|
||||
delta.lengthSqr() < lineLengthSq;
|
||||
delta = delta.add(incvec.scale(player.level().random.nextFloat())))
|
||||
delta = delta.add(incvec.scale(player.level().getRandom().nextFloat())))
|
||||
{
|
||||
player.serverLevel().sendParticles(
|
||||
player.level().sendParticles(
|
||||
player,
|
||||
mainParticle,
|
||||
true,
|
||||
true, true,
|
||||
delta.x+from.x, delta.y+from.y, delta.z+from.z, 1,
|
||||
0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
@@ -676,7 +676,7 @@ public class RedstoneWireTurbo
|
||||
// call BlockStateBase#neighborChanged directly. This change mostly
|
||||
// restores old behavior, at the cost of bypassing the
|
||||
// max-chained-neighbor-updates server property.
|
||||
worldIn.getBlockState(upd.self).handleNeighborChanged(worldIn, upd.self, wire, upd.parent, false);
|
||||
worldIn.getBlockState(upd.self).handleNeighborChanged(worldIn, upd.self, wire, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -951,7 +951,7 @@ public class RedstoneWireTurbo
|
||||
BlockPos neighborPos = pos.relative(dir);
|
||||
BlockState neighborState = level.getBlockState(neighborPos);
|
||||
|
||||
BlockState newState = neighborState.updateShape(dir.getOpposite(), state, level, neighborPos, pos);
|
||||
BlockState newState = neighborState.updateShape(level, level, neighborPos, dir.getOpposite(), pos, state, level.getRandom());
|
||||
Block.updateOrDestroy(neighborState, newState, level, neighborPos, Block.UPDATE_CLIENTS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
|
||||
@@ -80,7 +80,7 @@ public class ExplosionLogHelper
|
||||
messages.add(c((k.pos.equals(pos))?"r - TNT":"w - ",
|
||||
Messenger.dblt((k.pos.equals(pos))?"r":"y", k.pos.x, k.pos.y, k.pos.z), "w dV",
|
||||
Messenger.dblt("d", k.accel.x, k.accel.y, k.accel.z),
|
||||
"w "+ regs.registryOrThrow(Registries.ENTITY_TYPE).getKey(k.type).getPath(), (v>1)?"l ("+v+")":""
|
||||
"w "+ regs.lookupOrThrow(Registries.ENTITY_TYPE).getKey(k.type).getPath(), (v>1)?"l ("+v+")":""
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@ package carpet.logging.logHelpers;
|
||||
|
||||
import carpet.helpers.ParticleDisplay;
|
||||
import carpet.logging.LoggerRegistry;
|
||||
import net.minecraft.core.particles.DustParticleOptions;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
@@ -31,8 +34,8 @@ public class PathfindingVisualizer
|
||||
if (minDuration < 1)
|
||||
minDuration = 1;
|
||||
|
||||
String accent = successful ? "happy_villager" : "angry_villager";
|
||||
String color = (miliseconds/minDuration < 2)? "dust 1 1 0 1" : ((miliseconds/minDuration < 4)?"dust 1 0.5 0 1":"dust 1 0 0 1");
|
||||
ParticleOptions accent = successful ? ParticleTypes.HAPPY_VILLAGER : ParticleTypes.ANGRY_VILLAGER;
|
||||
ParticleOptions color = (miliseconds/minDuration < 2)? new DustParticleOptions(0xffffff00, 1) : ((miliseconds/minDuration < 4)?new DustParticleOptions(0xFFFF7700, 1): new DustParticleOptions(0xFFFF0000, 1));
|
||||
ParticleDisplay.drawParticleLine((ServerPlayer) player, entity.position(), target, color, accent, 5, 0.5);
|
||||
return null;
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@ import carpet.logging.LoggerRegistry;
|
||||
import carpet.logging.logHelpers.TrajectoryLogHelper;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.projectile.AbstractArrow;
|
||||
import net.minecraft.world.entity.projectile.arrow.AbstractArrow;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
@@ -23,7 +23,7 @@ public abstract class AbstractArrowMixin extends Entity
|
||||
@Inject(method = "<init>(Lnet/minecraft/world/entity/EntityType;DDDLnet/minecraft/world/level/Level;Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemStack;)V", at = @At("RETURN"))
|
||||
private void addLogger(final EntityType entityType, final double x, final double y, final double z, final Level level, final ItemStack itemStack, final ItemStack weapon, final CallbackInfo ci)
|
||||
{
|
||||
if (LoggerRegistry.__projectiles && !level.isClientSide)
|
||||
if (LoggerRegistry.__projectiles && !level.isClientSide())
|
||||
logHelper = new TrajectoryLogHelper("projectiles");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.cauldron.CauldronInteraction;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.ItemInteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.AbstractCauldronBlock;
|
||||
import net.minecraft.world.level.block.ShulkerBoxBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(AbstractCauldronBlock.class)
|
||||
public class AbstractCauldronBlock_stackableSBoxesMixin
|
||||
{
|
||||
@Redirect(method = "useItemOn", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/core/cauldron/CauldronInteraction;interact(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/entity/player/Player;Lnet/minecraft/world/InteractionHand;Lnet/minecraft/world/item/ItemStack;)Lnet/minecraft/world/ItemInteractionResult;"
|
||||
))
|
||||
private ItemInteractionResult wrapInteractor(final CauldronInteraction cauldronBehavior, final BlockState blockState, final Level world, final BlockPos blockPos, final Player playerEntity, final InteractionHand hand, final ItemStack itemStack)
|
||||
{
|
||||
int count = -1;
|
||||
if (CarpetSettings.shulkerBoxStackSize > 1 && itemStack.getItem() instanceof BlockItem && ((BlockItem)itemStack.getItem()).getBlock() instanceof ShulkerBoxBlock)
|
||||
count = itemStack.getCount();
|
||||
ItemInteractionResult result = cauldronBehavior.interact(blockState, world, blockPos, playerEntity, hand, itemStack);
|
||||
if (count > 0 && result.consumesAction())
|
||||
{
|
||||
ItemStack current = playerEntity.getItemInHand(hand);
|
||||
if (current.getItem() instanceof BlockItem && ((BlockItem)itemStack.getItem()).getBlock() instanceof ShulkerBoxBlock)
|
||||
current.setCount(count);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ClickType;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
@Mixin(AbstractContainerMenu.class)
|
||||
public abstract class AbstractContainerMenu_ctrlQCraftingMixin
|
||||
{
|
||||
|
||||
@Shadow public abstract void clicked(int int_1, int int_2, ClickType slotActionType_1, Player playerEntity_1);
|
||||
|
||||
@Shadow public abstract void broadcastChanges();
|
||||
|
||||
@Shadow @Final public NonNullList<Slot> slots;
|
||||
|
||||
@Shadow protected abstract void resetQuickCraft();
|
||||
|
||||
@Shadow public abstract ItemStack getCarried();
|
||||
|
||||
@Inject( method = "doClick", at = @At(value = "HEAD"), cancellable = true)
|
||||
private void onThrowClick(int slotId, int clickData, ClickType actionType, Player playerEntity, CallbackInfo ci)
|
||||
{
|
||||
if (actionType == ClickType.THROW && CarpetSettings.ctrlQCraftingFix && this.getCarried().isEmpty() && slotId >= 0)
|
||||
{
|
||||
Slot slot_4 = slots.get(slotId);
|
||||
if (/*slot_4 != null && */slot_4.hasItem() && slot_4.mayPickup(playerEntity))
|
||||
{
|
||||
if(slotId == 0 && clickData == 1)
|
||||
{
|
||||
Item craftedItem = slot_4.getItem().getItem();
|
||||
while(slot_4.hasItem() && slot_4.getItem().getItem() == craftedItem)
|
||||
{
|
||||
this.clicked(slotId, 0, ClickType.THROW, playerEntity);
|
||||
}
|
||||
this.broadcastChanges();
|
||||
this.resetQuickCraft();
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ import java.util.List;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.inventory.ClickType;
|
||||
import net.minecraft.world.inventory.ContainerInput;
|
||||
import net.minecraft.world.inventory.ContainerListener;
|
||||
import net.minecraft.world.inventory.DataSlot;
|
||||
|
||||
@@ -26,7 +26,7 @@ public abstract class AbstractContainerMenu_scarpetMixin implements AbstractCont
|
||||
@Shadow @Final private List<DataSlot> dataSlots;
|
||||
|
||||
@Inject(method = "doClick", at = @At("HEAD"), cancellable = true)
|
||||
private void callSlotClickListener(int slotIndex, int button, ClickType actionType, Player player, CallbackInfo ci) {
|
||||
private void callSlotClickListener(int slotIndex, int button, ContainerInput actionType, Player player, CallbackInfo ci) {
|
||||
if(!(player instanceof ServerPlayer serverPlayerEntity)) return;
|
||||
for(ContainerListener screenHandlerListener : this.containerListeners) {
|
||||
if(screenHandlerListener instanceof ScreenValue.ScarpetScreenHandlerListener scarpetScreenHandlerListener) {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.AbstractContainerMenuInterface;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.AbstractCraftingMenu;
|
||||
import net.minecraft.world.inventory.RecipeBookMenu;
|
||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
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(AbstractCraftingMenu.class)
|
||||
public class AbstractCraftingMenu_scarpetMixin
|
||||
{
|
||||
@Inject(method = "handlePlacement",at = @At("HEAD"), cancellable = true)
|
||||
private void selectRecipeCallback(boolean craftAll, boolean b, RecipeHolder<?> recipe, ServerLevel serverLevel, Inventory player, CallbackInfoReturnable<RecipeBookMenu.PostPlaceAction> cir) {
|
||||
if(((AbstractContainerMenuInterface) this).callSelectRecipeListener((ServerPlayer) player.player ,recipe,craftAll))
|
||||
cir.setReturnValue(RecipeBookMenu.PostPlaceAction.NOTHING);
|
||||
}
|
||||
}
|
||||
+10
-6
@@ -1,19 +1,23 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.AbstractContainerMenuInterface;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.player.Inventory;
|
||||
import net.minecraft.world.inventory.AbstractFurnaceMenu;
|
||||
import net.minecraft.world.inventory.RecipeBookMenu;
|
||||
import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
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;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(RecipeBookMenu.class)
|
||||
public class RecipeBookMenu_scarpetMixin {
|
||||
@Mixin(AbstractFurnaceMenu.class)
|
||||
public class AbstractFurnaceMenu_scarpetMixin
|
||||
{
|
||||
@Inject(method = "handlePlacement",at = @At("HEAD"), cancellable = true)
|
||||
private void selectRecipeCallback(boolean craftAll, RecipeHolder<?> recipe, ServerPlayer player, CallbackInfo ci) {
|
||||
if(((AbstractContainerMenuInterface) this).callSelectRecipeListener(player,recipe,craftAll))
|
||||
ci.cancel();
|
||||
private void selectRecipeCallback(boolean craftAll, boolean b, RecipeHolder<?> recipe, ServerLevel level, Inventory player, CallbackInfoReturnable<RecipeBookMenu.PostPlaceAction> cir) {
|
||||
if(((AbstractContainerMenuInterface) this).callSelectRecipeListener((ServerPlayer) player.player ,recipe,craftAll))
|
||||
cir.setReturnValue(RecipeBookMenu.PostPlaceAction.NOTHING);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import carpet.fakes.EntityInterface;
|
||||
import carpet.script.EntityEventsGroup;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.vehicle.AbstractMinecart;
|
||||
import net.minecraft.world.entity.vehicle.minecart.AbstractMinecart;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
@@ -29,12 +29,12 @@ public abstract class ArmorStand_scarpetMarkerMixin extends LivingEntity
|
||||
@Inject(method = "readAdditionalSaveData", at = @At("HEAD"))
|
||||
private void checkScarpetMarkerUnloaded(CallbackInfo ci)
|
||||
{
|
||||
if (!level().isClientSide)
|
||||
if (!level().isClientSide())
|
||||
{
|
||||
if (getTags().contains(Auxiliary.MARKER_STRING))
|
||||
if (entityTags().contains(Auxiliary.MARKER_STRING))
|
||||
{
|
||||
String prefix = Auxiliary.MARKER_STRING+"_";
|
||||
Optional<String> owner = getTags().stream().filter(s -> s.startsWith(prefix)).findFirst();
|
||||
Optional<String> owner = entityTags().stream().filter(s -> s.startsWith(prefix)).findFirst();
|
||||
if (owner.isPresent())
|
||||
{
|
||||
String hostName = StringUtils.removeStart(owner.get(),prefix);
|
||||
|
||||
@@ -2,8 +2,9 @@ package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.fakes.LevelInterface;
|
||||
import net.minecraft.world.level.redstone.NeighborUpdater;
|
||||
import net.minecraft.world.level.redstone.CollectingNeighborUpdater;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.redstone.Orientation;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
@@ -29,13 +30,13 @@ public class BarrierBlock_updateSuppressionBlockMixin extends Block {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level level, BlockPos pos, Block block, BlockPos fromPos, boolean notify) {
|
||||
public void neighborChanged(BlockState state, Level level, BlockPos pos, Block block, Orientation fromPos, boolean notify) {
|
||||
if (CarpetSettings.updateSuppressionBlock != -1) {
|
||||
if (fromPos.equals(pos.above())) {
|
||||
BlockState stateAbove = level.getBlockState(fromPos);
|
||||
if (true/*fromPos.equals(pos.above())*/) { // todo neighbour updates don't have source
|
||||
BlockState stateAbove = level.getBlockState(pos.above());
|
||||
if (stateAbove.is(Blocks.ACTIVATOR_RAIL) && !stateAbove.getValue(PoweredRailBlock.POWERED)) {
|
||||
level.scheduleTick(pos, this, 1);
|
||||
NeighborUpdater updater = ((LevelInterface)level).getNeighborUpdater();
|
||||
CollectingNeighborUpdater updater = ((LevelInterface)level).getNeighborUpdater();
|
||||
if (updater instanceof CollectingNeighborUpdaterAccessor cnua)
|
||||
cnua.setCount(cnua.getMaxChainedNeighborUpdates()-CarpetSettings.updateSuppressionBlock);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.BrainInterface;
|
||||
import net.minecraft.world.entity.ai.Brain;
|
||||
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
|
||||
import net.minecraft.world.entity.ai.memory.MemorySlot;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(Brain.class)
|
||||
public class Brain_scarpetMixin implements BrainInterface {
|
||||
@Shadow @Final
|
||||
private Map<MemoryModuleType<?>, MemorySlot<?>> memories;
|
||||
|
||||
@Override
|
||||
public Map<MemoryModuleType<?>, MemorySlot<?>> getMemoriesCM() {
|
||||
return memories;
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,10 @@ package carpet.mixins;
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.PickaxeItem;
|
||||
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.world.item.enchantment.Enchantments;
|
||||
import net.minecraft.world.level.Level;
|
||||
@@ -14,12 +14,8 @@ import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.BuddingAmethystBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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(BuddingAmethystBlock.class)
|
||||
public class BuddingAmethystBlock_movableAmethystMixin extends Block {
|
||||
@@ -33,8 +29,8 @@ public class BuddingAmethystBlock_movableAmethystMixin extends Block {
|
||||
// doing it here rather than though loottables since loottables are loaded on reload
|
||||
// drawback - not controlled via loottables, but hey
|
||||
if (CarpetSettings.movableAmethyst &&
|
||||
stack.getItem() instanceof PickaxeItem &&
|
||||
EnchantmentHelper.getItemEnchantmentLevel(world.registryAccess().registryOrThrow(Registries.ENCHANTMENT).getHolderOrThrow(Enchantments.SILK_TOUCH), stack) > 0
|
||||
stack.is(ItemTags.PICKAXES) &&
|
||||
EnchantmentHelper.getItemEnchantmentLevel(world.registryAccess().lookupOrThrow(Registries.ENCHANTMENT).getOrThrow(Enchantments.SILK_TOUCH), stack) > 0
|
||||
)
|
||||
popResource(world, pos, Items.BUDDING_AMETHYST.getDefaultInstance());
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
public abstract class ChunkAccess_warningsMixin
|
||||
{
|
||||
// failed to mixin into interface. need to mixin in two places that uses it
|
||||
@Inject(method = "markPosForPostprocessing(Lnet/minecraft/core/BlockPos;)V",
|
||||
@Inject(method = "markPosForPostProcessing(Lnet/minecraft/core/BlockPos;)V",
|
||||
at =@At("HEAD"), cancellable = true)
|
||||
private void squashWarnings(BlockPos blockPos_1, CallbackInfo ci)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ package carpet.mixins;
|
||||
import carpet.utils.SpawnOverrides;
|
||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.util.random.WeightedList;
|
||||
import net.minecraft.world.level.StructureManager;
|
||||
import net.minecraft.world.level.levelgen.structure.Structure;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -11,7 +12,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.util.random.WeightedRandomList;
|
||||
import net.minecraft.world.entity.MobCategory;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings;
|
||||
@@ -31,10 +31,10 @@ public abstract class ChunkGenerator_customMobSpawnsMixin
|
||||
target = "Ljava/util/Map$Entry;getKey()Ljava/lang/Object;"
|
||||
), cancellable = true)
|
||||
private void checkCMSpawns(Holder<Biome> holder, StructureManager structureFeatureManager, MobCategory mobCategory, BlockPos blockPos,
|
||||
CallbackInfoReturnable<WeightedRandomList<MobSpawnSettings.SpawnerData>> cir,
|
||||
CallbackInfoReturnable<WeightedList<MobSpawnSettings.SpawnerData>> cir,
|
||||
Map<Structure, LongSet> map, Iterator<?> var6, Map.Entry<Structure, LongSet> entry)
|
||||
{
|
||||
WeightedRandomList<MobSpawnSettings.SpawnerData> res = SpawnOverrides.test(structureFeatureManager, entry.getValue(), mobCategory, entry.getKey(), blockPos);
|
||||
WeightedList<MobSpawnSettings.SpawnerData> res = SpawnOverrides.test(structureFeatureManager, entry.getValue(), mobCategory, entry.getKey(), blockPos);
|
||||
if (res != null)
|
||||
{
|
||||
cir.setReturnValue(res);
|
||||
|
||||
@@ -9,12 +9,12 @@ import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import carpet.fakes.SimpleEntityLookupInterface;
|
||||
import carpet.fakes.ServerWorldInterface;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.TickTask;
|
||||
@@ -23,11 +23,11 @@ import net.minecraft.server.level.ChunkLevel;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import net.minecraft.server.level.ChunkMap.DistanceManager;
|
||||
import net.minecraft.server.level.ChunkResult;
|
||||
import net.minecraft.server.level.ChunkTaskPriorityQueueSorter;
|
||||
//import net.minecraft.server.level.ChunkTaskPriorityQueueSorter;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ThreadedLevelLightEngine;
|
||||
import net.minecraft.server.level.TicketType;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
|
||||
import net.minecraft.util.thread.BlockableEventLoop;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
@@ -46,7 +46,6 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import carpet.fakes.ChunkHolderInterface;
|
||||
import carpet.fakes.ChunkTicketManagerInterface;
|
||||
import carpet.fakes.ServerLightingProviderInterface;
|
||||
import carpet.fakes.ThreadedAnvilChunkStorageInterface;
|
||||
import carpet.script.utils.WorldTools;
|
||||
@@ -76,17 +75,17 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
@Final
|
||||
private ThreadedLevelLightEngine lightEngine;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private ChunkTaskPriorityQueueSorter queueSorter;
|
||||
//@Shadow
|
||||
//@Final
|
||||
//private ChunkTaskPriorityQueueSorter queueSorter;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private BlockableEventLoop<Runnable> mainThreadExecutor;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
private ChunkProgressListener progressListener;
|
||||
//@Shadow
|
||||
//@Final
|
||||
//private ChunkProgressListener progressListener;
|
||||
|
||||
@Shadow
|
||||
@Final
|
||||
@@ -95,8 +94,8 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
@Shadow
|
||||
protected abstract boolean promoteChunkMap();
|
||||
|
||||
@Shadow
|
||||
protected abstract Iterable<ChunkHolder> getChunks();
|
||||
//@Shadow
|
||||
//protected abstract void forEachReadyToSendChunk(Consumer<LevelChunk> consumer); // for getChunks()
|
||||
|
||||
|
||||
@Shadow
|
||||
@@ -165,7 +164,6 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
this.world.getServer().execute(() -> CHUNK_LOADED.onChunkEvent(this.world, chpos, generated));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@Unique
|
||||
private void addTicket(ChunkPos pos, ChunkStatus status)
|
||||
@@ -180,7 +178,6 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@Unique
|
||||
private void addRelightTicket(ChunkPos pos)
|
||||
{
|
||||
@@ -195,7 +192,7 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
() -> "release relight ticket " + pos
|
||||
));
|
||||
}
|
||||
*/
|
||||
|
||||
@Unique
|
||||
private void tickTicketManager()
|
||||
{
|
||||
@@ -220,7 +217,7 @@ public abstract class ChunkMap_scarpetChunkCreationMixin implements ThreadedAnvi
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@Unique
|
||||
private Set<ChunkPos> loadExistingChunksFromDisk(Set<ChunkPos> requestedChunks)
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ public abstract class ClientPacketListener_clientCommandMixin extends ClientComm
|
||||
if (CarpetServer.minecraft_server == null && !CarpetClient.isCarpet() && minecraft.player != null)
|
||||
{
|
||||
LocalPlayer playerSource = minecraft.player;
|
||||
CarpetServer.forEachManager(sm -> sm.inspectClientsideCommand(playerSource.createCommandSourceStack(), "/" + string));
|
||||
CarpetServer.forEachManager(sm -> sm.inspectClientsideCommand("/" + string));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl;
|
||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||
import net.minecraft.client.multiplayer.CommonListenerCookie;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.protocol.game.ClientboundExplodePacket;
|
||||
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.callback.CallbackInfo;
|
||||
|
||||
@Mixin(ClientPacketListener.class)
|
||||
public abstract class ClientPacketListener_explosionMixin extends ClientCommonPacketListenerImpl
|
||||
{
|
||||
|
||||
private static Vec3 vec3dmem;
|
||||
private static long tickmem;
|
||||
// For disabling the explosion particles and sounds if explosions are stacking up
|
||||
|
||||
protected ClientPacketListener_explosionMixin(final Minecraft minecraft, final Connection connection, final CommonListenerCookie commonListenerCookie)
|
||||
{
|
||||
super(minecraft, connection, commonListenerCookie);
|
||||
}
|
||||
|
||||
|
||||
@Inject(method = "handleExplosion", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/multiplayer/ClientLevel;playLocalSound(DDDLnet/minecraft/sounds/SoundEvent;Lnet/minecraft/sounds/SoundSource;FFZ)V"
|
||||
), cancellable = true)
|
||||
private void onHandleExplosion(final ClientboundExplodePacket clientboundExplodePacket, final CallbackInfo ci)
|
||||
{
|
||||
|
||||
if (CarpetSettings.optimizedTNT)
|
||||
{
|
||||
Vec3 vec3d = clientboundExplodePacket.center();
|
||||
long tick = minecraft.level.getGameTime();
|
||||
if (vec3dmem == null || !vec3dmem.equals(vec3d) || tickmem != tick) {
|
||||
vec3dmem = vec3d;
|
||||
tickmem = tick;
|
||||
} else {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.commands.CloneCommands;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
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.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@@ -14,10 +15,10 @@ public abstract class CloneCommands_fillUpdatesMixin
|
||||
{
|
||||
@Redirect(method = "clone", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/level/ServerLevel;blockUpdated(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;)V"
|
||||
target = "Lnet/minecraft/server/level/ServerLevel;updateNeighboursOnBlockSet(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V"
|
||||
))
|
||||
private static void conditionalUpdating(ServerLevel serverWorld, BlockPos blockPos_1, Block block_1)
|
||||
private static void conditionalUpdating(ServerLevel serverWorld, BlockPos blockPos_1, BlockState block_1)
|
||||
{
|
||||
if (CarpetSettings.fillUpdates) serverWorld.blockUpdated(blockPos_1, block_1);
|
||||
if (CarpetSettings.fillUpdates) serverWorld.updateNeighboursOnBlockSet(blockPos_1, block_1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.CommandSourceStackInterface;
|
||||
import net.minecraft.commands.CommandResultCallback;
|
||||
import net.minecraft.commands.CommandSigningContext;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.arguments.EntityAnchorArgument;
|
||||
import net.minecraft.util.TaskChainer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(CommandSourceStack.class)
|
||||
public class CommandSourceStack_scarpetMixin implements CommandSourceStackInterface {
|
||||
@Mutable @Shadow private boolean silent;
|
||||
@Mutable @Shadow private CommandResultCallback resultCallback;
|
||||
@Mutable @Shadow private EntityAnchorArgument.Anchor anchor;
|
||||
@Mutable @Shadow private CommandSigningContext signingContext;
|
||||
@Mutable @Shadow private TaskChainer chatMessageChainer;
|
||||
|
||||
@Override
|
||||
public void setupPrivates(boolean bl, CommandResultCallback commandResultCallback, EntityAnchorArgument.Anchor anchor, CommandSigningContext commandSigningContext, TaskChainer taskChainer) {
|
||||
this.silent = bl;
|
||||
this.resultCallback = commandResultCallback;
|
||||
this.anchor = anchor;
|
||||
this.signingContext = commandSigningContext;
|
||||
this.chatMessageChainer = taskChainer;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package carpet.mixins;
|
||||
import carpet.fakes.ClientConnectionInterface;
|
||||
import carpet.logging.logHelpers.PacketCounter;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.util.concurrent.Future;
|
||||
import io.netty.util.concurrent.GenericFutureListener;
|
||||
@@ -28,7 +29,7 @@ public abstract class Connection_packetCounterMixin implements ClientConnectionI
|
||||
|
||||
// Add to the packet counter whenever a packet is sent.
|
||||
@Inject(method = "sendPacket", at = @At("HEAD"))
|
||||
private void packetOutCount(final Packet<?> packet, final PacketSendListener packetSendListener, final boolean bl, final CallbackInfo ci)
|
||||
private void packetOutCount(Packet<?> packet, ChannelFutureListener channelFutureListener, boolean bl, CallbackInfo ci)
|
||||
{
|
||||
PacketCounter.totalOut++;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@Mixin(DebugRenderer.class)
|
||||
public class DebugRenderer_scarpetRenderMixin
|
||||
{
|
||||
@Inject(method = "clear", at = @At("HEAD"))
|
||||
@Inject(method = "refreshRendererList", at = @At("HEAD"))
|
||||
private void resetScarpetRenderes(CallbackInfo ci)
|
||||
{
|
||||
if (CarpetClient.shapes != null)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.DefaultRedstoneWireEvaluatorInferface;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.redstone.DefaultRedstoneWireEvaluator;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(DefaultRedstoneWireEvaluator.class)
|
||||
public abstract class DefaultRedstoneWireEvaluator_redstoneMixin implements DefaultRedstoneWireEvaluatorInferface
|
||||
{
|
||||
@Shadow protected abstract int calculateTargetStrength(final Level level, final BlockPos blockPos);
|
||||
|
||||
@Override
|
||||
public int calculateTargetStrengthCM(final Level level, final BlockPos pos)
|
||||
{
|
||||
return calculateTargetStrength(level, pos);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import net.minecraft.world.level.redstone.Orientation;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@@ -23,7 +24,7 @@ public class DispenserBlock_qcMixin {
|
||||
target = "Lnet/minecraft/world/level/Level;hasNeighborSignal(Lnet/minecraft/core/BlockPos;)Z"
|
||||
)
|
||||
)
|
||||
private boolean carpet_hasQuasiSignal(Level _level, BlockPos above, BlockState state, Level level, BlockPos pos, Block neighborBlock, BlockPos neighborPos, boolean movedByPiston) {
|
||||
private boolean carpet_hasQuasiSignal(Level _level, BlockPos above, BlockState state, Level level, BlockPos pos, Block neighborBlock, Orientation neighborPos, boolean movedByPiston) {
|
||||
return QuasiConnectivity.hasQuasiSignal(level, pos);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import java.util.Set;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.level.DistanceManager;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import carpet.fakes.ChunkTicketManagerInterface;
|
||||
|
||||
@Mixin(DistanceManager.class)
|
||||
public abstract class DistanceManager_scarpetChunkCreationMixin implements ChunkTicketManagerInterface
|
||||
{
|
||||
@Shadow
|
||||
@Final
|
||||
private Set<ChunkHolder> chunksToUpdateFutures;
|
||||
|
||||
@Override
|
||||
public void replaceHolder(final ChunkHolder oldHolder, final ChunkHolder newHolder)
|
||||
{
|
||||
this.chunksToUpdateFutures.remove(oldHolder);
|
||||
this.chunksToUpdateFutures.add(newHolder);
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,25 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.ChunkTicketManagerInterface;
|
||||
import carpet.fakes.TicketsFetcherInterface;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.minecraft.server.level.DistanceManager;
|
||||
import net.minecraft.server.level.Ticket;
|
||||
import net.minecraft.util.SortedArraySet;
|
||||
import net.minecraft.world.level.TicketStorage;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(DistanceManager.class)
|
||||
public abstract class DistanceManager_scarpetMixin implements ChunkTicketManagerInterface
|
||||
public abstract class DistanceManager_scarpetMixin implements TicketsFetcherInterface
|
||||
{
|
||||
@Shadow @Final private Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> tickets;
|
||||
@Shadow @Final private TicketStorage ticketStorage;
|
||||
|
||||
@Override
|
||||
public Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> getTicketsByPosition()
|
||||
public Long2ObjectOpenHashMap<List<Ticket>> getTicketsByPosition()
|
||||
{
|
||||
return tickets;
|
||||
return ((TicketsFetcherInterface)ticketStorage).getTicketsByPosition();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.ChunkTicketManagerInterface;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.minecraft.server.level.DistanceManager;
|
||||
import net.minecraft.server.level.Ticket;
|
||||
import net.minecraft.server.level.TicketType;
|
||||
import net.minecraft.util.SortedArraySet;
|
||||
import net.minecraft.util.Unit;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
@Mixin(DistanceManager.class)
|
||||
public abstract class DistanceManager_spawnChunksMixin implements ChunkTicketManagerInterface
|
||||
{
|
||||
@Shadow @Final private Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> tickets;
|
||||
|
||||
@Shadow protected abstract void removeTicket(long pos, Ticket<?> ticket);
|
||||
|
||||
@Shadow public abstract <T> void addRegionTicket(TicketType<T> type, ChunkPos pos, int radius, T argument);
|
||||
|
||||
@Override
|
||||
public void changeSpawnChunks(ChunkPos chunkPos, int distance)
|
||||
{
|
||||
long pos = chunkPos.toLong();
|
||||
SortedArraySet<Ticket<?>> set = tickets.get(pos);
|
||||
Ticket<?> existingTicket = null;
|
||||
if (set != null)
|
||||
{
|
||||
Iterator<Ticket<?>> iter = set.iterator();
|
||||
while(iter.hasNext())
|
||||
{
|
||||
Ticket<?> ticket = iter.next();
|
||||
if (ticket.getType() == TicketType.START)
|
||||
{
|
||||
existingTicket = ticket;
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
set.add(existingTicket);
|
||||
}
|
||||
// the reason we are removing the ticket this way is that there are sideeffects of removal
|
||||
if (existingTicket != null)
|
||||
{
|
||||
removeTicket(pos, existingTicket);
|
||||
}
|
||||
// set optionally new spawn ticket
|
||||
if (distance > 0)
|
||||
addRegionTicket(TicketType.START, chunkPos, distance, Unit.INSTANCE);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,9 @@ import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -32,9 +35,19 @@ public abstract class EntityMixin implements EntityInterface
|
||||
return partialTicks == 1.0F ? this.yRot : Mth.lerp(partialTicks, this.yRotO, this.yRot);
|
||||
}
|
||||
|
||||
@Inject(method = "isControlledByLocalInstance", at = @At("HEAD"), cancellable = true)
|
||||
@Inject(method = "isLocalInstanceAuthoritative", at = @At("HEAD"), cancellable = true)
|
||||
private void isFakePlayer(CallbackInfoReturnable<Boolean> cir)
|
||||
{
|
||||
if (getControllingPassenger() instanceof EntityPlayerMPFake) cir.setReturnValue(!level.isClientSide);
|
||||
// getControllingPassenger() does not return the EntityPlayerMPFake if there are no passengers involved with it
|
||||
if ((Object) this instanceof EntityPlayerMPFake || getControllingPassenger() instanceof EntityPlayerMPFake) cir.setReturnValue(!level.isClientSide());
|
||||
}
|
||||
|
||||
@Shadow
|
||||
protected abstract Stream<Entity> getIndirectPassengersStream();
|
||||
|
||||
@Override
|
||||
public Stream<Entity> cm$getIndirectPassengersStream()
|
||||
{
|
||||
return this.getIndirectPassengersStream();
|
||||
}
|
||||
}
|
||||
@@ -19,9 +19,6 @@ public abstract class ExperienceOrb_xpNoCooldownMixin extends Entity
|
||||
@Shadow
|
||||
private int count;
|
||||
|
||||
@Shadow
|
||||
private int value;
|
||||
|
||||
public ExperienceOrb_xpNoCooldownMixin(EntityType<?> type, Level world)
|
||||
{
|
||||
super(type, world);
|
||||
@@ -30,13 +27,15 @@ public abstract class ExperienceOrb_xpNoCooldownMixin extends Entity
|
||||
@Shadow
|
||||
protected abstract int repairPlayerItems(ServerPlayer player, int amount);
|
||||
|
||||
@Shadow public abstract int getValue();
|
||||
|
||||
@Inject(method = "playerTouch", at = @At("HEAD"))
|
||||
private void addXP(Player player, CallbackInfo ci) {
|
||||
if (CarpetSettings.xpNoCooldown && !level().isClientSide) {
|
||||
if (CarpetSettings.xpNoCooldown && !level().isClientSide()) {
|
||||
player.takeXpDelay = 0;
|
||||
// reducing the count to 1 and leaving vanilla to deal with it
|
||||
while (this.count > 1) {
|
||||
int remainder = this.repairPlayerItems((ServerPlayer) player, this.value);
|
||||
int remainder = this.repairPlayerItems((ServerPlayer) player, this.getValue());
|
||||
if (remainder > 0) {
|
||||
player.giveExperiencePoints(remainder);
|
||||
}
|
||||
|
||||
@@ -1,37 +1,22 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.level.ServerExplosion;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
@Mixin(Explosion.class)
|
||||
@Mixin(ServerExplosion.class)
|
||||
public interface ExplosionAccessor {
|
||||
|
||||
@Accessor
|
||||
boolean isFire();
|
||||
ServerLevel getLevel();
|
||||
|
||||
@Accessor
|
||||
Explosion.BlockInteraction getBlockInteraction();
|
||||
|
||||
@Accessor
|
||||
Level getLevel();
|
||||
|
||||
@Accessor
|
||||
RandomSource getRandom();
|
||||
|
||||
@Accessor
|
||||
double getX();
|
||||
|
||||
@Accessor
|
||||
double getY();
|
||||
|
||||
@Accessor
|
||||
double getZ();
|
||||
Vec3 getCenter();
|
||||
|
||||
@Accessor
|
||||
float getRadius();
|
||||
|
||||
@@ -4,11 +4,12 @@ import carpet.helpers.OptimizedExplosion;
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.logging.LoggerRegistry;
|
||||
import carpet.logging.logHelpers.ExplosionLogHelper;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.monster.breeze.Breeze;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.ServerExplosion;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -23,81 +24,74 @@ import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.ExplosionDamageCalculator;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(value = Explosion.class)
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(value = ServerExplosion.class)
|
||||
public abstract class Explosion_optimizedTntMixin
|
||||
{
|
||||
@Shadow
|
||||
@Final
|
||||
private ObjectArrayList<BlockPos> toBlow;
|
||||
|
||||
@Shadow @Final private Level level;
|
||||
@Shadow @Final private ServerLevel level;
|
||||
|
||||
@Shadow @Nullable public abstract LivingEntity getIndirectSourceEntity();
|
||||
|
||||
private ExplosionLogHelper eLogger;
|
||||
|
||||
@Inject(method = "explode", at = @At("HEAD"),
|
||||
@Inject(method = "calculateExplodedPositions", at = @At("HEAD"),
|
||||
cancellable = true)
|
||||
private void onExplosionA(CallbackInfo ci)
|
||||
private void calculateExplodedPositionsCM(final CallbackInfoReturnable<List<BlockPos>> cir)
|
||||
{
|
||||
if (CarpetSettings.optimizedTNT && !level.isClientSide && !(getIndirectSourceEntity() instanceof Breeze))
|
||||
if (CarpetSettings.optimizedTNT && !level.isClientSide() && !(getIndirectSourceEntity() instanceof Breeze))
|
||||
{
|
||||
OptimizedExplosion.doExplosionA((Explosion) (Object) this, eLogger);
|
||||
ci.cancel();
|
||||
cir.setReturnValue(OptimizedExplosion.doExplosionA((Explosion) (Object) this, eLogger));
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "finalizeExplosion", at = @At("HEAD"),
|
||||
cancellable = true)
|
||||
private void onExplosionB(boolean spawnParticles, CallbackInfo ci)
|
||||
@Inject(method = "interactWithBlocks", at = @At("HEAD"))
|
||||
private void interactWithBlocksCM(final List<BlockPos> list, final CallbackInfo ci)
|
||||
{
|
||||
if (eLogger != null)
|
||||
{
|
||||
eLogger.setAffectBlocks( ! toBlow.isEmpty());
|
||||
eLogger.setAffectBlocks( ! list.isEmpty());
|
||||
eLogger.onExplosionDone(this.level.getGameTime());
|
||||
}
|
||||
if (CarpetSettings.explosionNoBlockDamage)
|
||||
{
|
||||
toBlow.clear();
|
||||
}
|
||||
if (CarpetSettings.optimizedTNT && !level.isClientSide && !(getIndirectSourceEntity() instanceof Breeze))
|
||||
{
|
||||
OptimizedExplosion.doExplosionB((Explosion) (Object) this, spawnParticles);
|
||||
ci.cancel();
|
||||
list.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//optional due to Overwrite in Lithium
|
||||
//should kill most checks if no block damage is requested
|
||||
@Redirect(method = "explode", require = 0, at = @At(value = "INVOKE",
|
||||
target ="Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;"))
|
||||
private BlockState noBlockCalcsWithNoBLockDamage(Level world, BlockPos pos)
|
||||
@Redirect(method = "calculateExplodedPositions", require = 0, at = @At(value = "INVOKE",
|
||||
target ="Lnet/minecraft/world/level/ExplosionDamageCalculator;getBlockExplosionResistance(Lnet/minecraft/world/level/Explosion;Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/material/FluidState;)Ljava/util/Optional;"))
|
||||
private Optional<Float> noBlockCalcsWithNoBLockDamage(final ExplosionDamageCalculator instance, final Explosion explosion, final BlockGetter blockGetter, final BlockPos blockPos, final BlockState blockState, final FluidState fluidState)
|
||||
{
|
||||
if (CarpetSettings.explosionNoBlockDamage) return Blocks.BEDROCK.defaultBlockState();
|
||||
return world.getBlockState(pos);
|
||||
if (CarpetSettings.explosionNoBlockDamage) return Optional.of(Blocks.BEDROCK.getExplosionResistance());
|
||||
return instance.getBlockExplosionResistance(explosion, blockGetter, blockPos, blockState, fluidState);
|
||||
}
|
||||
|
||||
@Inject(method = "<init>(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/damagesource/DamageSource;Lnet/minecraft/world/level/ExplosionDamageCalculator;DDDFZLnet/minecraft/world/level/Explosion$BlockInteraction;Lnet/minecraft/core/particles/ParticleOptions;Lnet/minecraft/core/particles/ParticleOptions;Lnet/minecraft/core/Holder;)V",
|
||||
@Inject(method = "<init>",
|
||||
at = @At(value = "RETURN"))
|
||||
private void onExplosionCreated(Level world, Entity entity, DamageSource damageSource, ExplosionDamageCalculator explosionBehavior, double x, double y, double z, float power, boolean createFire, Explosion.BlockInteraction destructionType, ParticleOptions particleOptions, ParticleOptions particleOptions2, Holder soundEvent, CallbackInfo ci)
|
||||
private void onExplostion(ServerLevel world, Entity entity, DamageSource damageSource, final ExplosionDamageCalculator explosionBehavior, final Vec3 vec3, final float power, final boolean createFire, final Explosion.BlockInteraction destructionType, final CallbackInfo ci)
|
||||
{
|
||||
if (LoggerRegistry.__explosions && ! world.isClientSide)
|
||||
if (LoggerRegistry.__explosions && ! world.isClientSide())
|
||||
{
|
||||
eLogger = new ExplosionLogHelper(x, y, z, power, createFire, destructionType, level.registryAccess());
|
||||
eLogger = new ExplosionLogHelper(vec3.x, vec3.y, vec3.z, power, createFire, destructionType, level.registryAccess());
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "explode",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;setDeltaMovement(Lnet/minecraft/world/phys/Vec3;)V"))
|
||||
@Redirect(method = "hurtEntities",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;push(Lnet/minecraft/world/phys/Vec3;)V"))
|
||||
private void setVelocityAndUpdateLogging(Entity entity, Vec3 velocity)
|
||||
{
|
||||
if (eLogger != null) {
|
||||
eLogger.onEntityImpacted(entity, velocity.subtract(entity.getDeltaMovement()));
|
||||
}
|
||||
entity.setDeltaMovement(velocity);
|
||||
entity.push(velocity);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.particles.ParticleOptions;
|
||||
import net.minecraft.world.level.ServerExplosion;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -10,70 +8,52 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||
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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.ExplosionDamageCalculator;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import static carpet.script.CarpetEventServer.Event.EXPLOSION_OUTCOME;
|
||||
|
||||
@Mixin(value = Explosion.class, priority = 990)
|
||||
@Mixin(value = ServerExplosion.class, priority = 990)
|
||||
public abstract class Explosion_scarpetEventMixin
|
||||
{
|
||||
@Shadow @Final private Level level;
|
||||
@Shadow @Final private double x;
|
||||
@Shadow @Final private double y;
|
||||
@Shadow @Final private double z;
|
||||
@Shadow @Final private ServerLevel level;
|
||||
@Shadow @Final private Vec3 center;
|
||||
@Shadow @Final private float radius;
|
||||
@Shadow @Final private boolean fire;
|
||||
@Shadow @Final private ObjectArrayList<BlockPos> toBlow;
|
||||
@Shadow @Final private Explosion.BlockInteraction blockInteraction;
|
||||
@Shadow @Final private @Nullable Entity source;
|
||||
|
||||
@Shadow /*@Nullable*/ public abstract /*@Nullable*/ LivingEntity getIndirectSourceEntity();
|
||||
|
||||
@Shadow public static float getSeenPercent(Vec3 source, Entity entity) {return 0.0f;}
|
||||
private List<Entity> affectedEntities = new ArrayList<>();
|
||||
|
||||
private List<Entity> affectedEntities;
|
||||
|
||||
@Inject(method = "<init>(Lnet/minecraft/world/level/Level;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/damagesource/DamageSource;Lnet/minecraft/world/level/ExplosionDamageCalculator;DDDFZLnet/minecraft/world/level/Explosion$BlockInteraction;Lnet/minecraft/core/particles/ParticleOptions;Lnet/minecraft/core/particles/ParticleOptions;Lnet/minecraft/core/Holder;)V",
|
||||
at = @At(value = "RETURN"))
|
||||
private void onExplosionCreated(Level world, Entity entity, DamageSource damageSource, ExplosionDamageCalculator explosionBehavior, double x, double y, double z, float power, boolean createFire, Explosion.BlockInteraction destructionType, ParticleOptions particleOptions, ParticleOptions particleOptions2, Holder soundEvent, CallbackInfo ci)
|
||||
@Inject(method = "explode", at = @At("HEAD"))
|
||||
private void explodeCM(CallbackInfoReturnable<Integer> cir)
|
||||
{
|
||||
if (EXPLOSION_OUTCOME.isNeeded() && !world.isClientSide())
|
||||
{
|
||||
affectedEntities = new ArrayList<>();
|
||||
}
|
||||
affectedEntities.clear();
|
||||
}
|
||||
|
||||
@Redirect(method = "explode", at=@At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/Explosion;getSeenPercent(Lnet/minecraft/world/phys/Vec3;Lnet/minecraft/world/entity/Entity;)F")
|
||||
)
|
||||
private float onExplosion(Vec3 source, Entity entity)
|
||||
@Redirect(method = "hurtEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;onExplosionHit(Lnet/minecraft/world/entity/Entity;)V"))
|
||||
private void onEntityHit(Entity instance, Entity entity)
|
||||
{
|
||||
if (affectedEntities != null)
|
||||
{
|
||||
affectedEntities.add(entity);
|
||||
}
|
||||
return getSeenPercent(source, entity);
|
||||
affectedEntities.add(instance);
|
||||
instance.onExplosionHit(entity);
|
||||
}
|
||||
|
||||
@Inject(method = "finalizeExplosion", at = @At("HEAD"))
|
||||
private void onExplosion(boolean spawnParticles, CallbackInfo ci)
|
||||
@Inject(method = "explode", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/ServerExplosion;hurtEntities()V", shift = At.Shift.AFTER))
|
||||
private void onExplosionDone(CallbackInfoReturnable<Integer> cir, List list)
|
||||
{
|
||||
if (EXPLOSION_OUTCOME.isNeeded() && !level.isClientSide())
|
||||
{
|
||||
EXPLOSION_OUTCOME.onExplosion((ServerLevel) level, source, this::getIndirectSourceEntity, x, y, z, radius, fire, toBlow, affectedEntities, blockInteraction);
|
||||
EXPLOSION_OUTCOME.onExplosion((ServerLevel) level, source, this::getIndirectSourceEntity, center, radius, fire, list, affectedEntities, blockInteraction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ public abstract class FallingBlockEntityMixin extends Entity
|
||||
@Inject(method = "<init>(Lnet/minecraft/world/entity/EntityType;Lnet/minecraft/world/level/Level;)V", at = @At("RETURN"))
|
||||
private void addLogger(EntityType<? extends Projectile> entityType_1, Level world_1, CallbackInfo ci)
|
||||
{
|
||||
if (LoggerRegistry.__fallingBlocks && !world_1.isClientSide)
|
||||
if (LoggerRegistry.__fallingBlocks && !world_1.isClientSide())
|
||||
logHelper = new TrajectoryLogHelper("fallingBlocks");
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.commands.FillCommand;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
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.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@@ -14,10 +15,10 @@ public abstract class FillCommandMixin
|
||||
{
|
||||
@Redirect(method = "fillBlocks", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/server/level/ServerLevel;blockUpdated(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;)V"
|
||||
target = "Lnet/minecraft/server/level/ServerLevel;updateNeighboursOnBlockSet(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V"
|
||||
))
|
||||
private static void conditionalUpdating(ServerLevel serverWorld, BlockPos blockPos_1, Block block_1)
|
||||
private static void conditionalUpdating(ServerLevel serverWorld, BlockPos blockPos_1, BlockState block_1)
|
||||
{
|
||||
if (CarpetSettings.fillUpdates) serverWorld.blockUpdated(blockPos_1, block_1);
|
||||
if (CarpetSettings.fillUpdates) serverWorld.updateNeighboursOnBlockSet(blockPos_1, block_1);
|
||||
}
|
||||
}
|
||||
@@ -16,14 +16,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
public class FlowingFluid_liquidDamageDisabledMixin
|
||||
{
|
||||
@Inject(
|
||||
method = "canHoldFluid",
|
||||
method = "canHoldAnyFluid",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/block/state/BlockState;blocksMotion()Z"
|
||||
),
|
||||
cancellable = true
|
||||
)
|
||||
private void stopBreakingBlock(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid, CallbackInfoReturnable<Boolean> cir)
|
||||
private static void stopBreakingBlock(final BlockState state, final CallbackInfoReturnable<Boolean> cir)
|
||||
{
|
||||
if (CarpetSettings.liquidDamageDisabled)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.FoodDataInterface;
|
||||
import net.minecraft.world.food.FoodData;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
@Mixin(FoodData.class)
|
||||
public class FoodData_scarpetMixin implements FoodDataInterface
|
||||
{
|
||||
@Shadow private float exhaustionLevel;
|
||||
|
||||
@Override
|
||||
public float getCMExhaustionLevel()
|
||||
{
|
||||
return exhaustionLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExhaustion(float aFloat)
|
||||
{
|
||||
exhaustionLevel = aFloat;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.EntitySpawnReason;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.EntityTypes;
|
||||
import net.minecraft.world.entity.LightningBolt;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.entity.SpawnGroupData;
|
||||
import net.minecraft.world.entity.monster.ElderGuardian;
|
||||
import net.minecraft.world.entity.monster.Guardian;
|
||||
import net.minecraft.world.entity.monster.Monster;
|
||||
@@ -24,11 +23,11 @@ public abstract class Guardian_renewableSpongesMixin extends Monster
|
||||
@Override
|
||||
public void thunderHit(ServerLevel serverWorld, LightningBolt lightningEntity)
|
||||
{ // isRemoved()
|
||||
if (!this.level().isClientSide && !this.isRemoved() && CarpetSettings.renewableSponges && !((Object)this instanceof ElderGuardian))
|
||||
if (!this.level().isClientSide() && !this.isRemoved() && CarpetSettings.renewableSponges && !((Object)this instanceof ElderGuardian))
|
||||
{
|
||||
ElderGuardian elderGuardian = new ElderGuardian(EntityType.ELDER_GUARDIAN ,this.level());
|
||||
elderGuardian.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
|
||||
elderGuardian.finalizeSpawn(serverWorld ,this.level().getCurrentDifficultyAt(elderGuardian.blockPosition()), MobSpawnType.CONVERSION, null);
|
||||
ElderGuardian elderGuardian = new ElderGuardian(EntityTypes.ELDER_GUARDIAN ,this.level());
|
||||
elderGuardian.snapTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
|
||||
elderGuardian.finalizeSpawn(serverWorld ,serverWorld.getCurrentDifficultyAt(elderGuardian.blockPosition()), EntitySpawnReason.CONVERSION, null);
|
||||
elderGuardian.setNoAi(this.isNoAi());
|
||||
|
||||
if (this.hasCustomName())
|
||||
|
||||
@@ -3,6 +3,7 @@ package carpet.mixins;
|
||||
import carpet.fakes.PlayerListHudInterface;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.client.gui.Hud;
|
||||
import net.minecraft.client.gui.components.PlayerTabOverlay;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -10,7 +11,7 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(Gui.class)
|
||||
@Mixin(Hud.class)
|
||||
public abstract class Gui_tablistMixin
|
||||
{
|
||||
@Shadow
|
||||
@@ -19,7 +20,7 @@ public abstract class Gui_tablistMixin
|
||||
|
||||
@Shadow @Final private PlayerTabOverlay tabList;
|
||||
|
||||
@Redirect(method = "renderTabList", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;isLocalServer()Z"))
|
||||
@Redirect(method = "extractTabList", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Minecraft;isLocalServer()Z"))
|
||||
private boolean onDraw(Minecraft minecraftClient)
|
||||
{
|
||||
return this.minecraft.isLocalServer() && !((PlayerListHudInterface) tabList).hasFooterOrHeader();
|
||||
|
||||
@@ -3,7 +3,7 @@ package carpet.mixins;
|
||||
import carpet.fakes.InventoryBearerInterface;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.SimpleContainer;
|
||||
import net.minecraft.world.entity.animal.horse.AbstractHorse;
|
||||
import net.minecraft.world.entity.animal.equine.AbstractHorse;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.utils.SpawnOverrides;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.monster.Husk;
|
||||
import net.minecraft.world.level.ServerLevelAccessor;
|
||||
import net.minecraft.world.level.levelgen.structure.BuiltinStructures;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(Husk.class)
|
||||
public class Husk_templesMixin
|
||||
{
|
||||
@Redirect(method = "checkHuskSpawnRules", at = @At(value = "INVOKE", target="Lnet/minecraft/world/level/ServerLevelAccessor;canSeeSky(Lnet/minecraft/core/BlockPos;)Z"))
|
||||
private static boolean isSkylightOrTempleVisible(ServerLevelAccessor serverWorldAccess, BlockPos pos)
|
||||
{
|
||||
return serverWorldAccess.canSeeSky(pos) ||
|
||||
(CarpetSettings.huskSpawningInTemples && SpawnOverrides.isStructureAtPosition((ServerLevel)serverWorldAccess, BuiltinStructures.DESERT_PYRAMID, pos));
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,11 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.fakes.IngredientInterface;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Ingredient;
|
||||
|
||||
@Mixin(Ingredient.class)
|
||||
public class Ingredient_scarpetMixin implements IngredientInterface
|
||||
public class Ingredient_scarpetMixin// implements IngredientInterface
|
||||
{
|
||||
@Shadow @Final private Ingredient.Value[] values;
|
||||
|
||||
@Override
|
||||
public List<Collection<ItemStack>> getRecipeStacks()
|
||||
{
|
||||
return Arrays.stream(values).map(Ingredient.Value::getItems).toList();
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package carpet.mixins;
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.ItemInstance;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.component.ItemContainerContents;
|
||||
import net.minecraft.world.level.block.ShulkerBoxBlock;
|
||||
@@ -11,16 +12,17 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(ItemStack.class)
|
||||
public class ItemStack_stackableShulkerBoxesMixin
|
||||
@Mixin(ItemInstance.class)
|
||||
public interface ItemStack_stackableShulkerBoxesMixin
|
||||
{
|
||||
@Inject(method = "getMaxStackSize", at = @At("HEAD"), cancellable = true)
|
||||
private void getCMMAxStackSize(CallbackInfoReturnable<Integer> cir)
|
||||
{
|
||||
if (CarpetSettings.shulkerBoxStackSize > 1
|
||||
&& ((ItemStack)((Object)this)).getItem() instanceof BlockItem blockItem
|
||||
&& ((ItemInstance)((Object)this)) instanceof final ItemStack itemStack
|
||||
&& itemStack.getItem() instanceof BlockItem blockItem
|
||||
&& blockItem.getBlock() instanceof ShulkerBoxBlock
|
||||
&& ((ItemStack) ((Object) this)).getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).stream().findAny().isEmpty()
|
||||
&& ((ItemStack) ((Object) this)).getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY).allItemsCopyStream().findAny().isEmpty()
|
||||
) {
|
||||
cir.setReturnValue(CarpetSettings.shulkerBoxStackSize);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.component.Tool;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
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(Item.class)
|
||||
public class Item_missingToolsMixin
|
||||
{
|
||||
@Inject(method = "getDestroySpeed", at = @At("HEAD"), cancellable = true)
|
||||
public void getDestroySpeed(ItemStack itemStack, BlockState blockState, CallbackInfoReturnable<Float> cir) {
|
||||
if (CarpetSettings.missingTools && blockState.getSoundType() == SoundType.GLASS && itemStack.is(ItemTags.PICKAXES))
|
||||
{
|
||||
Tool tool = itemStack.get(DataComponents.TOOL);
|
||||
if (tool != null) {
|
||||
cir.setReturnValue(tool.getMiningSpeed(Blocks.STONE.defaultBlockState()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,9 @@ package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -25,20 +27,25 @@ public class LevelChunk_fillUpdatesMixin
|
||||
|
||||
@Redirect(method = "setBlockState", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/block/state/BlockState;onRemove(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Z)V"
|
||||
target = "Lnet/minecraft/world/level/block/entity/BlockEntity;preRemoveSideEffects(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V"
|
||||
))
|
||||
private void onRemovedBlock(BlockState blockState, Level world, BlockPos pos, BlockState state, boolean moved)
|
||||
private void onPreRemoveSideEffects(BlockEntity blockEntity, BlockPos blockPos_1, BlockState blockState_1)
|
||||
{
|
||||
if (CarpetSettings.impendingFillSkipUpdates.get()) // doing due dilligence from AbstractBlock onStateReplaced
|
||||
if (!CarpetSettings.impendingFillSkipUpdates.get())
|
||||
{
|
||||
if (blockState.hasBlockEntity() && !blockState.is(state.getBlock()))
|
||||
blockEntity.preRemoveSideEffects(blockPos_1, blockState_1);
|
||||
}
|
||||
}
|
||||
|
||||
@Redirect(method = "setBlockState", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/block/state/BlockState;affectNeighborsAfterRemoval(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;Z)V"
|
||||
))
|
||||
private void onAffectNeighborsAfterRemoval(final BlockState instance, final ServerLevel serverLevel, final BlockPos blockPos, final boolean b)
|
||||
{
|
||||
world.removeBlockEntity(pos);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!CarpetSettings.impendingFillSkipUpdates.get())
|
||||
{
|
||||
blockState.onRemove(world, pos, state, moved);
|
||||
instance.affectNeighborsAfterRemoval(serverLevel, blockPos, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,21 +4,24 @@ import carpet.CarpetSettings;
|
||||
import carpet.fakes.WorldChunkInterface;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.profiling.Profiler;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelHeightAccessor;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.block.BaseRailBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.piston.MovingPistonBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
import net.minecraft.world.level.chunk.UpgradeData;
|
||||
import net.minecraft.world.level.chunk.*;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.levelgen.blending.BlendingData;
|
||||
import net.minecraft.world.level.lighting.LightEngine;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -33,8 +36,8 @@ public abstract class LevelChunk_movableBEMixin extends ChunkAccess implements W
|
||||
@Final
|
||||
Level level;
|
||||
|
||||
public LevelChunk_movableBEMixin(ChunkPos pos, UpgradeData upgradeData, LevelHeightAccessor heightLimitView, Registry<Biome> biome, long inhabitedTime, @Nullable LevelChunkSection[] sectionArrayInitializer, @Nullable BlendingData blendingData) {
|
||||
super(pos, upgradeData, heightLimitView, biome, inhabitedTime, sectionArrayInitializer, blendingData);
|
||||
public LevelChunk_movableBEMixin(ChunkPos chunkPos, UpgradeData upgradeData, LevelHeightAccessor levelHeightAccessor, PalettedContainerFactory palettedContainerFactory, long l, @Nullable LevelChunkSection[] levelChunkSections, @Nullable BlendingData blendingData) {
|
||||
super(chunkPos, upgradeData, levelHeightAccessor, palettedContainerFactory, l, levelChunkSections, blendingData);
|
||||
}
|
||||
|
||||
@Shadow
|
||||
@@ -72,73 +75,110 @@ public abstract class LevelChunk_movableBEMixin extends ChunkAccess implements W
|
||||
*/
|
||||
/* @Nullable */
|
||||
// todo update me to the new version
|
||||
@Override
|
||||
public BlockState setBlockStateWithBlockEntity(BlockPos blockPos_1, BlockState newBlockState, BlockEntity newBlockEntity,
|
||||
boolean boolean_1)
|
||||
int flags)
|
||||
{
|
||||
int x = blockPos_1.getX() & 15;
|
||||
|
||||
int y = blockPos_1.getY();
|
||||
int z = blockPos_1.getZ() & 15;
|
||||
|
||||
LevelChunkSection chunkSection = this.getSection(this.getSectionIndex(y));
|
||||
if (chunkSection.hasOnlyAir())
|
||||
{
|
||||
if (newBlockState.isAir())
|
||||
|
||||
boolean hadOnlyAir = chunkSection.hasOnlyAir();
|
||||
|
||||
if (hadOnlyAir && newBlockState.isAir())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
boolean boolean_2 = chunkSection.hasOnlyAir();
|
||||
BlockState oldBlockState = chunkSection.setBlockState(x, y & 15, z, newBlockState);
|
||||
int x = blockPos_1.getX() & 15;
|
||||
int chunkY = blockPos_1.getY() & 15;
|
||||
int z = blockPos_1.getZ() & 15;
|
||||
BlockState oldBlockState = chunkSection.setBlockState(x, chunkY, z, newBlockState);
|
||||
if (oldBlockState == newBlockState)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
Block newBlock = newBlockState.getBlock();
|
||||
Block oldBlock = oldBlockState.getBlock();
|
||||
((Heightmap) this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING)).update(x, y, z, newBlockState);
|
||||
((Heightmap) this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES)).update(x, y, z, newBlockState);
|
||||
((Heightmap) this.heightmaps.get(Heightmap.Types.OCEAN_FLOOR)).update(x, y, z, newBlockState);
|
||||
((Heightmap) this.heightmaps.get(Heightmap.Types.WORLD_SURFACE)).update(x, y, z, newBlockState);
|
||||
boolean boolean_3 = chunkSection.hasOnlyAir();
|
||||
if (boolean_2 != boolean_3)
|
||||
this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING).update(x, y, z, newBlockState);
|
||||
this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES).update(x, y, z, newBlockState);
|
||||
this.heightmaps.get(Heightmap.Types.OCEAN_FLOOR).update(x, y, z, newBlockState);
|
||||
this.heightmaps.get(Heightmap.Types.WORLD_SURFACE).update(x, y, z, newBlockState);
|
||||
boolean hasOnlyAir = chunkSection.hasOnlyAir();
|
||||
if (hadOnlyAir != hasOnlyAir)
|
||||
{
|
||||
this.level.getChunkSource().getLightEngine().updateSectionStatus(blockPos_1, boolean_3);
|
||||
this.level.getChunkSource().getLightEngine().updateSectionStatus(blockPos_1, hasOnlyAir);
|
||||
this.level.getChunkSource().onSectionEmptinessChanged(chunkPos.x(), SectionPos.blockToSectionCoord(y), chunkPos.z(), hasOnlyAir);
|
||||
}
|
||||
|
||||
if (!this.level.isClientSide)
|
||||
if (LightEngine.hasDifferentLightProperties(oldBlockState, newBlockState)) {
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
profiler.push("updateSkyLightSources");
|
||||
if (skyLightSources != null) // compat with ScalableLux aka Starlight port
|
||||
{
|
||||
if (!(oldBlock instanceof MovingPistonBlock))//this is a movableTE special case, if condition wasn't there it would remove the blockentity that was carried for some reason
|
||||
oldBlockState.onRemove(this.level, blockPos_1, newBlockState, boolean_1);//this kills it
|
||||
skyLightSources.update(this, x, chunkY, z);
|
||||
}
|
||||
else if (oldBlock != newBlock && oldBlock instanceof EntityBlock)
|
||||
{
|
||||
this.level.removeBlockEntity(blockPos_1);
|
||||
profiler.popPush("queueCheckLight");
|
||||
level.getChunkSource().getLightEngine().checkBlock(blockPos_1);
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
if (chunkSection.getBlockState(x, y & 15, z).getBlock() != newBlock)
|
||||
boolean blockChanged = !oldBlockState.is(newBlock);
|
||||
boolean movedByPiston = (flags & Block.UPDATE_MOVE_BY_PISTON) != 0; // moved by pistons
|
||||
boolean sideEffects = (flags & Block.UPDATE_SKIP_BLOCK_ENTITY_SIDEEFFECTS) == 0;
|
||||
|
||||
if (blockChanged && oldBlockState.hasBlockEntity()) {
|
||||
if (level instanceof ServerLevel && !(oldBlockState.getBlock() instanceof MovingPistonBlock)) {
|
||||
if (sideEffects) {
|
||||
BlockEntity blockEntity = level.getBlockEntity(blockPos_1);
|
||||
if (blockEntity != null) {
|
||||
blockEntity.preRemoveSideEffects(blockPos_1, oldBlockState);
|
||||
}
|
||||
}
|
||||
}
|
||||
removeBlockEntity(blockPos_1);
|
||||
}
|
||||
|
||||
if (blockChanged || newBlock instanceof BaseRailBlock)
|
||||
{
|
||||
if (level instanceof ServerLevel serverLevel && !(oldBlockState.getBlock() instanceof MovingPistonBlock))
|
||||
{
|
||||
if ((flags & Block.UPDATE_NEIGHBORS) != 0 || movedByPiston)
|
||||
{
|
||||
oldBlockState.affectNeighborsAfterRemoval(serverLevel, blockPos_1, movedByPiston);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (chunkSection.getBlockState(x, chunkY, z).getBlock() != newBlock)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (!level.isClientSide() && sideEffects) {
|
||||
// this updates stuff, schedule ticks - do we want that since its only be called from MovingPistonBlock really?
|
||||
newBlockState.onPlace(level, blockPos_1, oldBlockState, movedByPiston);
|
||||
}
|
||||
|
||||
BlockEntity oldBlockEntity = null;
|
||||
if (oldBlockState.hasBlockEntity())
|
||||
{
|
||||
oldBlockEntity = this.getBlockEntity(blockPos_1, LevelChunk.EntityCreationType.CHECK);
|
||||
if (oldBlockEntity != null)
|
||||
if (oldBlockEntity != null && !oldBlockEntity.isValidBlockState(oldBlockState))
|
||||
{
|
||||
oldBlockEntity.setBlockState(oldBlockState);
|
||||
updateBlockEntityTicker(oldBlockEntity);
|
||||
}
|
||||
}
|
||||
|
||||
if (oldBlockState.hasBlockEntity())
|
||||
else
|
||||
{
|
||||
if (newBlockEntity == null)
|
||||
{
|
||||
newBlockEntity = ((EntityBlock) newBlock).newBlockEntity(blockPos_1, newBlockState);
|
||||
if (newBlockEntity != null)
|
||||
{
|
||||
addAndRegisterBlockEntity(newBlockEntity);
|
||||
}
|
||||
}
|
||||
if (newBlockEntity != oldBlockEntity && newBlockEntity != null)
|
||||
{
|
||||
@@ -148,15 +188,9 @@ public abstract class LevelChunk_movableBEMixin extends ChunkAccess implements W
|
||||
updateBlockEntityTicker(newBlockEntity);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.level.isClientSide)
|
||||
{
|
||||
newBlockState.onPlace(this.level, blockPos_1, oldBlockState, boolean_1); //This can call setblockstate! (e.g. hopper does)
|
||||
}
|
||||
|
||||
this.unsaved = true; // shouldSave
|
||||
markUnsaved();
|
||||
return oldBlockState;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ public class LevelEntityGetterAdapter_scarpetMixin<T extends EntityAccess> imple
|
||||
|
||||
@Override
|
||||
public List<T> getChunkEntities(ChunkPos chpos) {
|
||||
return this.sectionStorage.getExistingSectionsInChunk(chpos.toLong()).flatMap(EntitySection::getEntities).collect(Collectors.toList());
|
||||
return this.sectionStorage.getExistingSectionsInChunk(chpos.pack()).flatMap(EntitySection::getEntities).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(LevelRenderer.class)
|
||||
@Mixin(Camera.class)
|
||||
public class LevelRenderer_creativeNoClipMixin
|
||||
{
|
||||
@Redirect(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;isSpectator()Z"))
|
||||
@Redirect(method = "extractRenderState", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;isSpectator()Z"))
|
||||
private boolean canSeeWorld(LocalPlayer clientPlayerEntity)
|
||||
{
|
||||
return clientPlayerEntity.isSpectator() || (CarpetSettings.creativeNoClip && clientPlayerEntity.isCreative());
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import net.minecraft.client.renderer.DimensionSpecialEffects;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
//import net.minecraft.world.dimension.Dimension;
|
||||
import net.minecraft.client.renderer.fog.environment.AtmosphericFogEnvironment;
|
||||
import net.minecraft.world.attribute.EnvironmentAttribute;
|
||||
import net.minecraft.world.attribute.EnvironmentAttributeProbe;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(value = LevelRenderer.class, priority = 69420)
|
||||
@Mixin(value = AtmosphericFogEnvironment.class, priority = 69420)
|
||||
public class LevelRenderer_fogOffMixin
|
||||
{
|
||||
@Redirect(method = "renderLevel", require = 0, expect = 0, at = @At(
|
||||
@Redirect(method = "setupFog", require = 0, expect = 0, at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/renderer/DimensionSpecialEffects;isFoggyAt(II)Z"
|
||||
target = "Lnet/minecraft/world/attribute/EnvironmentAttributeProbe;getValue(Lnet/minecraft/world/attribute/EnvironmentAttribute;F)Ljava/lang/Object;"
|
||||
))
|
||||
private boolean isReallyThick(DimensionSpecialEffects skyProperties, int x, int z)
|
||||
private <Value> Value isReallyThick(EnvironmentAttributeProbe instance, EnvironmentAttribute<Value> environmentAttribute, float f)
|
||||
{
|
||||
if (CarpetSettings.fogOff) return false;
|
||||
return skyProperties.isFoggyAt(x, z);
|
||||
if (CarpetSettings.fogOff) return environmentAttribute.defaultValue();
|
||||
return instance.getValue(environmentAttribute, f);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,18 +2,35 @@ package carpet.mixins;
|
||||
|
||||
import carpet.network.CarpetClient;
|
||||
import carpet.script.utils.ShapesRenderer;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Camera;
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.mojang.blaze3d.buffers.GpuBufferSlice;
|
||||
import com.mojang.blaze3d.framegraph.FrameGraphBuilder;
|
||||
import com.mojang.blaze3d.framegraph.FramePass;
|
||||
import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
|
||||
import net.minecraft.client.DeltaTracker;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import net.minecraft.client.renderer.LevelRenderer;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.LevelTargetBundle;
|
||||
import net.minecraft.client.renderer.RenderBuffers;
|
||||
import net.minecraft.client.renderer.ShaderManager;
|
||||
import net.minecraft.client.renderer.SubmitNodeCollector;
|
||||
import net.minecraft.client.renderer.SubmitNodeStorage;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderDispatcher;
|
||||
import org.joml.Matrix4f;
|
||||
import net.minecraft.client.renderer.feature.FeatureRenderDispatcher;
|
||||
import net.minecraft.client.renderer.state.GameRenderState;
|
||||
import net.minecraft.client.renderer.state.level.CameraRenderState;
|
||||
import net.minecraft.client.renderer.state.level.LevelRenderState;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.client.resources.model.sprite.AtlasManager;
|
||||
import org.joml.Matrix4fc;
|
||||
import org.joml.Vector4f;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@@ -21,30 +38,45 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
@Mixin(LevelRenderer.class)
|
||||
public class LevelRenderer_scarpetRenderMixin
|
||||
{
|
||||
@Shadow @Final private LevelTargetBundle targets;
|
||||
|
||||
@Shadow @Final private FeatureRenderDispatcher featureRenderDispatcher;
|
||||
|
||||
@Shadow @Final private RenderBuffers renderBuffers;
|
||||
|
||||
@Shadow @Final private LevelRenderState levelRenderState;
|
||||
|
||||
@Shadow @Final private SubmitNodeStorage submitNodeStorage;
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void addRenderers(Minecraft minecraft, EntityRenderDispatcher entityRenderDispatcher, BlockEntityRenderDispatcher blockEntityRenderDispatcher, RenderBuffers renderBuffers, CallbackInfo ci)
|
||||
private void addRenderers(EntityRenderDispatcher entityRenderDispatcher, BlockEntityRenderDispatcher blockEntityRenderDispatcher, ModelManager modelManager, TextureManager textureManager, AtlasManager atlasManager, ShaderManager shaderManager, GameRenderer gameRenderer, int width, int height, CallbackInfo ci)
|
||||
{
|
||||
CarpetClient.shapes = new ShapesRenderer(minecraft);
|
||||
CarpetClient.shapes = new ShapesRenderer(Minecraft.getInstance());
|
||||
}
|
||||
|
||||
@Inject(method = "renderLevel", at = @At(
|
||||
@Inject(method = "render", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/renderer/Sheets;translucentCullBlockSheet()Lnet/minecraft/client/renderer/RenderType;", shift = At.Shift.BEFORE
|
||||
//target = "Lnet/minecraft/client/render/RenderLayer;getWaterMask()Lnet/minecraft/client/render/RenderLayer;", shift = At.Shift.AFTER
|
||||
//target = "Lnet/minecraft/client/render/BufferBuilderStorage;getEffectVertexConsumers()Lnet/minecraft/client/render/VertexConsumerProvider$Immediate;", shift = At.Shift.BEFORE
|
||||
//target = "Lnet/minecraft/client/render/WorldRenderer;renderChunkDebugInfo(Lnet/minecraft/client/render/Camera;)V", shift = At.Shift.AFTER
|
||||
//target = "Lnet/minecraft/client/render/BackgroundRenderer;method_23792()V", shift = At.Shift.AFTER
|
||||
//target = "Lnet/minecraft/client/render/BufferBuilderStorage;getEntityVertexConsumers()Lnet/minecraft/client/render/VertexConsumerProvider$Immediate;", shift = At.Shift.AFTER
|
||||
//target = "Lnet/minecraft/client/render/WorldRenderer;renderChunkDebugInfo(Lnet/minecraft/client/render/Camera;)V", shift = At.Shift.AFTER // before return
|
||||
target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/feature/FeatureRenderDispatcher$PreparedFrame;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/util/profiling/ProfilerFiller;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V",
|
||||
//target = "Lnet/minecraft/client/renderer/LevelRenderer;addAlwaysOnTopPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;)V",
|
||||
//target = "Lnet/minecraft/client/renderer/LevelRenderer;submitFeatures(Lnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/client/renderer/SubmitNodeCollector;Z)V",
|
||||
//target = "Lnet/minecraft/client/renderer/LevelRenderer;addMainPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/util/profiling/ProfilerFiller;Lnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V",
|
||||
//target = "Lnet/minecraft/client/renderer/LevelRenderer;addLateDebugPass(Lcom/mojang/blaze3d/framegraph/FrameGraphBuilder;Lnet/minecraft/client/renderer/state/level/CameraRenderState;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lorg/joml/Matrix4fc;)V",
|
||||
shift = At.Shift.AFTER
|
||||
))
|
||||
private void renderScarpetThings(final DeltaTracker deltaTracker, final boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightmapTextureManager, Matrix4f modelViewMatrix, Matrix4f matrix4f, CallbackInfo ci)
|
||||
private void renderScarpetThingsLate(GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker, boolean renderOutline, CameraRenderState cameraState, Matrix4fc modelViewMatrix, GpuBufferSlice terrainFog, Vector4f fogColor, boolean shouldRenderSky, CallbackInfo ci, @Local FrameGraphBuilder frameGraphBuilder)
|
||||
//private void renderScarpetThinsLate(GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker, boolean renderOutline, CameraRenderState cameraState, Matrix4fc modelViewMatrix, GpuBufferSlice terrainFog, Vector4f fogColor, boolean shouldRenderSky, CallbackInfo ci, @Local FrameGraphBuilder frameGraphBuilder)
|
||||
{
|
||||
// in normal circumstances we want to render shapes at the very end so it appears correctly behind stuff.
|
||||
// we might actually not need to play with render hooks here.
|
||||
//if (!FabricAPIHooks.WORLD_RENDER_EVENTS && CarpetClient.shapes != null )
|
||||
if (CarpetClient.shapes != null)
|
||||
{
|
||||
CarpetClient.shapes.render(modelViewMatrix, camera, deltaTracker.getGameTimeDeltaPartialTick(false));
|
||||
final float deltaPartialTick = deltaTracker.getGameTimeDeltaPartialTick(false);
|
||||
FramePass pass = frameGraphBuilder.addPass("scarpet_shapes");
|
||||
targets.main = pass.readsAndWrites(targets.main);
|
||||
pass.executes(() -> CarpetClient.shapes.render(submitNodeStorage, levelRenderState, modelViewMatrix, deltaPartialTick));
|
||||
//featureRenderDispatcher.renderAllFeatures(submitNodeStorage);
|
||||
//renderBuffers.bufferSource().uploadAndDraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,11 +23,11 @@ public abstract class Level_fillUpdatesMixin
|
||||
|
||||
@Redirect(method = "setBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;II)Z", at = @At( //setBlockState main
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/level/Level;blockUpdated(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;)V"
|
||||
target = "Lnet/minecraft/world/level/Level;updateNeighborsAt(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/Block;)V"
|
||||
))
|
||||
private void updateNeighborsMaybe(Level world, BlockPos blockPos, Block block)
|
||||
{
|
||||
if (!CarpetSettings.impendingFillSkipUpdates.get()) world.blockUpdated(blockPos, block);
|
||||
if (!CarpetSettings.impendingFillSkipUpdates.get()) world.updateNeighborsAt(blockPos, block);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package carpet.mixins;
|
||||
|
||||
import carpet.fakes.LevelInterface;
|
||||
import com.google.common.collect.Lists;
|
||||
import net.minecraft.util.profiling.Profiler;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -9,9 +10,8 @@ import org.spongepowered.asm.mixin.Shadow;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Predicate;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.boss.EnderDragonPart;
|
||||
import net.minecraft.world.entity.boss.enderdragon.EnderDragonPart;
|
||||
import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.entity.LevelEntityGetter;
|
||||
@@ -24,7 +24,7 @@ public abstract class Level_getOtherEntitiesLimited implements LevelInterface {
|
||||
|
||||
@Override
|
||||
public List<Entity> getOtherEntitiesLimited(@Nullable Entity except, AABB box, Predicate<? super Entity> predicate, int limit) {
|
||||
this.getProfiler().incrementCounter("getEntities"); // visit
|
||||
Profiler.get().incrementCounter("getEntities"); // visit
|
||||
AtomicInteger checkedEntities = new AtomicInteger();
|
||||
List<Entity> list = Lists.newArrayList();
|
||||
try {
|
||||
@@ -55,9 +55,6 @@ public abstract class Level_getOtherEntitiesLimited implements LevelInterface {
|
||||
return list;
|
||||
}
|
||||
|
||||
@Shadow
|
||||
public abstract ProfilerFiller getProfiler();
|
||||
|
||||
@Shadow
|
||||
protected abstract LevelEntityGetter<Entity> getEntities();
|
||||
}
|
||||
@@ -4,8 +4,8 @@ import carpet.fakes.WorldChunkInterface;
|
||||
import carpet.fakes.LevelInterface;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.FullChunkStatus;
|
||||
import net.minecraft.util.profiling.Profiler;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
@@ -28,32 +28,18 @@ public abstract class Level_movableBEMixin implements LevelInterface, LevelAcces
|
||||
@Shadow
|
||||
public abstract LevelChunk getChunkAt(BlockPos blockPos_1);
|
||||
|
||||
@Shadow
|
||||
public abstract BlockState getBlockState(BlockPos blockPos_1);
|
||||
|
||||
//@Shadow
|
||||
//public abstract ChunkManager getChunkManager();
|
||||
|
||||
@Shadow
|
||||
public abstract void setBlocksDirty(BlockPos blockPos_1, BlockState s1, BlockState s2);
|
||||
|
||||
@Shadow
|
||||
public abstract void sendBlockUpdated(BlockPos var1, BlockState var2, BlockState var3, int var4);
|
||||
|
||||
@Shadow
|
||||
public abstract void updateNeighborsAt(BlockPos blockPos_1, Block block_1);
|
||||
|
||||
@Shadow
|
||||
public abstract void onBlockStateChange(BlockPos blockPos_1, BlockState blockState_1, BlockState blockState_2);
|
||||
|
||||
@Shadow public abstract ProfilerFiller getProfiler();
|
||||
|
||||
@Shadow public abstract void updateNeighbourForOutputSignal(BlockPos pos, Block block);
|
||||
|
||||
//@Shadow public abstract boolean setBlockState(BlockPos pos, BlockState state, int flags);
|
||||
|
||||
@Shadow public abstract boolean isDebug();
|
||||
|
||||
@Shadow public abstract void updatePOIOnBlockStateChange(final BlockPos blockPos, final BlockState blockState, final BlockState blockState2);
|
||||
|
||||
/**
|
||||
* @author 2No2Name
|
||||
*/
|
||||
@@ -67,7 +53,7 @@ public abstract class Level_movableBEMixin implements LevelInterface, LevelAcces
|
||||
BlockState blockState_2;
|
||||
if (newBlockEntity != null && block_1 instanceof EntityBlock)
|
||||
{
|
||||
blockState_2 = ((WorldChunkInterface) worldChunk_1).setBlockStateWithBlockEntity(blockPos_1, blockState_1, newBlockEntity, (int_1 & 64) != 0);
|
||||
blockState_2 = ((WorldChunkInterface) worldChunk_1).setBlockStateWithBlockEntity(blockPos_1, blockState_1, newBlockEntity, int_1);
|
||||
if (newBlockEntity instanceof LidBlockEntity)
|
||||
{
|
||||
scheduleTick(blockPos_1, block_1, 5);
|
||||
@@ -75,24 +61,15 @@ public abstract class Level_movableBEMixin implements LevelInterface, LevelAcces
|
||||
}
|
||||
else
|
||||
{
|
||||
blockState_2 = worldChunk_1.setBlockState(blockPos_1, blockState_1, (int_1 & 64) != 0);
|
||||
blockState_2 = worldChunk_1.setBlockState(blockPos_1, blockState_1, int_1);
|
||||
}
|
||||
|
||||
if (blockState_2 == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
BlockState blockState_3 = this.getBlockState(blockPos_1);
|
||||
|
||||
if (blockState_3 != blockState_2 && (blockState_3.getLightBlock((BlockGetter) this, blockPos_1) != blockState_2.getLightBlock((BlockGetter) this, blockPos_1) || blockState_3.getLightEmission() != blockState_2.getLightEmission() || blockState_3.useShapeForLightOcclusion() || blockState_2.useShapeForLightOcclusion()))
|
||||
{
|
||||
ProfilerFiller profiler = getProfiler();
|
||||
profiler.push("queueCheckLight");
|
||||
this.getChunkSource().getLightEngine().checkBlock(blockPos_1);
|
||||
profiler.pop();
|
||||
}
|
||||
BlockState blockState_3 = this.getBlockState(blockPos_1);
|
||||
|
||||
if (blockState_3 == blockState_1)
|
||||
{
|
||||
@@ -122,9 +99,8 @@ public abstract class Level_movableBEMixin implements LevelInterface, LevelAcces
|
||||
blockState_1.updateNeighbourShapes(this, blockPos_1, int_2); // updateNeighbours
|
||||
blockState_1.updateIndirectNeighbourShapes(this, blockPos_1, int_2); // prepare
|
||||
}
|
||||
this.onBlockStateChange(blockPos_1, blockState_2, blockState_3);
|
||||
updatePOIOnBlockStateChange(blockPos_1, blockState_2, blockState_3);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package carpet.mixins;
|
||||
|
||||
import carpet.fakes.LevelInterface;
|
||||
import carpet.utils.CarpetProfiler;
|
||||
import net.minecraft.world.level.redstone.NeighborUpdater;
|
||||
import net.minecraft.world.level.redstone.CollectingNeighborUpdater;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
@@ -22,7 +22,7 @@ import net.minecraft.world.level.Level;
|
||||
public abstract class Level_tickMixin implements LevelInterface
|
||||
{
|
||||
@Shadow @Final public boolean isClientSide;
|
||||
@Shadow @Final protected NeighborUpdater neighborUpdater;
|
||||
@Shadow @Final protected CollectingNeighborUpdater neighborUpdater;
|
||||
CarpetProfiler.ProfilerToken currentSection;
|
||||
CarpetProfiler.ProfilerToken entitySection;
|
||||
|
||||
@@ -30,7 +30,7 @@ public abstract class Level_tickMixin implements LevelInterface
|
||||
|
||||
@Override
|
||||
@Unique
|
||||
public NeighborUpdater getNeighborUpdater() {
|
||||
public CollectingNeighborUpdater getNeighborUpdater() {
|
||||
return this.neighborUpdater;
|
||||
}
|
||||
|
||||
|
||||
Loaded 100 of 264 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user