Jump to content

GroundItem Monitor | Detect New Ground Items


LoudPacks

Recommended Posts

Don't know if anyone will use but I needed something with this functionality and came up with this. Any feedback is appreciated, I'm always trying to learn new things.

 

c09d227f82ce2a2b643bb610dc8d087b.gif

 

GroundMonitor.java:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.osbot.rs07.api.model.GroundItem;
import org.osbot.rs07.script.Script;


public abstract class GroundMonitor {
//My implementation filters out items less than price x, but I removed because it was specific to my needs
	private ArrayList<GroundItem> cache = new ArrayList<GroundItem>();
	private Script ctx;

	public GroundMonitorRelease(Script ctx, int valueThreshold) {
		updateContext(ctx);
		update();
	}

	public void updateContext(Script ctx) {
		this.ctx = ctx;
	}

	public abstract void onChange();

	public boolean hasChanged() {
		return getChanges().length > 0;
	}

	public void update() {
		for (GroundItem item : ctx.getGroundItems().getAll()) {
			if (item != null) {
				cache.add(item);
			}
		}
	}

	public GroundItem[] getChanges() {
		List<GroundItem> items = new ArrayList<GroundItem>();
		ArrayList<GroundItem> ci = new ArrayList<GroundItem>();
		int changes = 0;
		for(GroundItem q : ctx.getGroundItems().getAll()){
			if(q != null){
			items.add(q);
			}
		}
		
		for (GroundItem item : items) {
			if (item != null) {
				int id = item.getId();
                if (!contains(ci, id) && !cached(item)) {
                    ci.add(item);
        			changes++;
                }
			}
		}
	
		Collections.sort(ci, new Comparator<GroundItem>(){
			@Override
			public int compare(GroundItem o1, GroundItem o2) {
				 int d0 = CheckPrice.get(o1.getId()); //Use distance instead of price
				 int d1 = CheckPrice.get(o2.getId()); //Use distance instead of price
				   return (d0 < d1 ? -1 :             //It will return the closer one first
		               (d0 == d1 ? 0 : 1));
			}
			
		});
		
		return Arrays.copyOf(ci.toArray(new GroundItem[ci.size()]), changes);
	}
	
	private boolean cached(GroundItem item){
		return cache.contains(item);
	}

	private boolean contains(ArrayList<GroundItem> list, int id) {
		for (GroundItem i : list) {
			if (i == null)
				continue;
			if (i.getId() == id) {
				return true;
			}
		}
		return false;
	}
	
}

Main.java (onStart):

groundMonitor = new GroundMonitor(getScript()) {
				@Override
				public void onChange() {
					for (GroundItem i : getChanges()) {
						if(i != null){
						log(i.getName() + " : " + CheckPrice.get(i.getId()));
						}
					}

				}
			};

Main.java (onPaint):

if (groundMonitor != null && groundMonitor.hasChanged()) {
			groundMonitor.onChange();
			groundMonitor.update();
		}
Edited by LoudPacks
  • Like 4
Link to comment
Share on other sites

Looks good, you might want to consider using a proper thread instead of the paint thread though. As far as I know the paint thread is executed like 60 times a second, so that's literally every ~16 ms which is not really necessary. If you want to go with the optimisations to the maximum then you can detect the changes every tick instead since we have the possibilities to do so with the current API which would be about 40 times more efficient CPU wise. 

 

VSuShjF.gif

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

Dank EDT errors u have there doge.png

what

Looks good, you might want to consider using a proper thread instead of the paint thread though. As far as I know the paint thread is executed like 60 times a second, so that's literally every ~16 ms which is not really necessary. If you want to go with the optimisations to the maximum then you can detect the changes every tick instead since we have the possibilities to do so with the current API which would be about 40 times more efficient CPU wise. 

 

VSuShjF.gif

 

Will something like this suffice?

 monitorThread = new Thread(){
			    public void run() {
			    	inventoryMonitor = new InventoryMonitor(getScript()) {
						@Override
						public void onChange() {
							for (Item i : getChanges()) {
								if(i != null){
								lootCount += i.getAmount();
								lootValue += CheckPrice.get(i.getId());
								}
							}

						}
					};
					
					groundMonitor = new GroundMonitor(getScript(), Settings.lootThresh, Settings.zoneArea) {
						@Override
						public void onChange() {
							for (org.osbot.rs07.api.model.GroundItem i : getChanges()) {
								if(i != null){
								log(i.getName() + " : " + CheckPrice.get(i.getId()));
								}
							}

						}
					};
			    
			    while(!monitorThread.isInterrupted()){
			    	if (inventoryMonitor != null && !getBank().isOpen() && inventoryMonitor.hasChanged()) {
						inventoryMonitor.onChange();
						inventoryMonitor.update();
					}
					
					if (groundMonitor != null && !getBank().isOpen() && groundMonitor.hasChanged()) {
						groundMonitor.onChange();
						groundMonitor.update();
					}
			    }
			    }
			    
				};
				monitorThread.start();
Edited by LoudPacks
Link to comment
Share on other sites

what

 

Will something like this suffice?

 monitorThread = new Thread(){
			    public void run() {
			    	inventoryMonitor = new InventoryMonitor(getScript()) {
						@Override
						public void onChange() {
							for (Item i : getChanges()) {
								if(i != null){
								lootCount += i.getAmount();
								lootValue += CheckPrice.get(i.getId());
								}
							}

						}
					};
					
					groundMonitor = new GroundMonitor(getScript(), Settings.lootThresh, Settings.zoneArea) {
						@Override
						public void onChange() {
							for (org.osbot.rs07.api.model.GroundItem i : getChanges()) {
								if(i != null){
								log(i.getName() + " : " + CheckPrice.get(i.getId()));
								}
							}

						}
					};
			    
			    while(!monitorThread.isInterrupted()){
			    	if (inventoryMonitor != null && !getBank().isOpen() && inventoryMonitor.hasChanged()) {
						inventoryMonitor.onChange();
						inventoryMonitor.update();
					}
					
					if (groundMonitor != null && !getBank().isOpen() && groundMonitor.hasChanged()) {
						groundMonitor.onChange();
						groundMonitor.update();
					}
			    }
			    }
			    
				};
				monitorThread.start();

That should freeze your client because it has no sleeps so the new thread will attempt to use the whole CPU execution cap.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

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