FAQ Search Memberlist Usergroups
Jolt Country Forum Index
Register Profile Log in to check your private messages Log in
Log in Log in

Pocket code and inv_desc

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Jolt Country Forum Index -> Hugo's House of Horrors
View previous topic :: View next topic  
Author Message
Bainespal



Joined: 09 Jul 2010
Posts: 151

PostPosted: Thu Jun 27, 2013 2:37 pm    Post subject: Pocket code and inv_desc Reply with quote

In the first Hugo game that I made and never released or debugged a few years ago, I had a coat with a component object representing the coat pockets. The code worked for taking things out of the pockets and putting them back in again, but the inventory listing was a problem.

Today I revisited the code. I got rid of the component object, merging everything into the coat. It's still not perfect, because I can't get both the coat objects inv_desc and contains_desc properties to be displayed on inventory. Inv_desc seems to override contains_desc. I can still see the contains_desc when I explicitly type "LOOK IN COAT," but I want it to appear for the inventory list as well.

I was thinking this might be a good one for the "Quick Code Samples" thread, but it's still not quite right, so I'll post code here anyways:

Code:
object coat "coat"
{
  is clothing, worn, container
  in you
    nouns "coat", "jacket", "windbreaker", "pockets", "pocket"
    adjective "synthetic"
    article "your"
    long_desc
    {
      "An inexpensive synthetic windbreaker with two large pockets."
    }
    inv_desc
    {
      "You are ";
      if self is worn
      {
        print "wearing ";
      }
      else
      {
        print "carrying ";
      }
      print Art(self); ".";
    }
    contains_desc
    {
      "Inside the coat's pockets ";
      if Children(self) > 1
      {
        print "are";
      }
      else
      {
        print "is";
      }
    }
    capacity 10
}


And here's the portable object that begins in the coat pocket:

Code:
object keychain "keychain"
{
  in coat
    nouns "keychain", "chain", "keyring", "ring", "fob", "keys", "attachments"
    adjectives "plastic", "key", "miscellaneous"
    article "your"
}
Back to top
View user's profile Send private message
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Thu Jun 27, 2013 3:14 pm    Post subject: Reply with quote

Interesting problem. I will look into this.
Back to top
View user's profile Send private message AIM Address
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Thu Jun 27, 2013 7:25 pm    Post subject: Reply with quote

Ok, to get this working how I'd like, it took some finessing of WhatsIn and SpecialDesc. Working with important but complicated routines like WhatsIn and Parse always make me feel like trying to fix a leaky boat, but I'm sure whatever new leaks I spring will bring us closer to better routines in the long run.

Here are the updated routines:
Code:
!\ Added some code so that if the obj is the only child of a parent, it still
checks (and lists) any children of that obj. \!

replace SpecialDesc(obj)
{
   local a, c, flag, printed_blankline

   if FORMAT & LIST_F
      return

   list_count = 0
   for a in obj
   {
      if a is not hidden
      {
         c++
         flag = true
      }
      else
         flag = false

      if FORMAT & INVENTORY_F and obj = player and flag
      {
         if &a.inv_desc
            Indent
         if a.inv_desc
         {
            if FORMAT & LIST_F:  print newline
            AddSpecialDesc(a)
         }
      }

      elseif a is not moved and flag
      {
         if &a.initial_desc
         {
            print newline
            override_indent = false
            if FORMAT & INVENTORY_F and FORMAT & NOINDENT_F and not printed_blankline
               print ""
            printed_blankline = true
            Indent
         }
         if a.initial_desc
            AddSpecialDesc(a)
      }
   }
   list_count = c - list_count
   if not list_count and c
   {
      for a in obj
      {
         if children(a) and a is not quiet and (a is platform or a is transparent or (a is container and a is open)) and
         not a.list_contents
         {
            WhatsIn(a)
            list_count = 0
         }
      }
   }
}

