dw_fluffos_v2/
dw_fluffos_v2/fluffos-2.9-ds2.05/
dw_fluffos_v2/fluffos-2.9-ds2.05/ChangeLog.old/
dw_fluffos_v2/fluffos-2.9-ds2.05/Win32/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/
dw_fluffos_v2/fluffos-2.9-ds2.05/compat/simuls/
dw_fluffos_v2/fluffos-2.9-ds2.05/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/clone/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/command/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/data/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/etc/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/include/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/inherit/master/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/log/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/compiler/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/efuns/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/single/tests/operators/
dw_fluffos_v2/fluffos-2.9-ds2.05/testsuite/u/
dw_fluffos_v2/fluffos-2.9-ds2.05/tmp/
dw_fluffos_v2/fluffos-2.9-ds2.05/windows/
dw_fluffos_v2/lib/
dw_fluffos_v2/lib/binaries/cmds/
dw_fluffos_v2/lib/binaries/cmds/creator/
dw_fluffos_v2/lib/binaries/cmds/living/
dw_fluffos_v2/lib/binaries/cmds/player/
dw_fluffos_v2/lib/binaries/d/admin/obj/
dw_fluffos_v2/lib/binaries/d/liaison/
dw_fluffos_v2/lib/binaries/global/virtual/
dw_fluffos_v2/lib/binaries/global/virtual/setup_compiler/
dw_fluffos_v2/lib/binaries/obj/handlers/autodoc/
dw_fluffos_v2/lib/binaries/obj/handlers/terrain_things/
dw_fluffos_v2/lib/binaries/obj/misc/
dw_fluffos_v2/lib/binaries/obj/misc/buckets/
dw_fluffos_v2/lib/binaries/obj/monster/
dw_fluffos_v2/lib/binaries/obj/reactions/
dw_fluffos_v2/lib/binaries/obj/reagents/
dw_fluffos_v2/lib/binaries/secure/cmds/creator/
dw_fluffos_v2/lib/binaries/secure/master/
dw_fluffos_v2/lib/binaries/std/
dw_fluffos_v2/lib/binaries/std/dom/
dw_fluffos_v2/lib/binaries/std/effects/object/
dw_fluffos_v2/lib/binaries/std/guilds/
dw_fluffos_v2/lib/binaries/std/languages/
dw_fluffos_v2/lib/binaries/std/races/
dw_fluffos_v2/lib/binaries/std/room/
dw_fluffos_v2/lib/binaries/std/room/basic/
dw_fluffos_v2/lib/binaries/std/shops/
dw_fluffos_v2/lib/binaries/std/shops/inherit/
dw_fluffos_v2/lib/binaries/www/
dw_fluffos_v2/lib/cmds/guild-race/
dw_fluffos_v2/lib/cmds/guild-race/crafts/
dw_fluffos_v2/lib/cmds/guild-race/other/
dw_fluffos_v2/lib/cmds/playtester/
dw_fluffos_v2/lib/cmds/playtester/senior/
dw_fluffos_v2/lib/d/admin/
dw_fluffos_v2/lib/d/admin/log/
dw_fluffos_v2/lib/d/admin/mapper/31-10-01/mapmaker/event/
dw_fluffos_v2/lib/d/admin/meetings/
dw_fluffos_v2/lib/d/admin/obj/
dw_fluffos_v2/lib/d/admin/room/we_care/
dw_fluffos_v2/lib/d/admin/save/
dw_fluffos_v2/lib/d/dist/
dw_fluffos_v2/lib/d/dist/mtf/
dw_fluffos_v2/lib/d/dist/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/chars/
dw_fluffos_v2/lib/d/dist/pumpkin/desert/
dw_fluffos_v2/lib/d/dist/pumpkin/gumboot/
dw_fluffos_v2/lib/d/dist/pumpkin/hospital/
dw_fluffos_v2/lib/d/dist/pumpkin/inherit/
dw_fluffos_v2/lib/d/dist/pumpkin/map/
dw_fluffos_v2/lib/d/dist/pumpkin/plain/
dw_fluffos_v2/lib/d/dist/pumpkin/pumpkin/
dw_fluffos_v2/lib/d/dist/pumpkin/save/
dw_fluffos_v2/lib/d/dist/pumpkin/squash/
dw_fluffos_v2/lib/d/dist/pumpkin/terrain/
dw_fluffos_v2/lib/d/dist/pumpkin/woods/
dw_fluffos_v2/lib/d/dist/start/
dw_fluffos_v2/lib/d/learning/TinyTown/buildings/
dw_fluffos_v2/lib/d/learning/TinyTown/map/
dw_fluffos_v2/lib/d/learning/TinyTown/roads/
dw_fluffos_v2/lib/d/learning/add_command/
dw_fluffos_v2/lib/d/learning/arms_and_weps/
dw_fluffos_v2/lib/d/learning/chars/
dw_fluffos_v2/lib/d/learning/cutnpaste/
dw_fluffos_v2/lib/d/learning/examples/npcs/
dw_fluffos_v2/lib/d/learning/examples/player_houses/npcs/
dw_fluffos_v2/lib/d/learning/examples/terrain_map/basic/
dw_fluffos_v2/lib/d/learning/functions/
dw_fluffos_v2/lib/d/learning/handlers/
dw_fluffos_v2/lib/d/learning/help_topics/npcs/
dw_fluffos_v2/lib/d/learning/help_topics/objects/
dw_fluffos_v2/lib/d/learning/help_topics/rcs_demo/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/crowd/
dw_fluffos_v2/lib/d/learning/help_topics/rooms/situations/
dw_fluffos_v2/lib/d/learning/items/
dw_fluffos_v2/lib/d/learning/save/
dw_fluffos_v2/lib/d/liaison/
dw_fluffos_v2/lib/d/liaison/NEWBIE/doc/
dw_fluffos_v2/lib/d/liaison/NEWBIE/save/oldlog/
dw_fluffos_v2/lib/db/
dw_fluffos_v2/lib/doc/
dw_fluffos_v2/lib/doc/creator/
dw_fluffos_v2/lib/doc/creator/autodoc/include/reaction/
dw_fluffos_v2/lib/doc/creator/autodoc/include/ritual_system/
dw_fluffos_v2/lib/doc/creator/autodoc/include/talker/
dw_fluffos_v2/lib/doc/creator/autodoc/include/terrain_map/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/baggage/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clock/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/clothing/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/cont_save/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/corpse/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/money/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/monster/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/scabbard/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/service_provider/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/state_changer/
dw_fluffos_v2/lib/doc/creator/autodoc/obj/wand/
dw_fluffos_v2/lib/doc/creator/autodoc/std/book_dir/
dw_fluffos_v2/lib/doc/creator/autodoc/std/key/
dw_fluffos_v2/lib/doc/creator/autodoc/std/learning/
dw_fluffos_v2/lib/doc/creator/autodoc/std/map/
dw_fluffos_v2/lib/doc/creator/autodoc/std/race/
dw_fluffos_v2/lib/doc/creator/autodoc/std/weapon_logic/
dw_fluffos_v2/lib/doc/creator/files/
dw_fluffos_v2/lib/doc/creator/policy/
dw_fluffos_v2/lib/doc/creator/room/
dw_fluffos_v2/lib/doc/effects/
dw_fluffos_v2/lib/doc/ideas/
dw_fluffos_v2/lib/doc/known_command/
dw_fluffos_v2/lib/doc/lpc/basic_manual/
dw_fluffos_v2/lib/doc/lpc/intermediate/
dw_fluffos_v2/lib/doc/new/add_command/
dw_fluffos_v2/lib/doc/new/handlers/
dw_fluffos_v2/lib/doc/new/living/
dw_fluffos_v2/lib/doc/new/living/race/
dw_fluffos_v2/lib/doc/new/living/spells/
dw_fluffos_v2/lib/doc/new/player/
dw_fluffos_v2/lib/doc/new/room/guild/
dw_fluffos_v2/lib/doc/new/room/outside/
dw_fluffos_v2/lib/doc/new/room/storeroom/
dw_fluffos_v2/lib/doc/object/
dw_fluffos_v2/lib/doc/playtesters/
dw_fluffos_v2/lib/doc/policy/
dw_fluffos_v2/lib/doc/weapons/
dw_fluffos_v2/lib/global/handlers/
dw_fluffos_v2/lib/global/virtual/setup_compiler/
dw_fluffos_v2/lib/include/
dw_fluffos_v2/lib/include/cmds/
dw_fluffos_v2/lib/include/effects/
dw_fluffos_v2/lib/include/npc/
dw_fluffos_v2/lib/include/shops/
dw_fluffos_v2/lib/net/daemon/chars/
dw_fluffos_v2/lib/net/inherit/
dw_fluffos_v2/lib/net/intermud3/
dw_fluffos_v2/lib/net/intermud3/services/
dw_fluffos_v2/lib/net/obj/
dw_fluffos_v2/lib/net/save/
dw_fluffos_v2/lib/net/smnmp/
dw_fluffos_v2/lib/net/snmp/
dw_fluffos_v2/lib/obj/amulets/
dw_fluffos_v2/lib/obj/b_day/
dw_fluffos_v2/lib/obj/examples/
dw_fluffos_v2/lib/obj/food/alcohol/
dw_fluffos_v2/lib/obj/food/chocolates/
dw_fluffos_v2/lib/obj/food/fruits/
dw_fluffos_v2/lib/obj/food/meat/
dw_fluffos_v2/lib/obj/food/nuts/
dw_fluffos_v2/lib/obj/food/seafood/
dw_fluffos_v2/lib/obj/food/vegetables/
dw_fluffos_v2/lib/obj/fungi/
dw_fluffos_v2/lib/obj/furnitures/artwork/
dw_fluffos_v2/lib/obj/furnitures/bathroom/
dw_fluffos_v2/lib/obj/furnitures/beds/
dw_fluffos_v2/lib/obj/furnitures/cabinets/
dw_fluffos_v2/lib/obj/furnitures/chairs/
dw_fluffos_v2/lib/obj/furnitures/chests/
dw_fluffos_v2/lib/obj/furnitures/clocks/
dw_fluffos_v2/lib/obj/furnitures/crockery/
dw_fluffos_v2/lib/obj/furnitures/cupboards/
dw_fluffos_v2/lib/obj/furnitures/cushions/
dw_fluffos_v2/lib/obj/furnitures/fake_plants/
dw_fluffos_v2/lib/obj/furnitures/lamps/
dw_fluffos_v2/lib/obj/furnitures/mirrors/
dw_fluffos_v2/lib/obj/furnitures/outdoor/
dw_fluffos_v2/lib/obj/furnitures/safes/
dw_fluffos_v2/lib/obj/furnitures/shelves/
dw_fluffos_v2/lib/obj/furnitures/sideboards/
dw_fluffos_v2/lib/obj/furnitures/sofas/
dw_fluffos_v2/lib/obj/furnitures/stoves/
dw_fluffos_v2/lib/obj/furnitures/tables/
dw_fluffos_v2/lib/obj/furnitures/wardrobes/
dw_fluffos_v2/lib/obj/handlers/
dw_fluffos_v2/lib/obj/handlers/autodoc/
dw_fluffos_v2/lib/obj/jewellery/anklets/
dw_fluffos_v2/lib/obj/jewellery/bracelets/
dw_fluffos_v2/lib/obj/jewellery/earrings/
dw_fluffos_v2/lib/obj/jewellery/misc/
dw_fluffos_v2/lib/obj/jewellery/necklaces/
dw_fluffos_v2/lib/obj/jewellery/rings/
dw_fluffos_v2/lib/obj/media/
dw_fluffos_v2/lib/obj/misc/buckets/
dw_fluffos_v2/lib/obj/misc/jars/
dw_fluffos_v2/lib/obj/misc/papers/
dw_fluffos_v2/lib/obj/misc/player_shop/
dw_fluffos_v2/lib/obj/misc/shops/
dw_fluffos_v2/lib/obj/misc/traps/
dw_fluffos_v2/lib/obj/monster/
dw_fluffos_v2/lib/obj/monster/godmother/
dw_fluffos_v2/lib/obj/monster/transport/
dw_fluffos_v2/lib/obj/plants/inherit/
dw_fluffos_v2/lib/obj/potions/
dw_fluffos_v2/lib/open/boards/
dw_fluffos_v2/lib/save/autodoc/
dw_fluffos_v2/lib/save/bank_accounts/
dw_fluffos_v2/lib/save/boards/frog/
dw_fluffos_v2/lib/save/books/bed_catalog/
dw_fluffos_v2/lib/save/creators/
dw_fluffos_v2/lib/save/mail/
dw_fluffos_v2/lib/save/mail/p/
dw_fluffos_v2/lib/save/soul/data/
dw_fluffos_v2/lib/save/tasks/
dw_fluffos_v2/lib/save/vaults/
dw_fluffos_v2/lib/secure/cmds/lord/
dw_fluffos_v2/lib/secure/config/
dw_fluffos_v2/lib/secure/items/
dw_fluffos_v2/lib/secure/player/
dw_fluffos_v2/lib/soul/
dw_fluffos_v2/lib/soul/i/
dw_fluffos_v2/lib/soul/j/
dw_fluffos_v2/lib/soul/k/
dw_fluffos_v2/lib/soul/o/
dw_fluffos_v2/lib/soul/q/
dw_fluffos_v2/lib/soul/to_approve/
dw_fluffos_v2/lib/soul/u/
dw_fluffos_v2/lib/soul/v/
dw_fluffos_v2/lib/soul/wish_list/
dw_fluffos_v2/lib/soul/y/
dw_fluffos_v2/lib/soul/z/
dw_fluffos_v2/lib/std/creator/
dw_fluffos_v2/lib/std/effects/
dw_fluffos_v2/lib/std/effects/attached/
dw_fluffos_v2/lib/std/effects/external/
dw_fluffos_v2/lib/std/effects/fighting/
dw_fluffos_v2/lib/std/effects/other/
dw_fluffos_v2/lib/std/environ/
dw_fluffos_v2/lib/std/guilds/
dw_fluffos_v2/lib/std/hospital/
dw_fluffos_v2/lib/std/house/
dw_fluffos_v2/lib/std/house/onebedhouse/
dw_fluffos_v2/lib/std/house/onebedhut/
dw_fluffos_v2/lib/std/house/tworoomflat/
dw_fluffos_v2/lib/std/languages/
dw_fluffos_v2/lib/std/liquids/
dw_fluffos_v2/lib/std/nationality/
dw_fluffos_v2/lib/std/nationality/accents/
dw_fluffos_v2/lib/std/nationality/accents/national/
dw_fluffos_v2/lib/std/nationality/accents/regional/
dw_fluffos_v2/lib/std/npc/goals/
dw_fluffos_v2/lib/std/npc/goals/basic/
dw_fluffos_v2/lib/std/npc/goals/misc/
dw_fluffos_v2/lib/std/npc/inherit/
dw_fluffos_v2/lib/std/npc/plans/
dw_fluffos_v2/lib/std/npc/plans/basic/
dw_fluffos_v2/lib/std/outsides/
dw_fluffos_v2/lib/std/races/shadows/
dw_fluffos_v2/lib/std/room/basic/topography/
dw_fluffos_v2/lib/std/room/controller/
dw_fluffos_v2/lib/std/room/controller/topography/
dw_fluffos_v2/lib/std/room/furniture/games/
dw_fluffos_v2/lib/std/room/furniture/inherit/
dw_fluffos_v2/lib/std/room/inherit/carriage/
dw_fluffos_v2/lib/std/room/inherit/topography/
dw_fluffos_v2/lib/std/room/punishments/
dw_fluffos_v2/lib/std/room/topography/area/
dw_fluffos_v2/lib/std/room/topography/iroom/
dw_fluffos_v2/lib/std/room/topography/milestone/
dw_fluffos_v2/lib/std/shadows/
dw_fluffos_v2/lib/std/shadows/attached/
dw_fluffos_v2/lib/std/shadows/curses/
dw_fluffos_v2/lib/std/shadows/disease/
dw_fluffos_v2/lib/std/shadows/fighting/
dw_fluffos_v2/lib/std/shadows/room/
dw_fluffos_v2/lib/std/shops/controllers/
dw_fluffos_v2/lib/std/shops/objs/
dw_fluffos_v2/lib/std/shops/player_shop/
dw_fluffos_v2/lib/std/shops/player_shop/office_code/
dw_fluffos_v2/lib/std/socket/
dw_fluffos_v2/lib/www/
dw_fluffos_v2/lib/www/external/autodoc/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/
dw_fluffos_v2/lib/www/external/java/telnet/Documentation/images/
dw_fluffos_v2/lib/www/external/java/telnet/examples/
dw_fluffos_v2/lib/www/external/java/telnet/tools/
dw_fluffos_v2/lib/www/pics/
dw_fluffos_v2/lib/www/secure/creator/
dw_fluffos_v2/lib/www/secure/editors/
dw_fluffos_v2/lib/www/secure/survey_results/
dw_fluffos_v2/win32/
<html><!-- #BeginTemplate "/Templates/Body Text.dwt" -->
<head>
<title> Discworld Documentation </title>
</head>
<body bgcolor="#ffffff" TEXT="#000030" LINK="#4a529c" VLINK="#b57339">
<table width="75%" border="0">
  <tr>
    <td><font face="arial,helvetica"><img align=left src="http://discworld.imaginary.com/external//pics/dw4.gif"></font></td>
    <td><font face="arial,helvetica">
      <h2>Discworld Documentation:</h2>
      <h2>LPC for Dummies</h2>
      </font> 
      <p><font size="+1"><!-- #BeginEditable "Title" --><font size="+1"><b>Tutorial 
  One: Putting It All Together - Simple NPCs</b></font><!-- #EndEditable --></font></p>
      <p><i>N.B - This is a work in progress... a living document if you like. 
        If it appears to be dead when you view it, don't worry. It's most likely 
        just playing possum.</i></p>
      <p>Comments on these chapters and tutorials can be e-mailed to <a href="mailto:drakkos@cableinet.co.uk">Drakkos.</a></p>
    </td>
  </tr>
