Jump to content

[Snippet] Get the Nearest Npc You can Attack


Jack

Recommended Posts

private NPC getBestNpcToAttack(ArrayList<String> ourNames){
		java.util.List<NPC> allNPCs= client.getLocalNPCs(); //all local npcs
		ArrayList<NPC> goodNPCs = new ArrayList<NPC>(); //all npcs with names we are looking for
		ArrayList<NPC> temp = new ArrayList<NPC>(); //A holder
		int[] currentBest = {-1,1000}; //Used in returning value
		
		//Find all npcs with names we are looking for
		for(int i = 0; i < allNPCs.size(); i++){
			if(ourNames.contains(allNPCs.get(i).getName())){
				temp.add(allNPCs.get(i));
			}
		}
		
		//Make sure they exist, are alive, and attackable
		for(int i = 0; i < temp.size(); i++){
			if((temp.get(i).exists())&&(temp.get(i).getHealth()>0)&&!temp.get(i).isUnderAttack()){
				goodNPCs.add(temp.get(i));
			}
		}
		
		if(goodNPCs.size()<1)
			return null; //No npcs you can fight
		else{
			//Find out which npc is closest
			for(int i = 0; i < goodNPCs.size(); i++){
				if(goodNPCs.get(i).getPosition().distance(myPlayer().getPosition())<currentBest[1]){
					currentBest[0] = i;
					currentBest[1] = goodNPCs.get(i).getPosition().distance(myPlayer().getPosition());
				}
			}
			if(currentBest[0]==-1) //Should never happen, just a check.
				return null;
			else{
				return goodNPCs.get(currentBest[0]); //returns the closest npc
			}
		}
	}

Usage:

NPC openNPC = getBestNpcToAttack("NPC_NAME_HERE");
openNPC.interact("Attack");

Please post if you can improve it. I just threw this together really fast and thought it would be a good recourse for people new to scripting that want to make a combat script.

  • Like 1
Link to comment
Share on other sites

That snippet works pretty well almost out of the box,

native closestAttackableNPCForName is a bit buggy it returns not closest npc but first found in the area and  npcs underattack.

 I ran your snippet on chickens and cows worked pretty flawlessly.

I have  added isInArea support and replaced isUnderAttack with canAttack also added getFacingId to be on safe side

 

 

Edited by andzelmaz
  • Like 1
Link to comment
Share on other sites

I've used similar in the past.  I'd suggest to add a check for the NPC with the highest HP - even though there's an NPC next to with with 1 hp, that's not the best choice if there's one 2 blocks away @ full hp

 

Also,the way you are iterating through the arraylist of local NPC's you will find a pattern it will attack by.  Such as if you're surrounded by NPC's it will always attack the east one or something.

 

Once you find an NPC that is closer than the previous, add it to a list.  If the next NPC is the same distance away, add it to the list, repeat.

 

Once you iterate through all of them, chose a random NPC from the list.

  • Like 1
Link to comment
Share on other sites

Sure I have five minutes.

@ScriptManifest(name = "Demo 3", info = "Demoooo", version = 1.0, author = "DeadCommon")
public class Demo3 extends Script {
	
	NPC[] attackable;
	
	@Override
	public int onLoop() throws InterruptedException {
		
		attackable = getAllAttackableNPC("Guard", "Goblin", "Cow", "Chicken");
		
		return 550;
	}
	
	@Override
	public void onPaint(Graphics arg0) {
		
		if (attackable != null) {
			boolean closest = true;
			for (NPC next : attackable)
				if (next != null) {
					
					arg0.setColor(closest ? Color.GREEN : Color.RED);
					
					arg0.drawPolygon(next.getPosition().getPolygon(bot));
					
					closest = false;
				}
		}
	}
	
	public NPC[] getAllAttackableNPC(String... arg0) {
		
		List<NPC> cache = client.getLocalNPCs();
		
		if (cache == null || cache.isEmpty())
			return null; // No NPCs found (whatsoever)
		
		final Player me = myPlayer();
		
		for (Iterator<NPC> i = cache.iterator(); i.hasNext(); ) {
			
			NPC next = i.next();

			if (next == null || !next.exists()
					|| !contains(arg0, next.getName())
					|| next.getHealth() == 0
					|| (next.getFacing() != null && !next.isFacing(me)))
				i.remove();
		}
		
		if (cache.isEmpty())
			return null; // No valid NPCs filtered		
		
		Collections.sort(cache, new Comparator<NPC>() {
			@Override
			public int compare(NPC o1, NPC o2) {
				return new Integer(o1.getPosition().distance(me.getPosition()))
						.compareTo(new Integer(o2.getPosition().distance(
								me.getPosition())));
			}
		});
		
		return cache.toArray(new NPC[cache.size()]);
	}
	
