Synchronisation Entity



  • Hey 🙂
    J'ai créé une entité qui possède un attribut supplémentaire, un boolean "agressive".
    Par defaut agressive = false
    Quand agressive est false, le joueur peut faire un clic droit sur l'entité et un GUI s'ouvre.
    Ce qui lui propose 3 boutons, l'un d'entre eux rend l'entité agressive.

    Coté serveur, tout fonctionne.
    Par contre au niveau client, l'attribut vaut toujours true.
    Même quand je quitte et relance la partie l'attribut coté serveur est a true, mais celui du client reste a false.

    Voila le code en question :

    Entity

    ​public class Migrant extends EntityCreature {
    
    private boolean agressive;
    
    public Migrant(World world) {
    super(world);
    }
    
    public void applyEntityAttributes()
    {
    super.applyEntityAttributes();
    this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.8D);
    
    }
    
    public boolean isAgressive() {
    return agressive;
    }
    
    public void setAgressive(boolean agressive) {
    this.agressive = agressive;
    }
    
    @Override
    public boolean isEntityInvulnerable() {
    return !agressive;
    }
    
    @Override
    protected boolean interact(EntityPlayer player) {
    System.out.println("INTERACT : aggressif : "+agressive);
    if(agressive) return false;
    if(player.worldObj.isRemote) {
    FMLClientHandler.instance().displayGuiScreen(Minecraft.getMinecraft().thePlayer, new GuiMigrant(this));
    }
    return true;
    }
    
    public void join() {
    this.setDead();
    }
    
    public void injuries(EntityPlayer player) {
    setAgressive(true);
    setTarget(player);
    }
    
    @Override
    public void writeToNBT(NBTTagCompound tag) {
    super.writeToNBT(tag);
    tag.setBoolean("agressive", agressive);
    }
    
    @Override
    public void readFromNBT(NBTTagCompound tag) {
    super.readFromNBT(tag);
    this.agressive = tag.getBoolean("agressive");
    }
    
    }
    

    Gui

    ​public class GuiMigrant extends GuiScreen {
    
    private final static ResourceLocation GUI_TEXTURE = new ResourceLocation(ColonsMod.MODID, "textures/gui/migrant.png");
    
    static {
    Minecraft.getMinecraft().renderEngine.bindTexture(GUI_TEXTURE);
    }
    
    private int xPos, yPos, xSize=248, ySize=166;
    private GuiButton get, fight, nothing;
    private String sentence;
    private Migrant entity;
    
    public GuiMigrant(Migrant entity) {
    this.entity = entity;
    }
    
    @Override
    public void drawScreen(int p_73863_1_, int p_73863_2_, float p_73863_3_) {
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, mc.renderEngine.getTexture(GUI_TEXTURE).getGlTextureId());
    drawTexturedModalRect(xPos,yPos,0, 0, xSize, ySize);
    drawCenteredString(mc.fontRenderer, sentence, width/2,yPos+12, 0xFFFFFF);
    super.drawScreen(p_73863_1_, p_73863_2_, p_73863_3_);
    }
    
    @Override
    public void initGui() {
    xPos = (width-xSize)/2;
    yPos = (height-ySize)/2;
    get = new GuiButton(1, 9+xPos, 57+yPos, 232, 20, "Voulez-vous rejoindre notre colonie ?");
    fight = new GuiButton(2, 9+xPos, 92+yPos, 232, 20, "Hors de ma vue miserable !");
    nothing = new GuiButton(3, 9+xPos, 127+yPos, 232, 20, "Je ne peux rien faire pour vous, désolé");
    
    buttonList.add(get);
    buttonList.add(fight);
    buttonList.add(nothing);
    
    sentence = "Je n'ai nul part où aller …";
    
    super.initGui();
    }
    
    @Override
    protected void actionPerformed(GuiButton button) {
    if(button != nothing) {
    ColonsMod.getInstance().getChannel().sendToServer(new MigrantPacket(entity, button==get));
    }
    this.mc.displayGuiScreen(null);
    }
    
    @Override
    public boolean doesGuiPauseGame() {
    return true;
    }
    
    }
    

    #Packet + Handler(Packet + Handler)

    ​public class MigrantPacket implements IMessage {
    
    private Migrant entity;
    private boolean join;
    
    public MigrantPacket() {}
    
    public MigrantPacket(Migrant entity, boolean join) {
    this.entity = entity;
    this.join = join;
    }
    
    @Override
    public void fromBytes(ByteBuf buf) {
    World w = DimensionManager.getWorld(buf.readInt());
    if(w == null) return;
    Entity entity = w.getEntityByID(buf.readInt());
    if(entity instanceof Migrant) {
    this.entity = (Migrant) entity;
    }
    join = buf.readBoolean();
    }
    
    @Override
    public void toBytes(ByteBuf buf) {
    buf.writeInt(entity.worldObj.provider.dimensionId);
    buf.writeInt(entity.getEntityId());
    buf.writeBoolean(join);
    }
    
    public static class MigrantPacketHandler implements IMessageHandler <migrantpacket, imessage="">{
    
    @Override
    public IMessage onMessage(MigrantPacket message, MessageContext ctx) {
    if(!cheat(message.entity, ctx.getServerHandler().playerEntity)) {
    if(message.join) {
    System.out.println("MIGRANT JOIN");
    message.entity.join();
    }
    else {
    System.out.println("MIGRANT AGGRESSIF");
    message.entity.injuries(ctx.getServerHandler().playerEntity);
    }
    }
    return null;
    }
    
    private boolean cheat(Entity entity, EntityPlayer player) {
    return entity.dimension != player.dimension || Math.abs(entity.serverPosX - player.serverPosX) > 10 || Math.abs(entity.serverPosZ - player.serverPosZ) > 10 || Math.abs(entity.serverPosY - player.serverPosY) > 6;
    }
    
    }
    

    Avez-vous une idée ?</migrantpacket,>


  • Administrateurs

    Ça ne serait pas mieux de passer par un data watcher ?


  • Administrateurs

    Sinon regarde le code du loup ou du pigman.



  • J'ai regardé le code du loup et du pigman, puisqu'au final je veux que l'entité attaque le joueur si celui ci clique sur le bouton qui rend agressif mais j'ai le même problème que notre collègue Degraduck. J'ai beau faire des copier/coller, ça ne fonctionne pas 😕

    Je vais me renseigner sur les data watchers. Je ne connaissais pas.


  • Administrateurs

    C'est bizarre, je vais checker ça, j'ai déjà fais des mobs neutres qui deviennent hostiles, et ça fonctionnait très bien.