ScriptUO

Official ScriptUO EasyUO Scripts => Scripting Chat => Topic started by: NObama on March 22, 2010, 05:43:45 PM

Title: Building a Sub: Find and tag all NPCs in the local area
Post by: NObama on March 22, 2010, 05:43:45 PM
Salutations -

I'm toying with the idea of a sub that will do the following:

1) Scan a given radius and find all NPCs
2) Determine, via context menu, if each NPC is a vendor
3) Assign each vendor's unique ID to a %npc_id[num] variable.  For example, if there were 3 vendors, the variables would be
   - %npc_id1 XXXXX
   - %npc_id2 YYYYY
   - %npc_id3 ZZZZZ

The point of this sub is, of course, to abuse TM's item buying routines.

Basic structure would be something like this, I think:

Code: [Select]
scan tile radius 15 for type IS
determine if IS is yellow
Open context menu for yellow IS
   If context includes 'buy'
     assign ID to %npc_ id[#]
     increment %npc_id[#]
   ignore vendor

Eventually, it should also identify types of npc vendor (tailor, provisioner, mage, scribe, etc, etc).  

Is my approach logical, or do I need a different angle?  

 :)
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: Endless Night on March 22, 2010, 06:04:00 PM
Your approach looks fine to me .. what do you need to index all vendors in this manner if you dont mind me asking
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: NObama on March 22, 2010, 06:09:45 PM
I'm automating item buying.  Basically, I want to fill a runebook with runes and just recall into a shop and auto-buy everything on my list from every NPC in the joint.

I hit my first snag.  I'm trying to build a set of conditions that will increment variable names, but I can't figure out the logical structure.

My intent is to do something like this:

Code: [Select]
sub Find_NPCs
set !npc_counter 1

  finditem IS G_15
    if #findkind = 1 && #findrep = 7
      set %npc_id[!npc_counter value] #findid
      set !npc_counter !npc_counter + 1
    ...etc

...but I don't know how to tell EUO to do that...

 ???
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: Scrripty on March 22, 2010, 08:29:29 PM
I'm automating item buying.  Basically, I want to fill a runebook with runes and just recall into a shop and auto-buy everything on my list from every NPC in the joint.

I hit my first snag.  I'm trying to build a set of conditions that will increment variable names, but I can't figure out the logical structure.

My intent is to do something like this:

Code: [Select]
sub Find_NPCs
set !npc_counter 1
  finditem IS G_15
    if #findkind = 1 && #findrep = 7
      set %npc_id[!npc_counter value] #findid
      set !npc_counter !npc_counter + 1
    ...etc
...but I don't know how to tell EUO to do that...
 ???

Use a for loop to iterate through all within range and any that meet your criteria would get set to a variable name with a number applied.  But I would think you might want to add their vendor TYPE on there too... but do you need to go all that way?  Why not just recall in to where there's a bunch of vendors, set your search range, and have it buy everything from them?  That's what gen200's script does basically...  It will find any vendor and then buy from every one within range.
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: BadManiac on March 22, 2010, 09:47:49 PM
probably easier to do with some string magic, or at least it's an alternative to OCR'ing the popup menu. Make a list of all vendor professions. Blah the Tinker, Blah the Tailor and so on, make a long list, tailor_tinker_blacksmith_provisioner_mage_scribe_...
Then read each NPC name, and either use STR functions to find each separate word from the list in the vendor name via for loop, or extract the vendors title from it's name. Should be pretty simple, find 'the' in the title, delete anything from the start of the name to the space after 'the', find the next space, delete everything including and after that space. Then you're left with a #STRRES containing the vendors profession. Then simply check IF #STRRES IN %longassvendorlist. If it is, it's a vendor and you can go shopping.

Either way works, but I avoid using OCR unless absolutely necessary so that's how I'd solve your problem.

As for your second question what you want is the DOT concatenation operator.
Code: [Select]
finditem HS_IS_XU_AV_GARGOYLES G_15
    if #findkind = 1 && #findrep = 7
      set %npc_id . !npc_counter #findid
      set !npc_counter !npc_counter + 1

Then you can go through the list:
Code: [Select]
FOR %i 1 !npc_counter
{
  SET !current_npc_id %npc_id . %i
  ;do things with !current_npc_id
}
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: Scrripty on March 22, 2010, 10:22:34 PM
Make sure to ignore anything you find that doesn't meet your criteria too so you don't search it again while buying regs. :)
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: Endless Night on March 23, 2010, 05:48:18 AM
Do as BM said.   But i would use an array of profession names.  That way dont have to pase the vendor profession but rather do

