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:
parent
7405427199
commit
148f203817
5 changed files with 54 additions and 21 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -21,5 +21,6 @@ fn auto_respawn(
|
|||
perform_respawn_events.send(PerformRespawnEvent {
|
||||
entity: event.entity,
|
||||
});
|
||||
println!("auto respawning");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue