Forum du serveur Computercraft FR
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
Le Deal du moment :
Jeux, jouets et Lego : le deuxième à ...
Voir le deal

Entity Detector getEntityList : Range (rayon) [Life id peripheral]

2 participants

Aller en bas

Entity Detector getEntityList : Range (rayon) [Life id peripheral] Empty Entity Detector getEntityList : Range (rayon) [Life id peripheral]

Message par skypop Ven 2 Sep - 2:24

La méthode getEntityList() de l'Entity Detector (du mod Life is peripheral) permet de récupérer la liste des entités présente dans le périmètre des coordonnées indiquées.
Ses arguments se présentent ainsi :
Code:
local entity_detector = peripheral.find("EntityDetector")
local entity_list = entity_detector.getEntityList(range, x, y, z)

Ce que j'avance reste à confirmer, par l'expérience ou la confidence des auteurs du mod.
Les paramètre de cette méthode serviraient à définir un volume sphérique, dont X, Y et Z sont les coordonnées du centre, et range son rayon.

Je pense que pour tous les joueurs de Minecraft qui se confrontent à la technicité du jeu, c'est pas très évident de se représenter une sphère dans un monde fait de cases et de cubes.

Une application de l'Entity Detector, intégré à une usine à mob basée sur un spawner, pourrait être de compter les mobs générés. Donc les mobs qui apparaissent dans le volume qui enveloppe le spawner.
Si vous avez l'habitude de ce genre de travaux, vous avez surement cet automatisme : compter deux blocs au dessus, 4 blocs autour, et un paquet de blocs en dessous..
Entity Detector getEntityList : Range (rayon) [Life id peripheral] F8d44986-5fa1-411e-81ac-9408cc02e359

En tout cas, c'est mon habitude, et naturellement, quand j'ai voulu employer l'Entity Detector pour compter les mobs d'un spawner, j'ai de suite pensé à un rayon de 4 blocs.
Mais oui, mais non, mais voila.. Même en se ravisant que l'espace fait 9 blocs de large, le rayon devrait faire 4,5 un dessin démontre bien que ça n'est pas ce qu'il faut :
Entity Detector getEntityList : Range (rayon) [Life id peripheral] 311f5eb1-e0ba-47bd-950d-e0eaa46cc4fb

Il s'agit d'évaluer un volume cubique par un volume sphérique, il faut donc que le premier puisse s'inclure dans le second. Pour savoir quel est le rayon, on peut sortir sa calculette et invoquer je ne sais quel Pythagore, Thales ou Google... Personnellement j'ai plus facile à fouiller au fond de mon tiroir que dans mes vieux souvenirs d'école ou sur wikipédia. Un bon vieux compas qui dormait là depuis les années collège, ça c'est une solution. (Sinon on peut également placer un waypoint de journey map au centre du spawner, et lire la distance affichée)

Enfin en deux coups de compas, je vérifie rapidement que le rayon qui fera l'affaire est 6,5. Aussi que sur le plan vertical, ça ne coûterait pas bien cher d'ajuster le centre de la spère deux blocs en dessous du spawner.
Entity Detector getEntityList : Range (rayon) [Life id peripheral] Bdd83c91-2572-4a7a-8ef7-790286a156d6

Mais un dernier détail, que tout ceux qui ont déjà bâti la bonne vieille ferme à Blazes n'ignorent pas. Le centre d'une sphère dans Minecraft, n'est pas un bloc, mais un point. Il peut se trouver au coin Nord-Ouest d'un bloc. On pourrait le négliger en acceptant le risuq eque par hasard quelque mobs puissent passer sous le radar :
Entity Detector getEntityList : Range (rayon) [Life id peripheral] 7e6302cf-c8ff-4326-b073-1278f23c7921

Mais ça ne coûterait pas cher de préciser les coordonnées du centre du spawner (ajouter 0,5), sinon élargir le rayon d'un bloc.

Une autre solution, la plus efficace et sans aucun doute possible, c'est d'élargir très largement ce rayon. De toute façon, pour compter, il vaut mieux parcourir la liste et s'assurer qu'on compte les bonnes entités, dans la foulée, on peut aussi contrôler leur coordonnées x,y,z et vérifier s'ils se trouvent bien à l'intérieur de la chambre de spawn, et non à l'extérieur.

Voila, j'espère avoir éclairci le sujet.
Peut être que j'y reviendrai avec une API dédiée (enfin pour l'instant c'est qu'une idée)
skypop
skypop

Messages : 95
Date d'inscription : 25/07/2016

Revenir en haut Aller en bas

Entity Detector getEntityList : Range (rayon) [Life id peripheral] Empty Re: Entity Detector getEntityList : Range (rayon) [Life id peripheral]

Message par skypop Dim 18 Sep - 3:35

Un exemple d'utilisation de l'EntityDetector et sa fonction getEntityList().



Su l'écran de gauche, j'ai dessiné la section d'une usine basée sur un spawner à zombie. Le mobspawner est symbolisé par le pixel blanc, et les courants d'eau en bleu.
Les pixels rouges sont des grinders, celui du haut est une turtle, celui en bas à droite, une fosse pleine de lave (au bout d'une conduite qui filtre les baby-zombies)

Toutes les 0.5 secondes, j'effectue un scan avec getEntityList, avec un rayon de 20 (qui couvre très largement toute l'usine) et centré légèrement à droite de la turtle (pixel rouge en haut à gauche)

