// 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 */