Updating a Sign

Discussion in 'Plugin Development' started by isoccerplayer, Aug 8, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    isoccerplayer

    I am in the process of making a Zombie Arena type plugin, and I want to be able to List the Leaders (People with most kills) On signs, and have those signs update after each round, should there be a new leader.

    These signs will be declared with [Leaderboard] as the first line, and once the sign is made, it's Location will be saved to a yaml file, so the Location can be loaded after restarts, etc.

    Anyways, I was just testing if I COULD create a sign, then find it's location, then send it's location to a method where it will then update the sign's lines.

    I can't seem to get it to work, though, so could someone shed some light on what I am doing wrong?

    Code:
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.World;
    import org.bukkit.block.Block;
    import org.bukkit.block.Sign;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.SignChangeEvent;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class SignAutoUpdater extends JavaPlugin implements Listener{
        public void onEnable() {
            getLogger().info("SignUpdater Enabled");
            getServer().getPluginManager().registerEvents(this, this);
           
        }
       
        public void onDisable() {
            getLogger().info("SignUpdater Disabled");
        }
        @EventHandler
        public void blockPlaced(SignChangeEvent event) {
            String[] a= event.getLines();
            if (a[1].equals("[Test]")) {
                Location b = event.getBlock().getLocation();
                signUpdater(b);
            }
        }
        public void signUpdater(Location loc) {
            World w = loc.getWorld();
            Block a = w.getBlockAt(loc);
            if (a.getType() == Material.SIGN_POST || a.getType() == Material.WALL_SIGN) {
                Sign sign = (Sign)a.getState();
                if (sign.getLine(1).equals("[Test]")) {
                    sign.setLine(1, "isoccerplayer");
                }
            }
        }
       
     
    }
    
     
  2. add a sign.update(); after you change the sign.
    (If that doesn't work, try calling sign.update(true); but you shouldn't have to)
     
  3. Offline

    isoccerplayer

    I tried both sign.update(); and sign.update(true); byt the sign still read as [Test] :/
     
  4. Offline

    bitfreeze

    event.setLine(1, "isoccerplayer");
     
  5. Offline

    isoccerplayer

    I know I can change the text, straight from the event, but I need to take the Sign's location, so I can save it in a yaml file, and be able to reference that location, and update the sign. Unless theres a better way of saving sign data, between server restarts?

    I am just using this program, to test taking a sign's location, and changing the lines, but it isn't working :/
     
  6. Offline

    messageofdeath

  7. Offline

    bitfreeze

    It is working.
    The problem here is that you're calling signUpdate from inside the event.

    When you place a sign in-game it actually places the empty sign in the world then opens the edit interface.
    When you click Done, the event will be called, giving you the opportunity to check/censor/log/replace the sign lines.
    So far, the physical sign on the world is blank yet.
    Then the event ends, and the lines are written on the physical sign.

    Your signUpdate is updating the sign, but right after that the event is overriding any changes with the lines stored in it.

    Update the event lines, not directly the sign on the world.


    EDIT:
    messageofdeath: he is already using the SignChangeEvent.
     
  8. Offline

    hawkfalcon

    //offtopic
    Nice Avatar!:D
     
  9. Offline

    messageofdeath

    bitfreeze
    Oh shoot. I saw the "blockPlaced" thing (label of his SignChangeEvent). So my guess is now @isoccerplayer is you don't/not correct plugin.yml
     
  10. Offline

    isoccerplayer

    bitfreeze I updated it, so when you place the sign, it will save it's location, if it has [Test] on line 2. Then, you use the command /signs to update the sign. Still isn't working. Am I still doing something wrong?

    Code:
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.World;
    import org.bukkit.block.Block;
    import org.bukkit.block.Sign;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.SignChangeEvent;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class SignAutoUpdater extends JavaPlugin implements Listener{
        private Location b;
       
        public void onEnable() {
            getLogger().info("SignUpdater Enabled");
            getServer().getPluginManager().registerEvents(this, this);
           
        }
       
        public void onDisable() {
            getLogger().info("SignUpdater Disabled");
        }
        @EventHandler
        public void blockPlaced(SignChangeEvent event) {
            String[] a= event.getLines();
            if (a[1].equals("[Test]")) {
                b = event.getBlock().getLocation();
            }
        }
        public void signUpdater(Location loc) {
            World w = loc.getWorld();
            Block a = w.getBlockAt(loc);
            if (a.getType() == Material.SIGN_POST || a.getType() == Material.WALL_SIGN) {
                Sign sign = (Sign)a.getState();
                    sign.setLine(1, "isoccerplayer");
               
            }
        }
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args){
            if(cmd.getName().equalsIgnoreCase("signs")) {
                signUpdater(b);
                return true;
            }
            return false;
        }
       
     
    }
    
     
  11. Offline

    bitfreeze

    Ah well, are you typing [Test] on the first or on the second line?
    a[1] refers to the second if I'm not wrong... only noticed that now.
     
  12. Offline

    isoccerplayer

    I am putting [Test] on the 2nd line down.

    Maybe my way isn't the correct way of doing things... Do you have a suggestion, as to how I can refer back to a sign, later on, to change it's contents w/o a player clicking it?

    Bump?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 27, 2016
  13. Offline

    travja

    What would happen that you would need to change the contents of the sign?
     
  14. Offline

    isoccerplayer

    I want to be able to display a leader board. After each round, if one of the high scores were beaten, the leader board would need to update to display the new leader(s).
     
  15. Offline

    travja

    So when the winner is announced, in that same event change the sign instead of making your own event and just update the sign there, would seem easier.
     
  16. Offline

    isoccerplayer

    But, how would you change the sign, in the event? I'm trying to find a way to where I could refer back to that sign, so it COULD be changed, when it needs to be. Any ideas? xD
     
  17. Offline

    travja

    Use:
    Code:java
    1. Block b = world.getBlockAtLocation(x,y,z);
    2. if(b instanceof Sign){
    3. sign = (Sign) b;
    4. //do stuff
    5. sign.getState().update();
    6. }


    Just put that in the event where needed, should work.
     
  18. Offline

    isoccerplayer

    It's returning errors. To test this, I want to be able to save the sign's location, as a variable, then when I use the command, /signs, the sign will update.

    My Code:

    Code:
    import org.bukkit.Location;
    import org.bukkit.Material;
    import org.bukkit.World;
    import org.bukkit.block.Block;
    import org.bukkit.block.Sign;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.SignChangeEvent;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class SignAutoUpdater extends JavaPlugin implements Listener{
        private Location bLocation;
       
        public void onEnable() {
            getLogger().info("SignUpdater Enabled");
            getServer().getPluginManager().registerEvents(this, this);
           
        }
       
        public void onDisable() {
            getLogger().info("SignUpdater Disabled");
        }
        @EventHandler
        public void blockPlaced(SignChangeEvent event) {
            String[] a= event.getLines();
            if (a[1].equals("[Test]")) {
                bLocation = event.getBlock().getLocation();
            }
        }
        public void signUpdater(Location loc) {
            Block b = bLocation.getWorld().getBlockAtLocation(bLocation.getX(),bLocation.getY(),bLocation.getZ());
            if(b instanceof Sign){
            sign = (Sign) b;
            //do stuff
            sign.getState().update();
            }
            }
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args){
            if(cmd.getName().equalsIgnoreCase("signs")) {
                signUpdater(bLocation);
                return true;
            }
            return false;
        }
       
     
    }
    
     
  19. Offline

    travja

    isoccerplayer ok, to do this, you will need to get the doubles of x,y,z and the WorldName it is stored in. So something like:
    double x = bLocation.getX();
    double y = bLocation.getY();
    double z = bLocation.getZ();
    String w = bLocation.getWorld().getName();

    Then input them into your config or something. Then you can retrieve them later and use them to locate the sign.
     
  20. Offline

    isoccerplayer

    Ok, and when I do:

    Code:
    if(b instanceof Sign){
            Sign sign = (Sign) b;
            //do stuff
            sign.getState().update();
    It won't let me 'getState()' from the sign object
     
  21. Offline

    travja

    Try to do b.getState().update(); instead of updating the sign object.
     
  22. Offline

    isoccerplayer

    Alright, heres my code right now (I had to make a few changes, to your suggestion, inorder for Eclipse to read it w/o any red marks)

    Code:
    import org.bukkit.Location;
    import org.bukkit.World;
    import org.bukkit.block.Block;
    import org.bukkit.block.Sign;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.SignChangeEvent;
    import org.bukkit.plugin.java.JavaPlugin;
     
    public class SignAutoUpdater extends JavaPlugin implements Listener{
        private Location bLocation;
       
       
        public void onEnable() {
            getLogger().info("SignUpdater Enabled");
            getServer().getPluginManager().registerEvents(this, this);
           
        }
       
        public void onDisable() {
            getLogger().info("SignUpdater Disabled");
        }
        @EventHandler
        public void blockPlaced(SignChangeEvent event) {
            String[] a= event.getLines();
            if (a[1].equals("[Test]")) {
                bLocation = event.getBlock().getLocation();
            }
        }
        public void signUpdater(Location bLocation) {
            World w = bLocation.getWorld();
            Block b = w.getBlockAt(bLocation);
            if(b instanceof Sign){
            Sign sign = (Sign) b;
            sign.setLine(1, "isoccerplayer");
            b.getState().update();
            }
            }
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args){
            if(cmd.getName().equalsIgnoreCase("signs")) {
                signUpdater(bLocation);
                return true;
            }
            return false;
        }
       
     
    }
    
    Still not working :/
     
  23. Offline

    travja

    I don't know custom event very well.. I would just code all the updating in the command itself.... I don't know if that would even make a difference though.... Try that, if it doesn't work..... I'ma do a little coding of myself tomorrow to figure this out...
     
  24. Offline

    isoccerplayer

    Ok, thanks for all the advice, so far. If you figure it out tomorrow, I would be happy to hear your solution :) I'll toy around with it some more; maybe I can figure it out.

    Thank you, though. You help is appreciated :)
     
  25. Offline

    bitfreeze

    Code:
        public void signUpdater(Location bLocation) {
            World w = bLocation.getWorld();
            Block b = w.getBlockAt(bLocation);
            if(b.getTypeId() == Material.SIGN_POST.getId() || b.getTypeId() == Material.WALL_SIGN.getId()) {
                Sign sign = (Sign) b.getState();
                sign.setLine(1, "isoccerplayer");
                sign.update();
            }
        }
    
     
  26. Offline

    isoccerplayer

    That works :D

    Thank you, for your help. It was much appreciated!
     
Thread Status:
Not open for further replies.

Share This Page