1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 06:16:04 +00:00

fix auto respawn and fix entity metadata

This commit is contained in:
mat 2023-07-15 02:06:19 -05:00
parent 7405427199
commit 148f203817
5 changed files with 54 additions and 21 deletions

View file

@ -20,7 +20,7 @@ use crate::{
use azalea_auth::{game_profile::GameProfile, sessionserver::ClientSessionServerError};
use azalea_chat::FormattedText;
use azalea_core::Vec3;
use azalea_entity::{EntityPlugin, EntityUpdateSet, Local, Position};
use azalea_entity::{metadata::Health, EntityPlugin, EntityUpdateSet, Local, Position};
use azalea_physics::{PhysicsPlugin, PhysicsSet};
use azalea_protocol::{
connect::{Connection, ConnectionError},
@ -548,6 +548,12 @@ impl Client {
pub fn position(&self) -> Vec3 {
Vec3::from(&self.component::<Position>())
}
/// Get the health of this client.
///
/// This is a shortcut for `*bot.component::<Health>()`.
pub fn health(&self) -> f32 {
*self.component::<Health>()
}
}
/// A bundle for the components that are present on a local player that received

View file

@ -3,8 +3,8 @@ use std::{collections::HashSet, io::Cursor, sync::Arc};
use azalea_core::{ChunkPos, GameMode, ResourceLocation, Vec3};
use azalea_entity::{
metadata::{apply_metadata, Health, PlayerMetadataBundle},
Dead, EntityBundle, EntityKind, EntityUpdateSet, LastSentPosition, LoadedBy, LookDirection,
Physics, PlayerBundle, Position, RelativeEntityUpdate,
Dead, EntityBundle, EntityInfos, EntityKind, EntityUpdateSet, LastSentPosition, LoadedBy,
LookDirection, Physics, PlayerBundle, Position, RelativeEntityUpdate,
};
use azalea_protocol::{
connect::{ReadConnection, WriteConnection},
@ -21,14 +21,15 @@ use azalea_protocol::{
read::ReadPacketError,
};
use azalea_world::{InstanceContainer, InstanceName, MinecraftEntityId, PartialInstance};
use bevy_app::{App, First, Plugin, PreUpdate};
use bevy_app::{App, First, Plugin, PreUpdate, Update};
use bevy_ecs::{
component::Component,
entity::Entity,
event::{EventReader, EventWriter, Events},
prelude::Event,
query::Changed,
schedule::IntoSystemConfigs,
system::{Commands, Query, ResMut, SystemState},
system::{Commands, Query, Res, ResMut, SystemState},
world::World,
};
use log::{debug, error, trace, warn};
@ -86,6 +87,7 @@ impl Plugin for PacketHandlerPlugin {
// we want to index and deindex right after
.before(EntityUpdateSet::Deindex),
)
.add_systems(Update, death_event_on_0_health)
.init_resource::<Events<PacketEvent>>()
.add_event::<AddPlayerEvent>()
.add_event::<RemovePlayerEvent>()
@ -130,6 +132,20 @@ pub struct DeathEvent {
pub packet: Option<ClientboundPlayerCombatKillPacket>,
}
pub fn death_event_on_0_health(
query: Query<(Entity, &Health), Changed<Health>>,
mut death_events: EventWriter<DeathEvent>,
) {
for (entity, health) in query.iter() {
if **health == 0. {
death_events.send(DeathEvent {
entity,
packet: None,
});
}
}
}
/// A KeepAlive packet is sent from the server to verify that the client is
/// still connected.
#[derive(Event, Debug, Clone)]
@ -558,18 +574,37 @@ fn process_packet_events(ecs: &mut World) {
ClientboundGamePacket::AddEntity(p) => {
debug!("Got add entity packet {:?}", p);
let mut system_state: SystemState<(Commands, Query<Option<&InstanceName>>)> =
SystemState::new(ecs);
let (mut commands, mut query) = system_state.get_mut(ecs);
let world_name = query.get_mut(player_entity).unwrap();
let mut system_state: SystemState<(
Commands,
Query<Option<&InstanceName>>,
ResMut<InstanceContainer>,
ResMut<EntityInfos>,
)> = SystemState::new(ecs);
let (mut commands, mut query, mut instance_container, mut entity_infos) =
system_state.get_mut(ecs);
let instance_name = query.get_mut(player_entity).unwrap();
if let Some(InstanceName(world_name)) = world_name {
let bundle = p.as_entity_bundle(world_name.clone());
if let Some(instance_name) = instance_name {
let bundle = p.as_entity_bundle((**instance_name).clone());
let mut entity_commands = commands.spawn((
MinecraftEntityId(p.id),
LoadedBy(HashSet::from([player_entity])),
bundle,
));
{
// add it to the indexes immediately so if there's a packet that references
// it immediately after it still works
let instance = instance_container.get(instance_name).unwrap();
instance
.write()
.entity_by_id
.insert(MinecraftEntityId(p.id), entity_commands.id());
entity_infos
.entity_by_uuid
.insert(p.uuid, entity_commands.id());
}
// the bundle doesn't include the default entity metadata so we add that
// separately
p.apply_metadata(&mut entity_commands);
@ -664,13 +699,6 @@ fn process_packet_events(ecs: &mut World) {
let (mut query, mut death_events) = system_state.get_mut(ecs);
let mut health = query.get_mut(player_entity).unwrap();
if p.health == 0. && **health != 0. {
death_events.send(DeathEvent {
entity: player_entity,
packet: None,
});
}
**health = p.health;
// the `Dead` component is added by the `update_dead` system

View file

@ -170,7 +170,7 @@ impl EntityCommand for RelativeEntityUpdate {
#[derive(Resource, Default)]
pub struct EntityInfos {
/// An index of entities by their UUIDs
pub(crate) entity_by_uuid: HashMap<Uuid, Entity>,
pub entity_by_uuid: HashMap<Uuid, Entity>,
}
impl EntityInfos {

View file

@ -45,11 +45,9 @@ async fn main() -> anyhow::Result<()> {
}
let mut accounts = Vec::new();
let mut states = Vec::new();
for i in 0..1 {
accounts.push(Account::offline(&format!("bot{i}")));
states.push(State::default());
}
loop {

View file

@ -21,5 +21,6 @@ fn auto_respawn(
perform_respawn_events.send(PerformRespawnEvent {
entity: event.entity,
});
println!("auto respawning");
}
}