For !x 1 %TotalProfessions
  if %profession . !x  in Vendorname
      set Whaterver to somesomething

and second question  as BM siad use DOT .  operator

Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: Scrripty on March 23, 2010, 08:03:24 AM
Well as Twinkle McNugget said, and BM elaborated anyways... heh
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: BadManiac on March 23, 2010, 01:06:42 PM
Yes Twinkle McNugget did say it. But Twinkle McNugget was so incredibly non specific and vague that I felt some clarification to what Twinkle McNugget had said was in order :P
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: NObama on March 23, 2010, 02:52:59 PM
Yes Twinkle McNugget did say it. But Twinkle McNugget was so incredibly non specific and vague that I felt some clarification to what Twinkle McNugget had said was in order :P

I second that.  Twinkle McNugget forgets that I are a scriptingz newb.

Thanks everyone.  I will go learn more about arrays after I master the dot concatenation doo hickey.

 :)
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: Scrripty on March 23, 2010, 03:47:48 PM
Yes Twinkle McNugget did say it. But Twinkle McNugget was so incredibly non specific and vague that I felt some clarification to what Twinkle McNugget had said was in order :P

I second that.  Twinkle McNugget forgets that I are a scriptingz newb.

Thanks everyone.  I will go learn more about arrays after I master the dot concatenation doo hickey.

 :)

I'm a scripting noob too.  Seriously...  I'm still learning new stuff every day.
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: NObama on March 23, 2010, 06:31:09 PM
Alright - thanks to the expert tutelage above, I believe I have mastered the concept of DOT and also correctly applied EN's earlier lessons on REPEAT/UNTIL.

It correctly assigned variable names and values.  Anyone have any critique of this piece before I continue?

Code: [Select]
ignoreitem #charid
gosub Find_NPCs

sub Find_NPCs
set !npc_counter 1
finditem IS G_15
  set !Exit 10
  Repeat
     set !Exit !exit - 1
     {
     finditem IS G_15
       if #findkind = 1 && #findrep = 7
         {
         set %npc_id . !npc_counter #findid
         set !npc_counter !npc_counter + 1
         }
       ignoreitem #findid
     }
  Until #findkind = -1
halt

Victory comes in small slices for newbs.

 ;)
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: BadManiac on March 23, 2010, 06:41:10 PM
I'd put the IGNOREITEM #CHARID in it's own ignorelist, and place it at the top of the sub, and then IGNOREITEM RESET that list before returning from the sub. Globally ignoring yourself can be a bad idea ;)
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: Endless Night on March 23, 2010, 07:04:15 PM
I hardly ever find a need to use ignore item
In this case i would use a for loop like below.

Code: [Select]
sub Find_NPCs
  set !npc_counter 1
  finditem IS G_15
  If #findcnt > 0
    {
    For #findindex 1 #findnct
      {
      if #findkind = 1 && #findrep = 7
         {
         set %npc_id . !npc_counter #findid
         set !npc_counter !npc_counter + 1
          }
      }
    }
Return
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: NObama on March 23, 2010, 07:47:44 PM
NObama's Emerging Rules of Coding:

1. Whatever you write, Endless Night can do it better and with at least 12.5% fewer lines.


 :P
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: NObama on March 23, 2010, 07:48:25 PM
Globally ignoring yourself can be a bad idea ;)

Tell me about it.  Chicks did it to me for years.

 ;)
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: Endless Night on March 23, 2010, 08:52:51 PM
NObama's Emerging Rules of Coding:

1. Whatever you write, Endless Night can do it better and with at least 12.5% fewer lines.
 :P

LOL ...  your projects are defaintly getting more ambitious
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: NObama on March 24, 2010, 01:26:47 PM
Can someone point me to a tutorial on arrays or a good example of a script that effectively uses an array?  There is no discussion of them on EUO's wiki as far as I've been able to find.

I really need the array to help me ignore the NPCs that are yellow that don't actually sell anything...

Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: Endless Night on March 24, 2010, 01:44:02 PM
Tm i belive has some array subs on these boards some place

Arrays and how to make them in EUO

1 dimensional array  Var[x= 1.....]
set %MYArray . !CountX  !Value
 
2 dimensional array  var[x,y]
set %MYArrayVarNAme %MyArray , !CountX , _ , !CountY
set % . %MyArrayVarName !Value
(eg %Myarray1_1 )

3 dimensional array  var[x,y,z]
set %MYArrayVarNAme %MyArray , !CountX , _ , !CountY , _ , !CountZ
set % . %MyArrayVarName !Value
(eg %Myarray1_1_1 )

4 dimensional array  var[A,b,c,d]etc
set %MYArrayVarNAme %MyArray , !CountA , _ , !CountB , _ , !CountC , _ , !CountD
set % . %MyArrayVarName !Value
(eg %Myarray1_1_1_1 )


In your case you probably just need a One Dimensional Array  (you have already used them with my MiniRail system you just might not have realised - Every time you add a way point you add a record to 3 one dimensional arrarys  x[], y[], z[])




Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: NObama on March 24, 2010, 01:48:48 PM
Ahhhh...that helps put them in perspective.

I really only need a one dimensional array.  I'm looking to do:

if X in #property
ignore id

Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: TrailMyx on March 24, 2010, 01:50:52 PM
Tm i belive has some array subs on these boards some place...

Indeed:


http://www.scriptuo.com/index.php?topic=19.msg19#msg19
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: NObama on March 24, 2010, 02:08:45 PM
Heh - that thread is only somewhat less arcane to me as when I first commented on it...=P

Codingz is hard
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: NObama on March 24, 2010, 02:58:26 PM
Okay - I'm stripping this down to components to try and solve it one piece at a time.

This definitely works to establish the bad NPC names:

Code: [Select]
goSub Setup_Ignore_NPC_Type_Values
halt
;--------------------------------------------------------------
Sub Setup_Ignore_NPC_Type_Values
  gosub Add_Ignore_NPC_Type guildmaster
  gosub Add_Ignore_NPC_Type banker
  gosub Add_Ignore_NPC_Type minter
Return
;--------------------------------------------------------------
Sub Add_Ignore_NPC_Type
  if %Ignore_NPC_Type_Max = N/A
     set %Ignore_NPC_Type_Max 0
  set %Ignore_NPC_Type_Max %Ignore_NPC_Type_Max + 1
  set %Ignore_NPC_Type_Max . %Ignore_NPC_Type_Max %1
Return
;--------------------------------------------------------------

Var Dump yields:
%IGNORE_NPC_TYPE_MAX: 3
%IGNORE_NPC_TYPE_MAX1: guildmaster
%IGNORE_NPC_TYPE_MAX2: banker
%IGNORE_NPC_TYPE_MAX3: minter

I still don't get why I have to have "MAX" in there, so if someone could educate me...

Now, I just need to apply the array values in a loop...
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: NObama on March 24, 2010, 03:20:39 PM
Ok - someone check my logic and tell me if I'm using #result correctly:

Given the following sub:

Code: [Select]
;--------------------------------------------------------------
sub Ignore_NPC_Types

set !loopvalue 1
  If %Ignore_NPC_TYPE_Max = N/A
    gosub Setup_Ignore_NPC_Type_Values
