Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Damaging entities + death #556

Open
SelfMadeSystem opened this issue Oct 12, 2023 · 0 comments
Open

Damaging entities + death #556

SelfMadeSystem opened this issue Oct 12, 2023 · 0 comments
Labels
enhancement New feature or request

Comments

@SelfMadeSystem
Copy link
Contributor

SelfMadeSystem commented Oct 12, 2023

Describe the problem related to your feature request.

We need a way to damage & heal entities. We can currently just set their health via valence_entity::living::Health, but there are a few problems with this:

If decrementing health:

  1. This doesn't have a damage source (e.g. magic, wither, pvp ig idk, etc.)
  2. The entity's health just drops, without any effect (sound effect, camera effect, etc.)
  3. There's no death either. If the entity dies, they just stay there and if the client gets a death screen, they're soft locked because they can't respawn.
  4. Absorption isn't considered. See Absorption #557

If incrementing health:

  1. We have no way of knowing the entity's max health yet. See Add EntityAttributes #555 for EntityAttributes

What solution would you like?

  1. A way to damage entities
  2. Damage sources
  3. A way to heal entities

What alternative(s) have you considered?

Just setting Health, but it has drawbacks as previously mentioned.

Additional context

See net.minecraft.entity.damage

@SelfMadeSystem SelfMadeSystem added the enhancement New feature or request label Oct 12, 2023
dyc3 added a commit that referenced this issue Oct 13, 2023
# Problem

See #557

Will be necessary to implement #556 and #558

# Objective

Implement absorption for ALL living entities.

# Solution

Make a special case for LivingEntity for Absorption since it's
untracked.

# Playground

<details>
<summary>Playground</summary>

```rs
use valence::client::despawn_disconnected_clients;
use valence::entity::living::Absorption;
use valence::log::LogPlugin;
use valence::network::ConnectionMode;
use valence::prelude::*;

#[allow(unused_imports)]
use crate::extras::*;

const SPAWN_Y: i32 = 64;

pub fn build_app(app: &mut App) {
    app.insert_resource(NetworkSettings {
        connection_mode: ConnectionMode::Offline,
        ..Default::default()
    })
    .add_plugins(DefaultPlugins.build().disable::<LogPlugin>())
    .add_systems(Startup, setup)
    .add_systems(EventLoopUpdate, toggle_absorption_on_sneak)
    .add_systems(Update, (init_clients, despawn_disconnected_clients))
    .run();
}

fn setup(
    mut commands: Commands,
    server: Res<Server>,
    biomes: Res<BiomeRegistry>,
    dimensions: Res<DimensionTypeRegistry>,
) {
    let mut layer = LayerBundle::new(ident!("overworld"), &dimensions, &biomes, &server);

    for z in -5..5 {
        for x in -5..5 {
            layer.chunk.insert_chunk([x, z], UnloadedChunk::new());
        }
    }

    for z in -25..25 {
        for x in -25..25 {
            layer
                .chunk
                .set_block([x, SPAWN_Y, z], BlockState::GRASS_BLOCK);
        }
    }

    commands.spawn(layer);
}

fn init_clients(
    mut clients: Query<
        (
            &mut EntityLayerId,
            &mut VisibleChunkLayer,
            &mut VisibleEntityLayers,
            &mut Position,
            &mut GameMode,
        ),
        Added<Client>,
    >,
    layers: Query<Entity, (With<ChunkLayer>, With<EntityLayer>)>,
) {
    for (
        mut layer_id,
        mut visible_chunk_layer,
        mut visible_entity_layers,
        mut pos,
        mut game_mode,
    ) in &mut clients
    {
        let layer = layers.single();

        layer_id.0 = layer;
        visible_chunk_layer.0 = layer;
        visible_entity_layers.0.insert(layer);
        pos.set([0.0, SPAWN_Y as f64 + 1.0, 0.0]);
        *game_mode = GameMode::Survival;
    }
}

pub fn toggle_absorption_on_sneak(
    mut clients: Query<&mut Absorption>,
    mut events: EventReader<SneakEvent>,
) {
    for event in events.iter() {
        if event.state == SneakState::Start {
            if let Ok(mut absorption) = clients.get_mut(event.client) {
                absorption.0 = if absorption.0 == 0.0 { 4.0 } else { 0.0 };
            }
        }
    }
}
```
</details>

---------

Co-authored-by: Carson McManus <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant