mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 11:06:11 -10:00
Merge pull request #11561 from rdbtCVS/agent/rdbtcvs/one-rust-version
🤖 Agent: one workspace rust-version (1.95, which horizon-mods already needed); the second commit is clippy's let-chain/as_chunks/is_multiple_of rewrites, all on unsigned values with non-zero divisors, so no behaviour moves.
This commit is contained in:
100 files changed
+459
-446
No files matched your search
+1
-1
@@ -47,7 +47,7 @@ resolver = "2"
|
||||
[workspace.package]
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
rust-version = "1.85"
|
||||
rust-version = "1.95"
|
||||
|
||||
# Ports mirror vanilla's Java signatures, index loops and nested generic types
|
||||
# one to one so they can be checked against the decompiled sources.
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "cargo-horizon-mod"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.86"
|
||||
rust-version.workspace = true
|
||||
description = "cargo horizon-mod new/build/run/check: make Horizon content mods (docs/mods.md)"
|
||||
|
||||
# `cargo binstall --git https://github.com/horizon-rust/horizon cargo-horizon-mod` (#2120) reads this: the archive
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-anticheat"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.85"
|
||||
rust-version.workspace = true
|
||||
description = "The dedicated server's anticheat: its [anticheat] settings, violation levels and the checks' rules, with no game state (docs/anticheat.md)"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -179,19 +179,19 @@ impl Condition {
|
||||
let fields = object(raw)?;
|
||||
if fields.len() == 1 {
|
||||
for name in ["OR", "AND"] {
|
||||
if let Some(raw) = fields.get(name) {
|
||||
if let Ok(values) = array(raw).and_then(|values| {
|
||||
if let Some(raw) = fields.get(name)
|
||||
&& let Ok(values) = array(raw).and_then(|values| {
|
||||
values
|
||||
.into_iter()
|
||||
.map(Self::decode)
|
||||
.collect::<Result<Vec<_>>>()
|
||||
}) {
|
||||
return Ok(if name == "OR" {
|
||||
Self::Or(values)
|
||||
} else {
|
||||
Self::And(values)
|
||||
});
|
||||
}
|
||||
})
|
||||
{
|
||||
return Ok(if name == "OR" {
|
||||
Self::Or(values)
|
||||
} else {
|
||||
Self::And(values)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "horizon-bench"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
rust-version.workspace = true
|
||||
license = "MIT"
|
||||
description = "The benchmark report format (docs/benchmark-report.md), shared by the game, the launcher and the upload"
|
||||
|
||||
|
||||
@@ -694,7 +694,7 @@ fn costly(
|
||||
Behaviour::FloodUse => {
|
||||
// A block within reach: place stone there, or break what is there.
|
||||
let at = [0, 1, 2].map(|k| block[k] + (random.unit() * 7.0) as i32 - 3);
|
||||
if i % 2 == 0 {
|
||||
if i.is_multiple_of(2) {
|
||||
play::Serverbound::UseItemOn(play::UseItemOn {
|
||||
hand: 0,
|
||||
pos: at,
|
||||
@@ -723,7 +723,7 @@ fn costly(
|
||||
carried: None,
|
||||
}),
|
||||
Behaviour::FloodSuggest => {
|
||||
let text = if i % 2 == 0 {
|
||||
let text = if i.is_multiple_of(2) {
|
||||
"/"
|
||||
} else {
|
||||
LONG_COMMAND.as_str()
|
||||
@@ -1555,10 +1555,10 @@ fn main() {
|
||||
});
|
||||
if o.report.as_deref() == Some("-") {
|
||||
println!("{summary:#}");
|
||||
} else if let Some(path) = &o.report {
|
||||
if let Err(e) = std::fs::write(path, format!("{summary:#}\n")) {
|
||||
eprintln!("horizon-bots: {path}: {e}");
|
||||
}
|
||||
} else if let Some(path) = &o.report
|
||||
&& let Err(e) = std::fs::write(path, format!("{summary:#}\n"))
|
||||
{
|
||||
eprintln!("horizon-bots: {path}: {e}");
|
||||
}
|
||||
let errors: Vec<String> = bots
|
||||
.iter()
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-chat-filter"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.88"
|
||||
rust-version.workspace = true
|
||||
description = "The dedicated server's chat filter: its [chat_filter] settings, the slur list's matcher and the mutes, with no game state (docs/chat-filter.md)"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-client-core"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.90"
|
||||
rust-version.workspace = true
|
||||
description = "The client's lowest layer: chat text and translations, SNBT and NBT paths, the scoreboard, boss bars, game rules and the registry and particle tables commands name"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-client-input"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.90"
|
||||
rust-version.workspace = true
|
||||
description = "The client's input layer: key bindings and their names, mouse, controllers, clipboard and window options"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -6,7 +6,7 @@ autotests = false
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.90"
|
||||
rust-version.workspace = true
|
||||
description = "Reusable client systems, control tool and parity probes"
|
||||
|
||||
[lib]
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-client-render"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.90"
|
||||
rust-version.workspace = true
|
||||
description = "The client's world data, rendering and screens: chunks, meshing, light, streaming, the renderer, the HUD, menus and settings; no gameplay"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -4,7 +4,7 @@ default-run = "horizon-client"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.90"
|
||||
rust-version.workspace = true
|
||||
description = "Horizon native development client"
|
||||
autobins = false
|
||||
autoexamples = false
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-command"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.90"
|
||||
rust-version.workspace = true
|
||||
description = "Commands (Brigadier): the vanilla command tree, argument types, selectors, parsing, suggestions and the network form of the tree"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -162,10 +162,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let key = (number(&mut input), number(&mut input));
|
||||
let time = number(&mut input);
|
||||
if let Some(c) = access.containers_mut().chunks.get_mut(&key) {
|
||||
if op == "promote" {
|
||||
if let Container::Proto(proto) = c {
|
||||
*c = Container::Level(ChunkTicks::from_saved(proto.scheduled_ticks()));
|
||||
}
|
||||
if op == "promote"
|
||||
&& let Container::Proto(proto) = c
|
||||
{
|
||||
*c = Container::Level(ChunkTicks::from_saved(proto.scheduled_ticks()));
|
||||
}
|
||||
if let Container::Level(c) = c {
|
||||
c.unpack(time);
|
||||
|
||||
@@ -61,8 +61,10 @@ fn read(strategy: Strategy, bytes: &[u8]) -> PalettedContainer {
|
||||
Vec::new()
|
||||
};
|
||||
let words = bytes[at..]
|
||||
.chunks_exact(8)
|
||||
.map(|c| u64::from_be_bytes(c.try_into().unwrap()))
|
||||
.as_chunks::<8>()
|
||||
.0
|
||||
.iter()
|
||||
.map(|c| u64::from_be_bytes(*c))
|
||||
.collect();
|
||||
PalettedContainer::from_wire(strategy, bits, palette, words).unwrap()
|
||||
}
|
||||
|
||||
@@ -36,7 +36,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut buffer = vec![0_u8; 1 << 20];
|
||||
while remaining > 0 {
|
||||
let entries = remaining.min((buffer.len() / 4) as u64) as usize;
|
||||
for (offset, bytes) in buffer[..entries * 4].chunks_exact_mut(4).enumerate() {
|
||||
for (offset, bytes) in buffer[..entries * 4]
|
||||
.as_chunks_mut::<4>()
|
||||
.0
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
{
|
||||
let bits = (start + offset as u64) as u32;
|
||||
let value = sampler.sample_value(&mut context, [bits as i32, 0, 0])?;
|
||||
let result = if value.is_nan() {
|
||||
|
||||
@@ -82,12 +82,14 @@ fn utf16(token: &str) -> Result<Vec<u16>, String> {
|
||||
if token == "-" {
|
||||
return Ok(Vec::new());
|
||||
}
|
||||
if token.len() % 4 != 0 {
|
||||
if !token.len().is_multiple_of(4) {
|
||||
return Err("invalid UTF-16 hex".to_owned());
|
||||
}
|
||||
token
|
||||
.as_bytes()
|
||||
.chunks_exact(4)
|
||||
.as_chunks::<4>()
|
||||
.0
|
||||
.iter()
|
||||
.map(|part| {
|
||||
u16::from_str_radix(
|
||||
std::str::from_utf8(part).map_err(|_| "invalid UTF-16 hex")?,
|
||||
|
||||
@@ -101,10 +101,10 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
"restore" => {
|
||||
let pos = input.chunk()?;
|
||||
if level.chunk(pos).is_none() {
|
||||
if let Some(chunk) = detached.remove(&pos) {
|
||||
level.add_chunk(pos, chunk)?;
|
||||
}
|
||||
if level.chunk(pos).is_none()
|
||||
&& let Some(chunk) = detached.remove(&pos)
|
||||
{
|
||||
level.add_chunk(pos, chunk)?;
|
||||
}
|
||||
}
|
||||
"enable" => {
|
||||
|
||||
@@ -95,10 +95,10 @@ impl DensitySampler for CachingDensitySampler {
|
||||
if cell.value_key == key && !cell.value.is_nan() {
|
||||
return Ok(cell.value);
|
||||
}
|
||||
if let Some(volume) = cell.volume {
|
||||
if let Some(index) = volume.index_of_block(position) {
|
||||
return Ok(cell.buffer[index]);
|
||||
}
|
||||
if let Some(volume) = cell.volume
|
||||
&& let Some(index) = volume.index_of_block(position)
|
||||
{
|
||||
return Ok(cell.buffer[index]);
|
||||
}
|
||||
cell.active = true;
|
||||
let result = self.input.sample_value(context, position);
|
||||
|
||||
@@ -415,10 +415,9 @@ impl DensityGraph {
|
||||
input,
|
||||
holder: Some(holder),
|
||||
} = node
|
||||
&& self.holders.get(holder.0) != Some(&input)
|
||||
{
|
||||
if self.holders.get(holder.0) != Some(&input) {
|
||||
return Err(CompileError::UnknownHolder);
|
||||
}
|
||||
return Err(CompileError::UnknownHolder);
|
||||
}
|
||||
if let GraphNode::Noise { noise, .. } | GraphNode::OffsetNoise { noise, .. } = node {
|
||||
self.noise_entry(noise)?;
|
||||
@@ -428,10 +427,9 @@ impl DensityGraph {
|
||||
branches,
|
||||
..
|
||||
} = &node
|
||||
&& (branches.len() != thresholds.len().saturating_add(1) || branches.len() > 256)
|
||||
{
|
||||
if branches.len() != thresholds.len().saturating_add(1) || branches.len() > 256 {
|
||||
return Err(CompileError::InvalidIntervals);
|
||||
}
|
||||
return Err(CompileError::InvalidIntervals);
|
||||
}
|
||||
// Fastutil threshold lists compare zeros numerically but hash their
|
||||
// signed bits. Among equal definitions, the only possible hash delta
|
||||
|
||||
@@ -150,7 +150,7 @@ fn end_islands_use_the_world_seed_independently_of_the_noise_algorithm() {
|
||||
sampler
|
||||
.sample_volume(&mut SamplerContext::default(), &mut output, volume)
|
||||
.unwrap();
|
||||
for column in output[..volume.size()].chunks_exact(4) {
|
||||
for column in output[..volume.size()].as_chunks::<4>().0 {
|
||||
assert!(column.iter().all(|&value| value == column[0]));
|
||||
}
|
||||
assert_eq!(output[volume.size()], 17.0);
|
||||
@@ -321,8 +321,8 @@ fn spline_coordinates_share_bulk_evaluation_after_graph_rewriting() {
|
||||
.sample_volume(&mut SamplerContext::default(), &mut output, volume)
|
||||
.unwrap();
|
||||
assert_eq!(trace.0.lock().unwrap().len(), 1);
|
||||
for column in output.chunks_exact(3) {
|
||||
assert_eq!(column, [2.0, 3.0, 4.0]);
|
||||
for column in output.as_chunks::<3>().0 {
|
||||
assert_eq!(*column, [2.0, 3.0, 4.0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -544,8 +544,8 @@ fn compiler_reduces_uniform_axes_and_preserves_strided_vertical_samples() {
|
||||
*trace.0.lock().unwrap(),
|
||||
vec![DensityVolume::new([1, 4, 1], [0, -7, 0], [2, 3, 5]).unwrap()]
|
||||
);
|
||||
for column in output[..volume.size()].chunks_exact(4) {
|
||||
assert_eq!(column, [-7.0, -4.0, -1.0, 2.0]);
|
||||
for column in output[..volume.size()].as_chunks::<4>().0 {
|
||||
assert_eq!(*column, [-7.0, -4.0, -1.0, 2.0]);
|
||||
}
|
||||
assert_eq!(output[volume.size()], 17.0);
|
||||
assert_eq!(compiler.graph().domain_axes(root), Ok(2));
|
||||
|
||||
@@ -230,7 +230,7 @@ fn shift_b_repeats_each_horizontal_sample_and_preserves_tail() {
|
||||
sampler
|
||||
.sample_volume(&mut context, &mut buffer, volume)
|
||||
.unwrap();
|
||||
for column in buffer[..volume.size()].chunks_exact(3) {
|
||||
for column in buffer[..volume.size()].as_chunks::<3>().0 {
|
||||
assert!(column.iter().all(|v| v.to_bits() == column[0].to_bits()));
|
||||
}
|
||||
assert_eq!(&buffer[volume.size()..], &[19.0, 19.0]);
|
||||
|
||||
@@ -18,12 +18,9 @@ impl FxHasher {
|
||||
impl Hasher for FxHasher {
|
||||
#[inline]
|
||||
fn write(&mut self, bytes: &[u8]) {
|
||||
let words = bytes.chunks_exact(8);
|
||||
let rest = words.remainder();
|
||||
let (words, rest) = bytes.as_chunks::<8>();
|
||||
for word in words {
|
||||
let mut w = [0u8; 8];
|
||||
w.copy_from_slice(word);
|
||||
self.add(u64::from_le_bytes(w));
|
||||
self.add(u64::from_le_bytes(*word));
|
||||
}
|
||||
if !rest.is_empty() {
|
||||
let mut word = [0u8; 8];
|
||||
|
||||
@@ -505,7 +505,7 @@ impl PalettedContainer {
|
||||
// Four bits a linear palette's usual width: a whole word of them is a
|
||||
// row of 16, and immediate shifts for the compiler to unroll.
|
||||
if self.bits == 4 {
|
||||
for (row, &word) in out.chunks_exact_mut(16).zip(&self.words) {
|
||||
for (row, &word) in out.as_chunks_mut::<16>().0.iter_mut().zip(&self.words) {
|
||||
for (x, cell) in row.iter_mut().enumerate() {
|
||||
*cell = map[((word >> (x * 4)) & 0xF) as usize];
|
||||
}
|
||||
@@ -1273,8 +1273,8 @@ mod tests {
|
||||
let y = i >> 8;
|
||||
let r = rng(&mut state);
|
||||
terrain.push(match y {
|
||||
0..=8 if r % 40 == 0 => 2000 + (r >> 8) as u32 % 6,
|
||||
0..=8 if r % 13 == 0 => 0,
|
||||
0..=8 if r.is_multiple_of(40) => 2000 + (r >> 8) as u32 % 6,
|
||||
0..=8 if r.is_multiple_of(13) => 0,
|
||||
0..=8 => 1,
|
||||
9..=10 => 10,
|
||||
11 => 9,
|
||||
|
||||
@@ -140,7 +140,9 @@ impl PreparedFiles {
|
||||
return Ok(None);
|
||||
};
|
||||
let entries: Box<[Entry]> = raw_entries
|
||||
.chunks_exact(ENTRY)
|
||||
.as_chunks::<ENTRY>()
|
||||
.0
|
||||
.iter()
|
||||
.map(|e| {
|
||||
let at = |i: usize, n: usize| {
|
||||
let mut b = [0; 8];
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "horizon-cosmetics"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
rust-version.workspace = true
|
||||
license = "MIT"
|
||||
description = "Cosmetic items drawn on players by Horizon clients: the item format, attachment to the player model's bones, simple animations, and what other players wear (fetched and cached)"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-dualsense"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.85"
|
||||
rust-version.workspace = true
|
||||
description = "The DualSense's output over HID: rumble, adaptive triggers, lightbar and player LEDs"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "horizon-friends"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
rust-version.workspace = true
|
||||
license = "MIT"
|
||||
description = "Play with friends: invite codes, the relay protocol, the end-to-end encrypted tunnel between a host's integrated server and its guests"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-hdr"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.85"
|
||||
rust-version.workspace = true
|
||||
description = "HDR metadata for the swapchain: the Vulkan calls the crates that forbid unsafe code can't make"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-items"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.90"
|
||||
rust-version.workspace = true
|
||||
description = "Blocks and items as the client knows them: block facts, item stacks and their data components, enchantments, cooldowns, bundles, and items in NBT"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-mcp"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.88"
|
||||
rust-version.workspace = true
|
||||
description = "The Model Context Protocol, one implementation for Horizon's three servers (horizon-ctl mcp, horizon-server mcp, horizon-launcher mcp)"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "horizon-mod-api-gen"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
license.workspace = true
|
||||
publish = false
|
||||
description = "Build-time typed native mod API generation"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "horizon-mod-api-gen-tests"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
license.workspace = true
|
||||
publish = false
|
||||
description = "Generated mod API dispatch contract tests"
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-mods"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.95"
|
||||
rust-version.workspace = true
|
||||
description = "Horizon's mod files: content mods, modpacks and the registry index (docs/mods.md)"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-narrator"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.85"
|
||||
rust-version.workspace = true
|
||||
description = "The narrator: vanilla's text-to-speech (GameNarrator, com.mojang.text2speech) and screen narration state"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -178,10 +178,11 @@ impl GameNarrator {
|
||||
self.sink.as_mut().is_some_and(|sink| sink.active())
|
||||
}
|
||||
pub fn clear(&mut self) {
|
||||
if self.status != Status::Off && self.is_active() {
|
||||
if let Some(sink) = &mut self.sink {
|
||||
sink.clear();
|
||||
}
|
||||
if self.status != Status::Off
|
||||
&& self.is_active()
|
||||
&& let Some(sink) = &mut self.sink
|
||||
{
|
||||
sink.clear();
|
||||
}
|
||||
}
|
||||
pub fn recent(&self) -> Vec<String> {
|
||||
|
||||
@@ -620,7 +620,7 @@ impl Emit {
|
||||
}
|
||||
Node::If(args) => {
|
||||
let mut ends = Vec::new();
|
||||
for pair in args.chunks_exact(2) {
|
||||
for pair in args.as_chunks::<2>().0 {
|
||||
self.node(&pair[0]);
|
||||
let next = self.here();
|
||||
self.push(Op::JumpIfZero(0), -1);
|
||||
|
||||
@@ -344,14 +344,14 @@ impl ComponentTest {
|
||||
};
|
||||
// Enchantments were `{levels: {id: level}}` until 1.21.5 and are the bare map since, as
|
||||
// OptiFine's doc still writes them (`components.enchantments.levels.~thorns`).
|
||||
if let Source::Component(id) = &source {
|
||||
if matches!(
|
||||
if let Source::Component(id) = &source
|
||||
&& matches!(
|
||||
&**id,
|
||||
"minecraft:enchantments" | "minecraft:stored_enchantments"
|
||||
) && path.first().is_some_and(|s| s == "levels")
|
||||
{
|
||||
path.remove(0);
|
||||
}
|
||||
)
|
||||
&& path.first().is_some_and(|s| s == "levels")
|
||||
{
|
||||
path.remove(0);
|
||||
}
|
||||
let (value, negate) = ValueTest::parse(value)?;
|
||||
Some(Self {
|
||||
@@ -743,10 +743,9 @@ fn asset(
|
||||
if let Some((ns, rest)) = resolved
|
||||
.strip_prefix("assets/")
|
||||
.and_then(|p| p.split_once('/'))
|
||||
&& !rest.starts_with(&format!("{typed}/"))
|
||||
{
|
||||
if !rest.starts_with(&format!("{typed}/")) {
|
||||
candidates.push(format!("assets/{ns}/{typed}/{rest}"));
|
||||
}
|
||||
candidates.push(format!("assets/{ns}/{typed}/{rest}"));
|
||||
}
|
||||
if !value.contains(':') {
|
||||
candidates.push(format!("{dir}/{value}"));
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-port-pack"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.86"
|
||||
rust-version.workspace = true
|
||||
description = "Port a Java modpack to Horizon: import, inventory, classification and data carry-over (docs/modpacks.md)"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -309,10 +309,10 @@ impl Local {
|
||||
fn index(dir: &Path) -> Local {
|
||||
let mut local = Local::default();
|
||||
local.walk(dir, 3);
|
||||
if let Ok(text) = fs::read_to_string(dir.join("minecraftinstance.json")) {
|
||||
if let Ok(v) = serde_json::from_str::<Value>(&text) {
|
||||
local.curseforge = curseforge_names(&v);
|
||||
}
|
||||
if let Ok(text) = fs::read_to_string(dir.join("minecraftinstance.json"))
|
||||
&& let Ok(v) = serde_json::from_str::<Value>(&text)
|
||||
{
|
||||
local.curseforge = curseforge_names(&v);
|
||||
}
|
||||
local
|
||||
}
|
||||
|
||||
@@ -307,11 +307,10 @@ fn instance(dir: &Path) -> Result<Pack, String> {
|
||||
}
|
||||
// A CurseForge app instance has no `mmc-pack.json`; fill only when that
|
||||
// file gave no Minecraft version, so Prism behaviour is unchanged.
|
||||
if pack.minecraft.is_empty() {
|
||||
if let Some((minecraft, loader, loader_version)) = curseforge_instance_target(dir) {
|
||||
(pack.minecraft, pack.loader, pack.loader_version) =
|
||||
(minecraft, loader, loader_version);
|
||||
}
|
||||
if pack.minecraft.is_empty()
|
||||
&& let Some((minecraft, loader, loader_version)) = curseforge_instance_target(dir)
|
||||
{
|
||||
(pack.minecraft, pack.loader, pack.loader_version) = (minecraft, loader, loader_version);
|
||||
}
|
||||
let game = game_dir(dir)?;
|
||||
let mods = if game.join("mods").is_dir() {
|
||||
|
||||
@@ -75,19 +75,19 @@ pub(super) fn feature(v: &Value, report: &mut Report) -> Value {
|
||||
fn nested(v: &mut Value, report: &mut Report) {
|
||||
match v {
|
||||
Value::Object(o) => {
|
||||
if let Some(t) = kind(&Value::Object(o.clone())) {
|
||||
if let Some(to) = provider(t) {
|
||||
if t == "simple_state_provider" {
|
||||
// A direct provider is a state object: a bare string
|
||||
// would name a provider in its registry instead.
|
||||
*v = match o.get("state").cloned().unwrap_or_default() {
|
||||
id @ Value::String(_) => json!({"id": id}),
|
||||
state => state,
|
||||
};
|
||||
return;
|
||||
}
|
||||
o.insert("type".into(), vanilla(to));
|
||||
if let Some(t) = kind(&Value::Object(o.clone()))
|
||||
&& let Some(to) = provider(t)
|
||||
{
|
||||
if t == "simple_state_provider" {
|
||||
// A direct provider is a state object: a bare string
|
||||
// would name a provider in its registry instead.
|
||||
*v = match o.get("state").cloned().unwrap_or_default() {
|
||||
id @ Value::String(_) => json!({"id": id}),
|
||||
state => state,
|
||||
};
|
||||
return;
|
||||
}
|
||||
o.insert("type".into(), vanilla(to));
|
||||
}
|
||||
// An inline placed feature: {feature, placement}.
|
||||
if o.contains_key("placement") && o.contains_key("feature") {
|
||||
|
||||
@@ -614,10 +614,10 @@ fn moogs_spacing(p: &mut Value, lost: &mut BTreeMap<String, usize>) {
|
||||
let separation = scaled("separation").min(spacing - 1);
|
||||
p["spacing"] = spacing.into();
|
||||
p["separation"] = separation.into();
|
||||
if let Some(o) = p.as_object_mut() {
|
||||
if o.remove("when_replacing").is_some() {
|
||||
*lost.entry("when_replacing".into()).or_default() += 1;
|
||||
}
|
||||
if let Some(o) = p.as_object_mut()
|
||||
&& o.remove("when_replacing").is_some()
|
||||
{
|
||||
*lost.entry("when_replacing".into()).or_default() += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -798,10 +798,10 @@ pub fn loader_biome_tags(work: &Path) -> BTreeMap<String, Value> {
|
||||
continue;
|
||||
};
|
||||
let declared = entry.size();
|
||||
if let Ok(text) = budget.read_text(&mut entry, declared, crate::entry::MAX_TEXT) {
|
||||
if let Ok(v) = serde_json::from_str(&text) {
|
||||
out.insert(path, v);
|
||||
}
|
||||
if let Ok(text) = budget.read_text(&mut entry, declared, crate::entry::MAX_TEXT)
|
||||
&& let Ok(v) = serde_json::from_str(&text)
|
||||
{
|
||||
out.insert(path, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "horizon-prepare"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
rust-version.workspace = true
|
||||
license = "MIT"
|
||||
description = "Prepares Horizon's resources from the player's own Minecraft: imports and checks the pinned jars, runs the vanilla exporters, writes the resource folder"
|
||||
|
||||
|
||||
@@ -16,7 +16,9 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
let bytes = hex
|
||||
.as_bytes()
|
||||
.chunks_exact(2)
|
||||
.as_chunks::<2>()
|
||||
.0
|
||||
.iter()
|
||||
.map(|pair| {
|
||||
u8::from_str_radix(std::str::from_utf8(pair)?, 16).map_err(Box::<dyn Error>::from)
|
||||
})
|
||||
|
||||
@@ -17,7 +17,9 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
let bytes = hex
|
||||
.as_bytes()
|
||||
.chunks_exact(2)
|
||||
.as_chunks::<2>()
|
||||
.0
|
||||
.iter()
|
||||
.map(|pair| {
|
||||
u8::from_str_radix(std::str::from_utf8(pair)?, 16).map_err(Box::<dyn Error>::from)
|
||||
})
|
||||
|
||||
@@ -73,10 +73,10 @@ fn append(tag: &Tag, lang: &Language, out: &mut String, depth: usize) {
|
||||
out.push_str(lang.get(&key).map_or(key.as_str(), String::as_str));
|
||||
} else if let Some(selector) = get(tag, "selector").and_then(string) {
|
||||
out.push_str(&selector);
|
||||
} else if let Some(score) = get(tag, "score") {
|
||||
if let Some(name) = get(score, "name").and_then(string) {
|
||||
out.push_str(&name);
|
||||
}
|
||||
} else if let Some(score) = get(tag, "score")
|
||||
&& let Some(name) = get(score, "name").and_then(string)
|
||||
{
|
||||
out.push_str(&name);
|
||||
}
|
||||
if let Some(Tag::List(extra)) = get(tag, "extra") {
|
||||
for e in extra {
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-release-sign"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.85"
|
||||
rust-version.workspace = true
|
||||
description = "Signed release checksums: release.yml signs SHA256SUMS, the launcher and horizon-server check them before installing"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-server-files"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.90"
|
||||
rust-version.workspace = true
|
||||
description = "The dedicated server's vanilla files: server.properties, eula.txt, ops, whitelist and bans, and account lookups"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-server"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.90"
|
||||
rust-version.workspace = true
|
||||
description = "Host a Horizon server: server.toml, the CLI and the supervisor that runs the game headless (docs/server.md)"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-shader-api"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.85"
|
||||
rust-version.workspace = true
|
||||
description = "Horizon's own shader packs (WGSL, docs/shaders.md): the format, the stages, the check, and the horizon-shader tool"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-shaders"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.85"
|
||||
rust-version.workspace = true
|
||||
description = "Shader packs (the shaders/ folder format): reading packs, their .properties and .lang files, and later their GLSL"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -216,12 +216,16 @@ pub fn decode_png(bytes: &[u8]) -> Option<Texture> {
|
||||
let rgba: Vec<f32> = match info.color_type {
|
||||
png::ColorType::Rgba => pixels.iter().map(|&b| b as f32 / 255.0).collect(),
|
||||
png::ColorType::Rgb => pixels
|
||||
.chunks_exact(3)
|
||||
.as_chunks::<3>()
|
||||
.0
|
||||
.iter()
|
||||
.flat_map(|p| [p[0], p[1], p[2], 255])
|
||||
.map(|b| b as f32 / 255.0)
|
||||
.collect(),
|
||||
png::ColorType::GrayscaleAlpha => pixels
|
||||
.chunks_exact(2)
|
||||
.as_chunks::<2>()
|
||||
.0
|
||||
.iter()
|
||||
.flat_map(|p| [p[0], p[0], p[0], p[1]])
|
||||
.map(|b| b as f32 / 255.0)
|
||||
.collect(),
|
||||
|
||||
@@ -413,12 +413,11 @@ impl Stage<'_> {
|
||||
// `T x[] = T[](a, b)`: naga gives unsized arrays no size, so the count is written in.
|
||||
if t == "["
|
||||
&& let Some(close) = next(i).filter(|&j| self.tokens[j] == "]")
|
||||
&& let Some(n) = self.array_length(close)
|
||||
{
|
||||
if let Some(n) = self.array_length(close) {
|
||||
write!(out, "[{n}]").unwrap();
|
||||
skip_until = close + 1;
|
||||
continue;
|
||||
}
|
||||
write!(out, "[{n}]").unwrap();
|
||||
skip_until = close + 1;
|
||||
continue;
|
||||
}
|
||||
if !is_ident(t) {
|
||||
out.push_str(t);
|
||||
@@ -434,19 +433,21 @@ impl Stage<'_> {
|
||||
continue;
|
||||
}
|
||||
// A function definition's sampler parameters: `sampler2D s` → `texture2D s, sampler hz_s_s`.
|
||||
if depth == 0 && is_sampler_type(t) && calls.len() == 1 {
|
||||
if let Some(n) = next(i).filter(|&n| is_ident(self.tokens[n])) {
|
||||
let name = self.tokens[n];
|
||||
let (texture, sampler) = split_sampler(t);
|
||||
write!(out, "{texture} {name}, {sampler} hz_s_{name}").unwrap();
|
||||
if t == "sampler2D" && depth_params.contains(&(calls[0].0, calls[0].2)) {
|
||||
write!(out, ", float hz_l_{name}").unwrap();
|
||||
depth_scope.push(name);
|
||||
}
|
||||
params.insert(name.to_owned(), t.to_owned());
|
||||
skip_until = n + 1;
|
||||
continue;
|
||||
if depth == 0
|
||||
&& is_sampler_type(t)
|
||||
&& calls.len() == 1
|
||||
&& let Some(n) = next(i).filter(|&n| is_ident(self.tokens[n]))
|
||||
{
|
||||
let name = self.tokens[n];
|
||||
let (texture, sampler) = split_sampler(t);
|
||||
write!(out, "{texture} {name}, {sampler} hz_s_{name}").unwrap();
|
||||
if t == "sampler2D" && depth_params.contains(&(calls[0].0, calls[0].2)) {
|
||||
write!(out, ", float hz_l_{name}").unwrap();
|
||||
depth_scope.push(name);
|
||||
}
|
||||
params.insert(name.to_owned(), t.to_owned());
|
||||
skip_until = n + 1;
|
||||
continue;
|
||||
}
|
||||
// `float specular`: a variable of the same name as a sampler or a sampler parameter,
|
||||
// from the end of its initializer to the function's end; `.specular` a member.
|
||||
|
||||
@@ -38,8 +38,10 @@ fn words(p: &horizon_shaders::Program, name: &str, n: usize) -> Vec<u32> {
|
||||
.unwrap()
|
||||
.offset as usize;
|
||||
p.interface.initial_values[offset..offset + n * 4]
|
||||
.chunks_exact(4)
|
||||
.map(|b| u32::from_le_bytes(b.try_into().unwrap()))
|
||||
.as_chunks::<4>()
|
||||
.0
|
||||
.iter()
|
||||
.map(|b| u32::from_le_bytes(*b))
|
||||
.collect()
|
||||
}
|
||||
#[test]
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-telemetry"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.90"
|
||||
rust-version.workspace = true
|
||||
description = "Opt-in data collection: the player's consent, the payloads, the local outbox and its upload"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "horizon-theme"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
rust-version.workspace = true
|
||||
license = "MIT"
|
||||
description = "Horizon's design tokens, fonts and icons, shared by the launcher, the website and the game's menus"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ name = "horizon-threads"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version = "1.85"
|
||||
rust-version.workspace = true
|
||||
description = "Scheduling hints for the game's threads and its allocator, and the other OS calls the crates that forbid unsafe code can't make"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@@ -93,10 +93,10 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
}
|
||||
assert!(InteractionShapes::from_nbt(&bad, ®istry).is_err());
|
||||
let mut bad = data.clone();
|
||||
if let Some(Tag::List(shapes)) = bad.get_mut("shapes") {
|
||||
if let Tag::Compound(first) = &mut shapes[0] {
|
||||
first.remove(&"canonical".into());
|
||||
}
|
||||
if let Some(Tag::List(shapes)) = bad.get_mut("shapes")
|
||||
&& let Tag::Compound(first) = &mut shapes[0]
|
||||
{
|
||||
first.remove(&"canonical".into());
|
||||
}
|
||||
assert!(InteractionShapes::from_nbt(&bad, ®istry).is_err());
|
||||
let mut bad = data.clone();
|
||||
|
||||
@@ -426,16 +426,16 @@ where
|
||||
let mut library = rules_data
|
||||
.map(|data| data.library(f, registry, noises, None))
|
||||
.transpose()?;
|
||||
if let Some(data) = rules_data {
|
||||
if let Some(values) = f.get("library_json") {
|
||||
for value in values.as_array().unwrap() {
|
||||
let result = data.library(f, registry, noises, Some(value.as_str().unwrap()));
|
||||
writeln!(
|
||||
out,
|
||||
"rule decode {}",
|
||||
if result.is_ok() { "ok" } else { "error" }
|
||||
)?;
|
||||
}
|
||||
if let Some(data) = rules_data
|
||||
&& let Some(values) = f.get("library_json")
|
||||
{
|
||||
for value in values.as_array().unwrap() {
|
||||
let result = data.library(f, registry, noises, Some(value.as_str().unwrap()));
|
||||
writeln!(
|
||||
out,
|
||||
"rule decode {}",
|
||||
if result.is_ok() { "ok" } else { "error" }
|
||||
)?;
|
||||
}
|
||||
}
|
||||
let block_id = |name: &str, fallback| {
|
||||
|
||||
@@ -49,10 +49,10 @@ fn dump(out: &mut dyn Write, slots: &[Effect], ids: &mut Vec<Effect>) {
|
||||
.as_ref()
|
||||
.map(|v| id(ids, v).to_string())
|
||||
.unwrap_or("none".into());
|
||||
if let Some(v) = &d.hidden {
|
||||
if !visit.iter().any(|e| e.same_reference(v)) {
|
||||
visit.push(v.clone());
|
||||
}
|
||||
if let Some(v) = &d.hidden
|
||||
&& !visit.iter().any(|e| e.same_reference(v))
|
||||
{
|
||||
visit.push(v.clone());
|
||||
}
|
||||
writeln!(
|
||||
out,
|
||||
|
||||
@@ -50,10 +50,10 @@ fn dump(out: &mut dyn Write, slots: &[Effect], ids: &mut Vec<Effect>) {
|
||||
.as_ref()
|
||||
.map(|v| id(ids, v).to_string())
|
||||
.unwrap_or("none".into());
|
||||
if let Some(v) = &d.hidden {
|
||||
if !visit.iter().any(|e| e.same_reference(v)) {
|
||||
visit.push(v.clone());
|
||||
}
|
||||
if let Some(v) = &d.hidden
|
||||
&& !visit.iter().any(|e| e.same_reference(v))
|
||||
{
|
||||
visit.push(v.clone());
|
||||
}
|
||||
writeln!(
|
||||
out,
|
||||
|
||||
@@ -118,12 +118,11 @@ impl<'r> BlockCollisionRegistry<'r> {
|
||||
| (u8::from(empty) << 2)
|
||||
| (u8::from(contextual.contains_key(&id)) << 3),
|
||||
);
|
||||
if cached.cached_shape(id)?.is_none() {
|
||||
if let Some(rule) =
|
||||
if cached.cached_shape(id)?.is_none()
|
||||
&& let Some(rule) =
|
||||
DynamicSupport::from_state(cached.registry().state(id).unwrap())?
|
||||
{
|
||||
dynamic.insert(id, rule);
|
||||
}
|
||||
{
|
||||
dynamic.insert(id, rule);
|
||||
}
|
||||
}
|
||||
let pistons = PistonBlockBindings::new(cached.registry()).ok();
|
||||
|
||||
@@ -182,10 +182,10 @@ impl<'r> BlockSupportRegistry<'r> {
|
||||
let mut dynamic = HashMap::new();
|
||||
for id in 0..registry.len() {
|
||||
let id = BlockStateId(id as u32);
|
||||
if cached.cached_shape(id)?.is_none() {
|
||||
if let Some(behavior) = DynamicSupport::from_state(registry.state(id).unwrap())? {
|
||||
dynamic.insert(id, behavior);
|
||||
}
|
||||
if cached.cached_shape(id)?.is_none()
|
||||
&& let Some(behavior) = DynamicSupport::from_state(registry.state(id).unwrap())?
|
||||
{
|
||||
dynamic.insert(id, behavior);
|
||||
}
|
||||
}
|
||||
Ok(Self { cached, dynamic })
|
||||
|
||||
@@ -38,10 +38,10 @@ impl<S: Copy> DamageReduction<S> {
|
||||
if angle > f64::from(0.017_453_292_f32 * self.horizontal_angle) {
|
||||
return Ok(0.0);
|
||||
}
|
||||
if let Some(set) = self.types {
|
||||
if !world.source_in_set(set)? {
|
||||
return Ok(0.0);
|
||||
}
|
||||
if let Some(set) = self.types
|
||||
&& !world.source_in_set(set)?
|
||||
{
|
||||
return Ok(0.0);
|
||||
}
|
||||
Ok(clamp(self.base + self.factor * damage, damage))
|
||||
}
|
||||
|
||||
@@ -34,14 +34,14 @@ pub fn after_armor<W: ArmorWorld>(
|
||||
let divisor = 2.0 + toughness / 4.0;
|
||||
let protection = clamp(armor - damage / divisor, armor * 0.2, 20.0);
|
||||
let mut effectiveness = protection / 25.0;
|
||||
if let Some(weapon) = world.weapon()? {
|
||||
if let Some(level) = world.server_level()? {
|
||||
effectiveness = clamp(
|
||||
world.modify_armor_effectiveness(level, weapon, effectiveness)?,
|
||||
0.0,
|
||||
1.0,
|
||||
);
|
||||
}
|
||||
if let Some(weapon) = world.weapon()?
|
||||
&& let Some(level) = world.server_level()?
|
||||
{
|
||||
effectiveness = clamp(
|
||||
world.modify_armor_effectiveness(level, weapon, effectiveness)?,
|
||||
0.0,
|
||||
1.0,
|
||||
);
|
||||
}
|
||||
Ok(damage * (1.0 - effectiveness))
|
||||
}
|
||||
|
||||
@@ -143,10 +143,10 @@ impl<S: Clone, E> Consumable<S, E> {
|
||||
stack: &StackRef<I, K, V>,
|
||||
) -> Result<bool, W::Error> {
|
||||
let food = world.food(stack);
|
||||
if let Some(food) = food {
|
||||
if world.is_player() {
|
||||
return world.can_eat(food.can_always_eat);
|
||||
}
|
||||
if let Some(food) = food
|
||||
&& world.is_player()
|
||||
{
|
||||
return world.can_eat(food.can_always_eat);
|
||||
}
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
@@ -167,11 +167,11 @@ impl Walker<'_> {
|
||||
}
|
||||
match ty {
|
||||
Ty::Level => {
|
||||
if k < key(4771, 0) {
|
||||
if let Some(Tag::Compound(c)) = v.get_mut("CustomBossEvents") {
|
||||
for e in c.values_mut() {
|
||||
self.field(Ty::TextComponent, e, "Name");
|
||||
}
|
||||
if k < key(4771, 0)
|
||||
&& let Some(Tag::Compound(c)) = v.get_mut("CustomBossEvents")
|
||||
{
|
||||
for e in c.values_mut() {
|
||||
self.field(Ty::TextComponent, e, "Name");
|
||||
}
|
||||
}
|
||||
self.walk(Ty::LightweightLevel, v);
|
||||
|
||||
@@ -103,15 +103,14 @@ impl FluidState {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if flowing {
|
||||
if let Some(value) = properties
|
||||
if flowing
|
||||
&& let Some(value) = properties
|
||||
.get("level")
|
||||
.and_then(serde_json::Value::as_str)
|
||||
.and_then(crate::registry::java_integer)
|
||||
.filter(|v| (1..=8).contains(v))
|
||||
{
|
||||
state.amount = value as u8;
|
||||
}
|
||||
{
|
||||
state.amount = value as u8;
|
||||
}
|
||||
}
|
||||
Ok(state)
|
||||
|
||||
@@ -56,10 +56,11 @@ pub fn apply<W: ItemBlockingWorld>(world: &mut W, damage: f32) -> Result<f32, W:
|
||||
if world.bypasses_component(component)? {
|
||||
return Ok(0.0);
|
||||
}
|
||||
if let Some(entity) = world.direct_entity()? {
|
||||
if world.is_arrow(entity) && world.pierce_level(entity)? > 0 {
|
||||
return Ok(0.0);
|
||||
}
|
||||
if let Some(entity) = world.direct_entity()?
|
||||
&& world.is_arrow(entity)
|
||||
&& world.pierce_level(entity)? > 0
|
||||
{
|
||||
return Ok(0.0);
|
||||
}
|
||||
let angle = if let Some(source) = world.source_position()? {
|
||||
let yaw = world.head_yaw()?;
|
||||
@@ -72,12 +73,12 @@ pub fn apply<W: ItemBlockingWorld>(world: &mut W, damage: f32) -> Result<f32, W:
|
||||
let level = world.level()?;
|
||||
let hand = world.used_hand()?;
|
||||
world.hurt_blocking_item(component, level, item, hand, blocked)?;
|
||||
if blocked > 0.0 && !world.source_is_projectile()? {
|
||||
if let Some(entity) = world.direct_entity()? {
|
||||
if world.is_living(entity) {
|
||||
world.block_using_item(entity, damage, blocked >= damage)?;
|
||||
}
|
||||
}
|
||||
if blocked > 0.0
|
||||
&& !world.source_is_projectile()?
|
||||
&& let Some(entity) = world.direct_entity()?
|
||||
&& world.is_living(entity)
|
||||
{
|
||||
world.block_using_item(entity, damage, blocked >= damage)?;
|
||||
}
|
||||
Ok(blocked)
|
||||
}
|
||||
@@ -689,14 +689,14 @@ impl<K: JavaKey, V> JavaHashMap<K, V> {
|
||||
if !self.node(p).red {
|
||||
root = self.balance_delete(root, Some(replacement));
|
||||
}
|
||||
if replacement == p {
|
||||
if let Some(pp) = self.node(p).parent {
|
||||
self.node_mut(p).parent = None;
|
||||
if self.node(pp).left == Some(p) {
|
||||
self.node_mut(pp).left = None;
|
||||
} else if self.node(pp).right == Some(p) {
|
||||
self.node_mut(pp).right = None;
|
||||
}
|
||||
if replacement == p
|
||||
&& let Some(pp) = self.node(p).parent
|
||||
{
|
||||
self.node_mut(p).parent = None;
|
||||
if self.node(pp).left == Some(p) {
|
||||
self.node_mut(pp).left = None;
|
||||
} else if self.node(pp).right == Some(p) {
|
||||
self.node_mut(pp).right = None;
|
||||
}
|
||||
}
|
||||
if movable {
|
||||
|
||||
@@ -124,10 +124,10 @@ impl Behaviours {
|
||||
}
|
||||
// Fallable.onLand
|
||||
if concrete {
|
||||
if self.is_water_fluid(self.fluid(current).kind()) || sim.concrete_touches_liquid(pos) {
|
||||
if let Some(solid) = self.data(state).link {
|
||||
sim.set_block_and_update(pos, self.default_of(solid));
|
||||
}
|
||||
if (self.is_water_fluid(self.fluid(current).kind()) || sim.concrete_touches_liquid(pos))
|
||||
&& let Some(solid) = self.data(state).link
|
||||
{
|
||||
sim.set_block_and_update(pos, self.default_of(solid));
|
||||
}
|
||||
} else if self.instance_of(state, Class::Anvil) {
|
||||
sim.level_event(1031, pos, 0);
|
||||
|
||||
@@ -311,16 +311,15 @@ impl<L: LevelAccess + ?Sized> Sim<'_, L> {
|
||||
let pushed_pos = rel_n(pos, direction, 2);
|
||||
let pushed = self.state(pushed_pos);
|
||||
let mut event = 1;
|
||||
if b.is_block(pushed, b.named.moving_piston) && b.facing(pushed) == direction {
|
||||
if let Some(piston) = self.moving_piston(pushed_pos) {
|
||||
if piston.extending
|
||||
&& (piston.progress_o < 0.5
|
||||
|| self.level.game_time() == piston.last_ticked
|
||||
|| self.ticks.handling_tick)
|
||||
{
|
||||
event = 2;
|
||||
}
|
||||
}
|
||||
if b.is_block(pushed, b.named.moving_piston)
|
||||
&& b.facing(pushed) == direction
|
||||
&& let Some(piston) = self.moving_piston(pushed_pos)
|
||||
&& piston.extending
|
||||
&& (piston.progress_o < 0.5
|
||||
|| self.level.game_time() == piston.last_ticked
|
||||
|| self.ticks.handling_tick)
|
||||
{
|
||||
event = 2;
|
||||
}
|
||||
self.block_event(pos, block, event, direction as i32);
|
||||
}
|
||||
@@ -752,13 +751,13 @@ impl<L: LevelAccess + ?Sized> Sim<'_, L> {
|
||||
let two = rel_n(pos, direction, 2);
|
||||
let moving_state = self.state(two);
|
||||
let mut piston_piece = false;
|
||||
if b.is_block(moving_state, b.named.moving_piston) {
|
||||
if let Some(entity) = self.moving_piston(two) {
|
||||
if entity.direction == direction && entity.extending {
|
||||
self.moving_piston_final_tick(two);
|
||||
piston_piece = true;
|
||||
}
|
||||
}
|
||||
if b.is_block(moving_state, b.named.moving_piston)
|
||||
&& let Some(entity) = self.moving_piston(two)
|
||||
&& entity.direction == direction
|
||||
&& entity.extending
|
||||
{
|
||||
self.moving_piston_final_tick(two);
|
||||
piston_piece = true;
|
||||
}
|
||||
if !piston_piece {
|
||||
let is_piston = b.is_block(moving_state, b.named.piston)
|
||||
|
||||
@@ -158,11 +158,11 @@ impl PlacementContext {
|
||||
return directions;
|
||||
}
|
||||
let target = self.face.opposite();
|
||||
if let Some(index) = directions.iter().position(|d| *d == target) {
|
||||
if index > 0 {
|
||||
directions.copy_within(0..index, 1);
|
||||
directions[0] = target;
|
||||
}
|
||||
if let Some(index) = directions.iter().position(|d| *d == target)
|
||||
&& index > 0
|
||||
{
|
||||
directions.copy_within(0..index, 1);
|
||||
directions[0] = target;
|
||||
}
|
||||
directions
|
||||
}
|
||||
@@ -735,19 +735,18 @@ impl<L: LevelAccess + ?Sized> Sim<'_, L> {
|
||||
let mut kind = "single";
|
||||
let mut facing = horizontal.opposite();
|
||||
let face = ctx.face;
|
||||
if is_horizontal(face) && ctx.sneaking {
|
||||
if let Some(neighbour_facing) =
|
||||
if is_horizontal(face)
|
||||
&& ctx.sneaking
|
||||
&& let Some(neighbour_facing) =
|
||||
self.chest_candidate_partner_facing(default, pos, face.opposite())
|
||||
{
|
||||
if axis_of(neighbour_facing) != axis_of(face) {
|
||||
facing = neighbour_facing;
|
||||
kind = if counter_clockwise(facing) == face.opposite() {
|
||||
"right"
|
||||
} else {
|
||||
"left"
|
||||
};
|
||||
}
|
||||
}
|
||||
&& axis_of(neighbour_facing) != axis_of(face)
|
||||
{
|
||||
facing = neighbour_facing;
|
||||
kind = if counter_clockwise(facing) == face.opposite() {
|
||||
"right"
|
||||
} else {
|
||||
"left"
|
||||
};
|
||||
}
|
||||
if kind == "single" && !ctx.sneaking {
|
||||
if self.chest_candidate_partner_facing(default, pos, clockwise(facing))
|
||||
|
||||
@@ -218,30 +218,30 @@ impl<L: LevelAccess + ?Sized> Sim<'_, L> {
|
||||
/// which made a lever on the piston's back pop off when it retracted.
|
||||
pub(super) fn support_state(&self, pos: BlockPos) -> BlockStateId {
|
||||
let state = self.state(pos);
|
||||
if self.b.is_block(state, self.b.named.moving_piston) {
|
||||
if let Some(piston) = self.moving_piston(pos) {
|
||||
// `PistonMovingBlockEntity.getCollisionShape`: only a piston base.
|
||||
if piston.source
|
||||
&& !piston.extending
|
||||
&& (self.b.is_block(piston.moved_state, self.b.named.piston)
|
||||
|| self
|
||||
.b
|
||||
.is_block(piston.moved_state, self.b.named.sticky_piston))
|
||||
{
|
||||
return self
|
||||
if self.b.is_block(state, self.b.named.moving_piston)
|
||||
&& let Some(piston) = self.moving_piston(pos)
|
||||
{
|
||||
// `PistonMovingBlockEntity.getCollisionShape`: only a piston base.
|
||||
if piston.source
|
||||
&& !piston.extending
|
||||
&& (self.b.is_block(piston.moved_state, self.b.named.piston)
|
||||
|| self
|
||||
.b
|
||||
.table
|
||||
.set_bool(piston.moved_state, self.b.props.extended, true);
|
||||
}
|
||||
// The same method for any other moving block: its collision shape
|
||||
// is `movedState.getCollisionShape(..).move(dir * extendedProgress)`,
|
||||
// and `getExtendedProgress` is 0 once progress reaches 1.0, so a
|
||||
// finished-but-not-yet-placed block supports like itself (a wall
|
||||
// coral fan keeps its slime block while the column lands). At 0 or
|
||||
// 0.5 progress the shape is shifted off the cell, a face never full.
|
||||
if !piston.source && piston.progress >= 1.0 {
|
||||
return piston.moved_state;
|
||||
}
|
||||
.is_block(piston.moved_state, self.b.named.sticky_piston))
|
||||
{
|
||||
return self
|
||||
.b
|
||||
.table
|
||||
.set_bool(piston.moved_state, self.b.props.extended, true);
|
||||
}
|
||||
// The same method for any other moving block: its collision shape
|
||||
// is `movedState.getCollisionShape(..).move(dir * extendedProgress)`,
|
||||
// and `getExtendedProgress` is 0 once progress reaches 1.0, so a
|
||||
// finished-but-not-yet-placed block supports like itself (a wall
|
||||
// coral fan keeps its slime block while the column lands). At 0 or
|
||||
// 0.5 progress the shape is shifted off the cell, a face never full.
|
||||
if !piston.source && piston.progress >= 1.0 {
|
||||
return piston.moved_state;
|
||||
}
|
||||
}
|
||||
state
|
||||
|
||||
@@ -146,10 +146,9 @@ impl<L: LevelAccess + ?Sized> Sim<'_, L> {
|
||||
.link
|
||||
.is_some_and(|fruit| b.is_block(nstate, fruit))
|
||||
&& dir == b.facing(state)
|
||||
&& let Some(stem) = b.data(state).link2
|
||||
{
|
||||
if let Some(stem) = b.data(state).link2 {
|
||||
return Some(table.set_int(b.default_of(stem), p.age, 7));
|
||||
}
|
||||
return Some(table.set_int(b.default_of(stem), p.age, 7));
|
||||
}
|
||||
sup!()
|
||||
}
|
||||
|
||||
@@ -79,26 +79,25 @@ impl<L: LevelAccess + ?Sized> Sim<'_, L> {
|
||||
}
|
||||
}
|
||||
Class::Coral => {
|
||||
if !self.coral_scan_for_water(pos) {
|
||||
if let Some(dead) = b.data(state).link {
|
||||
let next = b.default_of(dead);
|
||||
if self.level.allow_block_fade(pos, state, next) {
|
||||
self.set_block(pos, next, 2);
|
||||
}
|
||||
if !self.coral_scan_for_water(pos)
|
||||
&& let Some(dead) = b.data(state).link
|
||||
{
|
||||
let next = b.default_of(dead);
|
||||
if self.level.allow_block_fade(pos, state, next) {
|
||||
self.set_block(pos, next, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
Class::CoralFan | Class::CoralPlant | Class::CoralWallFan => {
|
||||
if !self.coral_plant_scan_for_water(state, pos) {
|
||||
if let Some(dead) = b.data(state).link {
|
||||
let mut next =
|
||||
b.table.set_bool(b.default_of(dead), p.waterlogged, false);
|
||||
if class == Class::CoralWallFan {
|
||||
next = b.table.set_dir(next, p.facing, b.facing(state));
|
||||
}
|
||||
if self.level.allow_block_fade(pos, state, next) {
|
||||
self.set_block(pos, next, 2);
|
||||
}
|
||||
if !self.coral_plant_scan_for_water(state, pos)
|
||||
&& let Some(dead) = b.data(state).link
|
||||
{
|
||||
let mut next = b.table.set_bool(b.default_of(dead), p.waterlogged, false);
|
||||
if class == Class::CoralWallFan {
|
||||
next = b.table.set_dir(next, p.facing, b.facing(state));
|
||||
}
|
||||
if self.level.allow_block_fade(pos, state, next) {
|
||||
self.set_block(pos, next, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -889,15 +888,14 @@ impl<L: LevelAccess + ?Sized> Sim<'_, L> {
|
||||
.support_tag2
|
||||
.as_ref()
|
||||
.is_some_and(|tag| b.in_set(below_state, tag))
|
||||
&& let (Some(fruit), Some(stem)) = (data.link, data.link2)
|
||||
{
|
||||
if let (Some(fruit), Some(stem)) = (data.link, data.link2) {
|
||||
self.set_block_and_update(relative, b.default_of(fruit));
|
||||
self.set_block_and_update(
|
||||
pos,
|
||||
b.table
|
||||
.set_dir(b.default_of(stem), b.props.facing, direction),
|
||||
);
|
||||
}
|
||||
self.set_block_and_update(relative, b.default_of(fruit));
|
||||
self.set_block_and_update(
|
||||
pos,
|
||||
b.table
|
||||
.set_dir(b.default_of(stem), b.props.facing, direction),
|
||||
);
|
||||
}
|
||||
}
|
||||
/// `PitcherCropBlock.grow`.
|
||||
@@ -1610,10 +1608,10 @@ impl<L: LevelAccess + ?Sized> Sim<'_, L> {
|
||||
}
|
||||
let chance = (older + 1) as f32 / (older + same + 1) as f32;
|
||||
let modifier = if own == 0 { 0.75 } else { 1.0 };
|
||||
if self.random().next_float() < chance * chance * modifier {
|
||||
if let Some(next) = self.copper_next(state) {
|
||||
self.set_block_and_update(pos, next);
|
||||
}
|
||||
if self.random().next_float() < chance * chance * modifier
|
||||
&& let Some(next) = self.copper_next(state)
|
||||
{
|
||||
self.set_block_and_update(pos, next);
|
||||
}
|
||||
}
|
||||
/// `WeatheringCopper.getNext` by registry naming.
|
||||
|
||||
@@ -274,10 +274,11 @@ impl<'a> Reader<'a, '_> {
|
||||
let mut values = Vec::with_capacity(len);
|
||||
for _ in 0..len {
|
||||
let mut value = self.payload(element_id, depth + 1)?;
|
||||
if let Tag::Compound(map) = &mut value {
|
||||
if map.len() == 1 && map.contains_key(&JavaString::default()) {
|
||||
value = map.remove(&JavaString::default()).unwrap();
|
||||
}
|
||||
if let Tag::Compound(map) = &mut value
|
||||
&& map.len() == 1
|
||||
&& map.contains_key(&JavaString::default())
|
||||
{
|
||||
value = map.remove(&JavaString::default()).unwrap();
|
||||
}
|
||||
values.push(value);
|
||||
}
|
||||
@@ -384,10 +385,11 @@ impl ListElements<'_, '_, '_> {
|
||||
}
|
||||
self.left -= 1;
|
||||
let mut value = self.reader.payload(self.element_id, self.depth)?;
|
||||
if let Tag::Compound(map) = &mut value {
|
||||
if map.len() == 1 && map.contains_key(&JavaString::default()) {
|
||||
value = map.remove(&JavaString::default()).unwrap();
|
||||
}
|
||||
if let Tag::Compound(map) = &mut value
|
||||
&& map.len() == 1
|
||||
&& map.contains_key(&JavaString::default())
|
||||
{
|
||||
value = map.remove(&JavaString::default()).unwrap();
|
||||
}
|
||||
Ok(Some(value))
|
||||
}
|
||||
|
||||
@@ -189,12 +189,12 @@ impl<K: ObjectKey + Clone, V: Clone> ObjectOpenMap<K, V> {
|
||||
}
|
||||
p = (p + 1) & mask;
|
||||
}
|
||||
if p < hole {
|
||||
if let Some(c) = &mut cursor {
|
||||
c.wrapped
|
||||
.get_or_insert_with(Vec::new)
|
||||
.push(table.keys[p].clone());
|
||||
}
|
||||
if p < hole
|
||||
&& let Some(c) = &mut cursor
|
||||
{
|
||||
c.wrapped
|
||||
.get_or_insert_with(Vec::new)
|
||||
.push(table.keys[p].clone());
|
||||
}
|
||||
let key = table.keys[p].clone();
|
||||
let value = table.values[p].clone();
|
||||
|
||||
@@ -133,13 +133,13 @@ impl<K: ObjectKey + Clone> ObjectOpenSet<K> {
|
||||
}
|
||||
p = (p + 1) & mask;
|
||||
}
|
||||
if p < hole {
|
||||
if let Some(cursor) = &mut cursor {
|
||||
cursor
|
||||
.wrapped
|
||||
.get_or_insert_with(Vec::new)
|
||||
.push(self.slots[p].clone());
|
||||
}
|
||||
if p < hole
|
||||
&& let Some(cursor) = &mut cursor
|
||||
{
|
||||
cursor
|
||||
.wrapped
|
||||
.get_or_insert_with(Vec::new)
|
||||
.push(self.slots[p].clone());
|
||||
}
|
||||
let key = self.slots[p].clone();
|
||||
*self
|
||||
|
||||
@@ -147,11 +147,12 @@ impl<'r> PistonBlockBindings<'r> {
|
||||
/// Its sticky/short/facing rules differ from the entity's own collision head.
|
||||
pub fn collision_related_state(&self, piston: MovingPistonState) -> io::Result<BlockStateId> {
|
||||
self.validate(piston.moved_state)?;
|
||||
if !piston.extending && piston.source {
|
||||
if let Some(base) = self.bases.get(&piston.moved_state) {
|
||||
return Ok(self.heads[usize::from(base.sticky)][base.facing as usize]
|
||||
[usize::from(piston.progress > 0.25)]);
|
||||
}
|
||||
if !piston.extending
|
||||
&& piston.source
|
||||
&& let Some(base) = self.bases.get(&piston.moved_state)
|
||||
{
|
||||
return Ok(self.heads[usize::from(base.sticky)][base.facing as usize]
|
||||
[usize::from(piston.progress > 0.25)]);
|
||||
}
|
||||
Ok(piston.moved_state)
|
||||
}
|
||||
|
||||
@@ -96,10 +96,10 @@ pub fn server_player_hurt_server<W: ServerPlayerHurtWorld>(
|
||||
}
|
||||
}
|
||||
CausingEntity::Arrow(a) => {
|
||||
if let Some(p) = w.arrow_player_owner(s, a)? {
|
||||
if !w.can_harm_player(s, p)? {
|
||||
return Ok(false);
|
||||
}
|
||||
if let Some(p) = w.arrow_player_owner(s, a)?
|
||||
&& !w.can_harm_player(s, p)?
|
||||
{
|
||||
return Ok(false);
|
||||
}
|
||||
}
|
||||
CausingEntity::Other => {}
|
||||
|
||||
@@ -71,14 +71,12 @@ pub fn clip_with_interaction<W: RayWorld>(
|
||||
state: W::Block,
|
||||
) -> Result<Option<BlockHit>, W::Error> {
|
||||
let mut hit = shape.clip(start, end, p);
|
||||
if let Some(hit) = &mut hit {
|
||||
if let Some(interaction) = world.interaction_shape(state, p)?.clip(start, end, p) {
|
||||
if interaction.location.subtract(start).length_squared()
|
||||
< hit.location.subtract(start).length_squared()
|
||||
{
|
||||
hit.direction = interaction.direction;
|
||||
}
|
||||
}
|
||||
if let Some(hit) = &mut hit
|
||||
&& let Some(interaction) = world.interaction_shape(state, p)?.clip(start, end, p)
|
||||
&& interaction.location.subtract(start).length_squared()
|
||||
< hit.location.subtract(start).length_squared()
|
||||
{
|
||||
hit.direction = interaction.direction;
|
||||
}
|
||||
Ok(hit)
|
||||
}
|
||||
@@ -175,19 +173,19 @@ pub fn fall_reset_shape<W: FallResetWorld>(
|
||||
if world.fall_reset_tag(state)? {
|
||||
return Ok(VoxelShape::block());
|
||||
}
|
||||
if let Some(entity) = entity {
|
||||
if world.entity_is_player(entity)? {
|
||||
if world.is_portal(state, ResetPortal::EndGateway)?
|
||||
|| world.is_portal(state, ResetPortal::EndPortal)?
|
||||
{
|
||||
return Ok(VoxelShape::block());
|
||||
}
|
||||
if world.is_server_level()
|
||||
&& world.is_portal(state, ResetPortal::NetherPortal)?
|
||||
&& world.players_nether_portal_delay()? == 0
|
||||
{
|
||||
return Ok(VoxelShape::block());
|
||||
}
|
||||
if let Some(entity) = entity
|
||||
&& world.entity_is_player(entity)?
|
||||
{
|
||||
if world.is_portal(state, ResetPortal::EndGateway)?
|
||||
|| world.is_portal(state, ResetPortal::EndPortal)?
|
||||
{
|
||||
return Ok(VoxelShape::block());
|
||||
}
|
||||
if world.is_server_level()
|
||||
&& world.is_portal(state, ResetPortal::NetherPortal)?
|
||||
&& world.players_nether_portal_delay()? == 0
|
||||
{
|
||||
return Ok(VoxelShape::block());
|
||||
}
|
||||
}
|
||||
Ok(VoxelShape::empty())
|
||||
|
||||
@@ -150,10 +150,10 @@ impl BiomeSourceCatalog {
|
||||
}
|
||||
"minecraft:multi_noise" => {
|
||||
// mapEither prefers a successful inline list, then tries preset.
|
||||
if let Some(raw) = optional(&object, "biomes") {
|
||||
if let Ok(value) = self.inline(raw) {
|
||||
return Ok(value);
|
||||
}
|
||||
if let Some(raw) = optional(&object, "biomes")
|
||||
&& let Ok(value) = self.inline(raw)
|
||||
{
|
||||
return Ok(value);
|
||||
}
|
||||
let raw = required(&object, "preset")?;
|
||||
if raw.get().starts_with('"') {
|
||||
|
||||
@@ -160,10 +160,10 @@ impl<'a> BiomeSourceResolver<'a> {
|
||||
volume: Option<&ClimateVolume>,
|
||||
quart: [i32; 3],
|
||||
) -> Result<&'a str, BiomeSourceError> {
|
||||
if let Self::MultiNoise(source) = self {
|
||||
if let Some(volume) = volume {
|
||||
return Ok(source.sample_prepared(volume, quart)?);
|
||||
}
|
||||
if let Self::MultiNoise(source) = self
|
||||
&& let Some(volume) = volume
|
||||
{
|
||||
return Ok(source.sample_prepared(volume, quart)?);
|
||||
}
|
||||
self.sample(context, quart)
|
||||
}
|
||||
|
||||
@@ -41,10 +41,10 @@ impl<'a, 'r, B: TerrainBlockStates> TerrainBulkAccess<'a, 'r, B> {
|
||||
return Ok(None);
|
||||
}
|
||||
let key = section.pack();
|
||||
if let Some((last, section)) = self.last {
|
||||
if last == key {
|
||||
return Ok(Some(section));
|
||||
}
|
||||
if let Some((last, section)) = self.last
|
||||
&& last == key
|
||||
{
|
||||
return Ok(Some(section));
|
||||
}
|
||||
let cached = if let Some(cached) = self.acquired.get(&key) {
|
||||
*cached
|
||||
|
||||
@@ -109,13 +109,11 @@ impl EndGatewayFeature {
|
||||
world
|
||||
.set_block(p, state, 3)
|
||||
.map_err(EndGatewayError::World)?;
|
||||
if center {
|
||||
if let Some(exit) = self.exit {
|
||||
// Native code looks up the entity even when the write returned false.
|
||||
world
|
||||
.configure_end_gateway(p, exit, self.exact)
|
||||
.map_err(EndGatewayError::Query)?;
|
||||
}
|
||||
if center && let Some(exit) = self.exit {
|
||||
// Native code looks up the entity even when the write returned false.
|
||||
world
|
||||
.configure_end_gateway(p, exit, self.exact)
|
||||
.map_err(EndGatewayError::Query)?;
|
||||
}
|
||||
}
|
||||
Ok(true)
|
||||
|
||||
@@ -1411,10 +1411,10 @@ where
|
||||
let name = resolver
|
||||
.sample_prepared(context, volume.as_ref(), quart)
|
||||
.map_err(|e| e.to_string())?;
|
||||
if let Some((pointer, id)) = last {
|
||||
if std::ptr::eq(pointer, name) {
|
||||
return Ok(id);
|
||||
}
|
||||
if let Some((pointer, id)) = last
|
||||
&& std::ptr::eq(pointer, name)
|
||||
{
|
||||
return Ok(id);
|
||||
}
|
||||
let id = ids.get(name).copied().ok_or_else(|| name.to_owned())?;
|
||||
last = Some((name as *const str, id));
|
||||
|
||||
@@ -132,10 +132,10 @@ impl<S: MaterialSurfaceQueries> MaterialSurfaceQueries for MaterialDensitySource
|
||||
.get(index)
|
||||
.ok_or(MaterialRuleError::MissingDensityProvider)?;
|
||||
let position = [position.x, position.y, position.z];
|
||||
if let Some(buffer) = source.buffer {
|
||||
if let Some(index) = block_index(self.expected, position) {
|
||||
return Ok(self.buffers[buffer][index]);
|
||||
}
|
||||
if let Some(buffer) = source.buffer
|
||||
&& let Some(index) = block_index(self.expected, position)
|
||||
{
|
||||
return Ok(self.buffers[buffer][index]);
|
||||
}
|
||||
Ok(source.sampler.sample_value(&mut self.context, position)?)
|
||||
}
|
||||
|
||||
@@ -459,10 +459,9 @@ impl BlockStateProvider {
|
||||
if predicate
|
||||
.test(world, position)
|
||||
.map_err(StateProviderError::Query)?
|
||||
&& let Some(state) = provider.get_optional_state(world, random, position)?
|
||||
{
|
||||
if let Some(state) = provider.get_optional_state(world, random, position)? {
|
||||
return Ok(Some(state));
|
||||
}
|
||||
return Ok(Some(state));
|
||||
}
|
||||
}
|
||||
match fallback {
|
||||
|
||||
@@ -194,10 +194,8 @@ impl StructureAdaptation {
|
||||
continue;
|
||||
}
|
||||
let rigid = pool.element.projection() == Projection::Rigid;
|
||||
if rigid {
|
||||
if let Some(b) = adaptation.piece_box(b, pool.rotation) {
|
||||
push_piece(pieces, adaptation, b, &mut include);
|
||||
}
|
||||
if rigid && let Some(b) = adaptation.piece_box(b, pool.rotation) {
|
||||
push_piece(pieces, adaptation, b, &mut include);
|
||||
}
|
||||
if (rigid && !self.rigid_junctions) || adaptation.band.is_some() {
|
||||
continue;
|
||||
|
||||
@@ -1474,11 +1474,11 @@ fn process_infos<W: PlacementContext>(
|
||||
before.clone(),
|
||||
settings,
|
||||
)?;
|
||||
if let Some(altered) = altered {
|
||||
if altered != before {
|
||||
replaced += 1;
|
||||
processed[index] = altered;
|
||||
}
|
||||
if let Some(altered) = altered
|
||||
&& altered != before
|
||||
{
|
||||
replaced += 1;
|
||||
processed[index] = altered;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -693,13 +693,13 @@ impl StructureRegistry {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if let Some(avoid) = set.avoid.as_ref().filter(|_| zones) {
|
||||
if avoid.sets.iter().any(|other| {
|
||||
if let Some(avoid) = set.avoid.as_ref().filter(|_| zones)
|
||||
&& avoid.sets.iter().any(|other| {
|
||||
let range = avoid.chunk_count;
|
||||
self.has_start_in_range(other, seed, x, z, range, rings, avoid.their_zones)
|
||||
}) {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if set.frequency < 1. && !reduce(set.reduction, seed, set.salt, x, z, set.frequency) {
|
||||
return false;
|
||||
@@ -1496,12 +1496,11 @@ pub fn beardifier(
|
||||
let mut kernels: Option<BoundingBox> = None;
|
||||
for start in starts {
|
||||
let def = ®istry.structures[start.structure];
|
||||
if let Some(enhanced) = &def.enhanced_terrain {
|
||||
if let Some(b) =
|
||||
if let Some(enhanced) = &def.enhanced_terrain
|
||||
&& let Some(b) =
|
||||
enhanced.collect(start, chunk, &mut kernel_pieces, &mut kernel_junctions)
|
||||
{
|
||||
include(b, &mut kernels);
|
||||
}
|
||||
{
|
||||
include(b, &mut kernels);
|
||||
}
|
||||
let adjustment = def.terrain;
|
||||
if adjustment == TerrainAdjustment::None {
|
||||
|
||||
@@ -316,10 +316,10 @@ impl Builder {
|
||||
if !any {
|
||||
return None;
|
||||
}
|
||||
if let Some(kind) = self.imposed.take() {
|
||||
if let Some(piece) = self.create(kind, r, foot, d, depth) {
|
||||
return Some(piece);
|
||||
}
|
||||
if let Some(kind) = self.imposed.take()
|
||||
&& let Some(piece) = self.create(kind, r, foot, d, depth)
|
||||
{
|
||||
return Some(piece);
|
||||
}
|
||||
for _ in 0..5 {
|
||||
let mut selection = int(r, total);
|
||||
|
||||
@@ -631,10 +631,10 @@ impl TreeFeature {
|
||||
if clipped < tree_height && self.min_clipped_height.is_none_or(|min| clipped < min) {
|
||||
return Ok(false);
|
||||
}
|
||||
if let Some(root) = &self.root_placer {
|
||||
if !root.place_roots(run, self, origin, trunk_origin)? {
|
||||
return Ok(false);
|
||||
}
|
||||
if let Some(root) = &self.root_placer
|
||||
&& !root.place_roots(run, self, origin, trunk_origin)?
|
||||
{
|
||||
return Ok(false);
|
||||
}
|
||||
let attachments = self
|
||||
.trunk_placer
|
||||
|
||||
@@ -392,15 +392,15 @@ impl TreeDecorator {
|
||||
else {
|
||||
return Ok(());
|
||||
};
|
||||
if d.run.random.next_float() < *ground {
|
||||
if let Some(patch) = patch {
|
||||
nested(
|
||||
patch,
|
||||
d.run.world,
|
||||
d.run.random,
|
||||
tb::offset(origin, 0, 1, 0),
|
||||
)?;
|
||||
}
|
||||
if d.run.random.next_float() < *ground
|
||||
&& let Some(patch) = patch
|
||||
{
|
||||
nested(
|
||||
patch,
|
||||
d.run.world,
|
||||
d.run.random,
|
||||
tb::offset(origin, 0, 1, 0),
|
||||
)?;
|
||||
}
|
||||
for (positions, chance) in [(&lists.logs, *trunk), (&lists.leaves, *leaves)] {
|
||||
for &pos in positions {
|
||||
|
||||
@@ -103,10 +103,10 @@ impl TrunkPlacer {
|
||||
"minecraft:cherry_trunk_placer" => {
|
||||
let start: Object =
|
||||
serde_json::from_str(required(&object, "branch_start_offset_from_top")?.get())?;
|
||||
if let Some(kind) = optional(&start, "type") {
|
||||
if serde_json::from_str::<String>(kind.get())? != "minecraft:uniform" {
|
||||
return Err(DecodeError::Field("cherry branch start type"));
|
||||
}
|
||||
if let Some(kind) = optional(&start, "type")
|
||||
&& serde_json::from_str::<String>(kind.get())? != "minecraft:uniform"
|
||||
{
|
||||
return Err(DecodeError::Field("cherry branch start type"));
|
||||
}
|
||||
let min = int_range(required(&start, "min_inclusive")?, "branch start", -16, 0)?;
|
||||
let max = int_range(required(&start, "max_inclusive")?, "branch start", -16, 0)?;
|
||||
|
||||
@@ -87,10 +87,10 @@ impl UnderwaterMagmaFeature {
|
||||
}
|
||||
let ceiling = self.scan(world, origin, 1)?;
|
||||
let floor = self.scan(world, origin, -1)?;
|
||||
if let (Some(floor), Some(ceiling)) = (floor, ceiling) {
|
||||
if ceiling.wrapping_sub(floor).wrapping_sub(1) < 0 {
|
||||
return Err(UnderwaterMagmaError::InvalidColumn);
|
||||
}
|
||||
if let (Some(floor), Some(ceiling)) = (floor, ceiling)
|
||||
&& ceiling.wrapping_sub(floor).wrapping_sub(1) < 0
|
||||
{
|
||||
return Err(UnderwaterMagmaError::InvalidColumn);
|
||||
}
|
||||
let Some(y) = floor else {
|
||||
return Ok(false);
|
||||
|
||||
@@ -58,13 +58,13 @@ fn registry() -> BlockRegistry {
|
||||
.iter()
|
||||
.map(|name| {
|
||||
let mut tag = Tag::compound([("id", Tag::String((*name).into()))]);
|
||||
if *name == "minecraft:water" {
|
||||
if let Tag::Compound(entries) = &mut tag {
|
||||
entries.insert(
|
||||
"properties".into(),
|
||||
Tag::compound([("level", Tag::String("0".into()))]),
|
||||
);
|
||||
}
|
||||
if *name == "minecraft:water"
|
||||
&& let Tag::Compound(entries) = &mut tag
|
||||
{
|
||||
entries.insert(
|
||||
"properties".into(),
|
||||
Tag::compound([("level", Tag::String("0".into()))]),
|
||||
);
|
||||
}
|
||||
tag
|
||||
})
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "xtask"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
license.workspace = true
|
||||
publish = false
|
||||
description = "Repository tasks: cargo run -p xtask -- package BINARY OUTDIR | tokens"
|
||||
|
||||
Reference in new issue
Block a user