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

Is there a way to determine if player is facing object?

Featured Replies

Coming back from a long break, I'm sure there was a function a long time ago to determine if character is facing an object? 
I've looked all over the API and I can't find it.

Context:

I have code to check if my player is animating and a rock exists then to sleep.

If my player is animating and the rock its mining is mined by someone else, my player is still animating and if there is a nearby rock it still exists, so it continues sleeping.

I remember using a check a long time ago that if the rock I'm facing exists then to sleep.

Any help would be appreciated.

@purplechalk why don't you just store the rock object you interact with as a global variable, and check if that exists, rather than any rock?

Edited by Explv

Here's code that we wrote years ago to do this, not the best looking code but it might help you!

protected RS2Object getFacingRock() {
        if (script.myPlayer().getAnimation() == -1)
            return null;
        int orientation = script.myPlayer().getRotation();
        if (Math.abs(orientation - 1536) < 50) {
            Position rockP = new Position(script.myPlayer().getX() + 1, script
                    .myPlayer().getY(), script.myPlayer().getZ());
            return getRockAt(rockP);
        } else if (Math.abs(orientation - 1024) < 50) {
            Position rockP = new Position(script.myPlayer().getX(), script
                    .myPlayer().getY() + 1, script.myPlayer().getZ());
            return getRockAt(rockP);
        } else if (Math.abs(orientation - 512) < 50) {
            Position rockP = new Position(script.myPlayer().getX() - 1, script
                    .myPlayer().getY(), script.myPlayer().getZ());
            return getRockAt(rockP);
        } else if (orientation < 25 || orientation > 1800) {
            Position rockP = new Position(script.myPlayer().getX(), script
                    .myPlayer().getY() - 1, script.myPlayer().getZ());
            return getRockAt(rockP);
        }
        return null;
   }

protected RS2Object getRockAt(Position p) {
        return script.objects.closest(new Filter<RS2Object>() {
            @Override
            public boolean match(RS2Object rs2Object) {
                return rs2Object.getName().equals("Rocks") && rs2Object.getX() == p.getX()
                        && rs2Object.getY() == p.getY();
            }
        });
   }
  • Author
30 minutes ago, Explv said:

@purplechalk why don't you just store the rock object you interact with as a global variable, and check if that exists, rather than any rock?

How would I store that? By using the position of the rock?

I'm currently using closest object that matches my rock ID.
 

private RS2Object getMiningRocks(){

    RS2Object miningSpot = getObjects().closest(ORE_IDS);
    if (miningSpot != null){
        if(miningSpot.hasAction("Mine")){
            return miningSpot;
        }
    }
    return null;
}

 

if (miningSpot.isVisible() && miningSpot.interact("Mine")) {
    status = "Clicking Rock";
    new ConditionalSleep(5000) {
        @Override
        public boolean condition() {
            return myPlayer().isAnimating() || !miningSpot.exists();
        }
    }.sleep();

}

With this code, if someone mines the rock before me, the mining spot will still exist if there is another rock close there for not breaking the sleep.

I've been using your guide, its very helpful :)

1 minute ago, Eliot said:

Here's code that we wrote years ago to do this, not the best looking code but it might help you!


protected RS2Object getFacingRock() {
        if (script.myPlayer().getAnimation() == -1)
            return null;
        int orientation = script.myPlayer().getRotation();
        if (Math.abs(orientation - 1536) < 50) {
            Position rockP = new Position(script.myPlayer().getX() + 1, script
                    .myPlayer().getY(), script.myPlayer().getZ());
            return getRockAt(rockP);
        } else if (Math.abs(orientation - 1024) < 50) {
            Position rockP = new Position(script.myPlayer().getX(), script
                    .myPlayer().getY() + 1, script.myPlayer().getZ());
            return getRockAt(rockP);
        } else if (Math.abs(orientation - 512) < 50) {
            Position rockP = new Position(script.myPlayer().getX() - 1, script
                    .myPlayer().getY(), script.myPlayer().getZ());
            return getRockAt(rockP);
        } else if (orientation < 25 || orientation > 1800) {
            Position rockP = new Position(script.myPlayer().getX(), script
                    .myPlayer().getY() - 1, script.myPlayer().getZ());
            return getRockAt(rockP);
        }
        return null;
   }

