Help with player dancing ( spinning when following each other)

Dec 9, 2013
136
0
0
So in osrs and rs3 there is a bug if you want to call it that... where if you follow someone and they follow you back you start to spin... (everyone should already know that...) I've been trying to replicate it for awhile now (not that its important just something to pass some time with i guess) and I can't figure out the formula or whatever... either they just face each other or they run around endlessly and clip into objects and stuff... I looked up some tutorials but couldn't find really anything that was too helpful... any help would be greatly appreciated... thanks!
 
Following is just walking to the target's previous tile. The previous tile is either the last tile they stepped on; which is a single step even if the target is running (which is 2 steps), or west of the targets current tile if they have just logged in/teleported.

The important part is to set the previousTile at the start (or the end) of the tick not when they actually move; this creates the one tick delay between a player moving and the follower moving which allows the circular dance to occur. Clipping should be checked when the path is made and when the player takes a step so isn't really related to following itself.
 
Hey thanks for the reply, forgive if I sound stupid but I'm not sure i fully understand what you're talking about... could you show me a code example? if that wouldn't be too much to ask?
 
Hey thanks for the reply, forgive if I sound stupid but I'm not sure i fully understand what you're talking about... could you show me a code example? if that wouldn't be too much to ask?

I don't know what source you're using, so I won't be able to help specifically, but maybe I can help point you in the right direction as well as providing you with generic code examples. RuneScape, as well as it's private server counterparts, uses a tick system to handle packets of information. I believe that delay of information is 600 milliseconds. Whatever source you're using more than likely uses a thread system in order to pull many different tasks from many different sources in order to perform this tick asynchronously and with concurrency. For example, one of these threads could look something like this:
Code:
private final ThreadGroup group;
private final String namePrefix;
private final AtomicInteger threadNumber = new AtomicInteger(1);

public Thread newThread(Runnable r) {
	Thread t = new Thread(group, r, namePrefix
		+ threadNumber.getAndIncrement(), 0);
	if (t.isDaemon())
		t.setDaemon(false);
	if (t.getPriority() != Thread.MAX_PRIORITY - 1)
		t.setPriority(Thread.MAX_PRIORITY - 1);
	return t;
}

Now to find where they are and when they are called shouldn't be too much of a challenge. Each tick will need to handle information of restoring energy, for example, so if you can find that, you'll eventually be able to find the code that handles updating the tick. I would assume whatever class handles the world information, such as player count, would handle restoring energy. Once you find the class that handles player count, you can then search for the method that handles restoring a player's run energy. This, I imagine, is where we will be able to find the parent code. Whichever class is being used to handle these fast-based tasks, like restoring run energy, is likely to be directly tied with the server tick. Lets call this task handling class the TaskHandler, and lets just say that energy restores every 3 server ticks. Again, these are examples. The energy restoration code might look something like this:
Code:
private static void addRestoreEnergyTask() {
	TaskHandler.addFastTask.schedule(new TimerTask() {
	  [MENTION=381607]Override[/MENTION]
		public void run() {
			try {
				for (Player player : getPlayers()) {
					if (player == null || player.isDead() || !player.isRunning()) 
						continue;
					player.restoreRunEnergy();
				}
			} catch (Throwable e) {
				Logger.handle(e);
			}
		}
	}, 0, 1800);
}

This TaskHandler class, which you can see is called at the top of the method, is likely pooling tasks directly to the tick's queue. Heading to the TaskHandler class you will probably see similar code in the init() method:
Code:
addFastTask = new Timer("Fast Task");
addSlowTask = availableProcessors >= 6 ? Executors
		.newScheduledThreadPool(availableProcessors >= 12 ? 4 : 2,
		new SlowThreadFactory()) : Executors
		.newSingleThreadScheduledExecutor(new SlowThreadFactory());

Towards the bottom of this method, you'll probably see some variable initiating it's start method ('serverThread.start()' for example). Go to the class that is initiating it's start method - in my example I used the variable serverThread. So, whichever class serverThread is calling, head there. You will likely find rows of code that look similar to this:
Code:
if (taskInformation.continueCount > 0) {
	taskInformation.continueCount--;
	continue;
}

