mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
* replace slot with ItemStackSeralizer * Dismantle current inv logic * Disassemble even more, items need fixing markd with TODO: Inv * Player inventory methods implmented * make some fields private * remove invalid comment * Partial screen handler and slot * Add armorslot * prepare for crafting * implement some more crafting traits * Fix ItemStack * Fix pickup and remove faulty crafting (getting reworked in inv revamp) * fix * fix error * add readme * move readme file * asd * remove readme * add uppsercase readme * Some more work * merge * Move from generics to dynamics * fix * move to same impl * Some changes * add player open logic * Basic impl of sync and listeners * Why did mojang complicate it so much * bruh * Simplify things with DefaultScreenHandlerBehaviour * Implement partial slot clicks * add * itemhashes are broken * Start implementing packets * fix deadlock * new vanilla update * Use static item refs and use Arc Mutex on invs * working normal click * fix deadlock * implement sync handler * small patch * Implement quick_move * Implement Swap click type * pickup, update bug * start fixing updates * fix pickup desync * Make Inventories non mutexes * Implement some finishing stuff * close screen on player leave * fix pick item * Move to item hashes * remove some logs * begin implementing barrels * Begin implementing barrel * implement barrels * fix clippy + typos * Fix merge conflicts * Fix lint error * don't use unwrap when getting equipment slot * Fix typo and single threaded * Accidentally removed tokio completley * Fix crash when opening barrel holding item * Add support for marking block entities dirty * Player Equipment changes * Make ScreenHandlerFactory own inventory instead of passing in optional * remove log * replace todo's * fix clippy --------- Co-authored-by: Alexander Medvedev <lilalexmed@proton.me>
131 lines
4.2 KiB
Rust
131 lines
4.2 KiB
Rust
use std::sync::Arc;
|
|
|
|
use crate::entity::player::Player;
|
|
use async_trait::async_trait;
|
|
use pumpkin_data::Block;
|
|
use pumpkin_data::fluid::Fluid;
|
|
use pumpkin_data::item::Item;
|
|
use pumpkin_util::GameMode;
|
|
use pumpkin_util::math::position::BlockPos;
|
|
use pumpkin_util::math::vector3::Vector3;
|
|
|
|
use crate::item::pumpkin_item::{ItemMetadata, PumpkinItem};
|
|
use crate::world::{BlockFlags, World};
|
|
|
|
pub struct EmptyBucketItem;
|
|
pub struct FilledBucketItem;
|
|
|
|
impl ItemMetadata for EmptyBucketItem {
|
|
fn ids() -> Box<[u16]> {
|
|
[Item::BUCKET.id].into()
|
|
}
|
|
}
|
|
|
|
impl ItemMetadata for FilledBucketItem {
|
|
fn ids() -> Box<[u16]> {
|
|
[
|
|
Item::WATER_BUCKET.id,
|
|
Item::LAVA_BUCKET.id,
|
|
// TODO drink milk
|
|
// Item::MILK_BUCKET.id,
|
|
// TODO implement these buckets, and getting the item from the world
|
|
// Item::POWDER_SNOW_BUCKET.id,
|
|
// Item::AXOLOTL_BUCKET.id,
|
|
// Item::COD_BUCKET.id,
|
|
// Item::SALMON_BUCKET.id,
|
|
// Item::TROPICAL_FISH_BUCKET.id,
|
|
// Item::PUFFERFISH_BUCKET.id,
|
|
// Item::TADPOLE_BUCKET.id,
|
|
]
|
|
.into()
|
|
}
|
|
}
|
|
|
|
fn get_start_and_end_pos(player: &Player) -> (Vector3<f64>, Vector3<f64>) {
|
|
let start_pos = player.eye_position();
|
|
let (yaw, pitch) = player.rotation();
|
|
let (yaw_rad, pitch_rad) = (f64::from(yaw.to_radians()), f64::from(pitch.to_radians()));
|
|
let block_interaction_range = 4.5; // This is not the same as the block_interaction_range in the
|
|
// player entity.
|
|
let direction = Vector3::new(
|
|
-yaw_rad.sin() * pitch_rad.cos() * block_interaction_range,
|
|
-pitch_rad.sin() * block_interaction_range,
|
|
pitch_rad.cos() * yaw_rad.cos() * block_interaction_range,
|
|
);
|
|
|
|
let end_pos = start_pos.add(&direction);
|
|
(start_pos, end_pos)
|
|
}
|
|
|
|
#[async_trait]
|
|
impl PumpkinItem for EmptyBucketItem {
|
|
#[allow(clippy::too_many_lines)]
|
|
async fn normal_use(&self, _item: &Item, player: &Player) {
|
|
let world = player.world().await.clone();
|
|
let (start_pos, end_pos) = get_start_and_end_pos(player);
|
|
|
|
let checker = async |pos: &BlockPos, world_inner: &Arc<World>| {
|
|
let Ok(state_id) = world_inner.get_block_state_id(pos).await else {
|
|
return false;
|
|
};
|
|
|
|
state_id == Block::WATER.default_state_id || state_id == Block::LAVA.default_state_id
|
|
};
|
|
|
|
let (block_pos, _) = world.raytrace(start_pos, end_pos, checker).await;
|
|
|
|
if let Some(pos) = block_pos {
|
|
let Ok(_state_id) = world.get_block_state_id(&pos).await else {
|
|
return;
|
|
};
|
|
|
|
world
|
|
.set_block_state(&pos, Block::AIR.id, BlockFlags::NOTIFY_NEIGHBORS)
|
|
.await;
|
|
//TODO: Pickup in inv
|
|
}
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl PumpkinItem for FilledBucketItem {
|
|
async fn normal_use(&self, item: &Item, player: &Player) {
|
|
if item.id == Item::MILK_BUCKET.id {
|
|
// TODO implement milk bucket
|
|
return;
|
|
}
|
|
|
|
let world = player.world().await.clone();
|
|
let (start_pos, end_pos) = get_start_and_end_pos(player);
|
|
let checker = async |pos: &BlockPos, world_inner: &Arc<World>| {
|
|
let Ok(state_id) = world_inner.get_block_state_id(pos).await else {
|
|
return false;
|
|
};
|
|
if Fluid::from_state_id(state_id).is_some() {
|
|
return false;
|
|
}
|
|
state_id != Block::AIR.id
|
|
};
|
|
|
|
let (block_pos, block_direction) = world.raytrace(start_pos, end_pos, checker).await;
|
|
|
|
if let (Some(pos), Some(direction)) = (block_pos, block_direction) {
|
|
world
|
|
.set_block_state(
|
|
&pos.offset(direction.to_offset()),
|
|
// Block::WATER.default_state_id,
|
|
if item.id == Item::WATER_BUCKET.id {
|
|
Block::WATER.default_state_id
|
|
} else {
|
|
Block::LAVA.default_state_id
|
|
},
|
|
BlockFlags::NOTIFY_NEIGHBORS,
|
|
)
|
|
.await;
|
|
if player.gamemode.load() != GameMode::Creative {
|
|
//TODO: Pickup in inv
|
|
}
|
|
}
|
|
}
|
|
}
|