protected RS2Object getRockAt(Position p) {
        return script.objects.closest(new Filter<RS2Object>() {
            @Override
            public boolean match(RS2Object rs2Object) {
                return rs2Object.getName().equals("Rocks") && rs2Object.getX() == p.getX()
                        && rs2Object.getY() == p.getY();
            }
        });
   }

Thanks I'll take a look into this, I'm sure there is an easy way of achieving what I need to, but I'm learning everything again as it's been a while.

10 minutes ago, purplechalk said:

How would I store that? By using the position of the rock?

I'm currently using closest object that matches my rock ID.
 


private RS2Object getMiningRocks(){

    RS2Object miningSpot = getObjects().closest(ORE_IDS);
    if (miningSpot != null){
        if(miningSpot.hasAction("Mine")){
            return miningSpot;
        }
    }
    return null;
}

 


if (miningSpot.isVisible() && miningSpot.interact("Mine")) {
    status = "Clicking Rock";
    new ConditionalSleep(5000) {
        @Override
        public boolean condition() {
            return myPlayer().isAnimating() || !miningSpot.exists();
        }
    }.sleep();

}

With this code, if someone mines the rock before me, the mining spot will still exist if there is another rock close there for not breaking the sleep.

I've been using your guide, its very helpful :)

Thanks I'll take a look into this, I'm sure there is an easy way of achieving what I need to, but I'm learning everything again as it's been a while.

You could use some basic trig to figure out what you're facing.

My first idea would be to normalize the rotation and then convert to radians, then feed that into polar coordinates with r = 1.5, then convert back into cartesian coordinates. As an added benefit, this function can be modified to check for positions further away than right next to you by just increasing r.

  • Author
3 hours ago, Zapako said:

You could use some basic trig to figure out what you're facing.

My first idea would be to normalize the rotation and then convert to radians, then feed that into polar coordinates with r = 1.5, then convert back into cartesian coordinates. As an added benefit, this function can be modified to check for positions further away than right next to you by just increasing r.

I'm not that experienced yet, still trying to work out how to do this guys, any help greatly appreciated it, I'm sure its easy for someone with experience I just need a little guidance.

Hey purplechalk,

I had some time to look into this. Funny thing, I thought this was in the API too. Here's what I came up with:
 

private static Position[] getSweepCorners(Position from, Entity o) {
    int offsetX = o.getSizeX() - 1;
    int offsetY = o.getSizeY() - 1;
    Position objPos = o.getPosition();

    if (offsetX == 0 && offsetY == 0) {
        return new Position[] {
            objPos, objPos
        };
    }

    int relativeX = from.getX() - o.getX();
    int relativeY = from.getY() - o.getY();
    boolean isOutOfBoundsX = relativeX < 0 || relativeX > offsetX - 1;
    boolean isOutOfBoundsY = relativeY < 0 || relativeY > offsetY - 1;

    int signX = Integer.signum(relativeX);
    int signY = Integer.signum(relativeY);

    if (isOutOfBoundsX && isOutOfBoundsY) {
        boolean sameSign = signX == signY;
        return new Position[] {
                objPos.translate(sameSign ? offsetX : 0, 0),
                objPos.translate(sameSign ? 0 : offsetX, offsetY)
        };
    }

    if (isOutOfBoundsX) {
        int staticX = signX < 0 ? 0 : offsetX;
        return new Position[] {
                objPos.translate(staticX, 0),
                objPos.translate(staticX, offsetY)
        };
    }

    int staticY = signY < 0 ? 0 : offsetY;
    return new Position[] {
            objPos.translate(0, staticY),
            objPos.translate(offsetX, staticY)
    };
}

