ScriptUO

Official ScriptUO EasyUO Scripts => Scripting Chat => Topic started by: Cerveza on February 13, 2010, 04:19:13 AM

Title: Follow sub
Post by: Cerveza on February 13, 2010, 04:19:13 AM
I need a following sub routine that will stop X tiles short of the followed target.

Right now I'm using

Code: [Select]
sub follow
Finditem %follow_target G_15
if #finddist > 2
  {
  event pathFind #findx #findy #findz
  }
return

I like the pathFind because the script continues while the char moves. Unlike the "move" command that must complete it's move before continuing the script.

Quote from: EasyUO Docs
The move command moves the character to a specified position. No pathfinding is done, so you should probably use event PathFind instead.

Event Pathfind - Please note that your script will keep on executing while the character is moving.

The issue is that the char will follow the target until the char is right on top of the char. I want to stop short by X (defined by me) tiles. AND I want the char to stop X tiles behind the target no matter what direction the target is going.

So if the target is going NORTH, I want to follow and stop say 4 tiles SOUTH of the target. And if the target is traveling WEST I want to stop 4 tiles EAST of the target.

If anyone has a good sub, or knows of one, lemme know so I can play with it.
Title: Re: Follow sub
Post by: Paulonius on February 13, 2010, 05:33:13 AM
What about working with an equation with -2 off of X and Y you are going to and X Y you currently have? You would have to account for the difference in different directions. Maybe something like this:


Code: [Select]
 
If #FindX > #CharposX
Set %NewFindX #FindX - 2

If #FindX < #CharposX
Set %NewFindX #FindX + 2

If #FindX = #CharposX
  {
  If #FindY > #CharposY
  Set %NewFindX #FindX - 2

  If #FindY < #CharposY
  Set %NewFindX #FindX + 2
 }

I think it would need another set of equations to work on the Y axis and some logic to decide which to use, but this is what I have been thinking about.  If you mod X and Y both you get the follower in a wing pattern and with a couple of followers you could walk around like a flock of geese. 

I would also like it to include a walk or run command so that it would keep you in stealth if appropriate.
Title: Re: Follow sub
Post by: Cerveza on February 13, 2010, 08:13:06 AM
That's what I need, some way of stopping short.

I'll play with it some and see what I can put together. I was hoping someone had already seen something in a script somewhere.
Title: Re: Follow sub
Post by: TrailMyx on February 13, 2010, 09:09:41 AM
I have one Cerveza I'll give ya that I used for a PvP bot contest I was working on.  You just can't distribute it since it's directional oriented.  It's funny chase my bot.  lol
Title: Re: Follow sub
Post by: Cerveza on February 13, 2010, 12:54:13 PM
Nice! I'll work it in. Thanks TM
Title: Re: Follow sub
Post by: TrailMyx on February 13, 2010, 12:57:48 PM
Nice! I'll work it in. Thanks TM

Ok, lemme locate it.  Remember, for your eyes only.  ;)
Title: Re: Follow sub
Post by: Cerveza on February 16, 2010, 06:50:54 AM
I like TM's solution, but since this would be a release script I'll have to come up with something myself. I was thinking along the lines of Pauls solution... here's my idea.

Code: [Select]
set %buffer 4

finditem %primary G_
if #finddist > %buffer
{
set %primaryX #findX
set %primaryY #findY
set %primaryZ #findZ

if #charPosX > %primaryX
set %movePosX ( %primaryX + %buffer )

if #charPosX < %primaryX
set %movePosX ( %primaryX - %buffer )

if #charPosX = %primaryX
set %movePosX %primaryX

if #charPosY > %primaryY
set %movePosY ( %primaryY + %buffer )

if #charPosY < %primaryY
set %movePosY ( %primaryY - %buffer )

if #charPosY = %primaryY
set %movePosY %primaryY

set %movePosZ %primaryZ

event pathFind %movePosX %movePosY %movePosZ
}
return

That *should* set the x and y properly for the char to stop behind in any of the 8 primary directions.
Title: Re: Follow sub
Post by: UOMaddog on February 16, 2010, 01:33:45 PM
You can't guarantee the Z-axis is correct however many tiles away from the person you're following, thereby causing the script to fail to pathfind. However, you might be able to look at the #TILEZ for the X/Y-coordinates. Just an idea!
Title: Re: Follow sub
Post by: Paulonius on February 16, 2010, 02:04:49 PM
I think there is going to be a Z variance to account for a lot of the time unless you are standing on the same spot, but do you really need Z for the pathfind? I leave Z out for subs that run into my house and it works fine.
Title: Re: Follow sub
Post by: Cerveza on February 23, 2010, 06:59:33 AM
This was over at EUO

