/* /adm/simul_efun/english.c
* from Dead Souls
* efuns for dealing with the oddity we know as the English language
* created by Descartes of Borg 940207
* Version: @(#) english.c 1.5@(#)
* Last modified: 97/01/01
*/
#include <daemons.h>
string *localcmds;
string match_command(string verb){
string *local_arr;
localcmds = ({});
filter(this_player()->GetCommands(), (: localcmds += ({ $1[0] }) :));
localcmds += CMD_D->GetCommands();
localcmds += keys(VERBS_D->GetVerbs());
if(member_array(verb,localcmds) == -1){
if(alphap(verb[0..0])) local_arr = regexp(localcmds,"^"+verb);
if(sizeof(local_arr) == 1) {
return local_arr[0];
}
}
return "";
}
varargs string add_article(string str, int def) {
if( !stringp(str) ) {
error("Bad argument 1 to add_article().\n");
}
if( def ) {
str = remove_article(str);
return "the " + str;
}
if( !strlen(str) ) {
return str;
}
switch(str[0]) {
case 'a': case 'e': case 'i': case 'o': case 'u':
case 'A': case 'E': case 'I': case 'O': case 'U':
return "an " + str;
default:
return "a " + str;
}
}
string remove_article(string str) {
string tmp;
if( !stringp(str) ) error("Bad argument 1 to remove_article().\n");
if( sscanf(str, "the %s", tmp) ) return tmp;
if( sscanf(str, "a %s", tmp) ) return tmp;
if( sscanf(str, "an %s", tmp) ) return tmp;
return str;
}
string array explode_list(string list) {
string array items;
string one, two;
list = lower_case(list);
if( sscanf(list, "%s and %s", one, two) == 2 ) {
items = explode(one, ",") + explode(two, ",");
}
else {
items = explode(list, ",");
}
items = map(items, function(string str) {
if( !str ) {
return 0;
}
str = trim(str);
if( strlen(str) > 4 && str[0..3] == "and " ) {
str = str[4..];
}
str = remove_article(str);
if( strlen(str) > 3 && str[0..2] == "my " ) {
str = str[3..];
}
return str;
});
return filter(items, (: $1 && $1 != "" :));
}
varargs string item_list(mixed array items...) {
mapping list = ([]);
string str;
int maxi;
if( !sizeof(items) ){
error("Bad argument 1 to item_list().\n");
}
if( arrayp(items[0]) ) {
if( !sizeof(items[0]) ) {
return "";
}
items = items[0];
}
foreach(mixed value in items) {
if( objectp(value) ) {
if( living(value) ) {
value = value->GetName();
}
else {
value = value->GetShort();
}
}
if( !value ) {
continue;
}
if( !list[value] ) {
list[value] = 1;
}
else {
list[value]++;
}
}
maxi = sizeof(items = keys(list));
if( maxi < 1 ) {
return "";
}
str = consolidate(list[items[0]], items[0]);
if( maxi == 1 ) {
return str;
}
if( maxi > 2 ) {
str += ",";
}
for(int i=1; i<maxi; i++) {
if( i == maxi-1 ) {
str += " and ";
}
else {
str += " ";
}
str += consolidate(list[items[i]], items[i]);
if( i < maxi-1 ) {
str += ",";
}
}
return str;
}
string possessive_noun(mixed val) {
if(objectp(val)) val = (string)val->GetName();
else if(!stringp(val)) error("Bad argument 1 to possessive_noun().\n");
switch(val[strlen(val)-1]) {
case 'x': case 'z': case 's': return sprintf("%s'", val);
default: return sprintf("%s's", val);
}
}
string possessive(mixed val) {
switch(objectp(val) ? (string)val->GetGender() : (string)val) {
case "male": return "his";
case "female": return "her";
case "neutral": return "hir";
default: return "its";
}
}
string strip_article(mixed val) {
int x;
if( objectp(val) ) val = (string)val->GetShort();
x = strlen(val);
if( x <= 2 ) return val;
if( val[0..1] == "a " || val[0..1] == "A " ) return val[2..];
if( x <= 3 ) return val;
if( val[0..2] == "an " || val[0..2] == "An " ) return val[3..];
if( x <= 4 ) return val;
if( val[0..3] == "the " || val[0..3] == "The " ) return val[4..];
return val;
}
string nominative(mixed val) {
switch(objectp(val) ? (string)val->GetGender() : (string)val) {
case "male": return "he";
case "female": return "she";
case "neutral": return "sie";
default: return "it";
}
}
string objective(mixed val) {
switch(objectp(val) ? (string)val->GetGender() : (string)val) {
case "male": return "him";
case "female": return "her";
case "neutral": return "hir";
default: return "it";
}
}
string reflexive(mixed val) { return sprintf("%sself", objective(val)); }
/*
#define VOWELS ({"a","e","i","o","u"})
#define ABNORMAL ([ "moose":"moose", "mouse":"mice", "die":"dice", "index":"indices", "human":"humans", "sheep":"sheep", "fish":"fish", "child":"children", "ox":"oxen", "tooth":"teeth", "deer":"deer", "bus":"busses" ])
string pluralize(mixed single) {
int x, i, y, ind;
string str, tmp, tmp1;
string *words;
if(objectp(single)) {
if(str = (string)single->query_plural_name()) return str;
else str = (string)single->GetKeyName();
}
else if(stringp(single)) str = (string)single;
else error("Bad argument 1 to pluralize()");
if(!str) return str;
i = sizeof(words = explode(str, " "));
if( i > 1 && words[i-1][0] == '(' && words[i-1][1<] == ')' )
return pluralize( implode(words[1..(i-2)]), " " );
if(words[0] == "a" || words[0] == "an" || words[0] == "the")
i = sizeof(words = words[1..(i-1)]);
if((y=member_array("of", words)) > 0 || (y=member_array("Of",words))>0)
str = words[ind = y-1];
else str = words[ind = i-1];
x = strlen(str);
if(ABNORMAL[str]) return ABNORMAL[str];
if(x > 2 && str[x-3..x-1] == "man") {
words[ind] = str[0..x-3]+"en";
return implode(words, " ");
}
if(x > 1) {
tmp = str[x-2..x-1];
switch(tmp) {
case "ch": case "sh":
words[ind] = sprintf("%ses", str);
return implode(words, " ");
case "ff": case "fe":
words[ind] = sprintf("%sves", str[0..x-3]);
return implode(words, " ");
case "us":
words[ind] = sprintf("%si", str[0..x-3]);
return implode(words, " ");
case "um":
words[ind] = sprintf("%sa", str[0..x-3]);
return implode(words, " ");
case "ef":
words[ind] = sprintf("%ss", str);
return implode(words, " ");
}
}
tmp = str[x-1..x-1];
switch(tmp) {
case "o": case "x": case "s":
words[ind] = sprintf("%ses", str);
return implode(words, " ");
case "f":
words[ind] = sprintf("%sves", str[0..x-2]);
return implode(words, " ");
case "y":
if(member_array(str[x-2..x-2],VOWELS)!=-1)
words[ind] = sprintf("%ss",str);
else
words[ind] = sprintf("%sies", str[0..x-2]);
return implode(words, " ");
}
words[ind] = sprintf("%ss", str);
return implode(words, " ");
}
*/
string cardinal(int x) {
string tmp;
int a;
if(!x) return "zero";
if(x < 0) {
tmp = "negative ";
x = absolute_value(x);
}
else tmp = "";
switch(x) {
case 1: return tmp+"one";
case 2: return tmp+"two";
case 3: return tmp+"three";
case 4: return tmp+"four";
case 5: return tmp+"five";
case 6: return tmp+"six";
case 7: return tmp+"seven";
case 8: return tmp+"eight";
case 9: return tmp+"nine";
case 10: return tmp+"ten";
case 11: return tmp+"eleven";
case 12: return tmp+"twelve";
case 13: return tmp+"thirteen";
case 14: return tmp+"fourteen";
case 15: return tmp+"fifteen";
case 16: return tmp+"sixteen";
case 17: return tmp+"seventeen";
case 18: return tmp+"eighteen";
case 19: return tmp+"nineteen";
case 20: return tmp+"twenty";
default:
if(x > 1000000000) return "over a billion";
else if(a = x /1000000) {
if(x = x %1000000)
return sprintf("%s million %s", cardinal(a), cardinal(x));
else return sprintf("%s million", cardinal(a));
}
else if(a = x / 1000) {
if(x = x % 1000)
return sprintf("%s thousand %s", cardinal(a), cardinal(x));
else return sprintf("%s thousand", cardinal(a));
}
else if(a = x / 100) {
if(x = x % 100)
return sprintf("%s hundred %s", cardinal(a), cardinal(x));
else return sprintf("%s hundred", cardinal(a));
}
else {
a = x / 10;
if(x = x % 10) tmp = "-"+cardinal(x);
else tmp = "";
switch(a) {
case 2: return "twenty"+tmp;
case 3: return "thirty"+tmp;
case 4: return "forty"+tmp;
case 5: return "fifty"+tmp;
case 6: return "sixty"+tmp;
case 7: return "seventy"+tmp;
case 8: return "eighty"+tmp;
case 9: return "ninety"+tmp;
default: return "error";
}
}
}
}
varargs string conjunction(mixed expressions, string coordinator) {
int size;
string tmp;
if(!expressions) error("Bad argument 1 to conjunction().\n");
else if(stringp(expressions)) expressions = ({ expressions });
else if(!pointerp(expressions))
error("Bad argument 1 to conjunction().\n");
size = sizeof(expressions);
if(size < 2) return expressions[0];
// Form the conjunction.
if(!coordinator) coordinator = "and";
tmp = "";
for(int i = 0; i < size; i++) {
tmp += expressions[i];
if(i < size - 2) tmp += ", ";
else return tmp + ", " + coordinator + " " + expressions[size - 1];
}
}
string consolidate(int x, string str) {
string array words;
string tmp;
if( x == 1 || !sizeof(str) ) return str;
words = explode(str, " ");
if( sscanf(words[<1], "(%s)", tmp) ) {
if( sizeof(words) == 1 )
return "(" + consolidate(x, tmp) + ")";
else return consolidate(x, implode(words[0..<2], " ")) +
" (" + tmp + ")";
}
if( sscanf(words[<1], "[%s]", tmp) ) {
if( sizeof(words) == 1 )
return "[" + consolidate(x, tmp) + "]";
else return consolidate(x, implode(words[0..<2], " ")) +
" [" + tmp + "]";
}
if( words[0][0..1] == "%^" ) {
string array parts;
string part, colour = "";
int i = 0;
parts = explode(words[0], "%^");
if( sizeof(parts) == 1 ) {
if( sizeof(words) == 1 ) return words[0];
else return words[0] + consolidate(x, implode(words[1..], " "));
}
foreach(part in parts) {
if( sizeof(part) && !sizeof(strip_colours("%^" + part + "%^")) )
colour += ("%^" + part + "%^");
else return colour + consolidate(x,
(implode(parts[i..], "%^")) + " " +
(implode(words[1..], " ")) );
i++;
}
return words[0] + " " + consolidate(x, implode(words[1..], " "));
}
if( member_array(lower_case(strip_colours(words[0])),
({"a", "an", "the", "one"}) ) > -1 ) words = words[1..];
return (cardinal(x) + " " + pluralize(implode(words, " ")));
}