Arguments and script file

Posted by Varkin on Fri 18 Apr 2008 01:58 PM — 2 posts, 11,997 views.

#0
I've been searching for a solution for quite some time as I usually don't need to post nor want to take up people's time. I'm attempting to use the external script file so I can easily see what I'm coding, however, I realise the three argument rule, which is unfortunate as I don't fully understand them. I've been trying to basically nullify them and continue with the subroutines that are being called by triggers. Here is my problem:

These subroutines are being called by triggers which fire at the entrance of a creature that I'd like to kill.

Quote:
Sub target_pincher (name, line, wildcards)
name = CInt(world.GetVariable ("TestVar"))
line = CInt(world.GetVariable ("TestVar"))
wildcards = CInt(world.GetVariable ("TestVar"))

If name = 0 then
End if
If line = 0 then
End if
If wilcards = 0 then
End if

world.DoAfterSpecial 1, "world.SetVariable ""Pincher"", CInt (world.GetVariable (""Pincher"")) + 1", 12
world.DoAfterSpecial 1, "Call pincher_action", 12
End Sub

Sub pincher_action (Balance_check, Pincher_count, Success_check)
Balance_check = CInt(world.GetVariable ("BalCheck"))
Pincher_count = CInt(world.GetVariable ("Pincher"))
Success_check = CInt(world.GetVariable ("TestVar"))

If CInt(Balance_check) = 0 then
If CInt(Pincher_count) > 0 then
world.send "claw pincher"
world.send "claw pincher"
Else
End if
Else
End if

If Success_check = 0 then
world.Note "Success"
End if
End sub


I keep getting the error about invalid property assignment and arguments are mentioned.

Could someone please provide some advice?
Australia Forum Administrator #1
Quote:

I realise the three argument rule, which is unfortunate as I don't fully understand them


I see what you are doing here. :)

The 3-argument rule simply applies when MUSHclient calls your script file in response to a trigger or alias firing. Internally it assembles 3 arguments:

  1. Name of the trigger/alias
  2. The matching line, in full
  3. An array of the matching wildcards, if any


Then it calls your script. Some languages, like VBscript, insist on argument-number matching, and thus you get an error if the script function does not have exactly three arguments. Lua on the other hand is more flexible, if you chose to use that.

Now let's look at your script, I'll number the lines to make it easier:


 1: Sub target_pincher (name, line, wildcards)
 2: name = CInt(world.GetVariable ("TestVar"))
 3: line = CInt(world.GetVariable ("TestVar"))
 4: wildcards = CInt(world.GetVariable ("TestVar"))
 5: 
 6: If name = 0 then
 7: End if
 8: If line = 0 then
 9: End if
10: If wilcards = 0 then
11: End if
12: 
13: world.DoAfterSpecial 1, "world.SetVariable ""Pincher"", CInt (world.GetVariable (""Pincher"")) + 1", 12
14: world.DoAfterSpecial 1, "Call pincher_action", 12
15: End Sub


Line 1 is fine - you have your trigger which has 3 arguments, as required.

I'm not sure about lines 2, 3, 4 - why are you getting the same variable and assigning it to the arguments? They already have the name of the trigger, the matching line, and the wildcards, as I described.

Lines 6 to 10 seem to have some pointless "if" statements. You are testing something and then doing nothing with the results. That is, nothing between the "if" and "end if".

Also, you misspelt "wilcards" on line 10.

Lines 13 and 14 seem to be adding 1 to the variable Pincher, and then calling a subroutine that you want to process the action. You are doing that after a second for some reason. Is there a reason it can't be done straight away?

Line 14 seems to introduce the real problem - after a second you "Call pincher_action" - OK so far so good - you are calling the function pincher_action with no arguments. There is nothing wrong with that. But later on you declare pincher_action with three arguments like this:


Sub pincher_action (Balance_check, Pincher_count, Success_check)


This call will fail because you did not call it with 3 arguments.

Let's see if we can simplify it a bit. The first sub, which is called by the trigger itself, can look like this:


Sub target_pincher (name, line, wildcards)

  DoAfterSpecial 1, "SetVariable ""Pincher"", CInt (GetVariable (""Pincher"")) + 1", 12
  DoAfterSpecial 1, "Call pincher_action", 12

  End Sub


However even here there are problems. When you use DoAfterSpecial it adds something to the internal timer queue. There is no guarantee that timers for a particular time (eg. in 1 second) will fire in the sequence they are added, so it might call pincher_action first and then add 1 to Pincher variable. A better way would be:


Sub target_pincher (name, line, wildcards)

  DoAfterSpecial 1, "SetVariable ""Pincher"", CInt (GetVariable (""Pincher"")) + 1", 12
  DoAfterSpecial 1.5, "Call pincher_action", 12

  End Sub


Note the extra 0.5 second delay.

However, why bother with timers? Why not do it immediately, like this:


Sub target_pincher (name, line, wildcards)

  SetVariable "Pincher", CInt (GetVariable ("Pincher")) + 1
  Call pincher_action

  End Sub


Isn't that much simpler?

Now as we have pincher_action being called with no arguments, we need to modify the way that is written too:



Sub pincher_action

Balance_check = CInt(GetVariable ("BalCheck"))
Pincher_count = CInt(GetVariable ("Pincher"))
Success_check = CInt(GetVariable ("TestVar"))

If Balance_check = 0 then
  If Pincher_count > 0 then
    Send "claw pincher"
    Send "claw pincher"
  End if
End if

If Success_check = 0 then
  Note "Success"
End if

End sub


The first line now has no arguments, as you are not calling it with any.

The next 3 lines are the same as you had.

The "if" checks don't need to do CInt again - that is "Convert to Integer" which you have already done once, you don't need to do it again.

You don't need an "Else" if there is nothing after the Else, that is just confusing.

I am not sure what Success_check is all about, but I left that there.

If you are just starting out with VBscript, and it looks like you are, I recommend using Lua. The whole thing would look similar in Lua, and a lot of people on the forums these days are using it. Plus Lua comes with some extra utilities, and has some fancier features for more complex scripting.

Converted to Lua, your revised script would look like:


function target_pincher (name, line, wildcards)

  SetVariable ("Pincher", tonumber (GetVariable ("Pincher")) + 1)
  pincher_action ()

end -- function target_pincher

function pincher_action ()

Balance_check = tonumber (GetVariable ("BalCheck"))
Pincher_count = tonumber (GetVariable ("Pincher"))
Success_check = tonumber (GetVariable ("TestVar"))

if Balance_check == 0 then
  if Pincher_count > 0 then
    Send "claw pincher"
    Send "claw pincher"
  end -- if
end -- if

if Success_check == 0 then
  Note "Success"
end -- if

end -- function pincher_action 


Looks similar doesn't it? But in Lua the 3 argument rule is not needed so you could drop the 3 unused arguments from the first function, like this:


function target_pincher ()

  SetVariable ("Pincher", tonumber (GetVariable ("Pincher")) + 1)
  pincher_action ()

end -- function target_pincher


Also Lua realizes that to add you must have numbers, so you don't need to convert to a number, making it simpler again:


function target_pincher ()

  SetVariable ("Pincher", GetVariable ("Pincher") + 1)
  pincher_action ()

end -- function target_pincher