« Mob commands | Main | Prog debuggery »

mprogs

July 20, 2005

Control logic waltz - IF then ELSE then ENDIF

Logic, like whiskey, loses its beneficial effect when taken in too large quantities.

Lord Dunsany

The mprog interpretter is a fussy little beast, and if the code isn't precisely how it expects it, your mprog will not run how you expect it to.

IF statements often throw people, as the syntax is not entirely consistant. Every IF needs to be partnered up with its ENDIF, or the mud will complain. If you do use an ELSE, ensure it's between the IF and the ENDIF and not outside. You do need to keep track of how many you've used, in particular when you nest IF statements (stack one inside another).

The basic flow logic of the if command is (though this is not the syntax):
IF (the condition) is true
then do this code
ELSE
do this code
ENDIF

Rot being rot, things are not quite so simple, and in this case the (condition) varies quite a bit depending on what you wish to test.

Before introducing all of the options and things you can do these truth tests on, to begin with, lets take some very simple cases. We want our greeting goblin from before to only greet people under level 15, so we need a way to compare the character's level to a certain value. Happily, IF level compares the level of a character to a number. Operators determine what kind of comparison will be performed (equal to, less than, etc).

Here is the complete list of operators, with a few examples.


OpMeaningCode exampleExplanation
== is equal to, matches IF level $n == 15 (If the character is level 15)
!= Not Equal toIF level $n != 101 (If the character is not hero level)
> Greater thanIF level $n > 101 (If the character is a higher level than 101)
< Less thanIF level $n < 102 (If the character is below level 102)
>= Greater than or equal toIF level $n >= 102 (If the character is level 102 or greater)
<= Less than or equal toIF level $n <= 101 (If the character is level 101 or below)

So we can finally add some smarts to the greeting goblin, and he can now determine for himself who he wants to talk to, with the code looking like this:


IF level $n <= 15
say Hello, little man thing.
ENDIF

If, however, you want it to laugh at everyone over level 15 as well, you need the else statement. The else statement is still part of the IF, it needs to be nestled between the IF and ENDIF


IF level $n <= 15
say Hello there, newbie.
ELSE
snicker $n
ENDIF

This also means the goblin will laugh at immortals, which does not bode well for its survival.

To extend the program above further, to laugh at everyone over level 15 but not immortals, you have to nest one if statements inside the other. This can be hard to follow, as an aid, the if statements are colour coded. You will see that the first endif closed the most recent if statement.


IF level $n <= 15
say Hello there, newbie.
ELSE
IF level $n >= 102
say Deus ex machina!
ELSE
snicker $n
ENDIF

say Perhaps you should reroll if you want me to talk to you?
ENDIF

There are three other ways to control the execution of mprogs, and they are BREAK, OR and AND. BREAK very simply stops the current mprog running in its tracks. It bails out. This can be useful if you just want a program to exclude certain people.


IF level $n <= 15
BREAK
ENDIF
....

The code above will bail out if the target is under level 16, or continue if they are 16 or over.

OR and AND are used in very similar ways and are extended parts of the IF statement. Their syntax is the same as an IF statement, and they must immediately follows the line with the IF.


IF (condition 1)
AND (condition 2)
[some code]
ENDIF

Both conditions must be true for the code to run.

If you wanted to test if an object had a vnum between 100 and 200 (from the Feline village), you'd have to nest two if statements like this:


IF vnum $o >= 100
IF vnum $o < 200
SAY Yes, it's from the Feline Village, all right.
ENDIF
ENDIF

Which works perfectly well, but looks a little messy. Using the AND statement, you can eliminate one of the IF/ENDIF pairs.

IF vnum $o >= 100
AND vnum $o < 200
SAY Yes, it's from the Feline Village, all right.
ENDIF

The OR statement is very much the same, though more useful. At least one condition must be true for the code to execute. Without an OR statement, the code can be repetitive, and quickly becomes nightmarish if you want to add an ELSE.

IF objtype $o wand
SAY Yessir, staves and wands, that's what I buy.
ELSE
IF objtype $o staff
SAY Yessir, staves and wands, that's what I buy.
ELSE
SAY Nosir, I don't buy those.
ENDIF
ENDIF

However, with the OR statement, it's quite simple to add an ELSE statement.

IF objtype $o wand
OR objtype $o staff
SAY Yessir, staves and wands, that's what I buy.
ELSE
SAY Nosir, I don't buy those.
ENDIF

The table below contains all the conditions that can be tested, with a short definition and example for each one.

