Jump to content

Note block plays note again after using a play button and closing the GUI


Markk

Recommended Posts

This video demonstrates the issue:

 

[embed=425,349]<iframe width="560" height="315" src="https://www.youtube.com/embed/5FWh_9MUk9I" frameborder="0" allowfullscreen></iframe>[/embed]

 

Event Handler:

 

public class EventHandlerCommon {	
    public static TileEntityNote entityNoteBlock;

    @SubscribeEvent
    public void noteBlockChange(NoteBlockEvent.Change event) {
        event.setCanceled(true);
        //CHANGE EVENT
    }

@SubscribeEvent
    public void playerInteract(PlayerInteractEvent event) {
    	if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) {
    		World world = event.world;
    		Block block = world.getBlockState(event.pos).getBlock();
    		if (block.equals(Blocks.noteblock)) {
                event.entityPlayer.openGui(NBGUI.instance, GUI.GUI_ID, world, event.pos.getX(), event.pos.getY(), event.pos.getZ());
                entityNoteBlock = (TileEntityNote) world.getTileEntity(event.pos);
                
                event.useBlock = Event.Result.DENY;
    		}
    	}
    }
}

 

 

actionPerformed method in GUI class:

 

protected void actionPerformed(GuiButton button) throws IOException {
	switch (button.id) {
		case 1: //Play
			Packet playNote = new Packet(EventHandlerCommon.entityNoteBlock);
			//playNote.setText("play");
			NBGUI.network.sendToServer(playNote);          
			break;
		case 2: //Note +1
			break;
		case 3: //Note -1
			break;
		case 4: //Octave +1
			break;
		case 5: //Octave -1
			break;
	}
}

 

 

IMessage:

 

public class Packet implements IMessage {
    protected static TileEntityNote entity;

    public Packet() {
    }

    public Packet(TileEntityNote entityNote) {
    	entity = entityNote;
    }

    @Override
    public void fromBytes(ByteBuf buf) {
    }

    @Override
    public void toBytes(ByteBuf buf) {
    }
}

 

 

IMessageHandler:

 

public class PacketHandler implements IMessageHandler<Packet, Packet> {
@Override
public Packet onMessage(final Packet packet, MessageContext ctx) {
	IThreadListener mainThread = (WorldServer) ctx.getServerHandler().playerEntity.worldObj;
	mainThread.addScheduledTask(new Runnable() {
		@Override
		public void run() {
			TileEntityNote noteBlock = packet.entity;
			noteBlock.triggerNote(noteBlock.getWorld(), noteBlock.getPos());
		}
	});
	return null;
}
}

 

Link to comment
Share on other sites

Okay, I think I understand where I went wrong. I was getting the TE before sending it to the server. Instead, I am now getting the world and the coordinates from the event that opens the GUI and sending that info to the server. I get the tile entity in the packet handler. However, this didn't fix the issue.

 

The point of the static field in the event handler is so that it can be used to send a packet in the actionPerformed method in the GUI class:

 

 

public static Packet entityNoteBlock;

    @SubscribeEvent
    public void playerInteract(PlayerInteractEvent event) {
    	if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) {
    		World world = event.world;
    		Block block = world.getBlockState(event.pos).getBlock();
    		if (block.equals(Blocks.noteblock)) {
                event.entityPlayer.openGui(NBGUI.instance, GUI.GUI_ID, world, event.pos.getX(), event.pos.getY(), event.pos.getZ());
                entityNoteBlock = new Packet(event.pos.getX(), event.pos.getY(), event.pos.getZ());
                
                event.useBlock = Event.Result.DENY;
    		}
    	}
   }

    @Override
protected void actionPerformed(GuiButton button) throws IOException {
	switch (button.id) {
		case 1: //Play
                Packet playNote = EventHandlerCommon.entityNoteBlock;
                //playNote.setText("play");
                NBGUI.network.sendToServer(playNote);          
                break;
		case 2: //Note +1
			break;
		case 3: //Note -1
			break;
		case 4: //Octave +1
			break;
		case 5: //Octave -1
			break;
	}
}

 

 

 

IMessage:

 

package com.mark.nbgui.packet;

import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntityNote;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;

public class Packet implements IMessage {
    protected int x;
    protected int y;
    protected int z;

    public Packet() {
    }

