Jump to content
View in the app

A better way to browse. Learn more.

OSBot :: 2007 OSRS Botting

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Differentiating between fishing spots

Featured Replies

I'm writing a fishing bot for the fishing guild and I need to be able to tell the difference between a shark fishing spot and a swordfish fishing spot.

 

Right now I have

NPC fishingSpot = npcs.closest("Fishing spot");

Which will select a shark spot if it's the closest when I only want swordfish spots for example.

I tried the following

NPC fishingSpot = npcs.closestThatContains(true, "Fishing spot", "Cage");

But this is not working. I'm not sure what the bool does but false doesn't work either. Obviously this method doesn't do what I hoped it would. How could I get the closest "Fishing spot" that contains the interaction "Cage"?

Each fishing spot (not ones with same actions I believe) should have their own NPC id. You may try using that as a way of differentiating between the spots.

Please use the action filter to find out which one is what.

 

i did this on my phone so dont copy an past

example:

getNPCs().filter(new ActionFilter<NPC>("actions here");

Edited by josedpay

  • Author

Thanks so much guys. That will help a lot :)


Optional<NPC> lobster = getNpcs().getAll().stream().filter(o -> o.hasAction("Cage")).min(new Comparator<NPC>() {

@Override

public int compare(NPC a, NPC b) {

return getMap().distance(a.getPosition()) - getMap().distance(b.getPosition());

}

});

if(lobster.isPresent()){

lobster.get().interact("Cage");

}

  • Author

I ended up going with this for anyone running into a similar problem. Thanks again to everyone that helped

List<NPC> fishingSpots = getNpcs().filter(new ActionFilter<NPC>("Cage"));
NPC fishingSpot = fishingSpots.get(0);
for (NPC n : fishingSpots) {
    if (getMap().distance(n) - getMap().distance(myPlayer()) < getMap().distance(fishingSpot) - getMap().distance(myPlayer())) {
        fishingSpot = n;
    }
}

 

I ended up going with this for anyone running into a similar problem. Thanks again to everyone that helped

List<NPC> fishingSpots = getNpcs().filter(new ActionFilter<NPC>("Cage"));
NPC fishingSpot = fishingSpots.get(0);
for (NPC n : fishingSpots) {
    if (getMap().distance(n) - getMap().distance(myPlayer()) < getMap().distance(fishingSpot) - getMap().distance(myPlayer())) {
        fishingSpot = n;
    }
}

 

You should really use Botre's answer for that, or do something like this:

NPC fishingSpot = getNpcs().closest(new Filter<NPC>() {
    @Override
    public boolean match(NPC n) {
        return (n.hasAction("Cage") /* Other options if needed */);
    }
});

 

  • Author

ah okay, Botre's answer didn't work for me. I'll try what you have

ah okay, Botre's answer didn't work for me. I'll try what you have

 

You probably need to add null checks and .exist() checks on top of the action one to the predicate.

I want to make a contribution, so here:

package com.liverare.better.scripts.farming_aid;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.osbot.rs07.api.model.NPC;
import org.osbot.rs07.script.MethodProvider;

public class FishingSpotIdentifier {

	/**
	 * MethodProvided the running script instance is using
	 */
	private final MethodProvider methodProvider;
	
	/**
	 * <key = action profile, value = NPC ID>
	 */
	private final Map<ActionProfile, Integer> fishingSpotIdCache;
	
	public FishingSpotIdentifier(MethodProvider methodProvider) {
		this.methodProvider = methodProvider;
		this.fishingSpotIdCache = new HashMap<>();
	}
	
	/**
	 * @param actionProfile
	 *            The specific fishing spot to find
	 * @return List of the requested fishing spot, ordered by distance
	 */
	public List<NPC> get(ActionProfile actionProfile) {
		
		List<NPC> result = null;
		
		final List<NPC> found = methodProvider.getNpcs().getAll();
		
		Integer cachedId = fishingSpotIdCache.get(actionProfile);
		
		if (cachedId != null) {

			result = found.stream().filter(npc -> cachedId.equals(npc.getId())).collect(Collectors.toList());

		} else {

			result = found.stream().filter(npc -> hasAllActions(npc.getActions(), actionProfile.getActions()))
					.collect(Collectors.toList());

			fishingSpotIdCache.put(actionProfile, result.iterator().next().getId());
		}
		
		if (!result.isEmpty()) {
			
			result.sort((a, b) -> Integer.compare(methodProvider.getMap().distance(a),
					methodProvider.getMap().distance(b)));
		}
		
		return result;
	}
	