IF … Argument Definition/Code
Rand 0 to 99 [example] Percentage chance of being true.

[definition]
IF rand 50
SAY Heads!
ELSE
SAY Tails!
ENDIF

Objhere <name/vnum> [example] Is the object (by vnum or name) in the room? Note: The object needs to be on the floor. It will not detect objects that are carried or in pits/containers. If you use a name and not a vnum, use one word only , do not use ' marks

[definition]
IF objhere 21298
SAY That is one powerful weapon there!
GET ultimate
WEAR ultimate
CACKLE
ENDIF

Mobexists <name> [example] Does a mob or PC with this name exist anywhere? Note: One word only , do not use ' marks'

[definition]
IF mobexists whitewhale
SAY So ye seek the white whale. This be luck, lad. Call me Ishmael.
ELSE
SAY Corsets and soap, lad. Corsets and soap.
ENDIF

Mobhere <name/vnum> [example] Is the mob (by vnum or name) or PC (by name) in the room. Note: If you use a name and not a vnum, use one word only , do not use ' marks

[definition]
IF mobhere whitewhale
SAY Thar she blows!
ELSE
SAY Back to the crows nest, lad.
ENDIF

Objexists <name> [example] Does the object with this name exist anywhere? Note: One word only , do not use ' marks'

[definition]
IF objexists 21298
SAY Yes, there is an ultimate weapon. Somewhere.
ENDIF

People Op. <num> [example] Compares the number to the count of visible NPCs/PCs in the room (always excludes the mob running the prog)

[definition]
IF people == 4
SAY Four people, for I never count myself.
ENDIF

Players Op. <num> [example] Compares the number to the count of visible PCs in the room

[definition]
IF players > 1
SAY You know what they say, two's company.
ENDIF

Mobs Op. <num> [example] Compares the number to the count of visible NPCs in the room (always excludes the mob running the prog)

[definition]
IF mobs == 4
SAY We could form a quintet!
ENDIF

Clones Op. <num> [example] Compares the number to the count of visible NPCs with the same vnum as the mob running the program (always excludes the mob running the prog)

[definition]
IF clones == 2
SAY We are now three.
ENDIF

Order Op. [example]

Researching

[definition]

Hour Op. <num> [example] Compares the number to the current hour (0=midnight to 23=11pm)

[definition]
IF hour == 0
SAY It's midnight and all's well that ends well. Go to bed already you slackers.
ENDIF
IF hour == 1
SAY It's 1 A.M. on the streets of Kjeldoran and the rats are out, grab yer slingshots and stones.
ENDIF
IF hour == 2
SAY It's 2 A.M. and the thieves are culling the unwary, step lively, do not tary.
ENDIF
IF hour == 23
SAY It's 11 P.M. and the cats are serenading each other from the fences, throw a shoe.
ENDIF

Ispc $_ [example] Is $_ a player?

[definition]
IF ispc $n
SAY You're not like the other mobs.
ENDIF

Isnpc $_ [example] Is $_ a mob?

[definition]
IF isnpc $n
SAY You're just like all the other mobs.
ENDIF

Isgood $_ [example] Is $_ good? (alignment 350 or over)

[definition]
IF isgood $n
SAY It is not enough to have a good mind; the main thing is to use it well.
ENDIF

Isevil $_ [example] Is $_ evil? (alignment -350 or less)

[definition]
IF isevil $n
SAY Work is a necessary evil to be avoided.
ENDIF

Isneutral $_ [example] Is $_ neutral? (alignment between 350 and -350)

[definition]
IF isneutral $n
SAY In truth, the world is neither with us or against us; it is but raw material in our hands, and can be heaven or hell according to what we are.
ENDIF

Isimmort $_ [example] Is $_ an immortal? (Level 102 or above)

[definition]
IF isimmort $n
SAY Before me things create were none, save things
SAY Eternal, and eternal I shall endure.
ENDIF

Ischarm $_ [example] Is $_ charmed?

[definition]
IF ischarm $n
SAY All charming people have something to conceal.
ENDIF

Isfollow $_ [example] Is $_ following anyone?

[definition]
IF isfollow $n
SAY All Now far ahead the Road has gone. And you must follow.
ENDIF

Isactive $_ [example] Is $_ in a position other than sleeping (awake, sitting, resting, standing, stunned)

[definition]
IF isactive $n
SAY You can trouble me for a warm glass of shut-the-hell-up. Now, you will go to sleep or I will put you to sleep. Check out the name tag. You're in my world now.
MOB FORCE $n sleep
ENDIF

