PDA

View Full Version : passing calls between active scripts



ShatteredCasis
09-30-2010, 03:26 AM
I have two active scripts where I need to pass a message from one to the other without stopping either one (which has been the way i've usually done this - or just combined them into one giant script).

I see that there's a send method for passing data to running scripts. (and from using go2).

My question is, how would I configure a running script to "catch" the send? Could anyone shoot me an example?

Thanks all!

BigWorm
09-30-2010, 10:24 AM
Send just sends the string to the other script as if it was a game line, so you can just use get like you would with any other game line.

ShatteredCasis
09-30-2010, 05:55 PM
So the only way to get the data is with a get?

Well damn.

ShatteredCasis
09-30-2010, 07:04 PM
Thanks for explaining it.

Sorry for omitting that in my reply...

Tillmen
09-30-2010, 09:05 PM
Depending on what you're trying to do, global variables might work well.

For instance, once script can watch the game stream for an offer, or a canceled offer, or an accepted offer. When someone offers you something, it might set:

$current_offer_from = "Jerk"
$current_offer_item = "strongbox"

upon accepting an offer:

$current_offer_from = nil
$current_offer_item = nil
$last_accepted_offer = "Jerk"

and upon a canceled offer:

$current_offer_from = nil
$current_offer_item = nil

Then, whenever the other script is ready to accept an offer, it can check $current_offer_from to see if there is an offer pending. It can check $current_offer_item to see if it wants to decline the offer. If there is no offer, it can just wait_while { $current_offer_from.nil? }. And when it's done with the box it can use $last_accepted_offer to know who to return the box to.

Or something like that.

ShatteredCasis
09-30-2010, 11:21 PM
Well, I was going to make it where I could send the Ezspell script commands
like "401 406 414 target 2" from another script. (actually, have the other character just whisper this to a spell bot.

like...

whisper spell_bot 401 406 414 503 casis 2

(which would have the spell_bot cast those spells 2 times)

But, ezspell uses an upstream hook, like voodoo, to get the command from the client to replace the spell numbers with the prep/cast routine. Since it's using an upstream hook, it's giving me grief trying to have another script send the command to ezspell (if there was a way to talk directly to the upstream hook, that would rule).

I'm thinking that a globalvar would work. I'll give that a shot.

Tillmen
09-30-2010, 11:52 PM
In that case, I wouldn't use global variables. I'd have the casting script take commands with unique_get, and the other script watching for whispers and send the commands to the first script with unique_send_to_script.

listener:

while line = get
if line =~ /^([A-Z][a-z]+) whispers, "([0-9\s]+)"/
unique_send_to_script 'caster', "#{$1.downcase} #{$2}"
end
end

caster:

while command = unique_get
command = command.split(' ')
name = command[0]
spell_list = command[1..-1]
for spell_num in spell_list
if (spell = Spell[spell_num]) and spell.known? and not spell.selfonly and not spell.type =~ /attack/
loop {
wait_until { spell.affordable? }
result = spell.cast(name)
break unless result =~ /Hindrance/
}
end
end
end

With this, the casting script will not miss any spell requests, because the unique buffer if separate from the game buffer. The listener script is so small, it looks like it could just be stuck in the caster script, but if you did that, it could easily miss any whispers that happened while it was casting.

As written, this only takes commands in the form of "whisper bot 401 401 406 406 414 414 503". The check for attack spells might keep you out of jail if you're running this in town. The check for selfcast spells will prevent you from casting mass blur, so that might need to be taken out if you're parked at a table or using group_ajar to allow people to join you, or if you're crazy enough to have a bot with his group open.

I didn't test this at all, but it should give you some ideas.

ShatteredCasis
10-01-2010, 01:39 AM
The problem with line.get is that it ties up the whole thread, waiting for the match. Meaning I can't accomplish anything else. Like in the second example, when that loop/wait_until is hit, the script freezes until that condition is met, or until there's a forced break. This was why I gave the "well crud", on the line/get option for the send-to-script method.

I certainly realize you didn't have the particulars on what I was hoping to accomplish with a remote script call...

Basically I wrote a script ezspellz.lic that works like voodoo, only I can pass multiple spells to it, tell it to cast the spells multiple times, and assign aliases. so at the command prompt I can just type... 402 blah blah blah without having to type 401 then blah then blah then blah and so on

So what I'm wanting to do is extend this functionality to be a remote call as well, not just a command line entry. In the past, I've just written a second script to match the first, only checking different inputs, or I've just copied the functions entirely. But I got to thinking that maybe I could use the send command or something like that so as to have one spell casting script (in this case).

I know I could create say, ezspellz_remote.lic which doesn't employ the upstreamhook and only looks for the line match. But my goal was to avoid that, so that friends could use it with their custom scripts without having to add alot of code.

What i'm thinking of now, with your suggestion of the global var, is to make a global array (spell_comman_queue), and rather than the main function in ezspellz work directly off the upstream hook, have the main function work directly off the queue as well. the upstream hook would simply push onto the global queue, just like another script could.

So in ezspells.lic i have an infinite loop checking whether there's anything in the queue, if not, keep looping, if so, process what's in the queue.
When someone enters a valid option in the command line, the upstreamhook grabs it, stacks it in the queue, and the loop will grab it on the next pass.
In another script i have some line match for whisper.. and this script would push the data into the global queue as well.
For me, I'm thinking that would work even better actually than using the send option, or having some other public accessor method, as it'll be less complexity (and less code)

Thanks for the assistance, as always!

ShatteredCasis
10-01-2010, 02:44 AM
worked like a dream.

from my test.lic script...


#test.lic
if running?('ezspellz')
$ezspellz.push("1003 1007")
else
start_script('ezspellz')
sleep(1)
$ezspellz.push("1003 1007")
end


in the ezspellz.lic script....


... (set the global var) ...
$ezspellz = Array.new

... (snippet of hook action) ...
action = proc { |client_string|
if client_string =~ /^(?:<c>)[0-9]{3,6}/
client_string.slice!(0..2)
$ezspellz.push(client_string)
$activate = true
nil

... (set the hook) ....
UpstreamHook.add('EZSpellz', action)

... (then later on in the main) ....
loop {
wait_while { ($ezspellz.empty?) }
sf_command = ($ezspellz.delete_at(0)).split
firstword = sf_command.first
if firstword.downcase == "ezalias"


worked like a dream from both command prompt and test script. woohoo! Thanks for the help!