alex/beta-minecraft-rust
Minecraft Beta 1.7.3 Rewrite
BRANCH main
SNAPSHOT Draw terrain GPU-driven from packed per-section buffers with GPU occlusion culling, add a render distance slider (2-128) with a quad/disk shape, cut chunk bookkeeping at high render distances, and fix a light underflow at y=0
DOWNLOAD
root crates server src entity fireball.rs
use common::entity::{Entity, EntityWorld};
use glam::DVec3;
use super::{Kind, Stuck};
use crate::level::Level;
#[derive(Clone, Debug, Default)]
pub struct Fireball {
pub owner: Option<i32>,
pub acceleration: DVec3,
pub stuck: Stuck,
pub shake: i32,
}
impl Level {
pub(super) fn shoot_fireball(&mut self, owner: &Entity, direction: DVec3) {
let mut stored = self.entities.create(Kind::Fireball(Fireball::default()));
let entity = &mut stored.entity;
let scatter = DVec3::from_array(std::array::from_fn(|_| entity.rand.next_gaussian()));
let direction = direction + scatter * 0.4;
let look = owner.look();
let offset = DVec3::new(
look.x * 4.0,
f64::from(owner.height / 2.0) + 0.5,
look.z * 4.0,
);
entity.set_location_and_angles(owner.pos + offset, owner.yaw, owner.pitch);
stored.kind = Kind::Fireball(Fireball {
owner: Some(owner.id),
acceleration: direction / f64::from(direction.length() as f32) * 0.1,
..Default::default()
});
self.entities.insert(stored);
}
pub(super) fn tick_fireball(&mut self, entity: &mut Entity, fireball: &mut Fireball) {
entity.base_update(self);
entity.fire = 10;
fireball.shake = (fireball.shake - 1).max(0);
if self.stays_stuck(entity, &mut fireball.stuck) {
return;
}
let owner = fireball.owner.filter(|_| fireball.stuck.air_ticks < 25);
let (hit, target) = self.projectile_hit(entity, false, owner, 0);
if hit.is_some() || target.is_some() {
if let Some(target) = target {
let source = self.entity_copy(fireball.owner);
self.attack_entity(target, source.as_ref(), 0);
}
self.explode(entity.pos, 1.0, None, true);
entity.dead = true;
return;
}
entity.set_position(entity.pos + entity.motion);
// `inWater` from the start of the tick
entity.motion = (entity.motion + fireball.acceleration) * self.drag(entity, 0.95);
self.spawn_particle("smoke", entity.pos + DVec3::Y * 0.5, DVec3::ZERO);
}
}