Il s'agit ensuite de filtrer dans le tableau, les mobs étant des zombies, et de récupérer leur coordonnées Z et Y (l'axe X n'est pas représenté sur mon plan)
Les coordonnées sont à titre d'exemple (ce n'est pas celle de l'usine)
Code:
local range,ox,oy,oz = 20,-50,20,26 --rayon et coordonnées X,Y,Z du centre
local function lookup()
  local _x,_y
  local list,_,mob = ed.getEntityList(range,ox,oy,oz)
  for _,mob in pairs(list) do
    if mob.name=="Zombie" then
      _x = math.floor(tonumber(mob.z))
      _y = math.floor(tonumber(mob.y))
      _x,_y = convert(_x,_y)
      pix(_x,_y,colors.green)
    end
  end
end

Je fais attention à bien convertir les coordonnées Z et Y en nombre. Car il s'agit d'un nombre décimal avec beaucoup de chiffres après la virgule et qu'il est de type string (techniquement, c'est du texte) La fonction math.floor efface toutes ces décimales, ce qui ramène à des coordonnées au bloc près.
Ensuite viens la fonction convert(), qui converti ces coordonnées Z,Y de l'overworld en position X,Y sur l'écran. Il y a un souci d'orientation, et dans mon cas je dois inverser les deux axes. (j'y reviens après)

La fonction pix() dessine un pixel vert à ces coordonnées.
Code:
local bg = colors.black
local function pix(x,y,c)
  c = c or "d" --lime=5 green=d
  mon.setCursorPos(x,y)
  mon.blit(" ","f","d")
  mon.setBackgroundColor(bg)
end

Le tout est placé dans une boucle While :
Code:
while true do
    drawBG()
    lookup()
    sleep(0.5)
end

La fonction drawBG() sert à rafraîchir l'arrière plan, avant de dessiner les zombies dessus. Il s'agit d'une image dessinée avec paint (le programme CC). J'ai téléchargé le fichier dans notepad et par quelques bidouilles, agrandi x2. C'est à dire que chaque pixels est devenu un carré de 2x2 pixels (comme un pixel-art).
Ensuite cette image agrandie est affichée par l'intermédiaire de l'API BLittle
C'est ainsi que je parviens à avoir des pixels carrés à l'écran, et que les pixels verts paraissent un peu plus grands. L'agrandissement que j'ai bidouillé était nécessaire, car BLittle est limité en nombre de couleurs (2 par pixels réels)
Pour que ça marche, en plus de convertir les coordonnées il m'a fallu multiplier la coordonnée Y par 2/3.
Code:
local minZ = 20
local width = 18
local minY = 7
local height = 24
local _2t = 2/3
local function convert(x,y)
  local _x = width-(x - minZ)
  local _y = math.floor((height-(y - minY))*_2t+.5)
  return _x+padX+1,_y+padY
end

NB :

  • minY et minZ sont les coordonnées minimale de l'usine dans l'OverWorld.
  • width et height sont respectivement la largeur et la hauteur de l'usine (du moins, la partie que je représente à l'écran.
  • _2t est le résultat de 2 divisé par 3, soit 0.66666666 etc. Pour compenser le fait que 2 pixels de mon moniteur contiennent 3 pixels de mon image. (Si c'est pas clair, renseignez vous sur BLittle)
  • padX et padY sont les marges que j'ai ajouté à l'écran pour centrer le graphisme. J'ajoute 1 à padX, car la première colonne de pixels de mon image est transparente.


Cette fonction ne fonctionnera pas n'importe où. Il faut la revoir entièrement en fonction de l'orientation de votre usine, l'orientation de votre moniteur, et les dimensions de l'usine, le moniteur et l'image... Bref, un petit casse tête à faire sur mesure. Mais grosso-modo, c'est des additions ou soustractions.

Sur l'écran de droite, j'affiche une série de données (collectées par d'autres computers) :

  • Délai : avant la prochaine génération du spawner (obtenue avec le WorldInterface et sa fonction getBlockDatatags())
  • Génération : compteur
  • Zombie, Villageois, Mioche : Type de zombies, une information obtenue par l'intermédiaire de l'EntityDetector et sa fonction getEntityListAdvanced(). (De mémoire) il faut tester les propriétés mob.datatags.IsVillager ou mob.datatags.IsBaby (note qu'il peut être les deux à la fois)
  • Total: compteur
  • Mode: "Tueur" car les zombies sont dirigés vers le grinder
skypop
skypop

Messages : 95
Date d'inscription : 25/07/2016

Revenir en haut Aller en bas

Entity Detector getEntityList : Range (rayon) [Life id peripheral] Empty Re: Entity Detector getEntityList : Range (rayon) [Life id peripheral]

Message par cedmeu Dim 18 Sep - 18:55

Pour l'avoir vu en action, ce programme est génial et ça fait son petit effet Very Happy

cedmeu
Admin

Messages : 493
Date d'inscription : 28/03/2016

https://computercraftfr.forumgaming.fr

Revenir en haut Aller en bas

Entity Detector getEntityList : Range (rayon) [Life id peripheral] Empty Re: Entity Detector getEntityList : Range (rayon) [Life id peripheral]

Message par Contenu sponsorisé


Contenu sponsorisé


Revenir en haut Aller en bas

Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum