"gopher-weather-map.moo 8/29/93 "A weather map, based on gopher, that displays real data. "Copyright (c) 1992, 1993, Larry Masinter. All Rights Reserved. "Permission granted to use this software for non-commercial purposes. "I'd appreciate it if you let me know if you use this or extend it. "Version 1.0 -- first release "To install, create an object, and then edit this to replace #79 with the object number. @create $thing named Weather Map:Weather Map,Map @prop #79."state" {} rc ;#79.("state") = {"NM", "New Mexico"} @prop #79."setting" "Temperature (F)" r @prop #79."states" {} rc ;#79.("states") = {{"AB", "Alberta", "Canada"}, {"AK", "Alaska"}, {"AL", "Alabama"}, {"AR", "Arkansas"}, {"AZ", "Arizona"}, {"CA", "California", "States", " (central)", " (south)", " (north)"}, {"CO", "Colorado"}, {"FL", "Florida"}, {"GA", "Georgia"}, {"IA", "Iowa"}, {"ID", "Idaho"}, {"IL", "Illinois"}, {"IN", "Indiana"}, {"KS", "Kansas"}, {"KY", "Kentucky"}, {"LA", "Louisiana"}, {"LI", "Long Island"}, {"MA", "Massachusetts"}, {"MD", "Maryland"}, {"ME", "Maine"}, {"MI", "Michigan"}, {"MN", "Minnesota"}, {"MO", "Missouri"}, {"MS", "Mississippi"}, {"MT", "Montana"}, {"NC", "North Carolina"}, {"ND", "North Dakota"}, {"NE", "Nebraska"}, {"NJ", "New Jersey"}, {"NM", "New Mexico"}, {"NV", "Nevada"}, {"NY", "New York"}, {"OH", "Ohio"}, {"OK", "Oklahoma"}, {"OR", "Oregon"}, {"PA", "Pennsylvania"}, {"SC", "South Carolina"}, {"SD", "South Dakota"}, {"TX", "Texas", "States", " (south)", " (north)", " (west)"}, {"TN", "Tennessee"}, {"MI", "Michigan", "States", "", " (upper pen)"}, {"UT", "Utah"}, {"VA", "Virginia"}, {"VT", "Vermont"}, {"WA", "Washington"}, {"WI", "Wisconsin"}, {"WV", "West Virginia"}, {"WY", "Wyoming"}, {"BC", "British Columbia", "Canada"}, {"MB", "Manitoba", "Canada"}, {"NW", "Northwest Territories", "Canada"}, {"SK", "Saskatchewan", "Canada"}, {"YK", "Yukon", "Canada"}} @prop #79."help_msg" {} rc ;#79.("help_msg") = {"A retargetable weather map.", " turn map to ", " point at another state", " set map to ", " change what property the map is showing.", " press on map", " ask map for ", " get a city forecast", " only for cities in the state you're looking at.", " press forecast on map", " ask map for forecast", " get the state forecast.", "", "see help for those verbs for more details.", " help map:turn", " help map:set", " help map:press"} @prop #79."place" {} r ;#79.("place") = {"wx.atmos.uiuc.edu", 70, "0/States/New Mexico/Surface Ascii Map", "0MN"} @prop #79."busy" 0 rc ;#79.("aliases") = {"Weather Map", "Map"} ;#79.("description") = {"An electronic weather map.", "", " Interesting verbs with help are: turn, set, press.", "The map gets real data from a gopher weather server.", "", "The map is blank at the moment."} ;#79.("object_size") = {11613, 746606078} @verb #79:"integrate_room_msg" this none this @program #79:integrate_room_msg return ((("You see a large electronic map of " + this.state[2]) + ". The legend below it reads ") + this.setting) + "."; . @verb #79:"set" this to any @program #79:set "set map to "; " change the map to display a different weather property."; " Maps include those for temperature, dew point, wind, wind gusts,"; " pressure, altimeter, visibility, cloud ceiling, weather, elevations"; " station names are the codes for weather stations"; "set map to legend"; " shows the names of the cities for the various weather stations."; if (this:busy("setting to " + iobjstr)) return; endif if (!(what = this:find(iobjstr))) if (!(what = this:find("settings"))) player:tell($string_utils:pronoun_sub(tostr("Sorry, %t seems not to work for ", this.state[2], " at the moment."))); else player:tell("Sorry, '", iobjstr, "' is not a valid setting for ", this:title(), ". Use one of:"); player:tell_lines(this:find("settings")); endif else this.location:announce_all($string_utils:pronoun_sub("%N sets %d to "), this.setting = $string_utils:trim(what[1]), "."); endif this:busy(); . @verb #79:"description" this none this @program #79:description if (!(map = this:find(this.setting))) return this.description; endif if (this.setting == "station names") return {@map, @this:find("legend")}; else return map; endif . @verb #79:"find" this none this @program #79:find what = args[1]; if (!(text = this:text())) return {}; endif if (what == "legend") while (text && (!match(text[1], "^[A-Z0-9][A-Z0-9][A-Z0-9] +[A-Z][A-Z][A-Z0-9/ ]*$", 1))) text = listdelete(text, 1); endwhile return {"Legend", "", @text}; endif results = {}; while (!text[1]) text = listdelete(text, 1); endwhile divider = "---------------------------------------------------------"; while (next = (divider in text)) text = text[next + 2..length(text)]; if (what == "settings") results = {@results, text[1]}; elseif (index(text[1], what)) return text[1..(divider in text) || 23]; endif endwhile return results; . @verb #79:"turn" this to any @program #79:turn "turn map to "; " is either a two letter state code or a state name"; " changes the map so that it shows the given state."; " NOTE: Not all states are available from the weather service."; if (!(which = ($list_utils:iassoc(iobjstr, this.states, 2) || $list_utils:iassoc(iobjstr, this.states)))) return player:tell("Sorry, '", iobjstr, "' isn't the name of a known state."); endif state = this.states[which]; code = state[1]; place = this.place; if (this:busy("turning to " + state[2])) return; endif place[3] = (((("0" + ((length(state) > 2) ? ("/" + state[3]) + "/" | "/States/")) + state[2]) + "/Surface Ascii Map") + ((length(state) > 3) ? state[4] | "")); if ((!(map = $gopher:get(@place))) || index(map[1], "server error")) player:tell("Sorry, no map of ", state[2], " is available."); else this.place = place; this.state = state; this.location:announce_all($string_utils:pronoun_sub("%N turns %d to look at "), state[2], "."); if (!this:text()) this.location:announce_all($string_utils:pronoun_sub("%D buzzes, blinks, and goes blank.")); endif endif this:busy(); . @verb #79:"press" any on this rxd @program #79:press "press on map"; " ask the map for the forcast for the given city."; " only works for cities in the state selected!"; "press forecast on map"; " gets the forecast for the whole state"; wx = {"wx.atmos.uiuc.edu", 70}; if (dobjstr in {"forecast", "state"}) this.location:announce_all($string_utils:pronoun_sub("%N asks %t for the state forecast for "), this.state[2], "."); states = $gopher:get(@wx, "1/Forecast/State_Forecasts"); if (!states) return this.location:announce_all("Ooops, ", this.name, " isn't working right now."); endif any = 0; for state in (states) parse = $gopher:parse(state); if (index(parse[4], this.state[2])) for x in ($gopher:get(@parse)) $command_utils:suspend_if_needed(0); player:tell($string_utils:lowercase(x)); endfor any = 1; endif endfor if (!any) this.location:announce_all("No state forecast for ", this.state[2], " was found."); endif else this.location:announce_all($string_utils:pronoun_sub("%N asks %t for the forecast for "), dobjstr, "."); loc = (("1/Forecast/City_Forecasts" + (((length(this.state) > 2) && (this.state[3] == "Canada")) ? "/Canada/" | "/US/")) + this.state[1]); cities = $gopher:get(@wx, loc); if (!cities) return this.location:announce_all("No city forcasts for ", this.state[2], " are available right now."); endif known = {}; any = 0; for city in (cities) parse = $gopher:parse(city); name = parse[4]; name = name[2..length(name)]; known = {@known, name}; if (index(name, dobjstr)) for x in ($gopher:get(@parse)) $command_utils:suspend_if_needed(0); player:tell($string_utils:lowercase(x)); endfor this.location:announce_all($string_utils:pronoun_sub("%N gets the forecast for "), name, "."); any = 1; endif endfor if (!any) this.location:announce_all("Forecasts are available for ", $string_utils:english_list(known, "no cities", " or "), "."); endif endif . @verb #79:"text" none none none rxd @program #79:text text = $gopher:get(@this.place); if (((typeof(ERR = text) != LIST) || (!text)) || index(ERR = text[length(text)], "Requested region not available")) return {tostr($string_utils:pronoun_sub("%T is blank at the moment: "), ERR)}; endif return text; . @verb #79:"kick" this none none r @program #79:kick $you:say_action("%N % %t."); if (this.busy) kill_task(this.busy[4]); this:busy(); endif $gopher:clear_cache(); . @verb #79:"busy" this none this @program #79:busy if (args && args[1]) if (this.busy && (this.busy[1] > time())) player:tell("***Sorry, ", this.name, " is busy ", this.busy[2], "."); return 1; else this.busy = {time() + (60 * 5), args[1], player.name, task_id()}; return 0; endif else this.busy = 0; return 0; endif . @verb #79:"look_self" this none this @program #79:look_self player:tell(this:integrate_room_msg()); pass(@args); if (this.busy) player:tell(this.name, " is busy ", this.busy[2], " for ", this.busy[3]); endif . @verb #79:"ask" this for any @program #79:ask "ask map for => press on map"; dobjstr = iobjstr; this:press(); . "***finished***