OLC

Variables

To make things come alive, variables are needed. These are represented in the MOBprograms by using a dollar sign convention as in the socials. When the mud command is processed, these variables are expanded into the values shown below. Usually, it is best to use the short descriptions of mobiles and the names of players when speaking them, but if you are performing an action to someone almost always you want the name. The title field for players is an extra that probably wont often be used.

Without further hesitation… the variables:

$i the first of the names of the mobile itself.
$I the short description of the mobile itself.
$n the name of whomever caused the trigger to happen.
$N the name and title of whomever caused the trigger to happen.
$t the name of a secondary character target (i.e A smiles at B)
$T the short description, or name and title of target (NPC vs PC)
$r the name of a random char in the room with the mobile (never == $i)
$R the short description, or name and title of the random char

$j he,she,it based on sex of $i.
$e he,she,it based on sex of $n.
$E he,she,it based on sex of $t.
$J he,she,it based on sex of $r.

$k him,her,it based on sex of $i.
$m him,her,it based on sex of $n.
$M him,her,it based on sex of $t.
$K him,her,it based on sex of $r.

$l his,hers,its based on sex of $i.
$s his,hers,its based on sex of $n.
$S his,hers,its based on sex of $t.
$L his,hers,its based on sex of $r.

$o the first of the names of the primary object (i.e A drops B)
$O the short description of the primary object
$p the first of the names of the secondary object (i.e A puts B in C)
$P the short description of the secondary object

$a a,an based on first character of $o
$A a,an based on first character of $p

Also, in if_checks, the accepted variables are the basic ones (i,n,t,r,o,p). If a variable is referenced that doesnt exist, then the value is simply left blank. (i.e referring to $o when the trigger is: A kisses B)

The only problem with the variables is that the secondary object and the secondary target are passed by act() in the same location. This means that if you reference $t in an A puts B in C situation, the result will probably be a happy mud crash or some weird side effect, espescially if $t is used in an if_check (i.e. if isnpc($t) in the above situation) The basic fix for this is to change everyone who calls the act() procedure to specify a secondary object and a secondary character. But that is a fairly comprehensive trivial twiddle, so we left it the way it is so that, you arent forced to make all those twiddles to use the MOBprograms.


—————————Control Flow Syntax——————————

In place of any legal mud command in a MOBprogram, one can substitute a flow of control command. Here is the syntax for a flow of control command.

“if” ” ” {if_check_1} “(” {argument} “)” [ {operator} {value} ] NL
[ “or” ” ” {if_check_2} “(” {argument} “)” [ {operator} {value} ] NL ]
. . .
[ “or” ” ” {if_check_N} “(” {argument} “)” [ {operator} {value} ] NL ]

[ {program_command_1} NL ]
[ {program_command_2} NL ]
. . .
[ “break” NL ]
. . .
[ {program_command_N} NL ]

[ “else” NL ]

[ {program_command_1} NL ]
[ {program_command_2} NL ]
. . .
[ “break” NL ]
. . .
[ {program_command_N} NL ]

“endif” NL

Basically, it is: an ‘if’ line, followed by zero or more ‘or’ lines, followed by zero or more legal mud commands, which may contain a ‘break’ line, possibly followed by an ‘else’ line , followed by zero or more legal mud commands, which may contain a ‘break’ line, followed by an ‘endif’ line.

The only new syntax labels are all in the IF line:

–Explainations

An IF_CHECK is a string which describes under what context to compare things. The ARGUMENT is the reference point from which the LHS of an expression comes. The OPERATOR indicates how the LHS and RHS are going to be compared. The VALUE is the RHS of the expression to be compared by the operator.

The BREAK command bails out of the entire MOBprogram regardless of the level if nesting.

If that looks confusing, skip to the end of the document and review the Example. Hopefully that should clear things, otherwise you’ll probably have to give us a mail since examples are the best way we know to explain syntax.


——————————–Operators———————————–

Most of the basic numeric operators are legal and perform the same function as in C. The string operators are a bit more confusing. There are negative versions of some of the operators. These are not strictly needed, since the if/else construct of Control Flow commands can handle either case.

Numeric Operators: == != > < >= <= & | String Operators: == != / !/

