Need help creating a web.

Discussion in 'Developer Support' started by Philosobyte, Dec 26, 2014.

  1. As I've said before, I've been attempting this for 3 days, with a total of about 20 hours burnt on trying to get from Point A to Point B. I would be strongly in your debt if you could help me get past this block.

    edit: The problem is that the web.getPathBuilder().buildTo(new Coordinate(2851, 3027, 0)); is returning a null Path. I think I've generated the coordinates correctly, written them down correctly, read them correctly, and assigned them back to the web correctly. I can't find any error.
    Code (Text):
    1.  
    2. // in WebCreator.java
    3. private Web web = new Web();
    4. private FileWeb fileWeb = new FileWeb();
    5. private Player player = Players.getLocal();
    6.  
    7. //these are Defeat3d's methods in his tutorial
    8.     public static List<Coordinate> getSurroundingWeb(final Locatable loc, final int radius, final int divisibleBy) {
    9.            final Coordinate[] reachable = loc.getPosition().getReachableCoordinates().toArray(new Coordinate[] {});
    10.            List<Coordinate> web = new ArrayList<Coordinate>();
    11.            for (Coordinate c : reachable) {
    12.                if (c.getX() % divisibleBy == 0 && c.getY() % divisibleBy == 0 && c.distanceTo(loc) <= radius) {
    13.                    web.add(c);
    14.                }
    15.            }
    16.            return web;
    17.        }
    18.    
    19.        public void addCoordinate(Coordinate... coordinates) {
    20.            final GameObjectQueryBuilder objects = GameObjects.newQuery().types(GameObject.Type.BOUNDARY_OBJECT, GameObject.Type.PRIMARY, GameObject.Type.WALL_DECORATION);
    21.            for (Coordinate c : coordinates) {
    22.                final CoordinateVertex cv = new CoordinateVertex(c);
    23.                web.addVertices(cv);
    24.                final int[][] add = new int[][]{{-2, +2}, {0, +2}, {+2, +2}, {+2, 0}, {+2, -2}, {0, -2}, {-2, -2}, {-2, 0}};
    25.                for (int[] i : add) {
    26.                    final Coordinate yes = new Coordinate(c.getX() + i[0], c.getY() + i[1], c.getPlane());
    27.                    final Coordinate between = new Coordinate(c.getX() + i[0] / 2, c.getY() + i[1] / 2, c.getPlane());
    28.                    final WebVertex v = getVertexAt(yes);
    29.                    if (v != null && objects.on(between).results().isEmpty()) {
    30.                        cv.addBidirectionalEdge(v);
    31.                    }
    32.                }
    33.            }
    34.        }
    35.    
    36.        WebVertex getVertexAt(Coordinate coordinate) {
    37.            for (WebVertex v : web.getRegularVertices()) {
    38.                if (v.getPosition().equals(coordinate)) {
    39.                    return v;
    40.                }
    41.            }
    42.            return null;
    43.        }
    44.  
    45.  
    46. //calling Defeat3d's methods with a GUI
    47. onActionPerformed(ActionEvent e)
    48. {
    49. if(e.getActionPerformed.equals("addArea")
    50.  
    51. // this is being called about every ten steps, encompassing with excess the starting and ending area
    52. addCoordinate(getSurroundingWeb(player, 20, 2).toArray(new Coordinate[] {}));
    53.  
    54. else if(e.getActionPerformed.equals("write")
    55. write();
    56. }
    57.  
    58. //my method to write to a file
    59.     public void write()
    60.     {
    61.         FileWeb web = new FileWeb();
    62.         web.addVertices(this.web.getVertices());
    63.         try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("webbie.web")))
    64.         {
    65.             oos.writeObject(web.toByteArray());
    66.         }
    67.         catch (Exception e)
    68.         {
    69.             e.printStackTrace();
    70.         }
    71.     }
    72.  

    Code (Text):
    1.  
    2. //in RaysNatRunner.java
    3. private Player player = Players.getLocal();
    4. private Web web = Traversal.getDefaultWeb();
    5.  
    6.     public boolean merge(final File file) {
    7.         try(ObjectInputStream input = new ObjectInputStream(new FileInputStream(file)))
    8.         {
    9.             Object obj = input.readObject();
    10.             if(obj != null && obj instanceof byte[])
    11.             {
    12.                 System.out.println("Is an instance of");       //successfully prints this
    13.                 FileWeb fileWeb = FileWeb.fromByteArray((byte[])obj);
    14.                 this.web.addVertices(fileWeb.getVertices());
    15.             }
    16.             else System.out.println("not an instance of");
    17.         } catch (Exception e) {
    18.             e.printStackTrace();
    19.         }
    20.         return true;
    21.     }
    22.  
    23. @Override
    24. public void onStart()
    25. {
    26.         merge(new File("webbie.web"));
    27. }
    28. @Override
    29. public void onLoop()
    30. {
    31. //prints  true, meaning the Path generated is null.
    32.         System.out.println(web.getPathBuilder().buildTo(new Coordinate(2851, 3027, 0)) == null);
    33.         stop();
    34. }
    35.  
     
    #1 Philosobyte, Dec 26, 2014
    Last edited: Dec 26, 2014
  2. Don't use an ObjectOutputStream, use a byte[] output stream. Next, by generating the "surrounding web" every few tiles, you're generating an enormously bulky and overlapping web that doesn't connect correctly.
     
  3. I sort of assumed that adding a vertex that the web already had would have no effect. I will use a byte[] output stream, and attempt to modify Defeat3d's methods to use a Set in hopes of preventing overlap. I'll report back.
     
  4. The problem isn't just overlap, the problem is the vertices that are like 1 tile away won't even be linked if you stick to defeateds method.
     
  5. @Furor You're my savior. You told me about the BresenhamPath, which works with the default web. Now I can wrap up my Nat Runner.

    My current dilemma is currently solved, thanks to Furor. My thanks to Cloud, also - I know you've spent a lot of time reading this and trying to help.



    But I still haven't managed to create a web.


    I don't need a web anymore, but the issue is still intriguing and might be worth an investigation if you have the time.
    That's why I tried to use general concept of his methods and create my own version using +-1. Instead of using a Set, like I said I would in my last post, I just put in a check to see if the Map already contained the key. Here's the code. It still has the same problem of returning a null Path.

    Code (Text):
    1.  
    2.  
    3. //the complete RaysWebCreator.java I didn't include the GUI.
    4. package com.raymondbl.runemate.webCreator;
    5.  
    6. import java.awt.Graphics2D;
    7. import java.awt.event.ActionEvent;
    8. import java.awt.event.ActionListener;
    9. import java.io.FileOutputStream;
    10. import java.util.ArrayList;
    11. import java.util.Collection;
    12. import java.util.HashMap;
    13. import java.util.Iterator;
    14. import java.util.List;
    15. import java.util.Map;
    16.  
    17. import com.runemate.game.api.client.paint.PaintListener;
    18. import com.runemate.game.api.hybrid.entities.GameObject;
    19. import com.runemate.game.api.hybrid.entities.Player;
    20. import com.runemate.game.api.hybrid.location.Coordinate;
    21. import com.runemate.game.api.hybrid.location.navigation.web.WebVertex;
    22. import com.runemate.game.api.hybrid.location.navigation.web.default_webs.FileWeb;
    23. import com.runemate.game.api.hybrid.location.navigation.web.vertex_types.CoordinateVertex;
    24. import com.runemate.game.api.hybrid.region.GameObjects;
    25. import com.runemate.game.api.hybrid.region.Players;
    26. import com.runemate.game.api.hybrid.util.StopWatch;
    27. import com.runemate.game.api.script.Execution;
    28. import com.runemate.game.api.script.framework.LoopingScript;
    29.  
    30. public class RaysWebCreator extends LoopingScript implements
    31.                                 PaintListener, ActionListener
    32. {
    33.     private boolean condition;
    34.     private Coordinate position;
    35.     private RaysWebCreatorGUI gui;
    36.     private Player player;
    37.     private String command;
    38.     private Map<Coordinate, WebVertex> vertices = new HashMap<>();
    39.     private StopWatch runtime = new StopWatch();
    40.  
    41.     @Override
    42.     public void actionPerformed(ActionEvent e)
    43.     {
    44.         String command = e.getActionCommand();
    45.         if(command.equals("addArea") || command.equals("gen"))
    46.         {
    47.             this.command = command;
    48.             condition = true;
    49.         }
    50.     }
    51.  
    52.     @Override
    53.     public void onPaint(Graphics2D g)
    54.     {
    55.         if(gui != null)
    56.         gui.setRuntime(runtime.getRuntimeAsString());
    57.     }
    58.  
    59.     @Override
    60.     public void onStart(String... args)
    61.     {
    62.         getEventDispatcher().addListener(this);
    63.         gui = new RaysWebCreatorGUI();
    64.         player = Players.getLocal();
    65.         gui.setVisible(true);
    66.         runtime.start();
    67.         gui.setListener(this);
    68.     }
    69.  
    70.     @Override
    71.     public void onLoop()
    72.     {
    73.         condition = false;
    74.         System.out.println("Waiting...");
    75.         gui.setStatus("Waiting...");
    76.         Execution.delayUntil(() -> condition);
    77.         if(command.equals("addArea"))
    78.         {
    79.             addArea();
    80.         }
    81.         if(command.equals("gen"))
    82.             gen();
    83.         if(command.equals("reset"))
    84.             reset();
    85.          
    86.     }
    87.  
    88.     public void addArea()
    89.     {
    90.         int radius = getRadius();
    91.         position = player.getPosition();
    92.         Collection<Coordinate> collection = position.getReachableCoordinates();
    93.         Iterator<Coordinate> iterator = collection.iterator();
    94.         while(iterator.hasNext())
    95.         {
    96.             Coordinate c = iterator.next();
    97.             if((c.distanceTo(player) <= radius) && !vertices.containsKey(c))
    98.             {
    99.                 GameObject object = GameObjects.getLoadedAt(c).first();
    100.                 if((object == null) || !object.getDefinition().impassable())
    101.                 {
    102.                     CoordinateVertex v = new CoordinateVertex(c);
    103.                     vertices.put(c, v);
    104.                 }
    105.             }
    106.         }
    107.      
    108.         vertices.forEach((Coordinate key, WebVertex vertex) ->
    109.         {
    110.             int[][] ar = new int[][]
    111.                     {
    112.                     {-1, 0, 1}, {-1, 0, 1}
    113.                     };
    114.             for(int i = 0; i < 3; i++)
    115.             {
    116.                 for(int k = 0; k < 3; k++)
    117.                 {
    118.                     Coordinate c = new Coordinate(ar[0][i], ar[1][k]);
    119.                     if(vertices.containsKey(c))
    120.                     {
    121.                         vertex.addBidirectionalEdge(vertices.get(c));
    122.                     }
    123.                 }
    124.             }
    125.         });      
    126.     }
    127.  
    128.     public void gen()
    129.     {
    130.         gui.setStatus("genning...");
    131.         System.out.println("genning...");
    132.         Collection<WebVertex> list = new ArrayList<>();
    133.         vertices.forEach((Coordinate key, WebVertex vertex) ->
    134.                 list.add(vertex));
    135.         FileWeb web = new FileWeb();
    136.         web.addVertices(list);
    137.         try(FileOutputStream fos = new FileOutputStream("webbset.web"))
    138.         {
    139.             fos.write(web.toByteArray());
    140.         }
    141.         catch (Exception e)
    142.         {
    143.             e.printStackTrace();
    144.         }
    145.     }
    146.  
    147.     public void reset()
    148.     {
    149.         vertices = new HashMap<>();
    150.     }
    151.  
    152.     public int getRadius()
    153.     {
    154.         return Integer.parseInt(gui.getRadius());
    155.     }
    156.  
    157. }
    158.  
    Code (Text):
    1.  
    2. //the only method that really matters in the main NatRunner class
    3.  
    4. public boolean merge(final File file) {
    5.         try(FileInputStream input = new FileInputStream("webbset.web"))
    6.         {
    7.             byte[] obj = new byte[input.available() + 32];
    8.             input.read(obj);
    9.               FileWeb fileWeb = FileWeb.fromByteArray(obj);
    10.             System.out.println(fileWeb.getVertices());
    11.             this.web.addVertices(fileWeb.getVertices());
    12.         } catch (Exception e) {
    13.             e.printStackTrace();
    14.         }
    15.         return true;
    16.     }
    17.  
     
  6. another problem is with your merge method, just adding the new vertices isn't enough. You have to connect things with edges or else you will have a split web. I'd assume the problem lies with your edges not correctly connecting and thus the web ending up with isolated sections.
     
  7. I thought the edges added before writing the file would carry over. I'll add them in the merge() method first thing tomorrow morning and post a status update.
     
  8. You're right, they should be. But you're never connecting your additions to the default web with an edge.
     
  9. The new vertices completely cover the path, though, with room to spare. Theoretically, the default web shouldn't even be needed.
    I'm also assuming in the code that the Coordinate class override the equals() method so that different objects with the same fields are treated as equal.
    I'll try to connect them to the default web.
     
  10. If they're not connected, then how would you expect it to build a path over the gap? Even if they overlap, if there's no edge there's no path to follow.
     
  11. What gap? If what's not connected? If what overlaps? I'm not sure what you mean here. All the new vertices should be interconnected - the path is wholly within those new vertices. That's why I said the default web shouldn't be needed. I tried it using private Web web = new Web(); and using the merge method to read the FileWeb into that empty Web, but the pathbuilder still came out with a null path.
     
  12. In the nested for loops - you see this?
    Code (Text):
    1.  
    2. Coordinate c = new Coordinate(ar[0][i], ar[1][k]);
    3.  
    I originally meant to put
    Code (Text):
    1.  
    2. Coordinate c = key.derive(ar[0][i], ar[1][k]);
    3.  
    ...

    *facepalm*

    That was pretty much the only change to the above code for it to work with its own web, without merging the default web!
    Thanks again, Cloud. I am in your debt.

    I plan on saving Defeat3d some time and uploading this as a similar tool, but for RS3 and open-source. I will give Cloud and Defeat3d credit in the GUI.
     

Share This Page

Loading...