Lords Lady Script Language Odds & Ends  - 13 Apr/02
---------------------------------------------------

by Gordon Lewicky, Sysop - Milky Way, 1:153/307

These quirks are found using Lord v4.07, 31 Mar/02 but any
commands/vars are from previous Lords. This supports v4.05 & up. 


After playing around with the script language for awhile I came up
with these odds & ends or quirks.

    *** Note *** #1 has been fixed in later beta versions

1 - &Pvar containing numerical values (eg. &Pex is xp pts.) can not
    be used as the source value in a "@set &N<num> to <num>" command. 
    You think you would be able to use "@set &N1 to &Pex"  but you can't
    N1 will always be 0 because &Pex does not parse to it's numerical
    value in a @set command.

    It does parse to it's numerical value in an @math or a @if
    and of course in any @writeln or within @display

    If you need a &Pvar numerical value to be in a &Nvar then
    use the @math statement to put it into the &Nvar by adding zero
    to the &Pvar. eg. "@math &N1 = &Pex + 0"  Now you have whatever
    the number of hit pts is, in the &N1 var. Play with it in there,
    and then reset the &Pex var to the new value you want with
    "@set &Pex to &N1"  This is the only way to alter the &P value without
    having to do multiple increments using the mail codes.

    Also, for some reason you can't @set a &Nvar to a &Nvar.
    Nvars can only be @set to a number. If you need 2 &Nvars to be
    identical, then use the @math and just add 0. 
    eg. @math &N3 = &N2 + 0 is the only way to make them equal.

    Now Pvars can be @set to &Nvars and also @set to other &Pvars of
    the same type. In otherwords, a &Pvar containing a numerical value
    can be set to another &Pvar containg a number and of course a &Nvar
    which does contain a number.

    The only &Pvars that can be set are the numerical ones.

    &Pvars containing text can't be set, but so far there are only 3
    of these, married to name, weapon and armor names as per v4.07

2 - I've found that the if.. then statements don't work if you use
    them within a case or a num id'ed if. When they are stand alone
    they will work. But as soon as a num id is used and the if is
    nested within it, then you MUST use an if <whatever> <num id>

    They will work stand alone if you use:

                        @if <whatever> then
                          @begin
                          @whatever
                          @end
                        @endif

    However, if you always use @if <whatever> <num id> with @begin,
    and whatever, and @end, and @endif <numid> structure, they
    will always work, regardless of whether they are nested or
    stand alone.

    eg. @if &N1 > &N2 1
          @begin
          @set &N3 to &N4
          @end
         @endif 1

    The above will always work whether there is a single statement or
    multiple statements between the @begin and @end lines. And if you
    are nesting if's, make the nested ifs using the same structure.
    If there is a @else then be sure to surround those statements inside
    the else with @begin and @end. Also don't forget to bump the num id
    per each if.

    A complicated nested if else would look like

    @if &N1 = &N2 1
      @begin
        @if &N3 > &N4 2 
          @begin
          @set &N5 to 1
          @math &N6 = &N1 - &N3        
          @end
        @endif 2
      @end
    @else
      @begin
        @set &N5 to 0
        @math &N6 = &N1 - &N4
      @end
    @endif 1

    This would always work, as far as the if's go. Haven't got a clue
    if N6 is what you wanted tho! ;)

    Insert as many nested if's or if elses as you want, up to 255 of them,
    and even cases or combos thereof, but make sure the id num is bumped
    up one each time, and always surround within, with the @begin & @end.

    *** NOTE WELL ***

    When nesting, you can't have any commands after the nested
    @endif other then the sequence of @end's and @endif's.

    Once the deepest nest ends, the whole nest structure exits all
    the way back to the originating mother, be it a case or an if.

    You can have commands within an if, and before the next nest,
    but you cannot have any following the nested if or case.

    Other languages will always exit an nested condition to the next
    line after the end of that condition, and allow you to do more
    after that end of condition, before exitting, and so on, until all
    conditions are ended. Lady does not allow this. Once the last
    child is done, it closes the starting mother.

    *** END OF NOTE WELL ***

    Personally, I try to stay away from nested if's cuz after 2 or 3 of them,
    I get lost and they just get to hard to figure out why and what all the 
    conditions were meant to do. :) 

    If there are a lot of conditions on any one var to be tested, then make 
    a flag var. Then test each condition in it's own if and set the value in
    the flag var appropriately. Say, make the flag var &N40 and then @set
    it to 0 at the start. Then for each condition set it up 1. You might end
    up with the flag var &N40 being anything from 0 thru to 5 according to
    the tests  made on &N1. For example there are 3 math comparisons with a
    Nvar ( =, <, > ). To test this in an if else you would need nesting.
    But if you tested each condition separately, then you could make N40
    be 1 for =, be 2 for < and be 3 for >

    Then you could use the @case to do what is neccessary for each condition
    should it occur eg.

    if N1 is equal to N2 then set N40 to 1
    if N1 is less then N2 then set N40 to 2
    if N1 is greater then N2 then set N40 to 3

    then use

    @case &N40 1
    1: stuff
    2: stuff
    3: stuff
    @endcase 1

    This to me, is a far better way and a lot easier to follow for
    complicated or multiple condition tests. Of course, this method is
    not just restricted to numerical vars. You could use it for text vars
    as well.

