Jack Posted March 9, 2014 Share Posted March 9, 2014 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. 1 Link to comment Share on other sites More sharing options...
Nicholas Posted March 9, 2014 Share Posted March 9, 2014 i thought it was closestNPCtoNAme("") well, i guess you can go both ways haha Link to comment Share on other sites More sharing options...
Pseudo Posted March 10, 2014 Share Posted March 10, 2014 Seems overcomplicated to me. 3 Link to comment Share on other sites More sharing options...
GoldenGates Posted March 10, 2014 Share Posted March 10, 2014 Isn't that a bit overkill? Also, throw in #isAnimating since #isUnderAttack is a bit unreliable for me while you're at it. 2 Link to comment Share on other sites More sharing options...
andzelmaz Posted March 12, 2014 Share Posted March 12, 2014 (edited) 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 March 13, 2014 by andzelmaz 1 Link to comment Share on other sites More sharing options...
Dreamliner Posted March 13, 2014 Share Posted March 13, 2014 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. 1 Link to comment Share on other sites More sharing options...
DeadCommon Posted March 13, 2014 Share Posted March 13, 2014 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; } } 2 Link to comment Share on other sites More sharing options...
Kenneh Posted April 6, 2014 Share Posted April 6, 2014 (edited) 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 April 6, 2014 by Kenneh Link to comment Share on other sites More sharing options...
paulrut24 Posted April 25, 2014 Share Posted April 25, 2014 Nah, i suck at java Link to comment Share on other sites More sharing options...
NotoriousPP Posted April 26, 2014 Share Posted April 26, 2014 (edited) 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 April 26, 2014 by NotoriousPP Link to comment Share on other sites More sharing options...
PolishCivil Posted April 29, 2014 Share Posted April 29, 2014 Um this will eat cpu. Link to comment Share on other sites More sharing options...
gearing Posted April 29, 2014 Share Posted April 29, 2014 can you make it somehow to reequip the firs 3items in inventory? so it could be used as suicide trainer at falador knights:) Link to comment Share on other sites More sharing options...