Hints
See also: NewMenu.h
Kent Tessman’s game Guilty Bastards has a great adaptive hint system (more hints are added as you progress further in the game). This page contains the code from that game, only slightly modified.
If you look at it, you’ll see that the heart of it is a Menu-calling routine that organizes groups of hints by category.
The code
!----------------------------------------------------------------------------
! HINT SYSTEM:
!----------------------------------------------------------------------------
routine DoHint ! i.e., in response to "hint" or "hints"
{
Help_Hints
window 0
cls
PrintStatusline
DescribePlace(location)
}
#ifset INCLUDE_HINTS
array hint_categories[MAX_MENUITEMS]
routine Help_Hints
{
local i, count, category, old_category
local topic, old_topic
MENU_TEXTCOLOR = DEF_FOREGROUND
MENU_BGCOLOR = DEF_BACKGROUND
MENU_SELECTCOLOR = DEF_SL_FOREGROUND
MENU_SELECTBGCOLOR = DEF_SL_BACKGROUND
! Since we're corrupting the graphics window
last_drawn_picture = 0
:PickHintCategory
! First, create a list of hint categories:
count = 0
for category in hint_category
{
if category.hints_available
{
menuitem[++count] = category.name
hint_categories[count] = category
}
}
if count = 0
{
CenterTitle("HINTS")
"\n[No hints available. Press any key...]";
pause
return
}
menuitem[0] = "HINTS"
category = Menu(count, 0, old_category)
old_category = category
if category = 0: return
! Convert category from a menu selection number to a
! hint_category class:
category = hint_categories[category]
:PickHintTopic
! For a selected category, create a list of subcategories:
! the original code
!\ for (topic=1; category.(hint1-1+topic)~=""; topic++)
{
menuitem[topic] = category.(hint1-1+topic)
hint_categories[topic] = category.(hint1-1+topic) #2
} \!
! the new code
! new loop so you can drop hints from the menu when the player is
! past that part
! (To clear a hint: "hotel_hints.hint4 = 0" )
local new
for (topic=1 ; topic <= 10 ; topic++)
{
if category.(hint1-1+topic)~=""
{
menuitem[++new] = category.(hint1-1+topic)
hint_categories[new] = category.(hint1-1+topic) #2
}
}
menuitem[0] = category.name
! let's clear out the rest of the menu
for ( new = new + 1 ; new <= 10 ; new++ )
{
menuitem[new] = ""
}
! Get the desired topic:
topic = Menu(topic-1, 0, old_topic)
new = 0
old_topic = topic
if topic = 0
jump PickHintCategory
! If we get here, then we've successfully selected a topic
! and can start printing the actual hints:
CenterTitle(menuitem[topic])
! Change topic from a menu selection number to a
! hint_topic class:
topic = hint_categories[topic]
i = 0
:PrintHints
for (; i<=topic.hints_revealed; i++)
{
print ""
run topic.(hint1+i)
}
if &topic.(hint1+i) = 0 ! i.e., no more topics
{
"\n[No more hints. Press any key...]";
pause
jump PickHintTopic
}
else
{
"[Press 'H' for another hint, or 'Q' to quit]";
:GetHintKey
pause
if word[0] = 'Q', 'q', ESCAPE_KEY
jump PickHintTopic
if word[0] = 'H', 'h'
{
topic.hints_revealed++
print newline
jump PrintHints
}
jump GetHintKey
}
}
property hint1 alias n_to
property hint2 alias ne_to
property hint3 alias e_to
property hint4 alias se_to
property hint5 alias s_to
property hint6 alias sw_to
property hint7 alias w_to
property hint8 alias nw_to
property hint9 alias u_to
property hint10 alias d_to
property hints_available alias in_to
property hints_revealed alias out_to
! hint_category objects must be explicitly placed "in hint_category". They
! should contain two values for each hint1, hint2, etc.: a label/question
! and the name of the hint_topic object. hint_topic objects should be
! comprised of property routines for hint1, hint2, etc., giving successive
! hints on the topic.
class hint_category
{
hints_available true
}
class hint_topic
{
hints_revealed 0
}
Hint Examples
!---------------
! STUDIO HINTS:
!---------------
hint_category studio_hints "Rocket Pictures Studios"
{
in hint_category
hints_available
{
if studiogate is visited
return true
else
return false
}
hint1 "How do I get on the studio lot?", studiopass_hints
hint2 "How do I open the soundstage door?", soundstage_hints
hint3 "Who is the mysterious figure?", figure_hints
}
hint_topic studiopass_hints
{
hint1
{
"Movie studio security is on par with Area 51. To get on
the lot, you'll need a pass."
}
hint2
{
"There's a studio pass in the envelope that was slipped
under the door of your hotel room."
}
hint3
{
"Drive to the studio lot. Make sure you've got the pass
handy. Get out of the car and go north."
}
}
Hint categories only show up if the property hints_available
returns
true. This way, you can avoid listing hints for areas the player hasn’t
seen yet.
The Slight Modification
The code on this page has been modified so that you can also remove hints from a category once a player has passed a certain puzzle. In the above example, if the player has made it on to the studio lot, we could add the following to our code at some point:
studio_hints.hint1 = 0
That option would then be skipped in the listing. Theren’t aren’t any checks right now to make sure that an available category has available hints, so you’ll have to code for that yourself if your game has categories is full of hints that will be removed.