feat: implement all missing entities
This commit is contained in:
parent
a36240dd40
commit
6f2c3cd5e3
@ -113,38 +113,43 @@ impl ChunkData {
|
|||||||
position.x, position.y, chunk_data.x_pos, chunk_data.z_pos,
|
position.x, position.y, chunk_data.x_pos, chunk_data.z_pos,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
let section_count = chunk_data.sections.len();
|
let min_y_section = chunk_data.min_y_section;
|
||||||
let mut block_lights = Vec::with_capacity(section_count);
|
let max_y_section = chunk_data
|
||||||
let mut sky_lights = Vec::with_capacity(section_count);
|
.sections
|
||||||
let mut block_palettes = Vec::with_capacity(section_count);
|
.iter()
|
||||||
let mut biome_palettes = Vec::with_capacity(section_count);
|
.map(|s| s.y)
|
||||||
|
.max()
|
||||||
|
.unwrap_or(min_y_section as i8);
|
||||||
|
|
||||||
|
let section_count = (max_y_section as i32 - min_y_section + 1).max(0) as usize;
|
||||||
|
let mut block_lights = vec![LightContainer::Empty(0); section_count];
|
||||||
|
let mut sky_lights = vec![LightContainer::Empty(0); section_count];
|
||||||
|
let mut block_palettes = vec![BlockPalette::default(); section_count];
|
||||||
|
let mut biome_palettes = vec![BiomePalette::default(); section_count];
|
||||||
|
|
||||||
for section in chunk_data.sections {
|
for section in chunk_data.sections {
|
||||||
|
let index = (section.y as i32 - min_y_section) as usize;
|
||||||
|
if index >= section_count {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// When loading light data, missing data should default to 0 (no light)
|
// When loading light data, missing data should default to 0 (no light)
|
||||||
block_lights.push(
|
block_lights[index] = section
|
||||||
section
|
|
||||||
.block_light
|
.block_light
|
||||||
.map_or(LightContainer::Empty(0), LightContainer::Full),
|
.map_or(LightContainer::Empty(0), LightContainer::Full);
|
||||||
);
|
sky_lights[index] = section
|
||||||
sky_lights.push(
|
|
||||||
section
|
|
||||||
.sky_light
|
.sky_light
|
||||||
.map_or(LightContainer::Empty(0), LightContainer::Full),
|
.map_or(LightContainer::Empty(0), LightContainer::Full);
|
||||||
);
|
|
||||||
|
|
||||||
// Convert NBT to Palettes
|
// Convert NBT to Palettes
|
||||||
block_palettes.push(
|
block_palettes[index] = section
|
||||||
section
|
|
||||||
.block_states
|
.block_states
|
||||||
.map(BlockPalette::from_disk_nbt)
|
.map(BlockPalette::from_disk_nbt)
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default();
|
||||||
);
|
biome_palettes[index] = section
|
||||||
biome_palettes.push(
|
|
||||||
section
|
|
||||||
.biomes
|
.biomes
|
||||||
.map(BiomePalette::from_disk_nbt)
|
.map(BiomePalette::from_disk_nbt)
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default();
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assemble the LightEngine
|
// Assemble the LightEngine
|
||||||
|
|||||||
@ -6,7 +6,8 @@ use crate::entity::{
|
|||||||
Entity, NBTStorage,
|
Entity, NBTStorage,
|
||||||
ai::goal::{
|
ai::goal::{
|
||||||
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
look_at_entity::LookAtEntityGoal,
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
},
|
},
|
||||||
mob::{Mob, MobEntity},
|
mob::{Mob, MobEntity},
|
||||||
};
|
};
|
||||||
@ -28,12 +29,16 @@ impl BlazeEntity {
|
|||||||
let mut goal_selector = mob_arc.entity.goals_selector.lock().await;
|
let mut goal_selector = mob_arc.entity.goals_selector.lock().await;
|
||||||
let mut target_selector = mob_arc.entity.target_selector.lock().await;
|
let mut target_selector = mob_arc.entity.target_selector.lock().await;
|
||||||
|
|
||||||
// TODO
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
// TODO: BlazeShootFireballGoal
|
||||||
|
goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, false)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
goal_selector.add_goal(
|
goal_selector.add_goal(
|
||||||
8,
|
8,
|
||||||
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
||||||
);
|
);
|
||||||
goal_selector.add_goal(8, Box::new(RandomLookAroundGoal::default()));
|
goal_selector.add_goal(8, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
target_selector.add_goal(
|
target_selector.add_goal(
|
||||||
2,
|
2,
|
||||||
ActiveTargetGoal::with_default(&mob_arc.entity, &EntityType::PLAYER, true),
|
ActiveTargetGoal::with_default(&mob_arc.entity, &EntityType::PLAYER, true),
|
||||||
|
|||||||
56
pumpkin/src/entity/mob/breeze.rs
Normal file
56
pumpkin/src/entity/mob/breeze.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, swim::SwimGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct BreezeEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BreezeEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let breeze = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(breeze);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for BreezeEntity {}
|
||||||
|
|
||||||
|
impl Mob for BreezeEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
26
pumpkin/src/entity/mob/cave_spider.rs
Normal file
26
pumpkin/src/entity/mob/cave_spider.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
mob::{Mob, MobEntity, spider::SpiderEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct CaveSpiderEntity {
|
||||||
|
pub spider: Arc<SpiderEntity>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CaveSpiderEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let spider = SpiderEntity::new(entity).await;
|
||||||
|
Arc::new(Self { spider })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for CaveSpiderEntity {}
|
||||||
|
|
||||||
|
impl Mob for CaveSpiderEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
self.spider.get_mob_entity()
|
||||||
|
}
|
||||||
|
// TODO: Poison effect on attack
|
||||||
|
}
|
||||||
58
pumpkin/src/entity/mob/creaking.rs
Normal file
58
pumpkin/src/entity/mob/creaking.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct CreakingEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CreakingEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let creaking = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(creaking);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, true)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for CreakingEntity {}
|
||||||
|
|
||||||
|
impl Mob for CreakingEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
56
pumpkin/src/entity/mob/elder_guardian.rs
Normal file
56
pumpkin/src/entity/mob/elder_guardian.rs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, swim::SwimGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct ElderGuardianEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ElderGuardianEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let guardian = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(guardian);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(4, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
5,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(6, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for ElderGuardianEntity {}
|
||||||
|
|
||||||
|
impl Mob for ElderGuardianEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
58
pumpkin/src/entity/mob/endermite.rs
Normal file
58
pumpkin/src/entity/mob/endermite.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct EndermiteEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EndermiteEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let endermite = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(endermite);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, true)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for EndermiteEntity {}
|
||||||
|
|
||||||
|
impl Mob for EndermiteEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
65
pumpkin/src/entity/mob/evoker.rs
Normal file
65
pumpkin/src/entity/mob/evoker.rs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, swim::SwimGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct EvokerEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EvokerEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let evoker = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(evoker);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
// Evokers have complex spell AI, but for now basic movement
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
2,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::VILLAGER, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
3,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::IRON_GOLEM, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for EvokerEntity {}
|
||||||
|
|
||||||
|
impl Mob for EvokerEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
50
pumpkin/src/entity/mob/ghast.rs
Normal file
50
pumpkin/src/entity/mob/ghast.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct GhastEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GhastEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let ghast = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(ghast);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
// TODO: GhastFlyGoal, GhastLookGoal, GhastAttackGoal
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(6, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for GhastEntity {}
|
||||||
|
|
||||||
|
impl Mob for GhastEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_mob_gravity(&self) -> f64 {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
49
pumpkin/src/entity/mob/giant.rs
Normal file
49
pumpkin/src/entity/mob/giant.rs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
melee_attack::MeleeAttackGoal, swim::SwimGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct GiantEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GiantEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let giant = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(giant);
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(2, Box::new(MeleeAttackGoal::new(1.0, true)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for GiantEntity {}
|
||||||
|
|
||||||
|
impl Mob for GiantEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
68
pumpkin/src/entity/mob/guardian.rs
Normal file
68
pumpkin/src/entity/mob/guardian.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, swim::SwimGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct GuardianEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GuardianEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let guardian = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(guardian);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(4, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
5,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(6, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
2,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::SQUID, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
2,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::GLOW_SQUID, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
3,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::AXOLOTL, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for GuardianEntity {}
|
||||||
|
|
||||||
|
impl Mob for GuardianEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
58
pumpkin/src/entity/mob/hoglin.rs
Normal file
58
pumpkin/src/entity/mob/hoglin.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct HoglinEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HoglinEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let hoglin = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(hoglin);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, true)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for HoglinEntity {}
|
||||||
|
|
||||||
|
impl Mob for HoglinEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
64
pumpkin/src/entity/mob/illusioner.rs
Normal file
64
pumpkin/src/entity/mob/illusioner.rs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, swim::SwimGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct IllusionerEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IllusionerEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let illusioner = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(illusioner);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
2,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::VILLAGER, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
3,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::IRON_GOLEM, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for IllusionerEntity {}
|
||||||
|
|
||||||
|
impl Mob for IllusionerEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
25
pumpkin/src/entity/mob/magma_cube.rs
Normal file
25
pumpkin/src/entity/mob/magma_cube.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
mob::{Mob, MobEntity, slime::SlimeEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct MagmaCubeEntity {
|
||||||
|
pub slime: Arc<SlimeEntity>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MagmaCubeEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let slime = SlimeEntity::new(entity).await;
|
||||||
|
Arc::new(Self { slime })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for MagmaCubeEntity {}
|
||||||
|
|
||||||
|
impl Mob for MagmaCubeEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
self.slime.get_mob_entity()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -27,13 +27,37 @@ use uuid::Uuid;
|
|||||||
|
|
||||||
pub mod bat;
|
pub mod bat;
|
||||||
pub mod blaze;
|
pub mod blaze;
|
||||||
|
pub mod breeze;
|
||||||
|
pub mod cave_spider;
|
||||||
|
pub mod creaking;
|
||||||
pub mod creeper;
|
pub mod creeper;
|
||||||
|
pub mod elder_guardian;
|
||||||
pub mod enderman;
|
pub mod enderman;
|
||||||
|
pub mod endermite;
|
||||||
|
pub mod evoker;
|
||||||
|
pub mod ghast;
|
||||||
|
pub mod giant;
|
||||||
|
pub mod guardian;
|
||||||
|
pub mod hoglin;
|
||||||
|
pub mod illusioner;
|
||||||
|
pub mod magma_cube;
|
||||||
|
pub mod phantom;
|
||||||
|
pub mod piglin;
|
||||||
|
pub mod piglin_brute;
|
||||||
|
pub mod pillager;
|
||||||
|
pub mod ravager;
|
||||||
pub mod shulker;
|
pub mod shulker;
|
||||||
pub mod silverfish;
|
pub mod silverfish;
|
||||||
pub mod skeleton;
|
pub mod skeleton;
|
||||||
pub mod slime;
|
pub mod slime;
|
||||||
|
pub mod spider;
|
||||||
|
pub mod vex;
|
||||||
|
pub mod vindicator;
|
||||||
|
pub mod warden;
|
||||||
|
pub mod witch;
|
||||||
|
pub mod zoglin;
|
||||||
pub mod zombie;
|
pub mod zombie;
|
||||||
|
pub mod zombified_piglin;
|
||||||
|
|
||||||
pub struct MobEntity {
|
pub struct MobEntity {
|
||||||
pub living_entity: LivingEntity,
|
pub living_entity: LivingEntity,
|
||||||
@ -78,6 +102,7 @@ impl MobEntity {
|
|||||||
last_sent_head_yaw: AtomicU8::new(0),
|
last_sent_head_yaw: AtomicU8::new(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_in_position_target_range(&self) -> bool {
|
pub fn is_in_position_target_range(&self) -> bool {
|
||||||
self.is_in_position_target_range_pos(&self.living_entity.entity.block_pos.load())
|
self.is_in_position_target_range_pos(&self.living_entity.entity.block_pos.load())
|
||||||
}
|
}
|
||||||
|
|||||||
50
pumpkin/src/entity/mob/phantom.rs
Normal file
50
pumpkin/src/entity/mob/phantom.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct PhantomEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PhantomEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let phantom = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(phantom);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
// TODO: PhantomCircleAroundAnchorGoal, PhantomSweepAttackGoal
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(6, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for PhantomEntity {}
|
||||||
|
|
||||||
|
impl Mob for PhantomEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_mob_gravity(&self) -> f64 {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
71
pumpkin/src/entity/mob/piglin.rs
Normal file
71
pumpkin/src/entity/mob/piglin.rs
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct PiglinEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PiglinEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let piglin = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(piglin);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
// Piglins use crossbows or swords, but for now we give them melee
|
||||||
|
goal_selector.add_goal(2, Box::new(MeleeAttackGoal::new(1.0, true)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
2,
|
||||||
|
ActiveTargetGoal::with_default(
|
||||||
|
&mob_arc.mob_entity,
|
||||||
|
&EntityType::WITHER_SKELETON,
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
2,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::WITHER, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for PiglinEntity {}
|
||||||
|
|
||||||
|
impl Mob for PiglinEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
70
pumpkin/src/entity/mob/piglin_brute.rs
Normal file
70
pumpkin/src/entity/mob/piglin_brute.rs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct PiglinBruteEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PiglinBruteEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let piglin = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(piglin);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(2, Box::new(MeleeAttackGoal::new(1.0, true)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
2,
|
||||||
|
ActiveTargetGoal::with_default(
|
||||||
|
&mob_arc.mob_entity,
|
||||||
|
&EntityType::WITHER_SKELETON,
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
2,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::WITHER, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for PiglinBruteEntity {}
|
||||||
|
|
||||||
|
impl Mob for PiglinBruteEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
67
pumpkin/src/entity/mob/pillager.rs
Normal file
67
pumpkin/src/entity/mob/pillager.rs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct PillagerEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PillagerEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let pillager = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(pillager);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
// Pillagers use crossbows, but for now we give them melee
|
||||||
|
goal_selector.add_goal(2, Box::new(MeleeAttackGoal::new(1.0, true)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
2,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::VILLAGER, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
3,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::IRON_GOLEM, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for PillagerEntity {}
|
||||||
|
|
||||||
|
impl Mob for PillagerEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
66
pumpkin/src/entity/mob/ravager.rs
Normal file
66
pumpkin/src/entity/mob/ravager.rs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct RavagerEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RavagerEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let ravager = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(ravager);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, true)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
2,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::VILLAGER, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
3,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::IRON_GOLEM, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for RavagerEntity {}
|
||||||
|
|
||||||
|
impl Mob for RavagerEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,10 +1,14 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
use pumpkin_data::entity::EntityType;
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
use crate::entity::{
|
use crate::entity::{
|
||||||
Entity, NBTStorage,
|
Entity, NBTStorage,
|
||||||
ai::goal::active_target::ActiveTargetGoal,
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
mob::{Mob, MobEntity},
|
mob::{Mob, MobEntity},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -15,13 +19,26 @@ pub struct SilverfishEntity {
|
|||||||
impl SilverfishEntity {
|
impl SilverfishEntity {
|
||||||
pub async fn new(entity: Entity) -> Arc<Self> {
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
let entity = Arc::new(MobEntity::new(entity));
|
let entity = Arc::new(MobEntity::new(entity));
|
||||||
let zombie = Self { entity };
|
let silverfish = Self { entity };
|
||||||
let mob_arc = Arc::new(zombie);
|
let mob_arc = Arc::new(silverfish);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
|
let mut goal_selector = mob_arc.entity.goals_selector.lock().await;
|
||||||
let mut target_selector = mob_arc.entity.target_selector.lock().await;
|
let mut target_selector = mob_arc.entity.target_selector.lock().await;
|
||||||
|
|
||||||
// TODO
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, false)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
8,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(8, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
target_selector.add_goal(
|
target_selector.add_goal(
|
||||||
2,
|
2,
|
||||||
ActiveTargetGoal::with_default(&mob_arc.entity, &EntityType::PLAYER, true),
|
ActiveTargetGoal::with_default(&mob_arc.entity, &EntityType::PLAYER, true),
|
||||||
|
|||||||
@ -6,7 +6,8 @@ use crate::entity::{
|
|||||||
Entity, NBTStorage,
|
Entity, NBTStorage,
|
||||||
ai::goal::{
|
ai::goal::{
|
||||||
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
look_at_entity::LookAtEntityGoal,
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, revenge::RevengeGoal,
|
||||||
|
swim::SwimGoal, wander_around::WanderAroundGoal,
|
||||||
},
|
},
|
||||||
mob::{Mob, MobEntity},
|
mob::{Mob, MobEntity},
|
||||||
};
|
};
|
||||||
@ -35,12 +36,16 @@ impl SkeletonEntityBase {
|
|||||||
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(2, Box::new(MeleeAttackGoal::new(1.2, false)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
goal_selector.add_goal(
|
goal_selector.add_goal(
|
||||||
8,
|
6,
|
||||||
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
||||||
);
|
);
|
||||||
goal_selector.add_goal(8, Box::new(RandomLookAroundGoal::default()));
|
goal_selector.add_goal(6, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
target_selector.add_goal(1, Box::new(RevengeGoal::new(true)));
|
||||||
target_selector.add_goal(
|
target_selector.add_goal(
|
||||||
2,
|
2,
|
||||||
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
|||||||
@ -1,10 +1,15 @@
|
|||||||
use std::sync::Arc;
|
|
||||||
use std::sync::atomic::Ordering::Relaxed;
|
use std::sync::atomic::Ordering::Relaxed;
|
||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
use pumpkin_data::sound::Sound;
|
use pumpkin_data::sound::Sound;
|
||||||
|
|
||||||
use crate::entity::{
|
use crate::entity::{
|
||||||
Entity, NBTStorage, NbtFuture,
|
Entity, NBTStorage, NbtFuture,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, swim::SwimGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
mob::{Mob, MobEntity},
|
mob::{Mob, MobEntity},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -13,10 +18,36 @@ pub struct SlimeEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SlimeEntity {
|
impl SlimeEntity {
|
||||||
pub fn new(entity: Entity) -> Arc<Self> {
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
Arc::new(Self {
|
let mob_entity = MobEntity::new(entity);
|
||||||
entity: Arc::new(MobEntity::new(entity)),
|
let slime = Self {
|
||||||
})
|
entity: Arc::new(mob_entity),
|
||||||
|
};
|
||||||
|
let mob_arc = Arc::new(slime);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.entity.goals_selector.lock().await;
|
||||||
|
let mut target_selector = mob_arc.entity.target_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(6, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) const fn hurt_sound_for_size(size: i32) -> Sound {
|
pub(crate) const fn hurt_sound_for_size(size: i32) -> Sound {
|
||||||
|
|||||||
64
pumpkin/src/entity/mob/spider.rs
Normal file
64
pumpkin/src/entity/mob/spider.rs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, revenge::RevengeGoal,
|
||||||
|
swim::SwimGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct SpiderEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SpiderEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let spider = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(spider);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(1, Box::new(SwimGoal::default()));
|
||||||
|
// TODO: SpiderAttackGoal for jumping
|
||||||
|
goal_selector.add_goal(3, Box::new(MeleeAttackGoal::new(1.0, false)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(0.8)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(6, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
target_selector.add_goal(1, Box::new(RevengeGoal::new(true)));
|
||||||
|
target_selector.add_goal(
|
||||||
|
2,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
3,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::IRON_GOLEM, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for SpiderEntity {}
|
||||||
|
|
||||||
|
impl Mob for SpiderEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
58
pumpkin/src/entity/mob/vex.rs
Normal file
58
pumpkin/src/entity/mob/vex.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct VexEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VexEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let vex = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(vex);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, true)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for VexEntity {}
|
||||||
|
|
||||||
|
impl Mob for VexEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
66
pumpkin/src/entity/mob/vindicator.rs
Normal file
66
pumpkin/src/entity/mob/vindicator.rs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct VindicatorEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VindicatorEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let vindicator = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(vindicator);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(2, Box::new(MeleeAttackGoal::new(1.0, true)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
2,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::VILLAGER, true),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
3,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::IRON_GOLEM, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for VindicatorEntity {}
|
||||||
|
|
||||||
|
impl Mob for VindicatorEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
58
pumpkin/src/entity/mob/warden.rs
Normal file
58
pumpkin/src/entity/mob/warden.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct WardenEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WardenEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let warden = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(warden);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, true)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(0.5)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for WardenEntity {}
|
||||||
|
|
||||||
|
impl Mob for WardenEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
59
pumpkin/src/entity/mob/witch.rs
Normal file
59
pumpkin/src/entity/mob/witch.rs
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, revenge::RevengeGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct WitchEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WitchEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let witch = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(witch);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(1, Box::new(SwimGoal::default()));
|
||||||
|
// TODO: WitchAttackGoal (potions)
|
||||||
|
goal_selector.add_goal(2, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
3,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
target_selector.add_goal(1, Box::new(RevengeGoal::new(true)));
|
||||||
|
target_selector.add_goal(
|
||||||
|
2,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for WitchEntity {}
|
||||||
|
|
||||||
|
impl Mob for WitchEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
58
pumpkin/src/entity/mob/zoglin.rs
Normal file
58
pumpkin/src/entity/mob/zoglin.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct ZoglinEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZoglinEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let zoglin = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(zoglin);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(4, Box::new(MeleeAttackGoal::new(1.0, true)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for ZoglinEntity {}
|
||||||
|
|
||||||
|
impl Mob for ZoglinEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,11 +1,8 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use pumpkin_data::entity::EntityType;
|
|
||||||
|
|
||||||
use crate::entity::mob::zombie::ZombieEntityBase;
|
use crate::entity::mob::zombie::ZombieEntityBase;
|
||||||
use crate::entity::{
|
use crate::entity::{
|
||||||
Entity, NBTStorage,
|
Entity, NBTStorage,
|
||||||
ai::goal::active_target::ActiveTargetGoal,
|
|
||||||
mob::{Mob, MobEntity},
|
mob::{Mob, MobEntity},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -17,23 +14,7 @@ impl HuskEntity {
|
|||||||
pub async fn new(entity: Entity) -> Arc<Self> {
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
let entity = ZombieEntityBase::new(entity).await;
|
let entity = ZombieEntityBase::new(entity).await;
|
||||||
let zombie = Self { entity };
|
let zombie = Self { entity };
|
||||||
let mob_arc = Arc::new(zombie);
|
Arc::new(zombie)
|
||||||
|
|
||||||
{
|
|
||||||
let mut target_selector = mob_arc.entity.mob_entity.target_selector.lock().await;
|
|
||||||
|
|
||||||
// TODO
|
|
||||||
target_selector.add_goal(
|
|
||||||
2,
|
|
||||||
ActiveTargetGoal::with_default(
|
|
||||||
&mob_arc.entity.mob_entity,
|
|
||||||
&EntityType::PLAYER,
|
|
||||||
true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
mob_arc
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
use super::{Mob, MobEntity};
|
use super::{Mob, MobEntity};
|
||||||
use crate::entity::ai::goal::destroy_egg::DestroyEggGoal;
|
use crate::entity::ai::goal::destroy_egg::DestroyEggGoal;
|
||||||
use crate::entity::ai::goal::look_around::RandomLookAroundGoal;
|
use crate::entity::ai::goal::look_around::RandomLookAroundGoal;
|
||||||
|
use crate::entity::ai::goal::revenge::RevengeGoal;
|
||||||
|
use crate::entity::ai::goal::swim::SwimGoal;
|
||||||
|
use crate::entity::ai::goal::wander_around::WanderAroundGoal;
|
||||||
use crate::entity::ai::goal::zombie_attack::ZombieAttackGoal;
|
use crate::entity::ai::goal::zombie_attack::ZombieAttackGoal;
|
||||||
use crate::entity::{
|
use crate::entity::{
|
||||||
Entity, NBTStorage,
|
Entity, NBTStorage,
|
||||||
@ -33,14 +36,17 @@ impl ZombieEntityBase {
|
|||||||
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(2, ZombieAttackGoal::new(1.0, false));
|
||||||
goal_selector.add_goal(4, DestroyEggGoal::new(1.0, 3));
|
goal_selector.add_goal(4, DestroyEggGoal::new(1.0, 3));
|
||||||
|
goal_selector.add_goal(7, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
goal_selector.add_goal(
|
goal_selector.add_goal(
|
||||||
8,
|
8,
|
||||||
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
||||||
);
|
);
|
||||||
goal_selector.add_goal(8, Box::new(RandomLookAroundGoal::default()));
|
goal_selector.add_goal(8, Box::new(RandomLookAroundGoal::default()));
|
||||||
goal_selector.add_goal(3, ZombieAttackGoal::new(1.0, false));
|
|
||||||
|
|
||||||
|
target_selector.add_goal(1, Box::new(RevengeGoal::new(true)));
|
||||||
target_selector.add_goal(
|
target_selector.add_goal(
|
||||||
2,
|
2,
|
||||||
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, true),
|
||||||
|
|||||||
57
pumpkin/src/entity/mob/zombified_piglin.rs
Normal file
57
pumpkin/src/entity/mob/zombified_piglin.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal,
|
||||||
|
melee_attack::MeleeAttackGoal, swim::SwimGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct ZombifiedPiglinEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZombifiedPiglinEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let piglin = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(piglin);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(2, Box::new(MeleeAttackGoal::new(1.0, true)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let _target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
// Zombified piglins are neutral by default (only attack if hit),
|
||||||
|
// but for now we give it ActiveTargetGoal for players to make them hostile
|
||||||
|
// (or we can leave it empty for neutral behavior).
|
||||||
|
// Let's make them neutral for now (no ActiveTargetGoal).
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for ZombifiedPiglinEntity {}
|
||||||
|
|
||||||
|
impl Mob for ZombifiedPiglinEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/allay.rs
Normal file
53
pumpkin/src/entity/passive/allay.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents an Allay, a passive, flying entity that can collect items for the player.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Allay>
|
||||||
|
pub struct AllayEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AllayEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let allay = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(allay);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for AllayEntity {}
|
||||||
|
|
||||||
|
impl Mob for AllayEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/armadillo.rs
Normal file
53
pumpkin/src/entity/passive/armadillo.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents an Armadillo, a passive entity that can roll into a ball when threatened.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Armadillo>
|
||||||
|
pub struct ArmadilloEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ArmadilloEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let armadillo = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(armadillo);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for ArmadilloEntity {}
|
||||||
|
|
||||||
|
impl Mob for ArmadilloEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/axolotl.rs
Normal file
53
pumpkin/src/entity/passive/axolotl.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents an Axolotl, a passive aquatic mob that can play dead to regenerate health.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Axolotl>
|
||||||
|
pub struct AxolotlEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AxolotlEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let axolotl = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(axolotl);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for AxolotlEntity {}
|
||||||
|
|
||||||
|
impl Mob for AxolotlEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/bee.rs
Normal file
53
pumpkin/src/entity/passive/bee.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Bee, a neutral flying mob that can pollinate crops and sting attackers.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Bee>
|
||||||
|
pub struct BeeEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BeeEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let bee = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(bee);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for BeeEntity {}
|
||||||
|
|
||||||
|
impl Mob for BeeEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/camel.rs
Normal file
53
pumpkin/src/entity/passive/camel.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Camel, a passive mount that can carry two players and dash.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Camel>
|
||||||
|
pub struct CamelEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CamelEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let camel = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(camel);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for CamelEntity {}
|
||||||
|
|
||||||
|
impl Mob for CamelEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,7 +5,8 @@ use pumpkin_data::{entity::EntityType, item::Item};
|
|||||||
use crate::entity::{
|
use crate::entity::{
|
||||||
Entity, NBTStorage,
|
Entity, NBTStorage,
|
||||||
ai::goal::{
|
ai::goal::{
|
||||||
escape_danger::EscapeDangerGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
breed::BreedGoal, escape_danger::EscapeDangerGoal, follow_parent::FollowParentGoal,
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
tempt::TemptGoal, wander_around::WanderAroundGoal,
|
tempt::TemptGoal, wander_around::WanderAroundGoal,
|
||||||
},
|
},
|
||||||
mob::{Mob, MobEntity},
|
mob::{Mob, MobEntity},
|
||||||
@ -13,6 +14,9 @@ use crate::entity::{
|
|||||||
|
|
||||||
const TEMPT_ITEMS: &[&Item] = &[&Item::COD, &Item::SALMON];
|
const TEMPT_ITEMS: &[&Item] = &[&Item::COD, &Item::SALMON];
|
||||||
|
|
||||||
|
/// Represents a Cat, a passive mob that can be tamed and scares away creepers.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Cat>
|
||||||
pub struct CatEntity {
|
pub struct CatEntity {
|
||||||
pub mob_entity: MobEntity,
|
pub mob_entity: MobEntity,
|
||||||
}
|
}
|
||||||
@ -32,12 +36,17 @@ impl CatEntity {
|
|||||||
|
|
||||||
goal_selector.add_goal(1, Box::new(SwimGoal::default()));
|
goal_selector.add_goal(1, Box::new(SwimGoal::default()));
|
||||||
goal_selector.add_goal(1, EscapeDangerGoal::new(1.5));
|
goal_selector.add_goal(1, EscapeDangerGoal::new(1.5));
|
||||||
|
// goal_selector.add_goal(2, SitGoal::new(mob_arc.clone()));
|
||||||
goal_selector.add_goal(4, Box::new(TemptGoal::new(0.6, TEMPT_ITEMS)));
|
goal_selector.add_goal(4, Box::new(TemptGoal::new(0.6, TEMPT_ITEMS)));
|
||||||
|
goal_selector.add_goal(5, BreedGoal::new(0.8));
|
||||||
|
// goal_selector.add_goal(7, FollowOwnerGoal::new(1.0, 10.0, 5.0, false));
|
||||||
|
goal_selector.add_goal(9, Box::new(FollowParentGoal::new(0.8)));
|
||||||
goal_selector.add_goal(11, Box::new(WanderAroundGoal::new(0.8)));
|
goal_selector.add_goal(11, Box::new(WanderAroundGoal::new(0.8)));
|
||||||
goal_selector.add_goal(
|
goal_selector.add_goal(
|
||||||
12,
|
12,
|
||||||
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 10.0),
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 10.0),
|
||||||
);
|
);
|
||||||
|
goal_selector.add_goal(12, Box::new(RandomLookAroundGoal::default()));
|
||||||
};
|
};
|
||||||
|
|
||||||
mob_arc
|
mob_arc
|
||||||
|
|||||||
@ -4,17 +4,21 @@ use std::sync::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use pumpkin_data::item_stack::ItemStack;
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
|
use pumpkin_data::particle::Particle;
|
||||||
|
use pumpkin_data::sound::{Sound, SoundCategory};
|
||||||
use pumpkin_data::{entity::EntityType, item::Item};
|
use pumpkin_data::{entity::EntityType, item::Item};
|
||||||
|
use pumpkin_util::math::vector3::Vector3;
|
||||||
use rand::RngExt;
|
use rand::RngExt;
|
||||||
|
|
||||||
use crate::entity::{
|
use crate::entity::{
|
||||||
Entity, EntityBase, EntityBaseFuture, NBTStorage,
|
Entity, EntityBase, EntityBaseFuture, NBTStorage,
|
||||||
ai::goal::{
|
ai::goal::{
|
||||||
escape_danger::EscapeDangerGoal, look_around::RandomLookAroundGoal,
|
breed::BreedGoal, escape_danger::EscapeDangerGoal, follow_parent::FollowParentGoal,
|
||||||
look_at_entity::LookAtEntityGoal, swim::SwimGoal, tempt::TemptGoal,
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
wander_around::WanderAroundGoal,
|
tempt::TemptGoal, wander_around::WanderAroundGoal,
|
||||||
},
|
},
|
||||||
mob::{Mob, MobEntity},
|
mob::{Mob, MobEntity},
|
||||||
|
player::Player,
|
||||||
};
|
};
|
||||||
|
|
||||||
const TEMPT_ITEMS: &[&Item] = &[
|
const TEMPT_ITEMS: &[&Item] = &[
|
||||||
@ -26,6 +30,9 @@ const TEMPT_ITEMS: &[&Item] = &[
|
|||||||
&Item::PITCHER_POD,
|
&Item::PITCHER_POD,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/// Represents a Chicken, a passive mob that lays eggs and is immune to fall damage.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Chicken>
|
||||||
pub struct ChickenEntity {
|
pub struct ChickenEntity {
|
||||||
pub mob_entity: MobEntity,
|
pub mob_entity: MobEntity,
|
||||||
egg_lay_time: AtomicI32,
|
egg_lay_time: AtomicI32,
|
||||||
@ -50,7 +57,9 @@ impl ChickenEntity {
|
|||||||
|
|
||||||
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
goal_selector.add_goal(1, EscapeDangerGoal::new(1.4));
|
goal_selector.add_goal(1, EscapeDangerGoal::new(1.4));
|
||||||
|
goal_selector.add_goal(2, BreedGoal::new(1.0));
|
||||||
goal_selector.add_goal(3, Box::new(TemptGoal::new(1.0, TEMPT_ITEMS)));
|
goal_selector.add_goal(3, Box::new(TemptGoal::new(1.0, TEMPT_ITEMS)));
|
||||||
|
goal_selector.add_goal(4, Box::new(FollowParentGoal::new(1.1)));
|
||||||
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
goal_selector.add_goal(
|
goal_selector.add_goal(
|
||||||
6,
|
6,
|
||||||
@ -85,4 +94,41 @@ impl Mob for ChickenEntity {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mob_interact<'a>(
|
||||||
|
&'a self,
|
||||||
|
player: &'a Player,
|
||||||
|
item_stack: &'a mut ItemStack,
|
||||||
|
) -> EntityBaseFuture<'a, bool> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let is_food = TEMPT_ITEMS.iter().any(|i| i.id == item_stack.item.id);
|
||||||
|
if is_food && self.is_breeding_ready() && !self.is_in_love() {
|
||||||
|
item_stack.decrement_unless_creative(player.gamemode.load(), 1);
|
||||||
|
|
||||||
|
self.mob_entity.set_love_ticks(600);
|
||||||
|
let entity = &self.mob_entity.living_entity.entity;
|
||||||
|
let world = entity.world.load();
|
||||||
|
let pos = entity.pos.load();
|
||||||
|
|
||||||
|
world
|
||||||
|
.spawn_particle(
|
||||||
|
pos + Vector3::new(0.0, f64::from(entity.height()), 0.0),
|
||||||
|
Vector3::new(0.5, 0.5, 0.5),
|
||||||
|
1.0,
|
||||||
|
7,
|
||||||
|
Particle::Heart,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
world
|
||||||
|
.play_sound(
|
||||||
|
Sound::EntityChickenAmbient,
|
||||||
|
SoundCategory::Neutral,
|
||||||
|
&entity.pos.load(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
53
pumpkin/src/entity/passive/cod.rs
Normal file
53
pumpkin/src/entity/passive/cod.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Cod, a common passive aquatic mob.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Cod>
|
||||||
|
pub struct CodEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CodEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let cod = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(cod);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for CodEntity {}
|
||||||
|
|
||||||
|
impl Mob for CodEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,19 +1,27 @@
|
|||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
|
use pumpkin_data::particle::Particle;
|
||||||
|
use pumpkin_data::sound::{Sound, SoundCategory};
|
||||||
use pumpkin_data::{entity::EntityType, item::Item};
|
use pumpkin_data::{entity::EntityType, item::Item};
|
||||||
|
use pumpkin_util::math::vector3::Vector3;
|
||||||
|
|
||||||
use crate::entity::{
|
use crate::entity::{
|
||||||
Entity, NBTStorage,
|
Entity, EntityBase, EntityBaseFuture, NBTStorage,
|
||||||
ai::goal::{
|
ai::goal::{
|
||||||
escape_danger::EscapeDangerGoal, look_around::RandomLookAroundGoal,
|
breed::BreedGoal, escape_danger::EscapeDangerGoal, follow_parent::FollowParentGoal,
|
||||||
look_at_entity::LookAtEntityGoal, swim::SwimGoal, tempt::TemptGoal,
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
wander_around::WanderAroundGoal,
|
tempt::TemptGoal, wander_around::WanderAroundGoal,
|
||||||
},
|
},
|
||||||
mob::{Mob, MobEntity},
|
mob::{Mob, MobEntity},
|
||||||
|
player::Player,
|
||||||
};
|
};
|
||||||
|
|
||||||
const TEMPT_ITEMS: &[&Item] = &[&Item::WHEAT];
|
const TEMPT_ITEMS: &[&Item] = &[&Item::WHEAT];
|
||||||
|
|
||||||
|
/// Represents a Cow, a common passive mob that provides milk, leather, and beef.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Cow>
|
||||||
pub struct CowEntity {
|
pub struct CowEntity {
|
||||||
pub mob_entity: MobEntity,
|
pub mob_entity: MobEntity,
|
||||||
}
|
}
|
||||||
@ -33,7 +41,9 @@ impl CowEntity {
|
|||||||
|
|
||||||
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
goal_selector.add_goal(1, EscapeDangerGoal::new(2.0));
|
goal_selector.add_goal(1, EscapeDangerGoal::new(2.0));
|
||||||
|
goal_selector.add_goal(2, BreedGoal::new(1.0));
|
||||||
goal_selector.add_goal(3, Box::new(TemptGoal::new(1.25, TEMPT_ITEMS)));
|
goal_selector.add_goal(3, Box::new(TemptGoal::new(1.25, TEMPT_ITEMS)));
|
||||||
|
goal_selector.add_goal(4, Box::new(FollowParentGoal::new(1.25)));
|
||||||
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
goal_selector.add_goal(
|
goal_selector.add_goal(
|
||||||
6,
|
6,
|
||||||
@ -52,4 +62,41 @@ impl Mob for CowEntity {
|
|||||||
fn get_mob_entity(&self) -> &MobEntity {
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
&self.mob_entity
|
&self.mob_entity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mob_interact<'a>(
|
||||||
|
&'a self,
|
||||||
|
player: &'a Player,
|
||||||
|
item_stack: &'a mut ItemStack,
|
||||||
|
) -> EntityBaseFuture<'a, bool> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let is_food = TEMPT_ITEMS.iter().any(|i| i.id == item_stack.item.id);
|
||||||
|
if is_food && self.is_breeding_ready() && !self.is_in_love() {
|
||||||
|
item_stack.decrement_unless_creative(player.gamemode.load(), 1);
|
||||||
|
|
||||||
|
self.mob_entity.set_love_ticks(600);
|
||||||
|
let entity = &self.mob_entity.living_entity.entity;
|
||||||
|
let world = entity.world.load();
|
||||||
|
let pos = entity.pos.load();
|
||||||
|
|
||||||
|
world
|
||||||
|
.spawn_particle(
|
||||||
|
pos + Vector3::new(0.0, f64::from(entity.height()), 0.0),
|
||||||
|
Vector3::new(0.5, 0.5, 0.5),
|
||||||
|
1.0,
|
||||||
|
7,
|
||||||
|
Particle::Heart,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
world
|
||||||
|
.play_sound(
|
||||||
|
Sound::EntityCowAmbient,
|
||||||
|
SoundCategory::Neutral,
|
||||||
|
&entity.pos.load(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
53
pumpkin/src/entity/passive/dolphin.rs
Normal file
53
pumpkin/src/entity/passive/dolphin.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Dolphin, a neutral aquatic mob that can give players the Dolphin's Grace effect.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Dolphin>
|
||||||
|
pub struct DolphinEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DolphinEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let dolphin = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(dolphin);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for DolphinEntity {}
|
||||||
|
|
||||||
|
impl Mob for DolphinEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/donkey.rs
Normal file
53
pumpkin/src/entity/passive/donkey.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Donkey, a passive mob that can be tamed and equipped with chests.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Donkey>
|
||||||
|
pub struct DonkeyEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DonkeyEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let donkey = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(donkey);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.7)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for DonkeyEntity {}
|
||||||
|
|
||||||
|
impl Mob for DonkeyEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
60
pumpkin/src/entity/passive/fox.rs
Normal file
60
pumpkin/src/entity/passive/fox.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::{entity::EntityType, item::Item};
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
breed::BreedGoal, escape_danger::EscapeDangerGoal, follow_parent::FollowParentGoal,
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
tempt::TemptGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
const TEMPT_ITEMS: &[&Item] = &[&Item::SWEET_BERRIES, &Item::GLOW_BERRIES];
|
||||||
|
|
||||||
|
/// Represents a Fox, a passive nocturnal mob.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Fox>
|
||||||
|
pub struct FoxEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FoxEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let fox = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(fox);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, EscapeDangerGoal::new(1.5));
|
||||||
|
goal_selector.add_goal(2, BreedGoal::new(1.0));
|
||||||
|
goal_selector.add_goal(3, Box::new(TemptGoal::new(1.2, TEMPT_ITEMS)));
|
||||||
|
goal_selector.add_goal(4, Box::new(FollowParentGoal::new(1.1)));
|
||||||
|
goal_selector.add_goal(6, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
7,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(8, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for FoxEntity {}
|
||||||
|
|
||||||
|
impl Mob for FoxEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/frog.rs
Normal file
53
pumpkin/src/entity/passive/frog.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Frog, a passive mob that can eat small slimes and magma cubes.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Frog>
|
||||||
|
pub struct FrogEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FrogEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let frog = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(frog);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for FrogEntity {}
|
||||||
|
|
||||||
|
impl Mob for FrogEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/glow_squid.rs
Normal file
53
pumpkin/src/entity/passive/glow_squid.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Glow Squid, a passive aquatic mob that emits a glowing particle effect.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Glow_Squid>
|
||||||
|
pub struct GlowSquidEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GlowSquidEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let glow_squid = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(glow_squid);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for GlowSquidEntity {}
|
||||||
|
|
||||||
|
impl Mob for GlowSquidEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/goat.rs
Normal file
53
pumpkin/src/entity/passive/goat.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Goat, a neutral mob that can jump high and ram players or other mobs.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Goat>
|
||||||
|
pub struct GoatEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GoatEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let goat = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(goat);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for GoatEntity {}
|
||||||
|
|
||||||
|
impl Mob for GoatEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/horse.rs
Normal file
53
pumpkin/src/entity/passive/horse.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Horse, a passive mob that can be tamed and ridden.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Horse>
|
||||||
|
pub struct HorseEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HorseEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let horse = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(horse);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.7)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for HorseEntity {}
|
||||||
|
|
||||||
|
impl Mob for HorseEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,10 +4,17 @@ use pumpkin_data::entity::EntityType;
|
|||||||
|
|
||||||
use crate::entity::{
|
use crate::entity::{
|
||||||
Entity, NBTStorage,
|
Entity, NBTStorage,
|
||||||
ai::goal::{look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal},
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, melee_attack::MeleeAttackGoal, revenge::RevengeGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
mob::{Mob, MobEntity},
|
mob::{Mob, MobEntity},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Represents an Iron Golem, a powerful neutral mob that protects villagers and players.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Iron_Golem>
|
||||||
pub struct IronGolemEntity {
|
pub struct IronGolemEntity {
|
||||||
pub mob_entity: MobEntity,
|
pub mob_entity: MobEntity,
|
||||||
}
|
}
|
||||||
@ -24,13 +31,25 @@ impl IronGolemEntity {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
|
||||||
// TODO
|
goal_selector.add_goal(1, Box::new(MeleeAttackGoal::new(1.0, true)));
|
||||||
|
goal_selector.add_goal(6, Box::new(WanderAroundGoal::new(0.6)));
|
||||||
goal_selector.add_goal(
|
goal_selector.add_goal(
|
||||||
8,
|
7,
|
||||||
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
);
|
);
|
||||||
goal_selector.add_goal(8, Box::new(RandomLookAroundGoal::default()));
|
goal_selector.add_goal(8, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
target_selector.add_goal(1, Box::new(RevengeGoal::new(true)));
|
||||||
|
target_selector.add_goal(
|
||||||
|
2,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::PLAYER, false),
|
||||||
|
);
|
||||||
|
target_selector.add_goal(
|
||||||
|
3,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::ZOMBIE, true),
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
mob_arc
|
mob_arc
|
||||||
|
|||||||
53
pumpkin/src/entity/passive/llama.rs
Normal file
53
pumpkin/src/entity/passive/llama.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Llama, a neutral mob that can be used for carrying items and spits at enemies.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Llama>
|
||||||
|
pub struct LlamaEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LlamaEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let llama = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(llama);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.7)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for LlamaEntity {}
|
||||||
|
|
||||||
|
impl Mob for LlamaEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +1,42 @@
|
|||||||
|
pub mod allay;
|
||||||
|
pub mod armadillo;
|
||||||
|
pub mod axolotl;
|
||||||
|
pub mod bee;
|
||||||
|
pub mod camel;
|
||||||
pub mod cat;
|
pub mod cat;
|
||||||
pub mod chicken;
|
pub mod chicken;
|
||||||
|
pub mod cod;
|
||||||
pub mod cow;
|
pub mod cow;
|
||||||
|
pub mod dolphin;
|
||||||
|
pub mod donkey;
|
||||||
|
pub mod fox;
|
||||||
|
pub mod frog;
|
||||||
|
pub mod glow_squid;
|
||||||
|
pub mod goat;
|
||||||
|
pub mod horse;
|
||||||
pub mod iron_golem;
|
pub mod iron_golem;
|
||||||
|
pub mod llama;
|
||||||
|
pub mod mooshroom;
|
||||||
|
pub mod mule;
|
||||||
|
pub mod ocelot;
|
||||||
|
pub mod panda;
|
||||||
|
pub mod parrot;
|
||||||
pub mod pig;
|
pub mod pig;
|
||||||
|
pub mod polar_bear;
|
||||||
|
pub mod pufferfish;
|
||||||
|
pub mod rabbit;
|
||||||
|
pub mod salmon;
|
||||||
pub mod sheep;
|
pub mod sheep;
|
||||||
|
pub mod skeleton_horse;
|
||||||
|
pub mod sniffer;
|
||||||
pub mod snow_golem;
|
pub mod snow_golem;
|
||||||
|
pub mod squid;
|
||||||
|
pub mod strider;
|
||||||
|
pub mod tadpole;
|
||||||
|
pub mod trader_llama;
|
||||||
|
pub mod tropical_fish;
|
||||||
|
pub mod turtle;
|
||||||
|
pub mod villager;
|
||||||
|
pub mod wandering_trader;
|
||||||
pub mod wolf;
|
pub mod wolf;
|
||||||
|
pub mod zombie_horse;
|
||||||
|
|||||||
53
pumpkin/src/entity/passive/mooshroom.rs
Normal file
53
pumpkin/src/entity/passive/mooshroom.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Mooshroom, a fungal variant of cows that can be milked for mushroom stew.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Mooshroom>
|
||||||
|
pub struct MooshroomEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MooshroomEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let mooshroom = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(mooshroom);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for MooshroomEntity {}
|
||||||
|
|
||||||
|
impl Mob for MooshroomEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/mule.rs
Normal file
53
pumpkin/src/entity/passive/mule.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Mule, a passive mob created by breeding a horse and a donkey.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Mule>
|
||||||
|
pub struct MuleEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MuleEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let mule = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(mule);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.7)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for MuleEntity {}
|
||||||
|
|
||||||
|
impl Mob for MuleEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/ocelot.rs
Normal file
53
pumpkin/src/entity/passive/ocelot.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents an Ocelot, a shy passive mob found in jungles.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Ocelot>
|
||||||
|
pub struct OcelotEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OcelotEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let ocelot = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(ocelot);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for OcelotEntity {}
|
||||||
|
|
||||||
|
impl Mob for OcelotEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/panda.rs
Normal file
53
pumpkin/src/entity/passive/panda.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Panda, a rare passive mob with various personalities.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Panda>
|
||||||
|
pub struct PandaEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PandaEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let panda = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(panda);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for PandaEntity {}
|
||||||
|
|
||||||
|
impl Mob for PandaEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/parrot.rs
Normal file
53
pumpkin/src/entity/passive/parrot.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Parrot, a passive flying mob that can mimic nearby mob sounds.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Parrot>
|
||||||
|
pub struct ParrotEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParrotEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let parrot = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(parrot);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for ParrotEntity {}
|
||||||
|
|
||||||
|
impl Mob for ParrotEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,16 +1,20 @@
|
|||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
use pumpkin_data::entity::EntityType;
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
use pumpkin_data::item::Item;
|
use pumpkin_data::particle::Particle;
|
||||||
|
use pumpkin_data::sound::{Sound, SoundCategory};
|
||||||
|
use pumpkin_data::{entity::EntityType, item::Item};
|
||||||
|
use pumpkin_util::math::vector3::Vector3;
|
||||||
|
|
||||||
use crate::entity::{
|
use crate::entity::{
|
||||||
Entity, NBTStorage,
|
Entity, EntityBase, EntityBaseFuture, NBTStorage,
|
||||||
ai::goal::{
|
ai::goal::{
|
||||||
escape_danger::EscapeDangerGoal, look_around::RandomLookAroundGoal,
|
breed::BreedGoal, escape_danger::EscapeDangerGoal, follow_parent::FollowParentGoal,
|
||||||
look_at_entity::LookAtEntityGoal, swim::SwimGoal, tempt::TemptGoal,
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
wander_around::WanderAroundGoal,
|
tempt::TemptGoal, wander_around::WanderAroundGoal,
|
||||||
},
|
},
|
||||||
mob::{Mob, MobEntity},
|
mob::{Mob, MobEntity},
|
||||||
|
player::Player,
|
||||||
};
|
};
|
||||||
|
|
||||||
const PIG_FOOD: &[&Item] = &[
|
const PIG_FOOD: &[&Item] = &[
|
||||||
@ -20,6 +24,9 @@ const PIG_FOOD: &[&Item] = &[
|
|||||||
&Item::CARROT_ON_A_STICK,
|
&Item::CARROT_ON_A_STICK,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/// Represents a Pig, a common passive mob that provides porkchops.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Pig>
|
||||||
pub struct PigEntity {
|
pub struct PigEntity {
|
||||||
pub mob_entity: MobEntity,
|
pub mob_entity: MobEntity,
|
||||||
}
|
}
|
||||||
@ -39,13 +46,15 @@ impl PigEntity {
|
|||||||
|
|
||||||
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
goal_selector.add_goal(1, EscapeDangerGoal::new(1.25));
|
goal_selector.add_goal(1, EscapeDangerGoal::new(1.25));
|
||||||
goal_selector.add_goal(4, Box::new(TemptGoal::new(1.2, PIG_FOOD)));
|
goal_selector.add_goal(2, BreedGoal::new(1.0));
|
||||||
goal_selector.add_goal(6, Box::new(WanderAroundGoal::new(1.0)));
|
goal_selector.add_goal(3, Box::new(TemptGoal::new(1.2, PIG_FOOD)));
|
||||||
|
goal_selector.add_goal(4, Box::new(FollowParentGoal::new(1.1)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
goal_selector.add_goal(
|
goal_selector.add_goal(
|
||||||
7,
|
6,
|
||||||
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
);
|
);
|
||||||
goal_selector.add_goal(8, Box::new(RandomLookAroundGoal::default()));
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
};
|
};
|
||||||
|
|
||||||
mob_arc
|
mob_arc
|
||||||
@ -58,4 +67,41 @@ impl Mob for PigEntity {
|
|||||||
fn get_mob_entity(&self) -> &MobEntity {
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
&self.mob_entity
|
&self.mob_entity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mob_interact<'a>(
|
||||||
|
&'a self,
|
||||||
|
player: &'a Player,
|
||||||
|
item_stack: &'a mut ItemStack,
|
||||||
|
) -> EntityBaseFuture<'a, bool> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let is_food = PIG_FOOD.iter().any(|i| i.id == item_stack.item.id);
|
||||||
|
if is_food && self.is_breeding_ready() && !self.is_in_love() {
|
||||||
|
item_stack.decrement_unless_creative(player.gamemode.load(), 1);
|
||||||
|
|
||||||
|
self.mob_entity.set_love_ticks(600);
|
||||||
|
let entity = &self.mob_entity.living_entity.entity;
|
||||||
|
let world = entity.world.load();
|
||||||
|
let pos = entity.pos.load();
|
||||||
|
|
||||||
|
world
|
||||||
|
.spawn_particle(
|
||||||
|
pos + Vector3::new(0.0, f64::from(entity.height()), 0.0),
|
||||||
|
Vector3::new(0.5, 0.5, 0.5),
|
||||||
|
1.0,
|
||||||
|
7,
|
||||||
|
Particle::Heart,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
world
|
||||||
|
.play_sound(
|
||||||
|
Sound::EntityPigAmbient,
|
||||||
|
SoundCategory::Neutral,
|
||||||
|
&entity.pos.load(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
60
pumpkin/src/entity/passive/polar_bear.rs
Normal file
60
pumpkin/src/entity/passive/polar_bear.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, swim::SwimGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Polar Bear, a neutral mob found in cold biomes.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Polar_Bear>
|
||||||
|
pub struct PolarBearEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PolarBearEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let polar_bear = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(polar_bear);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
// Polar bears are neutral but aggressive towards foxes
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::FOX, true),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for PolarBearEntity {}
|
||||||
|
|
||||||
|
impl Mob for PolarBearEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
53
pumpkin/src/entity/passive/pufferfish.rs
Normal file
53
pumpkin/src/entity/passive/pufferfish.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Represents a Pufferfish, a passive aquatic mob that can inflate when threatened.
|
||||||
|
///
|
||||||
|
/// Wiki: <https://minecraft.wiki/w/Pufferfish>
|
||||||
|
pub struct PufferfishEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PufferfishEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let pufferfish = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(pufferfish);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for PufferfishEntity {}
|
||||||
|
|
||||||
|
impl Mob for PufferfishEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
57
pumpkin/src/entity/passive/rabbit.rs
Normal file
57
pumpkin/src/entity/passive/rabbit.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::{entity::EntityType, item::Item};
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
breed::BreedGoal, escape_danger::EscapeDangerGoal, follow_parent::FollowParentGoal,
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
tempt::TemptGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
const TEMPT_ITEMS: &[&Item] = &[&Item::CARROT, &Item::GOLDEN_CARROT, &Item::DANDELION];
|
||||||
|
|
||||||
|
pub struct RabbitEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RabbitEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let rabbit = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(rabbit);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(1, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, EscapeDangerGoal::new(2.2));
|
||||||
|
goal_selector.add_goal(2, BreedGoal::new(0.8));
|
||||||
|
goal_selector.add_goal(3, Box::new(TemptGoal::new(1.0, TEMPT_ITEMS)));
|
||||||
|
goal_selector.add_goal(4, Box::new(FollowParentGoal::new(0.8)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(0.6)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
11,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 10.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(11, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for RabbitEntity {}
|
||||||
|
|
||||||
|
impl Mob for RabbitEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
50
pumpkin/src/entity/passive/salmon.rs
Normal file
50
pumpkin/src/entity/passive/salmon.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct SalmonEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SalmonEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let salmon = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(salmon);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for SalmonEntity {}
|
||||||
|
|
||||||
|
impl Mob for SalmonEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,15 +9,22 @@ use pumpkin_data::{
|
|||||||
use pumpkin_protocol::java::client::play::Metadata;
|
use pumpkin_protocol::java::client::play::Metadata;
|
||||||
|
|
||||||
use crate::entity::{
|
use crate::entity::{
|
||||||
Entity, EntityBaseFuture, NBTStorage, NbtFuture,
|
Entity, EntityBase, EntityBaseFuture, NBTStorage, NbtFuture,
|
||||||
ai::goal::{
|
ai::goal::{
|
||||||
eat_grass::EatGrassGoal, escape_danger::EscapeDangerGoal,
|
breed::BreedGoal, eat_grass::EatGrassGoal, escape_danger::EscapeDangerGoal,
|
||||||
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
follow_parent::FollowParentGoal, look_around::RandomLookAroundGoal,
|
||||||
tempt::TemptGoal, wander_around::WanderAroundGoal,
|
look_at_entity::LookAtEntityGoal, swim::SwimGoal, tempt::TemptGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
},
|
},
|
||||||
mob::{Mob, MobEntity},
|
mob::{Mob, MobEntity},
|
||||||
|
player::Player,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
|
use pumpkin_data::particle::Particle;
|
||||||
|
use pumpkin_data::sound::{Sound, SoundCategory};
|
||||||
|
use pumpkin_util::math::vector3::Vector3;
|
||||||
|
|
||||||
const TEMPT_ITEMS: &[&Item] = &[&Item::WHEAT];
|
const TEMPT_ITEMS: &[&Item] = &[&Item::WHEAT];
|
||||||
|
|
||||||
pub struct SheepEntity {
|
pub struct SheepEntity {
|
||||||
@ -43,7 +50,9 @@ impl SheepEntity {
|
|||||||
|
|
||||||
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
goal_selector.add_goal(1, EscapeDangerGoal::new(1.25));
|
goal_selector.add_goal(1, EscapeDangerGoal::new(1.25));
|
||||||
|
goal_selector.add_goal(2, BreedGoal::new(1.0));
|
||||||
goal_selector.add_goal(3, Box::new(TemptGoal::new(1.1, TEMPT_ITEMS)));
|
goal_selector.add_goal(3, Box::new(TemptGoal::new(1.1, TEMPT_ITEMS)));
|
||||||
|
goal_selector.add_goal(4, Box::new(FollowParentGoal::new(1.1)));
|
||||||
goal_selector.add_goal(5, Box::new(EatGrassGoal::default()));
|
goal_selector.add_goal(5, Box::new(EatGrassGoal::default()));
|
||||||
goal_selector.add_goal(6, Box::new(WanderAroundGoal::new(1.0)));
|
goal_selector.add_goal(6, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
goal_selector.add_goal(
|
goal_selector.add_goal(
|
||||||
@ -132,4 +141,41 @@ impl Mob for SheepEntity {
|
|||||||
self.set_sheared(false).await;
|
self.set_sheared(false).await;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mob_interact<'a>(
|
||||||
|
&'a self,
|
||||||
|
player: &'a Player,
|
||||||
|
item_stack: &'a mut ItemStack,
|
||||||
|
) -> EntityBaseFuture<'a, bool> {
|
||||||
|
Box::pin(async move {
|
||||||
|
let is_food = TEMPT_ITEMS.iter().any(|i| i.id == item_stack.item.id);
|
||||||
|
if is_food && self.is_breeding_ready() && !self.is_in_love() {
|
||||||
|
item_stack.decrement_unless_creative(player.gamemode.load(), 1);
|
||||||
|
|
||||||
|
self.mob_entity.set_love_ticks(600);
|
||||||
|
let entity = &self.mob_entity.living_entity.entity;
|
||||||
|
let world = entity.world.load();
|
||||||
|
let pos = entity.pos.load();
|
||||||
|
|
||||||
|
world
|
||||||
|
.spawn_particle(
|
||||||
|
pos + Vector3::new(0.0, f64::from(entity.height()), 0.0),
|
||||||
|
Vector3::new(0.5, 0.5, 0.5),
|
||||||
|
1.0,
|
||||||
|
7,
|
||||||
|
Particle::Heart,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
world
|
||||||
|
.play_sound(
|
||||||
|
Sound::EntitySheepAmbient,
|
||||||
|
SoundCategory::Neutral,
|
||||||
|
&entity.pos.load(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
50
pumpkin/src/entity/passive/skeleton_horse.rs
Normal file
50
pumpkin/src/entity/passive/skeleton_horse.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct SkeletonHorseEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SkeletonHorseEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let horse = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(horse);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.7)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for SkeletonHorseEntity {}
|
||||||
|
|
||||||
|
impl Mob for SkeletonHorseEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
50
pumpkin/src/entity/passive/sniffer.rs
Normal file
50
pumpkin/src/entity/passive/sniffer.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct SnifferEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SnifferEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let sniffer = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(sniffer);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for SnifferEntity {}
|
||||||
|
|
||||||
|
impl Mob for SnifferEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,7 +4,10 @@ use pumpkin_data::entity::EntityType;
|
|||||||
|
|
||||||
use crate::entity::{
|
use crate::entity::{
|
||||||
Entity, NBTStorage,
|
Entity, NBTStorage,
|
||||||
ai::goal::{look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal},
|
ai::goal::{
|
||||||
|
active_target::ActiveTargetGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
mob::{Mob, MobEntity},
|
mob::{Mob, MobEntity},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -15,8 +18,8 @@ pub struct SnowGolemEntity {
|
|||||||
impl SnowGolemEntity {
|
impl SnowGolemEntity {
|
||||||
pub async fn new(entity: Entity) -> Arc<Self> {
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
let mob_entity = MobEntity::new(entity);
|
let mob_entity = MobEntity::new(entity);
|
||||||
let wolf = Self { mob_entity };
|
let snow_golem = Self { mob_entity };
|
||||||
let mob_arc = Arc::new(wolf);
|
let mob_arc = Arc::new(snow_golem);
|
||||||
let mob_weak: Weak<dyn Mob> = {
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
Arc::downgrade(&mob_arc)
|
Arc::downgrade(&mob_arc)
|
||||||
@ -24,13 +27,20 @@ impl SnowGolemEntity {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
let mut target_selector = mob_arc.mob_entity.target_selector.lock().await;
|
||||||
|
|
||||||
// TODO
|
// TODO: SnowballAttackGoal
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
goal_selector.add_goal(
|
goal_selector.add_goal(
|
||||||
8,
|
6,
|
||||||
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(6, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
|
||||||
|
target_selector.add_goal(
|
||||||
|
1,
|
||||||
|
ActiveTargetGoal::with_default(&mob_arc.mob_entity, &EntityType::ZOMBIE, true),
|
||||||
);
|
);
|
||||||
goal_selector.add_goal(8, Box::new(RandomLookAroundGoal::default()));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mob_arc
|
mob_arc
|
||||||
|
|||||||
52
pumpkin/src/entity/passive/squid.rs
Normal file
52
pumpkin/src/entity/passive/squid.rs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct SquidEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SquidEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let squid = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(squid);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
// Squids don't have WanderAroundGoal in vanilla (they use custom movement),
|
||||||
|
// but for now we give it to them.
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.6)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for SquidEntity {}
|
||||||
|
|
||||||
|
impl Mob for SquidEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
50
pumpkin/src/entity/passive/strider.rs
Normal file
50
pumpkin/src/entity/passive/strider.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct StriderEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StriderEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let strider = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(strider);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for StriderEntity {}
|
||||||
|
|
||||||
|
impl Mob for StriderEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
50
pumpkin/src/entity/passive/tadpole.rs
Normal file
50
pumpkin/src/entity/passive/tadpole.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct TadpoleEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TadpoleEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let tadpole = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(tadpole);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for TadpoleEntity {}
|
||||||
|
|
||||||
|
impl Mob for TadpoleEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
50
pumpkin/src/entity/passive/trader_llama.rs
Normal file
50
pumpkin/src/entity/passive/trader_llama.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct TraderLlamaEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TraderLlamaEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let llama = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(llama);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.7)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for TraderLlamaEntity {}
|
||||||
|
|
||||||
|
impl Mob for TraderLlamaEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
50
pumpkin/src/entity/passive/tropical_fish.rs
Normal file
50
pumpkin/src/entity/passive/tropical_fish.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct TropicalFishEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TropicalFishEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let tropical_fish = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(tropical_fish);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for TropicalFishEntity {}
|
||||||
|
|
||||||
|
impl Mob for TropicalFishEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
54
pumpkin/src/entity/passive/turtle.rs
Normal file
54
pumpkin/src/entity/passive/turtle.rs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::{entity::EntityType, item::Item};
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
breed::BreedGoal, look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal,
|
||||||
|
swim::SwimGoal, tempt::TemptGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
const TEMPT_ITEMS: &[&Item] = &[&Item::SEAGRASS];
|
||||||
|
|
||||||
|
pub struct TurtleEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TurtleEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let turtle = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(turtle);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(1, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(2, BreedGoal::new(1.0));
|
||||||
|
goal_selector.add_goal(3, Box::new(TemptGoal::new(1.1, TEMPT_ITEMS)));
|
||||||
|
goal_selector.add_goal(5, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
6,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(7, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for TurtleEntity {}
|
||||||
|
|
||||||
|
impl Mob for TurtleEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
55
pumpkin/src/entity/passive/villager.rs
Normal file
55
pumpkin/src/entity/passive/villager.rs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct VillagerEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VillagerEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let villager = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(villager);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
// Villagers have complex AI, but for now we give them basic movement
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.6)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak.clone(), &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(
|
||||||
|
3,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::VILLAGER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(4, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for VillagerEntity {}
|
||||||
|
|
||||||
|
impl Mob for VillagerEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
50
pumpkin/src/entity/passive/wandering_trader.rs
Normal file
50
pumpkin/src/entity/passive/wandering_trader.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct WanderingTraderEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WanderingTraderEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let trader = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(trader);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.6)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for WanderingTraderEntity {}
|
||||||
|
|
||||||
|
impl Mob for WanderingTraderEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,7 +5,11 @@ use pumpkin_data::item::Item;
|
|||||||
|
|
||||||
use crate::entity::{
|
use crate::entity::{
|
||||||
Entity, NBTStorage,
|
Entity, NBTStorage,
|
||||||
ai::goal::{beg::BegGoal, look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal},
|
ai::goal::{
|
||||||
|
beg::BegGoal, breed::BreedGoal, escape_danger::EscapeDangerGoal,
|
||||||
|
follow_parent::FollowParentGoal, look_around::RandomLookAroundGoal,
|
||||||
|
look_at_entity::LookAtEntityGoal, swim::SwimGoal, wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
mob::{Mob, MobEntity},
|
mob::{Mob, MobEntity},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -26,12 +30,19 @@ impl WolfEntity {
|
|||||||
{
|
{
|
||||||
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(1, Box::new(SwimGoal::default()));
|
||||||
|
// goal_selector.add_goal(2, SitGoal::new(mob_arc.clone()));
|
||||||
|
goal_selector.add_goal(4, EscapeDangerGoal::new(1.5));
|
||||||
|
goal_selector.add_goal(5, BreedGoal::new(1.0));
|
||||||
|
// goal_selector.add_goal(6, FollowOwnerGoal::new(1.0, 10.0, 2.0, false));
|
||||||
|
goal_selector.add_goal(8, Box::new(FollowParentGoal::new(1.1)));
|
||||||
|
goal_selector.add_goal(9, BegGoal::new(8.0, &[&Item::BONE]));
|
||||||
goal_selector.add_goal(
|
goal_selector.add_goal(
|
||||||
8,
|
10,
|
||||||
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 8.0),
|
||||||
);
|
);
|
||||||
goal_selector.add_goal(8, Box::new(RandomLookAroundGoal::default()));
|
goal_selector.add_goal(10, Box::new(RandomLookAroundGoal::default()));
|
||||||
goal_selector.add_goal(9, BegGoal::new(8.0, &[&Item::BONE]));
|
goal_selector.add_goal(12, Box::new(WanderAroundGoal::new(1.0)));
|
||||||
};
|
};
|
||||||
|
|
||||||
mob_arc
|
mob_arc
|
||||||
|
|||||||
50
pumpkin/src/entity/passive/zombie_horse.rs
Normal file
50
pumpkin/src/entity/passive/zombie_horse.rs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
|
use pumpkin_data::entity::EntityType;
|
||||||
|
|
||||||
|
use crate::entity::{
|
||||||
|
Entity, NBTStorage,
|
||||||
|
ai::goal::{
|
||||||
|
look_around::RandomLookAroundGoal, look_at_entity::LookAtEntityGoal, swim::SwimGoal,
|
||||||
|
wander_around::WanderAroundGoal,
|
||||||
|
},
|
||||||
|
mob::{Mob, MobEntity},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct ZombieHorseEntity {
|
||||||
|
pub mob_entity: MobEntity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZombieHorseEntity {
|
||||||
|
pub async fn new(entity: Entity) -> Arc<Self> {
|
||||||
|
let mob_entity = MobEntity::new(entity);
|
||||||
|
let horse = Self { mob_entity };
|
||||||
|
let mob_arc = Arc::new(horse);
|
||||||
|
let mob_weak: Weak<dyn Mob> = {
|
||||||
|
let mob_arc: Arc<dyn Mob> = mob_arc.clone();
|
||||||
|
Arc::downgrade(&mob_arc)
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut goal_selector = mob_arc.mob_entity.goals_selector.lock().await;
|
||||||
|
|
||||||
|
goal_selector.add_goal(0, Box::new(SwimGoal::default()));
|
||||||
|
goal_selector.add_goal(1, Box::new(WanderAroundGoal::new(0.7)));
|
||||||
|
goal_selector.add_goal(
|
||||||
|
2,
|
||||||
|
LookAtEntityGoal::with_default(mob_weak, &EntityType::PLAYER, 6.0),
|
||||||
|
);
|
||||||
|
goal_selector.add_goal(3, Box::new(RandomLookAroundGoal::default()));
|
||||||
|
};
|
||||||
|
|
||||||
|
mob_arc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NBTStorage for ZombieHorseEntity {}
|
||||||
|
|
||||||
|
impl Mob for ZombieHorseEntity {
|
||||||
|
fn get_mob_entity(&self) -> &MobEntity {
|
||||||
|
&self.mob_entity
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,41 +5,114 @@ use pumpkin_util::math::vector3::Vector3;
|
|||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::entity::boss::ender_dragon::EnderDragonEntity;
|
use crate::entity::boss::ender_dragon::EnderDragonEntity;
|
||||||
|
use crate::entity::boss::wither::WitherEntity;
|
||||||
|
use crate::entity::decoration::{
|
||||||
|
armor_stand::ArmorStandEntity, end_crystal::EndCrystalEntity, painting::PaintingEntity,
|
||||||
|
};
|
||||||
|
use crate::entity::experience_orb::ExperienceOrbEntity;
|
||||||
|
use crate::entity::falling::FallingEntity;
|
||||||
|
use crate::entity::item::ItemEntity;
|
||||||
|
use crate::entity::living::LivingEntity;
|
||||||
|
use crate::entity::mob::bat::BatEntity;
|
||||||
use crate::entity::mob::blaze::BlazeEntity;
|
use crate::entity::mob::blaze::BlazeEntity;
|
||||||
|
use crate::entity::mob::breeze::BreezeEntity;
|
||||||
|
use crate::entity::mob::cave_spider::CaveSpiderEntity;
|
||||||
|
use crate::entity::mob::creaking::CreakingEntity;
|
||||||
|
use crate::entity::mob::creeper::CreeperEntity;
|
||||||
|
use crate::entity::mob::elder_guardian::ElderGuardianEntity;
|
||||||
|
use crate::entity::mob::enderman::EndermanEntity;
|
||||||
|
use crate::entity::mob::endermite::EndermiteEntity;
|
||||||
|
use crate::entity::mob::evoker::EvokerEntity;
|
||||||
|
use crate::entity::mob::ghast::GhastEntity;
|
||||||
|
use crate::entity::mob::giant::GiantEntity;
|
||||||
|
use crate::entity::mob::guardian::GuardianEntity;
|
||||||
|
use crate::entity::mob::hoglin::HoglinEntity;
|
||||||
|
use crate::entity::mob::illusioner::IllusionerEntity;
|
||||||
|
use crate::entity::mob::magma_cube::MagmaCubeEntity;
|
||||||
|
use crate::entity::mob::phantom::PhantomEntity;
|
||||||
|
use crate::entity::mob::piglin::PiglinEntity;
|
||||||
|
use crate::entity::mob::piglin_brute::PiglinBruteEntity;
|
||||||
|
use crate::entity::mob::pillager::PillagerEntity;
|
||||||
|
use crate::entity::mob::ravager::RavagerEntity;
|
||||||
use crate::entity::mob::shulker::ShulkerEntity;
|
use crate::entity::mob::shulker::ShulkerEntity;
|
||||||
|
use crate::entity::mob::silverfish::SilverfishEntity;
|
||||||
|
use crate::entity::mob::skeleton::{
|
||||||
|
bogged::BoggedSkeletonEntity, parched::ParchedSkeletonEntity, skeleton::SkeletonEntity,
|
||||||
|
stray::StraySkeletonEntity, wither::WitherSkeletonEntity,
|
||||||
|
};
|
||||||
|
use crate::entity::mob::slime::SlimeEntity;
|
||||||
|
use crate::entity::mob::spider::SpiderEntity;
|
||||||
|
use crate::entity::mob::vex::VexEntity;
|
||||||
|
use crate::entity::mob::vindicator::VindicatorEntity;
|
||||||
|
use crate::entity::mob::warden::WardenEntity;
|
||||||
|
use crate::entity::mob::witch::WitchEntity;
|
||||||
|
use crate::entity::mob::zoglin::ZoglinEntity;
|
||||||
use crate::entity::mob::zombie::zombie_villager::ZombieVillagerEntity;
|
use crate::entity::mob::zombie::zombie_villager::ZombieVillagerEntity;
|
||||||
|
use crate::entity::mob::zombie::{drowned::DrownedEntity, husk::HuskEntity, zombie::ZombieEntity};
|
||||||
|
use crate::entity::mob::zombified_piglin::ZombifiedPiglinEntity;
|
||||||
|
use crate::entity::passive::allay::AllayEntity;
|
||||||
|
use crate::entity::passive::armadillo::ArmadilloEntity;
|
||||||
|
use crate::entity::passive::axolotl::AxolotlEntity;
|
||||||
|
use crate::entity::passive::bee::BeeEntity;
|
||||||
|
use crate::entity::passive::camel::CamelEntity;
|
||||||
|
use crate::entity::passive::cat::CatEntity;
|
||||||
|
use crate::entity::passive::chicken::ChickenEntity;
|
||||||
|
use crate::entity::passive::cod::CodEntity;
|
||||||
|
use crate::entity::passive::cow::CowEntity;
|
||||||
|
use crate::entity::passive::dolphin::DolphinEntity;
|
||||||
|
use crate::entity::passive::donkey::DonkeyEntity;
|
||||||
|
use crate::entity::passive::fox::FoxEntity;
|
||||||
|
use crate::entity::passive::frog::FrogEntity;
|
||||||
|
use crate::entity::passive::glow_squid::GlowSquidEntity;
|
||||||
|
use crate::entity::passive::goat::GoatEntity;
|
||||||
|
use crate::entity::passive::horse::HorseEntity;
|
||||||
|
use crate::entity::passive::iron_golem::IronGolemEntity;
|
||||||
|
use crate::entity::passive::llama::LlamaEntity;
|
||||||
|
use crate::entity::passive::mooshroom::MooshroomEntity;
|
||||||
|
use crate::entity::passive::mule::MuleEntity;
|
||||||
|
use crate::entity::passive::ocelot::OcelotEntity;
|
||||||
|
use crate::entity::passive::panda::PandaEntity;
|
||||||
|
use crate::entity::passive::parrot::ParrotEntity;
|
||||||
|
use crate::entity::passive::pig::PigEntity;
|
||||||
|
use crate::entity::passive::polar_bear::PolarBearEntity;
|
||||||
|
use crate::entity::passive::pufferfish::PufferfishEntity;
|
||||||
|
use crate::entity::passive::rabbit::RabbitEntity;
|
||||||
|
use crate::entity::passive::salmon::SalmonEntity;
|
||||||
|
use crate::entity::passive::sheep::SheepEntity;
|
||||||
|
use crate::entity::passive::skeleton_horse::SkeletonHorseEntity;
|
||||||
|
use crate::entity::passive::sniffer::SnifferEntity;
|
||||||
|
use crate::entity::passive::snow_golem::SnowGolemEntity;
|
||||||
|
use crate::entity::passive::squid::SquidEntity;
|
||||||
|
use crate::entity::passive::strider::StriderEntity;
|
||||||
|
use crate::entity::passive::tadpole::TadpoleEntity;
|
||||||
|
use crate::entity::passive::trader_llama::TraderLlamaEntity;
|
||||||
|
use crate::entity::passive::tropical_fish::TropicalFishEntity;
|
||||||
|
use crate::entity::passive::turtle::TurtleEntity;
|
||||||
|
use crate::entity::passive::villager::VillagerEntity;
|
||||||
|
use crate::entity::passive::wandering_trader::WanderingTraderEntity;
|
||||||
|
use crate::entity::passive::wolf::WolfEntity;
|
||||||
|
use crate::entity::passive::zombie_horse::ZombieHorseEntity;
|
||||||
|
use crate::entity::projectile::ThrownItemEntity;
|
||||||
|
use crate::entity::projectile::arrow::ArrowEntity;
|
||||||
use crate::entity::projectile::egg::EggEntity;
|
use crate::entity::projectile::egg::EggEntity;
|
||||||
use crate::entity::projectile::ender_pearl::EnderPearlEntity;
|
use crate::entity::projectile::ender_pearl::EnderPearlEntity;
|
||||||
|
use crate::entity::projectile::eye_of_ender::EyeOfEnder;
|
||||||
|
use crate::entity::projectile::firework_rocket::FireworkRocketEntity;
|
||||||
|
use crate::entity::projectile::lingering_potion::LingeringPotionEntity;
|
||||||
use crate::entity::projectile::shulker_bullet::ShulkerBulletEntity;
|
use crate::entity::projectile::shulker_bullet::ShulkerBulletEntity;
|
||||||
use crate::entity::projectile::snowball::SnowballEntity;
|
use crate::entity::projectile::snowball::SnowballEntity;
|
||||||
use crate::{
|
use crate::entity::projectile::splash_potion::SplashPotionEntity;
|
||||||
entity::{
|
use crate::entity::projectile::wind_charge::WindChargeEntity;
|
||||||
Entity, EntityBase,
|
use crate::entity::tnt::TNTEntity;
|
||||||
boss::wither::WitherEntity,
|
use crate::entity::vehicle::boat::BoatEntity;
|
||||||
decoration::{
|
use crate::entity::{Entity, EntityBase};
|
||||||
armor_stand::ArmorStandEntity, end_crystal::EndCrystalEntity, painting::PaintingEntity,
|
use crate::world::World;
|
||||||
},
|
use pumpkin_data::Block;
|
||||||
living::LivingEntity,
|
use pumpkin_data::item::Item;
|
||||||
mob::{
|
use pumpkin_data::item_stack::ItemStack;
|
||||||
bat::BatEntity,
|
use std::sync::atomic::AtomicBool;
|
||||||
creeper::CreeperEntity,
|
|
||||||
enderman::EndermanEntity,
|
|
||||||
silverfish::SilverfishEntity,
|
|
||||||
skeleton::{
|
|
||||||
bogged::BoggedSkeletonEntity, parched::ParchedSkeletonEntity,
|
|
||||||
skeleton::SkeletonEntity, stray::StraySkeletonEntity, wither::WitherSkeletonEntity,
|
|
||||||
},
|
|
||||||
slime::SlimeEntity,
|
|
||||||
zombie::{drowned::DrownedEntity, husk::HuskEntity, zombie::ZombieEntity},
|
|
||||||
},
|
|
||||||
passive::{
|
|
||||||
cat::CatEntity, chicken::ChickenEntity, cow::CowEntity, iron_golem::IronGolemEntity,
|
|
||||||
pig::PigEntity, sheep::SheepEntity, snow_golem::SnowGolemEntity, wolf::WolfEntity,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
world::World,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
#[expect(clippy::too_many_lines)]
|
||||||
pub async fn from_type(
|
pub async fn from_type(
|
||||||
entity_type: &'static EntityType,
|
entity_type: &'static EntityType,
|
||||||
position: Vector3<f64>,
|
position: Vector3<f64>,
|
||||||
@ -54,8 +127,9 @@ pub async fn from_type(
|
|||||||
id if id == EntityType::DROWNED.id => DrownedEntity::new(entity).await,
|
id if id == EntityType::DROWNED.id => DrownedEntity::new(entity).await,
|
||||||
id if id == EntityType::HUSK.id => HuskEntity::new(entity).await,
|
id if id == EntityType::HUSK.id => HuskEntity::new(entity).await,
|
||||||
id if id == EntityType::ZOMBIE_VILLAGER.id => ZombieVillagerEntity::new(entity).await,
|
id if id == EntityType::ZOMBIE_VILLAGER.id => ZombieVillagerEntity::new(entity).await,
|
||||||
|
id if id == EntityType::ZOMBIFIED_PIGLIN.id => ZombifiedPiglinEntity::new(entity).await,
|
||||||
|
|
||||||
// Sekelton
|
// Skeleton
|
||||||
id if id == EntityType::SKELETON.id => SkeletonEntity::new(entity).await,
|
id if id == EntityType::SKELETON.id => SkeletonEntity::new(entity).await,
|
||||||
id if id == EntityType::BOGGED.id => BoggedSkeletonEntity::new(entity).await,
|
id if id == EntityType::BOGGED.id => BoggedSkeletonEntity::new(entity).await,
|
||||||
id if id == EntityType::PARCHED.id => ParchedSkeletonEntity::new(entity).await,
|
id if id == EntityType::PARCHED.id => ParchedSkeletonEntity::new(entity).await,
|
||||||
@ -67,14 +141,73 @@ pub async fn from_type(
|
|||||||
id if id == EntityType::ENDERMAN.id => EndermanEntity::new(entity).await,
|
id if id == EntityType::ENDERMAN.id => EndermanEntity::new(entity).await,
|
||||||
|
|
||||||
id if id == EntityType::BLAZE.id => BlazeEntity::new(entity).await,
|
id if id == EntityType::BLAZE.id => BlazeEntity::new(entity).await,
|
||||||
|
id if id == EntityType::SPIDER.id => SpiderEntity::new(entity).await,
|
||||||
|
id if id == EntityType::CAVE_SPIDER.id => CaveSpiderEntity::new(entity).await,
|
||||||
|
id if id == EntityType::GHAST.id => GhastEntity::new(entity).await,
|
||||||
|
id if id == EntityType::MAGMA_CUBE.id => MagmaCubeEntity::new(entity).await,
|
||||||
|
id if id == EntityType::PHANTOM.id => PhantomEntity::new(entity).await,
|
||||||
|
id if id == EntityType::WITCH.id => WitchEntity::new(entity).await,
|
||||||
|
id if id == EntityType::PIGLIN.id => PiglinEntity::new(entity).await,
|
||||||
|
id if id == EntityType::PIGLIN_BRUTE.id => PiglinBruteEntity::new(entity).await,
|
||||||
|
id if id == EntityType::PILLAGER.id => PillagerEntity::new(entity).await,
|
||||||
|
id if id == EntityType::VINDICATOR.id => VindicatorEntity::new(entity).await,
|
||||||
|
id if id == EntityType::EVOKER.id => EvokerEntity::new(entity).await,
|
||||||
|
id if id == EntityType::RAVAGER.id => RavagerEntity::new(entity).await,
|
||||||
|
id if id == EntityType::GUARDIAN.id => GuardianEntity::new(entity).await,
|
||||||
|
id if id == EntityType::ELDER_GUARDIAN.id => ElderGuardianEntity::new(entity).await,
|
||||||
|
id if id == EntityType::WARDEN.id => WardenEntity::new(entity).await,
|
||||||
|
id if id == EntityType::HOGLIN.id => HoglinEntity::new(entity).await,
|
||||||
|
id if id == EntityType::ZOGLIN.id => ZoglinEntity::new(entity).await,
|
||||||
|
id if id == EntityType::BREEZE.id => BreezeEntity::new(entity).await,
|
||||||
|
id if id == EntityType::CREAKING.id => CreakingEntity::new(entity).await,
|
||||||
|
id if id == EntityType::ILLUSIONER.id => IllusionerEntity::new(entity).await,
|
||||||
|
id if id == EntityType::VEX.id => VexEntity::new(entity).await,
|
||||||
|
id if id == EntityType::ENDERMITE.id => EndermiteEntity::new(entity).await,
|
||||||
|
id if id == EntityType::GIANT.id => GiantEntity::new(entity).await,
|
||||||
|
|
||||||
id if id == EntityType::CAT.id => CatEntity::new(entity).await,
|
id if id == EntityType::CAT.id => CatEntity::new(entity).await,
|
||||||
id if id == EntityType::CHICKEN.id => ChickenEntity::new(entity).await,
|
id if id == EntityType::CHICKEN.id => ChickenEntity::new(entity).await,
|
||||||
id if id == EntityType::COW.id => CowEntity::new(entity).await,
|
id if id == EntityType::COW.id => CowEntity::new(entity).await,
|
||||||
id if id == EntityType::PIG.id => PigEntity::new(entity).await,
|
id if id == EntityType::PIG.id => PigEntity::new(entity).await,
|
||||||
id if id == EntityType::SNOW_GOLEM.id => SnowGolemEntity::new(entity).await,
|
|
||||||
id if id == EntityType::IRON_GOLEM.id => IronGolemEntity::new(entity).await,
|
|
||||||
id if id == EntityType::SHEEP.id => SheepEntity::new(entity).await,
|
id if id == EntityType::SHEEP.id => SheepEntity::new(entity).await,
|
||||||
id if id == EntityType::WOLF.id => WolfEntity::new(entity).await,
|
id if id == EntityType::WOLF.id => WolfEntity::new(entity).await,
|
||||||
|
id if id == EntityType::FOX.id => FoxEntity::new(entity).await,
|
||||||
|
id if id == EntityType::RABBIT.id => RabbitEntity::new(entity).await,
|
||||||
|
id if id == EntityType::TURTLE.id => TurtleEntity::new(entity).await,
|
||||||
|
id if id == EntityType::VILLAGER.id => VillagerEntity::new(entity).await,
|
||||||
|
id if id == EntityType::SQUID.id => SquidEntity::new(entity).await,
|
||||||
|
id if id == EntityType::HORSE.id => HorseEntity::new(entity).await,
|
||||||
|
id if id == EntityType::DONKEY.id => DonkeyEntity::new(entity).await,
|
||||||
|
id if id == EntityType::MULE.id => MuleEntity::new(entity).await,
|
||||||
|
id if id == EntityType::ZOMBIE_HORSE.id => ZombieHorseEntity::new(entity).await,
|
||||||
|
id if id == EntityType::SKELETON_HORSE.id => SkeletonHorseEntity::new(entity).await,
|
||||||
|
id if id == EntityType::LLAMA.id => LlamaEntity::new(entity).await,
|
||||||
|
id if id == EntityType::TRADER_LLAMA.id => TraderLlamaEntity::new(entity).await,
|
||||||
|
id if id == EntityType::WANDERING_TRADER.id => WanderingTraderEntity::new(entity).await,
|
||||||
|
id if id == EntityType::ALLAY.id => AllayEntity::new(entity).await,
|
||||||
|
id if id == EntityType::ARMADILLO.id => ArmadilloEntity::new(entity).await,
|
||||||
|
id if id == EntityType::AXOLOTL.id => AxolotlEntity::new(entity).await,
|
||||||
|
id if id == EntityType::BEE.id => BeeEntity::new(entity).await,
|
||||||
|
id if id == EntityType::CAMEL.id => CamelEntity::new(entity).await,
|
||||||
|
id if id == EntityType::FROG.id => FrogEntity::new(entity).await,
|
||||||
|
id if id == EntityType::GOAT.id => GoatEntity::new(entity).await,
|
||||||
|
id if id == EntityType::MOOSHROOM.id => MooshroomEntity::new(entity).await,
|
||||||
|
id if id == EntityType::OCELOT.id => OcelotEntity::new(entity).await,
|
||||||
|
id if id == EntityType::PANDA.id => PandaEntity::new(entity).await,
|
||||||
|
id if id == EntityType::PARROT.id => ParrotEntity::new(entity).await,
|
||||||
|
id if id == EntityType::POLAR_BEAR.id => PolarBearEntity::new(entity).await,
|
||||||
|
id if id == EntityType::SNIFFER.id => SnifferEntity::new(entity).await,
|
||||||
|
id if id == EntityType::STRIDER.id => StriderEntity::new(entity).await,
|
||||||
|
id if id == EntityType::GLOW_SQUID.id => GlowSquidEntity::new(entity).await,
|
||||||
|
id if id == EntityType::COD.id => CodEntity::new(entity).await,
|
||||||
|
id if id == EntityType::SALMON.id => SalmonEntity::new(entity).await,
|
||||||
|
id if id == EntityType::PUFFERFISH.id => PufferfishEntity::new(entity).await,
|
||||||
|
id if id == EntityType::TROPICAL_FISH.id => TropicalFishEntity::new(entity).await,
|
||||||
|
id if id == EntityType::TADPOLE.id => TadpoleEntity::new(entity).await,
|
||||||
|
id if id == EntityType::DOLPHIN.id => DolphinEntity::new(entity).await,
|
||||||
|
|
||||||
|
id if id == EntityType::SNOW_GOLEM.id => SnowGolemEntity::new(entity).await,
|
||||||
|
id if id == EntityType::IRON_GOLEM.id => IronGolemEntity::new(entity).await,
|
||||||
|
|
||||||
id if id == EntityType::WITHER.id => WitherEntity::new(entity).await,
|
id if id == EntityType::WITHER.id => WitherEntity::new(entity).await,
|
||||||
id if id == EntityType::ENDER_DRAGON.id => EnderDragonEntity::new(entity).await,
|
id if id == EntityType::ENDER_DRAGON.id => EnderDragonEntity::new(entity).await,
|
||||||
@ -89,13 +222,72 @@ pub async fn from_type(
|
|||||||
id if id == EntityType::SNOWBALL.id => Arc::new(SnowballEntity::new(entity).await),
|
id if id == EntityType::SNOWBALL.id => Arc::new(SnowballEntity::new(entity).await),
|
||||||
id if id == EntityType::EGG.id => Arc::new(EggEntity::new(entity).await),
|
id if id == EntityType::EGG.id => Arc::new(EggEntity::new(entity).await),
|
||||||
id if id == EntityType::SILVERFISH.id => SilverfishEntity::new(entity).await,
|
id if id == EntityType::SILVERFISH.id => SilverfishEntity::new(entity).await,
|
||||||
id if id == EntityType::SLIME.id => SlimeEntity::new(entity),
|
id if id == EntityType::SLIME.id => SlimeEntity::new(entity).await,
|
||||||
id if id == EntityType::SHULKER.id => ShulkerEntity::new(entity).await,
|
id if id == EntityType::SHULKER.id => ShulkerEntity::new(entity).await,
|
||||||
id if id == EntityType::SHULKER_BULLET.id => {
|
id if id == EntityType::SHULKER_BULLET.id => {
|
||||||
// Shulker bullets are normally spawned by ShulkerEntity directly;
|
// Shulker bullets are normally spawned by ShulkerEntity directly;
|
||||||
// when loaded from the world we create a no-target bullet at the given position.
|
// when loaded from the world we create a no-target bullet at the given position.
|
||||||
Arc::new(ShulkerBulletEntity::orphan(entity))
|
Arc::new(ShulkerBulletEntity::orphan(entity))
|
||||||
}
|
}
|
||||||
|
id if id == EntityType::FALLING_BLOCK.id => {
|
||||||
|
Arc::new(FallingEntity::new(entity, Block::SAND.default_state.id))
|
||||||
|
}
|
||||||
|
id if id == EntityType::EXPERIENCE_ORB.id => Arc::new(ExperienceOrbEntity::new(entity, 1)),
|
||||||
|
id if id == EntityType::TNT.id => Arc::new(TNTEntity::new(entity, 4.0, 80)),
|
||||||
|
id if id == EntityType::ITEM.id => {
|
||||||
|
Arc::new(ItemEntity::new(entity, ItemStack::new(1, &Item::AIR)).await)
|
||||||
|
}
|
||||||
|
id if id == EntityType::ARROW.id => Arc::new(ArrowEntity::new(entity, None)),
|
||||||
|
id if id == EntityType::SPECTRAL_ARROW.id => Arc::new(ArrowEntity::new(entity, None)),
|
||||||
|
id if id == EntityType::WIND_CHARGE.id => {
|
||||||
|
let thrown = ThrownItemEntity {
|
||||||
|
entity,
|
||||||
|
owner_id: None,
|
||||||
|
collides_with_projectiles: false,
|
||||||
|
has_hit: AtomicBool::new(false),
|
||||||
|
};
|
||||||
|
Arc::new(WindChargeEntity::new(thrown))
|
||||||
|
}
|
||||||
|
id if id == EntityType::BREEZE_WIND_CHARGE.id => {
|
||||||
|
let thrown = ThrownItemEntity {
|
||||||
|
entity,
|
||||||
|
owner_id: None,
|
||||||
|
collides_with_projectiles: false,
|
||||||
|
has_hit: AtomicBool::new(false),
|
||||||
|
};
|
||||||
|
Arc::new(WindChargeEntity::new(thrown))
|
||||||
|
}
|
||||||
|
id if id == EntityType::FIREWORK_ROCKET.id => {
|
||||||
|
Arc::new(FireworkRocketEntity::new(entity).await)
|
||||||
|
}
|
||||||
|
id if id == EntityType::SPLASH_POTION.id => Arc::new(SplashPotionEntity::new(entity).await),
|
||||||
|
id if id == EntityType::LINGERING_POTION.id => {
|
||||||
|
Arc::new(LingeringPotionEntity::new(entity).await)
|
||||||
|
}
|
||||||
|
id if id == EntityType::EYE_OF_ENDER.id => Arc::new(EyeOfEnder::new(entity)),
|
||||||
|
id if id == EntityType::ACACIA_BOAT.id
|
||||||
|
|| id == EntityType::ACACIA_CHEST_BOAT.id
|
||||||
|
|| id == EntityType::BIRCH_BOAT.id
|
||||||
|
|| id == EntityType::BIRCH_CHEST_BOAT.id
|
||||||
|
|| id == EntityType::DARK_OAK_BOAT.id
|
||||||
|
|| id == EntityType::DARK_OAK_CHEST_BOAT.id
|
||||||
|
|| id == EntityType::JUNGLE_BOAT.id
|
||||||
|
|| id == EntityType::JUNGLE_CHEST_BOAT.id
|
||||||
|
|| id == EntityType::MANGROVE_BOAT.id
|
||||||
|
|| id == EntityType::MANGROVE_CHEST_BOAT.id
|
||||||
|
|| id == EntityType::OAK_BOAT.id
|
||||||
|
|| id == EntityType::OAK_CHEST_BOAT.id
|
||||||
|
|| id == EntityType::PALE_OAK_BOAT.id
|
||||||
|
|| id == EntityType::PALE_OAK_CHEST_BOAT.id
|
||||||
|
|| id == EntityType::SPRUCE_BOAT.id
|
||||||
|
|| id == EntityType::SPRUCE_CHEST_BOAT.id
|
||||||
|
|| id == EntityType::BAMBOO_RAFT.id
|
||||||
|
|| id == EntityType::BAMBOO_CHEST_RAFT.id
|
||||||
|
|| id == EntityType::CHERRY_BOAT.id
|
||||||
|
|| id == EntityType::CHERRY_CHEST_BOAT.id =>
|
||||||
|
{
|
||||||
|
Arc::new(BoatEntity::new(entity))
|
||||||
|
}
|
||||||
// Fallback Entity
|
// Fallback Entity
|
||||||
_ => {
|
_ => {
|
||||||
if entity_type.attributes.is_empty() {
|
if entity_type.attributes.is_empty() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user