mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
fix(ai): damage endermen in rain (#2714)
This commit is contained in:
@@ -67,7 +67,6 @@ impl TemperatureModifier {
|
||||
/// Represents weather information for a biome, including temperature and precipitation.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Weather {
|
||||
#[expect(dead_code)]
|
||||
has_precipitation: bool,
|
||||
/// Base temperature of the biome.
|
||||
temperature: f32,
|
||||
@@ -136,4 +135,37 @@ impl Weather {
|
||||
modified_temperature
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn warm_enough_to_rain(&self, x: i32, y: i32, z: i32, sea_level: i32) -> bool {
|
||||
self.compute_temperature(f64::from(x), y, f64::from(z), sea_level) >= 0.15
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_rain_at(&self, x: i32, y: i32, z: i32, sea_level: i32) -> bool {
|
||||
self.has_precipitation && self.warm_enough_to_rain(x, y, z, sea_level)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{TemperatureModifier, Weather};
|
||||
|
||||
#[test]
|
||||
fn precipitation_controls_rain() {
|
||||
let weather = Weather::new(false, 1.0, TemperatureModifier::None, 0.0);
|
||||
assert!(!weather.is_rain_at(0, 64, 0, 63));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn warm_precipitation_is_rain() {
|
||||
let weather = Weather::new(true, 1.0, TemperatureModifier::None, 0.0);
|
||||
assert!(weather.is_rain_at(0, 64, 0, 63));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cold_precipitation_is_snow() {
|
||||
let weather = Weather::new(true, 0.0, TemperatureModifier::None, 0.0);
|
||||
assert!(!weather.is_rain_at(0, 64, 0, 63));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,8 +427,12 @@ impl Mob for EndermanEntity {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: also check rain
|
||||
if entity.touching_water.load(Ordering::SeqCst) {
|
||||
let world = entity.world.load();
|
||||
let raining_at_feet = world.is_raining_at(&entity.block_pos.load()).await;
|
||||
let raining_at_head = world
|
||||
.is_raining_at(&entity.bounding_box.load().max_block_pos())
|
||||
.await;
|
||||
if entity.touching_water.load(Ordering::SeqCst) || raining_at_feet || raining_at_head {
|
||||
self.mob_entity
|
||||
.living_entity
|
||||
.damage_with_context(self, 1.0, DamageType::DROWN, None, None, None)
|
||||
|
||||
@@ -162,6 +162,8 @@ use weather::Weather;
|
||||
|
||||
type FlowingFluidProperties = pumpkin_data::fluid::FlowingWaterLikeFluidProperties;
|
||||
|
||||
const MAX_LIGHT_LEVEL: u8 = 15;
|
||||
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
impl PumpkinError for GetBlockError {
|
||||
@@ -1730,6 +1732,20 @@ impl World {
|
||||
self.weather.lock().await.raining
|
||||
}
|
||||
|
||||
pub async fn is_raining_at(&self, pos: &BlockPos) -> bool {
|
||||
if !self.is_raining().await {
|
||||
return false;
|
||||
}
|
||||
if self.get_heightmap_height(MotionBlocking, pos.0.x, pos.0.z) + 1 > pos.0.y {
|
||||
return false;
|
||||
}
|
||||
self.can_see_sky(pos)
|
||||
&& self
|
||||
.get_biome(pos)
|
||||
.weather
|
||||
.is_rain_at(pos.0.x, pos.0.y, pos.0.z, self.sea_level)
|
||||
}
|
||||
|
||||
pub async fn set_raining(&self, raining: bool) {
|
||||
let mut weather = self.weather.lock().await;
|
||||
if weather.raining != raining {
|
||||
@@ -4439,6 +4455,13 @@ impl World {
|
||||
.get_sky_light_level(&self.level, position)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn can_see_sky(&self, position: &BlockPos) -> bool {
|
||||
position.0.y >= self.dimension.min_y
|
||||
&& position.0.y < self.dimension.min_y + self.dimension.height
|
||||
&& self.get_sky_light_level(position) >= MAX_LIGHT_LEVEL
|
||||
}
|
||||
|
||||
pub fn set_block_light_level(&self, position: &BlockPos, light_level: u8) {
|
||||
let _ = self
|
||||
.level
|
||||
|
||||
Reference in New Issue
Block a user