Jump to content

jca

Members
  • Posts

    391
  • Joined

  • Last visited

  • Days Won

    1
  • Feedback

    100%

Posts posted by jca

  1. 18 minutes ago, liverare said:

    Naming anything "resource" is bad, because it has a very ambiguous meaning in programming. Anything could be a resource. Perhaps GEItem, or something?

    It made sense in the context, a Resource would be Oak logs, Lobsters etc. That wouldn't fit the GEItem as it's not specific to GE and couldn't think of another name.

    Would ItemResource work better? 

    Thanks for the feedback.

    15 minutes ago, Explv said:

    Not sure why you have the constants THOUSAND and MILLION (which should be static btw). Everyone knows what 1000 is, and if you have a hard time reading a lot of 0s you can separate using underscores: 1_000_000.

    Thanks! Edited the snippet with underscores.

  2. Needed a class that would hold active GE price, have the amount of item collected, name of item etc. 

    Please feedback if this is not the most efficient way of doing this. Use by calling 

    Spoiler
    
    itemResource = new ItemResource("Item name", item_id);

     

    Code: 

    Spoiler
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.URL;
    
    class ItemResource {
    
        private String name;
        private String url;
    
        private int id;
        private int price;
        private int amount;
    
        public ItemResource(String name, int id) {
    
            this.url = "http://services.runescape.com/m=itemdb_oldschool/api/catalogue/detail.json?item=" + id;
            this.name = name;
            this.id = id;
            this.price = fetchPrice();
    
        }
    
        // Getters
    
        public int getPrice() {
            return price;
        }
    
        public int getAmount() {
            return amount;
        }
    
        public String getName() {
            return name;
        }
    
        // Setters
    
        public void setAmount(int i) {
            amount = amount + i;
        }
    
        // Reset Amount
    
        public void resetAmount() {
            amount = 0;
        }
    
        private int fetchPrice() {
            try (final BufferedReader reader = new BufferedReader(new InputStreamReader(new URL(url).openStream()))) {
                final String raw = reader.readLine().replace(",", "").replace("\"", "").split("price:")[1].split("}")[0];
    
                reader.close();
                return raw.endsWith("m") || raw.endsWith("k") ? (int) (Double.parseDouble(raw.substring(0, raw.length() - 1))
                        * (raw.endsWith("m") ? 1_000_000 : 1_000)) : Integer.parseInt(raw);
            } catch (final Exception e) {
                e.printStackTrace();
            }
            return -1;
        }
    
    }

     

    Credit to whoever wrote the fetchPrice() snippet, found on external site. 

    • Like 1
  3. 15 minutes ago, Explv said:

     

    I didn't realise you wanted to wait for the animation to finish.

    This is probably how I would approach such a problem (note I wrote this fucking quickly, so it probably doesn't even work, but it should at least give you an idea)

    
    // If we're not fighting, and the current monster is dying, wait until the animation has finished so we can pick up items
    else if (currentMonster.isAnimating() && currentMonster.getHealthPercent() == 0) {
      new ConditionalSleep(3000) {
        @Override
          public boolean condition() {
          return !currentMonster.isAnimating(); // Could change to exists(), not sure
        }
      }.sleep();
      sleep(200); // Not sure if there is a delay between death and items appearing
    } 

     

    I'll try switching out the timer for isAnimating() && getHealthPercent 

    Thanks for the snippet. 

  4. 1 hour ago, Explv said:

    sleep() is not discouraged, the sleep method and the ConditionalSleep class serve two different purposes.

    The first allows you to sleep for a fixed amount of time, and the second allows you to sleep until a condition is satisfied or a timeout exceeded.

    As for your question about picking up an item after combat, isAnimating() is a shitty way to determine if you are in combat, you could do something like this instead (note, not tested at all) :

     

    
    if (!myPlayer().isUnderAttack() && myPlayer().getInteracting() == null) {
        GroundItem bones = getGroundItems().closest("Bones");
        if (bones != null) {
            if (bones.interact("Take")) {
                new CondtionalSleep(5000) {
                    @Override
                    public boolean condition() {
                        return !bones.exists(); 
                    }
                }.sleep();
            }
        } else {
            NPC monster = getNpcs().closest(npc -> npc.getName().equals("Monster") && npc.isAttackable());
            if (monster != null && monster.interact("Attack")) {
                new ConditionalSleep(5000) {
                    @Override
                    public boolean condition() {
                        return !monster.isAttackable() || myPlayer().getInteracting() == monster; 
                    }
                }
            }
        }
    }

     

    The problem with this is the dying animation of the NPC, if there's multiple NPCs and no item exists on the ground until the dying animation is complete. 

    myPlayer().isUnderAttack() resolves to false when NPC is dead, but has not completed dying animation, which means there's no item on the ground and bones != null will be false. 

    myPlayer().getInteracting() == null will also be true when the NPC is dead, but has not completed animation. 

    Therefore is there's another NPC near by they will go on to attack that NPC as monster != null && monster.interact("Attack") is true. 

    I also tried .exists(), isVisible() etc. but all have the same result, so the only option I've found is timer to allow for NPC to complete dying animation. 

     

  5. On 05/12/2017 at 2:48 PM, Explv said:

     

     

    This just looks like an over complicated, and less efficient way of writing:

    
    if (myPlayer().isAnimating()) {
        sleep(2000);
    } else {
        // do action 
    }

     

    I was under the impression sleep() was discouraged in place of ConditionalSleep() 

    Then with ConditionalSleep() I wasn't able to find the right condition that would allow me to pick an item up after combat, thus a timer seemed to come in handy to delay the action of combat so bot has time to pick up item.

    Please enlighten me if this is not the case.

    Also thanks for the maps - helped heaps. 

    EDIT: Also, surely this would not help in the case of picking up an item after combat? If the player is fighting then isAnimating() = true, but as soon as it stops fighting isAnimating() = false, which lets it proceed. 

×
×
  • Create New...