3 - Random numbers. Are they really random? Not in this script language
    at least. :)
    
    I recently wanted to generate 3 different random numbers and use 2 of
    them for a product with the third as a chance test. Naturally I tried
    this:

    @set &N1 to &rnd10 
    @set &N2 to &rnd10 
    @set &N3 to &rnd10 

    Then I was gonna do a @math &N4 = N1 * N2 to get some really random num
    bewteen 0 and 100 and then use N3 as a single chance by saying if N3 is 7
    then award the N4 value, and if N3 wasn't 7 then kill him. :)

    Seems reasonable doesn't it? Well it sure didn't work, because most of
    the time, N1 and N2 were the same, and N3 was usually 1 less, when it
    wasn't the same as N1 & N2

    I was constantly getting 8 8 7, or 5 5 4, or 3 3 2, and now and
    again all 3 would be the same. But never was N1 and N2 not identical.
    Sure the nums would be somewhere in the range of 0 to 10 but the
    pattern remained.

    So, I played around a bit more by changing the rnd<num> and found that
    when you create random nums within the same event, then the best way is
    to alter the number of chars possible per each try.

    I finally had to settle on rnd5, rnd20, rnd9. This made the first always
    only 1 num long, the second up to 2 nums long and the third up to 2 nums
    but at a lower range as well. Doing it this way, I truly got all 3 nums
    to be random, and it was hard to get any 2 to be identical, let alone
    all 3, even tho all 3 had overlapping ranges, being the 0 thru 5 of the
    first random range. It's probaly some sort of  memory addressing thing,
    but if you have more then one random generator in an event, this is the
    only way the results will be truly random. It didn't matter whether the
    lines were together or separated by lots of other statements, and even
    separated by labelled routines, the pattern always remained the same
    when the same range value was used in the @rnd. 

    Below are results using 4.07B pre & post random number generator fix,
    as well as the same thing done using a C++ routine.

    The lady script for testing random nums is count.ldy and
    the C++ routine is count.exe with code in count.cpp

    I'm showing these as an example of why I don't think the lady
    script engine really generates random numbers. The 2 scripts
    and the C++ routine were all done on the same Intel P3-550.

    The summary of the 3 results is as follows for doing
    a loop of ten, ten times.

    Generated       0   1  2   3   4   5   6   7   8   9

    Post fix        0  16  8  10   0  14  24  12  14   0
    Pre fix         0  10  6  22  12  28  13   9   0   0
    C++            13   9  9  13   8   8   8  13   9  10

    As you can see, for generating 100 numbers, using the lady
    script, 3 numbers are skipped in both pre and post and
    tend to concentrate heavily on 2 numbers. While the C++
    routine is pretty much spread out over the whole range and
    no numbers are skipped.

    But more importantly, looking at the results below, you'll see
    that with the lady script, in either pre or post, for a single
    loop of generating 10 nums in a row, it only generates at best
    2 numbers and is fairly consistant at returning either the same
    num half the time, or the same 2 nums the other half.

    Whereas, in the C++ routine, it varies from skipping 2 to 5 nums
    in a single loop of 10, but the other 5 to 8 nums are fairly well
    dispursed over the range. And doing the loop 10 times, no one
    number is left out.

    Here are the individual loops of 10, run 10 times, for pre, post and C++

    Using Lord 4.07 before the random num fix
                                                |  Totals
    n1 = 10  n1 = 0   n1 = 0   n1 = 0   n1 = 0  |  1 = 16
    n2 = 0   n2 = 0   n2 = 0   n2 = 0   n2 = 0  |  2 =  8
    n3 = 0   n3 = 0   n3 = 0   n3 = 0   n3 = 0  |  3 = 10
    n4 = 0   n4 = 0   n4 = 0   n4 = 0   n4 = 0  |  4 =  0
    n5 = 0   n5 = 0   n5 = 0   n5 = 4   n5 = 0  |  5 = 14
    n6 = 0   n6 = 0   n6 = 8   n6 = 6   n6 = 0  |  6 = 24
    n7 = 0   n7 = 0   n7 = 2   n7 = 0   n7 = 10 |  7 = 12
    n8 = 0   n8 = 10  n8 = 0   n8 = 0   n8 = 0  |  8 = 14
    n9 = 0   n9 = 0   n9 = 0   n9 = 0   n9 = 0  |  9 =  0
    n0 = 0   n0 = 0   n0 = 0   n0 = 0   n0 = 0  |  0 =  0
                                                      ---
                                                      100

    n1 = 0   n1 = 0   n1 = 6   n1 = 0   n1 = 0
    n2 = 4   n2 = 0   n2 = 4   n2 = 0   n2 = 0
    n3 = 6   n3 = 0   n3 = 0   n3 = 0   n3 = 4
    n4 = 0   n4 = 0   n4 = 0   n4 = 0   n4 = 0
    n5 = 0   n5 = 0   n5 = 0   n5 = 10  n5 = 0
    n6 = 0   n6 = 10  n6 = 0   n6 = 0   n6 = 0
    n7 = 0   n7 = 0   n7 = 0   n7 = 0   n7 = 0
    n8 = 0   n8 = 0   n8 = 0   n8 = 0   n8 = 6
    n9 = 0   n9 = 0   n9 = 0   n9 = 0   n9 = 0
    n0 = 0   n0 = 0   n0 = 0   n0 = 0   n0 = 0

    Using Lord 4.07 after the random num fix
                                                |  Totals
    n1 = 0   n1 = 0   n1 = 0   n1 = 0   n1 = 0  |  1 = 10
    n2 = 6   n2 = 0   n2 = 0   n2 = 0   n2 = 0  |  2 =  6
    n3 = 0   n3 = 0   n3 = 1   n3 = 1   n3 = 10 |  3 = 22
    n4 = 0   n4 = 2   n4 = 0   n4 = 0   n4 = 0  |  4 = 12
    n5 = 0   n5 = 8   n5 = 0   n5 = 0   n5 = 0  |  5 = 28
    n6 = 4   n6 = 0   n6 = 9   n6 = 0   n6 = 0  |  6 = 13
    n7 = 0   n7 = 0   n7 = 0   n7 = 9   n7 = 0  |  7 =  9
    n8 = 0   n8 = 0   n8 = 0   n8 = 0   n8 = 0  |  8 =  0
    n9 = 0   n9 = 0   n9 = 0   n9 = 0   n9 = 0  |  9 =  0
    n0 = 0   n0 = 0   n0 = 0   n0 = 0   n0 = 0  |  0 =  0
                                                      ---
    n1 = 0   n1 = 0   n1 = 10  n1 = 0   n1 = 0        100
    n2 = 0   n2 = 0   n2 = 0   n2 = 0   n2 = 0
    n3 = 0   n3 = 0   n3 = 0   n3 = 10  n3 = 0
    n4 = 0   n4 = 0   n4 = 0   n4 = 0   n4 = 10
    n5 = 10  n5 = 10  n5 = 0   n5 = 0   n5 = 0
    n6 = 0   n6 = 0   n6 = 0   n6 = 0   n6 = 0
    n7 = 0   n7 = 0   n7 = 0   n7 = 0   n7 = 0
    n8 = 0   n8 = 0   n8 = 0   n8 = 0   n8 = 0
    n9 = 0   n9 = 0   n9 = 0   n9 = 0   n9 = 0
    n0 = 0   n0 = 0   n0 = 0   n0 = 0   n0 = 0

    Using C++

    executing count.exe 10 times
    count.exe generates a number between 0-9 ten times

    n0=0 n1=2 n2=1 n3=1 n4=1 n5=2 n6=1 n7=1 n8=1 n9=0
    n0=2 n1=0 n2=0 n3=3 n4=1 n5=0 n6=0 n7=0 n8=2 n9=2
    n0=1 n1=0 n2=1 n3=2 n4=1 n5=0 n6=1 n7=0 n8=2 n9=2
    n0=3 n1=0 n2=1 n3=0 n4=1 n5=0 n6=2 n7=1 n8=1 n9=1
    n0=3 n1=1 n2=1 n3=1 n4=0 n5=3 n6=0 n7=0 n8=0 n9=1
    n0=1 n1=3 n2=1 n3=3 n4=0 n5=0 n6=0 n7=1 n8=0 n9=1
    n0=1 n1=1 n2=0 n3=1 n4=0 n5=0 n6=0 n7=4 n8=2 n9=1
    n0=2 n1=1 n2=0 n3=0 n4=1 n5=2 n6=0 n7=1 n8=1 n9=2
    n0=0 n1=1 n2=2 n3=1 n4=1 n5=1 n6=0 n7=4 n8=0 n9=0
    n0=0 n1=0 n2=2 n3=1 n4=2 n5=0 n6=4 n7=1 n8=0 n9=0
    ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
      13    9    9   13    8    8    8   13    9   10   Total = 100

    amount each n(0-9) is generated in 100 attempts

    I've included both the lady script for this random number
    tester (count.ldy) as well as the source and exe for the
    C++ routine (count.cpp & count.exe) within the zip including
    this file.

