!---------------------------------------------------------------------------- !This contains routines that have been slightly (or drastically) customized !for use in this game. Mainly, it's for asthetic purposes. !---------------------------------------------------------------------------- ! There is a bug in the library CalculateHolding (as of version 31031) where ! because "worn" and "mobile" are the same attribute, things that are mobile ! but are *nothing* clothing (can't be worn) are left out of the total. ! replace CalculateHolding(obj) { local i obj.holding = 0 for i in obj { if (i is not worn) or (i is not clothing) or (obj ~= player) { obj.holding = obj.holding + i.size } } } !---------------------------------------------------------------------------- replace PrintStatusline(clear_only) { !CHANGED: Added a local var for calculating score pos. local score_pos !CHANGED: Require short length for single-line status !if display.linelength < 80 if display.linelength < 40 display.statusline_height = 2 else display.statusline_height = 1 Font(BOLD_OFF | ITALIC_OFF | UNDERLINE_OFF | PROP_OFF) !!! if (glk_port): Font(BOLD_ON) window display.statusline_height { color SL_TEXTCOLOR, SL_BGCOLOR, INPUTCOLOR cls !CHANGED: Add a param so we can just clear the title. if (not clear_only) { locate 1, 1 if not location print "\_"; elseif not light_source print "In the dark"; else { !CHANGED: Start with a space always. !if FORMAT & DESCFORM_F: print "\_"; print "\_"; print capital location.name; } if display.statusline_height = 1 { !CHANGED: calculate location of score !CHANGED: instead of setting exact. !print to 65; score_pos = display.linelength !Initial length score_pos -= 4 !from for the % and the " / " score_pos -= 1 !leave one space to the right. score_pos -= GetLengthOfNum(score) score_pos -= GetLengthOfNum(counter) !print to (display.linelength - 12); print to score_pos; } else { locate 1, 2 !CHANGED: Start with a space always. !if FORMAT & DESCFORM_F: print "\_"; print "\_"; } if STATUSTYPE = 1 !CHANGED: added a "%" sign after the score. !print number score; " / "; number counter; print number score; "% / "; number counter; elseif STATUSTYPE = 2 print HoursMinutes(counter); } } color TEXTCOLOR, BGCOLOR, INPUTCOLOR Font(DEFAULT_FONT) !!! if (glk_port): Font(BOLD_OFF) } !---------------------------------------------------------------------------- ! DescribePlace(location, [optional parameter]) ! prints the location name, followed by the location description, if ! required ! ! DescribePlace(location, true) ! forces a location description replace Describeplace(place, long) { local obj, count, notlisted, tempformat parser_data[PARSER_STATUS] &= ~PRONOUNS_SET ! Since, for example, a room description following entering via ! DoGo does not trigger before/after properties tied to looking ! around: ! #ifclear NO_VERBS if verbroutine ~= &DoLookAround { if place is not visited and verbosity ~= 1 return Perform(&DoLookAround) elseif long = true or verbosity = 2 return Perform(&DoLookAround) } #endif if not light_source { Message(&DescribePlace, 1) ! "It's too dark to see..." return } place is known ! Print the name of the location as a heading Font(BOLD_ON) !CHANGED: Print room titles in blue. color ROOM_TITLE_COLOR, BGCOLOR, INPUTCOLOR print "\n"; capital place.name; ! Print ", in " if necessary if location = place and player not in place { !CHANGED - customize when standing on crates. if (player in cargo) { ", Standing on the Cargo Crates"; } else { if parent(player).prep print ", "; parent(player).prep; " "; elseif parent(player) is platform print ", "; ON_WORD; " "; else print ", "; IN_WORD; " "; !CHANGED: Don't do a linefeed. !print Art(parent(player)) print Art(parent(player)); } } !CHANGED: Print chrome around room description if (not glk_port) and (GAME_PRINTSTYLE = 2) { color ROOM_FRINGE_COLOR, BGCOLOR, INPUTCOLOR print " .... ... .. . . . . ."; } print newline !CHANGED: Switch now to room text color color ROOM_TEXT_COLOR, BGCOLOR, INPUTCOLOR Font(BOLD_OFF) override_indent = false if place is not visited and verbosity ~= 1 { if &place.initial_desc or &place.long_desc { !Indent !CHANGED: To help mimic ZCode style. } if not place.initial_desc run place.long_desc } elseif long = true or verbosity = 2 { if &place.long_desc { !Indent !CHANGED: To help mimic ZCode style. } run place.long_desc } !CHANGED - allow running a short_desc too. else { if &place.short_desc { !Indent !CHANGED: To help mimic ZCode style. } run place.short_desc } if &place.list_contents and FORMAT & DESCFORM_F print newline ! for double-space-after-heading formatting ! A location may contain an overriding listing routine, as may any ! parent, in the list_contents property ! if not place.list_contents { list_nest = 0 ! For double-space-after-heading formatting: if FORMAT & DESCFORM_F { for obj in place { if obj is not hidden and (player not in obj or children(obj) > 1) { print newline break } } } ! List contents of chair, vehicle, etc. player is in if player not in location { list_nest = 1 WhatsIn(Parent(player)) } ! List all characters, if any count = 0 for obj in place { if obj is hidden or obj is not living or player in obj { obj is already_listed } else { !CHANGED: ! MPS 08/17/2006 - special condition. We don't list the ! girl if she's going to be moving out of the room now. ! The only time we do is if the bees are going to fly in. ! Check with +1 added to turn counter. Daemon hasn't run. if (obj = girl) and (girl.misc #1) and \ (bees.found_in ~= nothing) and (girl in location) and \ (get_girl_movement(location, girl_moving.misc #1 + 1)) { obj is already_listed } else { obj is not already_listed } } } ! List any objects that have custom short descriptions. for obj in place { if obj is not already_listed { print newline ShortDescribe(obj) if obj is not already_listed count++ } } list_count = count count = 0 if list_count ! if characters are to be listed { tempformat = FORMAT FORMAT = FORMAT | FIRSTCAPITAL_F | ISORAREHERE_F FORMAT = FORMAT | USECHARNAMES_F if FORMAT & LIST_F { FORMAT = FORMAT & ~LIST_F ! clear it FORMAT = FORMAT | TEMPLIST_F } Indent list_nest = 0 ListObjects(place) FORMAT = tempformat } for obj in place { #ifset USE_ATTACHABLES ! Exclude all attachables for now (and characters) if obj is living or obj.type = attachable or player in obj #else if obj is living or player in obj #endif obj is already_listed else obj is not already_listed } for obj in place { #ifset USE_PLURAL_OBJECTS ! ...And don't list identical objects yet, either if (obj.identical_to).type = identical_class { if obj is not hidden count++ } elseif player not in obj #else if player not in obj #endif { if obj is not already_listed and obj is not hidden { !CHANGED: Yeah, I could do a custom list_contents, but ! I really just want to hide objects in the room if the ! player is in something other than the room. if (player in location) { ShortDescribe(obj) if obj is not already_listed notlisted++ } } } } if notlisted or count { list_count = notlisted + count tempformat = FORMAT FORMAT = FORMAT | FIRSTCAPITAL_F | ISORAREHERE_F if FORMAT & LIST_F { FORMAT = FORMAT & ~LIST_F ! clear it FORMAT = FORMAT | TEMPLIST_F } Indent list_nest = 0 ListObjects(place) FORMAT = tempformat } #ifclear NO_OBJLIB #ifset USE_ATTACHABLES for obj in place { ! Print attachables last if obj.type = attachable and obj is not hidden { ShortDescribe(obj) if obj is not already_listed Message(&DescribePlace, 2, obj) } } #endif print newline override_indent = false ! Finally, list contents of scenery objects (unless we've ! already done so as the parent of the player) ! for obj in place { if obj.type = scenery { obj is known if player not in obj and (obj is open or obj is not openable) { list_nest = 1 WhatsIn(obj) } } ! For scenery-derived objects that may change the type elseif obj is static, hidden obj is known } #endif ! ifclear NO_OBJLIB print newline need_newline = false } !CHANGED: Revert back to default colors color TEXTCOLOR, BGCOLOR, INPUTCOLOR } !---------------------------------------------------------------------------- ! There is a bug in the current version of the library (31031) that causes ! it to say "you don't see him" even if the living thing is an "it". ! I should probably call PrintMessage() to handle the actual responses, ! but I'll move them later, assuming I have time. ! ! replace NewParseError(errornumber, obj) { local retval = false select errornumber case 6 { ! The original message is "That doesn't make any sense." ! But, if the player says sensible things like "look over the edge" ! (when that exact verb phrasing isn't support), it can be a little ! misleading. So, what would be a better alternative? Hmmm.... ! Inform or maybe Tads will say something like "I understood you as ! far as wanting to EAT" (or whatever). Maybe something like that? ! I will need to really test it, to make sure it works in all cases. if (verbword = "style","theme") { PrintMessage(15,2,10) !Invalid theme. List real ones. retval = true ! So ParseError won't give the default. } elseif (VerbWord ~= "","with", "using") { print "If you want to \""; VerbWord; "\", you may need to rephrase it." retval = true ! So ParseError won't give the default. } } case 11 { if not ParseError_ObjectIsKnown(obj) { ParseError(10, obj) retval = true ! So ParseError won't give the default. } elseif obj is living { print CThe(actor); \ MatchPlural(actor, "doesn't", "don't"); \ " see "; if (obj.pronouns #2) print obj.pronouns #2; elseif obj is plural "them"; elseif obj is female "her"; else "him"; print "." retval = true ! So ParseError won't give the default. } } case 15 { if not ParseError_ObjectIsKnown(obj) { ParseError(10, obj) } elseif obj = player { ParseError(12, obj) } else { !So it makes sense for the identical_class, I'll tell the !player that they're not holding any of those. print CThe(actor); IsorAre(actor); " not holding"; if (obj.type = identical_class) { " any of"; !So it says "not holding any of those." } print MatchPlural(obj, "that", "those"); "." } retval = true ! So ParseError won't give the default. } return retval } !---------------------------------------------------------------------------- ! I want to customize some of the object messages. ! I should probably call PrintMessage() to handle the actual responses, ! but I'll move them later, assuming I have time. ! ! replace NewOMessages(obj, num, a, b) { local retval = false select obj case attachable { select num ! I don't know what it is about this wording, but it just doesn't ! seem quite right for this game. It's too referential to the ! parser. I can see the need to say it, but I'll reword it some. ! Note that this has to cover "tie" and "untie" both, to work. case 7 { ! print "You might want to try \""; a; "\" with "; \ ! The(object); " instead of "; "\""; VerbWord; "\"." print "You can't "; "\""; Verbword; "\""; " "; The(object); " "; if (verbroutine = &DoAttachObject) { print object.attach_prep; ! TO } else { print object.detach_prep; !FROM } print " anything, but it may be possible to "; print "\""; a; "\""; MatchPlural(object,"it.","them.") retval = true !So normal OMessage won't be printed. } ! And these (11, 12, 14, 15) as well. For this game, I'd ! rather not start out with "Except that..." if I don't have to. case 11 { !print "Except that "; The(object); \ print CThe(object); \ IsorAre(object, true); " already "; \ object.attached_desc; " "; The(xobject); "." retval = true !So normal OMessage won't be printed. } case 12 { !print "Except that "; The(object); " is already "; \ print CThe(object); " is already "; \ object.attached_desc; " "; ListAttachments(object) print "." retval = true !So normal OMessage won't be printed. } case 14 { !print "Except that "; The(object); \ print CThe(object); \ IsorAre(object, true); " not "; \ object.attached_desc; " "; The(xobject); "." retval = true !So normal OMessage won't be printed. } case 15 { !print "Except that "; The(object); \ print CThe(object); \ IsorAre(object, true); " not "; \ object.attached_desc; " anything." retval = true !So normal OMessage won't be printed. } } case direction { select num case 1 { if (self = u_obj) { select location case barn { !Player can see a loft above. PrintMessage(2,distant_loft,1) retval = true } case campsite { !Player can see a dark rectangle in the sky. PrintMessage(2,barge_bottom,1) retval = true } case in_mill { !Player can see up inside the windmill. PrintMessage(2,windmill,2) !Looking up. retval = true } case mill { !Player can see up outside the windmill. PrintMessage(2,windmill,3) !Looking up. retval = true } } if (self = d_obj) { if (location = loft) { !Print this if we attempt to look down from the loft. PrintMessage(2,loft_floor,2) !We look over the edge. retval = true } } } } return retval } !---------------------------------------------------------------------------- ! Also some instances where I want to replace the verb messages. ! I should probably call PrintMessage() to handle the actual responses, ! but I'll move them later, assuming I have time. ! replace NewVMessages(r, num, a, b) { local retval = false local temp1 = 0 local temp2 = 0 local loop select r case &DoLock { select num case 1 { !More formal "door is" instead of "door's" message. print CThe(object); IsorAre(object,true); " already locked." retval = true } } case &DoUnlock { select num case 3 { !More formal "door is" instead of "door's" message. print CThe(object); IsorAre(object,true); " already unlocked." retval = true !To skip the default message. } } case &DoPutIn { select num case 5 { !The purpose of this replacement is to say "one of the..." !if we are holding more than one of an identical_class object. print CThe(player); " put"; MatchSubject(player); temp1 = object.identical_to if (temp1) and (temp1.type = identical_class) { for (loop=1; loop <= temp1.#plural_of; loop++) { if Contains(player, temp1.plural_of #loop) { temp2 ++ } } } if (temp2 > 0) { print " one of "; The(temp1); " "; } else { print " "; The(object); " "; } if xobject.prep print xobject.prep; elseif xobject is platform print "on"; else print "in"; print " "; The(xobject); "." retval = true !To skip the default message. } case 6 { !If something is larger than the entire capacity of the thing !we're trying to put it into, then I want to give alternate. if (xobject.holding >= xobject.capacity) { "There's no more room "; } elseif (xobject.holding > 0) { "There's isn't enough room left "; } else { print CThe(object); " won't fit "; } !The rest of it is the same for both versions: "in the xobject." if xobject.prep print xobject.prep; " "; elseif xobject is platform print "on "; else print "in "; print The(xobject); "." retval = true !So normal VMessage won't be printed. } } case &DoEnter { select num case 3 { ! The default is "a bit redundant, don't you think?" ! This doesn't always make sense, when I'm redirecting ! "climb" to be enter or exit (something you're already in). ! So, I want to change it to say "you're already standing here." ! That'll cover "&DoStand" defaults, as well as &DoEnter. "You are already standing "; if (parent(player).type = room) { "here." !A simply way of saying yeah, we're already here. } else { !".... on the cargo crates." or whatever. print parent(player).prep #1; " "; The(parent(player)); "." } retval = true !So normal VMessage won't be printed. } } return retval } !---------------------------------------------------------------------------- ! Basically so I can avoid saying "The Game Has Ended". ! replace NewMessages(r, num, a, b) { local retval = false select r case &EndGame { select num case 1 { PrintMessage(15,2,20) !The endgame options. retval = true } } return retval !Let "Message()" know what we did. } !---------------------------------------------------------------------------- ! There is a "verbword" routine in the library, but it depends on the ! verbroutine being set. Plus, it doesn't translate "l" to "look" or handle ! abbreviations like that. So this one deals strictly with word[1] usage. ! replace VerbWord(which) { if (verbroutine = &DoSleep) and (word[1] = "take") { return "sleep" !because of "take a nap" version. } select word[1] case "i", "inv": return "take inventory" case "x": return "examine" case "l": return "look at" case "g": return "again" case else: return word[1] } !---------------------------------------------------------------------------- replace Indent(newl) { if (override_indent or display.cursor_column > 1) { print AFTER_PERIOD; } else { !In some cases, having a blank line is a problem, such as DoInventory. if (verbroutine ~= &DoInventory, &DoLookIn, &DoSearch) { !Going for a more spaced look, instead of normal indenting. print "" !Print blank line, not indent. Mimic ZCode style. } } }