Isdelay $_ [example] Does $_ have a delayed mprog pending? (see MOB DELAY and addmprog)

[definition]
IF isdelay $i
SAY You know, I don't think I'll do that anymore.
MOB CANCEL
ENDIF

Isvisible $_ [example] Is $_ visible to the mob?

[definition]
IF isvisible $n
SAY I can see you!
ELSE
SAY Damnit, I know you're here somewhere.
ENDIF

Hastarget $_ [example] Does $_ remember someone? (used with MOB REMEMBER)

[definition]
IF hastarget $i
SAY Yes, I remember $q.
ENDIF

Istarget $_ $_ [example] Is $_ the mob's target? (IF istarget $n would reveal if the mob remembers the one who triggers the mprog)

[definition]
IF istarget $n
SAY $Q! Of course I remember you.
ELSE
SAY Yes, of course. We met…
COUGH
ENDIF

Exists $_ [example]

Not working

This command is redundant, as there is IF objexists and IF mobexists.

[definition]

Affected $_ <spell> [example] Is $_ affected by the spell specified?

[definition]
IF affected $n bless
SAY You are truly blest.
ENDIF

Imm $_ <imm> [example] Is $_ immune to <imm>? (Only one immunity may be checked at a time)

[definition]
IF imm $n fire
SAY I hate you hot weather people.
ELSE
SAY Flame on!
MOB CAST flamestrike $n
ENDIF

Act $_ <flag> [example] Does $_ have the act flag specified? Act flags can be seen in medit with ? Act

[definition]
IF act $n aggressive
SAY Fiesty little one, aren't we.
ENDIF

Off $_ <flag> [example] Does $_ have the offensive flag specified? Off flags can be seen in medit with ? off

[definition]
IF off $n area_attack
SAY I bet you could flatten the whole room.
ENDIF

Carries $_ <name/vnum> [example] Is $_ carrying the object referred to by name or vnum?

[definition]
IF carries $n 59
SAY My pocket watch! The time! I must go. Tea party.
ENDIF

Wears $_ <name/vnum> [example] Is $_ wearing the object referred to by name or vnum?

[definition]
IF wears $n ultimate
SAY Mind you keep the sharp end of that away from me.
ENDIF

Has $_ <type> [example] Does $_ have an item of that type?

[definition]
IF has $n drinkcontainer
SAY Ye wouldn't have any rum in that there bottle for an old sea dog, would ye?
ENDIF

Uses $_ <type> [example] Is $_ wearing an item of that type? (armor/sword/etc) Note: IF wears is for specific items (by vnum/name)

[definition]
IF uses $n armor
SAY I see you have some armour already. But none so fine as my wares!
ENDIF

Name $_ <name> [example] Do $_ and the name match? Note: The name must be typed in - you cannot use a second $_ value.

[definition]
IF name $n Meathe
SAY Trust not my reading nor my observations,
SAY Which with experimental seal doth warrant
PONDER
SAY Much ado about nothing, I think.
ENDIF

Pos $_ <pos> [example] Is $_ in the position of <pos>? (standing, sleeping, resting, etc)

[definition]
IF hastarget $i
MOB FORGET $q
ENDIF
MOB REMEMBER $r
IF pos $q sleeping
SAY Ah, the children of the night. What beautiful music they make.
MOB ECHOAROUND $q $i plunges $l fangs into the bare neck of $q.
MOB ECHOAT $q You feel a sudden warmness, followed quickly by a chill you cannot explain.
MOB DAMAGE $q 1000 3000 lethal
ENDIF

Clan $_ <clan> [example] Is $_ in this clan?

