! Err, using attributes like this isn't really the best way to do ! things. ! Attribute is_tiny; Attribute is_coin; Attribute liquid; Attribute nonmagic; Attribute float; Attribute is_rug; ! necessary because of verb stuff Attribute on_rug; Include "chooseobjects.inf"; Include "torch.inf"; Object Moon "moon" with name "moon", description "It's full and bright.", found_in Courtyard Entrance Study TowerPrison, before [; Smell, Taste, Touch, Attack, Take, Transfer: "Don't be a lunatic!"; ], has scenery; ! From exercise 3 in the Inform Designers Manual 4th ed. ! ! Errata: ! The parenthesis in calling noun.door_dir() and self.door_dir() were ! missing from the DM4 example. Omitting them caused the routine to not ! work. ! Class ObligingDoor with name "door", react_before [; Go: if (noun.door_dir() == self.door_dir()) { return self.open_by_myself(); } Enter: if (noun == self) { return self.open_by_myself(); } ], open_by_myself [ ks; if (self has open) rfalse; print "(first opening ", (the) self, ")^"; ks = keep_silent; keep_silent = true; ; keep_silent = ks; if (self hasnt open) rtrue; ], has door; ! Maybe we don't want to make it lockable. ! has door openable static lockable; Class Stone with name "small" "stone" "rock", short_name "small stone", description "This stone would not be good for skipping.", plural "stones", parse_name [i j w; if (parser_action == ##TheSame) { if ((parser_one.&name)-->0 == (parser_two.&name)-->0) return -1; return -2; } w = (self.&name)-->0; for (::i++) { j = NextWord(); if (j == 'stones') parser_action=##PluralFound; else if (j~='stone' or w) return i; } ]; Class Bottle with name "bottle", parse_name [ i j w; if (parser_action == ##TheSame) { if ((parser_one.&name)-->0 == (parser_two.&name)-->0) return -1; return -2; } w = (self.&name)-->0; for (::i++) { j = NextWord(); if (j == 'bottles') parser_action=##PluralFound; else if (j~='bottle' or w) return i; } ], before [; Empty: if (self hasnt open) { give self open; print "(first opening ", (the) self, ")^"; } if (child(self) has liquid) { remove child(self); "The contents dribble out and evaporates."; } Receive: if (noun hasnt liquid or is_tiny) { print (The) noun, " is too big to fit in ", (the) self, "."; ""; } ], has container openable; Class Vial with name "vial" "phial", parse_name [ i j w; if (parser_action == ##TheSame) { if ((parser_one.&name)-->0 == (parser_two.&name)-->0) return -1; return -2; } w = (self.&name)-->0; for (::i++) { j = NextWord(); if (j == 'vials') parser_action=##PluralFound; else if (j~='vial' or w) return i; } ], before [; Empty: if (self hasnt open) { give self open; print "(first opening ", (the) self, ")^"; } if (child(self) has liquid) { remove child(self); "The contents dribble out and evaporates."; } Receive: if (noun hasnt liquid or is_tiny) { print (The) noun, " is too big to fit in ", (the) self, "."; ""; } ], capacity 1, has container openable; Class Gem with name "gem", parse_name [i j w; if (parser_action == ##TheSame) { if ((parser_one.&name)-->0 == (parser_two.&name)-->0) return -1; return -2; } w = (self.&name)-->0; for (::i++) { j = NextWord(); if (j == 'gems') parser_action=##PluralFound; else if (j~='gem' or w) return i; } ]; Class Coin with name "coin", parse_name [ i j w; if (parser_action == ##TheSame) { if ((parser_one.&name)-->0 == (parser_two.&name)-->0) return -1; return -2; } w = (self.&name)-->0; for (::i++) { j = NextWord(); if (j == 'coins') parser_action=##PluralFound; else if (j~='coin' or w) return i; } ], has is_coin is_tiny; Class CopperCoin class Coin, with name "copper", short_name "copper coin", description "It's a copper coin of some sort.", plural "copper coins"; Class GoldCoin class Coin with name "gold" "golden", short_name "gold coin", description "This coin has a mark on it that looks like a human skull.", plural "gold coins"; Class Key with name "key", parse_name [i j w; if (parser_action == ##TheSame) { if ((parser_one.&name)-->0 == (parser_two.&name)-->0) return -1; return -2; } w = (self.&name)-->0; for (::i++) { j = NextWord(); if (j == 'keys') parser_action=##PluralFound; else if (j~='key' or w) return i; } ]; Class Burnable with name "burnable", before [; Burn: if (second hasnt on) "You can't burn ", (the) self, " with ", (the) second, "."; remove self; print_ret (The) self, " quickly catches fire and burns away."; ]; Class Book class Burnable with name "book", parse_name [i j w; if (parser_action == ##TheSame) { if ((parser_one.&name)-->0 == (parser_two.&name)-->0) return -1; return -2; } w = (self.&name)-->0; for (::i++) { j = NextWord(); if (j == 'books') parser_action=##PluralFound; else if (j~='book' or w) return i; } ]; ! Putting stuff on and under the rug is handled in verbs.inf ! Class Rug with name "rug" "carpet", description [; if (self hasnt general) "It's a beautifully woven rug."; else "It's a rolled up rug."; ], describe [ i thing_on_rug; if (self hasnt general) print "^A beautifully woven"; else print "^A rolled up"; print " rug is in the middle of the room.^"; thing_on_rug = false; objectloop (i in self) { if (i has on_rug) thing_on_rug = true; } if (thing_on_rug) { print "^On the rug you see:^"; objectloop (i in self) { if (i has on_rug) print " ", (a) i; } ""; } rtrue; ], before [; Enter: "You walk around on the rug a bit."; Receive: if (self hasnt general) { move noun to self; give noun concealed; "You put ", (the) noun, " under ", (the) self, "."; } "That's difficult to do while the rug is rolled up."; Burn: if (second ~= nothing) { if (second hasnt on) { "You can't burn ", (the) self, " with ", (the) second, "."; } } else { "You can't burn ", (the) self, " without something that burns."; } print "The rug quickly catches fire and burns away."; if (self hasnt general) self.reveal_contents(); else print "^"; remove self; rtrue; Transfer, Take: print "The rug is far too heavy and cumbersome for one person to carry"; if (self has general) print ", even when rolled up"; "."; Search, LookUnder, Roll: if (self hasnt general) { print "You roll up the rug."; self.reveal_contents(); give self general; rtrue; } "It's already rolled up."; Open, Unroll: if (self has general) { give self ~general; "You unroll the rug."; } "It's already unrolled."; ], reveal_contents [objcount i; objcount = 0; objectloop (i in self) { if (i hasnt on_rug) objcount++; } switch (objcount) { 0: " You find nothing underneath."; 1: print ".^^Ah! It looks like "; objectloop (i in self) { if (i hasnt on_rug) { print (a) i, " was hidden underneath ", (the) self, ".^"; } } default: print ".^^Ah! It looks like there were^"; objectloop (i in self) { if (i hasnt on_rug) { give i ~concealed; print " ", (a) i, "^"; } } print "hidden underneath ", (the) self, ".^"; } ! When the rug is rolled up, stuff on top falls off. ! while (child(self)) { give child(self) ~concealed; move child(self) to parent(self); } ], has is_rug static container enterable; Class ShinyBottle class Bottle, with name "shiny" "light" "bottle", short_name "shiny bottle", description [; print "This small silver bottle glows with a lustrous shine."; if (child(self) ofclass ShinyPotion) { " You notice that the bottle is impossibly light."; } rtrue; ], capacity 1; Class ShinyPotion with name "shiny" "potion", short_name "shiny potion", description "It looks like faintly-glowing water.", before [; Smell: "It doesn't seem to have a smell."; Drop, Take: remove self; "The potion dribbles all over the ground."; Taste: "Tasting the potion makes you feel a bit like you're floating in the air."; Eat, Drink: remove self; levitating = true; StartTimer(self, 5); "You drink the liquid and immediately begin to rise in the air."; ], time_left 0, time_out [; levitating = false; "You slowly sink back to the floor."; ], has liquid edible; Class SmellyBottle class Bottle, with name "smelly", short_name "smelly bottle", description "It's a small silver bottle. It sure smells terrible!", before [; Smell: "It smells like sewage."; ], capacity 1; Class SmellyPotion with name "smelly" "potion", short_name "smelly potion", description "The potion is a nauseating mixture of brown and yellow.", before [; Smell: "It smells like sewage."; Drop, Take: remove self; "The potion dribbles all over the ground."; Taste, Eat, Drink: remove self; deadflag = 1; "As you consume the liquid in the vial, your body convulses and death spasms quickly follow."; ], has liquid edible; ! Bottle 4 Class SlimyBottle class Bottle, with name "slimy", short_name "slimy bottle", description "This bottle is extremely slimy.", before [; Smell: "It smells like swamp water."; ], capacity 1; Class SlimyPotion with name "slimy" "potion", short_name "slimy potion", description "The potion is a viscous black substance.", before [; Smell: "It smells like tar."; Drop, Take: remove self; "The potion dribbles all over the ground."; Taste, Eat, Drink: remove self; "Glug! You swallow a bit of the viscous liquid. It's like drinking tar!"; ], has liquid edible; ! For leverroom.inf ! Class Lever with name "lever", pulled false, describe [; print (The) self, " is in the "; if (self.pulled) print "down"; else print "up"; " position."; ], description [; print "A wooden lever, currently in the "; if (self.pulled) print "down"; else print "up"; " position."; ], before [; Pull: if (LeverCylinder has open) "It won't budge."; if (self.pulled) "But it's already been pulled down."; self.pulled = true; print "You pull ", (the) self, " down.^"; LeverCylinder.flip(); rtrue; Push: if (self.pulled) { self.pulled = false; print "You push ", (the) self, " up.^"; LeverCylinder.flip(); rtrue; } "But it's already been pushed up."; ], has static; Class Skull with name "skull", parse_name [ i j w; if (parser_action == ##TheSame) { if ((parser_one.&name)-->0 == (parser_two.&name)-->0) return -1; return -2; } w = (self.&name)-->0; for (::i++) { j = NextWord(); if (j == 'skulls') parser_action=##PluralFound; else if (j~='skull' or w) return i; } ], has float;