/* * Amiga MUD * * Copyright (c) 1997 by Chris Gray */ /* * simple.m - a very simple text-only adventure. Mostly just a tutorial. */ /* First, define the basic "properties" that we will use in this world */ /* Properties on rooms: */ public north CreateThingProp()$ /* the room to the north (if any) */ public south CreateThingProp()$ /* the room to the south (if any) */ public east CreateThingProp()$ /* the room to the east (if any) */ public west CreateThingProp()$ /* the room to the west (if any) */ public desc CreateStringProp()$ /* the description of the room */ public contents CreateThingListProp()$/* the list of stuff in the room */ /* Properties on players: */ public carrying CreateThingListProp()$/* the list of stuff being carried */ /* Properties on objects: */ public name CreateStringProp()$ /* internal-form name of object */ /* use this short name to avoid some typing */ public G CreateGrammar()$ /* The rooms in our world: */ /* First, create them all so we can reference them */ public clearing CreateThing(nil)$ public forestNorth CreateThing(nil)$ public forestSouth CreateThing(nil)$ public dam CreateThing(nil)$ public forestEast CreateThing(nil)$ public forestWest CreateThing(nil)$ public overlook CreateThing(nil)$ public forestNorthWest CreateThing(nil)$ public outsideHut CreateThing(nil)$ public insideHut CreateThing(nil)$ /* Now put in their descriptions and interconnections. Also give each one a 'contents', so objects can be there. */ clearing@contents := CreateThingList()$ clearing@desc := "You are standing in a small clearing in a forest. You can go in several " "directions from here.\n"$ clearing@north := forestNorth$ clearing@south := forestSouth$ clearing@east := forestEast$ clearing@west := forestWest$ forestNorth@contents := CreateThingList()$ forestNorth@desc := "You are in the forest. The clearing is to your south. You can also go " "to the west, but other directions are blocked by the undergrowth.\n"$ forestNorth@south := clearing$ forestNorth@west := forestNorthWest$ forestSouth@contents := CreateThingList()$ forestSouth@desc := "You are in the forest, south of the clearing. There is a small path " "here, leading west by a small stream.\n"$ forestSouth@north := clearing$ forestSouth@west := dam$ dam@contents := CreateThingList()$ dam@desc := "You have come to a dam on the stream. The rocky gully here prevents you " "from going anywhere but back to the east.\n"$ dam@east := forestSouth$ forestEast@contents := CreateThingList()$ forestEast@desc := "You are in the forest. Thick bushes and trees prevent you from going " "anywhere except back west.\n"$ forestEast@west := clearing$ forestWest@contents := CreateThingList()$ forestWest@desc := "You are in the forest. A rocky ridge to the west prevents you from going " "further in that direction, but you can wander through the trees in the " "other directions.\n"$ forestWest@east := clearing$ forestWest@north := forestNorthWest$ forestWest@south := overlook$ overlook@contents := CreateThingList()$ overlook@desc := "You have come to the edge of a small cliff. You can see down into a " "rocky gully here, where there is a dam across a small stream.\n"$ overlook@north := forestWest$ forestNorthWest@contents := CreateThingList()$ forestNorthWest@desc := "You are in the forest. You can't see much here, but you can go in " "several directions through the thick bushes.\n"$ forestNorthWest@east := forestNorth$ forestNorthWest@north := outsideHut$ forestNorthWest@south := forestWest$ outsideHut@contents := CreateThingList()$ outsideHut@desc := "You are standing outside a log hut in the forest. You can go north into " "the hut, or back south into the forest.\n"$ outsideHut@south := forestNorthWest$ outsideHut@north := insideHut$ insideHut@contents := CreateThingList()$ insideHut@desc := "You are inside a small hut. It looks like a trapper or hunter uses this " "hut during the winter, but there is no-one here now. The door out is " "to the south.\n\nSitting on the floor here is a large chest, securely " "locked with an iron padlock.\n"$ insideHut@south := outsideHut$ /* Create the objects in the world: */ public ironKey CreateThing(nil)$ ironKey@name := "key;iron"$ AddTail(dam@contents, ironKey)$ /* put it at the dam */ public rock CreateThing(nil)$ rock@name := "rock;small"$ AddTail(overlook@contents, rock)$ /* put it at the overlook */ /* Now create the commands in the world. */ /* First, some handy utilities. */ public proc showAgent(thing who)void: Print(who@p_pName + " is here.\n"); corp; public proc lookAround()void: int n, i; Print(Here()@desc); n := Count(Here()@contents); if n ~= 0 then Print("Nearby:\n"); for i from 0 upto n - 1 do Print(" " + FormatName(Here()@contents[i]@name) + "\n"); od; fi; ForEachAgent(Here(), showAgent); corp; public proc move(thing where)bool: if where = nil then Print("You can't go that direction.\n"); false else OPrint(Me()@p_pName + " leaves.\n"); SetLocation(where); OPrint(Me()@p_pName + " arrives.\n"); lookAround(); true fi corp; /* Next, the commands for moving. */ public proc goNorth()bool: move(Here()@north) corp; public proc goSouth()bool: move(Here()@south) corp; public proc goEast()bool: move(Here()@east) corp; public proc goWest()bool: move(Here()@west) corp; Verb0(G, "north", 0, goNorth)$ Synonym(G, "north", "n")$ Verb0(G, "south", 0, goSouth)$ Synonym(G, "south", "s")$ Verb0(G, "east", 0, goEast)$ Synonym(G, "east", "e")$ Verb0(G, "west", 0, goWest)$ Synonym(G, "west", "w")$ /* Now, commands for getting and dropping things. */ public proc get(string what)bool: thing object; status st; if what = "" then Print("You must say what you want to get.\n"); false else st := FindName(Here()@contents, name, what); if st = fail then Print("There is no " + FormatName(what) + " here.\n"); false elif st = continue then Print(FormatName(what) + " is ambiguous.\n"); false else object := FindResult(); AddTail(Me()@carrying, object); DelElement(Here()@contents, object); Print(FormatName(what) + " taken.\n"); true fi fi corp; public proc drop(string what)bool: thing object; status st; if what = "" then Print("You must say what you want to drop.\n"); false else st := FindName(Me()@carrying, name, what); if st = fail then Print(AAn("You are not carrying", FormatName(what)) + ".\n"); false elif st = continue then Print(FormatName(what) + " is ambiguous.\n"); false else object := FindResult(); AddTail(Here()@contents, object); DelElement(Me()@carrying, object); Print(FormatName(what) + " dropped.\n"); true fi fi corp; Verb1(G, "get", 0, get)$ Synonym(G, "get", "take")$ Verb1(G, "drop", 0, drop)$ /* A couple of 'utility' commands. */ public proc bye()bool: Print("Bye-bye! Come again soon!\n"); Quit(); true corp; Verb0(G, "bye", 0, bye)$ Synonym(G, "bye", "quit")$ public proc inventory()bool: int n, i; n := Count(Me()@carrying); if n = 0 then Print("You are not carrying anything.\n"); else Print("You are carrying:\n"); for i from 0 upto n - 1 do Print(" " + FormatName(Me()@carrying[i]@name) + "\n"); od; fi; true corp; Verb0(G, "inventory", 0, inventory)$ Synonym(G, "inventory", "i")$ public proc look()bool: lookAround(); true corp; Verb0(G, "look", 0, look)$ Synonym(G, "look", "l")$ /* And now, the command which lets you win this little game. */ public proc open(string openWhat, withWhat)bool: thing object; status st; string name2; name2 := FormatName(withWhat); if openWhat == "chest" or openWhat == "chest;large" then if Here() = insideHut then st := FindName(Me()@carrying, name, withWhat); if st = fail then Print(AAn("You are not carrying", name2) + ".\n"); false elif st = continue then Print(name2 + " is ambiguous.\n"); false else object := FindResult(); if object ~= ironKey then Print("You can't open things with that!\n"); false else Print("You open the chest with the iron key.\n"); Print("Congratulations! You have solved the puzzle.\n"); true fi fi else Print("There is no chest here.\n"); false fi else Print("You can't open that!\n"); false fi corp; Verb2(G, "open", Word(G, "with"), open)$ Synonym(G, "open", "unlock")$ /* The routine needed to get and parse the player's input. */ public proc parseInput(string inputLine)void: if SubString(inputLine, 0, 1) = "\"" then Say("", SubString(inputLine, 1, Length(inputLine) - 1)); else ignore Parse(G, inputLine); fi; corp; /* And, finally, the startup stuff, where a new player connects. */ public proc newPlayer()void: Me()@carrying := CreateThingList(); SetLocation(clearing); ignore SetCharacterInputAction(parseInput); Print("Welcome to the simple MUD world, " + Me()@p_pName + "! We hope you have fun with MUD.\n\n"); lookAround(); corp; ignore SetNewCharacterAction(newPlayer)$