private static double getAngleToPosition(Position from, Position to) {
    double distX = from.getX() - to.getX();
    double distY = from.getY() - to.getY();

    // -pi, pi
    double angleRadians = Math.atan2(distX, distY);

    // 0, 2pi
    final double TWO_PI = 2 * Math.PI;
    angleRadians = (angleRadians + TWO_PI) % TWO_PI;

    // 0, 2048
    final int HALF_ROTATION_GAME_ANGLE = 1024;
    final double RADIANS_TO_GAME_ANGLE = HALF_ROTATION_GAME_ANGLE / Math.PI;
    return angleRadians *  RADIANS_TO_GAME_ANGLE;
}

public boolean isFacingObject(Entity o) {
    Position ourPosition = myPosition();
    Position[] sweepCorners = getSweepCorners(ourPosition, o);

    double sweepAngle1 = getAngleToPosition(ourPosition, sweepCorners[0]);
    double sweepAngle2 = getAngleToPosition(ourPosition, sweepCorners[1]);

    final int FULL_ROTATION = 2048;
    long minTemp = (Math.round(Math.min(sweepAngle1, sweepAngle2)) - 1) % FULL_ROTATION;
    long maxTemp = (Math.round(Math.max(sweepAngle1, sweepAngle2)) + 1) % FULL_ROTATION;

    long minAngle = Math.min(minTemp, maxTemp);
    long maxAngle = Math.max(minTemp, maxTemp);

    int ourAngle = myPlayer().getRotation();

    if (maxAngle - minAngle <= FULL_ROTATION / 2) {
        return ourAngle >= minAngle && ourAngle <= maxAngle;
    }

    return (ourAngle >= 0 && ourAngle <= minAngle) ||
            (ourAngle >= maxAngle && ourAngle <= FULL_ROTATION);
}


You would then use "isFacingObject(Entity)" which returns true if your character is rotated towards the given Entity object. It should also work for Entity objects that span more than one tile, e.g., trees.

The code is chunky, but the calculations are not complex. I'm sure someone else can trim this down a bit (or contribute a cleaner alternative!). I don't think comments would help visualize the calculations, so if you'd like, I could make some sketches to show how it works.

Best,

randomjoe

Edited by randomjoe

On 6/21/2017 at 7:05 PM, Eliot said:

Here's code that we wrote years ago to do this, not the best looking code but it might help you!


protected RS2Object getFacingRock() {
        if (script.myPlayer().getAnimation() == -1)
            return null;
        int orientation = script.myPlayer().getRotation();
        if (Math.abs(orientation - 1536) < 50) {
            Position rockP = new Position(script.myPlayer().getX() + 1, script
                    .myPlayer().getY(), script.myPlayer().getZ());
            return getRockAt(rockP);
        } else if (Math.abs(orientation - 1024) < 50) {
            Position rockP = new Position(script.myPlayer().getX(), script
                    .myPlayer().getY() + 1, script.myPlayer().getZ());
            return getRockAt(rockP);
        } else if (Math.abs(orientation - 512) < 50) {
            Position rockP = new Position(script.myPlayer().getX() - 1, script
                    .myPlayer().getY(), script.myPlayer().getZ());
            return getRockAt(rockP);
        } else if (orientation < 25 || orientation > 1800) {
            Position rockP = new Position(script.myPlayer().getX(), script
                    .myPlayer().getY() - 1, script.myPlayer().getZ());
            return getRockAt(rockP);
        }
        return null;
   }

protected RS2Object getRockAt(Position p) {
        return script.objects.closest(new Filter<RS2Object>() {
            @Override
            public boolean match(RS2Object rs2Object) {
                return rs2Object.getName().equals("Rocks") && rs2Object.getX() == p.getX()
                        && rs2Object.getY() == p.getY();
            }
        });
   }

Off topic, but I was wondering why you use "script.myPlayer()" etc. instead of just "myPlayer()".

Recently Browsing 0

  • No registered users viewing this page.

Account

Navigation

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.