For strings, == and != check for exact match between the two strings and the other two, / and !/ check to see if the second string is contained in the first one. This is so things like: if name($n) / guard will respond true to “guard” “cityguard” “guardian” etc. Using == on a name implies that you are matching the complete name “cityguard guard” or whatever. The string operators are case SENSITIVE.


————————If_Checks In Control Flow—————————

The provided list of if_checks and their arguments are below. They should all be fairly obvious in what they do, but some of the more obtuse deserve a slight explanation. Any ‘==’ operator can be replaced with any of the available ones described above. The argument ($*) refers to any of the variables which make sense for that if_check (i.e. for an if_check which is referencing a person the only valid variables would be $i, $n, $t or $r). A value type of string is a sequence of characters. It does not need to be included in quotes or anything like that (i.e. name($n)== orc large brown)

rand(num) Is a random percentage less than or equal to num
isnpc($*) Is $* an NPC
ispc($*) Is $* a PC
isgood($*) Does $* have a good alignment
isevil($*) Does $* have an evil alignment
isneutral($*) Does $* have a neutral alignment
align($*) == integer Is the alignment of $* equal to integer
isfight($*) Is $* fighting
isimmort($*) Is the level of $* greater than max_mortal
ischarmed($*) Is $* affected by charm
isfollow($*) Is $* a follower with their master in the room
isaffected($*) & integer Is ($*->affected_by & integer) true (person only)
hitprcnt($*) == percent Is the hit/max_hit of $* equal to percent
inroom($*) == integer Is the room of $* equal to integer (person only)
sex($*) == integer Is the sex of $* equal to integer
position($*) == integer Is the position of $* equal to integer
level($*) == integer Is the level of $* equal to integer
class($*) == integer Is the class of $* equal to integer
race($*) == integer Is the race of $* equal to integer
goldamt($*) == integer Does $* have a gold total equal to integer
objtype($*) == integer Is the type of $* equal to integer (armor,boat,etc)
objval#($*) == integer Is $*->value[#] equal to integer (# from 0-3)
number($*) == integer Is the vnum of $* equal to integer
name($*) == string Is the name of $* equal to string

SEX:
0 – neutral
1 – male
2 – female

POSITION:
0 – dead
1 – mortally wounded
2 – incapacitated
3 – stunned
4 – sleeping
5 – resting
6 – fighting
7 – standing

CLASS:
0 – Mage
1 – Cleric
2 – Thief
3 – Warrior
4 – Knight
5 – Ranger
6 – Sage
7 – Bard
8 – Druid
9 – Priest
10 – Assassin
11 – Psionist
12 – Necromancer
13 – Monk

RACE:
0 – Human
1 – Dwarf
2 – Elf
3 – Half-Elf
4 – Kender
5 – Gnome
6 – Half-Giant
7 – Half-Orc
8 – Draconian
9 – Shadow
10 – Sprite

OBJTYPE:
1 – light
2 – scroll
3 – wand
4 – staff
5 – weapon
8 – treasure
9 – armor
10 – potion
12 – furniture
13 – trash
15 – container
17 – drink container
18 – key
19 – food
20 – money
22 – boat
23 – corpse NPC
24 – corpse PC
25 – fountain
26 – pill

————————MOBCommands Of Interest—————————–

These are fairly basic things, most of them are wiz commands which have been changed to allow for mobiles to perform the commands. If you have the problem of immortals abusing these powers on your mud either ditch the immortals, or add a check in all of them to only let NPC’s with null descriptors do the commands. (However, you lose a little debugging help that way). MERC 2.2 has provided a little security feature against this but it is by no means com- prehensive. Please check yourself if you are concerned.

Here are the basic MOBcommands that we found to be enticing:

Syntax: MPSTAT <mobile>

Shows the MOBprograms which are set on the mob of the given name or vnum and some basic stats for the mobile

Syntax: MPASOUND <text_string>

Prints the text string to the rooms around the mobile in the same manner as a death cry. This is really useful for powerful aggressives and is also nice for wandering minstrels or mobiles like that in concept.

Syntax: MPJUNK <object>

Destroys the object refered to in the mobiles inven. It prints no message to the world and you can do things like junk all.bread or junk all. This is nice for having janitor mobiles clean out their inventory if they are carrying too much (have a MOBprogram trigger on the ‘full inventory’)

