// File: /std/ghost.c // The ghost body from the TMI-2 lib. Part of the bodies project, conceived // by Buddha@TMI-2 and implmented by Mobydick@TMI-2 and Watcher@TMI-2. // The code contained in this object is heavily based on code found in the // original user.c and living.c at TMI-2. The relevant code headers follow: // 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 file is a part of the TMI distribution mudlib. // Please keep this header with any code within. #include <config.h> #include <mudlib.h> #include <daemons.h> #include <net/daemons.h> #include <move.h> #include <priv.h> #include <uid.h> #include <body.h> #include <logs.h> inherit BODY_BASE ; inherit "/std/living/env"; static void complete_setup(); // Basic and standard command sets // .. Initiated from inhabitant setup void basic_commands() { add_action("quit", "quit"); add_action("_revive", "_revive"); } static void init_commands() { add_action("cmd_hook", "", 1); } // Catch the heartbeat's continue_attack .. but since ghosts // can't fight, just ignore the call. void continue_attack() { return ; } // This function revives the user to its standard body void revive() { mapping skills; object body; mixed *names; int loop; // If the caller isn't this_object(), block the call. It would // mess up the resulting user body. The caller must be this_object(). if(this_player() != this_object()) return; if(!link || !link_data("dead")) return; body = new( (string)link_data("body") ); link->set("tmp_body", body); link->set("dead", 0); if(!link->switch_body()) { write("Error in the user body transfer. Please inform an Admin.\n"); return; } body->init_setup(); link = 0; // All the player's skills are reduced to 80% of their current value. skills = (mapping) body->query_skills(); names = keys(skills); for(loop=0; loop<sizeof(skills); loop++) skills[names[loop]] = skills[names[loop]] * 80/100; body->set("hit_points", 10); body->save_me(); body->move( environment() ); tell_object(body, "You return from the dead.\n"); tell_room(environment(), query("cap_name") + " returns from the dead.\n", ({ body }) ); remove(); } /* * 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. * Some of the arguments are ignored in the case of the ghost body. */ varargs int move_player(mixed dest, string message, string dir) { object prev; int res; prev = environment( this_object() ); if( res = move(dest) != MOVE_OK ) { write("You remain where you are.\n"); return res; } if(message == "SNEAK") { set_temp("force_to_look", 1); command("look"); set_temp("force_to_look", 0); return MOVE_OK; } if(!dir || dir == "") dir = "away"; if(!query("invisible")) { if(message == 0 || message == "") { tell_room(prev, "The ghost of " + query("cap_name") + " drifts " + dir + ".\n", ({ this_object() })); say("The ghost of " + query("cap_name") + " drifts in.\n", ({ this_object() })); } else { tell_room(prev, message + "\n", ({ this_object() })); say("The ghost of " + query("cap_name") + " drifts in.\n", ({ this_object() })); } } set_temp ("force_to_look", 1) ; command("look") ; set_temp("force_to_look", 0) ; return MOVE_OK ; } void create() { set ("volume", 0) ; set("capacity", 0) ; set("mass", 0) ; set("bulk", 0) ; set("short", "@@query_short"); set("vision", "@@query_vision") ; set("ghost", 1); set("_revive", 0, MASTER_ONLY); enable_commands(); } void remove() { // CMWHO_D->remove_user(this_object()); if (query_link()) query_link()->remove(); body::remove() ; } int quit(string str) { int i, j ; object *stuff ; if (str) { notify_fail("Quit what?\n"); return 0; } if( wizardp( this_object() ) ) { string quit_script; // Pallando 93-02-11 quit_script = user_path( query( "name" ) ) + ".quit"; if( file_size( quit_script ) > 0 ) call_other( this_object(), "tsh", quit_script ); } #ifdef LOGOUT_MSG write( LOGOUT_MSG ); #endif set("last_on", time()); ANNOUNCE->announce_user(this_object(), 1); say(query("cap_name") + " left the game.\n"); #ifdef QUIT_LOG log_file(QUIT_LOG, query("name") +": quit\t\t" + ctime(time()) + " from " + query_ip_name(this_object()) + "\n"); #endif remove(); return 1; } string process_input (string arg) { arg = do_alias(arg) ; return arg ; } // This function is used to check if the user is able to // see anything around it. Watcher (01/29/93) // // Ghosts can see anything at all times. If players find this advantageous // enough to die for, then cheerio for them :) int query_vision() { // If there is no environment, you obviously can't see anything. :) if (!environment(this_player())) return 0 ; // Otherwise, you can. return 1 ; } // Basic recognition function. int query_ghost() { return 1 ; } // The ghost's short description string query_short() { if(!query("name")) return "a mist"; if(interactive(this_object())) return "The ghost of " + capitalize(query("name")); else return "The ghost of " + capitalize(query("name")) + " [disconnected]"; } void setup_ghost() { if(!query("name") || query("name") != geteuid(link)) return; set ("cap_name", capitalize(query("name"))) ; set ("gender", "neuter"); set ("id", ({ "ghost", "mist", query("name"), query("cap_name") }) ); set ("long", "This appears to be the ghost of " + query("cap_name") + ".\n"); set ("PATH", ({ GHOST_CMDS })); } nomask static int cmd_hook(string cmd) { string file; string verb; verb = query_verb(); if (environment() && environment()->valid_exit(verb)) { verb = "go"; cmd = query_verb(); } file = (string)CMD_D->find_cmd(verb, ({ GHOST_CMDS }) ) ; if(file && file != "") return (int)call_other(file, "cmd_" + verb, cmd); return 0 ; } int _revive() { if(!query("_revive")) return 0; set("_revive", 0); revive(); return 1; } // This is needed as a catch for the non-existant save system in // the ghost body, as compared to the user system. Without this // catch, the ghost body can error at certain function calls when // save is called. Watcher (7/93) // // Removed again by leto, it caused inheritance problems 271194 //int save_data() { return 1; } /* EOF */