    public Packet(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    @Override
    public void fromBytes(ByteBuf buf) {
    	x = buf.readInt();
    	y = buf.readInt();
    	z = buf.readInt();
    }

    @Override
    public void toBytes(ByteBuf buf) {
    	buf.writeInt(x);
    	buf.writeInt(y);
    	buf.writeInt(z);
    }
}

 

 

IMessageHandler:

 

public class PacketHandler implements IMessageHandler<Packet, Packet> {
@Override
public Packet onMessage(final Packet packet, final MessageContext ctx) {
	final IThreadListener mainThread = (WorldServer) ctx.getServerHandler().playerEntity.worldObj;
	mainThread.addScheduledTask(new Runnable() {
		@Override
		public void run() {
			World world = (World) mainThread;
			BlockPos pos = new BlockPos(packet.x, packet.y, packet.z);
			TileEntityNote noteBlock = (TileEntityNote) world.getTileEntity(pos);
			noteBlock.triggerNote(world, pos);
		}
	});
	return null;
}
}

 

Link to comment
Share on other sites

You just don't understand the concept of server/client, do you? Static variables completely circumvent it and cause a lot of problems.

You shoud just send the packet from the actionPerformed method directly, what is the point of the event handler anyways?

 

The point of the event handler is to open the GUI. I need to obtain the position of the TileEntity, and I do that by obtaining the position of the block in the same event that opens the GUI. How can I obtain the position directly from the actionPerformed method?

Link to comment
Share on other sites

Okay. Again, how do I obtain the position of the block the GUI is open for then? If the field can not be static, that means that the actionPerformed method (which is in another class) can not use that, and conversely I cannot use the current method of obtaining the position from the same event as the one that opens the GUI. Thus, there needs to be an alternative.

Link to comment
Share on other sites

In your GUI handler you pass the position to the GuiScreen.

 

Okay, cool, that's simpler than what I was trying to do. I think I did it correctly, but it the issue still occurs.

 

Some of the GUI class:

 

public class GUI extends GuiScreen {
    private int x;
    private int y;
    private int z;
    
    public GUI(EntityPlayer player, World world, int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    @Override
protected void actionPerformed(GuiButton button) throws IOException {
    	switch (button.id) {
    		case 1: //Play
    			Packet playNote = new Packet(x, y, z);
    			NBGUI.network.sendToServer(playNote);          
    			break;
	}
    }
}

 

Link to comment
Share on other sites

I have this too right now, just excluded it:

    @SubscribeEvent
    public void noteBlockChange(NoteBlockEvent.Change event) {
        event.setCanceled(true);
        //CHANGE EVENT
    }

That, along with setting useBlock to DENY just stops the default action of changing the pitch. If I allow the pitch to be changed while still opening the GUI, a similar thing happens (since the note is played upon tuning the block). If I also left click to play a note and then open the GUI, again, a similar thing happens:

[embed=425,349]<iframe width="560" height="315" src="https://www.youtube.com/embed/mMUPkPS3hCY" frameborder="0" allowfullscreen></iframe>[/embed]

Note that the GUI does not pause the game.

 

And do I cancel the event with

event.setCanceled(true);

If so, it didn't help.

 

Link to comment
Share on other sites

package com.mark.nbgui;

import com.mark.nbgui.packet.Packet;

import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityNote;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.world.NoteBlockEvent;
import net.minecraftforge.fml.client.FMLClientHandler;
import net.minecraftforge.fml.common.eventhandler.Event;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

public class EventHandlerCommon {	

    /*@SubscribeEvent
    public void noteBlockChange(NoteBlockEvent.Change event) {
        event.setCanceled(true);
        //CHANGE EVENT
    }*/

    /*@SubscribeEvent
    public void noteBlockPlay(NoteBlockEvent.Play event) {
        //PLAY OVERRIDDEN
    }*/
    
    @SubscribeEvent
    @SideOnly(Side.CLIENT)
    public void onKeyInput(InputEvent.KeyInputEvent event) {
    	Minecraft mc = Minecraft.getMinecraft();
        if (KeyBindings.returnInput.isPressed() && FMLClientHandler.instance().getClient().inGameHasFocus) {
        }
    }

@SubscribeEvent
    public void playerInteract(PlayerInteractEvent event) {
    	if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) {
    		World world = event.world;
    		Block block = world.getBlockState(event.pos).getBlock();
    		if (block.equals(Blocks.noteblock)) {
                event.entityPlayer.openGui(NBGUI.instance, GUI.GUI_ID, world, event.pos.getX(), event.pos.getY(), event.pos.getZ());
                
                event.useBlock = Event.Result.DENY;
                event.setCanceled(true);
    		}
    	}
    }
}

 

package com.mark.nbgui;

import net.minecraft.block.Block;
import net.minecraft.block.BlockNote;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.tileentity.TileEntityNote;
import net.minecraft.util.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.world.NoteBlockEvent;
import net.minecraftforge.event.world.NoteBlockEvent.Octave;
import net.minecraftforge.fml.common.eventhandler.Event;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.network.internal.FMLMessage;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

import java.io.IOException;

import org.lwjgl.input.Keyboard;

import com.mark.nbgui.packet.Packet;

public class GUI extends GuiScreen {
public final static int GUI_ID = 20;

