/**
* A handler to deal with all the living objects on the disc.
* @author Wodan
* @changed Pinkfish March 16th
* After wodan didn't add any autodoc comments and made some bits quite
* inefficent
*/
private nosave mapping _lnames = ([]);
private nosave mapping _players = ([]);
#ifdef 0
void create() {
object player, *players;
players = filter(efun::users(), (: $1 && inherits("/std/container", $1) :));
foreach(player in players) {
_players[player->query_name()] = player;
}
}
#endif
/**
* This method checks through the living names in the handler and
* removes an invalid entries.
* @param names an array of strings which contains the names of
* the creatures to check in the array.
*/
private void check_lnames(string* names) {
string key;
foreach (key in names) {
mixed bing = _lnames[key];
// If the values are an array, then remove any zeros and check
// to see if we can clean up.
if (arrayp(bing)) {
bing -= ({ 0 });
if (sizeof(bing)) {
_lnames[key] = bing;
}
else {
// It's empty, so clean it up.
map_delete(_lnames, key);
}
}
else {
// We got an undefined or non-array value, so let's delete
// the key from the mapping.
map_delete(_lnames, key);
}
}
} /* check_lname() */
/**
* Same checks as in check_lname(), but for the _players
* mapping instead.
* @see check_lnames()
*/
private void check_players(string* names) {
string key;
foreach (key in names) {
mixed bing = _players[key];
if (arrayp(bing)) {
bing -= ({ 0 });
if (sizeof(bing)) {
_players[key] = bing;
}
else {
map_delete(_players, key);
}
}
else {
map_delete(_players, key);
}
}
} /* check_lname() */
/**
* Removes all the not very useful things from the huge mapping.
*/
void remove_garbage(){
string* names;
int i;
names = keys(_lnames);
for (i = 0; i < sizeof(names); i += 50) {
call_out((: check_lnames :), i / 25, names[i..i+50]);
}
names = keys(_players);
for (i = 0; i < sizeof(names); i += 50) {
call_out((: check_players :), i / 25, names[i..i+50]);
}
}
/**
* Enables commands on the object.
* @param ob the object to enable the commands on
*/
void enable_commands(object ob){
}
/**
* This method registers the living name with the specific object.
* @param name the name to register
* @param ob the object to register it with
*/
void set_living_name(string name, object ob){
if (!stringp(name) || !objectp(ob)) {
return ;
}
if(!_lnames[name]) {
_lnames[name] = ({ob});
} else {
_lnames[name] += ({ob});
}
if ( ob == master() ) {
log_file( "LIVINGS", "%O (%s) became a living. %O\n", ob,
name, call_stack(0) );
}
}
/**
* This method returns the name of all the named livings in the game.
* Do not use this method except for debugging.
*/
object *named_livings(){
object *ret;
ret = keys(_lnames);
ret = map(ret, (:$1?(_lnames)[$1]:0:));
reset_eval_cost();
ret = filter(ret, (:$1:));
reset_eval_cost();
ret = implode(ret, (:$1 + $2:));
reset_eval_cost();
ret = filter(ret, (:$1:));
return ret;
}
/**
* Returns the living object associated with the name.
* @return the living object
*/
object find_living(string it) {
if(_lnames[it]) {
_lnames[it] = filter(_lnames[it], (: $1 :));
if(sizeof(_lnames[it]))
return _lnames[it][<1];
}
return 0;
}
/**
* Returns the player associated with the name.
* @return the player object
*/
object find_player(string it) {
object *people;
int t = real_time();
object *tmp;
if(_players[it]) {
// temporarily removed this
// if(reference_allowed(_players[it]))
return _players[it];
return 0;
}
//reset_eval_cost();
people = filter(efun::users(), (: $1 && $1->query_name() == $(it) &&
inherits("/std/container", $1):));
if(sizeof(people)) {
_players[it] = people[0];
if(real_time() - t > 1)
log_file("GARBAGE", "find_player took %d seconds to find %s (1)\n",
real_time() - t, it);
// --temporarily removed this..
// if(reference_allowed(_players[it]))
return _players[it];
}
if(!_lnames[it]) {
if(real_time() - t > 1)
log_file("GARBAGE", "find_player took %d seconds to find %s (2)\n",
real_time() - t, it);
return 0;
}
tmp = filter(_lnames[it], (: $1 && userp($1) :));
if(real_time() - t > 1)
log_file("GARBAGE", "find_player took %d seconds to find %s (3)\n",
real_time() - t, it);
if(sizeof(tmp))
return tmp[0];
return 0;
}
/**
* These two are not here because the handler can be saved, but to keep
* the info over updates.
* @ignore yes
*/
mapping query_dynamic_auto_load() {
mapping tmp;
tmp = ([ "lnames" : _lnames,
"players" : _players,
]);
return tmp;
}
/**
* @ignore yes
*/
void init_dynamic_arg(mapping maps) {
object ob;
string name;
if (maps["lnames"])
_lnames = maps["lnames"];
if (maps["players"])
_players = maps["players"];
foreach(ob in efun::users()){
if ( !ob ) {
continue;
}
name = ob->query_name();
_players[name] = ob;
if(!_lnames[name]){
_lnames[name] = ({ob});
} else {
_lnames[name] |= ({ob});
}
}
}
mixed *stats() {
return ({ ({ "lnames", sizeof(keys(_lnames)) }),
({ "players", sizeof(keys(_players)) })});
}