5 votes

Comment puis-je savoir si deux entités Minecraft se trouvent dans le même plan d'eau ?

Comment puis-je tester deux entités, qui se trouvent toutes deux dans la même masse d'eau ?

La seule façon de procéder à laquelle je pense est d'avoir plusieurs commandes /testforblock, testant l'eau autour de l'entité, et d'avoir une autre commande bloquant le test pour les autres entités dans un rayon. Ensuite, il y a plus de blocs de commande qui testent l'eau, et plus de blocs de commande qui ont un rayon de test d'entité plus grand.

Donc, en théorie, si le bloc de commande trouve de l'eau ET une entité, il fera quelque chose, mais s'il trouve de la terre et une entité, il ne le fera pas. Cette approche fonctionnera-t-elle ? Existe-t-il une meilleure approche ?

0 votes

Cette approche fonctionnerait probablement. Mais il faudrait que je réfléchisse à des commandes efficaces.

0 votes

Cela serait très compliqué, mais vous pourriez théoriquement utiliser des valeurs de données inutilisées. Quelque chose comme ça : 'execute @a ~ ~ ~ détecter ~ ~ ~ stationary_water 0 remplir ~-10 ~-10 ~-10 ~10 ~10 ~10 stationary_water 1 remplacer stationary_water 0'. Puis, pour tous les autres joueurs : 'executez @a ~ ~ ~ ~ detect ~ ~ ~ stationary_water 1 scoreboard players set @p[c=1,r=1] dummyscoreboardobjective 1'.

5voto

SirBenet Points 27779

Cette question est très difficile. Tester si deux blocs sont connectés d'une manière ou d'une autre est déjà difficile, deux entités se trouvant dans la même masse d'eau est encore plus difficile. J'ai une solution, mais elle n'est pas géniale. Il existe probablement des solutions qui fonctionnent beaucoup mieux.

Je recommanderais plutôt de se pencher sur le problème réel pour lequel vous voulez cette solution ; voyez s'il n'y a pas une autre façon de le résoudre sans tester si deux entités sont dans la même masse d'eau.


Cette partie permet de s'assurer qu'une recherche fonctionnera réellement et ne brisera pas votre monde.

Tout d'abord, nous pouvons facilement nous assurer que les entités sont effectivement toutes deux dans l'eau. Si l'une d'entre elles ne l'est pas, alors nous pouvons sauter tout le reste puisqu'elles ne peuvent pas être toutes deux dans la même masse d'eau si l'une d'entre elles n'est même pas dans l'eau. Mettez une porte ET avec ces deux commandes :

/execute @e[name=Entity1] ~ ~ ~ /testforblock ~ ~ ~ water
/execute @e[name=Entity2] ~ ~ ~ /testforblock ~ ~ ~ water

Ensuite, je vérifierais que les entités sont au moins un peu proches les unes des autres. C'est une sorte de garantie ; elles pourraient être dans le même plan d'eau à des milliers de pâtés de maisons de distance, mais c'est peu probable et vous feriez planter le jeu en essayant de le résoudre de toute façon.

/execute @e[name=Entity1] ~ ~ ~ /testfor @e[name=Entity2,r=R] ~ ~ ~

Changement R avec la distance que vous voulez que la recherche aille. Cette solution est lente, il est donc préférable de la limiter.

