!\---------------------------------------------------------------------------
test game for newlib01.h
Test game and routines by J Nichols
newlib.h appended to end of program file.

It's a bunch of new library routines for the Hugo system and a
test program, in one text file.
---------------------------------------------------------------------------\!
! Uncomment the following to use a precompiled version of the Hugo Library:
!#set PRECOMPILED_LIBRARY

! Uncomment the following to include the HugoFix Debugging Library:
#set DEBUG

! Uncomment the following to include verb stub routines:
#set VERBSTUBS

#ifset DEBUG
#switches -d
#endif

#include "grammar.g"                    ! grammar must come first

#ifset DEBUG
xverb "mapit"
      *                            DoMapit
      *       "short"              DoMapit2
#endif

verb "goes", "where", "exits"
      *       "to"              DoExits

xverb "color"
      *              DoSetColor

#ifset PRECOMPILED_LIBRARY
#link "hugolib.hlb"
#else
#include "hugolib.h"
#endif

!#include "newlib01.h"

routine init
{
      counter = -1

      STATUSTYPE = 1                  ! score/turns
      TEXTCOLOR = DEF_FOREGROUND
      BGCOLOR = DEF_BACKGROUND
      SL_TEXTCOLOR = BRIGHT_WHITE
      SL_BGCOLOR = BLUE

      prompt = ">"
      color TEXTCOLOR, BGCOLOR

      cls
      Font(BOLD_ON | DEFAULT_FONT)
      "SHELL"
      Font(BOLD_OFF)
      "An Interactive Starting Point\n"
      print BANNER

      player = you                    ! player initialization
      location = room1
      old_location = location

      move player to location
      FindLight(location)
      DescribePlace(location)
      location is visited
      CalculateHolding(player)

#ifset USE_PLURAL_OBJECTS
      InitPluralObjects
#endif
}