[definition]
IF clan $n tabernacle
SAY Welcome to the narthex, friend.
ELSE
MOB ZECHO $I's screams echo through the halls. '{rAlarums! Divers alarums!{x'
MOB KILL $n
ENDIF

Race $_ <race> [example] Is $_ of this race?

[definition]
IF race $n seal
SAY Now you just slipped that one in. There isn't a seal race.
ELSE
SAY I knew there wasn't a race of seals.
ENDIF

Class $_ <class> [example] Is $_ of this class?

[definition]
IF class $n demon
SAY Exorcizo te, omnis spiritus immunde, in nomine Dei
MOB TRANSFER $n 1
ENDIF

Objtype $_ <type> [example] Is $_ an object of the type?

[definition]
IF objtype $o staff
SAY Yes, it is here...This means six kadams high.
SAY And take back one kadam to honor the Hebrew God whose Ark this is.
MOB FORCE $n say You said their headpiece only had markings on one side. Are you absolutely sure?
NOD
MOB FORCE $n SAY They're digging in the wrong place!
MOB FORCE $n laugh
ENDIF

Ismaster $_ [example] Is $_ the master/owner of the mob/object running the prog?

[definition]
IF ismaster $n
SAY What is thy bidding, my master?
ENDIF

Ispk $_ [example] Is $_ PK?

[definition]
IF ispk $n
SAY Welcome to the lounge, $n.
ELSE
SAY Killers and freaks only.
MOB BLOCK $n
ENDIF

Isnpk $_ [example] Is $_ NPK?

[definition]
IF isnpk $n
SAY Killers and freaks only.
MOB BLOCK $n
ELSE
SAY Welcome to the lounge, $n.
ENDIF

Age $_ Op. <age> [example] Is $_ (older/younger/equal) to the age specified?

[definition]
IF age $n < 100
SAY This is the Legends bar. You may not enter.
MOB BLOCK $n
ENDIF

Vnum $_ Op. <vnum> [example] Is $_ (higher/lower/this) vnum?

[definition]
IF vnum $o >= 100
IF vnum $o < 200
SAY Yes, it's from the Feline Village, all right.
ENDIF
ENDIF

[Using the AND logic]

IF vnum $o >= 100
AND vnum $o < 200
SAY Yes, it's from the Feline Village, all right.
ENDIF

Hpcnt $_ Op. <%> [example] Are $_'s HP at more than %?

[definition]
IF hpcnt $n <= 10
SAY You have fought well, Knight.
MOB FLEE
ENDIF

Room $_ Op. <vnum> [example] Is $_ in a room with a vnum (equal/less/greater) than <vnum>?

[definition]
IF room $n <= 100
SAY You are in the realms of limbo. No life. No death.
ENDIF

Sex $_ Op. <sex> [example] Is $_ (equal/less/more) than sex? (0=neuter, 1=male, 2=female, -1=?)

[definition]
IF sex $n < 2
SAY I knew you were lesser.
ENDIF

Level $_ Op. <level> [example] Is $_ (equal/higher/lower) than level?

[definition]
IF level $n < 101
SAY Heros only.
MOB BLOCK $n
ENDIF

Align $_ Op. <align> [example] Is $_ (more/less/equal) to this alignment?

[definition]
IF align $n > 900
SAY You've been very, very good.
ELSE
IF isgood $N
SAY You've been good this year.
ELSE
SAY Coal in your stocking, $n
ENDIF
ENDIF

Money $_ Op. <amount> [example] Does $_ have (more/less/this) platinum amount? Amount calculated to be: platinum + (gold/100) + (silver /100000)

[definition]
IF money $n <= 10
SAY You sad assed bastard.
ENDIF

Objval0 $_ Op. <num> [example] Is the item $_'s value0 (greater/equal/less than)this amount?

[definition]
IF objtype $o wand
AND objval0 $o < 101
SAY Yes, it's a wand, but it's hardly hero material, is it?
ENDIF

Objval1 $_ Op. <num> [example] Is the item $_'s value1 (greater/equal/less than)this amount?

[definition]
IF objtype $o wand
AND objval1 $o < 5
SAY Yes, it's a wand, but There's no life left in it. I'm afraid it's valueless.
ENDIF

Objval2 $_ Op. <num> [example] Is the item $_'s value2 (greater/equal/less than)this amount?

[definition]
IF objtype $o container
AND objval2 $o == 0
SAY It's a nice $O, but it's harldly secure. There's no lock.
ENDIF

Objval3 $_ Op. <num> [example] Is the item $_'s value3 (greater/equal/less than)this amount?

[definition]
IF objtype $o portal
AND objval3 $o == 22598
SAY Surely, that will take you straight to failure.
ENDIF

Objval4 $_ Op. <num> [example] Is the item $_'s value4 (greater/equal/less than)this amount?

[definition]
IF objtype $o container
AND objval4 $o <= 50
SAY Must make things seem half their weight.
ENDIF

Grpsize $_ Op. <num> [example] Is $n's group (greater/less than/equal to) num?

[definition]
IF grpsize $n < 5
SAY You're going to need a bigger boat
mob block $n
ENDIF

Scrawled illegibly by Meathe at July 20, 2005 04:33 PM

Comments

Excellent job on all of these tutorials. They are most productive and helpful as a resource. Thanks for the assistance! :)

Posted by: Navarre at July 21, 2005 10:40 PM