Theme

alex/beta-minecraft-rust

Minecraft Beta 1.7.3 Rewrite

BRANCH main
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
Download file

root / crates / server / src / player / stats.rs

use super::ServerPlayer;
use crate::level::Level;
use common::item::{Item, ItemStack};
use common::protocol::Packet;
use common::stats;

impl Level {
    pub(crate) fn add_stat(&mut self, player: i32, id: i32, amount: i32) {
        if amount > 0 && !stats::independent(id) {
            self.statistics
                .entry(player)
                .or_default()
                .push((id, amount));
        }
    }
    pub(crate) fn achievement(&mut self, player: i32, index: usize) {
        self.add_stat(player, stats::ACHIEVEMENT + index as i32, 1);
    }
}
impl ServerPlayer {
    pub(super) fn send_stat(&mut self, id: i32, mut amount: i32) {
        if stats::independent(id) {
            return;
        }
        while amount > 0 {
            let part = amount.min(100);
            self.send(Packet::Statistic {
                id,
                amount: part as i8,
            });
            amount -= part;
        }
    }
    pub(super) fn flush_stats(&mut self, level: &mut Level) {
        for (id, amount) in level
            .statistics
            .entry(self.entity_id)
            .or_default()
            .drain(..)
        {
            self.send_stat(id, amount);
        }
    }
    pub(super) fn crafted(&mut self, stack: ItemStack) {
        self.send_stat(stats::CRAFT + stats::item_id(stack.item), stack.count);
        if let Some(index) = stats::crafted_achievement(stack) {
            self.send_stat(stats::ACHIEVEMENT + index as i32, 1);
        }
    }
    pub(super) fn damage_held(&mut self, amount: i32) {
        let before = self.inventory.held();
        self.inventory.damage_held(amount);
        if let Some(stack) = before
            && self.inventory.held().is_none()
        {
            self.send_stat(stats::BREAK + stats::item_id(stack.item), 1);
        }
    }
    pub(super) fn used_item(&mut self, stack: ItemStack) {
        self.send_stat(stats::USE + stats::item_id(stack.item), 1);
    }
    pub(super) fn picked_up(&mut self, item: Item) {
        if item == Item::from_block(common::world::Block::LOG) {
            self.send_stat(stats::ACHIEVEMENT + 1, 1);
        } else if item == Item::LEATHER {
            self.send_stat(stats::ACHIEVEMENT + 14, 1);
        }
    }
}