Syntax:
MPECHO <text_string>
MPECHOAT <victim> <text_string>
MPECHOAROUND <victim> <text_string>

Prints the text message to the room of the mobile. The three options let you tailor the message to goto victims or to do things sneaky like having a merchant do: mpat guard mpechoat guard rescue_please This coupled with a guard act_prog trigger on rescue_please to mpgoto $n and mpecho $I has arrived. It is an affective way of quickly bringing guards to the scene of an attack.

Syntax:
MPMLOAD <vnum>
MPOLOAD <vnum> <level>

Loads the obj/mobile into the inven/room of the mobile. Even if the item is non-takable, the mobile will receive it in the inventory. This lets a mobile distribute a quest item or load a key or something. Syntax: MPKILL <victim>

Lets a mobile kill a player without having to murder and be fifth level. Lots of MOBprograms end up with mpkill $n commands floating around. It works on both mobiles and players.

Syntax: MPPURGE [argument]

Destroys the argument from the room of the mobile. Without an argument the result is the cleansing of all NPC’s and items from the room with the exception of the mobile itself. However, mppurge $i will indeed purge the mobile, but it MUST be the last command the mobile tries to do, otherwise the mud cant reference the acting mobile trying to do the commands and bad things happen.

Syntax: MPGOTO <dest>

Moves the mobile to the room or mobile or object requested. It makes no message of its departure or of its entrance, so these must be supplied with mpecho commands if they are desired.

Syntax: MPAT <dest> <command>

Perfoms the command at the designated location. Very useful for doing magic slight of hand tricks that leave players dumbfounded.. such as metamorphing mobiles, or guard summoning, or corpse vanishing.

Syntax: MPTRANSFER <victim> [dest]

Sends the victim to the destination or to the room of the mobile as a default. If the victim is “all” then all the characters in the room of the mobile are transfered to the destination. Good for starting quests or things like that. There is no message given to the player that it has been transfered and the player doesnt do a look at the new room unless the mob forces them to. Immortals cannot be tranfered.

Syntax: MPFORCE <victim> <command>

Forces the victim to do the designated command. The victim is not told that they are forced, they just do the command so usually some mpecho message is nice. You can force players to remove belongings and give them to you, etc. The player sees the normal command messages (such as removing the item and giving it away in the above example) Again, if the victim is “all” then everyone in the mobiles room does the command. This cannot be used on immortals.

MOBprogram quick reference to triggers/variables/ifchecks/mobcommands

trigger argument and what must happen to activate trigger
—————————————————————————–
bribe_prog INTEGER amount of miminum gold amount given to mobile
entry_prog PERCENT chance to check when mobile moves to a new room
give_prog FULL OBJECT NAME or ALL to match when obj given to mobile
greet_prog PERCENT chance to check if visable char enters mobile’s room
all_greet_prog PERCENT chance to check when any char enters mobile’s room
fight_prog PERCENT chance to check at fight_pulse if mobile is fighting
hitprcnt_prog PERCENT lower than mobiles hit/max_hit if mobile is fighting
death_prog PERCENT chance to check after mobile has been slain
rand_prog PERCENT chance to check whenever a PC is in the mobiles zone
speech_prog WORDLIST or P WORD_PHRASE to match in dialogue to mobile

variable mobile actor victim random object 2nd_object
—————————————————————————–
name $i $n $t $r $o $p
shrt_desc/title $I $N $T $R $O $P
he/she/it $j $e $E $J — — ‘$’symbol=$$
him/her/it $l $m $M $L — —
his/hers/its $k $s $S $K — —
a/an — — — — $a $A

