| /************************************************************************* | |
| * Possess.t: Using possessives as adjectives. | |
| * | |
| * By Garth Dighton, with help from Mike Roberts and Kevin Forchione on RAIF | |
| * This module is freely distributable and modifiable, as long as the credits | |
| * remain intact. | |
| * | |
| * This module enables players to refer to objects in the possession of actors | |
| * with possessive adjectives: "ASK JANE ABOUT HER BOX, ASK BOB ABOUT GEORGE'S | |
| * BOX", or similar. | |
| * | |
| * To use, each Actor should have the possessives property -- a list of | |
| * single-quoted words which are added to the adjectives list of objects they | |
| * carry. 'Her' and 'his' can be ignored. | |
| * Example: | |
| * Jane: Actor | |
| * noun = 'jane' | |
| * adjective = 'plain' | |
| * sdesc = "Jane" | |
| * possessives = ['jane\'s' 'girl\'s'] | |
| * ; | |
| * If any of these functions are overridden in your code, you'll have to make | |
| * adjustments: | |
| * thing.moveInto | |
| * parseNounPhrase | |
| * parseDisambig | |
| * Functions added | |
| * thing.Grab() -- Hook called when something is removed from an object's | |
| * possession. | |
| * thing.Accept() -- Hook called when somthing is moved into an object's | |
| * possession. | |
| * These functions are overridden in Actor to provides the necessary | |
| * functionality. You can still add your own code, as long as the Actor code | |
| * gets called | |
| *******************************************************************/ | |
| #ifndef POSSESS_T | |
| #define POSSESS_T | |
| #pragma C+ | |
| modify thing | |
| // Add an Accept(obj) hook to moveInto: | |
| moveInto(obj) = | |
| { | |
| local loc; | |
| /* | |
| * For the object containing me, and its container, and so forth, | |
| * tell it via a Grab message that I'm going away. | |
| */ | |
| loc = self.location; | |
| while (loc) | |
| { | |
| loc.Grab(self); | |
| loc = loc.location; | |
| } | |
| if (self.location) | |
| self.location.contents = self.location.contents - self; | |
| self.location = obj; | |
| if (obj) { | |
| obj.contents = obj.contents + self; | |
| loc = self.location; | |
| while (loc) | |
| { | |
| loc.Accept(self); | |
| loc = loc.location; | |
| } | |
| } | |
| } | |
| Grab(obj) = {} | |
| Accept(obj) = {} | |
| ; | |
| modify Actor | |
| Grab(obj) = { | |
| local i; | |
| for (i = 1; i <= length(self.possessives); i++) { | |
| delword(obj, &adjective, self.possessives[i]); | |
| } | |
| } | |
| Accept(obj) = { | |
| local i; | |
| for (i = 1; i <= length(self.possessives); i++) { | |
| addword(obj, &adjective, self.possessives[i]); | |
| } | |
| } | |
| ; | |
| // Returns true if the word is a noun of the object | |
| // Used to eliminate adjective-only matches. Necessary because parseNounList | |
| // does _not_ seem to return the correct value for PRSFLG_ENDADJ!!! | |
| isNounOf: function (word, obj) | |
| { | |
| local lst = getwords(obj, &noun); | |
| if (find(lst, word)) return true; else return nil; | |
| } | |
| // parseNounPhrase function by Kevin Forchione and Mike Roberts, in response | |
| // to a request for help made on rai-f. | |
| // Modified to handle 'his' (though not 'my' or other possessives). Also | |
| // modified to check that the objects exist within a valid person (ideally the | |
| // current 'her' or 'him'). | |
| // Further modified to eliminate matches ending in adjectives if there's any | |
| // other match. | |
| parseNounPhrase: function(wordList, typeList, current_index, | |
| complain_on_no_match, is_actor_check) | |
| { | |
| local i, next_index, next_token, ret, lst = []; | |
| local pos = parserGetObj(PO_HER); | |
| local found = nil; | |
| local gender = &isHer; | |
| local eliminateAdj = nil; | |
| local lastword = nil; | |
| /* let the parser handle noun phrases that don't start with 'her' */ | |
| if (wordList[current_index] != 'R' and wordList[current_index] != 'his') | |
| return PNP_USE_DEFAULT; | |
| if (wordList[current_index] != 'R') { | |
| pos = parserGetObj(PO_HIM); | |
| gender = &isHim; | |
| } | |
| /* | |
| * 'her' is the last word of the noun phrase, so it is not | |
| * being used as a possessive pronoun. | |
| */ | |
| if (length(wordList) == current_index) | |
| return PNP_USE_DEFAULT; | |
| /* set the next_index */ | |
| next_index = current_index + 1; | |
| /* get the next word's type */ | |
| next_token = typeList[next_index]; | |
| /* | |
| * If the next word is an article then 'her' is not being used as a | |
| * possessive pronoun. | |
| */ | |
| if ((next_token & PRSTYP_ARTICLE) != 0) | |
| return PNP_USE_DEFAULT; | |
| /* | |
| * If the next word cannot be an adjective, noun, or plural then | |
| * 'her' is not being used as a possessive pronoun. | |
| */ | |
| if ((next_token & PRSTYP_ADJ) == 0 | |
| && (next_token & PRSTYP_NOUN) == 0 | |
| && (next_token & PRSTYP_PLURAL) == 0) | |
| return PNP_USE_DEFAULT; | |
| ret = parseNounList(wordList, typeList, next_index, | |
| nil, nil, nil); | |
| /* | |
| * We don't have a syntactically valid noun phrase, so assume | |
| * that 'her' is not being used as a possessive pronoun. | |
| */ | |
| if (ret == nil) | |
| return PNP_USE_DEFAULT; | |
| /* | |
| * There are 2 cases to examine: no noun phrase or a syntactically | |
| * valid noun phrase, but with no matching objects. | |
| */ | |
| if (length(ret) == 1) | |
| /* | |
| * No noun phrase. The first word isn't a noun, adjective, | |
| * article, etc. | |
| */ | |
| if (ret[1] == current_index) | |
| return PNP_USE_DEFAULT; | |
| else { | |
| goto noObjects; | |
| } | |
| /* | |
| * We have a valid noun phrase, let's assume that 'her' is being | |
| * used as a possessive. We'll restructure the return from | |
| * parseNounList() so that it can be returned from | |
| * parseNounPhrase(). | |
| */ | |
| lst += ret[1]; | |
| lastword = wordList[ret[2][2]]; | |
| /* First we see if there are any objects within the current "her" | |
| * object. If so, we will return those possible objects only. | |
| * | |
| * We also note if the match ended with a noun -- if so, we will later | |
| * eliminate all adjective-only matches | |
| */ | |
| for (i = 3; i <= length(ret[2]); i += 2) { | |
| if (not ret[2][i].isIn(pos)) continue; | |
| lst += ret[2][i]; | |
| lst += ret[2][i+1]; | |
| if (isNounOf(lastword, ret[2][i])) eliminateAdj = true; | |
| found = true; | |
| } | |
| /* If there weren't any valid objects within 'her', check for objects | |
| * within _any_ female. | |
| */ | |
| if (not found) { | |
| for (i = 3; i < length(ret[2]); i += 2) { | |
| if (ret[2][i].location == nil or not ret[2][i].location.(gender)) | |
| continue; | |
| lst += ret[2][i]; | |
| lst += ret[2][i+1]; | |
| if (isNounOf(lastword, ret[2][i])) eliminateAdj = true; | |
| found = true; | |
| } | |
| } | |
| if (not found) goto noObjects; | |
| if (not eliminateAdj) return lst; | |
| // Eliminate any match which did not end in a noun. We use "ret" instead | |
| // of "lst" for the return value in this case. | |
| ret = [] + lst[1]; | |
| for (i = 2; i <= length(lst); i+=2) { | |
| if (isNounOf(lastword, lst[i])) { | |
| ret += lst[i]; | |
| ret += lst[i+1]; | |
| } | |
| } | |
| return ret; | |
| noObjects: | |
| /* | |
| * Syntactically valid noun phrase with no matching objects! | |
| */ | |
| "I don't see any "; | |
| for (i = next_index; i <= length(wordList); ++i) | |
| { | |
| say(wordList[i]); | |
| " "; | |
| } | |
| "here. "; | |
| return PNP_ERROR; | |
| } | |
| parseDisambig: function(str, lst) | |
| { | |
| local i, tot, cnt; | |
| local mystr = str; | |
| // Remove possessives (R, his, my, and words ending in 's) from the noun | |
| // phrase before asking. This is particularly necessary in the case of R, | |
| // because "Which R box do you mean..." is particularly annoying! | |
| local match = reSearch('R |his |my |%<%w*\'s%>', str); | |
| if (match) { | |
| // using length(str) for the length of the second substr will | |
| // guarantee that it goes to the end-of-string. A hack, but easier | |
| // than calculating. | |
| mystr = substr(str, 1, match[1]-1) + | |
| substr(str, match[1]+match[2], length(str)); | |
| } | |
| "Which << mystr >> do you mean, "; | |
| for (i = 1, cnt = length(lst) ; i <= cnt ; ++i) | |
| { | |
| lst[i].thedesc; | |
| if (i < cnt) ", "; | |
| if (i + 1 == cnt) "or "; | |
| } | |
| "?"; | |
| } | |
| #ifdef VERSION | |
| // versionTag for Jeff Laing's version.t module | |
| possessiveVersion: versionTag | |
| author = 'Garth Dighton' | |
| func = 'possessive handling' | |
| ; | |
| #endif VERSION | |
| #endif | |
Xet Storage Details
- Size:
- 8.06 kB
- Xet hash:
- a10a9df7cb37380cd1b373c2e8679eded6961a5eb106582abeb8ed5fc40538ae
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.