Repeat
  set #result true
  if %Ignore_NPC_TYPE_Max . !loopvalue notin #property
    {
    set #result false
    }
  set !loopvalue !loopvalue + 1
Until !loopvalue >= %Ignore_NPC_Type_Max
return #result
;--------------------------------------------------------------

Would this code execute the way I intend?

Code: [Select]
        if #result = false
           {
           set %npc_id . !npc_counter #findid
           set !npc_counter !npc_counter + 1
           set %npc_max !npc_counter
           }

I actually think I'm close to cracking this...
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: Scrripty on March 24, 2010, 03:25:21 PM
Why does this need to be so difficult?  There's not that many npcs that need to be ignored...

Code: [Select]
     if hairstylist in #property || sculptor in #property || Noble in #property || mage in #property || bride in #property || miner in #property || fighter in #property || peasant in #property || messenger in #property || guard in #property || adventure in #property || artist in #property || bard in #property || thief in #property || actor in #property || impresario in #property || beggar in #property || gypsy in #property || mondain in #property || breeder in #property
        ignoreitem #findid

Done.

Yes there's more, but they are easy to find.  Make a list menu script that adds any #findrep invulnerable npcs to the list and you can just run around a big town like brit and get them all.  Then add them to the list.  It's fast to read the line and if it gets too long, you can use the + thingy to add to it on another line...
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: NObama on March 24, 2010, 03:32:46 PM
I could take the moral high ground here and claim that I was trying to better my coding skills...but the truth is that I just didn't think of doing it that way.

The good news is, I think I learned how to do this with an array.

I think this is a working version...

Code: [Select]
goSub Setup_Ignore_NPC_Type_Values
gosub Find_NPCs
;--------------------------------------------------------------
sub Find_NPCs
set !npc_counter 1
finditem IS G_30
  set !Exit 10
  Repeat
     set !Exit !exit - 1
     {
     finditem IS G_15
       if #findkind = 1 && #findrep = 7
         {
         event Property #findid
         gosub Ignore_NPC_Types
         if #result = false
           {
           set %npc_id . !npc_counter #findid
           set !npc_counter !npc_counter + 1
           set %npc_max !npc_counter
           }
         }
         ignoreitem #findid
  Until #findkind = -1
return
;--------------------------------------------------------------
sub Ignore_NPC_Types

set !loopvalue 1
  If %Ignore_NPC_TYPE_Max = N/A
    gosub Setup_Ignore_NPC_Type_Values
Repeat
  set #result true
  if %Ignore_NPC_TYPE_Max . !loopvalue notin #property
    {
    set #result false
    }
  set !loopvalue !loopvalue + 1
Until !loopvalue >= %Ignore_NPC_Type_Max
return #result
;--------------------------------------------------------------
Sub Setup_Ignore_NPC_Type_Values
  gosub Add_Ignore_NPC_Type guildmaster
  gosub Add_Ignore_NPC_Type banker
  gosub Add_Ignore_NPC_Type minter
Return
;--------------------------------------------------------------
Sub Add_Ignore_NPC_Type
  if %Ignore_NPC_Type_Max = N/A
     set %Ignore_NPC_Type_Max 0
  set %Ignore_NPC_Type_Max %Ignore_NPC_Type_Max + 1
  set %Ignore_NPC_Type_Max . %Ignore_NPC_Type_Max %1
Return
;--------------------------------------------------------------

Var Dump:
%NPC_ID1: BVKLCC
%NPC_ID10: SWSMM
%NPC_ID2: JQNXXB
%NPC_ID3: QNLOM
%NPC_ID4: HAIOM
%NPC_ID5: BCPNM
%NPC_ID6: ZEPNM
%NPC_ID7: XMHNM
%NPC_ID8: KJHNM
%NPC_ID9: HYUMM

Booyah. 

 8)
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: Scrripty on March 24, 2010, 04:08:21 PM
You still need a type LIST correct?  So you're still doing what I just did there... just in a more complex way.  As EN would say about now:  KISS.  Keep it simple stupid. :)
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: NObama on March 24, 2010, 04:52:48 PM
Ok - the six-letter NPC IDs above are guildmasters and guildmistresses.  Any idea why this code is excluded everything on the list properly except those two words?

