Object coding

For the most things, like rooms, weapons, armour and monsters, there are
standard objects you can use. You will find them in the /room and /obj
directories. Look though them to see what is available. Don't think about
coding objects from scratch just now.

All objects use a standard format, but rooms look a bit different than
other objects:

inherit room/room

void reset( int arg ) {
  set_light( 1 )
    + You don't see any reason to stay here.\n
    "players/uglymouth/workroom", "north",
  })
    "room/church", "south",
  })
    "room", "Just a bare room",
  })
  ::reset( arg )
  replace_program( room/room )
}

OTHER OBJECTS (i.e. a monster):
inherit obj/monster

void reset( int arg ) {
  ::reset( arg )
  if( arg ) return
  set_name( ugly orc )
  set_alias( orc )
  set_short( An ugly orc )
  set_long( This is a very ugly orc. You don't want 
    + to think about what his parents must look like.\n )
  set_level( 3 )
  set_gender( 1 )
  set_race( orc )
  load_chat( 10, ({
    "Orc says: I hate humans.\n",
    "Orc screams an untranslatable orcish curse.\n",
  }) )
}

With inherit and reset you have created a simple, but functional object
that is usable in the game.
But what have you actually done?
With inherit you copied the code from a standard object. You then have
the basics of a room or monster, but it doesn't look like anything. It
has no name, no description, no exists or level, it is nowhere.

With reset you fill in all those details. Reset is an lfun (see mud_basics
en lfun files) that gets called at reset with arg == 0 and periodically
thereafter with arg == 1. The later resets will bring an object back into
its original state. With the different arg you simply prevent unnecessary
processing time being spent on things that wouldn't have changed anyway.
In room files you address the variables directly, while in monsters and
other objects you do this by calling functions, like set_name. Because
there are so many rooms, it is faster to address the variables directly,
even though it is then impossible to perform any security checks on them
(like with weapons if thet don't have too high a weapon class).

So what else is there?
For one, you may want to add your own commands to an object. Say you want
to pull the orc's nose. You do that as follows. After the reset you write:

void init() {
  ::init()
  add_action( do_pull, pull )
}

int do_pull( string str ) {
  if( str != orc's nose ) {
    notify_fail( You feel the orc's nose is a lot more attractive.\n )
    return 0
  }
  write( You pull the orc's nose. The orc pulls your nose in return.\n )
  say( this_player()->query_name() +  pulls the orc's nose. The orc 
    + pulls  + this_player()->query_possessive() +  nose in return.\n )
  return 1
}

What does all this code mean? Init is an lfun which is called every time
an object comes into contact with the orc, when it sees the orc, if you
like. Add_action is an efun that defines a function do_pull that must be
called whenever a player near the orc gives the command pull. Such a command
function is always of type int and must return 1 if the command is executed
successfully, or 0 if it isn't.
First you check whether the player pulls something other then the nose. If
so, the command fails and returns 0. You add the efun nofity_fail to give
the player a hint on why the command doesn't work. If it's the correct
command, then the efun write sends a message to the player and the efun say
to all other livings (players and monsters) in the room. In say you see
the efun this_player(), which refers to the player executing the command.
The sign a->b(c) means call function with name b in object a and pass
arguments c to that function. In this case, query_name() returns the
pretitle and name of the player and query_possessive() gives his or her
as result.

Similar to this you can code all kind of functions in any object you make.
Check also the exa*.c files in /doc/examples.
For questions, you know where to find me...

Uglymouth


