Jack Posted March 9, 2014 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
Nicholas Posted March 9, 2014 Posted March 9, 2014 i thought it was closestNPCtoNAme("") well, i guess you can go both ways haha
GoldenGates Posted March 10, 2014 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
andzelmaz Posted March 12, 2014 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
Dreamliner Posted March 13, 2014 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
DeadCommon Posted March 13, 2014 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
Kenneh Posted April 6, 2014 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
NotoriousPP Posted April 26, 2014 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
gearing Posted April 29, 2014 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:)