Teleport a player to block some dynamically

J’ai un petit problème et j’aimerais le résoudre.

Pour commencer:
J’ai créé un plugin de limite de monde. j’ai définie un centre qui est en X:0 et Z:0. Je délimite un cercle de 2000 bloc de rayon. J’en profite pour afficher ma limite de monde sur dynmap.
Ensuite, je regarde chaque seconde si les joueurs sont dans le cercle ou à l’extérieur. Si le joueur est à l’extérieur, je lui enlève 2 cœurs de vie à chaque fois avec un petit message d’avertissement.

Plutôt que de tuer le joueur, j’aimerais que quand il lui reste par exemple 2 cœurs le téléporté quelques blocs en arrière dans la zone, mais je ne sais pas comment faire, car pour le tp en arrière il faut connaitre les coordonnées.

J’ai vu qu’avec ce code je pouvais déplacer le joueur de quelques blocs:

    Vector3d rotation = player.getRotation();
    Direction dir = cardinalDirectionFromPitch(rotation.getX());
    Vector3d diff = dir.toVector3d().normalize().mul(3);
    Location newLoc = player.getLocation().add(diff);
    player.setLocationSafely(newLoc);

Donc je me dit: est ce qu’on peut créer une sorte de direction ou plutôt une position par exemple en X:0 et Z:0 et donc dès que le joueur sortirait du cercle on pourrait téléporter le joueur d’un nombre de bloc choisit vers cette position ou en arrière.
C’est possible ?

Google traduction:
I have a small problem and I would solve it.

To begin:
I created a world of limited plugin. I have a center which is defined by X 0 and Z 0. I delimits a circle of radius 2000 block. I take this opportunity to show the world my limit on Dynmap.
Then I look every second if players are in the circle or outside. If the player is outside, I take her life two hearts each time with a little warning.

Rather than kill the player, I would like that when he still has two
hearts eg teleported the few blocks back in the area, but I do not know
how to do, because right back tp must know the coordinates.

I saw that with this code I could move the player a few blocks:

Vector3D rotation player.getRotation = ();
Direction dir = cardinalDirectionFromPitch (rotation.getX ());
Vector3D = dir.toVector3d diff () normalize () mul (3)..;
NewLoc = player.getLocation Rentals () add (diff).
player.setLocationSafely (newLoc);

So
I said to myself, is what we can create a kind of management or rather a
position eg X: 0 and Z 0 and therefore when the player is beyond the
circle could teleport the player a number of block chooses to that position or backward.
It’s possible ?

Vector3d position = player.getLocation().getPosition();
Vector3d towards000 = position.negate();
Vector3d towards0y0 = new Vector3d(towards000.getX(),position.getY(),towards000.getZ())
Location newLoc = player.getLocation().add(towards0y0.normalize().mul(3));

Merci pour ton aide.
Eclipse me dit: The method setY(double) is undefined for the type Vector3d

Google traduction:
Thank you for your help.
Eclipse said: The method setY(double) is undefined for the type Vector3d

I forgot Vector3d was immutable.

replace broken line with Vector3d towards0y0 = new Vector3d(towards000.getX(),position.getY(),towards000.getZ())

I’ve edited the original post.

Dernière chose: est ce qu’on peut afficher ParticleTypes.HEART comme image dans les messages du chat ? Ce n’est pas les même cœurs, mais ça y ressemble:

Texts.builder("❤ ")
.color(TextColors.RED)
.style(TextStyles.BOLD)
.build();

Dernière chose: est ce qu’on peut récupérer le nom du bloc que le curseur pointe qu’on voit en faisant F3 ?

Google trad:
Last thing is what we can see Particle Types.HEART as picture messages in chat? This is not the same hearts, but it looks like:

Texts.builder("❤ ")
.color(TextColors.RED)
.style(TextStyles.BOLD)
.build();

Last thing is what we can retrieve the name of the block that the cursor is seen by F3 ?

Thank you for your help.

I’m sorry I do not understand.

Je veux récupérer ce qui est affiché la:


Google traduction:
I want to recover what is displayed in red:

Last thing is what we can see Particle Types.HEART as picture messages in chat?

No. Chat is only for text. The :heart: in your example is just a special symbol.

Last thing is what we can retrieve the name of the block that the cursor is seen by F3?

Location loc = ...;
BlockType blockType = loc.getBlockType();

