1.12.2 Player Capability et Gui Rendering problem



  • j'ai créé une capablility a mon joueur qui est basiquement un système de soif Enum Provider tout ce qui va avec le système fonctionne bien comme je le souhaite mais je cherche a écrire les valeurs de ce système de soif a l’écran comme le système utilise un event onPlayerTick pour dépenser l'eau du joueur j’aimerai éviter de passer par des paquet pour récupérer la valeur de l'eau sur le joueur en multiplayer (serveur dédier) pour l'afficher a l’écran par ce que si il doit demander au serveur les valeur a chaque tick multiplier par tout les joueur pour un simple affichage ca me semble un peu exagérer et minecraft.getMinecraft().getCapability() ne pourra pas fonctionner si je ne m'abuse dans ce contexte

    Si quelqu'un peut m’éclairer sur la possibilité ou non de ceci et si c'est possible sur la façon dont je pourrait le faire ça m'enlèverai une sale migraine en approche ;^p

    ps:ce coup si je fourni pas le code c'est du code fait a 4H du matin c'est pas propre donc pas reutilisable 😜


  • Moddeurs confirmés Rédacteurs Administrateurs

    Bonjour,
    Il faut forcement un paquet pour synchroniser les valeurs, ce n'est pas possible sans.
    Par contre tu n'es pas obligé de synchroniser la valeur à chaque tick.



  • oui mais du coup le paquet seras appeler par le gui et le gui il s'update bien a chaque tick? les gui c'est vraiment pas ma tasse de thé je suis plus code technique que interface utilisateur 😜



  • Je Galère avec les packets je comprend pas des masse comment ça marche j' trois classe pour le système d'eau

    public class Water implements IWater{
    	
    	private float maxWaterLevel = 600F;
    	private float waterLevel = 600.0F; 
    
    	@Override
    	public void consume(float amount) {
    		this.waterLevel -= amount;
    		 if (this.waterLevel < 0.0F) this.waterLevel = 0.0F;//make it no go to low
    	}
    
    	@Override
    	public void fill(float amount) {
    		this.waterLevel += amount;
    		if(this.waterLevel > maxWaterLevel) this.waterLevel = maxWaterLevel;//make it no go too hight
    	}
    
    	@Override
    	public void set(float amount) {
    		this.waterLevel = amount;
    	}
    
    	@Override
    	public float getWater() {
    		return this.waterLevel;
    	}
    
    	@Override
    	public float getMaxWater() {
    		return this.maxWaterLevel;
    	}
    
    }
    
    
    
    public class WaterProvider implements ICapabilitySerializable<NBTBase>{
    	
    	@CapabilityInject(IWater.class)
    	
    	public static final Capability<IWater> WATER_CAP = null;
    	
    	private IWater instance = WATER_CAP.getDefaultInstance();
    	
    	@Override
    	public boolean hasCapability(Capability<?> capability, EnumFacing facing){
    		return capability == WATER_CAP;
    	}
    	
    	@Override
    	public <T> T getCapability(Capability<T> capability, EnumFacing facing){
    		return capability == WATER_CAP ? WATER_CAP.<T> cast(this.instance) : null;
    	}
    	
    	@Override
    	public NBTBase serializeNBT(){
    		return WATER_CAP.getStorage().writeNBT(WATER_CAP, this.instance, null);
    	}
    	
    	@Override
    	public void deserializeNBT(NBTBase nbt){
    		WATER_CAP.getStorage().readNBT(WATER_CAP, this.instance, null, nbt);
    	}
    }
    
    public class WaterStorage implements IStorage<IWater>{
    	@Override
    	public NBTBase writeNBT(Capability<IWater> capability, IWater instance, EnumFacing side) {
    		return new NBTTagFloat(instance.getWater());
    	}
    
    	@Override
    	public void readNBT(Capability<IWater> capability, IWater instance, EnumFacing side, NBTBase nbt) {
    		 instance.set(((NBTPrimitive) nbt).getFloat());
    	}
    }
    
    

    J'ai une Interface

    public interface IWater {
    	 public void consume(float points);
    	 public void fill(float points);
    	 public void set(float points);
    	 
    	 public float getWater();
    	 public float getMaxWater();
    }
    
    

    et je l'enregistre comme ça dans mon commonProxy

        public void load()
        {
            MinecraftForge.EVENT_BUS.register(new CapabilityHandler());
            CapabilityManager.INSTANCE.register(IWater.class, new WaterStorage(), Water.class);
        }
    

    Ha et j'ai oublier

    public class CapabilityHandler
    {
     public static final ResourceLocation WATER_CAP = new ResourceLocation(Reference.MOD_ID, "water");
     
     @SubscribeEvent
     	public void attachCapability(AttachCapabilitiesEvent<Entity> event){
    	 
    	if (!(event.getObject() instanceof EntityPlayer)) return;
    	 	event.addCapability(WATER_CAP, new WaterProvider());
     	}
    }
    

    J'ai essayer de créé un packet :

    public class SyncWaterData implements IMessage{
    	  private float water;
    	  
      // We need to initialize our data, so provide a suitable constructor:
      public SyncWaterData(IWater water) {
        this.water = water.getWater();
      }
    
      @Override
      public void fromBytes(ByteBuf buf)
      {
    	  water = buf.readInt();
      }
    
      @Override
      public void toBytes(ByteBuf buf)
      {
          buf.writeFloat(water);
      }
    
      public static class Handler implements IMessageHandler<SyncWaterData, IMessage>
      {
          @Override
          public IMessage onMessage(SyncWaterData message, MessageContext ctx)
          {
          	VirusZMod.proxy.addScheduledTaskClient(() -> handle(message, ctx));
              return null;
          }
          
          private void handle(SyncWaterData message, MessageContext ctx)
          {
              EntityPlayer player = VirusZMod.proxy.getClientPlayer();
              if (player instanceof EntityPlayer)
              {
                 ((IWater) player.getCapability(WaterProvider.WATER_CAP, null)).getWater();
              }
          }
      }
    }
    

    que j'ai enregistrer avec network manager tout ca et j'ai le meme paquet a quelque modif pret qui sert de Requester coter serveur la partie que je trouve pas c'est Comment utiliser ce paquet pour recuperer les donnée dans mon gui

    Il y aurait des exemple concret existant parce je suis paumer le la doc a part me donner un migraine ca ma pas vraiment aider j'avoue que les packet et tout ce qui est serveur / HUD / interface graphique c'est pas vraiment mon fort 😜


  • Moddeurs confirmés Rédacteurs Administrateurs

    Le plus simple c'est que dans l'handler tu paquets tu assignes la valeur de message.water vers la capability.
    Comme ça tu aura juste à passer par la capa pour récupérer la valeur depuis le gui.



  • Comme ca?

            ((IWater) player.getCapability(WaterProvider.WATER_CAP, null)).set(message.water);
    

    Le problème c'est que ce paquet comment je l'envoie ou le demande? c'est automatique quand on utilise les capability?

    		network.registerMessage(SyncWaterData.Handler.class, SyncWaterData.class, 0, Side.CLIENT);
    
    

    j'ai trouver comme on l'utilisait

    		    new SyncWaterData(player.getCapability(WaterProvider.WATER_CAP, null));    
    
    

    mais je comprend pas ce que tu me dit :c



  • en gros j'ai changer par set au lieu de get mais ça change rien a mon affichage je suis pas sure mais j'ai essayer de print message dans mon handler et ça print jamais ya un truc que je fait mal surement devant mes yeux mais comme les paquets pour moi c'est de la magie noir je suis perdu xD


  • Moddeurs confirmés Rédacteurs Administrateurs

    Il faut que tu envoies la valeur depuis le serveur quand elle change.
    ClassePrincipale.network.sendTo(ew SyncWaterData(player.getCapability(WaterProvider.WATER_CAP, null)), player);



  • @robin4002 a dit dans Player Capability et Gui Rendering problem :

    ClassePrincipale.network.sendTo(ew SyncWaterData(player.getCapability(WaterProvider.WATER_CAP, null)), player);

    Merci!!!!!!!
    pour ceux qui veulent réutiliser le code au dessus vous pouvez mais je préfére prévenir c'est pas très très propre(écrit a 4H du mat corriger a 6H avec 2H sommeil) je vous conseillerait de faire ça par vous même au lieu de copier coller et aussi parce que l'exercice est sur intéressent et que si vous copier coller le code vous apprendrez pas son fonctionnement et le jour ou vous aurez besoin le faire par vous même vous allez galérer et avoir besoin ce jour la de tout réapprendre ;^p

    PS: ya des erreur dedans je vous laisse les trouver x)


Log in to reply