;--------------------------------------------------------------
Sub Setup_Ignore_NPC_Type_Values
  gosub Add_Ignore_NPC_Type guildmaster
  gosub Add_Ignore_NPC_Type guildmistress
  gosub Add_Ignore_NPC_Type banker
  gosub Add_Ignore_NPC_Type minter
  gosub Add_Ignore_NPC_Type trainer

Return
;--------------------------------------------------------------
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: NObama on March 24, 2010, 05:14:33 PM
Whoops.  Found my problem.  A wee tiny logical error.  Working sub below:

Code: [Select]
ignoreitem #charid
goSub Setup_Ignore_NPC_Type_Values
gosub Find_NPCs
event exmsg #charid 3 0 done$
halt
;--------------------------------------------------------------
sub Find_NPCs
set !npc_counter 1
finditem HS_IS G_15
  set !Exit 10
  Repeat
     set !Exit !exit - 1
     {
     finditem HS_IS G_15
       if #findkind = 1 && #findrep = 7
         {
         event Property #findid
         gosub Ignore_NPC_Types
         if #result = false
           {
           set %npc_id . !npc_counter #findid
           set !npc_counter !npc_counter + 1
           set %npc_max !npc_counter
           event exmsg #charid 3 0 adding #property $
           }
         }
         ignoreitem #findid
  Until #findkind = -1
return
;--------------------------------------------------------------
sub Ignore_NPC_Types

set !loopvalue 1
  If %Ignore_NPC_TYPE_Max = N/A
    gosub Setup_Ignore_NPC_Type_Values
Repeat
  set #result true
  if %Ignore_NPC_TYPE_Max . !loopvalue notin #property
    {
    event exmsg #charid 3 0 not %Ignore_NPC_TYPE_Max . !loopvalue
    set #result false
    }
  if %Ignore_NPC_TYPE_Max . !loopvalue in #property
    event exmsg #charid 3 0 matches %Ignore_NPC_TYPE_Max . !loopvalue
  set !loopvalue !loopvalue + 1
  if #result = true
    {
    event exmsg #charid 3 0 IGNORING NPC!
    return
    }
Until !loopvalue >= %Ignore_NPC_Type_Max
return #result
;--------------------------------------------------------------
Sub Setup_Ignore_NPC_Type_Values
  gosub Add_Ignore_NPC_Type guildmaster
  gosub Add_Ignore_NPC_Type guildmistress
  gosub Add_Ignore_NPC_Type banker
  gosub Add_Ignore_NPC_Type minter
  gosub Add_Ignore_NPC_Type trainer
  gosub Add_Ignore_NPC_Type vet
Return
;--------------------------------------------------------------
Sub Add_Ignore_NPC_Type
  if %Ignore_NPC_Type_Max = N/A
     set %Ignore_NPC_Type_Max 0
  set %Ignore_NPC_Type_Max %Ignore_NPC_Type_Max + 1
  set %Ignore_NPC_Type_Max . %Ignore_NPC_Type_Max %1
Return
;--------------------------------------------------------------

Gosh, this is a rush.

 :)
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: rana70 on March 26, 2010, 10:39:40 AM
Hi,

just in case you are too lazy to search :-)

Code: [Select]
     if #FindType in HS_IS
      Set %RACE HUMAN
     if #FindType in XU_AV
      Set %RACE ELF
     if  #FindType in OCB_NCB
      Set %RACE GARGOYLE


 :D
Title: Re: Building a Sub: Find and tag all NPCs in the local area
Post by: BadManiac on March 26, 2010, 07:02:00 PM
Oh thanks Rana, saved me from grabbing the gargy ones myself. *updates buying scripts*

Secondary, slightly on topic question:
Are there any gargoyle vendors outside the garg city in Ilsh and Ter Mur Royal City? Are there any other towns in Ter Mur with vendors?