!\---------------------------------------------------------------------------
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
! jnichols@cub.kcnet.org
! 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 -------------------------------------------------