! changed a carriage return to 'print newline'
replace WhatsIn(obj)
{
   local i, totallisted
   local initial_list_nest

   if FORMAT & NORECURSE_F
      return

   for i in obj
   {
      i is not already_listed
      if i is not hidden
         totallisted++
   }

   if totallisted = 0
      return

   list_count = totallisted

   if obj is not container or (obj is container and obj is platform) or
      (obj is container and (obj is not openable or
         (obj is openable and
            (obj is open or obj is transparent)))) and
      (obj ~= player or FORMAT & INVENTORY_F) and obj is not quiet
   {
      SpecialDesc(obj)

      ! If list_count is 0 now, but totallisted was not, something must have been
      ! printed by SpecialDesc


      if list_count = 0
      {
         if FORMAT & INVENTORY_F and not (FORMAT & LIST_F) and
            list_nest = 0
         {
!            print ""
            print newline
         }
         return totallisted
      }

         if obj.list_contents
         return totallisted

      initial_list_nest = list_nest

      if FORMAT & LIST_F
      {
         if list_nest
         {
            ! Indent the first time so that it lines up with
            ! paragraph indentation:
            i = list_nest
            if list_nest = 1 and not (FORMAT & NOINDENT_F)
            {
               Indent
               i--
            }

            print to (i * 2);   ! INDENT_SIZE);
         }
      }
      else
      {
         Indent
      }

      if obj.contains_desc    ! custom heading
      {
         if FORMAT & LIST_F
            RLibMessage(&WhatsIn, 1 )  !  ":"
      }
      else
      {
         if obj = player
         {
            if FORMAT & LIST_F and list_count < totallisted
               print "\n";

            ! "You are carrying..."
            Message(&WhatsIn, 1, totallisted)

            if FORMAT & LIST_F
               RLibMessage(&WhatsIn, 1 )  !  ":"
         }
         elseif obj is living and not obj.prep
         {
            ! "X has..."
            Message(&WhatsIn, 2, obj, totallisted)
            if FORMAT & LIST_F
               RLibMessage(&WhatsIn, 1 )  !  ":"
         }
         else
         {
            if list_count < totallisted
               ! "Also sitting on/in..."
               Message(&Whatsin, 3, obj)
            else
               ! "Sitting on/in..."
               Message(&Whatsin, 4, obj)
            The(obj)
            FORMAT = FORMAT | ISORARE_F
         }
      }

      ListObjects(obj)

      list_nest = initial_list_nest
   }
   return totallisted
}


This gives us a couple options. If we code the coat like this:
Code:
object coat "coat"
{
  is clothing, worn, container, open
  in you
    nouns "coat", "jacket", "windbreaker", "pockets", "pocket"
    adjective "synthetic"
    article "your"
    long_desc
    {
      "An inexpensive synthetic windbreaker with two large pockets."
    }
    inv_desc
    {
      if self is worn
      {
        print "You are wearing ";
      }
      else  ! if it isn't worn, we can treat it like a regular object
      {
        return false
      }
      print Art(self); "."
    }
    contains_desc
    {
      "Inside the coat's pockets ";
      if Children(self) > 1
      {
        print "are";
      }
      else
      {
        print "is";
      }
    }
    capacity 10
}


It'll default to responses like this, where the coat's children may be listed after everything else the player is carrying:
Quote:
> i
You are wearing your coat.
You are also carrying some toast. Inside the coat’s pockets is your keychain.

>


That may not be ideal, but it's workable. Still, we can use list_contents to determine when and how we want the coat's children to be listed. It's nice and powerful that way:
Code:
object coat "coat"
{
  is clothing, worn, container, open
  in you
    nouns "coat", "jacket", "windbreaker", "pockets", "pocket"
    adjective "synthetic"
    article "your"
    long_desc
    {
      "An inexpensive synthetic windbreaker with two large pockets."
    }
    inv_desc
    {
      if self is worn
      {
        print "You are wearing ";
      }
      else  ! if it isn't worn, we can treat it like a regular object
      {
        return false
      }
      print Art(self); ".";
      if children(self)
      {
         print AFTER_PERIOD;
         run self.contains_desc
         ListObjects(self)
      }
      else
         ""
    }
    list_contents
    {
      if (verbroutine = &DoLookIn,&DoLook) or self is not worn and
      verbroutine ~= &DoLookAround
      {
         return false
      }
      return true
    }
    contains_desc
    {
      "Inside the coat's pockets ";
      if Children(self) > 1
      {
        print "are";
      }
      else
      {
        print "is";
      }
    }
    capacity 10
}


This results in:
Quote:
> i
You are wearing your coat. Inside the coat’s pockets is your keychain.
You are also carrying some toast.

