// -------------------------------------------------------------- PREPROCESSOR
// LOGIN_LOCKED_TO_LEVEL is the minimum level needed to login
#define LOGIN_LOCKED_TO_LEVEL 0
#ifdef TESTMUD
#define ALLOW_NEW_CHARACTERS 0
#define ALLOW_GUESTS 0
#else // Standard setup.
#define ALLOW_NEW_CHARACTERS 1
#define ALLOW_GUESTS 1
#define ALLOW_GUEST_CHAT 0
#endif
#ifdef TESTMUD // Code in testing.
#define VERSION_NEW_COLOUR 1 // For Bytre's colour project.
// #define VERSION_DUEL 1 // Adinos's 'duel' project
#endif
#define MAX_PRETITLE_LENGTH 15
#define IDLE_SECONDS 300
#define REGISTER
#define RACE_DOCS "/doc/race_docs/"
#define EXPLORE_D "w/bytre/explore/control"
#define GRAVE_D "w/pantheon/gs/grave_gen"
#define SOULBASE "w/greyson/lib/soulbase"
#define CHURCH "room/newvill/inn"
#define POST_OFFICE "obj/secure/ims/imsof"
#define DEATH_MARK "room/death/death_mark"
#define APPRENTICE_SCROLL "obj/init_scroll"
#define NEW_COMBAT_ROOM "/w/bytre/adm/combat_check"
#define AUTOSAVE_TIME 300 // force early saves if mud unstable 30-may-06 bytre
// AUTOSAVE_TIME returned to 300, 2-apr-07 bytre
// AUTOSAVE_TIME set to 60 due to storms, 26-apr-07 bytre
// AUTOSAVE_TIME returned to 300, crash concerns. 07-mar-2008
// AUTOSAVE_TIME returned to 300, we're stable. 26-aug-2008 bytre
// IDLE_TIMEOUT now controlled by query_idle_timeout() in commands.c
//#define IDLE_TIMEOUT ((int)level * 1800 + 1800)
// IDLE_TIMEOUT controls how long a statue will remain before logout 2-apr-07 bytre
#ifdef TESTMUD
#define DESCRIPTOR_ALLOWED_EUIDS ({"greyson","Shifters","pris","theryn" })
#else
#define DESCRIPTOR_ALLOWED_EUIDS ({"greyson","Shifters","pris"})
#endif
#include <version.h>
#include <law.h>
#include <daemons.h>
#include <log.h>
#include <living.h>
#include <levels.h>
#include <classes.h>
#include <guilds.h>
#include <body_position.h>
#include "/secure/uids.h"
#include <regeneration.h>
#include <wizards.h>
#include <xfun.h>
#include <experience.h>
#include <ip.h>
#ifdef VERSION_NEW_COLOUR
#include <terminal.h>
#endif
//Mordecai OCT09: Added code to allow non-living objects to react to
// "kill <object>"
#define VERSION_KILL 1
// ------------------------------------------------------------------ INHERITS
inherit "lib/living/living";
inherit "lib/communication";
nomask inherit "secure/save_player";
inherit "lib/player/lib/addaction";
inherit "lib/player/lib/aliases";
inherit "lib/player/lib/more";
inherit "lib/player/lib/temp_save";
inherit "obj/lib/path_handle";
inherit "lib/player/basic/abilities";
inherit "lib/player/basic/effects"; // Fir 20 Jul 2008
inherit "lib/player/basic/ansi"; // Bytre, 01-26-96
inherit "lib/player/basic/auto_load";
inherit "lib/player/basic/charpic"; // Bytre 5-23-97
inherit "lib/player/basic/clan"; // Zor, 01-08-96
inherit "lib/player/basic/commands";
inherit "lib/player/basic/communication";
inherit "lib/player/basic/coords"; // Trixx, 10-17-95
inherit "lib/player/basic/description";
inherit "lib/player/basic/webpass.c"; // Paldin, 01 Feb 2009
#ifdef VERSION_DUEL
inherit "lib/player/basic/duel"; // Theryn / Adinos, Jan 2005
#endif
nomask inherit "lib/player/basic/explore";
nomask inherit "lib/player/basic/flags";
inherit "lib/player/basic/banks";
inherit "lib/player/basic/food";
inherit "lib/player/basic/fortune";
inherit "lib/player/basic/guild";
inherit "lib/player/basic/homepage"; // Bytre, 04-03-95
inherit "lib/player/basic/info";
inherit "lib/player/basic/lang";
inherit "lib/player/basic/login"; // Leoz, 03-21-95
inherit "lib/player/basic/misc";
inherit "lib/player/basic/msgs";
inherit "lib/player/basic/muds";
inherit "lib/player/basic/partycmds";
inherit "lib/player/basic/poison";
inherit "lib/player/basic/powerup";
#ifdef VERSION_NEW_PROMPT
inherit "lib/player/basic/prompt"; // Maker 08-08-13
#endif
inherit "lib/player/basic/pueblo"; // Arpeggio, 02-24-97
inherit "lib/player/basic/put_get";
nomask inherit "lib/player/basic/quests";
inherit "lib/player/basic/sense";
inherit "lib/player/basic/seq_login";
inherit "lib/player/basic/session_msg";
inherit "lib/player/basic/skills";
inherit "lib/player/basic/suicide"; // Buxley 14 Apr 2023
inherit "lib/player/basic/welcome";
inherit "/lib/player/basic/accredit";
inherit "/lib/player/basic/chatline";
inherit "lib/player/apprentice/commands";
inherit "lib/player/apprentice/msgs";
inherit "lib/player/apprentice/snoop";
inherit "lib/player/apprentice/sponsor";
inherit "lib/player/apprentice/su";
inherit "lib/player/apprentice/wiz_radio";
inherit "lib/player/wizard/commands";
nomask inherit "lib/player/wizard/file";
inherit "lib/player/wizard/position";
inherit "lib/player/arch/commands";
// --------------------------------------------------------- PUBLIC PROTOTYPES
int id( string str, int lvl );
nomask string query_real_name();
string short( int arg, int desc );
nomask int set_level( int lev );
nomask int set_title( string t );
// ------------------------------------------------------- EXTERNAL PROTOTYPES
string query_exp_number_string();
// ------------------------------------------------------- INTERNAL PROTOTYPES
static void make_scar();
void show_scar();
static void move_player_to_start( mixed where );
static void move_player_to_start2( mixed where );
static void move_player_to_start3( mixed where );
#ifdef VERSION_ASK_NEWBIES
static void move_player_to_start3a( mixed where );
#endif
static void move_player_to_start4( mixed where );
static void move_player_to_start5( mixed where );
void convert_stuff();
nomask int illegal_patch( string what );
nomask status valid_name( string str );
static int check_input_site( string str );
static int show_sites();
int check_site( string str );
int query_ld_idle_timeout();
int query_idle_timeout();
int log_quit( status flag );
void call_is_ld();
void true_notify_pk_death_objects( mixed *killarray );
void true_notify_death_objects( mixed *killarray );
#ifdef VERSION_PARTY_UPDATE
void true_notify_death_party( string opponent );
#endif
// ----------------------------------------------------------------- VARIABLES
static string pasword;
static object myself; // ourselves
string title;
string pre_title;
string al_title;
string called_from_ip; // IP number was used last time
static int time_to_save; // Time to autosave
int tot_value; // Saved values of this player
static string body; // for a description
static object descriptor; // for ...stuff
static status is_statue; // am I already a statue
int last_login, first_login; // when did we last login, when first time
static int remember_last_time; // used by file_date of NEWS
static object snoop_allow,snoop_allowed;
static status snoop_status; // if I'm snooping = 1, else 0
static status pk_member;
static status throw_flag; // are we in process of throwing out?
static status donate_force_quit;
static int last_experience; // for logging reasons, Zor
static int last_experience_billions; // Added for the logging
int bank_money;
int time_to_wake;
string c_name; // capitalized name
#ifdef VERSION_ASK_NEWBIES
static int newbie_status; // to ask new players questions, Scarecrazy, 2004-09-04
#endif
string player_source; // // Where did the player come from? bytre 2015-08-28
int player_newbiestatus; // original newbie_status of player bytre 2015-09-04
// ------------------------------------------------------------ IMPLEMENTATION
nomask void create() {
seteuid( getuid() );
if ( file_name( this_object() )[0..10] != "/obj/player" ) {
destruct( this_object() );
return;
}
if ( myself )
return;
first_login = time();
level = -1;
name = "logon";
cap_name = "Logon";
setmin( "arrives" );
setmout( "leaves" );
set_head_str( "head" );
set_body_str( "body" );
set_arm_str( "arm" );
set_leg_str( "leg" );
set_hand_str( "hand" );
set_foot_str( "foot" );
pasword = explode(read_file("/obj/save/PALLOW"), "\n")[random(3)];
setmmin( 0 );
setmmout( 0 );
title = "the title less";
al_title = "neutral";
misc = ([]);
// illegal values, so they will be changed later:
gender = -1;
my_quest_max = 0;
use_internal_aliases = -1;
cmd_stack_timing=time(); // command stack timing addition - Bytre 1/may/0
cmd_stack_counter=0;
#ifdef VERSION_ASK_NEWBIES
newbie_status = -1;
#endif
}
void reset() {
living::reset();
watches = 0;
}
string short( int arg, int desc ) {
string *modtitle;
object ob;
string tmp;
if ( is_invis ) {
if ( (level < WIZLEVEL) &&
(this_player()->see_invisible() ||
this_player()->query_level() > WIZLEVEL) ) {
if ( c_name )
cap_name = capitalize( c_name );
else
cap_name = capitalize( name );
is_invis = 0;
tmp = (string)short( arg, 0 );
is_invis = 1;
cap_name = "Someone";
return( tmp +" [invisible]" );
}
else
return 0;
}
if ( is_statue && !arg )
tmp = "a stone statue of "+ cap_name;
else if ( ghost )
tmp = "ghost of "+ cap_name;
else if( frog )
tmp = cap_name +" the frog";
else if ( (ob = present( "short_mod", this_object() )) &&
(modtitle=(string*)ob->short_mod(title,al_title,pre_title,desc)) &&
(pointerp( modtitle )) && (sizeof( modtitle ) == 3) ) {
if ( modtitle[0] && modtitle[0] != "" )
tmp = modtitle[0] +" "+ (desc ? capitalize( name ) : cap_name);
else
tmp = desc ? capitalize( name ) : cap_name;
if ( modtitle[1] )
tmp += " "+ modtitle[1];
if ( modtitle[2] )
tmp += " ("+ modtitle[2] +")";
} else {
if ( pre_title )
tmp = pre_title +" "+ cap_name;
else
tmp = cap_name;
tmp += " "+ title;
if ( al_title )
tmp += " ("+ al_title +")";
}
if ( pk_member )
tmp += " {SK}";
if ( !arg && body_position )
tmp += ", who is "+ query_body_position_string();
return tmp;
}
int long() {
if ( frog ) {
write( cap_name +" is a frog.\n" );
return 1;
} else if ( ghost ) {
write( "This is the ghost of "+ cap_name +".\n" );
return 1;
} else if ( descriptor ) {
string str;
if ( str = (string)descriptor->long_mod() )
writef( str );
if ( body_position )
write( cap_name +" is currently "+ query_body_position_string() +".\n" );
return 0;
}
write( cap_name +" is a "+ query_gender_string() +" "+ query_race() +
".\n" );
if ( body )
write( body );
show_scar();
if ( description && description[0] )
write( description[0] );
if ( body_position )
write( capitalize( (string)query_pronoun() ) +" is currently "+
query_body_position_string() +".\n" );
return 0;
}
int id( string str, int lvl ) {
if (descriptor && descriptor->id_mod( str, lvl )) return 1;
if ( level < WIZLEVEL ) {
if ( str == name || str == cap_name || str == "ghost of "+ name ||
str == "statue of "+ name || str == "player "+ name )
return 1;
}
if ( is_invis && lvl <= level )
return 0;
if ( ghost )
return str == "ghost of "+ name;
if ( is_statue )
return str == "statue of "+ name;
if ( str == name || str == "player "+ name )
return 1;
return 0;
}
void move( mixed dest ) {
if ( environment() )
environment()->exit( this_object() );
if (this_player() && interactive(this_player()) &&
this_player()->query_level() > MAXMORTAL &&
this_object()->query_level() < APPRENTICE &&
!this_object()->query_test_char() &&
dest && (stringp(dest) || objectp(dest)) ) {
"/adm/usr/flint/lawlog"->write_law_log("MOVE",
"["+ctime(time())+"] "+
capitalize((string)this_player()->query_real_name())+
" moved "+this_object()->query_real_name()+" from "+
(environment()?file_name(environment()):"???")+" to "+
(stringp(dest)?dest:file_name(dest)));
}
if (this_player() && dest && objectp(dest) &&
interactive(this_player()) &&
this_player()->query_level() > MAXMORTAL &&
dest->query_is_player() &&
!dest->query_test_char() ) {
"/adm/usr/flint/lawlog"->write_law_log("MOVE",
"["+ctime(time())+"] "+
capitalize((string)this_player()->query_real_name())+
" moved "+this_object()->query_real_name()+" from "+
(environment()?file_name(environment()):"???")+" into "+
dest->query_real_name());
}
// Added by Paldin 3-Jan-2005 to prevent players in inventories
if (this_player() && dest && objectp(dest) &&
dest->query_is_player() && query_level() < WIZARD) {
"/adm/usr/flint/lawlog"->write_law_log("INV_MOVE",
"["+ctime(time())+"] "+
capitalize((string)this_player()->query_real_name())+
" moved "+query_real_name()+ " into "+dest->query_real_name()+" inventory");
if (environment())
dest = environment(dest);
else
dest = CHURCH;
if (!dest) dest = CHURCH;
}
move_object( this_object(), dest );
}
nomask void is_destructed( object ob, object prev ) {
string uidp;
string prev_name, tp_name;
if ( level > MAXMORTAL )
WIZLINE_D->remove_entry( this_object() );
if ( !name || name == "logon" )
return;
if ( this_player() == this_object() || !previous_object() )
return;
tp_name = ( this_player() ?
(string)this_player()->query_real_name() : "" );
if ( tp_name == query_real_name() )
return;
if ( (uidp = geteuid( prev )) == "root" )
return;
prev_name = file_name( prev );
if ( prev_name == "/secure/simul_efun" )
return;
if ( GUEST_D->query_is_guest( name ) )
return;
log_file( "ILLEGAL_DES", ctime() +" "+ name +" by "+ prev_name +"("+ uidp +
","+ tp_name +","+ query_verb()+ ")\n" );
}
nomask status query_is_player() {
return !!environment(); // 14-Oct-96, Greyson
}
// --------------------------------------------------------------------- LOGON
static nomask int logon() {
time_to_save = AUTOSAVE_TIME;
show_greeter( 0 );
login_prompt( 0 );
return 1;
}
static void transfer_inventory( object src ) {
int i;
object *ob;
if( !src || !this_object() )
return;
ob = all_inventory( src );
for ( i = sizeof( ob ) ; i-- ; ) {
string file;
if ( !ob[i] || ob[i]->id( "soul" ) )
continue;
file = file_name(ob[i]);
if ( ob[i]->query_is_weapon() && ob[i]->query_cursed() &&
ob[i]->query_wielded() ) {
this_object()->wield( ob[i] );
} else if ( ob[i]->query_is_armour() && ob[i]->query_cursed() &&
ob[i]->query_worn() ) {
this_object()->wear_armour( ob[i] );
} else if ( ob[i]->query_is_shield() && ob[i]->query_cursed() &&
ob[i]->query_worn() ) {
this_object()->wear_shield( ob[i] );
} else {
ob[i]->drop( 1 );
}
if(ob[i]) ob[i]->move( this_object() );
else log_file("LOGIN", "Destructed on reconnect: "+file+"\n");
}
call_out( "fix_carry", 0 );
}
static void try_throw_out( string str, object other_copy ) {
object *ob;
object other_env;
object save_this_player;
int i;
remove_call_out( "time_out" );
if ( str == "" || (str[0] != 'y' && str[0] != 'Y') ) {
if ( str[0..11] == "PUEBLOCLIENT" ) {
set_is_html( this_object(), 1 );
write_html( "</xch_mudtext><img xch_mode=html><code>"
"Throw the other copy out? " );
call_out( "time_out", 60 );
input_to( "try_throw_out", 0, other_copy );
} else {
write( "Welcome another time then!\n" );
destruct( this_object() );
}
return;
}
#ifdef VERSION_LINKDEAD_CHILL
// teleport back from linkdeath jail, Maker, 2020 Mar 17
if(CHILL_D->query_chilled(query_real_name()))
CHILL_D->thaw_player(other_copy);
#endif
other_env = environment( other_copy );
other_copy->move( "room/ld_ghetto" );
if ( donate_force_quit ) {
remove_call_out( "first_log_check" );
donate_force_quit = other_copy->query_first_log_check();
if ( donate_force_quit < time() )
donate_force_quit = time() + 10;
write( "["+
(string)"secure/xfun"->time_to_string( donate_force_quit - time() ) +
" left this session.]\n" );
if ( donate_force_quit - time() < 180 )
call_out( "extra_quit2", donate_force_quit - time() );
else
call_out( "first_log_check", donate_force_quit - time() );
}
//Mordecai Jan2013: Set TP to other_copy
save_this_player = this_player();
set_this_player( other_copy );
if ( !other_copy->query_is_statue() ) {
other_copy->call_is_ld();
}
TAG_D->clear_tag( other_copy, "adm_dhealing" ); // do this before xfer inventory 2022-09-27 bytre
transfer_inventory( other_copy );
other_copy->leave_party();
if ( other_copy )
this_object()->set_thist( other_copy->get_thist() );
"secure/tool"->ask_to_quit( other_copy );
//Mordecai Jan2013: Set TP back to whomever was before
if( save_this_player )
set_this_player(save_this_player);
if ( restore_player( name ) )
write( "Points restored from the other object.\n" );
else {
write( "Could not restore points!\n" );
destruct( this_object() );
return;
}
last_experience = experience;
last_experience_billions = experience_billions;
if ( other_copy )
destruct( other_copy );
throw_flag = 1;
if ( cap_name == "Someone" && (!is_invis) ) {
if ( c_name )
cap_name = capitalize( c_name );
else
cap_name = capitalize( name );
}
move_player_to_start5( other_env );
#ifdef LOG_ENTER
"secure/tool"->adm_log( "ENTER", " (throw)\n", 1, 400000 );
#endif
}
static status mtch( string pattern, string str ) {
return (0 != sscanf( str, "%~s"+ pattern +"%~s" ));
}
static status username_denied( string str ) {
if ( mtch( "fuck", str ) || mtch( "shit", str ) )
return !"/secure/xfun"->query_player_exists( str );
}
static void logon2( string str ) {
remove_call_out( "time_out" );
if ( !str || str == "" ) {
destruct( this_object() );
return;
}
if ( name != "logon" ) {
illegal_patch( "logon2 "+ name );
destruct( this_object() );
return;
}
if ( str[0..3] == "*who" ) {
string dummy;
write("\n");
if ( sscanf( str,"*who %s",dummy ) == 1 )
show_who( dummy );
else
quick_who();
login_prompt( 0 );
return;
}
str = lower_case( str );
if ( str[0..11] == "puebloclient" ) {
set_is_html( this_object(), 1 );
show_greeter( 1 ); // With pueblo.
login_prompt( 1 );
return;
}
if ( member_array( str, ILLEGAL_UIDS ) != -1 ) {
write( "That name is reserved. ");
login_prompt( 0 );
return;
}
if ( GUEST_D->query_is_guest( str ) ) {
if (!ALLOW_GUESTS) { // lock out guests if not permitted. 02-jan-09 bytre
write("\nGuests are not currently permitted.\n\n");
destruct(this_object());
return;
}
if ( "secure/tool"->query_banished( query_ip_number(this_object() ),
"guest" ) ) {
write( (string)"secure/tool"->query_register_msg() );
destruct( this_object() );
return;
}
str = GUEST_D->query_name();
write( "You are now "+ capitalize( str ) +".\n" );
"secure/tool"->adm_log("GUEST", ctime() +": "+ str +" from "+
query_ip_name( this_object() ) +"\n" );
}
if ( !valid_name( str ) ) {
write( "Give name again: " );
call_out( "time_out", 60 );
input_to( "logon2" );
return;
}
if ( username_denied( str ) || "secure/banish"->query_banished( str ) ) {
write( "That name is reserved. ");
login_prompt( 0 );
return;
}
if ( !restore_player( str ) ) {
#if ALLOW_NEW_CHARACTERS
show_new_player_greeter();
#else
write( "No new characters at this time, please try again later!\n" );
destruct( this_object() );
return;
#endif
#ifdef REGISTER
if ( "secure/tool"->query_banished(query_ip_number(this_object()), str)) {
write( (string)"secure/tool"->query_register_msg() );
"secure/tool"->adm_log( "REG_LOGIN", ctime()[4..18] +" "+
query_ip_name( this_object() ) +" "+ str +" DENY\n" );
destruct( this_object() );
return;
}
#endif
}
#ifdef REGISTER
else if ( "secure/tool"->query_true_banished(query_ip_number(this_object()),
str, first_login) ) {
write( (string)"secure/tool"->query_register_msg() );
"secure/tool"->adm_log( "REG_LOGIN", ctime()[4..18] +" "+ query_ip_name(this_object()) +
" "+ query_ip_number(this_object())+
" "+ str +" RETRODENY\n" );
destruct( this_object() );
return;
}
#endif
#if LOGIN_LOCKED_TO_LEVEL
if ( (level < LOGIN_LOCKED_TO_LEVEL) &&
!("obj/login_allow"->login_allow( name ) ||
"obj/login_allow"->wizlock_login_allow( name )) ) {
"secure/tool"->adm_log( "REG_LOGIN", ctime() +" "+ query_ip_name( this_object() ) +" "+
name +" REJECT\n" );
write( "The game is temporarily closed for players up to level "+
LOGIN_LOCKED_TO_LEVEL +".\n" );
destruct( this_object() );
return;
}
#endif
time_to_save = age + AUTOSAVE_TIME;
/*
* Don't do this before the restore !
*/
name = str; /* Must be here for a new player. */
dead = ghost;
call_out( "reset_dead", 0 );
myself = this_player();
if ( is_invis )
cap_name = "Someone";
else if ( c_name && (lower_case( c_name ) == name) )
cap_name = capitalize( c_name );
else
cap_name = capitalize( name );
remember_last_time = last_login;
last_experience = experience;
last_experience_billions = experience_billions;
last_login = time();
#ifdef SCORE_SESSION
start_session();
#endif
local_weight = 0;
armour_class = 0;
wielded_weapon = 0;
weapon_class = 0;
#ifdef TESTMUD
if ( -1 == level ) {
log_file( "TESTMUD_CREATED", ctime() +" "+ name +".\n" );
if ( !flags ) flags = set_bit( "", 1 );
flags = set_bit( flags, 34 );
}
#else
if ( flags && test_bit( flags, 34 ) ) {
write( "This character is not allowed on Ancient Anguish.\n" );
destruct( this_object() );
return;
}
#endif
if ( GUEST_D->query_is_guest( name ) ) {
newbie_status = 0; // guest should get newbie treatment, bytre 10-sep-2008
move_player_to_start( 0 );
#ifdef LOG_ENTER
"secure/tool"->adm_log( "ENTER_BRIEF", name+","+query_ip_name(this_object())+
","+query_ip_number(this_object())+","+time()+"\n",1, 200000 );
"secure/tool"->adm_log( "ENTER", name +"("+ level +","+
query_exp_number_string() +") "+
ctime()[4..18] +" from "+ query_ip_name( this_object() ) +" ("+
query_ip_number( this_object() ) +
(string)"secure/xfun"->time_to_string( time() - remember_last_time ) +
").\n",
1, 200000 );
#endif
} else {
if ( !check_site( query_ip_number( this_object() ) ) ) {
write( "Login failure. You can't login as "+ name +
" from this site.\n" );
"secure/tool"->adm_log( "ILLEGAL_SITE", ctime() +" "+ name +" from "+
query_ip_number( this_object() ) +"("+
query_ip_name( this_object() )+ ")\n" );
if ( level && level > WIZLEVEL )
"secure/tool"->log_login_failure( name, "SITE" );
destruct( this_object() );
return;
}
if ( level != -1 ) {
write( "Password: " );
call_out( "time_out", 60 );
input_to( "check_password", 1 );
} else {
write( "Choose a password of at least 6 characters: " );
call_out( "time_out", 60 );
input_to( "new_password", 1 );
}
}
attacker_ob = 0;
alt_attacker_ob = 0;
}
nomask status valid_name( string str ) {
int i, length;
if ( str == "=]" )
return 1;
if ( str == "logon" ) {
write( "Invalid name" );
return 0;
}
length = strlen( str );
if ( length > 11 ) {
write( "Too long name.\n" );
return 0;
}
i = length;
while ( i-- ) {
if ( str[i] < 'a' || str[i] > 'z') {
write( "Invalid characters in name:"+ str +"\n"
"Character number was "+ ( i + 1 ) +".\n" );
return 0;
}
}
return 1;
}
static void check_password( string p ) {
remove_call_out( "time_out" );
write( "\n" );
if ( !"secure/xfun"->query_player_exists( name ) ) { // Greyson, 14-Mar-95
write( "Well, looks like your playerfile disappeared. Sorry.\n" );
destruct( this_object() );
return;
}
if ( password == 0 ) {
#if 1
write( "You have no password!\nMail law about having a password set.\n");
destruct( this_object() );
return;
#endif
} else if ( !GUEST_D->query_is_guest( name ) &&
crypt( p, password ) != password ) {
write( "Wrong password!\n" );
if ( level && level > WIZLEVEL )
"secure/tool"->log_login_failure( name );
destruct( this_object() );
return;
}
move_player_to_start( 0 );
#ifdef LOG_ENTER
if ( this_object() ) {
"secure/tool"->adm_log( "ENTER_BRIEF", name+","+query_ip_name(this_object())+
","+query_ip_number(this_object())+","+time()+"\n",1, 200000 );
"secure/tool"->adm_log( "ENTER", name +"("+ level +","+
query_exp_number_string() +") "+
ctime()[4..18] +" from "+ query_ip_name( this_object() ) +" ("+
query_ip_number( this_object() ) +" : "+
(string)"secure/xfun"->time_to_string( time() - remember_last_time ) +
").\n",
1, 200000 );
if ( level < WIZARDLEVEL )
"secure/tool"->adm_log( "ENTER", " "+ Str +","+ Con +"," + Dex +
","+ Int +","+ Wis +" "+ money +","+ bank_money +"\n", 1, 200000 );
}
#endif
}
static void new_password( string p ) {
remove_call_out( "time_out" );
write( "\n" );
if ( !p || p == "" ) {
write( "Try again another time then.\n" );
destruct( this_object() );
return;
}
if ( (strlen( p ) < 6) || (p[0] == '!') ) {
write( "The password must have at least 6 characters and may not start "
"with a '!'.\nPassword: " );
call_out( "time_out", 60 );
input_to( "new_password", 1 );
return;
}
if ( (lower_case( p ) == name) || (p == "123456") ||
(lower_case( p ) == "qwerty") || (lower_case( p ) == "asdfgh") ||
(lower_case( p ) == "zxcvbn") || (lower_case( p ) == "password") ) {
write( "You don't know too much about security, do you? Try again.\n"
"Password: " );
call_out( "time_out", 60 );
input_to( "new_password", 1 );
return;
}
if ( password == 0 ) {
password = p;
write( "Enter your password again to confirm: " );
call_out( "time_out", 60 );
input_to( "new_password", 1 );
return;
}
remove_call_out( "time_out" );
if ( password != p ) {
write( "You changed!\n" );
destruct( this_object() );
return;
}
password = crypt( password, 0 ); // Generate new seed.
set_level( 1 );
set_str( 1 );
set_con( 1 );
set_int( 1 );
set_dex( 1 );
set_wis( 1 );
set_title( "the utter novice" );
hit_point = max_hp;
#ifdef VERSION_ASK_NEWBIES
newbie_status = 0; // We're creating the player, so he is a newbie.
#endif
move_player_to_start( 0 );
"secure/tool"->notify_player_created( name );
catch(call_other("/w/bytre/stats/statcoll","new_user_today"));
#ifdef LOG_NEWPLAYER
log_file( "NEWPLAYER", cap_name +".\n", 200000 );
"secure/tool"->adm_log( "NEW_PLAYER", "["+ ctime()[4..15] +"] "+ cap_name +" "+
query_ip_name( this_object() ) +" "+ query_ip_number( this_object() ) +
"\n", 1, 200000 );
#endif
}
static void move_player_to_start( mixed where ) {
if ( !mailaddr || ("" == mailaddr) ) {
cat("/doc/newplayer/email");
write("Choose an e-mail address: ");
call_out( "time_out", 60 );
input_to( "getmailaddr", 0, where );
return;
}
move_player_to_start2( where );
}
static void getmailaddr( string maddr, mixed where ) {
remove_call_out( "time_out" );
if ( !maddr || ((maddr != "none") && (2 != sscanf(maddr,"%~s@%~s"))) ) {
move_player_to_start( where );
} else {
mailaddr = maddr;
set_player_data("newsletter",1);
move_player_to_start2( where );
}
}
static void move_player_to_start2( mixed where ) {
if ( gender == -1 ) {
write("\nDo you want your character to be male or female: ");
call_out( "time_out", 60 );
input_to( "getgender", 0, where );
} else {
move_player_to_start3( where );
}
}
static void getgender( string gender_string, mixed where ) {
remove_call_out( "time_out" );
gender_string = lower_case( gender_string );
if ( gender_string[0] == 'm' ) {
set_male();
} else if ( gender_string[0] == 'f' ) {
set_female();
} else {
write( "Sorry, but that is too weird for this game!\n"
"Are you male or female (type m or f): " );
call_out( "time_out", 120 );
input_to( "getgender", 0, where );
return;
}
move_player_to_start3( where );
}
static void move_player_to_start3( mixed where ) {
if ( !valid_race( query_real_race() ) ) {
write( "\nYou may now choose a race for your character.\n"
"You can choose between human, elf, dwarf, half-elf and orc.\n"
"To get the description of a race type 'help <race>' (Ex: help orc).\n"
"Please enter your choice: " );
call_out( "time_out", 60 );
input_to( "enter_race", 0, where );
} else {
#ifdef VERSION_ASK_NEWBIES
move_player_to_start3a( where );
#else
move_player_to_start4( where );
#endif
}
}
static void enter_race( string arg, mixed where ) {
remove_call_out( "time_out" );
switch ( arg ) {
case "dwarf":
case "elf":
case "half-elf":
case "human":
case "orc": {
set_real_race( arg );
write( "\n" );
create_starting_abilities();
NEW_COMBAT_ROOM->set_flag(this_object());
#ifdef VERSION_ASK_NEWBIES
move_player_to_start3a( where );
#else
move_player_to_start4( where );
#endif
return;
}
case "help human": {
cat( RACE_DOCS "human" );
break;
}
case "help elf": {
cat( RACE_DOCS "elf" );
break;
}
case "help dwarf": {
cat( RACE_DOCS "dwarf" );
break;
}
case "help half-elf": {
cat( RACE_DOCS "halfelf" );
break;
}
case "help orc": {
cat( RACE_DOCS "orc" );
break;
}
default: {
break;
}
}
move_player_to_start3( where );
}
#ifdef VERSION_ASK_NEWBIES
static void move_player_to_start3a( mixed where ) {
if (newbie_status != -1 && (newbie_status < 1 || newbie_status > 4) ) {
write("Which of the following statements would describe you the best?\n"+
"\t1\tI am new to playing MUDs.\n"+
"\t2\tI have played other MUDs before.\n"+
"\t3\tI have played Ancient Anguish before, or have other characters.\n"+
"\t4\tI am new to Ancient Anguish, but do not want new player assistance.\n"+
"Please enter your choice: ");
call_out( "time_out", 60 );
input_to( "help_newbie", 0, where );
} else {
move_player_to_start4( where );
}
}
static void help_newbie( string ansnewbie, mixed where ) {
int err;
string source;
remove_call_out( "time_out" );
if ( !ansnewbie ) {
move_player_to_start3a( where );
} else if ( sscanf(ansnewbie,"%d",newbie_status) != 1 ||
(newbie_status < 1) || (newbie_status > 4 ) ) {
writef("Your selection will help us to determine how much newbie "
"assistance we should provide. You can select option 4 if "
"you would like to start playing the game without further "
"ado. All our help files can be accessed by typing 'help' "
"(without the quotes) once you are in the game.\n");
move_player_to_start3a( where );
return;
}
// bytre 08aug07: protect with a catch
err=catch(source=(string)"/w/bytre/http/newbie_source"->match_player(cap_name, query_ip_number(this_object()) ));
"secure/tool"->adm_log( "NEWBIE", "["+ ctime()[4..15] +"] "+ cap_name +" "+
query_ip_name( this_object() ) +" "+ query_ip_number( this_object())+" ["+
source+
"] {"+(string)newbie_status+"}\n", 1, 200000 );
player_source=source; // store this for perpetuity bytre 2015-08-28
player_newbiestatus=newbie_status;
move_player_to_start4( where );
}
#endif
static void move_player_to_start4( mixed where ) {
object other_copy;
string tmp_name;
// see if we are already playing
tmp_name = name;
name = 0;
other_copy = find_player( tmp_name );
name = tmp_name;
enable_commands();
//Mordecai: The following block moved here to reorder actions when
//returning from linkdeath.
add_standard_commands();
init_internal_aliases();
if ( level >= WIZLEVEL )
wiz_commands();
if ( other_copy ) {
// if ( !query_ip_number( other_copy ) ) {
if (!interactive(other_copy)) {
try_throw_out( "y", other_copy );
} else {
write( "You are already playing!\n"
"Throw the other copy out? " );
call_out( "time_out", 60 );
input_to( "try_throw_out", 0, other_copy );
}
return;
}
move_player_to_start5( where );
}
static void move_player_to_start5( mixed where ) {
string err, log_dir, remember_race, *squelchees, tmp_msg;
int remember_throw, i, sqz;
if (!query_test_char())
err = catch( "/adm/usr/bytre/login_check"->do_ip_check(name,
query_ip_number(this_object())));
err = catch( "/adm/usr/bytre/login_check"->do_date_check(
this_object(), remember_last_time));
remember_race = race;
restore_player( name );
if ( remember_race )
race = remember_race;
if (ctime(time())[4..10] != ctime(last_login)[4..10]) {
set_misc("login_days",query_misc("login_days")+1); }
// This must be before last_login is updated.
this_object()->auto_toggle_chatline();
if("/secure/guest_handler"->query_is_guest(query_name())) {
set_chat_allowed(ALLOW_GUEST_CHAT);
}
last_login = time();
call_out("do_seq_playdate_check",300); // start seq_check, bytre
#ifndef ANARCHY
if ( time_to_wake && (time_to_wake > time()) ) {
write( "You are on the dark side of Ancient Anguish for "+
(string)"secure/xfun"->time_to_string( time_to_wake - time() ) +
" more.\n" );
destruct( this_object() );
return;
}
#endif
if ( time_to_wake ) {
last_played = time_to_wake;
// last playdate is moved forward to not disqualify during
// freeze or archkill time. bytre, 26 jan 2018
}
time_to_wake = 0;
level = "secure/tool"->enter( this_object() );
if ( throw_flag )
NOTIFIER_D->try_throw( this_object() );
else
NOTIFIER_D->login( this_object() );
if ( query_misc_contains( "gender" ) ) {
set_real_gender( query_misc( "gender" ) );
set_misc( "gender", 0 );
}
if ( query_misc_contains( "race" ) ) {
set_real_race( query_misc( "race" ) );
set_misc( "race", 0 ); // deletes
}
if ( misc["body"] && (body = BODY_D->create_body_string( misc["body"] )) )
body = get_f_string( (cap_name == "Someone" ? capitalize( name ) : cap_name) +
" "+ body +"." );
if ( !throw_flag && misc["watch"] )
misc = m_delete( misc, "watch" );
remember_throw = throw_flag;
throw_flag = 0;
convert_stuff();
set_living_name( name );
set_heart_beat( 1 );
//Mordecai: Previous location of the following, which have been moved
//up prior to ld-body destruction.
//add_standard_commands();
//init_internal_aliases();
if ( level >= WIZLEVEL ) {
//wiz_commands(); //Same as above
wiz_radio::add_init();
if ( member_array( class, CLASSES ) == -1 )
class = 0;
if ( member_array( guild, GUILDS ) == -1 )
guild = 0;
}
#if APRIL_FOOLS_ACTIVE
else {
if ( !misc["gender"] ) {
misc["gender"] = (int)this_object()->query_gender();
this_object()->set_gender( ({ 0, 2, 1 })[misc["gender"]] );
}
}
#endif
if ( level >= WIZARDLEVEL ) {
set_is_wizard( this_object() );
wiz_commands2();
}
if ( level >= SENATELEVEL ) {
arch_commands();
}
if ( misc["no_timeout"] && (level < SENATELEVEL) ) {
misc["no_timeout"] = 0;
}
if ( !misc["alt_soul"] )
err = catch( clone_object("obj/soul")->move( this_object() ) );
err = 0;
if ( class )
err = catch( class->player_login() );
if ( guild )
err = catch( guild->player_login() );
if ( err ) {
write( "WARNING: There was a critical error with your class or guild.\n"
"Please report this error to a wizard.\n" );
}
if ( level < WIZLEVEL ) {
manipulate_abilities();
if ( !random( 10 ) ) {
rethink_abilities();
}
}
if (newbie_status>0) {
cat("/doc/newplayer/entergame");
} else {
if ( (level < WIZARDLEVEL) || (remember_last_time<file_date("/WELCOME2")) ) {
cat( "/WELCOME2" );
}
if ( remember_last_time < file_date( "/NEWS" ) ) {
cat( "/NEWS" );
} else {
write( "\nYou can read the old news by typing 'oldnews'.\n\n" );
}
} // let's not show news and welcome to newbies
if ( tot_value ) {
write( "You find "+ tot_value +" coins of your lost money!\n" );
money += tot_value;
tot_value = 0;
}
if ((newbie_status==1) || (newbie_status==2)) { where="/secure/void"; }
if ( where ) {
this_object()->move( where );
} else {
this_object()->move( this_object()->query_login_loc() );
err = catch( load_auto_obj( auto_load ) );
if ( err )
write( "Error in autoloading: "+ err +"\n" );
if ( !this_object() ) { // destructed by eg, reality pill
log_file( "PLAYER_LOGIN_DEST", ctime()[4..15] +": "+ name +"\n" );
return;
}
}
if ( is_invis && (level < WIZLEVEL) )
vis();
if ( is_invis ) {
write( "YOU ARE INVISIBLE!\n\n" );
pseudo_last_login = remember_last_time;
} else {
say( cap_name +" enters the game.\n" );
}
if ( level >= WIZARDLEVEL ) {
if ( remember_last_time < file_date( "/WIZNEWS" ) )
cat( "/WIZNEWS" );
else
write( "\nYou can read the old wiznews by typing 'cat /WIZNEWS'.\n\n" );
log_dir = "/w/"+ name +"/log/";
if ( file_size( log_dir +"Bug" ) > 0 )
write( "You have a Bug log file to check.\n" );
if ( file_size( log_dir +"Typo" ) > 0 )
write( "You have a Typo log file to check.\n" );
if ( file_size( log_dir +".rep" ) > 0 )
write( "You have a .rep file to check.\n" );
if ( 0 < query_earmuff_level() )
earmuffs();
if ( level >= SENATELEVEL ) {
if ( remember_last_time < file_date( "/ARCHNEWS" ) )
cat( "/ARCHNEWS" );
else
write( "You can read the old archnews by typing 'cat /ARCHNEWS'.\n\n" );
if ( remember_last_time < file_date( log_dir +"login_failure" ) )
write( "You have failed login attempts since your last login.\n" );
catch( "adm/usr/piper/svote3"->check_open_votes() );
}
}
if ( add_msg[3] )
write( "\nYou are in tell refuse mode.\n\n" );
catch( CHURCH->inc_calls() );
catch( POST_OFFICE->query_mail( name ) );
catch( EXPLORE_D->update( this_object() ) );
if ( !GUEST_D->query_is_guest( name ) ) { // let's skip this for guests, bytre 10-sep-2008
if ( query_ip_name(this_object()) != called_from_ip && called_from_ip )
write( "Your last login was from "+ called_from_ip +"\n" );
if ( !remember_throw && remember_last_time )
write( "Your last login was "+
(string)"secure/xfun"->time_to_string( time() - remember_last_time ) +
" ago.\n" );
called_from_ip = query_ip_name(this_object());
} // end of guest skip of last login info
squelchees = query_squelchees();
sqz = sizeof(squelchees);
tmp_msg = "You have squelched: ";
if(sqz > 0)
{
if(sqz == 1){ tmp_msg += capitalize(squelchees[0])+"."; }
if(sqz == 2){ tmp_msg += capitalize(squelchees[0])+" and "
+capitalize(squelchees[1])+"."; }
if(sqz > 2)
{
tmp_msg += capitalize(squelchees[0]);
for(i=1; i<sqz-1; i++)
{
tmp_msg += ", "+capitalize(squelchees[i]);
}
tmp_msg += " and "+capitalize(squelchees[sqz-1])+".";
}
writef(tmp_msg);
}
if ( environment() ) {
object ob;
ob = first_inventory( environment() );
while ( ob ) {
if ( ob != this_object() ) {
string sh;
if ( sh = (string)ob->short() )
write( capitalize( sh ) + ".\n" );
}
ob = next_inventory( ob );
}
}
if ( level && (level > WIZLEVEL) ) {
if ( !"secure/config"->query_config( name, "pathsave" ) ) {
current_path = "/w/"+ name;
}
} else if ( level == WIZLEVEL &&
"d/Education/room/register"->is_student() ) {
current_path = "/w/"+name;
}
calculate_power();
if ( (level < WIZLEVEL) && (query_defend() == 4) && (class != FIGHTER) ) {
write( "Only fighters can fight like berserkers.\n" );
set_defend( "none" );
}
this_object()->alt_prompt( misc["prompt"] );
if ( misc["alt_soul"] && query_flag( "D1" ) && find_object( SOULBASE ) )
SOULBASE->register_donator( this_object() );
set_check_log( 1 );
if ( this_object()->query_lawlog() ) {
"adm/usr/flint/lawlog"->write_law_log2( name, ctime() +": LOGIN\n" );
}
set_check_log( 0 );
#ifdef VERSION_ASK_NEWBIES
#ifdef VERSION_NEWBIE_TUT
if( newbie_status == 1 || newbie_status == 2) //player is new to MUDS or AA
this_object()->move_player("silent#w/dafeon/tweaks/tutorial/room/entrance");
if ( err ) // Also remove later - will be pointless unless we change to 3 different err variables
write( "WARNING: There was a problem creating the newbie equipment.\n"
"Please report this error to a wizard.\n" );
return;
#endif
if ( newbie_status == 1 ) { // Player is new to MUDS
err=catch( clone_object("/w/llandra/newbie/carving")->move(this_object()) );
if (!err) // Remove later - Don't want to deny the newbie everything.
err=catch( clone_object("/w/scarecrazy/ironman/obj/newbie_club")->move(this_object()) );
if (!err) // Remove later - Don't want to deny the newbie everything.
err=catch( clone_object("/w/scarecrazy/ironman/obj/newbie_armour")->move(this_object()) );
if (!err) // Remove later - Don't want to deny the newbie everything.
err=catch( clone_object("/w/grunthex/map/mapkit")->move(this_object()) );
if (!err) // Remove later - Don't want to deny the newbie everything.
err=catch( clone_object("/w/dafeon/newbcard/card")->move(this_object()) );
set_wimpy( 1 );
} else if ( newbie_status == 2 ) { // Player is new to AA
err=catch ( clone_object("/w/llandra/newbie/carving")->move(this_object()) );
if (!err) // Remove later - Don't want to deny the newbie everything.
err=catch( clone_object("/w/scarecrazy/ironman/obj/newbie_club")->move(this_object()) );
if (!err) // Remove later - Don't want to deny the newbie everything.
err=catch( clone_object("/w/scarecrazy/ironman/obj/newbie_armour")->move(this_object()) );
if (!err) // Remove later - Don't want to deny the newbie everything.
err=catch( clone_object("/w/grunthex/map/mapkit")->move(this_object()) );
if (!err) // Remove later - Don't want to deny the newbie everything.
err=catch( clone_object("/w/dafeon/newbcard/card")->move(this_object()) );
set_wimpy( 1 );
} else { // Player is an AA native, he knows where to get the goodies.
}
if ( err ) { // Also remove later - will be pointless unless we change to 3 different err variables
write( "WARNING: There was a problem creating the newbie equipment.\n"
"Please report this error to a wizard.\n" );
}
#endif
}
void time_out() {
tell_object( this_object(), "Time out.\n" );
destruct( this_object() );
}
nomask void convert_stuff() {
/*
* wiz_radio and add_msg might have to be updated
*/
if(!wiz_radio||!mappingp(wiz_radio))
wiz_radio = ([ "wiz":1,"arch":0,"domain":0, ]);
if(!add_msg)
add_msg = ({ 0,1,0,0,0,1,0 });
else if(stringp(add_msg[1])){
add_msg += ({ 0, 0, 1, 0 });
add_msg[2] = add_msg[1];
add_msg[1] = 1;
}
else if(level < WIZLEVEL && add_msg[3]) add_msg[3] = 0;
// if(!mquest_level) mquest_level = 1;
if(!misc) misc = ([ ]);
/** for now, players will have to solve all quests..
11.4.92 Zor
if(my_quest_max == 0)
take old value for level 18+ 19.9.92 Zor
*/
/* Made it be 17+ with the addition of another quest (Midian) */
/* All will be updated again, but they only have to solve 80%
if(level < 17)
*/
if(level < WIZLEVEL)
my_quest_max = "room/quest_room"->current_quest_points();
/* only temporarily */
if(!flags) { /* no converts done yet, let's do all */
/* guild/class conversion */
if(guild) {
class = guild;
guild = 0;
}
flags = set_bit("", 1);
/* florin/halforc quest conversion */
if(quests) quests = replace_string(quests, "halforc", "florin");
flags = set_bit(flags, 2);
}
else {
if(!test_bit(flags, 1)) { /* quest/class not changed yet */
if(guild) {
class = guild;
guild = 0;
}
if(!flags) flags = "";
flags = set_bit(flags, 1);
}
if(!test_bit(flags, 2)) { /* florin/halforc quest not converted yet */
if(quests) quests = replace_string(quests, "halforc", "florin");
flags = set_bit(flags, 2);
}
}
if(!test_bit(flags, 16)) { /* not member of highest donation class */
string dtmp;
dtmp = (string)DONATOR_D->query_class(name);
if(!dtmp) return; /* NO OTHER CONVERSION BELOW!! */
if(dtmp == "D2") {
flags = set_bit(flags, 16); /* D2 */
flags = set_bit(flags, 17); /* D1 too */
}
else if(dtmp == "D1") flags = set_bit(flags, 17); /* D1 only */
}
}
// ------------------------------------------------------- QUITTING AND SAVING
int quit() {
object *inv, ob;
int cnt;
if ( is_statue ) {
remove_call_out( "extra_quit" );
#ifdef VERSION_LINKDEAD_CHILL
if(CHILL_D->query_chilled(query_real_name())) {
CHILL_D->thaw_player(this_object(), 1); // sending the 'quitting' flag
}
#endif
}
// the following loop moved above the call to save_me by Adinos, 000319
filter_objects( deep_inventory(), "owner_quit" );
if ( !GUEST_D->query_is_guest( name ) ) {
log_quit( throw_flag );
// removed wizard check to log_quit 12-jun-06 bytre
last_login = time();
if ( donate_force_quit && !time_to_wake && interactive( this_object() ) )
time_to_wake = time() + 100;
save_me( 0 );
write( "Saving "+ capitalize( name ) +".\n" );
}
if ( level < WIZLEVEL ) {
cnt = sizeof( inv = all_inventory() );
while ( cnt-- ) {
ob = inv[cnt];
// Dropping one item can cause others to self-dest.
if ( ob && (string)ob->short() && !(int)ob->drop() && ob &&
!(string)ob->query_auto_load() ) {
ob->move( environment() );
}
}
}
cnt = sizeof( inv = deep_inventory() );
while ( cnt-- ) {
if( inv[cnt] ) // Destructing one item can cause others to self-dest.
destruct( inv[cnt] );
}
if ( !is_invis )
say( cap_name +" left the game.\n" );
if ( !throw_flag ) {
NOTIFIER_D->logout( ({ name, level, DEFAULT_IP_NAME }) );
}
if ( MAXMORTAL < level ) {
catch( WIZLINE_D->remove_entry( this_object() ) );
}
log_file( "QUIT", name +"("+ level +","+ query_exp_number_string() +") "+
ctime()[4..18] +".\n", 200000 );
#ifdef SCORE_SESSION
if (query_player_data("session"))
score_session(1);
#endif
"secure/tool"->lw_delay();
fortune::quit();
destruct( this_object() );
return 1;
}
nomask void extra_quit() {
if ( level > MAXMORTAL || query_test_char() ) {
move_player( "away#secure/void" );
} else {
int mm;
mm = money;
keep_list = ({});
if (this_object()->query_player_data_default("autoquit autosell")) {
if ( file_name( environment() ) != "/room/newvill/shop" )
move_player( "away#room/newvill/shop" );
catch( command( "sell all" ) );
}
log_file( "EXQUIT", ctime() +": "+ capitalize( name ) +"("+ level +") ["+
money +"-"+ mm +"="+ (money - mm) +"] {"+
"}\n", 200000 );
}
quit();
}
void extra_quit2() {
extra_quit();
}
int log_quit( status flag ) {
string time1, time2, result;
int diff,diff2;
time1 = ctime(time());
time2 = ctime(last_login);
diff = experience - last_experience;
diff2 = experience_billions - last_experience_billions;
if (diff2) diff = diff2*BILLION + diff;
catch(call_other("/w/bytre/stats/statcoll","player_logout",
this_player(), time()-last_login, diff));
if (level > MAXMORTAL) return 1; // added 12-jun-06 bytre
if ( time1[4..9] == time2[4..9] )
result = time2[0..18] +" - "+ time1[11..18];
else
result = time2[0..18] +" - "+ time1[0..18];
if ( !diff ) {
log_file( "EXP_NO_CHANGE", result +": "+ capitalize( name ) +
"("+ level + (flag ? ") (throw)\n" : ")\n") );
return 1;
}
result = result +": "+ capitalize( name ) +"("+ level +") => "+ diff;
if ( flag )
result = result +" (throw)\n";
else
result = result +"\n";
log_file( "EXP_CHANGE", result );
if ( diff > 100000 ) {
log_file( "EXP_BIG_CHANGE", result );
}
return 1;
}
nomask silent_quit() {
if ( file_name( previous_object() ) == "/secure/tool" ) {
throw_flag = 1;
quit();
}
}
/*
* Recursively compute the values of the inventory.
* Beware that object may selfdestruct when asked for query_value().
*/
nomask int compute_values( object ob ) {
int v;
while ( ob ) {
int tmp;
object next_ob;
next_ob = next_inventory( ob );
tmp = (int)ob->query_value();
if ( (tmp > 1000) && (ob && !ob->no_max_value()) )
tmp = 1000;
v += tmp;
if ( ob && first_inventory( ob ) )
v += compute_values( first_inventory( ob ) );
ob = next_ob;
}
return v;
}
void save_me( int value_items ) {
if ( GUEST_D->query_is_guest( name ) ) {
if (0) // Let's not badger guests with this! bytre 10-sep-2008
write( "The state of guest cannot be saved!\n" );
} else {
if ( value_items )
tot_value = compute_values( first_inventory( this_object() ) );
else
tot_value = 0;
compute_auto_str();
if ( (level < WIZLEVEL) && !misc["testchar"] ) {
catch( LIST_D->update( this_object() ) );
}
save_player( name );
}
}
nomask int save_character() {
if ( GUEST_D->query_is_guest( name ) ) {
write( "The state of guest cannot be saved!\n" );
} else {
save_me( 1 );
write( "Ok.\n" );
}
return 1;
}
// --------------------------------------------------------------------- SITES
nomask int set_site( string str ) {
if ( previous_object() == this_object() ) {
string *site_result;
if ( !misc )
misc = ([]);
site_result = ({});
if ( str == "show" ) {
write( "You are allowing the following sites:\n" );
show_sites();
return 1;
} else if ( str == "add" ) {
site_result = misc["site"];
} else if ( str == "remove" ) {
site_result = misc["site"];
if ( !site_result ) {
write("You haven't defined any sites yet.\n");
return 1;
}
write( "Enter site to be removed (end with **): " );
input_to( "remove_site", 0, site_result );
return 1;
}
if ( !site_result )
site_result = ({});
write( "Enter site (end with **): " );
input_to( "add_site", 0, site_result );
return 1;
}
}
static void add_site( string str, string *site_result ) {
if ( str == "**" ) {
if ( sizeof( site_result ) )
misc["site"] = site_result;
else
misc = m_delete( misc, "site" );
show_sites();
return;
} else if ( check_input_site( str ) &&
member_array( str, site_result ) < 0 ) {
site_result += ({ str });
}
write( "Enter site (end with **): " );
input_to( "add_site", 0, site_result );
}
static void remove_site( string str, string *site_result ) {
if ( str == "**") {
if ( !misc["site"] ) {
misc = m_delete( misc, "site" );
write( "No sites defined.\n" );
} else {
show_sites();
}
return;
}
if ( member_array( str, site_result ) < 0 ) {
write( "No such site defined!\n" );
return;
}
site_result -= ({ str });
if ( !site_result || !sizeof( site_result ) )
misc = m_delete( misc, "site" );
else
misc["site"] = site_result;
write( "Enter site to be removed (end with **): " );
input_to( "remove_site", 0, site_result );
}
static int check_input_site( string str ) {
string *parts;
int i, dummy;
parts = explode( str, "." );
if ( (dummy = sizeof( parts )) != 4 ) {
write( "Corrupt site number, please enter it again.\n" );
return 0;
}
for ( i = 0 ; i < dummy ; i++ ) {
if ( parts[i] == "*" || sscanf( parts[i], "%~d" ) == 1 )
continue;
write( "Corrupt site number, use number only!\n" );
return 0;
}
return 1;
}
static int show_sites() {
mixed *sites;
sites = misc["site"];
if ( sites ) {
int i;
for ( i = sizeof( sites ) ; i-- ; ) {
write( sites[i] +"\n" );
}
}
return 1;
}
int check_site( string str ) {
string *sites, *sitep, *sitei;
int i, p, no_match;
if ( !misc )
return 1;
sites = misc["site"];
if ( !sites || member_array( str, sites ) >= 0 )
return 1;
sitei = explode( str, "." );
for ( i = 0 ; i < sizeof( sites ) ; i++ ) {
sitep = explode( sites[i], "." );
for ( p = 0 ; p < sizeof( sitep ) ; p++ ) {
if ( sitep[p] == "*" || sitep[p] == sitei[p] )
continue;
no_match = 1;
break;
}
if ( !no_match )
return 1;
no_match = 0;
}
return 0;
}
// -------------------------------------------------------------------- TITLES
private nomask void _log_set_title( string which, string t ) {
if ( this_player() && interactive( this_player() ) ) {
log_file( "SET_TITLE",
"["+ ctime()[4..15] +"] "+
capitalize( (string)this_player()->query_real_name() ) +
" ["+ (string)this_player()->query_level() +"] changed "+
cap_name +"'s ["+ level +"] "+ which +" to \""+ t +"\"\n" );
}
}
nomask int set_title( string t ) {
if ( !t ) {
write( "Your title is "+ title +".\n" );
return 1;
}
if ( strlen( t ) > 80 ) {
write( "Too long title.\n" );
return 1;
}
if ( this_player() != this_object() ) {
if ( level > WIZLEVEL )
tell_object( this_object(),
capitalize( (string)this_player()->query_real_name() ) +
" changed your title.\n" );
_log_set_title( "title", t );
}
title = t;
return 1;
}
int set_pretitle( string t ) {
if ( stringp( t ) && strlen( t ) > MAX_PRETITLE_LENGTH ) {
write( "Too long pretitle.\n" );
return 1;
}
if ( this_player() != this_object() ) {
if ( level > WIZLEVEL )
tell_object( this_object(),
capitalize( (string)this_player()->query_real_name() ) +
" changed your pretitle.\n" );
_log_set_title( "pretitle", t );
}
pre_title = t;
return 1;
}
// ------------------------------------------------------------ LIFE AND DEATH
int kill( string str ) {
object ob;
#if VERSION_KILL
string msg, tmp;
#endif /* VERSION_KILL */
if ( ghost )
return 0;
if ( !str ) {
write( "Kill what?\n" );
return 1;
}
ob = present( lower_case( str ), environment( this_player() ) );
if ( !ob ) {
write( "No "+ str +" here!\n");
return 1;
}
if ( (!living(ob)) || ((!ob->query_npc()) && (!ob->query_is_player())) ) {
#if VERSION_KILL
if ( !(tmp = (string)ob->query_short()) ) {
if ( !(tmp = (string)ob->query_name()) ) {
write( capitalize(str) +" is not a living thing!\n" );
//Note: No say() is given
return 1;
}
tmp = "the "+tmp;
}
str = tmp;
if ( msg = (string)ob->query_nokill_string() )
writef( msg );
else
write( capitalize(str)+" is not a living thing!\n" );
#else
write( str +" is not a living thing!\n" );
#endif /* VERSION_KILL */
say( cap_name +" foolishly tries to attack "+ str +".\n" );
return 1;
}
if ( ob == this_object() ) {
write( "What? Attack yourself?\n" );
return 1;
}
if ( attacker_ob == ob) {
write( "Yes, yes.\n" );
return 1;
}
#if VERSION_JUSTICE
if ( JUSTICE_D->query_no_kill( this_object(), ob, "attacked" ) )
return 1;
#else
if ( environment()->query_no_kill( ob ) )
return 1;
#endif
// handle obs that destruct in their no_kill, eg Ilderian child
if ( !ob )
return 1;
if (ob->query_hunted() == this_object()) {
attacked_by(ob);
if (attacker_ob != ob) {
alt_attacker_ob = attacker_ob;
attacker_ob = ob;
write("You turn to attack "+str+".\n");
}
return 1;
}
if ( attacker_ob && present( attacker_ob, environment( this_player() ) ) ) {
alt_attacker_ob = attacker_ob;
attacker_ob = ob;
write( "You turn to attack "+ str +".\n" );
return 1;
}
if ( body_position )
write( "You attack "+ str +" while "+ query_body_position_string() +
".\n" );
attack_object( ob );
return 1;
}
static void heart_beat() {
int t; // time to reboot
int logoutsec; // sec to logout
// moved from is_statue checks to ensure is_ld and saves happen - 1/2014 Newt
if ( !interactive( this_object() ) ) {
set_heart_beat( 0 );
if ( is_statue > 1 ) // now uses 2 in order to NOT call_is_ld
return; // 2 is already linkdead
if ( !is_statue ) {
if ( !is_invis )
say( cap_name + " turns into a stone statue.\n", this_object() );
} else if ( !is_invis )
say("The eyes of a stone statue of "+ cap_name +" seem to dim.\n", this_object() );
is_statue = 2; // now uses 2 in order to NOT call_is_ld next beat
remove_call_out("extra_quit");
call_out( "extra_quit", query_ld_idle_timeout() );
catch( NOTIFIER_D->link_dead( this_object() ) );
catch( WIZLINE_D->remove_entry( this_object() ) );
stop_follow();
if ( name_of_party )
leave_party();
call_is_ld();
save_me( 1 );
return;
}
if ( !is_statue ) {
if ( query_idle(this_object()) >= IDLE_SECONDS ) {
if ( geteuid() == ADMIN_UID ) {
seteuid( getuid() );
write("You retain your normal status.\n");
}
write( "As time passes you turn into a stone statue.\n" );
// add a save at the point of going idle, bytre 2012-07-23
save_me( 0 );
// change to time_to_string vs. minutes 2010-10-03 bytre
logoutsec=query_idle_timeout();
t=(int)"/room/newvill/inn"->query_time_to_reboot();
if (t<logoutsec)
logoutsec=t;
write( "You will be logged out in "+
(string)"/secure/xfun"->time_to_string( logoutsec)+".\n");
// change to time_to_string vs. minutes 2010-10-03 bytre
if ( !is_invis )
say( cap_name +" slowly turns into a stone statue.\n", this_object() );
is_statue = 1; // now uses 1 in order to call_is_ld properly
stop_follow();
if ( misc["testchar"] )
call_out( "test_char_warning", 3300 );
else if ( !misc["no_timeout"] )
call_out( "extra_quit", logoutsec );
return;
}
} else if ( query_idle( this_object() ) < IDLE_SECONDS ) {
is_statue = 0;
if ( misc["testchar"] )
remove_call_out( "test_char_warning" );
remove_call_out( "extra_quit" );
write( "As you move, you turn living again.\n" );
if ( !is_invis ) {
say( cap_name +" turns living again.\n", this_object() );
hook("destatue", ({}));
}
return;
} else {
return;
}
if ( ghost )
return;
age += 1;
hook("heart_beat", ({ }) );
if ( age > time_to_save ) {
if ( !brief && level < WIZLEVEL && !GUEST_D->query_is_guest( name) )
write( "Autosave.\n" );
save_me( 1 );
time_to_save = age + AUTOSAVE_TIME;
}
if ( poisoned && (age > time_to_act_poison) ) {
if ( body_position ) {
switch ( body_position ) {
case KNEELING: {
hit_point -= 1 + random( 2 );
break;
}
case SITTING: {
hit_point -= 1 + !random(3);
break;
}
case LYING: {
hit_point -= 1;
break;
}
}
} else {
hit_point -= 2;
}
if ( hit_point < 0 ) {
write( "You die from the poison.\n" );
hit_player( 1000 ); /* Make sure the player dies */
return;
} else {
write( "You feel the poison stealing your life away.\n" );
}
time_to_act_poison += (11 - poisoned);
}
intoxication_message();
time_to_heal -= 1;
if ( time_to_heal < 0 ) {
if ((hit_point < query_max_hp()) || (spell_points < query_max_sp()) ||
headache ) {
intoxicated_headache();
if ( (hit_point < query_max_hp()) || (spell_points < query_max_sp()) ) {
int *tmp_regen;
catch( tmp_regen = (int *)REGEN_D->
query_regen( BASE_HP_REGEN, BASE_SP_REGEN ) );
hit_point += tmp_regen[0];
spell_points += tmp_regen[1];
}
if ( hit_point > query_max_hp() )
hit_point = query_max_hp();
if ( spell_points > query_max_sp() )
spell_points = query_max_sp();
}
}
intoxicated_heart_beat( time_to_heal );
stuffed_heart_beat( time_to_heal );
soaked_heart_beat( time_to_heal );
// Reset time to heal
if ( time_to_heal < 0 )
time_to_heal = INTERVAL_BETWEEN_HEALING;
if ( attacker_ob )
attack();
if ( whimpy && attacker_ob && (hit_point < (query_max_hp() * whimpy) / 10) ) {
#ifdef VERSION_INCREASED_MORTAL_LEVEL
add_exp(-1*(int)((20000/3.1415926) * atan((float)(experience*3.1415926/20000000))));
#else
this_object()->add_exp(-1*(int)(experience / 1000)));
#endif
run_away();
}
// command stack timing addition - Bytre 1/may/0
if ( time() > (cmd_stack_timing + 6) ) {
if ( LAW_MAX_MOVES_PER_SIX < cmd_stack_counter )
"/adm/tools/slowdown/speedwalk"->slow( this_object(), cmd_stack_counter );
cmd_stack_timing = time();
cmd_stack_counter = 0;
}
}
reset_heart() {
set_heart_beat( 1 );
}
void call_is_ld() {
object *inv;
int i;
i = sizeof( inv = all_inventory( this_object() ) );
while ( i-- ) {
if (inv[i])
inv[i]->is_ld();
}
if ( environment() ) {
environment()->gone_linkdead( this_object() );
}
}
int second_life() {
object death_mark;
if ( level >= WIZLEVEL )
return illegal_patch( "second_life" );
NOTIFIER_D->death( ({ name, level,
attacker_ob ? attacker_ob->short() : (poisoned ? "poison" : "?") }) );
#ifndef TESTMUD /* off for testmud altogether. Fir Mar 2013 */
// death_fix Buxley Mar 2013: testchars off grave_d
if ( attacker_ob && attacker_ob->query_name() &&
!this_object()->query_test_char()) {
catch( GRAVE_D->gen_deaths( ({ name, level }),
({ attacker_ob->query_name() }) ) );
}
#endif
catch( environment()->player_died_here( this_object(), attacker_ob ) );
make_scar();
ghost = 1;
poisoned = 0;
if ( level > 1 )
level = level - 1;
if ( Str > 1 )
set_str( Str - 1 );
if ( Con > 1 )
set_con( Con - 1 );
if ( Dex > 1 )
set_dex( Dex - 1 );
if ( Int > 1 )
set_int( Int - 1 );
if ( Wis > 1 )
set_wis( Wis - 1 );
setmin( "drifts around" );
setmout( "blows" );
headache = 0;
intoxicated = 0;
stuffed = 0;
soaked = 0;
hunter = 0;
hunted = 0;
#ifdef LOG_KILLS
if ( attacker_ob ) {
call_out( "notify_death_objects", 0, ({ name, level,
attacker_ob->query_real_name(), attacker_ob->query_level() }) );
#ifdef VERSION_PARTY_UPDATE
call_out( "notify_death_party", 0, attacker_ob->query_cap_name());
#endif
if ( attacker_ob->query_npc() ) {
log_file( "KILLS", ctime()[4..15] +": "+ name +"("+ level +") killed by "+
(string)attacker_ob->short() +"("+ (int)attacker_ob->query_level() +
"), uid: " + getuid( attacker_ob ) +"\n" );
if ( attacker_ob->query_former_master() ) {
log_file( "PLAYER_KILLS", name +" killed by "+
(string)attacker_ob->query_former_master() +"'s pet in "+
file_name( environment() ) +".\n" );
}
call_out( "notify_pk_death_objects", 0, ({ name, level,
file_name( attacker_ob ), -10}) );
} else {
// Oliver 08 Sept 2008 - Moved the #endif above the call to the SK brain
// previous version skipped it causing all SK
// activity to cease.
#if VERSION_JUSTICE
JUSTICE_D->log_kill(attacker_ob,this_object());
#else
log_file( "PLAYER_KILLS", name +"("+ level +") killed by "+
(string)attacker_ob->query_real_name() +"("+
(int)attacker_ob->query_level() +") at "+ ctime() +"\n" );
#endif
call_out("notify_pk_death_objects", 0, ({ name, level,
attacker_ob->query_real_name(), attacker_ob->query_level() }) );
}
}
else // killed by a nameless cause?
log_file( "NAMELESS_KILLS", name +" killed in "+
file_name(environment())+ " after doing '"+
query_verb()+"'.\n" );
#endif
attacker_ob = 0;
alt_attacker_ob = 0;
tell_object( this_object(), "\nYou die.\nYou have a strange feeling.\n"
"You can see your own dead body from above.\n\n" );
#if VERSION_PARTY
// Arp 12/07/02: Done in party_notify_death
#else
if ( name_of_party )
leave_party();
#endif
death_mark = clone_object( DEATH_MARK );
death_mark->move( this_object() );
return 1;
}
void notify_pk_death_objects( mixed *killarray ) {
catch( true_notify_pk_death_objects( killarray ) );
}
void true_notify_pk_death_objects( mixed *killarray ) {
"w/hatamoto/pk/obj/brain"->death( killarray[0..1], killarray[2..3] );
}
void notify_death_objects( mixed *killarray ) {
catch( true_notify_death_objects( killarray ) );
}
void true_notify_death_objects( mixed *killarray ) {
if ( guild ) {
guild->notify_death( killarray[0..1], killarray[2..3] );
}
#if VERSION_PARTY
if ( name_of_party ) {
party_notify_death( killarray[0..1], killarray[2..3] );
}
#endif
}
#ifdef VERSION_PARTY_UPDATE
void notify_death_party( string opponent ) {
catch( true_notify_death_party( opponent ) );
}
void true_notify_death_party( string opponent ) {
string header;
if (name_of_party) {
header = "<"+name_of_party+"> *** ";
tell_all_party(get_f_string(header+cap_name+" ["+level+
"] has been killed by "+opponent+"! ***", 0, strlen(header)));
}
}
#endif
int remove_ghost() {
if ( ghost ) {
write( "You feel a very strong force.\n"
"You are sucked away...\n"
"You reappear in a more solid form.\n" );
say( "Some mist disappears.\n" );
say( cap_name +" appears in a solid form.\n" );
ghost = 0;
dead = 0;
setmin( "arrives" );
setmout( "leaves" );
save_me( 1 );
return 1;
}
}
int query_dead() {
return dead;
}
void reset_dead() {
dead = ghost;
}
#define MAX_SCAR 10
int scar;
static void make_scar() {
if ( level >= 10 ) {
scar |= 1 << random( MAX_SCAR );
}
}
void show_scar() {
int i, j, first, old_value;
string *scar_desc;
string poss;
scar_desc = ({ "left leg", "right leg", "nose", "left arm", "right arm",
"left hand", "right hand", "forehead", "left cheek",
"right cheek" });
j = 1;
first = 1;
old_value = scar;
poss = this_object()->query_possessive();
while ( i < MAX_SCAR ) {
if ( scar & j ) {
old_value &= ~j;
if ( first ) {
write( cap_name +" has a scar on "+ poss +" "+ scar_desc[i] );
first = 0;
} else if ( old_value ) {
write( ", "+ poss +" "+ scar_desc[i] );
} else {
write( " and "+ poss +" "+ scar_desc[i] );
}
}
j *= 2;
i += 1;
}
if ( !first )
write( ".\n" );
}
int query_scar() {
return scar;
}
void heal_scar( int i ) {
if ( (i >= 0) && (i <= MAX_SCAR) ) {
if ( this_player() != this_object() && (level < WIZLEVEL) ) {
log_file( "SUSPICIOUS", "["+ ctime() +"] "+
capitalize( (string)this_player()->query_real_name() ) +
" healed "+ name +"'s scar "+ i +".\n" );
}
scar &= ~(1 << i);
}
}
// ------------------------------------------------------------------ ARCHKILL
nomask void set_wakeup( int arg ) {
if ( interactive( this_player() ) && intp( arg ) ) {
if ( (this_player() == this_interactive()) &&
(this_player() == this_object() ||
(int)this_interactive()->query_level() > SENIORLEVEL) ) {
time_to_wake = arg;
}
}
}
int query_time_to_wake() {
return time_to_wake;
}
// ----------------------------------------------------------------- ALIGNMENT
void update_alignment_title(){
int al;
if ( ghost || level >= WIZLEVEL)
return;
al=(int)query_alignment();
if ( al > (KILL_NEUTRAL_ALIGNMENT * 100) )
al_title = "saintly";
else if ( al > (KILL_NEUTRAL_ALIGNMENT * 20) )
al_title = "good";
else if ( al > (KILL_NEUTRAL_ALIGNMENT * 4) )
al_title = "nice";
else if ( al > -(KILL_NEUTRAL_ALIGNMENT * 4) )
al_title = "neutral";
else if ( al > -(KILL_NEUTRAL_ALIGNMENT * 20) )
al_title = "nasty";
else if ( al > -(KILL_NEUTRAL_ALIGNMENT * 100) )
al_title = "evil";
else
al_title = "demonic";
}
void add_alignment( int a, int direct ) {
if ( !intp( a ) ) {
write( "Bad type argument to add_alignment.\n" );
return;
}
if ( ghost )
return; // bytre oct 8 95
if ( direct ) // Greyson, 13-Apr-96
alignment += a;
else
alignment = alignment * 9 / 10 + a;
update_alignment_title();
}
void set_al( int a ) {
if ( intp( a ) ) {
alignment = a;
update_alignment_title();
}
}
nomask void set_alignment( string al ) {
if ( this_player() != this_object() ) {
_log_set_title( "al_title", al );
}
al_title = al;
}
// ------------------------------------------------------ LEVEL AND EXPERIENCE
nomask add_exp( e ) {
if ( ghost ) return; // bytre oct 8 95
#ifdef LOG_EXP
if ( this_player() && (this_player() != this_object()) &&
interactive( this_player() ) ) {
log_file( "EXPERIENCE", ctime() +" "+ name +"("+ level +") "+ e +
" exp by "+ (string)this_player()->query_real_name() +"("+
this_player()->query_level() +")\n" );
if ( (this_player()->query_level() >= WIZLEVEL) && (level < WIZLEVEL) &&
(!(query_test_char())) ) {
log_file( "SUSPICIOUS", "["+ ctime() +"] "+ capitalize( name ) +
" ("+ level +") "+ e +" experience by "+
capitalize( (string)this_player()->query_real_name() ) +" ("+
this_player()->query_level() +")\n" );
}
}
#endif
// If were going to overflow, lets not, and cap it to the 31st bit.
if (experience > 0x70000000 && (experience+e) < 0)
e = 0x7fffffff-experience;
// If more than 2 billion, remove 1 billion and add one to the billion
// counter
if (experience+e >= 2*BILLION) {
experience -= BILLION;
experience_billions++;
}
// If we drop below 1 billion xp and we have billions, add one of the
// billions back on and remove one of the counters.
if (experience_billions && experience+e <= BILLION) {
experience += BILLION;
experience_billions--;
}
/* Clan dedication added by Zor, January 12 1996 */
if ( clan_dedication )
catch( CLAN_EXP_D->add_xp( clan, name, e ) );
else
experience += e;
if ( level <= MAXMORTAL )
add_worth( e );
// XP hook only available during event to prevent abuse.
#ifdef XP_EVENT
#if XP_EVENT
experience += hook("exp_mod", ({ e }));
#endif
#endif
}
nomask int set_level( int lev ) {
/* Do not allow WIZARDs to patch APPRENTICEs to WIZARD! Midian */
if ( lev > WIZLEVEL && file_name( previous_object() )[0..7] != "/obj/leo" )
return illegal_patch( "set_level" );
if ( (lev > WIZARDLEVEL) || lev < level && level >= WIZLEVEL )
return illegal_patch( "set_level" );
if ( this_interactive() ) {
log_file( "SET_LEVEL", this_interactive()->query_real_name() +" setted "+
query_real_name() +" level to "+ lev +"\n" );
}
if ( (this_player() != this_object()) && !query_test_char() ) {
log_file( "SUSPICIOUS", "["+ ctime() +"] "+ capitalize( name ) +
" ("+ level +") set to level "+ lev +" by "+
capitalize( (string)this_player()->query_real_name() ) +" ("+
this_player()->query_level() +")\n" );
}
level = lev;
if ( level == WIZLEVEL ) {
catch( clone_object( APPRENTICE_SCROLL )->move( this_object() ) );
tell_object( this_object(), "You have been given a scroll containing "
"valuable information. Read it now!\n"
"Adding wizard commands...\n"
"You may have to log off and back on for all the changes to take "
"effect.\n" );
"secure/tool"->adm_log( "APPRENTICE", "["+ ctime() +"] "+
capitalize( name ) );
/* wizards are not allowed in clans, Zor January 12 1996 */
if ( clan )
catch( CLAN_D->remove_member( clan, name, 3 ) );
wiz_commands();
wiz_radio::add_init();
}
if ( level == WIZARDLEVEL ) {
tell_object( this_object(), "Adding more wizard commands...\n"
"You may have to log off and back on for all the changes to take "
"effect.\n" );
wiz_commands2();
}
return 1;
}
list_peoples( str ) {
"secure/tool"->list_peoples( str );
return 1;
}
mixed *query_people() {
return ({ c_name ? c_name : name, level, age, is_invis, ghost,
misc["testchar"] });
}
nomask int illegal_patch( string what ) {
write( "You are struck by a mental bolt from the interior of the game.\n" );
log_file( "ILLEGAL", ctime() +": "+
(string)this_player()->query_real_name() +" "+ what +"\n" );
return 0;
}
void smart_report( string file, string str ) {
string euid, pa, current_room;
euid = geteuid( environment() );
current_room = file_name( environment() );
if ( euid != "map" ) {
pa = "secure/tool"->get_log_dir( euid );
if ( pa ) {
if ( "secure/config"->query_config( euid, "one_rep" ) ) {
"secure/tool"->log_smart_report( pa +".rep",
file +" "+ current_room +" "+ str +"\n\n" );
} else {
"secure/tool"->log_smart_report( pa + file, current_room +" "+
str +"\n\n" );
}
} else {
log_file( euid +".rep", file +" "+ current_room +" "+ str +"\n" );
}
} else {
log_file( "map.rep", file +" "+ current_room +" "+ str +"\n" );
}
}
// to reset some parameters in OTHER players!
int do_transmute() {
if ( snoop_allow )
snoop_on( "forbid" );
if ( snoop_allowed )
snoop_allowed->remove_snoop_allow();
if ( name_of_party )
leave_party();
return 0;
}
// ------------------------------------------------------------------- QUERIES
nomask int query_hit_point() {
return hit_point;
}
string query_title() {
return title;
}
string query_pretitle() {
return pre_title;
}
string query_al_title() {
return al_title;
}
nomask status query_is_statue() {
// pl_selfharm: Return up-to-date statuedness data for combat purposes.
// heart_beat updates the variable and callouts in a second. Fir Nov'15
// Protect query_idle against exposure to non-interactive statues.
if( is_statue == 1 && interactive( this_object() ) &&
query_idle( this_object() ) < IDLE_SECONDS )
return 0; // Not a statue.
return !!is_statue; // is_statue >1 is internal only Newt 1/25/2014
}
nomask string query_real_name() {
return name;
}
nomask string query_capi_name() {
return c_name;
}
int query_last_login() {
return last_login;
}
nomask string query_password() {
string s;
int i;
if (previous_object() == 0) return crypt(pasword, 0);
if (query_verb() == "suicide") return password; // [Buxley 14 April 2023]
s = file_name(previous_object());
if (s == "/room/wiz/meat_locker") return password;
if (s == "/w/greyson/room/basement") return password;
log_file( "ILLEGAL_QUERY_PASSWORD", ctime() +" "+s[0..10]+" called query_password in "+this_object()->query_real_name()+"\n" );
if (s[0..10] == "/obj/player")
{
s = previous_object()->query_real_name();
i = 0;
if (interactive(previous_object())) i = previous_object()->query_level();
log_file( "ILLEGAL_QUERY_PASSWORD", ctime() +" "+s+" ["+i+"] called query_password in "+this_object()->query_real_name()+"\n" );
if (i > 899) return password;
}
return crypt(pasword, 0);
}
void test_char_warning() {
object ob;
tell_object( this_object(),
"You are far too idle... 5 minutes till autoquit!\n" );
if ( ob = find_player( misc["testchar"] ) )
tell_object( ob, "Don't forget your test character!\n" );
call_out( "extra_quit", 300 );
}
// ---------------------------------------------------------------- BANK MONEY
nomask int add_bank_money( int m ) {
if ( this_player()!=this_object() ) {
log_file( "ILLEGAL_BANK", ctime() +" "+
(string)this_player()->query_real_name() +"("+
file_name( this_player() ) +") add "+ m +" in "+ cap_name +"\n" );
return 0;
}
if ( m < 0 )
return 0;
bank_money += m;
return bank_money;
}
nomask int sub_bank_money( int m ) {
if ( this_player() != this_object() && previous_object() != this_object() ) {
log_file( "ILLEGAL_BANK", ctime() +" "+
(string)this_player()->query_real_name() +"("+
file_name( this_player() ) +") sub "+ m +" in "+ cap_name +"\n" );
return 1;
}
if ( m < 0 )
return 0;
bank_money -= m;
if ( bank_money < 0 )
bank_money = 0;
return bank_money;
}
nomask int query_bank_money() {
return bank_money;
}
nomask int query_level_sec() {
return level;
}
int equivalent_level() {
int i;
int eq_lev;
int *lev_exp;
if (experience_billions) { // means we have at least 2 billion xp
if (level < 49) return 49;
return level; // This function is really only used for low level checks
// But if we have more than 50 levels, worry then
}
lev_exp = "/room/class_room"->query_exp_level();
if (!lev_exp) { // Happens when classroom inherited badly
"/room/class_room"->init_stuff();
lev_exp = "/room/class_room"->query_exp_level();
}
eq_lev = 0;
for(i=0;i<sizeof(lev_exp);i++) {
if (experience < lev_exp[i] && !eq_lev)
eq_lev = i;
}
if (!eq_lev) return level;
return eq_lev;
}
string query_called_from_ip() {
if (!this_interactive() ||
this_interactive()->query_level() < SENATELEVEL)
return DEFAULT_IP_NUMBER;
return called_from_ip;
}
int capi_name( string input ) {
if ( !input ) {
notify_fail( "How do you want your name to be capitalized?\n" );
return 0;
}
if ( this_player() != this_interactive() || this_player() != this_object() )
return 0;
if ( !this_player()->query_flag( "D2" ) ) {
notify_fail( "You are not allowed to do this.\n" );
return 0;
}
if ( lower_case( input ) != name ) {
write( "That is not your name.\n" );
return 1;
}
c_name = input;
cap_name = capitalize( c_name );
write( "You are now spelled \""+ cap_name +"\".\n" );
if ( is_invis )
cap_name = "Someone";
return 1;
}
void set_descriptor( string new_name ) {
if ( -1 != member( DESCRIPTOR_ALLOWED_EUIDS,
geteuid( previous_object() ) ) ) {
if ( !new_name ) {
cap_name = c_name = capitalize( name );
if ( !this_object()->query_flag("D2") )
c_name = 0;
descriptor = 0;
} else {
cap_name = c_name = new_name;
descriptor = previous_object();
}
}
}
void update_body_string( string x ) {
body = x;
}
int query_intermud() {
#ifdef TESTMUD
return 1; // let testers use intermud
#endif
if ( level >= WIZARDLEVEL || (flags && test_bit( flags, 16 )) )
return 1;
}
void first_log_check() {
write( "\n\n*** You will be forced to quit in 3 minutes! ***\n\n" );
call_out( "extra_quit2", 3 * 60 );
}
query_first_log_check() {
return donate_force_quit;
}
void set_pk() {
pk_member = present( "pk_brand", this_object() ) ? 1 : 0;
}
status query_pk() {
return pk_member;
}
int query_remember_last_time() {
return remember_last_time;
}
int query_first_login() {
return first_login;
}
int query_player_list() {
int pts, qrat;
// the first quest gives a boost
if ( !quests )
return experience;
pts = experience + Dex*Con*Str*Int*Wis + age/15 + (money + bank_money) / 5;
qrat = (100 * "room/quest_room"->count_solved(this_object())) / my_quest_max;
// points + points * percentage achieved quest points of necessary qpoints
// Changed by Arpeggio, 16Sep95 to avoid overflowing on large pts values
// This may change some players' ratings due to integer math, but fuck'em
// return pts + (pts * qrat)/150;
return pts + ( ( pts / 150 ) * qrat );
}
// next section removed by Maker for prompt project, 08 Aug 2013
#ifndef VERSION_NEW_PROMPT
void quick_info() {
tell_object( this_object(), query_hp_ansi() +":"+ query_sp_ansi() +"> " );
}
void path_prompt()
{
tell_object(this_object(), (string)this_object()->query_path() + ": ");
}
void alt_prompt( int type ) {
switch(type) {
case 0:
set_prompt( "> ", this_object() );
break;
case 1:
set_prompt( #'quick_info, this_object() );
break;
case 2:
set_prompt( #'path_prompt, this_object() );
break;
}
}
#endif
mixed *query_clan_info() {
return ({ name, clan, level, age, (Dex+Str+Int+Wis+Con), explore_p });
}
int query_can_be_followed() {
return 1;
}
// --------------------------------------------------------------- MINI-QUESTS
#if 0
// int mquest_level; /* to what level are we allowed to advance without mquest*/
set_mquest_level( level ) {
if(!previous_object()) return 0;
if(file_name(previous_object())!="/room/mquest_room"){
log_file("MQUEST_ILLEGAL",ctime(time())+" set_mquest_level by "+
file_name(previous_object())+" ("+this_player()->query_real_name()+")\n");
return 0;
}
if(mquest_level>level) return 0;
mquest_level = level;
return 1;
}
int query_mquest_level() { return mquest_level; }
#endif
void test_login() {
if ( this_interactive()->query_real_name() == "greyson" ) {
object login;
login = clone_object( "/secure/login" );
exec( login, this_object() );
login->logon();
quit();
}
}
// ------------------------------------------------------------------------ EOF