	/**
	 * 
	 * @param actions
	 *            Actions to check against
	 * @param actionsToFind
	 *            Actions to find (all!)
	 * @return <tt>Actions array contains all of our requested actions</tt>
	 */
	private boolean hasAllActions(String[] actions, String... actionsToFind) {
		boolean result = true;
		for (String actionToFind : actionsToFind) {
			if (!contains(actions, actionToFind)) {
				result = false;
				break;
			}
		}
		return result;
	}
	
	/**
	 * 
	 * @param arr
	 *            Array of strings to search
	 * @param aString
	 *            String to find within the array
	 * @return <tt>Requested string is present within the array</tt>
	 */
	private boolean contains(String[] arr, String aString) {
		boolean found = false;
		for (String s : arr) {
			if (s.equals(aString)) {
				found = true;
				break;
			}
		}
		return found;
	}

	/*
	 * Each record will be used to distinguish each fishing spot.
	 */
	public static enum ActionProfile {
		
		CAGE_HARPOON("Cage", "Harpoon"),
		NET_HARPOON("Net", "Harpoon"),
		
		;
		
		private final String[] actions;
		
		private ActionProfile(String... actions) {
			this.actions = actions;
		}
		
		public String[] getActions() {
			return actions;
		}
	};
	
}

It can be used as:

package com.liverare.better.scripts.farming_aid;

import java.util.List;

import org.osbot.rs07.api.model.NPC;
import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;

import com.liverare.better.scripts.farming_aid.FishingSpotIdentifier.ActionProfile;

@ScriptManifest(name = "Fishing", info = "Fishes", version = 1.0, author = "LiveRare", logo = "")
public class FishingScript extends Script {
	
	FishingSpotIdentifier fishingSpotIdentifier;
	
	@Override
	public void onStart() throws InterruptedException {
	
		fishingSpotIdentifier = new FishingSpotIdentifier(this);
	}
	
	@Override
	public int onLoop() throws InterruptedException {
		
		List<NPC> fishingSpot = fishingSpotIdentifier.get(ActionProfile.NET_HARPOON);
		
		if (!fishingSpot.isEmpty()) {
			
			fishingSpot.iterator().next().interact("Harpoon");
		}
		
		return 500;
	}

}


Same fishing spots all have a consistent ID, so if you can discern which spot is for which fish, you can cach the profile and ID of the fishing spot. Then, when you need to re-find a new fishing spot, you won't need to run another action check, since you now have the ID of the fishing spot. This is more efficient, also the FishingSpotIdentifier#ActionProfile enumerator can be expanded to include all fishing spots. In fact, you could add an uninitiated integer field variable in the enumerator and initiate that, instead of dealing with a Map. But...cba. The Map strategy came to me first. :)

 

Edited by liverare

Optional<NPC> lobster = getNpcs().getAll().stream().filter(o -> o.hasAction("Cage")).min(new Comparator<NPC>() {
                    @Override
                    public int compare(NPC a, NPC b) {
                        return getMap().distance(a.getPosition()) - getMap().distance(b.getPosition());
                    }
                });
                if(lobster.isPresent()){
                    lobster.get().interact("Cage");
                }

Integer.compare pls

 

@OP: All fishing spots have 2 actions registered to them. For example, lobsters will have Cage and Harpoon. You can identify fishing spots based on that.

 

Integer.compare pls

 

@OP: All fishing spots have 2 actions registered to them. For example, lobsters will have Cage and Harpoon. You can identify fishing spots based on that.

 

Good call, didn't know about that one.

 

For those who also don't know about it(yet):

/**
     * Compares two {@code int} values numerically.
     * The value returned is identical to what would be returned by:
     * <pre>
     *    Integer.valueOf(x).compareTo(Integer.valueOf(y))
     * </pre>
     *
     * @param  x the first {@code int} to compare
     * @param  y the second {@code int} to compare
     * @return the value {@code 0} if {@code x == y};
     *         a value less than {@code 0} if {@code x < y}; and
     *         a value greater than {@code 0} if {@code x > y}
     * @since 1.7
     */
    public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }

Doesn't #closest take a filter argument

instance.npcs.closest(npc -> {
        return npc.hasAction(action 1)
		&& npc.hasAction(action 2);

});

Create an account or sign in to comment

Recently Browsing 0

  • No registered users viewing this page.

Account

Navigation

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.