What you do next depends on why you need the name.

  • If you just want to check if the block is of a specific type (chest, trapped chest, wool, etc.), then use boolean matches = blockType.equals(BlockTypes.CHEST); (Replace CHEST with the name of the block you want, in upper case.)
  • If you want to send the block type in a message to the player, use Text message = Text.of(blockType);

If it’s something else, let me know.

Je veux afficher dans un message ce que le joueur regarde comme le font certain mod et comme sur l’image.

Google trad:
I want to display a message in the player looks as do some mod and like the picture

What part of the picture?

Je veux afficher le bloc bloc que regarde le joueur:

Google trad:
I want to display the block that block the player looks:

Where are you trying to display it?

Text.of(blockType); just results in “Wool”

The other text is known as Traits in SpongeAPI, however theres no clean way to get them from strings as far as I know.

However blockState.toString will give minecraft:wool[color=green] But if you need to go the other way it can get rather hairy.

Swappa/BlockStateMappingsRegistry.java at master · AlmuraDev/Swappa · GitHub has an example of getting blockstates from blocktraits.



def textKV(prefix: String, data: String)    = Text.of(TextColors.BLUE, prefix, TextColors.WHITE, data)
  def textKV(prefix: String, data: Text)    = Text.of(TextColors.BLUE, prefix, TextColors.WHITE, data)
  def sendTraits(interactBlockEvent: InteractBlockEvent, location: Location[World], player: Player): Unit ={
    val state = interactBlockEvent.getTargetBlock.getExtendedState
    val stringTraits = state.getTraits.asScala.map(b=>b.toString)
    val values = state.getTraitValues.asScala.map(b=>b.toString)
    val map = state.getTraitMap.asScala.toString
    val prop = state.getApplicableProperties.asScala.map(b=>(b.getKey, b.getOperator, b.getValue))
    val keys = state.getKeys.asScala.map(b=>b.toString)
    val data = state.getContainers.asScala.map(b=>b.toString)
    val manips = state.getManipulators
    val item = player.getItemInHand.get()
    item.get(CatalogItemData.DISPLAY_NAME_DATA);
    player.sendMessages(
      textKV("     Type: ", Text.of(state.getType)),
      textKV("   Traits: ", stringTraits.toString),
      textKV("   Values: ", values.toString),
      textKV("      Map: ", map.toString),
      textKV("     Prop: ", prop.toString),
      textKV("      Key: ", keys.toString),
      textKV("     Data: ", data.toString),
      textKV("   Manips: ", manips.toString),
      textKV("    State: ", state.toString),
      textKV("Container: ", state.toContainer.toString)
    )
  }

Is it possible to get the block I’m looking?

https:https://forums-cdn.spongepowered.org/uploads/default/original/2X/a/a7d93279704ef87d7b4e941690f0eb7d5d48207e.jpg

I think they just want the block the player is currently targetting.

Oh… That would be the BlockRay class.

Optional<BlockRayHit> block = BlockRay.from(entity).filter(BlockRay.ONLY_AIR_FILTER).end();
if (block.isPresent()) {
    Location<World> loc = block.get().getLocation();
    // do something with loc
} else {
    // player is not looking at a block
}

Ca me dit que le joueur regarde que des blocs d’air:

Code:

Optional<BlockRayHit<World>> optHit = BlockRay.from(player).filter(BlockRay.onlyAirFilter()).build().end();
if (optHit.isPresent()) {
    Vector3d lookPos = optHit.get().getBlockPosition().toDouble();
    player.sendMessage(ChatTypes.ACTION_BAR, Texts.of(TextColors.RED, TextStyles.BOLD, optHit.get().getLocation().getBlockType().getName()));
}

Google trad:
It tells me that the player looks that air blocks:

Code:

Optional<BlockRayHit<World>> optHit = BlockRay.from(player).filter(BlockRay.onlyAirFilter()).build().end();
if (optHit.isPresent()) {
    Vector3d lookPos = optHit.get().getBlockPosition().toDouble();
    player.sendMessage(ChatTypes.ACTION_BAR, Texts.of(TextColors.RED, TextStyles.BOLD, optHit.get().getLocation().getBlockType().getName()));
}

Can you print the co-ordinates of the blocks you are checking to chat as well, with f3 open? (Also you are getting the end block, what you want is the first block, not the last.)

What’s happening is probably the block ray is shooting into the ground and stopping somewhere when it hits the 1000 block limit. Or the void. That’ll do it too.

That’s not an issue. That just tells blockray to skip air blocks and only return solid blocks.

It’s the .end(). He should be using .next()