// File: /std/user.c
// Original Authors: Sulam and Buddha @ The Mud Institute
// Many other people have added to this as well.
//
// This file has a long revision history dating back to the
// hideous mudlib.n and is now probably not at all the same.
// This is the standard user object.
// This file is a part of the TMI distribution mudlib.
// Please keep this header with any code within.
#include <config.h>
#include <money.h>
#include <daemons.h>
#include <move.h>
#include <flags.h>
#include <user.h>
#include <priv.h>
#include <uid.h>
int coins_carried() ;
void get_email(string e) {
string who, where;
write("\n");
if( sscanf(e, "%s@%s", who, where) != 2 ) {
write("Sorry, email must be in the form of user@host\n");
write("Please reenter your email address: ");
input_to("get_email");
return;
}
set("email", e);
}
void basic_commands() {
add_action("quit", "quit");
}
/*
* Move the player to another room. Give the appropriate
* message to on-lookers.
* The optional message describes the message to give when the player
* leaves.
*/
// This one's due for a rewrite. -Buddha
varargs int move_player(mixed dest, string message) {
object prev;
int res;
prev = environment( this_object() );
if( res = move(dest) != MOVE_OK ) {
write("You remain where you are.\n");
return res;
}
if((int)query("brief") == 2) set("brief", 1);
if (message == "SNEAK") {
command("look") ;
return 0 ;
}
if( !query("invisible") )
if( message == 0 || message == "" )
tell_room(prev, query_mmout() + "\n", ({ this_object() }));
else tell_room( prev, message + "\n", ({ this_object() }) );
if( !query("invisible") )
if( message == 0 || message == "" )
say( query_mmin() + "\n", ({ this_object() }) );
else say( query_min() + "\n", ({ this_object() }) );
command("look");
if((int)query("brief") == 1) set("brief", 2);
return 0;
}
void create() {
set("position", "punk", MASTER_ONLY);
set("level", 1, MASTER_ONLY);
set("autosave", 500);
set("volume", 500);
set("capacity", 5000);
set("mass", 7500) ;
set("bulk", 1000) ;
set("time_to_heal",10) ;
set("short", "@@query_short");
set("ghost", 0);
set("leader", 0);
enable_commands();
}
void remove() {
destroy_autoload_obj();
this_object()->tsh_cleanup();
CMWHO_D->remove_user(this_object());
living::remove();
}
void restore_status() {
set("cap_name", capitalize((string)query("name")));
set("short", "@@query_short");
set("title", "@@query_title");
set("ghost", 0);
set("leader", 0);
}
void enable_me() {
if (geteuid(previous_object()) != ROOT_UID) return ;
enable_wizard() ;
}
int quit(string str) {
int i, j ;
object *stuff ;
if (str) {
notify_fail("Quit what ?\n");
return 0;
}
check_team();
write("See you another time!\n");
// If this is an invisible wizard, we let the invisibility stay on: but
// if it's a player who cast the invisibility spell, then we want him
// to be visible when he reappears.
if (!wizardp(this_object())) {
set("invisible",0) ;
}
restore_status();
set("last_on", time());
save_me();
ANNOUNCE->announce_user(this_object(), 1);
say(query("cap_name") + " left the game.\n");
log_file("ENTER", query("name") +": quit\t\t" +
ctime(time()) + " from " + query_ip_name(this_object()) + "\n");
remove();
return 1;
}
// This procedure is called from the setup() function below. It is
// basically here to check that existing users get whatever new settings
// they need to function in today's changing mudlib.
void consistency_check() {
if (!query("short")) set("short", "@@query_short");
if (!query("cap_name")) set("cap_name", capitalize(query("name")));
if (!query("title")) set("title", "@@query_title");
if (!query("shell")) set("shell", "none", MASTER_ONLY);
}
// This function is called when the player logs in. It sets his bulk and
// things appropriately, loads his autoloading objects, etc.
// This function is probably being called on to do too much, we think; it
// is a candidate for large changes in future revisions.
void setup() {
int i;
string temp, *temp2;
set_living_name( query("name") );
seteuid(getuid(this_object()));
set_heart_beat(1);
set("id", ({ query("name") }), MASTER_ONLY);
set("ip", query_ip_name(this_object()));
if (file_size(user_path(geteuid())) == -2) enable_wizard(); // has a dir...
if (query("wizard")==1) enable_wizard(); // has been promoted to wiz
init_living();
basic_commands();
consistency_check(); /* this is a catch-all function to upgrade old users */
if(query("inactive")) delete("inactive");
if( !query("cwd") ) set("cwd", "/doc");
i = query("last_on");
/* read the news... if our last_on value is bad, reset it. */
if (intp(i)) MSG_D->read_news(i);
else MSG_D->read_news(0);
set("last_on", time());
temp = query("start");
if(!(temp && stringp(temp) && move(temp) == MOVE_OK))
move(START);
call_out("save_me", 1);
ANNOUNCE->announce_user(this_object(), 0);
say(query("cap_name") + " enters the game.\n");
tsh::initialize();
if(!sizeof(query_aliases())) command("alias -clear");
set("volume", 500) ;
set ("capacity", 5000-coins_carried()) ;
set ("weapon1",0) ;
set ("weapon2",0) ;
set ("armor", ([]) ) ;
load_autoload_obj(); /* Truilkan@TMI 01/18/92 */
command("look") ;
}
void heart_beat() {
continue_attack();
unblock_attack();
if(query("report") && (query("old_hp") > query("hit_points"))) {
write("HP: "+query("hit_points")+"("+query("max_hp")+
")\tSP: "+query("spell_points")+"("+query("max_sp")+")\n");
}
if(query("report")) set("old_hp", query("hit_points"));
heal_up();
}
void net_dead() {
check_team();
save_me();
say((string)this_object()->query("cap_name") + " has gone net-dead.\n");
ANNOUNCE->announce_user(this_object(), 3);
CMWHO_D->remove_user(this_object());
set_heart_beat(0);
log_file("ENTER", this_object()->query("cap_name") + ": net-dead\t\t" +
ctime(time()) + " from " + query("ip") + "\n");
}
void restart_heart() {
say(query("cap_name")+" has reconnected.\n");
write("Reconnected.\n");
ANNOUNCE->announce_user(this_object(), 2);
set_heart_beat(1);
}
void die() {
object ob;
object coins ;
mapping wealth ;
string *names ;
object corpse;
object *stuff;
int i, res, totcoins ;
init_attack();
check_team();
ob = clone_object("/obj/shadow_death");
corpse = clone_object("/obj/corpse");
corpse->set_name(query("cap_name")) ;
i = query("mass") ;
if (i>0) corpse->set("mass", i) ;
i = query("bulk") ;
if (i>0) corpse ->set("bulk", i) ;
i = query("capacity") ;
if (i>0) corpse ->set ("capacity", i) ;
i = query("volume") ;
if (i>0) corpse ->set("volume", i) ;
corpse->move(environment(this_object()));
stuff = all_inventory(this_object());
for(i=0;i<sizeof(stuff);i++)
stuff[i]->move(corpse);
wealth = query("wealth") ;
if (wealth) {
names=keys(wealth) ;
for (i=0;i<sizeof(wealth);i++) {
coins = clone_object(COINS) ;
coins->set_type(names[i]) ;
coins->set_number(wealth[names[i]]) ;
totcoins = totcoins + wealth[names[i]] ;
if (coins) coins->move(corpse) ;
}
}
set ("wealth", ([])) ;
res = query("capacity") ;
set ("capacity", res + totcoins);
set ("deaths", query("deaths")+1);
ob->init_shadow(this_object());
}
string query_short() {
if (interactive(this_object())) return query("title");
else return (query("title") + " [disconnected]");
}
string query_title() {
string str, foo, fii;
str = getenv( "TITLE" );
if( !str ) str = query("cap_name");
else if( !sscanf(str, "%s$N%s", foo,fii) )
str = query("cap_name") + " " + str;
else str = substr( str, "$N", query("cap_name") );
return str;
}
string local_commands() {
mixed *cmds;
int i;
string result;
if (geteuid(previous_object()) != ROOT_UID)
return "You aren't authorized to check this information.\n";
cmds = commands();
if (!sizeof(cmds)) return "no commands available";
result = "";
while (i < sizeof(cmds)) {
result += (cmds[i][0] + " ");
i++;
}
return result + "\n";
}
mixed *user_commands() { return commands(); }
nomask void receive_message(string class, string msg) {
object shell;
string foo ;
if (getenv("shelltest") == "on")
receive("[" + file_name(previous_object()) + "]");
// Invisibility screen. This should catch all tells and says and so forth,
// and all soul commands, and most command messages.
if (this_player() && this_object()!=this_player()) {
if ((int)this_player()->query("invisible")==1 &&
this_object()!=(object)this_player()->query_attacker() &&
!wizardp(this_object())) {
return ;
}
if ((int)this_player()->query("invisible")==2 &&
!member_group(geteuid(this_object()),"admin")) {
return ;
}
}
// Check for earmuffs.
if ((int)this_object()->query("earmuffed")==1) {
foo = geteuid(previous_object()) ;
if (foo!=ROOT_UID && !member_group(foo,"admin") && foo!=getuid(this_object())) return ;
}
// Mudlib support for user environment shell
shell = present("shell", this_object());
if(shell && previous_object() != shell &&
base_name(shell) + ".c" == (string) this_object()->query("shell"))
shell->receive_message(class, msg);
else receive(msg);
}
// not too sure what this came from.
nomask void catch_msg(object source, string *msg) {
int i;
for (i=0;i<sizeof(msg);i++)
receive(msg[i]);
}
void hide(int i) {
set_hide(i);
}
// This procedure returns the total number of coins the player is carrying.
// Mobydick, 10-13-92.
int coins_carried() {
mapping wealth ;
string *types ;
int i, coins ;
coins = 0 ;
wealth = query("wealth") ;
if (!wealth || wealth==([])) return 0 ;
types = keys(wealth) ;
for (i=0;i<sizeof(types);i++) {
coins = coins + wealth[types[i]] ;
}
return coins ;
}
// This function returns the player's total wealth in value units.
// Mobydick, 11-5-92.
int total_wealth() {
mapping wealth ;
string *types ;
int i, coins ;
coins = 0 ;
wealth = query("wealth") ;
if (!wealth || wealth==([])) return 0 ;
types = keys(wealth) ;
for (i=0;i<sizeof(types);i++) {
coins = coins + wealth[types[i]]*coinvalue(types[i]) ;
}
return coins ;
}
string myname() { return _query("cap_name"); }
/* EOF */