Or maybe it's lots of for loops that look like this:
Code:
for (NPC npc : World.getNPCs()) {
	if (npc == null || npc.hasFinished())
		continue;
	npc.processEntity();
}

Either way, if you can find whichever thread that handles where local players and entities are updated, you will be able to save your player's previous tile at the start of the tick. This information is probably already saved in a method somewhere in the Player class. Lets call that method processInformation. In that init() method, where you found the thread, you can add something like this to save your player's information at the start of the tick:
Code:
for (Player player : World.getPlayers()) {
	if (player == null)
		continue;
	player.processInformation();
}

This way, your player's information should be stored at the start of each tick, and you could enjoy dancing with others.


Please be aware that the above may be wildly inaccurate for the source you're using, and that it is difficult to provide you with direct code examples without having any information to rely on. What I provided is simply very generic examples of where you may update this information, and how you may find it. Also be aware that you may also need to remove whatever code saves your player's information currently if you do intend on trying to add this.

And as I was writing this reply, the thought occurred that you may want to check the method that handles your player following. It could be that the players are not going to the player's last tile and facing the target, but instead it may be pathfinding to the target, +/- their x/y coordinates based off of clipping restrictions.

Hope this helps!
 
Last edited:
Hey thanks for the reply, forgive if I sound stupid but I'm not sure i fully understand what you're talking about... could you show me a code example? if that wouldn't be too much to ask?

Here is something little prof oak did on ruse for me back in the day, i think the same sort of system is in place in elvarg
Code:
			// If two players are following eachother, make them "dance" with
			// each other by marking the destination as their old position.
			if (character.isPlayer() && followCharacter.isPlayer()) {
				if (followCharacter.getMovementQueue().getFollowCharacter() != null
						&& followCharacter.getMovementQueue().getFollowCharacter().equals(character)) {
					destination = ((Player)followCharacter).getPreviousPosition();
					inRange = false;
				}
			}
 
Here is something little prof oak did on ruse for me back in the day, i think the same sort of system is in place in elvarg
Code:
			// If two players are following eachother, make them "dance" with
			// each other by marking the destination as their old position.
			if (character.isPlayer() && followCharacter.isPlayer()) {
				if (followCharacter.getMovementQueue().getFollowCharacter() != null
						&& followCharacter.getMovementQueue().getFollowCharacter().equals(character)) {
					destination = ((Player)followCharacter).getPreviousPosition();
					inRange = false;
				}
			}

Thanks! Im using pi at the moment I also have a ruse base im coding so I can add that to it. I'm not to familar with ruse just yet so is there a followplayer class?
 
Thanks! Im using pi at the moment I also have a ruse base im coding so I can add that to it. I'm not to familar with ruse just yet so is there a followplayer class?

I haven’t touched it in a while. I think it is 317pathfinder.java lmk if its not and ill look it up when im home/could give you my entire class in private if you want
 
I haven’t touched it in a while. I think it is 317pathfinder.java lmk if its not and ill look it up when im home/could give you my entire class in private if you want
It doesn't seem to be in the pathfinder class but there is a movementque class I think its in there (my ruse base is faladorPS) however its not that important to have this feature. I would like to have it but its not a priority, my priority is figuring out what happened to my health bars/hit splats on my pi... I recently did some work with HP Overlays and it messed up my health bars with npc vs player combat. ( sometimes hit splats come up other times they don't, health bars never show up above the players head though... but they do in pvp. Any ideas there? I made a post about it but no one replied. To me its not a big deal either but someone is bound to complain about it... I mean you could just watch the health orb to see how much hp you have... Also I was planning on displaying your Hp at the top of the screen 100% of the time anyways (part of the hp overlays) anyways thanks for the help!
 

Users who are viewing this thread (total: 1, members: 0, guests: 1)

Who read this thread (total members: 6)