ifcheck argument? meaning
—————————————————————————–
rand(num) Is a random percentage less than or equal to num
isnpc($*) Is $* an NPC
ispc($*) Is $* a PC
isgood($*) Does $* have a good alignment
isevil($*) Does $* have an evil alignment
isneutral($*) Does $* have a neutral alignment
align($*) == integer Is the alignment of $* equal to integer
isfight($*) Is $* fighting
isimmort($*) Is the level of $* greater than max_mortal
ischarmed($*) Is $* affected by charm
isfollow($*) Is $* a follower with their master in the room
isaffected($*) & integer Is ($*->affected_by & integer) true (person only)
hitprcnt($*) == percent Is the hit/max_hit of $* equal to percent
inroom($*) == integer Is the room of $* equal to integer (person only)
sex($*) == integer Is the sex of $* equal to integer
position($*) == integer Is the position of $* equal to integer
level($*) == integer Is the level of $* equal to integer
class($*) == integer Is the class of $* equal to integer
race($*) == integer Is the race of $* equal to integer
goldamt($*) == integer Does $* have a gold total equal to integer
objtype($*) == integer Is the type of $* equal to integer (armor,boat,etc)
objval#($*) == integer Is $*->value[#] equal to integer (# from 0-3)
number($*) == integer Is the vnum of $* equal to integer
name($*) == string Is the name of $* equal to string

MOBcommand argument_list MOBcommand argument_list
—————————————————————————–
MPSTAT <mobile> MPASOUND <text_string>
MPJUNK <object> MPECHO <text_string>
MPMLOAD <mobile> MPECHOAT <victim> <text_string>
MPOLOAD <object> <level> MPECHOAROUND <victim> <text_string>
MPKILL <victim> MPPURGE [argument]
MPGOTO <dest> MPAT <dest> <command>
MPTRANSFER <dest> [location] MPFORCE <victim> <command>

======================END OF QUICK REFERENCE SHEET===========================

++++++++++++++++++++++++++++++++EXAMPLE++++++++++++++++++++++++++++++++++++++

Referenced from above in the Control Flow section

>act_prog p pokes you in the~
if isnpc($n)
chuckle
poke $n
else
if level($n) <= 5
or isgood($n)
tell $n I would rather you didnt poke me.
else
if level($n)>15
scream
say Ya know $n. I hate being poked!!!
kill $n
break
endif
slap $n
shout MOMMY!!! $N is poking me.
endif
endif
~


if isnpc($n)
chuckle
poke $n
else
if level($n) <= 5
or isgood($n)
tell $n I would rather you didnt poke me.
endif
endif


>entry_prog 100
if ispc($n)
or isimmort($n)
say triggrar forsta
else
if isgood($n)
say andra
endif
endif
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

================================================================================

Test of diffrent attacks in mob progs:

Tested attack 1-7, On char with sanc, -1321
hgi warrior with max stats

attack1 give pummels
attack2 give ELIMINATES
attack3 give * DEMOLISHES *
attack4 give *** ANNIHILATES ***
attack5 give **** BRUTALIZES ****
attack6 give <-> PULVERIZES <->
attack7 give <<-*->> ERADICATES <<-*->>

——————————————————————————–

tested attack 1-7, On char with NO sanc, -1321
hgi warrior with max stats

attack1 give SHREDS
attack2 give * DISMEMBERS *
attack3 give *** ANNIHILATES ***
attack4 give ***** SLAUGHTERS *****
attack5 give <-> PULVERIZES <->
attack6 give <<-*->> ERADICATES <<-*->>
attack7 give <<–*–>> DECAPITATES <<–*–>>

MPEXP

Using this allows you to let your quest mobs give exp during a quest. This is to be used restrictively and M U S T have a level restriction on any exp given. It is not written to allow for the change in exp which happens in the 170s.

To use mpexps (or exp for *s*olo) check the level command to see how much exp is needed for a person to level at the level range you are making the quest for. Then choose suitable exp to give them. suppose im level 363 i’ll need 3395000 exp to level. I can get prolly 30k off a lazy kill somewhere. so you would put mpexps 30000 if you wanted to give them 30k exp for completing that task.

A good way to limit the abuse of this is to use qbits so they cannot repeat this step forever and just do that instead of leveling.

To use mpexpg (or exp for *g*roup) do the same thing. I’m pretty sure it does not split the exp u use. It awards each person in the group however much u specify. so if you put mpexpg 30000 each person in the group would get that. But! to avoid abuse with the level ranges use this group exp only when writing for quests well away from that 170 range. You might also want to give a heads up that its a group quest for group exp in your greet progs.

Mob vs Mob