	public static boolean contains(String[] a, String b) {
		if (a == null || a.length == 0 || b == null || b.isEmpty())
			return false;
		else for (String next : a)
			if (next != null && !next.isEmpty() && next.equals(b))
				return true;
		return false;
	}
	
}
  • Like 2
Link to comment
Share on other sites

  • 4 weeks later...

Sure I have five minutes.

@ScriptManifest(name = "Demo 3", info = "Demoooo", version = 1.0, author = "DeadCommon")
public class Demo3 extends Script {
	
	NPC[] attackable;
	
	@Override
	public int onLoop() throws InterruptedException {
		
		attackable = getAllAttackableNPC("Guard", "Goblin", "Cow", "Chicken");
		
		return 550;
	}
	
	@Override
	public void onPaint(Graphics arg0) {
		
		if (attackable != null) {
			boolean closest = true;
			for (NPC next : attackable)
				if (next != null) {
					
					arg0.setColor(closest ? Color.GREEN : Color.RED);
					
					arg0.drawPolygon(next.getPosition().getPolygon(bot));
					
					closest = false;
				}
		}
	}
	
	public NPC[] getAllAttackableNPC(String... arg0) {
		
		List<NPC> cache = client.getLocalNPCs();
		
		if (cache == null || cache.isEmpty())
			return null; // No NPCs found (whatsoever)
		
		final Player me = myPlayer();
		
		for (Iterator<NPC> i = cache.iterator(); i.hasNext(); ) {
			
			NPC next = i.next();

			if (next == null || !next.exists()
					|| !contains(arg0, next.getName())
					|| next.getHealth() == 0
					|| (next.getFacing() != null && !next.isFacing(me)))
				i.remove();
		}
		
		if (cache.isEmpty())
			return null; // No valid NPCs filtered		
		
		Collections.sort(cache, new Comparator<NPC>() {
			@Override
			public int compare(NPC o1, NPC o2) {
				return new Integer(o1.getPosition().distance(me.getPosition()))
						.compareTo(new Integer(o2.getPosition().distance(
								me.getPosition())));
			}
		});
		
		return cache.toArray(new NPC[cache.size()]);
	}
	
	public static boolean contains(String[] a, String b) {
		if (a == null || a.length == 0 || b == null || b.isEmpty())
			return false;
		else for (String next : a)
			if (next != null && !next.isEmpty() && next.equals(b))
				return true;
		return false;
	}
	
}

 

Annnnd this is why osbot api is shit..

 

 

 

    public Npc[] attackableNpcs(String... names) {
        final List<Npc> npcList = new ArrayList<Npc>();
        final Player local = ctx.players.local();

        final Filter<Npc> npcFilter = new Filter<Npc>() {
            @Override
            public boolean accept(Npc npc) {
                return npc.animation() == -1 && !npc.inCombat() && !npc.interacting().valid()
                        && Arrays.asList(npc.actions()).contains("Attack");
            }
        };

        final Comparator<Npc> npcComparator = new Comparator<Npc>() {
            @Override
            public int compare(Npc o1, Npc o2) {
                return  (int) o1.tile().distanceTo(local) - (int) o2.tile().distanceTo(local);
            }
        };

        for(Npc npc : ctx.npcs.select().select(npcFilter).name(names).sort(npcComparator)) {
            npcList.add(npc);
        }

        return npcList.toArray(new Npc[npcList.size()]);
    }

 

looks so much better and neater.

Edited by Kenneh
Link to comment
Share on other sites

  • 3 weeks later...

 

Annnnd this is why osbot api is shit..

 

 

 

    public Npc[] attackableNpcs(String... names) {
        final List<Npc> npcList = new ArrayList<Npc>();
        final Player local = ctx.players.local();

        final Filter<Npc> npcFilter = new Filter<Npc>() {
            @Override
            public boolean accept(Npc npc) {
                return npc.animation() == -1 && !npc.inCombat() && !npc.interacting().valid()
                        && Arrays.asList(npc.actions()).contains("Attack");
            }
        };

        final Comparator<Npc> npcComparator = new Comparator<Npc>() {
            @Override
            public int compare(Npc o1, Npc o2) {
                return  (int) o1.tile().distanceTo(local) - (int) o2.tile().distanceTo(local);
            }
        };

        for(Npc npc : ctx.npcs.select().select(npcFilter).name(names).sort(npcComparator)) {
            npcList.add(npc);
        }

        return npcList.toArray(new Npc[npcList.size()]);
    }

 

looks so much better and neater.

 

Or just closestAttackableNPCListForName(String... names);  / closestAttackableNPCList(int... ids); ?

Edited by NotoriousPP
Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...