Code: [Select]
if #FindX >= #CharPosX
  set %x #FindX - 1
else 
  set %x #FindX + 1
 
if #FindY >= #CharPosY
  set %y #FindY - 1
else 
  set %y #FindY + 1
 
event pathfind %x %y #findz

Just putting it here to consolidate all these options.
Title: Re: Follow sub
Post by: MWinc on March 08, 2010, 09:35:39 AM
Code: [Select]
namespace global Movement
set !characters ; all characters intending to be moved
set !Leader ; the leader
set %Move_Timer 200 ; time in ms between move checks
set %Move_Time #systime
set %Follow_Dist 2 ; how far it stays behind

While #true
{
while #systime < %Move_Time
wait 1
repeat
uoxl swap
until #charid = !Leader
set !Leaderx #charposx
set !Leadery #charposy
for %clinr 1 #clicnt
{
uoxl swap
if #charid notin !characters
continue
Gosub Calculate_Dist ; Some math required in this sub. Explanation below
if #result > 2
{
gosub Calculate_Move ; based on #chardir sets where the follower should move
Event pathind %Pathfindx %Pathfindy %Pathfindz
}
}
set %Move_Time #systime + %Move_Timer
}

Sub Calculate_Dist
set %Distance_X ABS ( #charposx - !Leaderx )
set %Distance_Y ABS ( #charposy - !Leadery )
if %Distance_X >= %Distance_Y
set %Distance1 %Distance_X
else
set %Distance1 %Distance_Y
set %Total_Distance  ( %Distance1 + ( ABS ( %Distance_X - %Distance_Y ) ) )
return %Total_Distance

The Cpu usage and script lag for doing a mathematical calculation is far less than that of Repeated Finditems. Plus Utilizing the info already on your computer (!Leaderx !Leadery) you get a much more accurate reading of the distance/location.
Title: Re: Follow sub
Post by: Cerveza on March 08, 2010, 11:35:46 AM
I see what your doing, eliminate the finditem to determine distance and use values of x,y for the different chars.

I'll play with that... thanks!
Title: Re: Follow sub
Post by: manwinc on March 08, 2010, 11:48:17 AM
Yeah, I haven't played with the sub for find dist yet because all i've incorporated is moving to the Exact location of the leader
Title: Re: Follow sub
Post by: Cerveza on March 08, 2010, 11:52:05 AM
It will work, I'm sure. Swap to one char, note his position, swap to the other char, note his position. Compare the two and move accordingly.

Eliminating the finditem is a great idea. Swapping is much quicker. I'm going to work this idea into my movement. I also want to go back to a position oriented system, now it's based on whatever direction the Primary char is facing, which *could* be a problem.
Title: Re: Follow sub
Post by: NObama on March 08, 2010, 11:53:18 AM
Yeah, I haven't played with the sub for find dist yet because all i've incorporated is moving to the Exact location of the leader

Another reference to the army!  It's like manwinc has a superpower that lets him predict which threads I'm lurking each day and posts tidbits to torment me!

Curses!

:p
Title: Re: Follow sub
Post by: Scrripty on March 08, 2010, 12:20:40 PM
It will work, I'm sure. Swap to one char, note his position, swap to the other char, note his position. Compare the two and move accordingly.

Eliminating the finditem is a great idea. Swapping is much quicker. I'm going to work this idea into my movement. I also want to go back to a position oriented system, now it's based on whatever direction the Primary char is facing, which *could* be a problem.

That gave me a small idea for the targetter I'm working on.  It does a finditem every loop to find new targets... so I basically made it a for #findindex loop and sped it WAY up. :)  The little things set off inspiration I guess.  Now it will scan for new enemies and iterate through ALL FOUND before searching again.  It's a little thing... but in some situations it REALLY speeds things up.  I ran around luna and added vendor scanning... and they loaded up pretty fast since I didn't have to do a finditem for EVERY one of them.  I do an initial finditem, then loop through it testing each one found for addition to my lists... so all of them that are found get ignored before the next scan.  Sped it WAY up. :)  I knew to do this, but it just sparked me to get it done.  I also noticed a little tidbit that anything PLAYER based gets loaded immediately no matter what.  But anything like a vendor or an npc, WILL NOT update it's info while you are running.  It waits till you stop or pause your running.  Something to think about while writing scripts.
Title: Re: Follow sub
Post by: manwinc on March 09, 2010, 07:20:59 PM
So, I was running the following part of the army utilizing the Math functions Orn gave me from EUO and noticed that my characters weren't following me when they had a #finddist of 10 and I set them to follow if the Computed Distance was Less than 15.


Did Some tests between Calculated Distance and #Finddist and Determined that you can just use this

Code: [Select]
set %Distance_X ABS ( #charposx - %Pathfindx )
set %Distance_Y ABS ( #charposy - %Pathfindy )
if %Distance_X >= %Distance_Y
set %Distance1 %Distance_X
else
set %Distance1 %Distance_Y

%Distance1 = #finddist
for every instance I've tested So far.
Title: Re: Follow sub
Post by: BadManiac on March 10, 2010, 04:29:55 PM
I need a following sub routine that will stop X tiles short of the followed target.
I'll be giving you exactly that as soon as I get home today. Watch this space.

You can use my Automagic Pathfinding sub along with a component sub from it called "ScaledLine" to achieve what you're trying to do. I initially wrote it to use in rail engines, for resource gathering scripts, they often use move, so you need very precise routes between for example tree's and other obstacles. I wanted to use Event Pathfind instead, but it can only pathfind a small distance (depending on your update radius). So I wrote a (BIG) sub that chops a distance into manageable pieces and pathfinds each individual segment.

What you can do is use the ScaledLine sub to calculate a point X tiles away from your target, along a life from your current position to the target. Then pathfind to that new point. It'll use the UO event pathfind function, and stop X tiles from the target. I've used exactly this in the past for disco training at the oriental dragon spawn in ilsh, to disco and follow it around at a fixed distance. Don't expect EXACT precision at all times tho, UO's pathfind function has a bit of a personality ;)

I'll share the full source later when I get home.
Title: Re: Follow sub
Post by: Cerveza on March 10, 2010, 04:43:38 PM
Wow! Thanks BM! I'm looking forward to seeing/trying it out.
Title: Re: Follow sub
Post by: manwinc on March 10, 2010, 04:50:58 PM
Cerv, DL the newest army menu/cs Run 2 Clients with it and select Fall back for the movement.
Title: Re: Follow sub
Post by: Scrripty on March 10, 2010, 04:54:53 PM
Cerv, DL the newest army menu/cs Run 2 Clients with it and select Fall back for the movement.

I can't wait to play with BM's sub since I had a love affair with his looter for so long. :)  I'll go test the army script for ya right now manw.
Title: Re: Follow sub
Post by: BadManiac on March 10, 2010, 06:24:36 PM
Ok, here's the original script posted on EUO.com: http://www.easyuo.com/forum/viewtopic.php?p=189786 (http://www.easyuo.com/forum/viewtopic.php?p=189786)
Saves me posting the full description again.

The whole thing is recursive too, so if the pathfind fails, but is yet within it's timelimit, it will call itself to get around large obstacles like mountains and player houses.
For lulz try pathfinding straight through a large town like Britain. For Epic Lulz try to pathfind across an ocean (to an island from mainland) and set a really long timeout, It'll keep tying, persistent bastard that it is ;)


But the interesting bit for this task is the ScaledLine sub. Which I originally wrote a full fixed point square root function for, until I realized that all 8 directions are the same distance according to the UO client...
Take this grid: (works better in monospace font)
123
456
789
in the real world, moving from 1 to 9 is a longer distance than moving from 7 to 9. Diagonal, hypotenuse and all that. In UO it's the same distance. A right triangle where side A and B are of equal length would have an equal length hypotenuse too (wrap your head around that for a bit :P ). So that simplified the math required almost infinitely.

So here's a sub you can use alongside the pathfinding sub(s) to do what you want, right out of the box.
Note that you could use event pathfind instead of calling my sub here, or even move, if the distance is always reasonably short.

Interesting things are the ScaledLine sub, which takes two sets of coordinates, X1, Y1 and X2,Y2, and a distance, it returns a XXX_YYY formatted set of coordinates *distance* tiles away from X1,Y1 along the straight line to X2,Y2.
Sub XYReadout simply changes those to separate variables, saves a few lines of code.
Code: [Select]
;#############################
;# KeepDistance Sub
;# %1 is the target to keep at distance
;# %2 is the distance to keep
;#############################
SUB KeepDistance
SET !target %1
SET !distance %2
FINDITEM !target
IF #FINDKIND = -1
RETURN
IF #FINDDIST <> !distance
{
GOSUB ScaledLine #FINDX #FINDY #CHARPOSX #CHARPOSY !distance
GOSUB XYReadout #RESULT targx targy
GOSUB Distance #CHARPOSX #CHARPOSY !targx !targy
GOSUB BMPathfind !targx !targy 0
}
RETURN
Title: Re: Follow sub
Post by: Cerveza on March 10, 2010, 07:07:16 PM
Ok, so I have my weekend planned... around working with this!

Thanks a ton for this. I'm really looking forward to pluggin it in and seein how it runs!
Title: Re: Follow sub
Post by: Paulonius on March 11, 2010, 01:29:59 AM
Very cool.  I will be taking a look at this as well.
Title: Re: Follow sub
Post by: Cerveza on March 11, 2010, 07:58:00 AM
Lemme run this past everyone.

The %buffer is how far away I want the follower. The level at which the follower should begin movement.

Would this formula work?

Code: [Select]
sub follow
  set %pri_X #charPosX
  set %pri_Y #charPosY

gosub SwapTo %support ; swap clients to the support char
  set %sup_X #charPosX
  set %sup_Y #charPosY

; compare the two, is the formula here right?
if %sup_X < ( %pri_X + %buffer ) && %sup_X > ( %pri_X - %buffer) && %sup_Y < ( %pri_Y + %buffer ) && %sup_Y > ( %pri_Y - %buffer )
  {
    gosub SwapTo %primary ; go back to the primary char and return to the main loop because they are within %buffer of each other
    return
  }

movement stuff

I think I'm doing that right...

*The intent here is to remove the "finditem" and rely on position and math to speed up the script.
Title: Re: Follow sub
Post by: Paulonius on March 11, 2010, 08:25:18 AM
So BM, as I understand it, your script doesn't care how far away the target it is heading to is, it simply sets course based on the direction and breaks the trip down into segments to pathfind (or move) there. 

I REALLY like the idea and am psyched to check it out.  I was talking this over with MWinc and Twinkle McNugget and we were playing with the idea of creating an array of waypoints based on movement by the leader.  This sounds like it has the potential to be a lot simpler.
Title: Re: Follow sub
Post by: BadManiac on March 11, 2010, 08:38:23 AM
The target has to be within finditem range for my sub to work, but if you're multi clienting and share the position via globals, no it doesn't matter, as long as there IS a path between the two.
Title: Re: Follow sub
Post by: Katu on March 11, 2010, 01:47:49 PM
So BM, if i understood right, basically it just needs the coords to look for?
Could it walk from Britain to cove? For example?
That certainly sounds great piece of ascii chars. If it works as i think, i might snag it to my current project :)
Title: Re: Follow sub
Post by: BadManiac on March 11, 2010, 02:01:52 PM
It CAN walk from anywhere to anywhere. Britain to Cove is certainly possible. However there's a lot of crap in the way so it'd take a while to get there, and getting through the swamp with a billion player houses and mobs spawning could be interesting...

It's not meant for quite such long range pathfinding, it can, but it definitely won't get you there in a hurry. I fact when I was testing it I frequently ran from the Skara ferry to east Brit bank. And from one side of Brit to the other. Takes a while for it to find the bridges and paths through mountains by completely random trial and error, but it eventually gets there.
Title: Re: Follow sub
Post by: Katu on March 11, 2010, 02:39:10 PM
Heh, its not like i would take that trip, i was just curious if it could handle that kind of distances.
Anyways! Sounds interesting and usefull script.

-Katu
Title: Re: Follow sub
Post by: Cerveza on March 14, 2010, 07:46:54 AM
Cerv, DL the newest army menu/cs Run 2 Clients with it and select Fall back for the movement.

I *finally* got a chance to use this... awesome. Follows correctly and darn near impossible to lose the follower.

I also played with BadManiac's briefly, but was unable to work it in right away. I'll have to play with it more when I get a little time.
Title: Re: Follow sub
Post by: BadManiac on March 18, 2010, 07:51:13 PM
Let me know if you need any more info, I'd love to see these subs used more widely. It's easily my favorite work.

It totally transformed what my scripts could do in terms of movement. No more rails, just an end coordinate and it gets there. Has never failed me so far. Well, except in caves and tunnels, but that's UO's built in pathfind function being screwey. Try Solen caves for eaxmple, produces some interesting results :)