4 - When displaying or writelining, if you are trying to change the color
    of a var make sure that you do not tightly surround it, if only the
    var is to be in the separate color.

    If you use "`0&N1`2 stuff" then the engine isn't able to separate out
    the var and you usually get a large number displayed instead. The value
    of the var doesn't change, only what is displayed.

    Use "`0&N2 `2stuff". Leave that space after the var and this will make
    the var in it's own color and change the remaining text back to it's
    color.
    
    *** Apparently this is also fixed in later beta versions. ***

5 - Ahhh... the marvelous critters called string variable vars,
    found as &S<num>

    Lets see... you can set them, no problem. You can do a boolean
    test on them, no problem either. You can stipilate how many
    max chars in them, agian no problem.

    I suppose you could test one against the other as in
    @ if &S1 = &S2, never tried it, but that's a boolean so why bother. :)

    *** BUT *** for some cockamammy reason you CAN'T display them!!!
    In a display or writeln. Sheesh!!!

    I wanted to do an @if &Pho is true then set &S1 to got a horse
    or if not true the set &S1 to not got a horse.

    Of course I used the proper @if structure with all the @begin
    and @end, etc. and with or without a num id.

    Good idea but no joy! All you could see when you tried to
    display it or writeln it was &S1 and not what it was set too!

    Me thinks Michael will fix this one when he hears about it. :)

I guess that is about it for now. Newer 4.07 beta versions have
added a lot of new stuff, like read/writing to text files sews yew can
make anouncements in the lognow.txt or in the bar/darkbar/garden.txt
files, to announce your event happening. That's a nice feature! :)

There are a few more vars added as well and setting clean mode on
or off and adding a not equals to condition as well. Could have use
that one quite a few times! :)

I'll add more, if and when I find more lady quirks. But, then again,
"Everybody knows that ladies are quirky"! :P

Cheers...