>


Let me know if you have any other thoughts on this.

EDIT: Added the list_contents code above to also allow &DoLook


Last edited by Roody_Yogurt on Fri Jun 28, 2013 11:40 am; edited 1 time in total
Back to top
View user's profile Send private message AIM Address
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Fri Jun 28, 2013 11:40 am    Post subject: Reply with quote

One other thing! It bugged me that with the above, we got a default message ("The coat is empty.") when it has no children. To fix this, we add the following to the coat object:
Code:
    after
    {
         object DoLookIn
         {
            if not child(self)
            {
               "The coat's pockets are empty."
            }
            else
               return false
         }
    }
Back to top
View user's profile Send private message AIM Address
Bainespal



Joined: 09 Jul 2010
Posts: 151

PostPosted: Sat Jun 29, 2013 10:57 am    Post subject: Reply with quote

I'm sorry for the delay in responding to your interesting solution here. My power's been out, and it might still be out for another day or two, so I might not be able to do much until then. Anyways, I just added your replacement routines, but I can't compile because your routines require Roodylib. I think I can probably just include the main libraries without completely installing Roodylib, but I don't really time to try it right now. I have to go somewhere, and then I'll have to charge my laptop with a generator. So, I'll play with this code when I get the chance!

As always, thank you very much. :)

[Edit] Hmm, I'm getting an error message "Maximum number of 1024 dictionary entires exceeded" after adding roodylib.g and roodylib. h.


Last edited by Bainespal on Sat Jun 29, 2013 11:11 am; edited 1 time in total
Back to top
View user's profile Send private message
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Sat Jun 29, 2013 11:09 am    Post subject: Reply with quote

Since I ran into the same thing when I was trying to test something else (while still using the file I had thrown together for your problem, I tried compiling without Roodylib to see if any of the behavior was caused by it), here is an edited version of WhatsIn that should work for you:

Code:

replace WhatsIn(obj)
{
   local i, totallisted
   local initial_list_nest

   if FORMAT & NORECURSE_F
      return

   for i in obj
   {
      i is not already_listed
      if i is not hidden
         totallisted++
   }

   if totallisted = 0
      return

   list_count = totallisted

   if obj is not container or (obj is container and obj is platform) or
      (obj is container and (obj is not openable or
         (obj is openable and
            (obj is open or obj is transparent)))) and
      (obj ~= player or FORMAT & INVENTORY_F) and obj is not quiet
   {
      SpecialDesc(obj)

      ! If list_count is 0 now, but totallisted was not, something must have been
      ! printed by SpecialDesc


      if list_count = 0
      {
         if FORMAT & INVENTORY_F and not (FORMAT & LIST_F) and
            list_nest = 0
         {
!            print ""
            print newline
         }
         return totallisted
      }

         if obj.list_contents
         return totallisted

      initial_list_nest = list_nest

      if FORMAT & LIST_F
      {
         if list_nest
         {
            ! Indent the first time so that it lines up with
            ! paragraph indentation:
            i = list_nest
            if list_nest = 1 and not (FORMAT & NOINDENT_F)
            {
               Indent
               i--
            }

            print to (i * 2);   ! INDENT_SIZE);
         }
      }
      else
      {
         Indent
      }

      if obj.contains_desc    ! custom heading
      {
         if FORMAT & LIST_F
#ifset _ROODYLIB_H
            RLibMessage(&WhatsIn, 1 )  !  ":"
#else
            ":"
#endif
      }
      else
      {
         if obj = player
         {
            if FORMAT & LIST_F and list_count < totallisted
               print "\n";

            ! "You are carrying..."
            Message(&WhatsIn, 1, totallisted)

            if FORMAT & LIST_F
#ifset _ROODYLIB_H
               RLibMessage(&WhatsIn, 1 )  !  ":"
#else
               ":"
#endif
         }
         elseif obj is living and not obj.prep
         {
            ! "X has..."
            Message(&WhatsIn, 2, obj, totallisted)
            if FORMAT & LIST_F
#ifset _ROODYLIB_H
               RLibMessage(&WhatsIn, 1 )  !  ":"
#else
               ":"
#endif
         }
         else
         {
            if list_count < totallisted
               ! "Also sitting on/in..."
               Message(&Whatsin, 3, obj)
            else
               ! "Sitting on/in..."
               Message(&Whatsin, 4, obj)
            The(obj)
            FORMAT = FORMAT | ISORARE_F
         }
      }

      ListObjects(obj)

      list_nest = initial_list_nest
   }
   return totallisted
}
Back to top
View user's profile Send private message AIM Address
Bainespal



Joined: 09 Jul 2010
Posts: 151

PostPosted: Sat Jun 29, 2013 11:19 am    Post subject: Reply with quote

Roody_Yogurt wrote:
here is an edited version of WhatsIn that should work for you

Yes, that compiles. Thank you.

Unfortunately, the keychain still isn't being listed in inventory when inside the coat:

Quote:
>i
You are wearing your coat.

>look in coat
Inside the coat's pockets is your keychain.


I did verify that the HDX file I opened was the one just compiled with your new code, so, I think something might still be conflicting somewhere.

Sorry that I don't have more time to get in to this right now.
Back to top
View user's profile Send private message
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Sat Jun 29, 2013 11:27 am    Post subject: Reply with quote

No worries. You'll get to it when you get to it. Just want to point out that you do also need the replaced SpecialDesc routine I listed earlier, too.
Back to top
View user's profile Send private message AIM Address
Roody_Yogurt



Joined: 29 Apr 2002
Posts: 1993
Location: Milwaukee

PostPosted: Sun Jun 30, 2013 1:03 am    Post subject: Reply with quote

The main other thing I figured might be the issue was that you hadn't noticed that my coat code added the "open" attribute, which my new SpecialDesc code required for listing the contents.

Anyhow, I've talked to Kent, and it turns out I've made some bad assumptions about containers along the way. This has resulted in a new Not Dead Hugo blog post:
http://notdeadhugo.blogspot.com/2013/06/container-theory-or-how-do-you-code.html

and an updated SpecialDesc:
Code:
replace SpecialDesc(obj)
{
   local a, c, flag, printed_blankline

   if FORMAT & LIST_F
      return

   list_count = 0
   for a in obj
   {
      if a is not hidden
      {
         c++
         flag = true
      }
      else
         flag = false

      if FORMAT & INVENTORY_F and obj = player and flag
      {
         if &a.inv_desc
            Indent
         if a.inv_desc
         {
            if FORMAT & LIST_F:  print newline
            AddSpecialDesc(a)
         }
      }

      elseif a is not moved and flag
      {
         if &a.initial_desc
         {
            print newline
            override_indent = false
            if FORMAT & INVENTORY_F and FORMAT & NOINDENT_F and not printed_blankline
               print ""
            printed_blankline = true
            Indent
         }
         if a.initial_desc
            AddSpecialDesc(a)
      }
   }
   list_count = c - list_count
   if not list_count and c
   {
      for a in obj
      {
         if children(a) and a is not quiet and
         (a is platform or a is transparent or
         (a is container and
         (a is not openable or (a is openable and a is open)))) and
         not a.list_contents
         {
            WhatsIn(a)
            list_count = 0
         }
      }
   }
}
Back to top
View user's profile Send private message AIM Address
Bainespal



Joined: 09 Jul 2010
Posts: 151

PostPosted: Mon Jul 01, 2013 12:33 pm    Post subject: Reply with quote

Roody_Yogurt wrote:
The main other thing I figured might be the issue was that you hadn't noticed that my coat code added the "open" attribute, which my new SpecialDesc code required for listing the contents.

Yes, that was it. Your code works well, in both wide and tall inventory listing modes. I think the aesthetics could use some work, but then, I've never been a fan of simply putting one line beneath another. I think the code as it is could be recommended on the wiki or as an extension, since this is something that could be relatively common.

I probably wouldn't have associated "open" as a requirement for inventory listing, but I have no problem using it for that purpose. Intuitiveness is fine, but practicality is even more important. If the best way to make the routine do what we need is to use the open attribute to signify being included in lists, then I think that's how to code should work.
Back to top
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Jolt Country Forum Index -> Hugo's House of Horrors All times are GMT - 7 Hours
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001 phpBB Group

Theme by Kage Musha - RPG Garden

Copyrights and trademarks are all of the belonging company. No copyright Infringement intended