    private static String instrumentText = I18n.format("nbgui.string.gui.instrument", new Object[0])+" {instrument}";
    private static String noteText = I18n.format("nbgui.string.gui.note", new Object[0])+" {note}";
    private static String octaveText = I18n.format("nbgui.string.gui.octave", new Object[0])+" {octave}";

    private int x;
    private int y;
    private int z;
    private TileEntityNote entityNote;
    private BlockNote blockNote;
    private Block underBlock;
    
    public static GuiTextField noteTextField;
    public static GuiTextField octaveTextField;
    
    public GUI(EntityPlayer player, World world, int x, int y, int z) {
        BlockPos pos = new BlockPos(x, y, z);
        this.x = x;
        this.y = y;
        this.z = z;
        
        //TODO Returns null, fix.
        //System.out.println("[DEBUG] GNote: "+entityNote);
        //System.out.println("[DEBUG] GBlock: "+blockNote);
        //System.out.println("[DEBUG] GUnder: "+underBlock);
        this.entityNote = (TileEntityNote) world.getTileEntity(pos);
        this.blockNote = (BlockNote) world.getBlockState(pos).getBlock();
        this.underBlock = world.getBlockState(pos.down()).getBlock();
    }

@Override
    public void drawScreen(int x, int y, float f) {
		this.drawDefaultBackground();
		super.drawScreen(x, y, f);

		this.noteTextField.drawTextBox();
		this.octaveTextField.drawTextBox();

            this.drawCenteredString(this.fontRendererObj,
                    GUI.instrumentText.replace("{instrument}",
                    NoteUtils.getInstrumentString(NoteUtils.getNoteBlockInstrument(this.underBlock))),
                    this.width / 2, 30, 0xFFFFFFFF);
            //TODO Remove note and octave strings; redundant with text fields
            this.drawCenteredString(this.fontRendererObj,
                    GUI.noteText.replace("{note}", 
                    NoteUtils.getNoteString(NoteUtils.getBlockNote(this.entityNote))),
                    this.width / 2, 50, 0xFFFFFFFF);
            this.drawCenteredString(this.fontRendererObj,
                    GUI.octaveText.replace("{octave}", 
                    NoteUtils.getOctaveString(NoteUtils.getBlockOctave(this.entityNote))),
                    this.width / 2, 70, 0xFFFFFFFF);
            
    }

@Override
public void initGui() {    
	Keyboard.enableRepeatEvents(false);

	//Play Button
	GuiButton playButton = new GuiButton(1, this.width / 2 - 30, 90, 60, 20, I18n.format("nbgui.button.playNote", new Object[0]));	
	this.buttonList.add(playButton);

	//Note +1 Button
	GuiButton noteButtonAdd = new GuiButton(2, this.width / 2 - 60, 130, 20, 20, "+");
	this.buttonList.add(noteButtonAdd);

	//Note -1 Button
	GuiButton noteButtonSub = new GuiButton(3, this.width / 2 + 40, 130, 20, 20, "-");
	this.buttonList.add(noteButtonSub);

	//Octave +1 Button
	GuiButton octaveButtonAdd = new GuiButton(4, this.width / 2 - 60, 160, 20, 20, "+");
	this.buttonList.add(octaveButtonAdd);
	//TODO Grey out button if octave == 5 && note.equals("F_SHARP")

	//Octave -1 Button
	GuiButton octaveButtonSub = new GuiButton(5, this.width / 2 + 40, 160, 20, 20, "-");
	this.buttonList.add(octaveButtonSub);
	//TODO Grey out button if octave == 3


	//Note Text Field
	this.noteTextField = new GuiTextField(2, fontRendererObj, this.width/2 - 30, 130, 60, 20);
	this.noteTextField.setFocused(false);
	this.noteTextField.setCanLoseFocus(true);
	this.noteTextField.setText(NoteUtils.getNoteString(NoteUtils.getBlockNote(this.entityNote)));
	this.noteTextField.setTextColor(-1);
	this.noteTextField.setDisabledTextColour(-1);
	this.noteTextField.setEnableBackgroundDrawing(true);
	this.noteTextField.setMaxStringLength(7);

	//Octave Text Field
	this.octaveTextField = new GuiTextField(3, fontRendererObj, this.width/2 - 30, 160, 60, 20);
	this.octaveTextField.setFocused(false);
	this.octaveTextField.setCanLoseFocus(true);
	this.octaveTextField.setText(NoteUtils.getOctaveString(NoteUtils.getBlockOctave(this.entityNote)));
	this.octaveTextField.setTextColor(-1);
	this.octaveTextField.setDisabledTextColour(-1);
	this.octaveTextField.setEnableBackgroundDrawing(true);
	this.octaveTextField.setMaxStringLength(1);	

	//TODO Add option to merge note and octave text fields into one.
    }

