mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 11:06:11 -10:00
Merge pull request #11637 from horizon-rust/fix/lightning-fire-radius-11376
🤖 Agent: lightning now places fire (and draws its extra-source offsets) only when canSpreadFireAround passes at the bolt, so fire_spread_radius_around_player holds for strikes far from every player.
This commit is contained in:
1 file changed
+56
-1
@@ -300,7 +300,8 @@ impl Game<'_> {
|
||||
});
|
||||
}
|
||||
/// `spawnFire`: fire at the strike point and `extra` random neighbours,
|
||||
/// wherever `BaseFireBlock.getState` fire can survive. Returns how many
|
||||
/// wherever `BaseFireBlock.getState` fire can survive, when a player is
|
||||
/// within the fire-spread radius. Returns how many
|
||||
/// blocks it set on fire.
|
||||
fn bolt_fire(&mut self, at: [f64; 3], extra: i32) -> i32 {
|
||||
let mut set = 0;
|
||||
@@ -309,6 +310,14 @@ impl Game<'_> {
|
||||
at[1].floor() as i32,
|
||||
at[2].floor() as i32,
|
||||
];
|
||||
// ServerLevel.canSpreadFireAround at the bolt: no fire at all, and no
|
||||
// draws for the extra sources, away from every player (#11376).
|
||||
let origin = BlockPos::new(base[0], base[1], base[2]);
|
||||
if !self.with_level(|_, level, _| {
|
||||
horizon_world::level::LevelAccess::can_spread_fire_around(level, origin)
|
||||
}) {
|
||||
return 0;
|
||||
}
|
||||
let mut spots = vec![base];
|
||||
for _ in 0..extra {
|
||||
let r = &mut self.world.random;
|
||||
@@ -756,6 +765,52 @@ mod tests {
|
||||
use horizon_core::geometry::Vec3;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// `LightningBolt.spawnFire` places nothing, and draws no extra sources,
|
||||
/// unless `canSpreadFireAround` passes at the bolt (#11376).
|
||||
#[test]
|
||||
#[ignore = "needs prepared resources (HORIZON_TEST_RESOURCES)"]
|
||||
fn a_bolt_away_from_players_starts_no_fire() {
|
||||
use horizon_client::gamerules::Value;
|
||||
let mut game = super::super::native_machines::tests::server_game();
|
||||
let stone = game
|
||||
.pack
|
||||
.assets
|
||||
.registry
|
||||
.default_state("minecraft:stone")
|
||||
.unwrap();
|
||||
let air = game.res.facts().air;
|
||||
game.world.set(8, 64, 8, stone).unwrap();
|
||||
let bolt = [8.5, 65.0, 8.5];
|
||||
// (radius, player's x): fires expected at the strike.
|
||||
for (radius, player_x, fires) in [
|
||||
(128, 12.5, true),
|
||||
(1, 12.5, false),
|
||||
(0, 8.5, false),
|
||||
(-1, 1000.0, true),
|
||||
] {
|
||||
game.world.set(8, 65, 8, air).unwrap();
|
||||
game.ui
|
||||
.rules
|
||||
.set("fire_spread_radius_around_player", Value::Int(radius));
|
||||
game.player = Some(
|
||||
horizon_client::motion::PlayerMotion::new(
|
||||
game.motion,
|
||||
Vec3::new(player_x, 65.0, 8.5),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
let random = game.world.random.clone();
|
||||
let set = game.bolt_fire(bolt, 4);
|
||||
let burning = game.world.block(8, 65, 8) != air;
|
||||
assert_eq!((set > 0, burning), (fires, fires), "radius {radius}");
|
||||
if !fires {
|
||||
// No offset draws either.
|
||||
let mut before = random;
|
||||
assert_eq!(game.world.random.next_long(), before.next_long());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn viewer_box_reaches_15_around_and_down_and_21_up() {
|
||||
let bolt = [0.0, 64.0, 0.0];
|
||||
|
||||
Reference in new issue
Block a user