Si cela réussit (les entités sont toutes deux dans l'eau, et ne sont pas ridiculement éloignées l'une de l'autre), il est temps de faire la recherche réelle qui déterminera si elles sont dans la même masse d'eau.


Cette partie est la recherche proprement dite.

Les commandes suivantes rendent les deux Entity1 y Entity2 invoquez marker ArmorStands dans chaque direction adjacente autour d'eux dans laquelle il y a de l'eau. Le type de données -1 signifie que tout type d'eau (coulant, source, etc.) fonctionnera :

/execute @e[name=Entity1] ~ ~ ~ detect ~1 ~ ~ water -1 /summon ArmorStand ~1 ~ ~ {CustomName:"Entity1",Marker:1b,NoGravity:1b}
/execute @e[name=Entity1] ~ ~ ~ detect ~-1 ~ ~ water -1 /summon ArmorStand ~-1 ~ ~ {CustomName:"Entity1",Marker:1b,NoGravity:1b}
/execute @e[name=Entity1] ~ ~ ~ detect ~ ~1 ~ water -1 /summon ArmorStand ~ ~1 ~ {CustomName:"Entity1",Marker:1b,NoGravity:1b}
/execute @e[name=Entity1] ~ ~ ~ detect ~ ~-1 ~ water -1 /summon ArmorStand ~ ~-1 ~ {CustomName:"Entity1",Marker:1b,NoGravity:1b}
/execute @e[name=Entity1] ~ ~ ~ detect ~ ~ ~1 water -1 /summon ArmorStand ~ ~ ~1 {CustomName:"Entity1",Marker:1b,NoGravity:1b}
/execute @e[name=Entity1] ~ ~ ~ detect ~ ~ ~-1 water -1 /summon ArmorStand ~ ~ ~-1 {CustomName:"Entity1",Marker:1b,NoGravity:1b}

/execute @e[name=Entity2] ~ ~ ~ detect ~1 ~ ~ water -1 /summon ArmorStand ~1 ~ ~ {CustomName:"Entity2",Marker:1b,NoGravity:1b}
/execute @e[name=Entity2] ~ ~ ~ detect ~-1 ~ ~ water -1 /summon ArmorStand ~-1 ~ ~ {CustomName:"Entity2",Marker:1b,NoGravity:1b}
/execute @e[name=Entity2] ~ ~ ~ detect ~ ~1 ~ water -1 /summon ArmorStand ~ ~1 ~ {CustomName:"Entity2",Marker:1b,NoGravity:1b}
/execute @e[name=Entity2] ~ ~ ~ detect ~ ~-1 ~ water -1 /summon ArmorStand ~ ~-1 ~ {CustomName:"Entity2",Marker:1b,NoGravity:1b}
/execute @e[name=Entity2] ~ ~ ~ detect ~ ~ ~1 water -1 /summon ArmorStand ~ ~ ~1 {CustomName:"Entity2",Marker:1b,NoGravity:1b}
/execute @e[name=Entity2] ~ ~ ~ detect ~ ~ ~-1 water -1 /summon ArmorStand ~ ~ ~-1 {CustomName:"Entity2",Marker:1b,NoGravity:1b}

Notez que toutes les nouvelles ArmorStands invoquées portent le nom de leur invocateur. Cela signifie que lors de la prochaine itération de la recherche, chacun de ces Fers à cheval invoquera également d'autres Fers à cheval autour de lui dans les directions où il y a de l'eau, et ainsi de suite. On se souviendra aussi de l'entité dont ils proviennent par leur nom.

Faites suivre tout ça par :

/execute @e[name=Entity1] ~ ~ ~ /setblock ~ ~ ~ red_sandstone
/execute @e[name=Entity2] ~ ~ ~ /setblock ~ ~ ~ red_sandstone

N'importe quel bloc solide fera l'affaire. Il s'agit de marquer les blocs d'eau comme ayant déjà un marqueur ArmorStand sur eux, afin que les futures détections d'eau n'en génèrent pas un autre sur cette tuile.

Répétez toute cette recherche sur une horloge qui s'arrête lorsque la recherche réussit, ou lorsque la recherche a duré un certain nombre (je recommande R) d'itérations (ou elle continuera indéfiniment s'ils ne sont pas dans le même plan d'eau). Cette recherche devrait ressembler à ceci pour chaque entité :

The search of 1 entity

Pour vérifier si la recherche a abouti, il suffit d'en faire la demande :

/execute @e[name=Entity1] ~ ~ ~ /testfor @e[r=1,Entity2]

Ce qui fera que chaque Entity1 ArmorStand cherchera des Entity2 ArmorStands adjacents, les deux entités ayant alors été reliées par une route adjacente.


Pour nettoyer tous les supports d'armure de type red_sandstone et marker que vous venez de créer pour cette recherche, tout ce que vous devez faire est :

/execute @e[name=Entity1] ~ ~ ~ /setblock ~ ~ ~ water
/execute @e[name=Entity2] ~ ~ ~ /setbock ~ ~ ~ water
/kill @e[name=Entity1, type=ArmorStand]
/kill @e[name=Entity2, type=ArmorStand]

Et voilà, c'est fait. C'est très salissant, mais ça marche bien d'après ce que j'ai essayé. Il peut détecter si des entités sont connectées même à travers des labyrinthes d'eau.

0 votes

Désolé que ça m'ait pris une éternité pour te répondre à ce sujet. Je ne travaille plus sur le projet qui nécessitait ces commandes, mais pour autant que je sache (je ne l'ai pas testé moi-même), cela semble fonctionner parfaitement bien. Je vous félicite d'avoir mis au point ce système de bloc de commandes très compliqué ! Je ne manquerai pas de lui trouver une utilité à l'avenir.

0 votes

C'est très similaire à quelque chose que j'avais déjà prévu de programmer dans Minecraft un jour, mais mon cas d'utilisation aurait été par exemple d'analyser les grottes ou les minerais ou autre. Je parie que vous pouvez maintenant le faire dans la version 1.13+ avec beaucoup moins de lag et sans réellement changer aucun bloc. Je vais faire un rapport ici une fois que je l'ai fait.

0 votes

@FabianRöling Avez-vous jamais fini ça ?

AlleGamers.com

AlleGamers est une communauté de gamers qui cherche à élargir la connaissance des jeux vidéo.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X