Constant Story "69,105 Keys"; Constant Headline "^by David Welbourn. ^For more about this game, type ABOUT. For credits, type CREDITS. ^(Note: This game uses the longint extension by Chris Hall and Francis Irving.)^"; Release 1; Constant AMUSING_PROVIDED; Constant MANUAL_PRONOUNS; Constant MAX_SCORE = 100; Constant DIALECT_US = 1; Include "longint"; Array num1 -> 4; Array num2 -> 4; Array num3 -> 4; Array num5 -> 4; Array num9 -> 4; Array num17 -> 4; Array num254 -> 4; Array num68850 -> 4; Array num69105 -> 4; Array numkeys -> 4; Array numtmp -> 4; Global colorhinted = 0; Global metalhinted = 0; Global brandhinted = 0; Global sizehinted = 0; Global shapehinted = 0; Global edgehinted = 0; Global markhinted = 0; Global f_ckmode = 0; ! 18 Colour names Array colors --> 18 "white" "black" "red" "orange" "yellow" "green" "blue" "violet" "brown" "pink" "grey" "turquoise" "magenta" "taupe" "beige" "aqua" "navy" "cyan"; ! 6 brand names Array brands --> 7 "Acme" "Borden" "Carter" "Dynamo" "Emperor" "Guardian"; ! 4 size names Array sizes --> 4 "tiny" "small" "big" "huge"; ! 6 shape names Array shapes --> 6 "oval" "circular" "square" "trapezoidal" "hexagonal" "octagonal"; ! 10 metal names Array metals --> 10 "silver" "copper" "steel" "iron" "gold" "nickel" "bronze" "brass" "chrome" "aluminum"; ! 6 cleanliness names !Array cleans --> 6 "shiny" "dusty" "tarnished" "plain" "grimy" "rusty"; ! 4 edge names Array edges --> 4 "milled" "rounded" "flat" "pebbled"; ! 2 marked names Array marks --> 2 "scratched" "unscratched"; Include "Parser"; Object LibraryMessages with before [; Inv: if (lm_n == 1) "You are carrying nothing. So not cool."; Jump: "Ugh, no. The Pit of De Spare Keys was exhausting. You've had enough jumping about for today."; Pray: "Most gods tend to frown on prayers involving personal gain."; Rub: if (noun == player) "You're in the Vault Antechamber, not the Bathroom."; else "Don't bother."; Sing: "You sing:^~You can't ride in my little wagon,^ The front seat's broken, and the back wheel's saggin'. ^ Chug. Chug. Chug chug chug.^ Next verse, the same as the first! ^ A little bit LOUDER and a little bit WORSE!~"; Miscellany: if (lm_n == 19) "You're a young adventurer determined to win the Count's final challenge: to obtain the treasure he locked up in his vault so many years ago."; ]; Include "VerbLib"; !================================================================== ! Assistant routines !================================================================== [ emph str; style underline; print (string) str; style roman; ]; [ strong str; style bold; print (string) str; style roman; ]; [ Cfck str; if (f_ckmode) print "Fuck"; else print "Count"; ]; [ fck str; if (f_ckmode) print "fuck"; else print "count"; ]; !================================================================== ! Entry point routines ! - Amusing, Initialise. !================================================================== [ Amusing; print_ret "Did you try: ^* ", (fck) "count", "ing leaves?^* ", (fck) "count", "ing anything else? (tiles, walls, vault door, etc.) ^* xyzzy?^* plugh?^* remembering the Count?^* singing? ^^Also, did you find a naughty mode?"; ]; [ ChooseObjects obj code; if (code < 2) { if (obj has scenery) return 2; rfalse; } ! Exclude scenery objects from "all". if (obj hasnt scenery) return 2; return 1; ]; [ Initialise; location = VaultAnte; lookmode = 2; ! Verbose ! Decide the adjectives that describe the Unique Key that the player is looking for: keys.ucolor = random(18); keys.ubrand = random(6); keys.ushape = random(6); keys.umetal = random(10); keys.usize = random(4); keys.uedge = random(4); keys.umark = random(2); ! init the longints LongSet(num1, 0,0,0,1); LongSet(num2, 0,0,0,2); LongSet(num3, 0,0,0,3); LongSet(num5, 0,0,0,5); LongSet(num9, 0,0,0,9); LongSet(num17, 0,0,0,17); LongSet(num254, 0,0,0,254); LongSet(num68850, $00,$01,$0C,$F2); LongSet(num69105, $00,$01,$0D,$F1); print "After a series of adventures too mind-boggling to put into words, you finally arrive at the antechamber to the Count's treasure vault! Oh my, oh me...^^"; ]; [ NoteColor n; if (keys.pcolor == 0) keys.pcolor = n; else if (keys.pcolor ~= n) keys.pcolor2 = n; ]; [ NoteBrand n; if (keys.pbrand == 0) keys.pbrand = n; else if (keys.pbrand ~= n) keys.pbrand2 = n; ]; [ NoteShape n; if (keys.pshape == 0) keys.pshape = n; else if (keys.pshape ~= n) keys.pshape2 = n; ]; [ NoteMetal n; if (keys.pmetal == 0) keys.pmetal = n; else if (keys.pmetal ~= n) keys.pmetal2 = n; ]; [ NoteSize n; if (keys.psize == 0) keys.psize = n; else if (keys.psize ~= n) keys.psize2 = n; ]; [ NoteEdge n; if (keys.pedge == 0) keys.pedge = n; else if (keys.pedge ~= n) keys.pedge2 = n; ]; [ NoteMark n; if (keys.pmark == 0) keys.pmark = n; else if (keys.pmark ~= n) keys.pmark2 = n; ]; [ Colorhintable ; return ((colorhinted == 0) && (keys.pcolor == 0) && (keys.pmetal ~= keys.umetal) && (keys.pbrand ~= keys.ubrand) && (keys.psize ~= keys.usize) && (keys.pshape ~= keys.ushape) && (keys.pedge ~= keys.uedge)); ]; [ Metalhintable ; return ((metalhinted == 0) && (keys.pmetal == 0) && (keys.pcolor ~= keys.ucolor) && (keys.pbrand ~= keys.ubrand) && (keys.psize ~= keys.usize) && (keys.pshape ~= keys.ushape) && (keys.pedge ~= keys.uedge)); ]; [ Brandhintable ; return ((brandhinted == 0) && (keys.pbrand == 0) && (keys.pcolor ~= keys.ucolor) && (keys.pmetal ~= keys.umetal) && (keys.psize ~= keys.usize) && (keys.pshape ~= keys.ushape) && (keys.pedge ~= keys.uedge)); ]; [ Sizehintable ; return ((sizehinted == 0) && (keys.psize == 0) && (keys.pcolor ~= keys.ucolor) && (keys.pbrand ~= keys.ubrand) && (keys.pmetal ~= keys.umetal) && (keys.pshape ~= keys.ushape) && (keys.pedge ~= keys.uedge)); ]; [ Shapehintable ; return ((shapehinted == 0) && (keys.pshape == 0) && (keys.pcolor ~= keys.ucolor) && (keys.pbrand ~= keys.ubrand) && (keys.psize ~= keys.usize) && (keys.pmetal ~= keys.umetal) && (keys.pedge ~= keys.uedge)); ]; [ Edgehintable ; return ((edgehinted == 0) && (keys.pedge == 0) && (keys.pcolor ~= keys.ucolor) && (keys.pbrand ~= keys.ubrand) && (keys.psize ~= keys.usize) && (keys.pshape ~= keys.ushape) && (keys.pmetal ~= keys.umetal)); ]; [ Markhintable targ; ! Since scratches are tied to brands, it's simplest to make sure a brand wasn't named for this hint, ! unless it's the target brand, in which case, we really should say something. targ = (keys.pbrand == keys.ubrand) || (keys.pcolor == keys.ucolor) || (keys.psize == keys.usize) || (keys.pshape == keys.ushape) || (keys.pedge == keys.uedge) || (keys.pmetal == keys.umetal); if (keys.pbrand == 0) return ((markhinted == 0) && (keys.pmark == 0) && (~~targ)); else return ((markhinted == 0) && (keys.pmark == 0) && (targ)); ]; !================================================================== ! Classes !================================================================== Class Concept with before [; Rub: "It's exceedingly difficult to clean abstract concepts at the best of times and impossible when under stress."; Think2: print_ret "You could examine or ", (fck) "count", " that."; Find: <>; FCount: rfalse; default: if (self provides default) { PrintOrRun(self,default); rtrue; } else "You can't do that with an abstract concept."; ], has scenery; Class NotPresent with before [; Rub: "You can't clean what's not here."; Find: "You don't know where that is."; FCount: rfalse; default: "You can't see any such thing."; ], has scenery; !================================================================== Object VaultAnte "Vault Antechamber" with name 'antechamber' 'tomb' 'garden' 'pit', description [; print_ret "Wowzers. The ", (Cfck) "Count", " opted for simplicity and vague elegance in his treasure vault antechamber, choosing to dress the walls, floor, and ceiling alike in money-green marble tiles delicately flecked with gold. Apart from yourself and the stupendously locked vault door to the south, there's nothing here. Except for... THE KEYS."; ], cant_go "There's only two exits from here: south, through the vault door where fame and fortune await; and north, to ignominious failure. And frankly, failure is not an option.", n_to "There's no way back for you. Not without the treasure.", s_to vaultdoor, before [; Listen: "This place is filled with an unnatural quiet. Apart from yourself, you hear nothing. Nothing at all. It's as if the world was reduced to just this room, yourself, and these numerous keys."; default: if (noun == keys) { if (keys.pcolor2) print_ret "There are no keys that are both ", (string) colors-->keys.pcolor, " and ", (string) colors-->keys.pcolor2, ". Each individual key is painted with just a single color on its bow."; if (keys.pmetal2) print_ret "There are no keys that are made of both ", (string) metals-->keys.pmetal, " and ", (string) metals-->keys.pmetal2, ". Each individual key is made from a single type of metal."; if (keys.psize2) print_ret "There are no keys that are both ", (string) sizes-->keys.psize, " and ", (string) sizes-->keys.psize2, ". No individual key can be of two sizes at the same time."; if (keys.pshape2) print_ret "There are no keys with bows that are both ", (string) shapes-->keys.pshape, " and ", (string) shapes-->keys.pshape2, ". No key's bow can have two different shapes simultaneously."; if (keys.pbrand2) print_ret "There are no keys that are made by both ", (string) brands-->keys.pbrand, " and ", (string) brands-->keys.pbrand2, ". Every key is bears just one manufacturer's brand."; if (keys.pedge2) print_ret "There are no keys that have both ", (string) edges-->keys.pedge, " and ", (string) edges-->keys.pedge2, " edges on their bows. Every key can only have one style of edging."; if (keys.pmark2) print_ret "How can there be any keys that are both ", (string) marks-->keys.pmark, " and ", (string) marks-->keys.pmark2, "? For any particular key, it's either one or the other."; if (keys.pround) "[What do you mean by ~round~? Use ~circular~ if you mean the shape or use ~rounded~ if you mean the edging style.]"; } ], has light; Object keys "keys" VaultAnte with name 'key' 'keys' 'bow' 'bows' 'of' 'with' 'a\\' 'round' 'painted' 'unique' 'shaft' 'shafts', jcolors 'white' 'black' 'red' 'orange' 'yellow' 'green' 'blue' 'violet' 'purple' 'brown' 'pink' 'grey' 'turquoise' 'magenta' 'taupe' 'beige' 'aqua' 'navy' 'cyan', jbrands 'acme' 'borden' 'carter' 'dynamo' 'emperor' 'guardian', jsizes 'tiny' 'small' 'big' 'large' 'huge', jshapes 'oval' 'circular' 'square' 'trapezoidal' 'hexagonal' 'octagonal', jmetals 'silver' 'copper' 'steel' 'iron' 'gold' 'nickel' 'nickle' 'bronze' 'brass' 'chrome' 'aluminum', jedges 'milled' 'rounded' 'flat' 'pebbled', jmarks 'scratched' 'unscratched' 'marked' 'unmarked', pcolor 0, ! Parsed color; 0 means no color was specified. pbrand 0, ! Parsed brand; 0 means no brand was specified. psize 0, ! Parsed size; 0 means no size was specified. pshape 0, ! Parsed shape, etc. pmetal 0, pedge 0, pmark 0, pcolor2 0, ! The player used a contradictory adjective; remember it. pbrand2 0, psize2 0, pshape2 0, pmetal2 0, pedge2 0, pmark2 0, pround 0, ! Notice if the player tried to use 'round' or 'unique'. punique 0, ucolor 0, ! Unique Key's color; the color of the unique key. ubrand 0, ! Unique Key's brand; the brand of the unique key. usize 0, ! Unique Key's size; the size of the unique key. ushape 0, umetal 0, uedge 0, umark 0, counted 0, ! Set to 1 if 69,105 keys were ever counted. Used by initial. parse_name [ wd num ok; ! It's not enough to know we matched the keys. We need to know which adjectives the player used. self.pcolor = 0; self.pbrand = 0; self.psize = 0; self.pshape = 0; self.pmetal = 0; self.pedge = 0; self.pmark = 0; self.pcolor2 = 0; self.pbrand2 = 0; self.psize2 = 0; self.pshape2 = 0; self.pmetal2 = 0; self.pedge2 = 0; self.pmark2 = 0; self.pround = 0; self.punique = 0; wd = NextWord(); ok = 1; while (ok) { ok = 0; ! if we find a valid word, set ok to 1. if (WordInProperty(wd, self, name)) { ok = 1; switch (wd) { 'round': self.pround = 1; 'unique': if (theKey in player) ok = 0; else self.punique = 1; } } else if (WordInProperty(wd, self, jcolors)) { ok = 1; switch (wd) { 'white': NoteColor(1); 'black': NoteColor(2); 'red' : NoteColor(3); 'orange' : NoteColor(4); 'yellow' : NoteColor(5); 'green': NoteColor(6); 'blue': NoteColor(7); 'violet': NoteColor(8); 'purple': print "(assuming that ~purple~ means ~violet~)^"; NoteColor(8); 'brown': NoteColor(9); 'pink': NoteColor(10); 'grey': NoteColor(11); 'turquoise': NoteColor(12); 'magenta': NoteColor(13); 'taupe': NoteColor(14); 'beige': NoteColor(15); 'aqua': NoteColor(16); 'navy': NoteColor(17); 'cyan': NoteColor(18); } } else if (WordInProperty(wd, self, jbrands)) { ok = 1; switch (wd) { 'acme': NoteBrand(1); 'borden': NoteBrand(2); 'carter': NoteBrand(3); 'dynamo': NoteBrand(4); 'emperor': NoteBrand(5); 'guardian': NoteBrand(6); } } else if (WordInProperty(wd, self, jsizes)) { ok = 1; switch (wd) { 'tiny': NoteSize(1); 'small': NoteSize(2); 'big': NoteSize(3); 'large': NoteSize(3); 'huge': NoteSize(4); } } else if (WordInProperty(wd, self, jshapes)) { ok = 1; switch (wd) { 'oval': NoteShape(1); 'circular': NoteShape(2); 'square': NoteShape(3); 'trapezoidal': NoteShape(4); 'hexagonal': NoteShape(5); 'octagonal': NoteShape(6); } } else if (WordInProperty(wd, self, jmetals)) { ok = 1; switch (wd) { 'silver': NoteMetal(1); 'copper': NoteMetal(2); 'steel': NoteMetal(3); 'iron': NoteMetal(4); 'gold': NoteMetal(5); 'nickel': NoteMetal(6); 'nickle': NoteMetal(6); 'bronze': NoteMetal(7); 'brass': NoteMetal(8); 'chrome': NoteMetal(9); 'aluminum': NoteMetal(10); } } else if (WordInProperty(wd, self, jedges)) { ok = 1; switch (wd) { 'milled': NoteEdge(1); 'rounded': NoteEdge(2); 'flat': NoteEdge(3); 'pebbled': NoteEdge(4); } } else if (WordInProperty(wd, self, jmarks)) { ok = 1; switch (wd) { 'scratched': NoteMark(1); 'unscratched': NoteMark(2); 'marked': NoteMark(1); 'unmarked': NoteMark(2); } } if (ok) { num++; wd = NextWord(); } } return num; ], initial [; print "Like so many fallen autumn leaves, an astonishing "; if (self.counted) { if (theKey in player) print "69,104"; else print "69,105"; } else print "number of"; print " keys litter the floor of this antechamber.^"; ], description [; if (keys.punique) print_ret "You need to find the unique key first. ", (emph) "Then", ", it can be described to you."; self.count(); if (LongSignEQ(numkeys,1) && theKey in player) <>; if (LongIsZero(numkeys)) print "Hm. You don't see any "; else if (~~markhinted) print "You see nothing special about the "; else print "You examine the "; if (keys.psize) print (string) sizes-->keys.psize, " "; if (keys.pmark) print (string) marks-->keys.pmark, " "; if (keys.pbrand) print (string) brands-->keys.pbrand, " "; if (keys.pmetal) print (string) metals-->keys.pmetal, " "; print "key"; if (LongSignNE(numkeys,num1)) print "s"; if (keys.pcolor || keys.pshape || keys.pedge) { print " with "; if (LongSignEQ(numkeys,num1)) { if (keys.pcolor == 4 || keys.pcolor == 16) print "an "; ! orange or aqua else if (keys.pcolor == 0 && (keys.pshape == 1 || keys.pshape == 6)) print "an "; ! oval or octagonal else print "a "; } if (keys.pcolor) print (string) colors-->keys.pcolor, " "; if (keys.pshape) print (string) shapes-->keys.pshape, " "; if (keys.pedge) print (string) edges-->keys.pedge, "-edge "; print "bow"; if (LongSignNE(numkeys,num1)) print "s"; } if (markhinted && ~~LongIsZero(numkeys)) print (string) random(" intensely", " vigorously", " avidly", " keenly", " methodically", " studiously", " strenuously", " thoroughly"); print "."; if (LongSignEQ(numkeys,num1)) { print " There's only one of those! Take it!"; PronounNotice(fakeKey); } else if (LongSignEQ(numkeys,num2)) print " They both seem to be identical."; else if (LongSignEQ(numkeys,num254)) print " They all seem to be identical."; else if (LongIsZero(numkeys)) ; ! say nothing further else if (colorhintable()) { colorhinted = 1; print "^^Except, of course, that the keys come in a large number of garish colors. The bows of the keys, that is, the wide ends of the keys are painted in various colors. The shafts of the keys, of course, are not painted."; } else if (metalhintable()) { metalhinted = 1; print "^^Sorry, that's a lie. Looking at the shafts, you can see that the keys are made of different metals. Iron, bronze, and steel, and so on. Lots of metals."; } else if (brandhintable()) { brandhinted = 1; print "^^Wait. The keys have brand names stamped on them. Acme, Borden, Carter, and so on. How many brands are there?"; } else if (sizehintable()) { sizehinted = 1; print "^^Except... is size special? There's not, y'know, a wide variety of sizes, but some keys are bigger than others. Huh. Some of these keys are tiny. And some might be said to be huge."; } else if (shapehintable()) { shapehinted = 1; print "^^Hold on. Just noticed that the bows of the keys have a number of distinctive shapes. There's keys with oval bows, circular bows, square bows, and so on. (These keys sure have a lot of different properties, don't they?)"; } else if (edgehintable()) { edgehinted = 1; print "^^No, wait! The edges of bows are different! Some keys have a flat edge as you might expect from keys stamped straight from a metal sheet, but others have a milled edge, like some coins. Other keys have rounded edges. Still others have pebbled edges. What should we call this? The edging style property?"; } else if (markhintable()) { markhinted = 1; print " Hmmm. There's gotta be something else...^^And there is! Some keys are scratched and some keys are unscratched! At the top of the shafts of some keys, there's a tiny little horizontal scratch. Bwah-ha-ha! Other adventurers might miss such a tiny detail, but not you!^^Let's call this the scratchness property. (How many properties is that now?)"; } else if (theKey notin player) { print "^^Perhaps you should be more specific? Try specifying the "; if (self.pcolor == 0) print "color"; else if (self.pmetal == 0) print "metal"; else if (self.pbrand == 0) print "brand"; else if (self.psize == 0) print "size"; else if (self.pshape == 0) print "shape"; else if (self.pedge == 0) print "edging style"; else if (self.pmark == 0) print "scratchness"; print " as well."; } new_line; ], before [; Count: if (keys.punique) print_ret "Oh please. Find the unique key first. Then you may ", (fck) "count", " it, if you must."; self.count(); if (LongSignEQ(numkeys,num69105)) self.counted = 1; print "You see ", (longsign) numkeys, " "; if (keys.psize) print (string) sizes-->keys.psize, " "; if (keys.pmark) print (string) marks-->keys.pmark, " "; if (keys.pbrand) print (string) brands-->keys.pbrand, " "; if (keys.pmetal) print (string) metals-->keys.pmetal, " "; print "key"; if (LongSignNE(numkeys,num1)) print "s"; if (keys.pcolor || keys.pshape || keys.pedge) { print " with "; if (LongSignEQ(numkeys,num1)) { if (keys.pcolor == 4 || keys.pcolor == 16) print "an "; ! orange or aqua else if (keys.pcolor == 0 && (keys.pshape == 1 || keys.pshape == 6)) print "an "; ! oval or octagonal else print "a "; } if (keys.pcolor) print (string) colors-->keys.pcolor, " "; if (keys.pshape) print (string) shapes-->keys.pshape, " "; if (keys.pedge) print (string) edges-->keys.pedge, "-edge "; print "bow"; if (LongSignNE(numkeys,num1)) print "s"; } print " here."; if (LongSignEQ(numkeys,num1)) { if (theKey in player) print " You're carrying it."; else { print " That's it! Take it!"; PronounNotice(fakeKey); } } else if (theKey in player) { if ((keys.pcolor == 0 || keys.pcolor == keys.ucolor) && (keys.pmetal == 0 || keys.pmetal == keys.umetal) && (keys.pbrand == 0 || keys.pbrand == keys.ubrand) && (keys.pshape == 0 || keys.pshape == keys.ushape) && (keys.psize == 0 || keys.psize == keys.usize) && (keys.pedge == 0 || keys.pedge == keys.uedge) && (keys.pmark == 0 || keys.pmark == keys.umark)) print " (Including the key you're carrying, of course.)"; } new_line; rtrue; Take: if (keys.punique) print_ret "You can't take the unique key ", (emph) "that", " easily."; self.count(); if (LongSignNE(numkeys, num1)) "It's pointless to pick up any of these keys except the one key that you want: the key to the vault door."; else if (theKey in player) { PronounNotice(theKey); "You're already carrying it."; } else { move theKey to player; PronounNotice(theKey); "With confidence, you take the one and only ", (name) theKey, "."; } List: print_ret "Just try examining or ", (fck) "count", "ing the keys (or interesting subsets of keys)."; Rub: "That won't help. None of the keys are dusty, dirty, grimy, slimy, tarshined, rusty, or encrusted. Cleanliness is not a property you have to worry about. Be thankful."; Search: <>; ], count [ g1 g2 i; LongAssign(numkeys, num68850); g1 = 0; g2 = 0; if (keys.pedge == keys.uedge) g2++; else if (keys.pedge) { g1++; LongSignDiv(numkeys, numkeys, num3); } if (keys.psize == keys.usize) g2++; else if (keys.psize) { g1++; LongSignDiv(numkeys, numkeys, num3); } if (keys.pcolor == keys.ucolor) g2++; else if (keys.pcolor) { g1++; LongSignDiv(numkeys, numkeys, num17); } if (keys.pshape == keys.ushape) g2++; else if (keys.pshape) { g1++; LongSignDiv(numkeys, numkeys, num5); } if (keys.pbrand == keys.ubrand) g2++; else if (keys.pbrand) { g1++; LongSignDiv(numkeys, numkeys, num5); } if (keys.pmetal == keys.umetal) g2++; else if (keys.pmetal) { g1++; LongSignDiv(numkeys, numkeys, num9); } if (g1 && g2) LongSet(numkeys, 0,0,0,0); else if (g2) { LongSet(numkeys, 0,0,0,255); if (keys.pmark == keys.umark) LongSet(numkeys, 0,0,0,1); else if (keys.pmark) LongSet(numkeys, 0,0,0,254); } else if (g1) { ! What if specifying scratched or unscratched? ! If the brand was specified, then the number should be either unchanged or 0. if (keys.pbrand ~= 0) { if (keys.pbrand <= 3 && keys.pmark == 2) LongSet(numkeys, 0,0,0,0); ! Zero unscratched A/B/C keys. else if (keys.pbrand > 3 && keys.pmark == 1) LongSet(numkeys, 0,0,0,0); ! Zero scratched D/E/G keys. } ! If the brand was NOT specified, then the number should be either 2/5ths or 3/5ths of what we calculated. else if (keys.pmark) { LongSignDiv(numkeys, numkeys, num5); if (keys.ubrand <= 3 && keys.pmark == 1) LongMul(numtmp, numkeys, num2); else if (keys.ubrand <= 3 && keys.pmark == 2) LongMul(numtmp, numkeys, num3); else if (keys.ubrand > 3 && keys.pmark == 1) LongMul(numtmp, numkeys, num3); else if (keys.ubrand > 3 && keys.pmark == 2) LongMul(numtmp, numkeys, num2); LongAssign(numkeys, numtmp); } } else { LongAssign(numkeys, num69105); ! But specifying just either scratched or unscratched requires a bit more effort: if (keys.pmark) { LongSet(numkeys, 0,0,0,0); LongSignDiv(numtmp, num68850, num5); for (i = 1: i <= 6: i++) { ! Cycle thru the 6 possible brands if (i == keys.ubrand) { if (keys.pmark == keys.umark) LongAdd(numkeys, numkeys, num1); else LongAdd(numkeys, numkeys, num254); } else if (keys.pmark == 1 && i <= 3) ! We're counting scratched brands LongAdd(numkeys, numkeys, numtmp); ! Acme, Borden, Carter keys are usually all scratched else if (keys.pmark == 2 && i > 3) ! We're counting unscratched brands LongAdd(numkeys, numkeys, numtmp); ! Dynamo, Emperor, Guardian keys are usually all unscratched } } } ], has pluralname; Object vaultdoor "vault door" VaultAnte with name 'vault' 'door' 'inscription' 'lock', article "the", description [; print_ret "The heavy vault door is closed and locked. Very locked. Your keen adventurer eyes espy the following inscription:^^ ~One of these keys is not like the others.^ One of these keys just isn't the same. ^ That one unique key unlocks my vault.^ Perhaps it would help if you tried my name.^ -- ", (cfck) "Count", " Keys~"; ], with_key theKey, before [; Open: if (second == 0) { if (theKey in player) { print "(with the unique key)^"; <>; } else "It seems to be locked. Darn!"; } Attack: "Violence isn't the answer to this one. Drat!"; Search: <>; ], after [; Unlock: score = 100; deadflag = 2; ! *** You won *** "You fancy you hear hosannas sing in your honor as you unlock the vault door and claim a treasure so fabulous, a mere text description of which could hardly do it justice. Gosh."; ], has scenery door locked openable ~open lockable; Object tiles "marble tiles" VaultAnte with name 'marble' 'tiles', article "several", description "You spare a moment to admire the workmanship of the tilework.", before [; Take: "Dude. They're hardly portable."; Count: "There are 2400 marble tiles here. You're glad it wasn't you that had to install all these tiles and get them to line up straight. You hate repetitive work."; Search: "Looking for a loose tile? Sorry. Not this time."; Rub: "You're not a maid."; Attack, Listen, Touch, Smell, Taste, Push, Pull: "Stop fiddling with the tiles. It's the keys you need to worry about."; ], has scenery pluralname; Concept qcolors "colors" VaultAnte with name 'colors' 'colours' 'color' 'colour', default [; print_ret "Color is a quality or property of each key. You may only examine or ", (fck) "count", " the colors of the keys."; ], before [; Examine: "There are numerous colors of keys. You see white keys, black keys, red keys, orange keys, yellow keys, green keys, blue keys, violet keys, brown keys, pink keys, grey keys, turquoise keys, magenta keys, taupe keys, beige keys, aqua keys, navy keys, and cyan keys.^^The colors are painted on the bows (the fat ends) of the keys; the metal shafts of the keys are bare. Every key is painted with exactly one color. There are no unpainted keys."; Count: "There are 18 colors of key bows here."; FCount: rfalse; ], has scenery pluralname; Concept qsizes "sizes" VaultAnte with name 'sizes' 'size', default [; print_ret "Size is a quality or property of each key. You may only examine or ", (fck) "count", " the sizes of the keys."; ], before [; Examine: "There's just a few different distinct key sizes: tiny, small, big, and huge."; Count: "There are 4 sizes of keys here."; FCount: rfalse; ], has scenery pluralname; Concept qbrands "brands" VaultAnte with name 'brands' 'brand' 'makers' 'maker' 'manufacturer' 'names' 'name', default [; print_ret "The brand name is a quality or property of each key. You may only examine or ", (fck) "count", " the brand names of the keys."; ], before [; Examine: "There's a handful of different brand names printed on the keys: Acme, Borden, Carter, Dynamo, Emperor, and Guardian."; Count: "There are 6 brands of keys here."; FCount: rfalse; ], has scenery pluralname; Concept qshapes "shapes" VaultAnte with name 'shapes' 'shape', default [; print_ret "Shape is a quality or property of each key. You can only examine or ", (fck) "count", " the shapes of the keys."; ], before [; Examine: "The bows of keys come in several different shapes. They may be oval, circular, square, trapezoidal, hexagonal, or octagonal."; Count: "There are 6 shapes of key bows here."; FCount: rfalse; ], has scenery pluralname; Concept qmetals "metals" VaultAnte with name 'metals' 'metal' 'materials' 'material', default [; print_ret "The metal is a quality or property of each key. You can only examine or ", (fck) "count", " the metals of the keys."; ], before [; Examine: "Who knew that keys were made in so many types of metal? You can see silver keys, copper keys, steel keys, iron keys, gold keys, nickel keys, bronze keys, brass keys, chrome keys, and even aluminum keys here."; Count: "There are 10 metals used to make the keys here."; FCount: rfalse; ], has scenery pluralname; Concept qedges "edging styles" VaultAnte with name 'edge' 'edges' 'style' 'styles' 'edgings' 'edging', default [; print_ret "Edging style is a quality or property of each key. You can only examine or ", (fck) "count", " the edging styles of the keys."; ], before [; Examine: print_ret "Carefully inspecting the keys before you, you notice that the edges of the keys' bows have different edging styles. Some edges are ", (strong) "milled", " with tiny grooves. Some keys have ", (strong) "pebbled", " edges which feel bumpy. Some keys have ", (strong) "rounded", " edges. And, of course, some key edges are ", (strong) "flat", " and unadorned."; Count: "There are 4 edging styles used on the keys' bows."; FCount: rfalse; ], has scenery pluralname; Concept qscratch "scratchnesses" VaultAnte with name 'scratchness', default [; print_ret "~Scratchness~ is a quality or property of each key. You can only examine or ", (fck) "count", " it."; ], before [; Examine: print_ret "Each key is either ", (strong) "scratched", " or ", (strong) "unscratched", ". Strangely, the scratches themselves are all just one tiny horizontal scratch, all alike and indistinguishable from each other."; Count: "There are 2 scratchnesses."; FCount: rfalse; ], has scenery pluralname; Concept qualities "qualities" VaultAnte with name 'quality' 'qualities' 'property' 'properties', default [; print_ret "Qualities are an abstract concept which you can only examine or ", (fck) "count", "."; ], before [; Examine: print_ret "Several qualities may help you distinguish one key from another. The keys differ from each other in their ", (strong) "size", ", ", (strong) "shape", ", ", (strong) "color", ", ", (strong) "brand name", ", ", (strong) "metal", ", ", (strong) "edging style", ", and, ", (strong) "scratchness", ". (By ~scratchness~, we mean whether the key is scratched or not.)"; Count: "Each key has 7 qualities or properties."; FCount: rfalse; ], has scenery pluralname; NotPresent leaves "leaves" VaultAnte with name 'leaves', before [; Count: "There are 0 leaves here. But nice try."; Find: "That's in the Forest of Fond Memories."; FCount: rfalse; Think2: "You remember jumping into a pile of leaves as a kid. You enjoyed doing that until the day you found yourself covered in ants. Bleah. Never again."; default: "You can't see any such thing."; ], has scenery pluralname; Object theKey "unique key" with name 'unique' 'key' 'bow', article "a", description [; print "It's a ", (string) sizes-->keys.usize, " ", (string) marks-->keys.umark, " ", (string) brands-->keys.ubrand, " ", (string) metals-->keys.umetal, " key with "; if (keys.ucolor == 4 || keys.ucolor == 16) print "an "; else print "a "; print_ret (string) colors-->keys.ucolor, " ", (string) shapes-->keys.ushape, " ", (string) edges-->keys.uedge, "-edge bow. And it's unique."; ], before [; Drop, ThrowAt: "Are you mad? After all your trouble to find it?"; Rub: "The unique key is already clean."; ], ; ! This shadowy version of the unique key can only be refered to as "it" under the right circumstances. ! We use PronounNotice to assign "it" to this fakeKey when the player is urged to "Take it!" ! Notice there's no name property defined; the player cannot refer to this item any other way. Object fakeKey "unique key" VaultAnte with before [; Examine: PrintOrRun(theKey, description); rtrue; Take: move theKey to player; PronounNotice(theKey); remove fakeKey; "With confidence, you take the one and only unique key."; ], has scenery; ! Two of my betatesters tried "pick up key to the vault door", so now I have to allow that phrase. ! This object exists only to match that phrasing, and all actions are redirected to either keys or theKey. ! At minimum, the words 'key' and 'vault' MUST both be used in order so for this item to match. Object vakeKey "key to the vault door" VaultAnte with name 'key' 'to' 'the' 'vault' 'door', parse_name [ wd num gotkey gotvault; wd = NextWord(); while (WordInProperty(wd, self, name)) { if (wd == 'key') gotkey = true; if (wd == 'vault') gotvault = true; num++; wd = NextWord(); } if (gotkey && gotvault) return num; else return 0; ], before [; default: ! Using R_Process is a no-no, but how else is this gonna work? if (theKey in player) R_Process(action, theKey); else { keys.punique = 1; R_Process(action, keys); } rtrue; ], has scenery; NotPresent CountKeys "Count Keys" VaultAnte with name 'count' 'keys', parse_name [ wd num gotit; wd = NextWord(); while (WordInProperty(wd, self, name)) { if (wd == 'count') ! The word 'count' MUST be used in order to match. gotit = true; num++; wd = NextWord(); } if (~~gotit) return 0; return num; ], before [; Examine: print_ret "Alas, the ", (cfck) "Count", " is no longer with us, except in our thoughts."; Think2: print_ret "You remember three things about ", (cfck) "Count", " Keys. One: he loves ", (fck) "count", "ing things. Two: he loves keys. Three: he has a marvelous treasure in his treasure vault. You're not quite sure what this treasure is, but you know he obtained it during his worldwide travels.^^In his will, the ", (cfck) "Count", " decreed that after he died, a grand contest should be held in his home. Adventurers would compete, solving a series of intricate puzzles of his own design until, finally, one adventurer manages to reach the treasure and claim it. You hope that that adventurer will be you."; Try: "Yes. Try that."; Find: "He's in the Keys Ancestral Tomb."; default: "He's not here."; ], has scenery male proper; NotPresent treasure "treasure" VaultAnte with name 'treasure', before [; Think2: print_ret "All you really know about the treasure is that the ", (cfck) "Count", " picked it up during his travels around the world, and that it's currently inside the vault to the south."; Find: "That's in the Treasure Vault."; default: "It's not here. It's still inside the vault, darn it."; ], has scenery; Object walls "walls" VaultAnte with name 'wall' 'walls', before [; Count: "There are 4 walls here. No surprise there."; default: R_Process(action, tiles); rtrue; ! R_Process was needed since <> isn't misunderstood. ], has scenery pluralname; !- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - [ AboutSub ; print "The idea for ", (strong) "69,105 Keys", " came to me during a conversation on ifMud with Taleslinger, although I can't remember what he actually said. Probably something to do with counting and the naming of things. I wasn't sure how exactly it was going to work, except that I wanted the player to count ", (emph) "red", " keys, then red ", (emph) "iron", " keys, and then ", (emph) "tiny", " red iron keys, and so on, eventually finding out which key was the correct one.^^"; print "This was coded in Inform 6, not Inform 7. It did not escape my notice that this would mean a parse_name function of prodigious size, and maybe, since Inform 7 did away with parse_name functions, maybe this game is impossible to code in Inform 7. I really don't know. I can imagine a TADS 3 port, although I haven't a clue how to do it. Systems like ADRIFT and Quest definitely can't code this game, not unless the author wants to code each of several million possible commands separately, and I bet even if the author was willing to code it that way, those systems would simply fail to compile it, since there are likely hard limits to how many commands those systems will permit.^^"; "Also, the longint extension was necessary to let me do arithmetic with numbers as large as 69105. I'm very glad someone else wrote that part. Thanks, Chris Hall and Francis Irving, wherever you are."; ]; [ CountSub ; if (noun == player) "There's just one of you, babe."; if (noun == u_obj) "You see just one ceiling here."; if (noun == d_obj) "You see just one floor here."; print_ret "You see just one ", (name) noun, " here."; ]; [ CreditsSub; "This game was designed and coded by David Welbourn in February 2009. ^^Thanks to Marius M@:uller a.k.a. Taleslinger for the idea. ^Thanks to my beta-testers: Jeremy Freese, Bonnie Montgomery, Sarah Morayati, and Marius M@:uller, all of whom gave me more work to do. ^Thanks to the denizens of ifMud just for being there. (Where else would I have found out about R_Process? Thanks, vimes!) ^Thanks to Chris Hall and Francis Irving for writing the longint.h extension. ^And last but not least, thanks to Graham Nelson for Inform."; ]; [ DanceSub; "This antechamber isn't zoned for public dancing. Nertz."; ]; [ FindSub; if (noun == player) "You're in the Vault Antechamber."; if (noun in player) "You're carrying it."; if (noun in VaultAnte || noun == u_obj || noun == d_obj) "That's in the Vault Antechamber."; "You don't know where that is."; ]; [ FuckSub; if (f_ckmode == 0) <>; else <>; ]; [ FuckOnSub; if (f_ckmode == 0) { f_ckmode = 1; "Count off. Fuck on."; } "Fuck mode is already on."; ]; [ FuckOffSub; if (f_ckmode == 1) { f_ckmode = 0; "Fuck off. Count on."; } "Fuck mode is already off."; ]; [ FCountSub; if (f_ckmode == 1) <>; "But fuck mode isn't on!"; ]; [ HintSub; print_ret (string) random("~COUNT~ is an important verb in this game.", "You can refer to types of keys, such as the red keys, or the iron keys, or the red iron keys.", "You can refer to abstract properties like color or size, as in EXAMINE COLORS.", "You can refer to ~properties~ itself.", "The ~scratchness~ property acts differently than the other properties.", "You're looking for the unique key.", "The tiles are unimportant. You can ignore them.", "The unique key can be specified with just two adjectives -- if you can figure out which two.", "The unique key is randomly determined for each game."); ]; [ ListSub; if (noun has pluralname) <>; "That doesn't make any sense."; ]; [ PlughSub; print_ret "My original title was always ", (strong) "69,105 Keys", ", but I brainstormed some other titles anyway. They were: ", (strong) "Which Key?", "; ", (strong) "The Count of Keys", "; ", (strong) "Keygasm", "; ", (strong) "Antechamber of Keys", "; ", (strong) "Keys, Keys, Keys", "; and ", (strong) "Qualia Control", "."; ]; [ SortSub; if (noun == keys) "How? There's no obvious order to sort them into."; if (noun hasnt pluralname) "You can't sort something by itself."; if (noun has scenery || noun has static) "You can't sort what you can't pick up."; if (noun == player) "You can't sort yourself."; "You can't sort that."; ]; [ Think2Sub; if (noun == theKey && thekey in player) "You think you're happy you've found it."; if (noun == vaultdoor) "You should probably try to unlock it."; if (noun == player) "You think you'd be happier with the treasure from the Count's treasure vault."; if (noun == keys) { if (theKey in player) "You think you've done enough thinking about those keys for one day."; print_ret "You think you should examine or ", (fck) "count", " them."; } if (noun == 0) "You think about nothing in particular."; "You can't remember anything about that."; ]; [ TrySub; if (noun == theKey && theKey in player) <>; "Try that how? It's unclear what you mean. Try rephasing your command."; ]; [ XyzzySub; "A hollow voice sings:^~I xyz zy spiders on the wall... I xyz zy cobwebs in the hall... ^ I xyz zy candles on the shelf... When I'm alone, I xyz myself!~"; ]; Include "Grammar"; Verb meta 'about' * -> About; Verb 'count' * 'on' -> FuckOff * 'off' -> FuckOn * noun -> Count; Verb meta 'credits' * -> Credits; Verb 'dance' * -> Dance; Verb 'find' * noun -> Find; Extend only 'fuck' replace * -> Fuck * 'on' -> FuckOn * 'off' -> FuckOff * noun -> FCount; Verb meta 'hint' 'hints' * -> Hint; Verb 'list' * noun -> List; Verb meta 'plugh' * -> Plugh; Verb 'remember' * -> Think2 * 'about' noun -> Think2 * noun -> Think2; Verb 'sort' * noun -> Sort; Verb 'try' * noun -> Try; Extend 'think' replace * -> Think2 * 'about' noun -> Think2 * noun -> Think2; Verb 'wash' * noun -> Rub; Verb meta 'xyzzy' * -> Xyzzy;