• Bonsoir,

    Je cherche à créer un Item qui, au moment où l'on fait un clique droit avec, ouvre une interface permettant la combustion de blocs.

    Je traîne pas mal sur le forum officiel de Forge où j'y ai également posté un topic expliquant ma démarche. Mais puisque le français est ma langue maternelle, j'espère pouvoir m'expliquer un peu mieux sur ce forum.

    Le cas d'utilisation de l'Item est le suivant : on fait un clique droit avec, ce qui nous ouvre une interface et nous offre la possibilité de consumer des blocs. Il y a un slot d'entrée et un slot de sortie : le slot d'entrée va accueillir le bloc à consumer et le slot de sortie va accueillir le résultat de la combustion (une ressource quelconque) en fonction du bloc entrant (Il n'y a pas besoin de combustible pour que ça fonctionne). Vous l'aurez compris, il s'agit entre autre du système de four déjà existant mais allégé de par sa non-nécessité de combustible.

    Le gros problème que je rencontre est que je n'ai aucune idée de comment implémenter la partie de combustion. Pour les blocs, c'est plutôt simple puisqu'il est possible d'ajouter au bloc un TileEntity : cela permettrait de tout sauvegarder, que ce soit données de combustion (temps total, temps restant, etc) ou items présents dans les slots du bloc en question. Dans mon cas, il s'agit d'un Item, en l'occurrence il ne m'est pas possible d'y assigner un TileEntity. Les choses dont j'ai besoin sont des variables à update à chaque tick (temps de combustion, sans les sauvegarder) pour pouvoir update visuellement la barre de progression du Gui et de faire tout un tas de choses comme le four (savoir s'il a fini la combustion, savoir quel recette s'applique à celle-ci, etc)

    Je tiens toutefois à préciser que si le joueur décide de quitter l'interface, la combustion s'arrête et les ressources présentes dans le conteneur de l'interface seront drop par terre. Aucune utilité de sauvegarder les slots donc.

    Actuellement, j'ai un Container qui contient (lel) un Slot d'entrée, un Slot de sortie, l'inventaire du joueur ainsi que sa hotbar. Les méthodes principales y sont implémentées (transferStackInSlot, onContainerClosed pour le drop des items à la fermeture, slotClick pour éviter de bouger l'item qu'on utilise actuellement) et cela marche à merveille. J'ai également une Gui qui est bien calquée par rapport aux slots du Container ainsi que quelques strings par-ci par-là. Il ne me manque plus que ce système de combustion où je ne sais pas où l'implémenter…

    De ce que j'ai compris de plusieurs topics sur l'Internet, l'ItemStack est l'équivalent du TileEntity par sa capacité à stocker des informations dans l'Item, mais comme je vous l'ai dit je n'ai pas besoin de stocker quoi que ce soit dans l'Item mais juste au moment de son utilisation au clic droit. Un peu d'aide et de compréhension seraient sincèrement les bienvenues.

    Pour examiner un peu ce que j'ai fait pour l'instant, les fichiers sont en pastebin dans le topic anglais linké juste au-dessus.

    En attente de votre aide et de vos réponses,
    Bonne soirée !


  • Je pense que tu pourrais utiliser la méthode detectAndSendChanges() du container, update tous les ticks côté serveur par l entityplayer

  • Moddeurs confirmés Rédacteurs Administrateurs

    Salut,
    Il y a ce tutoriel : http://www.minecraftforgefrance.fr/showthread.php?tid=2197
    Qui explique comment ajouter un container sur un item (type coffre). Ce n'est pas exactement la même chose mais ça devrait t'aider.


  • La solution à ton problème se trouve probablement dans les NBTTags 🙂


  • Bonsoir et merci pour vos réponses !

    Concernant le tutoriel backpack j'ai suivi celui de coolAlias, comme je l'avais écrit j'ai déjà la logique du Container.

    Là où je sèche c'est que je ne sais pas où (dans quelle classe, Container ou autre ?) implémenter la logique de combustion et d'update. Que devrais-je utiliser pour effectuer mon update ? L'interface ITickable ?

  • Moddeurs confirmés Rédacteurs Administrateurs

    Dans la classe item il y a une fonction nommé onUpdate, tu peux utiliser celle-ci.


  • Moi je stockerai sinon dans un ExtendedEntityProperties, avec un tick handler sur le joueur pour faire avancer la cuisson lorsque le Gui est fermé


  • @'robin4002':

    Dans la classe item il y a une fonction nommé onUpdate, tu peux utiliser celle-ci.

    Apparemment cette méthode est appelée à chaque fois que le-dit Item est dans l'inventaire du joueur, ce qui n'est pas le but. C'est vraiment quand l'interface est ouverte qu'il faudrait appeler un update. 🙂

    @'SCAREX':

    Moi je stockerai sinon dans un ExtendedEntityProperties, avec un tick handler sur le joueur pour faire avancer la cuisson lorsque le Gui est fermé

    Le fait que les slots ne soient pas sauvegardés et qu'aucune action ne soit possible hors interface est complètement voulu ! J'ai vraiment voulu que le joueur soit sur l'interface pour effectuer la combustion 😄

    EDIT: vraiment ça m'étonne que personne ne s'y soit frotté avant moi. À moins que cette personne n'ait pas communiqué ce sujet.


  • Effectivement il n'y a pas de fonction onUpdate, en revanche je te propose 2 solutions :

    • Tu peux relier le onUpdate de l'Item au container et créer une fonction onUpdate qui sera appelée depuis l'Item
    • ou tu peux ré-écrire la fonction detectAndSendChanges qui elle est tickée côté serveur, et donc qui est appelée à chaque tick du joueur
  • Moddeurs confirmés Rédacteurs Administrateurs

    Dans ce cas passe par player tick event, si event.player.openContainer instanceof TonContainer tu cast puis tu fais avancer la cuisson.


  • D'accord, merci de vos conseils les gars. Selon vous, où est-ce qu'il serait le plus logique de stocker ces variables ? Le container directement ?


  • Oui pourquoi pas ? Tu fais une méthode update appelée par le tick Èvent


  • Bonjour !

    J'ai décidé de le faire en bloc plutôt qu'en item : la solution employée pour les items ne me plaît guère et je souhaitais avant tout reprendre le concept du four pour des connaissances personnelles. 🙂

    However, je rencontre un problème lorsque je décide de split le mod en deux jar : un pour le client et un pour le serveur (serveur privé en somme). En fait, je souhaite que toute la logique du bloc ne soit pas dans le mod du client mais dans celui du serveur (en outre, il est évident que le mod client n'a pas pour but de marcher en singleplayer) et lorsque j'essaie de faire un clic droit sur un serveur, j'obtiens un crash au niveau du rendering du gui, je pense que je fais mal la différence entre client et serveur.

    Lien du crash ici

    Si vous ne voyez pas où je veux en venir, je vais vous expliquer plus en détails. Dans ce même mod j'ai créé un bloc tonneau qui possède un TileEntity. Dans le mod du client il n'y a pas de TileEntity tandis que dans le mod du serveur il y est, et oui, ça fonctionne : le tonneau fermente correctement, ce qui me permet de faire marcher le bloc en multijoueur et non en singleplayer (dans le client, hasTileEntity retourne false et dans le serveur retourne true). Je souhaite faire la même chose avec le bloc dont je vous parle dans ce topic, mais j'avoue être un peu perdu avec le gui et le container en plus.

    Si quelqu'un voit à peu près de quoi je parle, pourrait-il me donner quelques astuces ? 😄

  • Moddeurs confirmés Rédacteurs Administrateurs

    GuiSieve.java ligne 81
    tu as quoi ?


  • @'robin4002':

    GuiSieve.java ligne 81
    tu as quoi ?

    Woops, my bad j'ai oublié de montrer le code. J'ai un this.tileSieve.getField(0), en gros je pense que le TileEntity côté client est null. Le problème c'est que je ne sais pas comment je pourrais récupérer la valeur du TileEntity du serveur.

    GuiSieve.java
    ContainerSieve.java
    TileEntityBlockSieve.java

    GuiHandler

    Le playerIn.openGui(…) est bien appelé côté serveur (notamment grâce à !isRemote). Le but serait d'enlever le fichier TileEntity sur le jar du client, mais dans ce cas le GuiHandler donnerait une erreur de TileEntityBlockSieve inconnu. (... à moins que j'implémente une classe vide ? Mais dans ce cas sur le gui je n'aurais pas accès au getField, j'me sens oppressé !)


  • Si tu veux récup la valeur du serveur sans pour autant que le client ai le tile entity, tes obligé de créer un packet

  • Moddeurs confirmés Rédacteurs Administrateurs

    Le tile entity tout comme le container et quelque chose de commun au client et au serveur.
    Ne pas mettre le tile entity côté client ne fonctionnera pas.

    Ce que tu peux faire par contre c'est mettre côté client un tile entity sans les fonctions writeTo et readFrom Nbt


  • @'robin4002':

    Le tile entity tout comme le container et quelque chose de commun au client et au serveur.
    Ne pas mettre le tile entity côté client ne fonctionnera pas.

    Ce que tu peux faire par contre c'est mettre côté client un tile entity sans les fonctions writeTo et readFrom Nbt

    Comment se fait-il dans ce cas que mon autre bloc marche très bien alors qu'il n'y a pas de TileEntity côté client ? 😕

  • Moddeurs confirmés Rédacteurs Administrateurs

    Tu as quoi dans cet autre bloc ?


  • @'robin4002':

    Tu as quoi dans cet autre bloc ?

    Il s'agit de la même classe de bloc côté client et serveur, excepté que côté client hasTileEntity retourne false et ne créé pas de TileEntity, et côté serveur hasTileEntity retourne true et createTileEntity créé un nouvel TileEntity.

    Mais je pense que ça marche parce que le client ne peut pas interagir avec le TileEntity : seul le serveur le fait et update le TileEntity avec le packet d'update de TE. 🙂