How to create 'Wires'

Discussion in 'Plugin Development' started by VortexGmer, May 29, 2015.

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

    VortexGmer

    Hi! I wanted to create Wires in minecraft to carry around electricity. I already have a solar panel that generates but that goes into a battery which must be moved by hand then to a machine. I need something like wires so maybe like influencing the iron fences as wires so that when you connect them they can carry the charge automatically from a solar panel to a machine? I know that I will have to use block metadata but I don't know exactly how... thanks for any help in advance!
     
  2. Offline

    Zombie_Striker

    @VortexGmer
    The best way you can try to use this is to store all the energy generators (E.G Solar panels or battery packs) in an Array List, loop through that array list in a scheduled repeating task and look at adjacent blocks and testing if they have the metadata. If the block has the meta data, find all adjacent blocks to that block, and do this over and over again with all wires that are connected.
     
  3. Offline

    VortexGmer

    Yes but what if they are multiple solar panels and the power is trying to go into one slar panel etc... I need like a block that has metadata of input and output so it can pathfind but how
     
  4. Offline

    Zombie_Striker

    @VortexGmer
    I don't know why that would be. Why would you want energy to go into something that creates energy? Because your idea is to take energy from solar panels and put it into solar panels (in and out the same type of block), your idea will be hard make and hard for me to explain how to do it.

    Set blocks as two types, with two different metadata values: Energy:IN and Energy:OUT. The IN are mechines that use up energy, the Out generates electricity. All you would need to do is use my wire explanation from above to connect the OUT to the INs.

    Unless you look at Tekkit's code and see how wires work, which I'm assuming you're basing this off of, I don't think there really is a way to find pathways for wires. My explanation from above just says to basically try all directions until it hits a machine, which I think is also how tekkits code works as well.
     
  5. Offline

    VortexGmer

    ok! So.. I tried doing this with some code and it crashes the server?
    Wire.java:
    Code:
    package me.VortexGamer.survival.Blocks;
    
    import java.util.ArrayList;
    
    import me.VortexGamer.survival.Survival;
    
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.block.Furnace;
    
    public class Wire {
        public Survival plugin;
    
        public Wire(Survival s) {
            this.plugin = s;
        }
    
        public static void transfer(Block b, Boolean Output, Short amt) {
            if (Output) {
    
                ArrayList<Block> blocks = new ArrayList<Block>();
                int radius = 1;
                for (int x = -b.getLocation().getBlockX(); x < b.getLocation()
                        .getBlockX() + radius; x++)
                    for (int y = -b.getLocation().getBlockY(); x < b.getLocation()
                            .getBlockY() + radius; y++)
                        for (int z = -b.getLocation().getBlockZ(); x < b
                                .getLocation().getBlockZ() + radius; z++)
                            blocks.add(b.getLocation().getWorld()
                                    .getBlockAt(x, y, z));
                for(Block a : blocks){
                    if(a.getType() == Material.IRON_FENCE){
                        transfer(a,true,amt);
                    }
                    if(a.hasMetadata("Chargeable")){
                        if(a.hasMetadata("efurnace")){
                            if(a.getType() == Material.FURNACE){
                                Furnace f = (Furnace) b.getState();
                                f.setBurnTime(amt);
                            }
                        }
                    }
                }
            }
        }
    }
    
    And SolarPanel.java:
    Code:
    package me.VortexGamer.survival.Blocks;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    
    import me.VortexGamer.survival.Survival;
    
    import org.bukkit.Bukkit;
    import org.bukkit.block.Block;
    import org.bukkit.event.Listener;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.meta.ItemMeta;
    
    public class SolarPanel implements Listener {
        public Survival plugin;
        public static ArrayList<Block> solars = new ArrayList<Block>();
        public float speed = 5F;
    
        public SolarPanel(Survival s) {
            this.plugin = s;
            plugin.getServer().getScheduler()
                    .scheduleSyncRepeatingTask(plugin, new Runnable() {
                        public void run() {
                            for(Block b : solars){
                            Wire.transfer(b,true,(short)5);
                            }
                        }
                    }, 0, 5L);
        }
    }
    
    Any ideas?

    Also I think you have misunderstood. I'm trying to make solar panel to the electric furnace

    EDIT by Timtower: merged posts
     
    Last edited by a moderator: May 30, 2015
  6. Offline

    Zombie_Striker

    @VortexGmer
    I think you did not type what you were thinking then :p

    The problem you're running into is you're doing this on the same, default thread. Sync means runs with the server, so if the server laggs, the runnable does too and vise versa. Async on the other hand does not run on the same thread, meaning that the Async can run for as long as it needs and it will not halt the server.

    Just change SyncReaptingTask to AsyncRepeatingTask.
     
  7. Offline

    mythbusterma

    By god, that's the worst advice I've seen all day, and I've been browsing the Bukkit Forums!

    Asynchrnous scheduling isn't just for "yea, this lags the server so do it on another thread." Running something on a different thread leads to many thread safety problems, none of which the Bukkit API addresses.

    Don't use "async" unless:
    1. You know what it actually means
    2. You know how to write thread-safe code
    3. You won't be accessing any of the Bukkit API from the other thread

    Besides, his issue isn't with the fact that it's running synchronously, the issue is that he wrote a horrendously inefficient algorithm.



    @VortexGmer

    First off, why is that method static and in the Wire class? That doesn't make a whole lot of sense. Second, fix your variable names. Third, you can't just make O(n^4) time complexity algorithms for your plugin, that's never going to reasonably run in real-time.

    You're probably going to want to go practice Java on something much simpler, and then instead use a recursive function to propagate power, and only actually do that when an update happens.
     
    CraftCreeper6, nverdier and AdamQpzm like this.
  8. Offline

    VortexGmer

    @Zombie_Striker
    @mythbusterma
    The solar panel works fine, I just am having problems with the wire
    If I change it to not static how will I be able to access the transfer FROM solar panel? So If it's running that fast how can I make it better?
     
  9. Offline

    mythbusterma

    @VortexGmer

    It's running extremely slow right now. "Wire" shouldn't even be it's own class if you never instantiate it, just have a method in SolarPanel called "propogate" or something like that that spreads the power.

    Again, figure out a more efficient way of writing the algorithm.
     
  10. Offline

    VortexGmer

    So put the method Indianola panel and efficient way, I have been researching and I just can't find out about if there's any way to make it work more efficiently, I will need to get some help from you or someone else.
     
  11. Offline

    mythbusterma

    @VortexGmer

    As I said before, use a recursive algorithm and only update when a change happens.
     
  12. Offline

    VortexGmer

    @mythbusterma
    So like not a scheduler?
    I don't understand how to do this..

    bump

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

    Zombie_Striker

  14. Offline

    VortexGmer

    So basically this is my thing. I will make a statement in the solarpanel which checks the blocks around it and around that block until it see a wire. Then it will Execute itself with a different center block and checks if that has wires around it. Then if it does it does it over and over until it reaches a chargeable block(Metadata)
    @Zombie_Striker @mythbusterma
    Is that good?
     
  15. Offline

    mythbusterma

    @VortexGmer

    Yes, you may want to safeguard that, however, as it could very easily wind up in an infinite loop.
     
  16. Offline

    VortexGmer

    Why would it go into that loop? @mythbusterma Also, @mrCookieSlime has a sensible toolbox plugin which uses this...
     
    Last edited: Jun 7, 2015
  17. Offline

    mythbusterma

    If someone were to create a loop with your "wires," wouldn't it wind up in infinite-depth recursion?
    @VortexGmer
     
  18. Offline

    VortexGmer

    Yes... It would... I just had it *Slightly* working and then when I tried what you suggested about the loop it did make the server crash. How would I fix this?
     
  19. Offline

    mythbusterma

    @VortexGmer

    Add some sort of value to the block to indicate you've already been there? Maybe keep track of the ones you've already gone over?
     
  20. Offline

    VortexGmer

    Now I'm totally stumped. Could you help me make the code from scratch?
     
  21. Offline

    I Al Istannen

    @VortexGmer Add some metadata to the block and only check for touching wires if they don't have that metadata. Or probably more easy to implement, make a HashSet and add every wireBlock just right before you start the search for touching wires for this block. And, of course only check if it is not on the set.
    I chose an HashSet, because the lookup should be quite fast. Maybe @mythbusterma has a better option though :)
     
  22. Offline

    mythbusterma

    @I Al Istannen

    That's a lot of junk data to store if you're using a HashSet of Blocks.


    @VortexGmer

    If you can make it work with some block metadata (I'm not sure if it's possible) that's by far the best option.

    If not, use a HashSet of Vectors, as they would be the smallest practical representation for the Location of Block.
     
  23. Offline

    I Al Istannen

    @mythbusterma The problem I see with blockMetadata is the removal. You would need to remove it by the next iteration. Alternativly you could use an incrementing score for the metadata and remove the last one, but I don't know if it's that practical.

    And, for the HashSet. Sadly i haven't had Vectors in school, so I have a very limited understanding of them. Are they just like a String containing x,y,z in this case? That's what I saw in an "A*" pathfinding library for Bukkit. He generated a UID out of the offset to the start. So, are Vectors better or Strings?
     
  24. Offline

    RingOfStorms

    I would only check for wire connection whenever a wire block is placed or destroyed, then simply save which blocks are connected to each other and then simply update the energy based on those saved connections. You want to minimize how often you "scan" your wires as it is a really heavy process. Also, for scanning, I don't see any practical way to use metadata, so yes storing vectors you've visited is probably the best option.

    A vector is literally just an object with three numbers representing the x/y/z of the block, you don't need any understanding in order to use the vectors in this case, unless you have no idea how to compare two numbers.
     
Thread Status:
Not open for further replies.

Share This Page