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

Add utility function to ItemStack for creating custom PlayerHeads #621

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

NotThatRqd
Copy link

Objective

  • Make it easier to create PlayerHeads with a custom skin.

Solution

  • Quick utility function on the ItemStack struct that will add the necessary NBT for you.

Concerns

  • Not sure if my explanation of how you're supposed to use the function (in the rustdoc) is good enough.
  • Not sure if returning a Result on a function meant to be chained is okay.
  • Not sure if I've chosen a good name for the function.

@NotThatRqd
Copy link
Author

Hmm, not sure why the tests are failing because it doesn't seem like what I changed should cause this to happen

@NotThatRqd NotThatRqd marked this pull request as ready for review June 5, 2024 00:05
@NotThatRqd
Copy link
Author

Some of the tests are failing but I don't think it's related to my changes.

@JackCrumpLeys
Copy link
Contributor

JackCrumpLeys commented Jun 5, 2024

Hmm, not sure why the tests are failing because it doesn't seem like what I changed should cause this to happen

cargo fmt --all

In the example you don't use the command system (a system that is near and dear to me), this encourages library users not to do so. See the command example. I recommend something like this:

#[derive(Command, Debug, Clone)]
#[paths("head")]
#[scopes("valence.command.head")]
enum HeadCommand {
    #[paths("{whos_head}")]
    Head { whos_head: String }, // see https://valence.rs/rustdoc/src/valence_command/parsers/strings.rs.html for more string options
}



fn command_handler(
     mut command_events: EventReader<CommandResultEvent<HeadCommand>>>,
     mut clients_query: Query<(&mut Client, &Username, &Properties, &mut Inventory)>,
 ) {
     for event in command_events.read() {
         let target = if let Some(target_username) = &event.result {
             clients_query
                 .iter()
                 .find(|(_, username, _, _)| username.0 == target_username) 
         } else {
             Some(clients_query.get(event.executor).unwrap())
         };

         if let Some(target) = target {
             let properties = target.2;
             let textures = properties.textures().unwrap();

             // Construct a PlayerHead using `with_playerhead_texture_value`
             let head = ItemStack::new(
                 ItemKind::PlayerHead,
                 1,
                 None,
             ).with_playerhead_texture_value(textures.value.clone()).unwrap();

             let (_, _, _, mut inventory) = clients_query.get_mut(event.executor).unwrap();
             inventory.set_slot(36, head);
         } else {
             let (mut client, _, _, _) = clients_query.get_mut(event.executor).unwrap();
             client.send_chat_message(
                 "No player with that username found on the server".color(Color::RED),
             );
             continue;
         }
     }
 }

This will allow the client to do syntax highlighting and error handling to be done upstream. NOTE: I did not test this code.

@NotThatRqd
Copy link
Author

Wow, didn't know that existed until today 😅
Thanks for letting me know about the command system

One thing though, wouldn't it be like this?

mut command_events: EventReader<CommandResultEvent<HeadCommand>>>,

@JackCrumpLeys
Copy link
Contributor

Wow, didn't know that existed until today 😅
Thanks for letting me know about the command system

One thing though, wouldn't it be like this?

mut command_events: EventReader<CommandResultEvent<HeadCommand>>>,

Haha 😂 silly me. I copied from the command example and forgot to change. Good catch. I will edit to improve clarity in the future.

@NotThatRqd
Copy link
Author

NotThatRqd commented Jun 5, 2024

#[derive(Command, Debug, Clone)]
#[paths("head")]
#[scopes("valence.command.head")]
enum HeadCommand {
    #[paths("{whos_head}")]
    Head { whos_head: String }, // see https://valence.rs/rustdoc/src/valence_command/parsers/strings.rs.html for more string options
}

Is there a way to specify Head must be a Player's username for auto complete? I vageuly remember doing something like that in Bukkit once..

Maybe EntitySelector, but it seems to allow you to select multiple Players or even entities which isn't quite what I'm talking about

@JackCrumpLeys
Copy link
Contributor

JackCrumpLeys commented Jun 5, 2024 via email

@JackCrumpLeys
Copy link
Contributor

JackCrumpLeys commented Jun 5, 2024 via email

@NotThatRqd
Copy link
Author

NotThatRqd commented Jun 5, 2024

Yeah that's a good point, I always thought that the auto complete for online players was clientside but now that I think about it it's probably not

@JackCrumpLeys
Copy link
Contributor

JackCrumpLeys commented Jun 5, 2024

auto complete for online players was clientside

See PlayerSelector this will match players in the server.

@NotThatRqd
Copy link
Author

Doesn't seem to come up when searching in the docs https://valence.rs/rustdoc/valence_command/parsers/index.html?search=PlayerSelector

@NotThatRqd
Copy link
Author

NotThatRqd commented Jun 5, 2024

I edited my comment above, that's what I was considering but it also allows you to select any entity or multiple entities which I don't want, so I think just manually parsing single usernames for online players like I do in the example is fine bc it's pretty simple to do.

@JackCrumpLeys
Copy link
Contributor

Just use the command to get a string.

@NotThatRqd
Copy link
Author

NotThatRqd commented Jun 6, 2024

Alright idk why it doesn't like my formatting, I've ran the formatter on my code.
I'm not sure what this means
Diff in /home/runner/work/valence/valence/crates/valence_protocol/src/item.rs at line __

@JackCrumpLeys
Copy link
Contributor

If you read the pipeline log you can see the executed command and the mentioned diff. You may have an old version of rust try rustup update.

@NotThatRqd
Copy link
Author

Just ran rustup update and then cargo fmt --all -- --check but there weren't any changes :/

@NotThatRqd
Copy link
Author

YES okay I just manually added in the changes it wanted because cargo fmt wouldn't for some reason.

@rj00a
Copy link
Member

rj00a commented Jun 6, 2024

We're using nightly rustfmt settings here, so you probably need to do cargo +nightly fmt or switch to the nightly toochain.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants