Skip 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.

Star Simple Construction [OPEN SOURCE!!!] [Supports multiple plank types & objects]

Featured Replies

o905qXV.png

Star Simple Construction

Welcome to the thread of my first (of hopefully many) scripts.

 

Features:

Spoiler

DONE | IN PROGRESS | NOT STARTED 

Furniture

  • crude chairs
  • wooden bookcase
  • oak larders
  • teak tables
  • mahogany tables

Plank supplying

  • butler
  • demon butler
  • Castle wars teleport -> House tabs

Nails

  • Bronze nails
  • Iron nails
  • Steel nails

Locations

  • Rimmington

Other features

  • Simple GUI
  • Paint 
  • Overall paint/GUI design

If you start in Castle Wars area the script will automatically withdraw all supplies.

Paint currently looks like this:

currentpaint.PNG.8eb06aec23af1d5a498c37c408126f2a.PNG

Ugly af, but does the job for now.

Current GUI look:

5970fd1bcaa0d_GUIsimple.PNG.141e3302a4952a432dcfd610bf9dec88.PNG

 

Download:
Only open source ATM

 

Open source <3:
I'm sorry if there's some rookie mistakes in here.

Spoiler

/* 
 * 
 * WRITEN BY RALLOSTAR @ osbot.org
 * https://osbot.org/forum/profile/266432-rallostar/
 * 
 * If you leech stuff pls credit <3
 * 
 * Hope you learn something from this. Will update it regularly on:
 * https://osbot.org/forum/topic/126293-star-simple-construction-open-source-supports-multiple-plank-types-objects/
 * 
 * FYI: this is my first script, if you think you can improve stuff or
 * give me tips please do. I would really appreciate it.
 * FYI2: the paint font/colors are fucked, will fix later 
 *
 */

import org.osbot.rs07.api.Dialogues;
import org.osbot.rs07.api.map.Area;
import org.osbot.rs07.api.map.Position;
import org.osbot.rs07.api.model.Entity;
import org.osbot.rs07.api.model.RS2Object;
import org.osbot.rs07.api.ui.EquipmentSlot;
import org.osbot.rs07.api.ui.RS2Widget;
import org.osbot.rs07.api.ui.Skill;
import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;
import org.osbot.rs07.utility.ConditionalSleep;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.TimeUnit;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.EmptyBorder;



@ScriptManifest(author = "rallostar", info = "Simple construction script.", name = "Star Construction", version = 0.1, logo = "http://i.imgur.com/o905qXV.png")
public class Main extends Script {

	
    private boolean isBuilding = false;
    private int minimumPlanks;
    private String plankType = "";
    private String objectType = "";
    private String objectTypeSpace = "";
    private int interfaceID = 458;
    private int interfaceChildID;
    private int buildSleep;
    private String status = "Starting bot"; 
    private int beginLevel;
    private int currentLevel;
    private Font runescape_chat_font; // Font used by paint
	private long startTime;	
	private final Image bg = getImage("http://i.imgur.com/o905qXV.png");
	private boolean showPaint = false;
	private boolean scriptStarted = false;
    starGUI g = new starGUI();

    private final Area castleWars = new Area(
    	    new int[][]{
    	        { 2433, 3098 },
    	        { 2433, 3078 },
    	        { 2452, 3078 },
    	        { 2452, 3098 }
    	    }
    	);
	private final Area rimmington = new Area(
		    new int[][]{
		            { 2950, 3227 },
		            { 2950, 3221 },
		            { 2959, 3221 },
		            { 2958, 3226 },
		            { 2958, 3228 }
		        }
		    );
	
	@Override
	public void onStart() {
    	startTime = System.currentTimeMillis();
    	getExperienceTracker().start(Skill.CONSTRUCTION);
    	beginLevel = getSkills().getStatic(Skill.CONSTRUCTION);
        g.setVisible(true);
    	g.setTitle("Star Construction");

	}

	  private Image getImage(String url)
	  {
	    try
	    {
	      return ImageIO.read(new URL(url));
	    }
	    catch (IOException e) {}
	    return null;
	  }

	private enum State {
		BUILD, REMOVE, BANK, WAIT, ENTER_HOUSE, SETUP
	};

	private State getState() {
    	if(!scriptStarted) {
    		return State.SETUP;
    	}
		if(!hasRequiredItems()) // If you don't have a hammer/saw/nails and planks it will bank.
    	{    		
    		isBuilding = false;
    		return State.BANK;   		
    	}	
    	if(rimmington.contains(myPlayer())) {
    		return State.ENTER_HOUSE;
    	}
		final Entity objectToBuildSpace = objects.closest(objectTypeSpace);
		if (objectToBuildSpace != null) {
			return State.BUILD;
		}
		final Entity objectToBuild = objects.closest(objectType);
		if (objectToBuild != null) {
			return State.REMOVE;
		}
		return State.WAIT;
	}
	
    private boolean hasRequiredItems() {
    	if(inventory.getAmount(plankType) < minimumPlanks || !inventory.contains("Hammer") || !inventory.contains("Saw") || inventory.getAmount("Steel nails") <= 100)
    	{
    	return false;
    	}
		return true;
	}
	
	@Override
	public int onLoop() throws InterruptedException {
		switch (getState()) {
		case SETUP:
			
		break;
		case ENTER_HOUSE:
			if(rimmington.contains(myPlayer())) {
				Entity portal = objects.closest("Portal");
				status = "Entering POH (build mode)";
				portal.interact("Build mode");
				new ConditionalSleep(10000) {
					@Override
					public boolean condition() throws InterruptedException {
						return !rimmington.contains(myPlayer());
					}
				}.sleep();
			}
			break;
		case BANK:
			if (castleWars.contains(myPlayer()))
			{
				status = "chilling in cw area";
				if(!getBank().isOpen())
				{
					status = "Opening bank";
					getBank().open();
					new ConditionalSleep(10000) {
						@Override
						public boolean condition() throws InterruptedException {
							return bank.isOpen();
						}
					}.sleep();
				}
				else
				{
					if(!inventory.contains("Hammer")) {
						status = "Withdrawing hammer";
						getBank().withdraw("Hammer", 1);
						new ConditionalSleep(10000) {
							@Override
							public boolean condition() throws InterruptedException {
								return inventory.contains("Hammer");
							}
						}.sleep();
					}
					if(!inventory.contains("Teleport to house")) {
						status = "Withdrawing teleport tabs";
						getBank().withdrawAll("Teleport to house");
						new ConditionalSleep(10000) {
							@Override
							public boolean condition() throws InterruptedException {
								return inventory.contains("Teleport to house");
							}
						}.sleep();
					}
					if(!inventory.contains("Saw")) {
						status = "Withdrawing saw";
						getBank().withdraw("Saw", 1);
						new ConditionalSleep(10000) {
							@Override
							public boolean condition() throws InterruptedException {
								return inventory.contains("Saw");
							}
						}.sleep();
					}
					if(inventory.getAmount("Steel nails") < 100) {
						status = "Withdrawing nails";
						getBank().withdrawAll("Steel nails");
						new ConditionalSleep(10000) {
							@Override
							public boolean condition() throws InterruptedException {
								return inventory.contains("Saw");
							}
						}.sleep();
					}
					if (!equipment.isWearingItemThatContains(EquipmentSlot.RING, "Ring of dueling")) {
						status = "Withdrawing ring of dueling";
						//getBank().withdraw("Ring of dueling(8)", 1);
						getBank().withdraw(duelring -> duelring.getName().contains("Ring of dueling"), 1);
						
						new ConditionalSleep(10000) {
							@SuppressWarnings("unchecked")
							@Override
							public boolean condition() throws InterruptedException {
								return inventory.contains(duelring -> duelring.getName().contains("Ring of dueling"));
							}
						}.sleep();
						getBank().close();
						sleep(random(500,700));
						equipment.equipForNameThatContains(EquipmentSlot.RING, "Ring of dueling");
						new ConditionalSleep(10000) {
							@Override
							public boolean condition() throws InterruptedException {
								return getEquipment().isWearingItem(EquipmentSlot.RING);
							}
						}.sleep(); 
						status = "Opening bank";
						getBank().open();
						new ConditionalSleep(10000) {
							@Override
							public boolean condition() throws InterruptedException {
								return bank.isOpen();
							}
						}.sleep();
						
					}
					status = "Withdrawing " + plankType;
					getBank().withdrawAll(plankType);
					new ConditionalSleep(10000) {
						@Override
						public boolean condition() throws InterruptedException {
							if(!getBank().contains(plankType) && inventory.getAmount(plankType) < minimumPlanks) {
								logoutTab.logOut();
								stop();
							}
							return inventory.getAmount(plankType) >= minimumPlanks;
						}
					}.sleep();
					getBank().close();
					status = "Teleporting to Rimmington.";
					inventory.getItem("Teleport to house").interact("Break");
				}	
			}
			else
			{
				status = "Teleporting to Castle Wars...";
				equipment.interact(EquipmentSlot.RING, "Castle wars");
				sleep(random(3000,3500)); //couldnt get the condsleep to work properly
				/*new ConditionalSleep(random(2000,4000)) {
					@Override
					public boolean condition() throws InterruptedException {
						return castleWars.contains(myPlayer());
					}
				}.sleep();	*/			
				Entity cwbank = objects.closest("Bank chest");
				cwbank.interact("Use");
				}	
			
			break;
		case BUILD:
			final Entity objectToBuildSpace = objects.closest(objectTypeSpace);
			if (objectToBuildSpace != null) {
				objectToBuildSpace.interact("Build");
				sleep(random(500,700));			
			}
			RS2Widget buildInterface = getWidgets().get(interfaceID, interfaceChildID);
	        if (buildInterface != null){
	            buildInterface.interact("Build");
	            status = "Building " + objectType;
	            sleep(buildSleep); //couldnt get the condsleep to work properly
	        }
			break;
			
		case REMOVE:
			Entity objectToBuild = objects.closest(objectType);
			if(objectToBuild != null) {
				objectToBuild.interact("Remove");
				status = "Removing " + objectType;
				sleep(random(500,700));
				new ConditionalSleep(10000) {
					@Override
					public boolean condition() throws InterruptedException {
						return dialogues.inDialogue();
					}
				}.sleep(); 		        
				dialogues.selectOption(1);
				new ConditionalSleep(10000) {
					@Override
					public boolean condition() throws InterruptedException {
						return !dialogues.inDialogue();
					}
				}.sleep();
			}
			break;
			
		case WAIT:
			sleep(random(500, 700));
			break;
		}
		return random(200, 300);
	}


	@Override
	public void onExit() {
		log("Script stopped..");
        g.dispose();	    
	}
	
 
    @Override
    public void onPaint(Graphics2D g) {
    	if (showPaint) {
    	final long runTime = System.currentTimeMillis() - startTime;
    	currentLevel = getSkills().getStatic(Skill.CONSTRUCTION);
    	long xpGained = getExperienceTracker().getGainedXP(Skill.CONSTRUCTION);
    	long xpPerHour = getExperienceTracker().getGainedXPPerHour(Skill.CONSTRUCTION);
    	long timeToLevel = getExperienceTracker().getTimeToLevel(Skill.CONSTRUCTION);
    	int levelsGained = currentLevel - beginLevel;

    	g.setFont(runescape_chat_font);
    	//g.drawImage(bg, 1, 100, null);

    	g.drawString("Runtime: " + formatTime(runTime), 10, 35);
    	g.drawString("Construction level: " + currentLevel + " (+" + levelsGained + ")", 10, 50);
    	g.drawString("Exp gained: " + xpGained + " (" + xpPerHour + " per hour)" , 10, 65);
    	g.drawString("TTL: " + formatTime(timeToLevel), 10, 80);
    	g.drawString("Status: " + status, 10, 95);

    	//mouse
    	Point mP = getMouse().getPosition();
    	g.drawLine(mP.x, 0, mP.x, 500);
    	g.drawLine(0, mP.y, 800, mP.y);
    	}
    }

    
    public final double percentToNextLevel(final Skill skill){

        int curLvl = getSkills().getStatic(skill),
        curXP = getSkills().getExperience(skill),
        xpCurLvl = getSkills().getExperienceForLevel(curLvl),
        xpNextLvl = getSkills().getExperienceForLevel(curLvl + 1);

        return (((curXP - xpCurLvl) * 100) / (xpNextLvl - xpCurLvl));
    }
    
    public final String formatTime(final long ms){
        long s = ms / 1000, m = s / 60, h = m / 60, d = h / 24;
        s %= 60; m %= 60; h %= 24;

        return d > 0 ? String.format("%02d:%02d:%02d:%02d", d, h, m, s) :
               h > 0 ? String.format("%02d:%02d:%02d", h, m, s) :
               String.format("%02d:%02d", m, s);
    }
    
    public final String formatValue(final long l) {
        return (l > 1_000_000) ? String.format("%.2fm", ((double) l / 1_000_000))
               : (l > 1000) ? String.format("%.1fk", ((double) l / 1000)) 
               : l + "";
    }


    class starGUI extends JFrame {
    	private JLabel titleLabel;
        private JButton start;
        private JComboBox selectPlankType;
        private JComboBox selectObject;
        private JLabel selectPlankTypeLabel;
        private JLabel selectObjectLabel;
        private JCheckBox checkbox = new JCheckBox("Use demon butler");

        
        public starGUI() {
            initComponents();
        }

        private void startScript(ActionEvent e) {
        	plankType = selectPlankType.getSelectedItem().toString();
        	objectType = selectObject.getSelectedItem().toString();
        	if(objectType == "Larder") {
        		minimumPlanks = 8;
            	objectTypeSpace = "Larder space";
            	interfaceChildID = 5;
            	buildSleep = random(900,1400);
        	}else if (objectType == "Chair") {
        		minimumPlanks = 2;
            	objectTypeSpace = "Chair space";
            	interfaceChildID = 4;
            	buildSleep = random(2500,4000);
        	}else if (objectType == "Bookcase") {
        		minimumPlanks = 4;
            	objectTypeSpace = "Bookcase space";
            	interfaceChildID = 4;
            	buildSleep = random(5500,8000);
        	}
        	showPaint = true;
        	scriptStarted = true;
            dispose();
        }

        private void initComponents() {

        	titleLabel = new JLabel();
        	
            start = new JButton();
            String[] plankTypes = { "Plank", "Oak plank"};
            String[] objectTypes = { "Chair", "Bookcase", "Larder"};
            selectPlankTypeLabel = new JLabel();
            selectObjectLabel = new JLabel();
            selectPlankType = new JComboBox(plankTypes);
            selectObject = new JComboBox(objectTypes);

            Container contentPane = getContentPane();
            contentPane.setLayout(null);

            //labels
            titleLabel.setText("Welcome to Star Construction");
            contentPane.add(titleLabel);
            titleLabel.setBounds(new Rectangle(new Point(80, 15), titleLabel.getPreferredSize()));

            selectPlankTypeLabel.setText("Plank type: ");
            selectObjectLabel.setText("Select object: ");
            contentPane.add(selectPlankTypeLabel);
            contentPane.add(selectObjectLabel);
            selectPlankTypeLabel.setBounds(new Rectangle(new Point(40, 55), titleLabel.getPreferredSize()));
            selectObjectLabel.setBounds(new Rectangle(new Point(40, 90), titleLabel.getPreferredSize()));
            
            selectPlankType.setSelectedIndex(0);
            contentPane.add(selectPlankType);
            selectPlankType.setBounds(new Rectangle(new Point(120, 55), selectPlankType.getPreferredSize()));
            
            selectObject.setSelectedIndex(0);
            contentPane.add(selectObject);
            selectObject.setBounds(new Rectangle(new Point(120, 90), selectObject.getPreferredSize()));

            contentPane.add(checkbox);
            checkbox.setBounds(new Rectangle(new Point(40, 125), checkbox.getPreferredSize()));

            
            start.setText("Start bot");
            start.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    startScript(e);
                }
            });
            contentPane.add(start);
            start.setBounds(100, 175, 110, start.getPreferredSize().height);

            contentPane.setPreferredSize(new Dimension(310, 200));
            pack();
            setLocationRelativeTo(getOwner());
        }

    }

}

 

 

Edited by rallostar

OoooOo I would love for it to be open source. I could learn a thing or two about scripting. Please do! :) 

Nice, gl on your script :D

Open source is also nice ;)

  • Author
6 minutes ago, Sofakin said:

OoooOo I would love for it to be open source. I could learn a thing or two about scripting. Please do! :) 

 

4 minutes ago, Myte said:

Would be awesome if it's open source.

Okay guys! Will update source once I wrap up the GUI. Will update regularly :)

Open source would be nice to look at :)

 

is it onLoop, task or state?

Edited by vaynex

  • Author
29 minutes ago, vaynex said:

Open source would be nice to look at :)

 

is it onLoop, task or state?

States :)

Only had a quick look - Not bad for your first script :) 

Some things I have spotted though are your logic flow seems to be off and it appears you're relying on things executing correctly, as well as objects existing, for the script to function. Just a quick example is:

		else
			{
				status = "Teleporting to Castle Wars...";
				equipment.interact(EquipmentSlot.RING, "Castle wars");
				sleep(random(3000,3500)); //couldnt get the condsleep to work properly
				/*new ConditionalSleep(random(2000,4000)) {
					@Override
					public boolean condition() throws InterruptedException {
						return castleWars.contains(myPlayer());
					}
				}.sleep();	*/			
				Entity cwbank = objects.closest("Bank chest");
				cwbank.interact("Use");
				}	
			

What if we don't have a ring of dueling equipped or the interaction event isn't successful? The Bank chest will then no longer exist. Etc. :P 

Edited by HeyImJamie

  • Author
3 hours ago, HeyImJamie said:

Only had a quick look - Not bad for your first script :) 

Some things I have spotted though are your logic flow seems to be off and it appears you're relying on things executing correctly, as well as objects existing, for the script to function. Just a quick example is:


		else
			{
				status = "Teleporting to Castle Wars...";
				equipment.interact(EquipmentSlot.RING, "Castle wars");
				sleep(random(3000,3500)); //couldnt get the condsleep to work properly
				/*new ConditionalSleep(random(2000,4000)) {
					@Override
					public boolean condition() throws InterruptedException {
						return castleWars.contains(myPlayer());
					}
				}.sleep();	*/			
				Entity cwbank = objects.closest("Bank chest");
				cwbank.interact("Use");
				}	
			

What if we don't have a ring of dueling equipped or the interaction event isn't successful? The Bank chest will then no longer exist. Etc. :P 

Well it actually wouldnt exist cuz it didnt teleport right? :p

1 hour ago, rallostar said:

Well it actually wouldnt exist cuz it didnt teleport right? :p

You're not if checking that your teleport method executed so it would assume it has and then NPE as the chest doesn't exist. :P 

  • Author
8 hours ago, HeyImJamie said:

You're not if checking that your teleport method executed so it would assume it has and then NPE as the chest doesn't exist. :P 

Ah I see. How would you check that?

46 minutes ago, rallostar said:

Ah I see. How would you check that?

Check if cwbank is not null, and before interacting with ring check if there is a ring equiped, as for the conditionalsleep, do 2 sleeps, first is sleep untill animating and 2nd is sleep untill cwbank has ur player and u are not animating

if cwbank contains my player
  if bank is not open
  	open
  else
  	handle it
else
  if u have ring equpied
  	if u sucessfully interact
  		condsleep untill is animating
  		cond sleep untill cwbank contains my player and u are not interacting
  

and etc

Edited by progamerz

  • Author
12 minutes ago, progamerz said:

Check if cwbank is not null, and before interacting with ring check if there is a ring equiped, as for the conditionalsleep, do 2 sleeps, first is sleep untill animating and 2nd is sleep untill cwbank has ur player and u are not animating


if cwbank contains my player
  if bank is not open
  	open
  else
  	handle it
else
  if u have ring equpied
  	if u sucessfully interact
  		condsleep untill is animating
  		cond sleep untill cwbank contains my player and u are not interacting
  

and etc

Thanks man will try that :)

  • 2 weeks later...
  • Author

Sorry guys lost interested. Not going to update but feel free to use this for anything :)

  • 1 month later...
On 2017-08-02 at 5:54 PM, rallostar said:

Sorry guys lost interested. Not going to update but feel free to use this for anything :)

:( looked good

Recently Browsing 0

  • No registered users viewing this page.

Account

Navigation

Search

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.