Time and time again i see on the crash board mob killing mob, for example dhugal the bandit killer, crashing the mud. i even tried to change this to slay today so it would avoid the whole fighting thing. that crashed it too. so keep mob vrs mob battles and slays to an absolute minimum please. i’m trying to eliminate reasons for crashes as i find them. i’ve also noticed a lot of crashes on greet progs which do not have an if ispc($n) check. it could just be something unknown crashed the mud and the greet prog just happened to be the last thing that happened or it could be that the 100’s or 1000’s of greet progs firing at every move update are just too much to stand. so just in case remember to put an if ispc($n) check at the beginning of your greets and an endif at the end of them unless it is something very special that u just wanna make mobs interact.

Reset to inventory

The syntax to load an item in a mobiles inventory is:

reset 1 obj 12345 none

will load an item into the inv. you actually have to type the “none” at the end. you can also do:

reset 2 obj 12346 none 100

to give the item in the inventory a level. sometimes this works..sometimes its buggy. This reset MUST be placed directly AFTER the mobile you want to give the item to. The mud will look up to see what the last mobile reset was and give the item to them.

Reset mobiles

One thing i can tell u. Is that if u use one mobile many times you must set a ‘global’ number in each reset. suppose you have a guard, you know ahead of time you want 10 guards. You would do the resets for the guard something like this:

reset 1 mob 1234 10
reset 2 mob 1234 10

(Note: you must be standing in the room u want that mob to load in when u type each reset.)

The 10 at the end is the global number for how many of those guards there will be in the whole world. If you only make 5 resets there will theoretically be 2 guards in each room if your global number is 10. But, using this method of resets requires you wait a couple of ticks for the area to load your mobs. Also if someone kills some of these mobiles but not all it sometimes results in a bad pop. Have you ever seen a room stacked with 10 mobs that should be spread out over the area? This is what happened.

This method of resetting should only be used for wandering mobs. You won’t notice if they popped wrong if they are all spread out.

For stationary/sentinel mobs you should make as many unique mobs as u possibly can. Lets say u want 5 sentinel skeletons in a gauntlet. Medit create 5 different skeletons, all looking alike if you want. go to each room in turn that u want a skeleton to pop in in each room type this:

reset 1 mob 1234 1
-in the next room
reset 1 mob 1235 1

Repeat until you have set one skeleton in each room. The global number there is 1 and you will avoid bad pops that way…most of the time 😛 This is, after all, DS. Help reset has the syntax for resetting mobs if you forget.

Creating doors

Creating doors in OLC can be quite tricky. First read over the second section of HELP REDIT.

Let’s say you want to make a door to the east which is closed, locked and pickproof Here is the procedure to do that:

Go to the room you want to add the door to. Make sure there is an exit to the east. If not you can create one by using the link or dig commands. You would use EAST DIG #VNUM to create a new room to the east. You would use EAST LINK #VNUM to make an exit between the room you are in and another existing room.

Once you have an exit to the east, you can begin editing the properties of the door. Again we wanted the door to be closed, locked and pickproof. First, you must make it a door and not just a plain exit. Type EAST DOOR to make this happen. Hitting return while using redit will allow you to review the stats of the room you are in. Hit return to make sure the change was made to your eastern exit.

Next, you can type EAST CLOSED LOCKED PICKPROOF all at once to add multiple flags. Doing this should set the stats on both sides of the door. However, you must go to both sides of the door to set the name.

To set the name of the first side of the door type EAST NAME DOOR then open the door and go through and type redit in the room on the other side of the door and type WEST NAME DOOR. Easy enough, yes? From here you can also check the stats on this side of the door to make sure they are correct.

If you change your mind about a flag on a door, you can just type DIRECTION FLAG to toggle the flag back off. When naming a door it is best not to use color in the door’s name. This is the actual keyword of the door as well as what you see on scan. Though most people type OPEN DIRECTION to use a door…you never know.

Using resets to equip mobs

Here is a list of the wear locations and the syntax used to equip mobiles with items in certain slots.

none light lfinger
rfinger neck1 neck2
body head legs
feet hands arms
shield about waist
lwrist rwrist wielded
hold l_ear r_ear
main_gauche

The syntax you would use is:

reset 1 obj VNUM# legs ITEMLEVEL#

This would of course be put directly after the mob you want the eq to load on.