</table>
<br>
<!-- #BeginEditable "Body" --> 
<p>Now that we've gone over some of the concepts you'll need to understand as 
  a creator on Discworld, let's put them all together and actually create some 
  objects to do some nifty things. The first thing we'll do is create a basic 
  NPC and set it up so it can talk to us a little. Sound like fnu? Well, let's 
  give it a try and see! 
<p><b>Commenting Your Code</b> 
<p>Well, first things first, you should always put a comment at the top of your 
  code indicating what the object is, who wrote the object, and on what date it 
  was coded. This is very useful for later assigning blame. Did I say blame? I 
  meant praise. Yes. Comments are basically little sections of text that are completely 
  ignored by the driver. We can use them to add little notes about our code. This 
  is extremely useful if you have written some monstrously complicated function 
  that only you and someone with a PhD in Advanced Astrophysics could possibly 
  understand. By commenting the code thoroughly, you can explain what bits of 
  code are trying to do. This is also vital if someone else will be debugging 
  your code. If there's an explanation of what the code *should* be doing, an 
  examination of the code may show some subtle error in logic that can then be 
  fixed. Otherwise, who knows what any one piece of code is supposed to be doing? 
  But I digress. We can put comments into our file by one of two methods The first 
  is to preface your comment with the '//'. This signifies a comment that extends 
  to the end of the current line of code: void bing() { // Anything after the 
  double slash is a comment. Or, you can use the /* */ pair of symbols. Anything 
  between these two symbols is classed as a comment: 
<blockquote> 
  <p><code>/* &nbsp;<br>
    &nbsp;&nbsp;&nbsp;&nbsp;</code><code>This is a comment. <br>
    &nbsp;&nbsp;&nbsp;&nbsp;And so is this.<br>
    &nbsp;&nbsp;&nbsp;&nbsp;In fact, everything until I put in the closing symbol: 
    <br>
    */ </code></p>
</blockquote>
<p>For the purposes of our tutorials, we will be using the /* */ convention. So 
  let's start with a leetle header to our file, indicating what it is, who we 
  are, and when we coded it: 
<blockquote> 
  <p><code>/* <br>
    &nbsp;&nbsp;&nbsp;&nbsp;This is a basic NPC!<br>
    &nbsp;&nbsp;&nbsp;&nbsp;Written by Drakkos. <br>
    &nbsp;&nbsp;&nbsp;&nbsp;26/09/2000 <br>
    */ </code></p>
</blockquote>
<p>Woo, that was easy! Now what do we do? 
<p><b>Inherit, and Setup!</b> 
<p>Well, if you've read the chapter on inheritance, you probably think we inherit 
  a file. And you'd be 100% correct! The file we inherit for creating a basic 
  NPC is called /obj/monster, and deals with all the horrendously complicated 
  stuff that must be done before you can start being creative with your code. 
  We already know that we inherit a file using the 'inherit' keyword, so let's 
  do that now: 
<blockquote> 
  <p><code>inherit "/obj/monster"; </code></p>
</blockquote>
<p>Woo, that was easy too! But now we get a little more complicated. Because, 
  having written our comment and inherited the correct file, we now have to define 
  a function in our NPC. All objects that can be seen, touched, and played with 
  (oo-er) by creators and players must have a setup() function. This function 
  is called by the driver when a tangible object is created, and deals with setting 
  up all the values our NPC must have. The first thing we have in our setup is 
  a name. All objects that can be manipulated by other objects must have a name. 
  The name is the label by which we refer to the object. Since we're not trying 
  for Shakespeare at the moment, we'll simply give our npc the name 'blob'. To 
  do this, we use the line: 
<blockquote> 
  <p><code>set_name("blob"); </code></p>
</blockquote>
<p>So whenever we want to look at our NPC, give something to our NPC, or... shock 
  horror, kill our NPC, we can do it by 'look blob', 'give <item> to blob', or 
  'kill blob'. Neat! 
<p>Next thing we need is to set the short of the NPC. This is the pretty description 
  we see when the NPC enters the room, or does an action. We do this by: 
<blockquote> 
  <p><code>set_short("grey blob"); </code></p>
</blockquote>
<p>Again, simple to do. Now we'll see: <i>A grey blob is standing here</i> When 
  we look at the room we're in. We also need to set a long description for our 
  NPC. The long description, or simple 'long', is what is returned when we 'look' 
  or 'examine' an object. Essentially, it's the description of what the object 
  looks like. So we put something like: 
<blockquote> 
  <p><code>set_long("This is a grey blob. It is grey. It is also quite " <br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "blobby.\n"); </code></p>
</blockquote>
<p>So whenever anyone looks at our blob, they see: <i>This is a grey blob. It 
  is grey. It is also quite blobby</i>. Woo! We're building up our NPC real nicely 
  now. But there's still more stuff that we need to do before our NPC is ready 
  to be cloned into life. We need to give our NPC a race, a guild, and a level. 
  If we don't, then our NPC will wither and fade away before we can even say hello. 
  There are two ways to do this. One is to call first set_race(), then set_guild(), 
  and then set_level(), within the setup() of the NPC. However, a better and simpler 
  way to setup the three values is to use the basic_setup() function. This takes 
  three arguments... the first two are strings, and are the race, and the guild 
  respectively. The third is an integer argument and is the level of our NPC. 
  We'll talk some more about races in one of our later tutorials in this suite 
  of documents, but for now we'll do something simple and make our blob a human 
  warrior: 
<blockquote> 
  <p><code>basic_setup("human", "warrior", 10); </code></p>
</blockquote>
<p>And finally... well... finally for now, we need a gender for our NPC. Let's 
  make him male, for the simple fact that female blobs are too provocative for 
  this sedate document: 
<blockquote> 
  <p><code>set_gender("male"); </code></p>
</blockquote>
<p>And that's all we need to have our fully working NPC! 
<p>To recap, the code up 'till now will look like this: 
<blockquote> 
  <p><code>/* <br>
    &nbsp;&nbsp;&nbsp;&nbsp;This is a basic NPC!<br>
    &nbsp;&nbsp;&nbsp;&nbsp;Written by Drakkos. <br>
    &nbsp;&nbsp;&nbsp;&nbsp;26/09/2000 <br>
    */ </code></p>
  <p><code>inherit "/obj/monster"; </code></p>
  <p><code>void setup() { <br>
    &nbsp;&nbsp;&nbsp;&nbsp;set_name("blob"); <br>
    &nbsp;&nbsp;&nbsp;&nbsp;set_short("grey blob"); <br>
    &nbsp;&nbsp;&nbsp;&nbsp;set_long("This is a grey blob. It is grey. It is also 
    quite " <br>
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "blobby.\n"); 
    <br>
    &nbsp;&nbsp;&nbsp;&nbsp;basic_setup("human", "warrior", 10); <br>
    &nbsp;&nbsp;&nbsp;&nbsp;set_gender("male"); <br>
    } </code></p>
</blockquote>
<p>Now, all we have to do is save that into a file with a .c extension, and then 
  type 'clone <filename>' to summon up our very own grey blob to keep us company. 
  Woohoo! 
<p><b>Cloning and Updating </b> 
<p>When we first clone our object, we make a master copy of it in memory that 
  is then used as the basis for all other clones. We talked about this a bit in 
  chapter one. Basically, this means that every time you clone an NPC, it will 
  first check for a master object. If there isn't one, it will create one, If 
  there is, then it will make a clone of the object from the master object. This 
  means that if you clone an object, discover some errors, fix them, then clone 
  another object, these errors will still be present. To update the master object 
  with the new code, we use the 'update' command on the filename: update /d/learning/newbie/introduction/examples/simple_npc. 
  This creates an updated master object of your code. All objects cloned from 
  the old master object will still have the errors, however, so you can 'update' 
  them individually. This may introduce some peculiarities into objects... NPCs 
  in particular, so if you find things like add_responses are no longer working, 
  dest the offending object and clone a fresh copy. You can update a local NPC, 
  rather than the master object, in the same way you would give them something 
  or attack them... 'update <npc_name>&lt;name&gt;'. 
<p><b>More Setup! </b> 
<p>But we're not quite done yet with our setup. Okay, we have enough to load our 
  NPC, but we need to make sure he's designed properly. For example, we have a 
  blob... we can only reference it by 'blob'. Isn't it a grey blob? We can't we 
  reference it as a 'grey blob'? Well... we can. If we add an adjective to it: 
<blockquote> 
  <p><code>add_adjective("grey"); </code></p>
</blockquote>
<p>Woo, so we can now refer to it as 'blob', or 'grey blob'. Actually, for good 
  measure, let's add 'oozing' as an adjective as well: 
<blockquote> 
  <p><code>add_adjective("oozing"); </code></p>
</blockquote>
<p>So we can refer to it as 'blob', 'grey blob', 'oozing blob', or 'oozing grey 
  blob' if we so desired. Mmm! We could consolidate both of these lines, however, 
  into one add_adjective statement by passing the adjectives in as an array: 
<blockquote> 
  <p><code>add_adjective(({"oozing", "grey"})); </code></p>
</blockquote>
<p>Woo! When you look at our leetle NPC in the right light, however... he does 
  look a little like a sack of porridge. A moving sack, but a sack nonetheless. 
  Just in case people get confused whether our NPC is a blob, or a sack of porridge, 
  let's make it easy for them by adding 'porridge' as an alias: 
<blockquote> 
  <p><code>add_alias("porridge"); </code></p>
</blockquote>
<p>So now 'look porridge' will work just as 'look blob' does. Whee! And finally, 
  let's set the plural of our NPC. Normally the MUD will do that for us when more 
  than one NPC of the same type are in the room... instead of '<i>A grey blob 
  is standing here</i>', it would be <i>'two grey blobs are standing</i>' here. 
  But that's what everyone else is doing. Let's go Tolkein for our tutorial NPC! 
<p>If we use the set_main_plural method, we can change the way the mud pluralises 
  our NPC: 
<blockquote> 
  <p><code>set_main_plural("grey blobses"); </code></p>
</blockquote>
<p>In this case, it's purely a matter of whimsey that we do this. But if you're 
  coding items such as a pair of trousers, you'll need to set the main plural 
  properly to avoid the mud pluralising them as: a pair of trouserses. Instead, 
  you'd use set_main_plural to set them as 'pairs of trousers'. Well, now that 
  we've got all of that sorted out, let's see what else we can do with our leetle 
  NPC. 
<p><b>Load Chats!</b> 
<p>Now, this is all very well and good... but... well... our blob doesn't really 
  do much with himself at the moment, does he? He just stands around doing nothing. 
  If we want him to speak up for himself, we're going to have to put some words 
  in his mouth. Luckily, we have a function that does this for is: load_chat(): 
<blockquote> 
  <p><code>load_chat(20, ({ <br>
    &nbsp;&nbsp;&nbsp;&nbsp;2, ": oozes around.", <br>
    &nbsp;&nbsp;&nbsp;&nbsp;1, "' I'm very grey.",<br>
    </code><code>&nbsp;&nbsp;&nbsp;&nbsp;2 , "' I'm a blob.",<br>
    </code><code>&nbsp;&nbsp;&nbsp;&nbsp;2 , &quot;@bing&quot;,<br>
    }) ); </code></p>
  </blockquote>
<p>The arguments to this function are a little more complicated, so we'll look 
  at it in action. The first argument (20) is the frequency of a chat. The number 
  represents the chance in 1000 of one of the following chats to occur every two 
  seconds. It sounds complex, but it isn't really... essentially it can be worked 
  out with ((20/1000) * 100) to give a percentage chance that a chat will occur 
  every two seconds. You can vary this initial argument to increase or decrease 
  the frequency of chats. The second argument is an array. The first argument 
  of the array is the 'weighting'... the chance a particular chat will occur. 
  The second is the chat itself. The chat itself takes the form of a command for 
  the NPC to execute, prefaced by a control code. The apostrophe is shorthand 
  for 'say', and colon is shorthand for an emote. The @ is shorthand for a soul 
  command. So the actions we've given our NPC will appear as: 
<blockquote> 
  <p><code>The grey blob oozes around. <br>
    The grey blob says: I'm very grey. <br>
    The grey blob says: I'm a blob.<br>
    The grey blob bings.</code> </p>
  </blockquote>
<p>These chats will be chosen at random according to the weighting. The weighting 
  allows you to favour particular chats... in this case, the weightings are 2, 
  1, and 2 respectively, giving a total of five. This means that the first chat 
  has a two in five chance of being executed, the second has a one in five chance, 
  and the third also a two in five chance. 
<p><b>Adding Responses!</b> 
<p>Mmm... isn't our Blob nice and talkative now? Indeed he is... but he's also 
  peculiarly unresponsive. We can say anything to him, and he just stands there 
  like a big sack of porridge. Wouldn't it be nice if we could get him to talk 
  back to us? The method add_respond_to_with allows for you to setup a trigger 
  for the NPC to respond to. The argument list is a little complicated, so let's 
  have a look at an actual function call: 
<blockquote> 
  <p><code>add_respond_to_with(({ "@say",({"blob"}), }), <br>
    &nbsp;&nbsp;&nbsp;&nbsp; "say Yes, I am a grey blob."); </code> </p>
</blockquote>
<p>Now, for the first argument here, we're actually passing in an array of arrays. 
  Don't worry too much about this for the moment. The first argument to this function 
  is the ({ "@say",({"blob"}), }) part. The first part of this argument is the 
  type of action to trigger on... in this case, the action will be triggered on 
  a 'say'. The second part is the text to trigger with... in this case, blob. 
  So, this response will only be triggered if someone does a 'say' containing 
  the word 'blob' in the room occupied by the NPC. Should the trigger event occur, 
  the NPC will then execute the command passed in as the second argument of the 
  function. In this case, 'say Yes, I am a grey blob'. You can use add_respond_to_with 
  as often as you like within the NPC, each use will add another response trigger 
  and action... these will not overwrite each other, so you can make an NPC as 
  interactive as you wish. 
<p>The trigger we have above responds only to a single trigger word, however. 
  Surely our blob would be slightly less restrictive than that? Surely he should 
  also respond to 'grey', for example, with the same comment? Well, luckily we 
  can do this very easily by expanding the trigger a little: 
<blockquote> 
  <p><code>add_respond_to_with(({ "@say",({"blob", "grey"}), }), <br>
    &nbsp;&nbsp;&nbsp;&nbsp; "say Yes, I am a grey blob."); </code></p>
</blockquote>
<p>This simply means that either the word 'blob', or the word 'grey', will trigger 
  this response from our NPC. But, as always, we want more. Yes, more! Hang those 
  who talk of less! Why should we have to settle for one boring trigger phrase? 
  We should be able to make our NPC respond to any number of words, in any combination! 
  We can do this too with add_respond_to_with(), simply by adding new arrays containing 
  extra trigger words: 
<blockquote> 
  <p><code>add_respond_to_with(({ "@say",({"ooze"}), ({"porridge"}), }), <br>
    &nbsp;&nbsp;&nbsp;&nbsp;"' Yes, I'm oozing quite nicely, like grey "<br>
    &nbsp;&nbsp;&nbsp;&nbsp; "blobs do. Like porridge!"); </code></p>
</blockquote>
<p>So now our NPC can also respond to the phrase 'ooze porridge', but won't respond 
  to 'ooze', or 'porridge' by themselves. And, like above, you can make each of 
  these trigger phrases less restrictive by adding in alternatives for that trigger: 
<blockquote> 
  <p><code>add_respond_to_with(({ "@say",({"ooze", "blue", "cardboard"}), <br>
    &nbsp;&nbsp;&nbsp;&nbsp; ({"porridge", "bing", "womble"}), }), <br>
    &nbsp;&nbsp;&nbsp;&nbsp; "' Yes, I'm oozing quite nicely, like grey " <br>
    &nbsp;&nbsp;&nbsp;&nbsp;"blobs do. Like porridge!"); </code></p>
</blockquote>
<p>So our NPC will respond to 'ooze porridge', or 'ooze womble', or 'blue womble', 
  or any combination. And if we want to add another trigger, we just have to add 
  another array to the list as we did before. Woo!
<p>But what say we wanted to make our NPC respond not to a say, but to a soul? 
  Well, that's easy to do to with add_respond_to_with... just change the '@say' 
  into the soul we want. If we want to make our leetle blob respond when we 'thank' 
  him, for example, we use:
<blockquote> 
  <p> <code>add_respond_to_with(({ "@thank", ({ "you", "blob" }) }),<br>
    </code><code>&nbsp;&nbsp;&nbsp;&nbsp; "' Aw, shucks. T'weren't nuthin'.&quot;);</code></p>
</blockquote>
<p>Tada! Simple? Indeed! We can also give our NPC a selection of responses to 
  the same trigger by passing in an array for his responses. Our NPC will randomly 
  pick one of these actions when triggered:</p>
<blockquote> 
  <p><code>add_respond_to_with(({ "@gnaw", ({ "you", "blob" }) }),<br>
    </code><code>&nbsp;&nbsp;&nbsp;&nbsp; ({"' What did you do that for?!&quot;, 
    &quot;scream&quot;, &quot;cry&quot;, &quot;weep&quot;}));</code></p>
</blockquote>
<p>We can also allow different actions to trigger the same response set by passing 
  in the first argument as an array... through the combination of these we can 
  build very versatile triggers. For example, with the gnawing response above:</p>
<blockquote> 
  <p> <code>add_respond_to_with( ({ ({"@gnaw", "@bite", "@chew"}),</code><code>({ 
    "you", "blob" }) }), <br>
    &nbsp;&nbsp;&nbsp;&nbsp; ({"' What did you do that for?!", "scream", "cry", 
    "weep"}));</code></p>
</blockquote>
<p>This allows us to make the blob respond to being the gnaw, bite and chew souls 
  with the same set of random responses. Nifty!</p>
<p><b>Finishing Up! </b> 
<p>So, now we have an NPC we can talk to, and an NPC that will potter around doing 
  it's Own Thang when we leave it alone. Neat! So, what else can we do with it? 
  Well... in the great traditions of the MUD... let's kill it! So we start to 
  hurt our leetle NPC... but what's this? It doesn't seem perturbed at all: 
<blockquote> 
  <p><code>You miss the grey blob. <br>
    Hp: 639 (639) Gp: 270 (270) <br>
    The grey blob says: I'm very grey. <br>
    The grey blob oozes around. <br>
    The grey blob swings wildly</code>. </p>
</blockquote>
<p>It's just making its normal chats all the way through. Perhaps it should be 
  a little more... well... upset, when someone is trying to kick seven shades 
  of ooze out of it. Well, there's another function, exactly like load_chat, but 
  that deals solely with combat chats. The parameters are exactly the same, just 
  the function names is different: 
<blockquote> 
  <p><code>load_a_chat(20,({ <br>
    &nbsp;&nbsp;&nbsp;&nbsp;2, ": oozes all over you.", <br>
    &nbsp;&nbsp;&nbsp;&nbsp;1, "' Lemme alone!.", <br>
    &nbsp;&nbsp;&nbsp;&nbsp;2 , ": sobs bitter, slimy tears.", <br>
    }) ); </code></p>
</blockquote>
<p>And now when we pick a fight with the poor little fellow: 
<blockquote> 
  <p><code>The grey blob oozes all over you. <br>
    You miss the grey blob. <br>
    Hp: 639 (639) Gp: 270 (270) </code></p>
</blockquote>
<p>Whee! Now he can Hurl Insults at his foes as they try and beat him up. What 
  NPC could ask for more? 
<p><b>Chapter Summary</b> 
<p>And that's it for our NPC for now. We've put into practise some of the concepts 
  we've discussed in the previous chapter... here, we've used inheritance, predefined 
  functions (both efuns and lfuns) and data types. We still have to see how we 
  can use our own functions in an object, but that's for the next tutorial. :-) 
<ul>
  <li><code>Code files should be commented with what the file is, who coded it, 
    and when it was coded. <br>
    </code></li>
  <li><code>Basic NPCs inherit /obj/monster as a base.</code></li>
  <li><code> All tangible objects in the MUD require a setup() function, which 
    is called when an object is created. </code></li>
  <li><code>All objects that may be manipulated or referenced to must have a set_name() 
    in their setup. </code></li>
  <li><code>The short of an object is the text that appears to describe an object 
    in the inventory of another object, or when the object enters/exits a room 
    or performs an action/</code></li>
  <li><code> The long of an object is that text that is returned when you look 
    at that object. </code></li>
  <li><code>All NPCs require a race, guild, and level to be set. Basic_setup() 
    is used for this. If an NPC doesn't have these set, then it will fail to clone. 
    </code></li>
  <li><code>Set_gender() will set the sex of the NPC. </code></li>
  <li><code>Load_chat and load_a_chat are used to add random actions to an NPC. 
    load_chat will set the actions for when the NPC is not in combat, load_a_chat 
    will set the actions for when an NPC is.</code></li>
  <li><code>add_respond_to_with() is used to add trigger phrases for an NPC to 
    respond to. </code></li>
</ul>
<p><b>Support Files </b></p>
<blockquote> 
  <p><code>/d/learning/newbie/introduction/examples/simple_npc.c</code></p>
</blockquote>
<!-- #EndEditable --> 
<p>
<hr>
<center><font size="-1"><a href="/login.html">Discworld MUD</a>'s world wide web pages.<br>brought to you by<br>
  <strong>Cut Me Own Throat Dibbler's <a href="/sausages.html">Sensational Sausages</a>;&nbsp;buy 
  one while they are hot.</strong> <br>
<hr>Lost?  Try Discworld's <a href="/">home page</a>.</font></center><font size="-1"><i><a href="mailto:drakkos@cableinet.co.uk"><font size="-2">Mail Drakkos!</font></a></i>
</font>
</body>
<!-- #EndTemplate --></html>