/**
* Generates random names for whatever reason.
* <p>
* Werd - a perl script that generates random words according to some
* simple rules (inspired by phrase structure trees in Syntax).
* <p>
* Based on a program by Mark Rosenfelder (markrose@spss.com)
* called psrGrammar
* <p>
* Rewritten in perl by Chris Pound (pound@rice.edu)
* <p>
* Rewritten in lpc by Pinkfish@Discworld MUD.
* 10th of January 1996.
*/
#include <random_names.h>
mapping rules;
void create() {
seteuid("Room");
rules = ([ ]);
unguarded((: restore_object, RANDOM_NAME_SAVE_FILE :));
} /* create() */
/**
* Read in a random name grammer from the data dir. Any line with
* # at the start is considered a comment, and anything after
* a # on a line is ignored. Every line in the file will have
* 3 fields seperated by a :. The first field is the name
* the second is a one letter expansion string, the third is a
* a space separeted list of things to expand it to.
* <p>
* The word starts off as a "W", this is looked up in the expansion
* first string list. If it is found then that is expanded to
* a random selection of the space seperated data elements. This
* process is repeated until there are no bits in the word that can
* be expanded.
* @param f the name of the file to read
*/
void open_file(string f) {
string str, *bits, *stuff, lang;
int i;
bits = explode(f, ".");
if (sizeof(bits) > 1)
lang = implode(bits[0..sizeof(bits)-2], ".");
else
lang = f;
lang = replace(lang, "_", " ");
str = unguarded((: read_file, RANDOM_NAME_DATA_DIR+f :));
bits = explode(str, "\n");
rules[lang] = ([ ]);
for (i=0;i<sizeof(bits);i++) {
sscanf(bits[i], "%s#%*s", bits[i]);
if (strlen(bits[i])) {
stuff = explode("G"+bits[i], ":");
if (sizeof(stuff) >= 3)
rules[lang][stuff[1]] = stuff[2];
else
write("Incorrect file format at line "+i+".\n");
}
}
unguarded((: save_object, RANDOM_NAME_SAVE_FILE :));
} /* open_file() */
/**
* Generate a random name in the given language.
* @param lang the language to generate teh name int
* @return the random name
*/
string random_name(string lang) {
string word = "W", *bing;
int some_caps = 1, i;
do {
some_caps = 0;
for (i = 0; i < strlen(word); i++)
if (word[i] >= 'A' && word[i] <= 'Z') {
bing = explode(rules[lang][word[i..i]], " ") - ({ "" });
word = word[0..i-1] + bing[random(sizeof(bing))] + word[i+1..];
some_caps = 1;
}
} while (some_caps);
return word;
} /* random_name() */
/**
* The list of all the current languages known.
* @return an array of the language names.
*/
string *query_languages() { return keys(rules); }
/**
* Return a name that is not banished or a player name already.
* It is > 2 and < 11 chars, it is not banished, a player or
* in the game.
* @param lang the language to generat ethe name in
* @return the generated name
*/
string unique_name(string lang) {
string str;
int ok;
do {
ok = 1;
str = random_name(lang);
if (strlen(str) < 2 || strlen(str) > 11)
ok = 0;
if (ok && "/secure/login"->test_user(str))
ok = 0;
if (ok && file_size("/banished/"+str+".o") > 0)
ok = 0;
if (ok && find_living(str))
ok = 0;
} while (!ok);
return str;
} /* unique_name() */
/** @ignore yes */
void dest_me() {
destruct(this_object());
} /* dest_me() */