    @Override
    public void keyTyped(char character, int keyCode) throws IOException {
    	super.keyTyped(character, keyCode);
    	if (keyCode == 28 && this.noteTextField.isFocused()) {
        	System.out.println("[DEBUG] Character: "+character);
        	System.out.println("[DEBUG] Code: "+keyCode);        	
		//TODO Send packets
    	} else if (keyCode == 28 && this.octaveTextField.isFocused()) {
        	System.out.println("[DEBUG] Character: "+character);
        	System.out.println("[DEBUG] Code: "+keyCode);        	
		//TODO Send packets
    	}   	
    }
    
    @Override
    public void mouseClicked(int x, int y, int clickedButon) throws IOException {
    	super.mouseClicked(x, y, clickedButon);
    	this.noteTextField.mouseClicked(x, y, clickedButon);
    	this.octaveTextField.mouseClicked(x, y, clickedButon);
    	if (this.noteTextField.isFocused()) {
    		this.noteTextField.setText("");
    	} else if (this.octaveTextField.isFocused()) {
    		this.octaveTextField.setText("");   		
    	}
    	/*Debug
    	System.out.println("[DEBUG] Note focused: "+noteTextField.isFocused());
    	System.out.println("[DEBUG] Octave focused: "+octaveTextField.isFocused());
    	System.out.println("[DEBUG]-------------------END-----------------------");*/
    	}
    
    @Override	
    public void updateScreen() {
    	 this.noteTextField.updateCursorCounter();
    	 this.octaveTextField.updateCursorCounter();
    }
    
    @Override
    public void onGuiClosed() {
    	Keyboard.enableRepeatEvents(false);
        super.onGuiClosed();
    }
    
    @Override
protected void actionPerformed(GuiButton button) throws IOException {
    	switch (button.id) {
    		case 1: //Play
    			Packet playNote = new Packet(x, y, z);
    			//playNote.setText("play");
    			NBGUI.network.sendToServer(playNote);          
    			break;
		case 2: //Note +1
			break;
		case 3: //Note -1
			break;
		case 4: //Octave +1
			break;
		case 5: //Octave -1
			break;
	}
    }

    @Override
    public boolean doesGuiPauseGame() {
        return false;
    }
}

 

package com.mark.nbgui;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.IGuiHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;

@SideOnly(Side.CLIENT)
public class GUIHandler implements IGuiHandler {

@Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
        return null;
}

@Override
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
	if (ID == GUI.GUI_ID) {
		return new GUI(player, world, x, y, z);
	}
	return null;
}

}

 

package com.mark.nbgui.packet;

import io.netty.buffer.ByteBuf;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntityNote;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;

public class Packet implements IMessage {
    //protected NBTTagCompound compound;
    protected int x;
    protected int y;
    protected int z;

    public Packet() {
        //this.compound = new NBTTagCompound();
    }

    public Packet(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
        		 	
    	//this();
        //entityNote.writeToNBT(this.compound);
    }

    /*public void setText(String text) {
        this.compound.setString("____NBGUIMsg", text);
    }

    public void setPitch(int pitch) {
        this.compound.setString("____NBGUIMsg", "PITCH_" + pitch);
    }*/

    @Override
    public void fromBytes(ByteBuf buf) {
        //this.compound = ByteBufUtils.readTag(buf);
    	x = buf.readInt();
    	y = buf.readInt();
    	z = buf.readInt();
    }

    @Override
    public void toBytes(ByteBuf buf) {
        //ByteBufUtils.writeTag(buf, this.compound);
    	buf.writeInt(x);
    	buf.writeInt(y);
    	buf.writeInt(z);
    }
}

 

package com.mark.nbgui.packet;

import net.minecraft.client.Minecraft;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntityNote;
import net.minecraft.util.BlockPos;
import net.minecraft.util.IThreadListener;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;

public class PacketHandler implements IMessageHandler<Packet, Packet> {
@Override
public Packet onMessage(final Packet packet, final MessageContext ctx) {
	final IThreadListener mainThread = (WorldServer) ctx.getServerHandler().playerEntity.worldObj;
	mainThread.addScheduledTask(new Runnable() {
		@Override
		public void run() {
			World world = (World) mainThread;
			BlockPos pos = new BlockPos(packet.x, packet.y, packet.z);
			TileEntityNote noteBlock = (TileEntityNote) world.getTileEntity(pos);
			System.out.println("[DEBUG] PH World: "+world);
			System.out.println("[DEBUG] PH Pos: "+pos);
			noteBlock.triggerNote(world, pos);

			//DEBUG
			System.out.println("[DEBUG] PH getWorld: "+noteBlock.getWorld());
			System.out.println("[DEBUG] PH getPos: "+noteBlock.getPos());
			System.out.println("[DEBUG] PH note: "+noteBlock.note);
		}
	});
	return null;
}
}

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.