aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2023-07-15 02:06:19 -0500
committermat <git@matdoes.dev>2023-07-15 02:06:19 -0500
commit148f20381750be3e2c38a6bdaf8d339113da1b39 (patch)
tree893fc171b4228eb7c90d4df7c3394e22042a3d6b
parent7405427199e5a994d4a6a706f84434a69cb7a7d9 (diff)
downloadazalea-drasl-148f20381750be3e2c38a6bdaf8d339113da1b39.tar.xz
fix auto respawn and fix entity metadata
-rw-r--r--azalea-client/src/client.rs8
-rw-r--r--azalea-client/src/packet_handling.rs62
-rw-r--r--azalea-entity/src/info.rs2
-rw-r--r--azalea/examples/testbot.rs2
-rw-r--r--azalea/src/auto_respawn.rs1
5 files changed, 54 insertions, 21 deletions
diff --git a/azalea-client/src/client.rs b/azalea-client/src/client.rs
index 0b1fccc1..301d9197 100644
--- a/azalea-client/src/client.rs
+++ b/azalea-client/src/client.rs
@@ -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
diff --git a/azalea-client/src/packet_handling.rs b/azalea-client/src/packet_handling.rs
index fd8d77e5..4ceb3999 100644
--- a/azalea-client/src/packet_handling.rs
+++ b/azalea-client/src/packet_handling.rs
@@ -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
diff --git a/azalea-entity/src/info.rs b/azalea-entity/src/info.rs
index 18021d36..0c5fd3d3 100644
--- a/azalea-entity/src/info.rs
+++ b/azalea-entity/src/info.rs
@@ -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 {
diff --git a/azalea/examples/testbot.rs b/azalea/examples/testbot.rs
index d9bd8681..337ac6ec 100644
--- a/azalea/examples/testbot.rs
+++ b/azalea/examples/testbot.rs
@@ -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 {
diff --git a/azalea/src/auto_respawn.rs b/azalea/src/auto_respawn.rs
index 77a75b4b..6d9c5954 100644
--- a/azalea/src/auto_respawn.rs
+++ b/azalea/src/auto_respawn.rs
@@ -21,5 +21,6 @@ fn auto_respawn(
perform_respawn_events.send(PerformRespawnEvent {
entity: event.entity,
});
+ println!("auto respawning");
}
}