#ifset PRECOMPILED_LIBRARY
replace main
{
#else
routine main
{
#endif
      counter = counter + 1
      PrintStatusLine
      run location.each_turn
      runevents
      RunScripts
      if parent(speaking)~=location
             speaking = 0
}

player_character you "you"
{
      long_desc
      {"It's me,... me,me,me. ";
      print number you}
      before
      {
             actor DoGet
             {
                    if object
                           showall(object)
                    return
             }
      }
}

room start_room !required by mapit
{}

room room1 "room #1"
{
      n_to room2
      s_to room3
      long_desc
      {
             "A empty room. (almost)"
             if FindSame(iggy)
                  print "Iggy is with his pet ";the(obj_found);"."
             show_exits
      }
}

room1 room2 "room #2"
{
      s_to
      {
             if not showing_exits !added to keep the DoExit, show_exits and mapit
                                                                     !  routines working correctly
                    "You scamper out the North exit."
             return room1
      }
      n_to 0
}
room1 room3 "room #3"
{
      n_to room1
      s_to 0
}

room last_room !required by mapit
{}

object lettuce "head of lettuce"
{
      type lettuce
      noun "lettuce"
      article "a", "the"
      in room1
      misc 10
}

character human "dumb human"
{
      article "a", "the"
      noun "human"
      in room1
}

character iggy "green iguana"
{
      noun "iguana","iggy"
      in room1
      long_desc
      {
              "It's a big green iguana named Iggy."
               if FindSType(lettuce)
                    print cpn1;"'s munching on ";art(obj_found)
               else
                    print cpn1;"'s hungry."
      }
      before
      {
             self DoYell
             {
                    pname("you yelling at me", 1)
             }
             xobject DoShow
             {
                    if object = lettuce
                    {
                           print cthe(xobject);" sees you take ";the(object);"."
                           print cpn1;" snaps at you. It's ";pn3;" ";object.name;"."
                           return
                    }
             }
      }
}

!----------------- newlib01.h starts here --------------------
!
! a assortment of new library routines for Kent's HUGO system
! Oct 16, 1997
! by Jerome T. Nichols
! [email protected]
! http://cub.kcnet.org/~jnichols/hugo
! if anyone can think of any improvements on these routines please let me know.
! --------------------------------------------------------------
! new verb definitions
!--------------------------------------------------------------
! xverb "mapit"
!       *                            DoMapit
!       *       "short"              DoMapit2
!
! verb "goes", "where", "exits"
!       *       "to"              DoExits
!
! xverb "color"
!       *              DoSetColor
!
!------------  some new classes --------------
!
!property dex
!property stamina
!property hits
!
property damage
property sub_type ! I use the new property sub_type in my games you may want to replace it
                           ! with the system "type" property.
class weapon ! a super class for weapons
{
      type weapon
!       sub_type weapon
      noun "weapon"
      size 20
      damage 5
      article "a","the"
}

class box ! a super class for containers
{
      type box
      is static, open, container
      prep "in", "out"
      article "a","the"
}

class stage ! a super class for platforms
{
      type stage
      is static, open, platform
      prep "on", "off"
      article "a","the"
}

class clothes ! a super class for clothes
{
      noun "clothes"
      is clothing
      type clothes
      article "a", "the"
!       sub_type clothes
!       in_scope {return parent(self)}
      size 8
      before
      {
! You may want to modify or remove these before & after routines.
             object dolook
             {
             if parent(self) is living
             {
                    print parent(self).name;
                    if object is worn: " is wearing";: else: " is carrying ";
             }
             else
                    "It's ";
             return false
             }
      }
      after
      {
             object DoWear
             {self is worn}
             object DoGet
             {
                    self is not worn
                    print cthe(self);" taken!"
             }
             object DoDrop
             {
                    self is not worn
             }
      }
}
!------------- Pronoun printers --------------------
! trivial but handy routines for printing pronouns
!
routine cpn1(obj)
      {if obj = 0: obj=self: print capital obj.pronoun;}
routine pn1(obj)
      {if obj = 0: obj=self: print obj.pronoun;}
routine cpn3(obj)
      {if obj = 0: obj=self: print capital obj.pronoun #3;}
routine pn3(obj)
      {if obj = 0: obj=self: print obj.pronoun #3;}

!------------ some more fun routines ---------------
! another trivial but useful routine for outputing statments
! by NPCs
! in form {name asks/exclaims/says "babal babal ?/!/."}
! if q = 1 asks ?
! if q = 2 exclaims !
! default: says .
! n = speaking OBJECT. Default SELF
!
routine pname(str, q, n)
{
      if n = 0: n = self
      print capital n.name;
      if str = "": str = "Epps..."
      if q = 1: print " asks: \"";capital str;"?\""
      elseif q = 2: print " exclaims: \"";capital str;"!\""
      else: print " says: \"";capital str;".\""
}
!--------------------------------------------
routine showall(obj)
! SHOWALL: shows <obj> to ever living thing in the room
! could for example be added to the 'player before DoGet'.
! note: if argument omitted, current object is used.
!
{
      local x, y, z
      y = object
      x = xobject
      z = verbroutine
      verbroutine = &DoShow
      if obj: object = obj
      for xobject in location
             If xobject is living: run xobject.before
      object = y
      xobject = x
      verbroutine = z
}
!------------------------------------------------------------
! use verbstubs.h
! similar to showall (above)
! if player yells every living thing in the room will hear and respond.
!
replace DoYell
             {
                    if object and object is living
                           return
                    local x, y
                    y = false
                    for x in location
                           if x is living and x ~= player
                           {
                                  y = true
                                  if not x.before
                                  {
                                         print cart(x);" hears ";actor.name;" yell ";
                                         if word[words] ~= "yell"
                                                print "\"";word[words];"\" ";
                                         "but doesn't understand."
                                  }
                           }
                    if y = false
                           print "Why are you yelling? There's no one to hear!"
                    return true
             }
!-------------------------------------------------------
! xverb "mapit"
!       *                            DoMapit
!       *       "short"              DoMapit2
! intended mainly for dianostic use, note debug flag.
! prints listing of all rooms and exits.
!
global showing_exits

#ifset DEBUG
!
! room start_room
! {}
! ...
! more rooms...
! ...
! room last_room
! {}
! Besure to read comments for DoExits
!
routine DoMapit2
{
      local j
      for(j=start_room; j<last_room; j++)
      {
             if j.type = room or j is platform or j is container
             {
                    print  j.name;" ("; Number j; ") [";number j.sub_type;"]"
             }
      }
}

routine DoMapit
{
      local i, j, k
      showing_exits = true

      for(j=start_room; j<last_room; j++)
      {
             if j.type = room or j is platform or j is container
             {
                    print  j.name;" ("; Number j; ") [";number j.sub_type;"]"
                    for(i=n_to; i<cant_go; i++)
                    {
                           if j.i.type = room or j.i is platform or j.i is container
                           {
                                  print "\_   "; CAPITAL (i-n_to+n_obj).name; "->"; j.i.name; " ("; Number i; ") ";

                                  if i = u_to
                                         k = d_to
                                  elseif i = d_to
                                         k = u_to
                                  else
                                  {
                                         k = i + 4
                                         if k > nw_to
                                                k = k - nw_to + n_to - 1
                                  }
                                  if j.i.k = j or j.i.out_to = j or i = out_to
                                         print " "
                                  else
                                         print "***"
                           }
                    }
             }
      }
      showing_exits = false
}
#endif
!------------------------------- navigation aids -------------------------------
routine DoExits
! verb "goes", "where", "exits"
!       *       "to"              DoExits
!
! I regard DoExit and show_exits as the most important routines in this library.
! The common fault I find with adventure game design is navigation, the player
! should not spend time finding the right exit when it adds nothing to the
! play. So I created these two rather simple routines to aid the player in navigation.
! DoExit is a verb routine which lists all the normal exits in a location and if visited,
! where they lead. Likewise 'show_exits' is a subroutine, listing all exits, appending
! a question mark if not visited.
! Both routines:
! use the attributes quiet and hidden (not other wise used on rooms)
! If QUIET is set on a room no exits in the room are displayed, 'show_exits' is skipped.
! If HIDDEN is set on a room any exits to this room from another are not shown.
! You can still have secret passages.
! They also work for exits to containers and platforms, anything marked enterable.
! Special considerations:
! these routines work fine as long as the basic format for exits are used
!Like: 'n_to room2'
! for more complex exits like:
! n_to
! {
!        "You crawl through the crack."
!        return room2
! }
! Trouble can arise, it can be remedied by adding a extra line like this:
! n_to
! {
!        if not showing_exits
!                     "You crawl through the crack,"
!        return room2
! }
! DoExits and show_exits always set showing_exits = true.
! the extra message will not display.
!
{
      if location is quiet
             {"No obvious exits, sorry!": return}
      if not light_source
             {print "It's dark here! ": return}
      local i, k
      showing_exits = true
      for(i=n_to; i<cant_go; i++)
      {
             k = location.i
             if (k.type = room or k is enterable) and k is not hidden
             {
                    print capital (i-n_to+n_obj).nouns #2;
                    if k is visited! or k.type ~= room
                           print " goes to ";k.name
                    else
                           print " <destination unknown>"
             }
      }
      print newline;
      showing_exits = false
}
routine show_exits(loc)
! this routine can be used in the 'long_desc', 'after.DoGo' or added in to 'DescribePlace' routine
! to display a list of all obvious exits.
! Besure to see comments in DoShow before using.
!
{
      if location is quiet or not light_source: return
      local i, j, k
      showing_exits = true
      if loc = 0: loc = location
      j = "Obvious exits: "
      for(i=n_to; i<cant_go; i++)
      {
             k = loc.i
             if (k.type = room or k is enterable) and k is not hidden
             {
                    print j;capital (i-n_to+n_obj).nouns #2;
                    if k is not visited: "?";
                    j = ", "
             }
      }
      print newline;
      showing_exits = false
}
!----------------------------------------------------------------------------
! xverb "color"
!       *              DoSetColor
!
! menu for changing system colors (simple)
!-------------------------------------------------------
global BOLDCOLOR=RED
routine DoSetColor
{
   local t, a
      menuitem[0]="Choose Color Field"
      menuitem[1]="Status foreground"
      menuitem[2]="Status background"
      menuitem[3]="Text forground"
      menuitem[4]="Text Background"
      menuitem[5]="Bold color"
      t = menu(5, 18)
      if t > 0
      {
         menuitem[0]="Choose Color"
         menuitem[1]="Black"
         menuitem[2]="Blue"
         menuitem[3]="Green"
         menuitem[4]="Cyan"
         menuitem[5]="Red"
         menuitem[6]="Magenta"
         menuitem[7]="Brown"
         menuitem[8]="White"
         a = menu(8, 9)
         if a > 0
         {
            a = a - 1
            menuitem[0]="Choose Intensity"
            menuitem[1]="Light"
            menuitem[2]="Dark"
            if menu(2, 6) = 1
               a =a + 8
            select t
            case 1
               SL_TEXTCOLOR = a
            case 2
               SL_BGCOLOR = a
            case 3
               TEXTCOLOR = a
            case 4
               BGCOLOR = a
            case 5
               BOLDCOLOR = a
         }
      color TEXTCOLOR, BGCOLOR
      cls
      PrintStatusline
      run location.long_desc
      }
}
!-------------------------------------------------------
! for RPGers
! just emulates dice rolls
! s = number of sides
! n = number of dice
! defult: 6 sides, 2 dice
!remember just using 'random(n)' will not give you a provability curve (except straight line)
!
routine dice(s, n)
{
      local x
      if n = 0: n = 2
      if s = 0: s = 5
      while n > 0
      {
             x += (random(s) + 1)
             --n
      }
      return x
}
!----------------------------------------------------------------------------
global obj_found
routine FindSType(val, loc, attr, field)
! This function search the parent 'loc' for any object with a property 'field' with
! the value 'val' and a attribute 'attr'.
! defaults:
! field = type
! attr = doesn't check
! loc = location
! see FindSame below.
!
{
      if field = 0: field = type
      if loc = 0: loc = location
      for obj_found in loc
      {
             if obj_found.field = val
             {
                    if attr
                    {
                           if obj_found is attr
                           return obj_found
                    }
                    else
                    return obj_found
             }
      }
      obj_found = nothing
      return false
}

!----------------------------------------------------------------------------
routine FindSame(obj, attr, field)
! This function search the parent of 'obj' for any other object with a
! property 'field' with the same value as the same property in 'obj'.
! default for 'field' is type.
! attribute 'attr' is optional.
! default for 'obj' is self
! If not found returns 0 (false).
! Similar to FindSType above.
!
{
      if obj = 0: obj = self
      if field = 0: field = type
      for obj_found in parent(obj)
      {
             if obj_found.field = obj.field  and obj_found ~= obj
             {
                    if attr
                    {
                           if obj_found is attr
                                  return obj_found
                    }
                    else
                           return obj_found
             }
      }
      obj_found = 0
      return 0
}
!----------------- eof -------------------------------------------------