mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 17:21:49 -10:00
Hurt crammed mobs by 6 at the max entity cramming limit
Mobs only drew the cramming random and never took damage, so a crowd was never thinned. Vanilla's LivingEntity.pushEntities hurts a mob by 6 on a quarter of the ticks while max_entity_cramming or more non-riding entities are pushable around it.
This commit is contained in:
1 parent
b6c936f82b
commit
f6b467eba9
4 files changed
+25
-8
No files matched your search
@@ -1121,6 +1121,7 @@ pub fn main() -> horizon_client::Result<()> {
|
||||
biomes: &biomes,
|
||||
mob_griefing: true,
|
||||
mob_drops: true,
|
||||
max_entity_cramming: 24,
|
||||
difficulty: LocalDifficulty::new(s.difficulty, world.day_time, 0, 0.0),
|
||||
end: false,
|
||||
world_seed: 0,
|
||||
|
||||
@@ -456,6 +456,7 @@ impl Game<'_> {
|
||||
biomes: self.res.biomes(),
|
||||
mob_griefing: self.ui.rules.bool("mob_griefing"),
|
||||
mob_drops: self.ui.rules.bool("mob_drops"),
|
||||
max_entity_cramming: self.ui.rules.int("max_entity_cramming"),
|
||||
end: self.dim == Dim::End,
|
||||
world_seed: self.level.seed,
|
||||
sea_level: if self.dim == Dim::Nether { 32 } else { 63 },
|
||||
@@ -4561,6 +4562,7 @@ pub(super) fn damage_type(kind: horizon_client::mobs::DamageKind, player: bool)
|
||||
K::SonicBoom => "minecraft:sonic_boom",
|
||||
K::Freeze => "minecraft:freeze",
|
||||
K::OutOfWorld => "minecraft:out_of_world",
|
||||
K::Cramming => "minecraft:cramming",
|
||||
}
|
||||
}
|
||||
/// A Horizon item stack as a loot stack (id, count, damage, enchantments).
|
||||
|
||||
@@ -538,6 +538,8 @@ pub enum DamageKind {
|
||||
Freeze,
|
||||
/// `fell_out_of_world`: below the world's floor.
|
||||
OutOfWorld,
|
||||
/// `cramming`: too many entities in one place (`maxEntityCramming`).
|
||||
Cramming,
|
||||
}
|
||||
/// A damage source: its type, the attacking entity and where it came from.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
@@ -616,6 +618,7 @@ impl Damage {
|
||||
| DamageKind::SonicBoom
|
||||
| DamageKind::Freeze
|
||||
| DamageKind::OutOfWorld
|
||||
| DamageKind::Cramming
|
||||
)
|
||||
}
|
||||
pub fn is_fire(&self) -> bool {
|
||||
@@ -642,6 +645,7 @@ impl Damage {
|
||||
| DamageKind::InWall
|
||||
| DamageKind::Freeze
|
||||
| DamageKind::OutOfWorld
|
||||
| DamageKind::Cramming
|
||||
)
|
||||
}
|
||||
pub fn is_projectile(&self) -> bool {
|
||||
@@ -1811,6 +1815,8 @@ pub struct MobWorld<'a> {
|
||||
pub mob_griefing: bool,
|
||||
/// The `mob_drops` game rule (`shouldDropLoot`).
|
||||
pub mob_drops: bool,
|
||||
/// The `max_entity_cramming` game rule.
|
||||
pub max_entity_cramming: i32,
|
||||
/// `getCurrentDifficultyAt` at the mob being ticked (near the player
|
||||
/// outside the mob tick).
|
||||
pub difficulty: spawning::LocalDifficulty,
|
||||
@@ -2183,6 +2189,7 @@ impl Mob {
|
||||
| DamageKind::InWall
|
||||
| DamageKind::Thorns
|
||||
| DamageKind::OutOfWorld
|
||||
| DamageKind::Cramming
|
||||
| DamageKind::Generic
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1058,7 +1058,8 @@ fn push_entities(m: &mut Mob, w: &MobWorld, events: &mut Vec<MobEvent>) {
|
||||
&& m.species() != Species::Shulker
|
||||
&& !on_climbable(m, w)
|
||||
&& (m.species() != Species::Creaking || super::creaking::can_move(m));
|
||||
let mut targets: Vec<(Who, Vec3)> = Vec::new();
|
||||
// Each with whether it rides a vehicle (`Entity.isPassenger`).
|
||||
let mut targets: Vec<(Who, Vec3, bool)> = Vec::new();
|
||||
if let Some(p) = &w.player
|
||||
// Entity.push: passengers of the same vehicle never push each other.
|
||||
&& m.rider.is_none()
|
||||
@@ -1066,21 +1067,27 @@ fn push_entities(m: &mut Mob, w: &MobWorld, events: &mut Vec<MobEvent>) {
|
||||
&& !p.spectator
|
||||
&& p.bounds.intersects(bounds)
|
||||
{
|
||||
targets.push((Who::Player, p.position));
|
||||
targets.push((Who::Player, p.position, p.passenger));
|
||||
}
|
||||
for o in w.others_near(bounds) {
|
||||
if o.id != m.id && o.alive && o.pushable && o.bounds.intersects(bounds) {
|
||||
targets.push((Who::Mob(o.id), o.position));
|
||||
targets.push((Who::Mob(o.id), o.position, o.passenger));
|
||||
}
|
||||
}
|
||||
// EntitySelector.pushableBy(this): the teams' collision rules.
|
||||
let own = w.teams.of(Who::Mob(m.id));
|
||||
targets.retain(|(who, _)| crate::scoreboard::pushable_by(own, w.teams.of(*who), true));
|
||||
// Cramming (maxEntityCramming 24).
|
||||
if targets.len() > 23 {
|
||||
let _ = m.random.next_int_bound(4);
|
||||
targets.retain(|(who, ..)| crate::scoreboard::pushable_by(own, w.teams.of(*who), true));
|
||||
// Cramming: a quarter of the ticks spent with `maxEntityCramming` or more
|
||||
// others around that are not riding anything hurts it by 6.
|
||||
let limit = w.max_entity_cramming;
|
||||
if limit > 0
|
||||
&& targets.len() as i64 > i64::from(limit) - 1
|
||||
&& m.random.next_int_bound(4).unwrap_or(1) == 0
|
||||
&& targets.iter().filter(|t| !t.2).count() as i64 > i64::from(limit) - 1
|
||||
{
|
||||
m.damage(6.0, Damage::of(DamageKind::Cramming));
|
||||
}
|
||||
for (who, at) in targets {
|
||||
for (who, at, _) in targets {
|
||||
// Warden.doPush: touching it angers it, then the push itself.
|
||||
if m.species() == Species::Warden {
|
||||
super::warden::do_push(m, w, who, events);
|
||||
|
||||
Reference in new issue
Block a user